Files
Aislo/B06_Section/B06_Section_UI_Page_Common.ts
T
eomsangdonandClaude Sonnet 5.5 2c520537b6 refactor(B05·B06): 좌측 칸을 등록부로 · 아래 단추 넷 · B05 Panel 나눔(24-2b)
- B05 좌측 패널(714줄)을 Fields · Settings · Route · View · Sections 로 나누고 createRoutePanel 은 등록부로 세움
- B06 좌측 칸(횡단 보기 설정 · 표준 횡단면 설정)을 등록부로 · 페이지는 createDesignPanel 만 부름
- 「구조물 배치」는 design_sections 한 정의로 두 보기
- 아래 단추 [초기화][저장][확정][보기 전환] — B05 [확정]은 저장 흐름 이음 전까지 꺼 둠
- [초기화] 는 design_reset 한 함수를 두 보기가 부름
- 칸 DOM 은 고치기 전과 같음(전후 DOM 대조)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EauA2ATmqNRbeV48s9CcBr
2026-09-29 20:17:35 +09:00

58 lines
2.6 KiB
TypeScript

import { currentLanguageIndex, ui_locales } from "@ui/ui_template_locale";
import { hideLoadingOverlay, showLoadingOverlay, showToast } from "@ui/ui_template_elements";
import {
fetchSectionDetail,
regenerateSections,
type SectionDetailResponse,
} from "./B06_Section_Api_Fetch";
import { replaceSectionDetail } 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 사용자 지시).
*/
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;
showLoadingOverlay();
try {
await regenerateSections(target.projectId, target.routeId, widthM);
// 재생성 응답에는 설계가 없다 — 상세를 다시 받아 기본 설계 프리뷰까지 얹는다.
const fresh = await fetchSectionDetail(target.projectId, target.routeId);
// 공유 캐시도 새 상세로 바꿔 B05가 옛 값을 못 보게 한다.
replaceSectionDetail(target.projectId, target.routeId, fresh);
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;
hideLoadingOverlay();
}
};
}