/* ============================================================================= * B05_Profile_UI_RouteReset.ts * 노선 모양 바뀐 [저장] = 초기화(요구 283 · 284 · 285 · 492-2) — 화면 몫. * * · 띠 — 평면(노선 편집) 위 한 줄 · 노선 초안이 저장 노선 모양을 바꾸면 보임(B06 평면 패널로 옮겨져도 같이 감). * · 확인 창 — [저장](`design_save`) · 추천 [적용](476-2) 앞 · 지워질 수 = 지금 캐시의 사용자 구조물 · 관 · * 추가 측점 · 종단 편집 · [취소] = 요청 0. * · 저장 뒤 알림 — 서버 응답 `route_reset`(정본 판정) · 없으면(옛 서버) 건너뜀. * 셈 · 글 = `logic/B05_Profile_Route_Reset` · 저장 노선 = 페이지 자료 줄(`pageRoutePlan` · 조작마다 안 물음). * ========================================================================== */ import { showConfirmDialog } from "@ui/ui_template_elements"; import type { RouteDraft } from "../A00_Common/design/logic/design_pipeline_types"; import { useDesignStore } from "../A00_Common/design/design_store"; import { pagePipes, pageRouteId, pageRoutePlan, pageStructures, } from "../A00_Common/design/design_page_data"; import { plusStationsOf } from "./B05_Profile_Api_PlusStations"; import { pendingAlignment, routeAlignment } from "./B05_Profile_UI_Profile_Edit"; import { askRouteReset, draftShapeChanged, ROUTE_RESET_BAND, routeResetConfirmText, type RouteResetCounts, } from "./logic/B05_Profile_Route_Reset"; /** 노선 초안 동안의 계획고 초안 칸 — `design_pipeline_page` 의 `DRAFT_ROUTE_ID` 와 같은 값. */ const DRAFT_ROUTE_ID = 0; /** 초안이 저장 노선 모양을 바꾸나(저장 노선을 못 받으면 바뀜으로 봄). */ export async function draftResets(projectId: string, draft: RouteDraft | null): Promise { if (!draft) return false; const plan = await pageRoutePlan(projectId).catch(() => null); return draftShapeChanged(plan?.planned ?? null, draft, plan?.min_radius_m ?? 0); } /** 지금 캐시(초안 ?? 저장분)에서 지워질 수. */ export async function routeResetCounts(projectId: string): Promise { const store = useDesignStore(projectId, null); const [structures, pipes] = await Promise.all([ store.get("structures") ?? pageStructures(projectId).then( (list) => list.structures, () => [], ), store.get("pipes") ?? pagePipes(projectId).then( (list) => list.pipe_points, () => [], ), ]); const routeId = pageRouteId(projectId); const edits = pendingAlignment(DRAFT_ROUTE_ID) ?? (routeId === null ? null : routeAlignment(routeId)); return { structures: structures?.length ?? 0, pipes: pipes?.length ?? 0, plusStations: plusStationsOf(projectId).length, profileEdits: Object.keys(edits?.station_offsets ?? {}).length + Object.keys(edits?.curve_radii ?? {}).length, }; } /** [저장] 앞 — 모양 바뀐 초안이면 확인 창 · [취소] = false(요청 0) · 안 바뀜 = 묻지 않고 true. */ export async function confirmRouteReset(projectId: string, draft: RouteDraft): Promise { return askRouteReset( await draftResets(projectId, draft), () => routeResetCounts(projectId), (text) => showConfirmDialog(text, "저장"), ); } /** 추천 [적용] 확인 창 글 — [저장]과 같은 글 · 수. */ export async function applyResetText(projectId: string): Promise { return routeResetConfirmText(await routeResetCounts(projectId), "적용"); } /** 평면 위 띠를 세움 — 노선 초안이 바뀔 때마다 맞춤 · 돌려준 함수 = 떠날 때 풂. */ export function mountRouteResetBand(parent: HTMLElement, projectId: string): () => void { const band = document.createElement("div"); band.className = "b05-routeedit__reset-band"; band.setAttribute("role", "status"); band.textContent = ROUTE_RESET_BAND; band.hidden = true; parent.append(band); const store = useDesignStore(projectId, null); let turn = 0; const sync = async (draft: RouteDraft | null): Promise => { const mine = ++turn; // 늦게 온 옛 판정이 새 판정을 덮지 않게 const changed = await draftResets(projectId, draft); if (mine === turn) band.hidden = !changed; }; void sync(store.get("routeDraft")); const stop = store.subscribe("routeDraft", (draft) => void sync(draft)); return () => (stop(), band.remove()); }