- SPipe_server_2026-10-30.zip 내용을 풀어서 등록 (압축 파일은 올리지 않음) - README에 데모 v2 서버 업데이트 순서 추가, 저장소에 없는 문서 목차 정리 - 패치내역을 docs/로 이동, _worklog.md 추가 - 임시 파일(backend/temp.*)과 API 키가 든 파일은 제외
70 lines
2.9 KiB
TypeScript
70 lines
2.9 KiB
TypeScript
import React from 'react';
|
|
import type { SessionSnapshot } from './sessionStore';
|
|
|
|
interface SessionRecoveryModalProps {
|
|
recoverySnapshot: SessionSnapshot;
|
|
handleRestoreSession: () => void;
|
|
handleDiscardSession: () => Promise<void> | void;
|
|
}
|
|
|
|
/** Asks whether to restore the last autosaved session (never overwrites silently). */
|
|
export const SessionRecoveryModal: React.FC<SessionRecoveryModalProps> = ({
|
|
recoverySnapshot,
|
|
handleRestoreSession,
|
|
handleDiscardSession,
|
|
}) => (
|
|
<div className="modal-overlay">
|
|
<div
|
|
className="modal-content"
|
|
role="dialog"
|
|
aria-modal="true"
|
|
aria-labelledby="session-recovery-title"
|
|
style={{ width: 'min(460px, calc(100vw - 32px))', padding: 'var(--s-6)' }}
|
|
>
|
|
<h3
|
|
id="session-recovery-title"
|
|
style={{ margin: '0 0 var(--s-4)', fontSize: 'var(--fs-lg)', color: 'var(--text)' }}
|
|
>
|
|
이전 작업을 복구하시겠습니까?
|
|
</h3>
|
|
<p style={{ margin: '0 0 var(--s-4)', color: 'var(--text-muted)', lineHeight: 1.6 }}>
|
|
{new Date(recoverySnapshot.savedAt).toLocaleString('ko-KR')}에 자동 저장된 모델이 있습니다.
|
|
자동으로 덮어쓰지 않으며, 복구 여부를 직접 선택할 수 있습니다.
|
|
</p>
|
|
<div
|
|
style={{
|
|
padding: 'var(--s-4)',
|
|
border: '1px solid var(--border)',
|
|
borderRadius: 'var(--r-sm)',
|
|
background: 'var(--bg-subtle)',
|
|
marginBottom: 'var(--s-5)',
|
|
fontSize: 'var(--fs-sm)',
|
|
lineHeight: 1.7,
|
|
}}
|
|
>
|
|
<div>파일: {recoverySnapshot.fileName ?? '이름 없는 모델'}</div>
|
|
<div>
|
|
절점 {Object.keys(recoverySnapshot.networkModel.nodes).length} · 관로{' '}
|
|
{Object.keys(recoverySnapshot.networkModel.pipes).length}
|
|
</div>
|
|
<div style={{ color: 'var(--text-muted)' }}>
|
|
{/* The v2 snapshot does store results (wasmResult/serverResult and
|
|
every scenario's result); the old text said it never did. */}
|
|
{recoverySnapshot.wasmResult || recoverySnapshot.serverResult
|
|
? `해석 결과와 대안 ${recoverySnapshot.scenarios?.length ?? 0}개도 함께 복구됩니다.`
|
|
: '저장 당시 해석 결과가 없었으므로 복구 후 해석을 실행해야 합니다.'}
|
|
</div>
|
|
</div>
|
|
<div style={{ display: 'flex', justifyContent: 'flex-end', gap: 'var(--s-3)' }}>
|
|
<button className="btn btn-secondary" onClick={() => void handleDiscardSession()}>
|
|
저장본 삭제
|
|
</button>
|
|
<button className="btn btn-primary" onClick={handleRestoreSession} autoFocus>
|
|
이전 작업 복구
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
|