feat(520-3): 페이지 넘김 공용 moveStage — 잠금 + 진행 원(n/N 단계 이름 · 지난 초) · B07 · B08 · B09 · 미리보기 [<] [>] · 단계 판 누름을 한 길로

- ui_template setLoadingOverlayProgress(ratio, label) — 잠금판 스피너 자리에 진행 원 · 참조가 모두 풀리면 함께 걷힘
- b_workflow_nav moveStage(projectId, 주소 또는 이동 함수, steps) — 단계 { 이름 · 실행 · 선택 서버 진행 묻기 } · 거짓 · 던짐 = 잠금 풀고 머묾(던짐은 까닭 토스트) · 넘기는 중 다시 누름 무시
- goToWorkflowStage 가 Promise 를 돌려줌 — 잠금이 이동 뒤에 풀림
- 낡은 시험 고침 — 298-2 · 481-2 가짜 의존에 moveStage · 290-1 · 280-5 글 약속을 새 길로 · 520-3 시험 새로

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-25 07:59:58 +09:00
co-authored by Claude Opus 5.5
parent b522a52622
commit 10894b5b34
12 changed files with 320 additions and 60 deletions
+12 -13
View File
@@ -27,7 +27,7 @@ import { attachHoverInfo } from "@ui/ui_template_hover_info";
import { ui_locales, currentLanguageIndex } from "@ui/ui_template_locale";
import { clearState, readState, writeState } from "../A00_Common/b_page_state";
import { workflowSteps } from "../A00_Common/b_page_scaffold";
import { goToWorkflowStage, WORKFLOW_STEP_ROUTES } from "../A00_Common/b_workflow_nav";
import { moveStage, WORKFLOW_STEP_ROUTES } from "../A00_Common/b_workflow_nav";
import { computeBase, type Row } from "./B09_Estimation_Calc_Base";
import { computeEstimation } from "./B09_Estimation_Calc_Bill";
import { computeLabor, daegaPrice } from "./B09_Estimation_Calc_Labor";
@@ -357,9 +357,9 @@ export function renderB09Estimation(root: HTMLElement): void {
// 481-2 단계 이동 = 고친 값 저장 성공 뒤 · 실패면 머묾 · 불러오기 전 · 고침 없음 = 요청 없이
onStepClick: (stepIndex: number) => {
if (!projectId) return;
void saveChanged().then(
(ok) => ok && goToWorkflowStage(projectId, WORKFLOW_STEP_ROUTES[stepIndex]),
);
void moveStage(projectId, WORKFLOW_STEP_ROUTES[stepIndex], [
{ name: "원가 저장", run: saveChanged },
]);
},
});
// [>] = 다음 단계 없음 → 공용 틀 대신 여기서 — 저장 → 단계 6 완료 → 초안 다음 길 · 초안 없으면 흐림 그대로
@@ -369,15 +369,14 @@ export function renderB09Estimation(root: HTMLElement): void {
left.addEventListener("ui-step-nav", (event) => {
if ((event as CustomEvent<number>).detail !== 1 || !goNext || !projectId) return;
event.stopPropagation();
void (async () => {
if (!(await saveChanged())) return;
try {
await request(`/projects/${projectId}/estimation/complete`, { method: "POST" });
} catch (error) {
return showToast(`단계를 마치지 못했습니다 — ${String(error)}`, "error");
}
goNext();
})();
void moveStage(projectId, goNext, [
{ name: "원가 저장", run: saveChanged },
{
name: "원가 계산 단계 완료",
run: async () =>
void (await request(`/projects/${projectId}/estimation/complete`, { method: "POST" })),
},
]);
});
root.append(layout.root);
show(current);