feat(B 페이지): 떠남 물음 가드 · 지금 프로젝트 = 탭마다 (PLAN 572-2 · 요구 400~403)
- B04 · B07 · B08 · B09 가 공용 guardProjectLeave 에 {dirty, save, discard} 등록 — 고침 있을 때만 [취소 · 폐기 · 저장]
- B04 = 관 지점 고침(drainageDirty) · 저장 = 관 지점 · 세부유역 영구저장
- B07 = CAD · 탭 고침 · 저장 = saveEditedDrawings · 폐기 = 고친 도면 CAD 자동백업도 버림(discardEditedRecovery)
- B08 = 세션 b08-* 칸 넷 · 저장 = saveShown · B09 = b09-estimation 칸 · 저장 = saveChanged
- 지금 프로젝트 직접 읽기(localStorage) → currentProjectId() · B02 새 프로젝트 = setCurrentProject — B02 · B03 · B04 · B07 · B08 · B09 · B11
- 다른 프로젝트 보관함 지우기 셋(B04 · B05 종단 · B11) 뺌 — enterProject 한 곳 · 다른 탭 보관분 안 지움
- B02 · B03 은 가드 없음 — 저장 안 한 프로젝트 값 없음(B03 올리기 끊김은 이어 올리기 배너가 받음)
- 시험 test_560_4 넓힘(B 가드 · 탭 프로젝트 · 보관함) · helper_298_2 · helper_481_2 · test_204_2 흉내를 currentProjectId 로
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -150,6 +150,7 @@ export interface DetailBasinOverlay {
|
||||
handleClick: (view: ViewState, x: number, y: number) => boolean;
|
||||
/** 모델 확정 시점에 관 지점과 세부유역을 영구저장한다. */
|
||||
commit: () => Promise<number>;
|
||||
isDirty: () => boolean;
|
||||
draw: (context: CanvasRenderingContext2D, normalizer: Normalizer | null, view: ViewState) => void;
|
||||
dispose: () => void;
|
||||
}
|
||||
@@ -474,6 +475,7 @@ export function createDetailBasinOverlay(onChange: () => void): DetailBasinOverl
|
||||
]);
|
||||
return true;
|
||||
},
|
||||
isDirty: () => dirty,
|
||||
async commit() {
|
||||
if (!projectId) return 0;
|
||||
const response = await saveDetailPipePoints(
|
||||
|
||||
@@ -54,6 +54,8 @@ export interface SurfaceMapViewer {
|
||||
render: (projectId: string, routeBounds?: PlanBounds | null) => void;
|
||||
/** 관 매설 지점·세부유역을 영구저장한다. 저장한 관 개수를 돌려준다(모델 확정과 함께 호출). */
|
||||
commitDrainage: () => Promise<number>;
|
||||
/** 관 지점을 고치고 아직 저장 안 했나(떠날 때 물음 · 572-2). */
|
||||
drainageDirty: () => boolean;
|
||||
dispose: () => void;
|
||||
}
|
||||
|
||||
@@ -675,6 +677,7 @@ export function createSurfaceMapViewer(): SurfaceMapViewer {
|
||||
},
|
||||
/** 모델 확정과 함께 관 매설 지점·세부유역을 영구저장한다. */
|
||||
commitDrainage: () => detailBasins.commit(),
|
||||
drainageDirty: () => detailBasins.isDirty(),
|
||||
dispose() {
|
||||
loadSequence += 1;
|
||||
if (frameHandle) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { CURRENT_PROJECT_ID_KEY, ROUTES } from "@config/config_frontend";
|
||||
import { ROUTES } from "@config/config_frontend";
|
||||
import { currentLanguageIndex, ui_locales } from "@ui/ui_template_locale";
|
||||
import {
|
||||
createButton,
|
||||
@@ -15,7 +15,7 @@ import { createToggle } from "@ui/ui_template_toggle";
|
||||
import { createToolbar } from "@ui/ui_template_toolbar";
|
||||
import { createWorkflowLayout } from "@ui/ui_template_workflow_layout";
|
||||
import { fetchDashboardMe } from "../B01_Dashboard/B01_Dashboard_Api_Fetch";
|
||||
import { clearPreloadMark, purgeOtherProjects } from "../A00_Common/b_asset_cache";
|
||||
import { clearPreloadMark } from "../A00_Common/b_asset_cache";
|
||||
import { clearRouteLatestCache } from "../B05_Profile/B05_Profile_Api_Fetch";
|
||||
import { workflowSteps } from "../A00_Common/b_page_scaffold";
|
||||
import {
|
||||
@@ -47,6 +47,7 @@ import { createSurfacePointCloudViewer } from "./B04_PreProcess_UI_Viewer";
|
||||
import "./B04_PreProcess_UI_Style.css";
|
||||
// 700줄 제한으로 잘라낸 조각 — 본체 **다음에** 불러야 캐스케이드 순서가 같다(2026-09-04).
|
||||
import "./B04_PreProcess_UI_Style_Map.css";
|
||||
import { currentProjectId, guardProjectLeave } from "../A00_Common/b_project_switch";
|
||||
|
||||
// 고를 수 있는 필터. 자동 전처리는 이 중 기본 하나만 만들고, 나머지는 관리자가
|
||||
// 드롭다운에서 고를 때 그 조합만 계산한다 (2026-09-01 사용자 확정).
|
||||
@@ -93,9 +94,7 @@ function getModelFilter(model: SurfaceModelSummary): string {
|
||||
}
|
||||
|
||||
export async function renderB04Surface(root: HTMLElement): Promise<void> {
|
||||
const guardedProjectId = localStorage.getItem(CURRENT_PROJECT_ID_KEY);
|
||||
// 새로고침으로 바로 들어온 경우에도 다른 프로젝트 자료는 보관함에서 지운다.
|
||||
if (guardedProjectId) void purgeOtherProjects(guardedProjectId);
|
||||
const guardedProjectId = currentProjectId();
|
||||
if (guardedProjectId) {
|
||||
const user = await fetchDashboardMe();
|
||||
if (user.role !== "SYSTEM_ADMIN") {
|
||||
@@ -293,7 +292,7 @@ export async function renderB04Surface(root: HTMLElement): Promise<void> {
|
||||
workspace.append(statusBox, viewers, sheetSection, mapViewer.root);
|
||||
|
||||
let workflowState: WorkflowState | undefined;
|
||||
const layoutProjectId = localStorage.getItem(CURRENT_PROJECT_ID_KEY);
|
||||
const layoutProjectId = currentProjectId();
|
||||
if (layoutProjectId) {
|
||||
try {
|
||||
workflowState = await fetchWorkflowState(layoutProjectId);
|
||||
@@ -317,7 +316,7 @@ export async function renderB04Surface(root: HTMLElement): Promise<void> {
|
||||
});
|
||||
|
||||
function getProjectId(): string | null {
|
||||
const projectId = localStorage.getItem(CURRENT_PROJECT_ID_KEY);
|
||||
const projectId = currentProjectId();
|
||||
if (!projectId) showToast(L("B04_Surface_Error_Project"), "error");
|
||||
return projectId;
|
||||
}
|
||||
@@ -670,6 +669,11 @@ export async function renderB04Surface(root: HTMLElement): Promise<void> {
|
||||
});
|
||||
|
||||
root.replaceChildren(layout.root);
|
||||
// 572-2 떠남 물음 — 고침 = 관 지점 · 저장 = 관 지점 · 세부유역 영구저장(모델 [확정]과 같은 길)
|
||||
guardProjectLeave(layout.root, {
|
||||
dirty: mapViewer.drainageDirty,
|
||||
save: mapViewer.commitDrainage,
|
||||
});
|
||||
const projectId = getProjectId();
|
||||
if (projectId) void onB04_Surface_Reset_Click();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user