feat(B11): 자료 준비 화면 신설 — 작업 화면 진입 전 3D·등고선 선적재
- B11_Status_UI_Loading + 라우트 b11-loading: 공통 프로그레스 서클로 단계·진행률 표시, 끝나면 원래 가려던 화면으로 자동 이동 - goToWorkflowStage: 아직 준비하지 않은 프로젝트면 준비 화면 경유, 같은 프로젝트로 다시 들어오면 건너뜀(탭 단위 기억). 다른 프로젝트면 보관분 교체 - 선적재 범위: 확정 지표면 3D + 그 등고선만 (종단·횡단은 0.86MB·0.06초로 이미 즉시라 제외, 배수유역·포인트클라우드도 제외) - 실패 시 자동 이동하지 않고 담당자 연락 안내 + [그래도 이동]/[대시보드로] - B04 등고선 간격 시작값을 B05 저장값과 공유(B04 변경은 DB에 쓰지 않음) - 새 문구는 ui_locales에 한국어·영어 등록
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
import { CURRENT_PROJECT_ID_KEY, ROUTES, type RoutePath } from "@config/config_frontend";
|
||||
import { createButton } from "@ui/ui_template_elements";
|
||||
import { createGeneralLayout } from "@ui/ui_template_general_layout";
|
||||
import { t } from "@ui/ui_template_locale";
|
||||
import { createProgressCircle } from "@ui/ui_template_progress";
|
||||
import {
|
||||
markProjectPreloaded,
|
||||
preloadSurfaceAssets,
|
||||
purgeOtherProjects,
|
||||
readPreloadTarget,
|
||||
} from "../A00_Common/b_asset_cache";
|
||||
import { navigateTo } from "../A00_Common/router";
|
||||
import "./B11_Status_UI_Style.css";
|
||||
|
||||
/* =============================================================================
|
||||
* 자료 준비 화면 (B11)
|
||||
*
|
||||
* 대시보드에서 프로젝트를 골라 작업 화면으로 들어갈 때, 먼저 이 화면이 3D 지표면과
|
||||
* 등고선을 브라우저에 담아 둔다. 담아 두면 B04·B05가 그것을 그대로 쓰므로 화면이 바로 뜬다.
|
||||
* 이미 담겨 있으면 순식간에 지나간다.
|
||||
*
|
||||
* 자료를 준비하지 못하면(분석 실패·저장 경로 문제) 넘어가지 않고 사유를 알린다.
|
||||
* ========================================================================== */
|
||||
|
||||
export async function renderB11Loading(root: HTMLElement): Promise<void> {
|
||||
const projectId = localStorage.getItem(CURRENT_PROJECT_ID_KEY);
|
||||
const target = (readPreloadTarget() ?? ROUTES.B03_FILE_INPUT) as RoutePath;
|
||||
|
||||
const progress = createProgressCircle({ label: t("B11_Loading_Start"), size: 96 });
|
||||
const message = document.createElement("p");
|
||||
message.className = "b11-loading__message";
|
||||
message.textContent = t("B11_Loading_Message");
|
||||
|
||||
const actions = document.createElement("div");
|
||||
actions.className = "b11-loading__actions";
|
||||
|
||||
const body = document.createElement("div");
|
||||
body.className = "b11-loading__body";
|
||||
body.append(progress.root, message, actions);
|
||||
|
||||
const layout = createGeneralLayout({
|
||||
pageClass: "b11-status",
|
||||
title: t("B11_Loading_Title"),
|
||||
subtitle: t("B11_Loading_Subtitle"),
|
||||
content: [body],
|
||||
});
|
||||
root.replaceChildren(layout.root);
|
||||
|
||||
if (!projectId) {
|
||||
showFailure(t("B11_Loading_NoProject"));
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// 다른 프로젝트 자료가 남아 있으면 지운다 — 프로젝트끼리 섞이면 안 된다.
|
||||
await purgeOtherProjects(projectId);
|
||||
await preloadSurfaceAssets(projectId, (label, ratio) => {
|
||||
progress.set(ratio, label);
|
||||
});
|
||||
markProjectPreloaded(projectId);
|
||||
navigateTo(target);
|
||||
} catch (error) {
|
||||
const detail = error instanceof Error ? ` (${error.message})` : "";
|
||||
showFailure(`${t("B11_Loading_Failed")}${detail}`);
|
||||
}
|
||||
|
||||
function showFailure(text: string): void {
|
||||
progress.root.hidden = true;
|
||||
message.textContent = text;
|
||||
message.classList.add("b11-loading__message--error");
|
||||
actions.replaceChildren(
|
||||
createButton({
|
||||
label: t("B11_Loading_Btn_Continue"),
|
||||
variant: "ghost",
|
||||
// 준비를 못 했어도 같은 세션에서 다시 붙잡지 않도록 표시해 둔다.
|
||||
onClick: () => {
|
||||
if (projectId) markProjectPreloaded(projectId);
|
||||
navigateTo(target);
|
||||
},
|
||||
}),
|
||||
createButton({
|
||||
label: t("B11_Loading_Btn_Dashboard"),
|
||||
variant: "filled",
|
||||
onClick: () => navigateTo(ROUTES.B01_ACCOUNT),
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user