Files
Aislo/B06_Section/B06_Section_UI_Page_Common.ts
T
eomsangdonandClaude Opus 5.5 341e83114e fix(446 B06 표본 넓힘): 카드 폭 넘김 다시 만들기가 측점 설계 · 표준 횡단면 · 유토 풍선 · 계획고 편집 옮겨 담음 · 다시 만들기 전 확인창
- 반폭 재생성 = 옛 횡단 행 data · 상태를 측점 열쇠(0.01 m)로 새 행에 · 옛 종단 data 사용자 키(표준 횡단면 · 유토 · 계획 입력 · 상태) — 같은 트랜잭션
- 계획고 편집 = 옛 계획선 통째(_carry_profile 같은 노선 갈래) · 실패면 종 · 횡단 파일 되돌림
- 넓힌 지반 위 [저장]과 같은 서버 재계산
- 화면 = 다시 만들기 전 확인창 · 취소면 재생성 없음 · 오버레이 셈 짝

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Se7ytqbohmBQnfYpwYFnYf
2026-10-18 18:42:21 +09:00

65 lines
3.1 KiB
TypeScript

import { currentLanguageIndex, ui_locales } from "@ui/ui_template_locale";
import {
hideLoadingOverlay,
showConfirmDialog,
showLoadingOverlay,
showToast,
} from "@ui/ui_template_elements";
import { regenerateSections, type SectionDetailResponse } from "./B06_Section_Api_Fetch";
import { loadSectionDetail } from "./B06_Section_Section_Store";
export function L(key: keyof typeof ui_locales): string {
return ui_locales[key][currentLanguageIndex];
}
/** 반폭 확대(백엔드 재생성)에 필요한 페이지 상태 — 클로저 대신 함수로 받아 결합을 끊는다. */
export interface SampleWidenerDeps {
/** 현재 대상 경로. 없으면 확대 불가. */
target: () => { projectId: string; routeId: number } | null;
/** 보유 샘플의 최대 반폭(m). */
sampledHalfWidth: () => number;
/** 재생성으로 받은 새 상세를 페이지 상태에 반영하고 다시 그린다. */
applyDetail: (detail: SectionDetailResponse) => void;
}
/**
* 요청 반폭까지 지반 샘플을 넓히는 함수를 만든다 — 보유 샘플로 충분하면 즉시 true
* (재계산 없음). 모자라면 그 폭으로 B05부터 재생성(영구 저장)하고 상세를 다시 받는다.
* 느려도 허용(2026-08-06 사용자 확정). 전역 [전체 측점 반영]과 카드 줌 버튼의 반폭
* 확대가 같은 경로를 쓴다(2026-08-23 사용자 지시). 다시 만들기 전 확인창 · 서버가 측점 설계 ·
* 계획고 편집 · 유토 풍선을 옮겨 담음(446).
*/
export function createSampleWidener(deps: SampleWidenerDeps): (widthM: number) => Promise<boolean> {
let running = false;
return async (widthM) => {
const target = deps.target();
if (!target) return false;
if (widthM <= deps.sampledHalfWidth() + 1e-6) return true;
if (running) return false; // 재생성 중 중복 요청은 무시(버튼 연타).
running = true;
let shown = false; // 오버레이는 셈 수 — 취소면 안 내림(남의 오버레이까지 내려감)
try {
const ask = L("B06_Profile_Regenerate_Confirm")
.replace("{width}", String(widthM))
.replace("{sampled}", String(deps.sampledHalfWidth()));
if (!(await showConfirmDialog(ask, L("B06_Profile_Regenerate_Go")))) return false;
showLoadingOverlay();
shown = true;
await regenerateSections(target.projectId, target.routeId, widthM);
// 재생성 응답에는 설계가 없다 — 상세를 다시 받아 기본 설계 프리뷰까지 얹는다 · 공유 캐시도
// 새 상세로(B05 가 옛 값을 못 보게) · 초안 측점 · 그림 자료도 같은 길(323-4)
const fresh = await loadSectionDetail(target.projectId, target.routeId, { force: true });
deps.applyDetail(fresh);
showToast(L("B06_Profile_Regenerate_Success"), "success");
return true;
} catch (error) {
const detail = error instanceof Error ? ` ${error.message}` : "";
showToast(`${L("B06_Profile_Regenerate_Failed")}${detail}`, "error");
return false;
} finally {
running = false;
if (shown) hideLoadingOverlay();
}
};
}