Files
Aislo/B08_Quantity/B08_Quantity_UI_Page.ts
T
eomsangdonandClaude Opus 5.5 aefcb23dd2 feat(b08): 3탭 토적표 — 옛 평균단면적법 엔진 복사 · 서버 읽기 전용 길 · 측점별 표 + 합계 줄(PLAN 61-3)
- 엔진 = old_code B08_Quantity_Engine_EarthworkTable.py 복사(B08_Quantity_Engine_Earthwork.py) · 계산식 그대로
- 고친 곳 = 입력부(암 종류 없으면 암 지반 유형) · 줄 cut_rock_kind · 합계 리핑암 · 발파암 칸
- 길 = GET /quantity/earthwork — B06 횡단 설계 저장 단면적(확정 노선 · 없으면 최신) · 환산계수 = 유토곡선과 같은 mixed_conversion_factors · 아무것도 안 씀
- 화면 = 측점 · 거리 · 절토(토사 · 리핑암 · 발파암) · 측구터파기(토사 · 암) 각 단면적 · 입적 · 보정량 · 보정량계 · 성토 · 유용토 · 차인토량 · 누가토량 · 합계 줄
- 옛 시험 test_b08_earthwork_table.py 는 가져오는 경로만 새 엔진으로 · 새 시험 test_61_3_b08_earthwork_kinds.py

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UoSr2sqvYtBf1dtQdus88s
2026-10-06 18:26:17 +09:00

101 lines
3.9 KiB
TypeScript

/* =============================================================================
* B08_Quantity_UI_Page.ts
* 로그인 후 08: 5차 워크플로우 (수량 산출) — 위 탭 화면 (PLAN 61)
*
* 탭 = 구조물 집계표 · 구조물도 · 토적표 · 수리집수면적표 — 차례대로 만듦.
* 1탭(구조물 집계표 · 61-1) · 4탭(수리집수면적표 · 홍수량 계산서 62-2) 내용 · 나머지는 빈 탭.
* 옛 수량 산출 코드(`old_code/B08_Quantity/`)는 가져오지 않음 — 새로 씀.
* ========================================================================== */
import "@ui/ui_template_general_layout.css";
import "./B08_Quantity_UI_Page.css";
import { createWorkflowLayout } from "@ui/ui_template_workflow_layout";
import { createButton } from "@ui/ui_template_elements";
import { ui_locales, currentLanguageIndex } from "@ui/ui_template_locale";
import { CURRENT_PROJECT_ID_KEY } from "@config/config_frontend";
import { workflowSteps } from "../A00_Common/b_page_scaffold";
import { goToWorkflowStage, WORKFLOW_STEP_ROUTES } from "../A00_Common/b_workflow_nav";
import { renderStructureSummary } from "./B08_Quantity_UI_Summary";
import { renderHydro } from "./B08_Quantity_UI_Hydro";
import { renderStructureSheets } from "./B08_Quantity_UI_Drawing";
import { renderEarthwork } from "./B08_Quantity_UI_Earthwork";
function L(key: keyof typeof ui_locales): string {
return ui_locales[key][currentLanguageIndex];
}
const TABS = [
{ id: "summary", label: "B08_Quantity_Tab_StructureSummary" },
{ id: "sheet", label: "B08_Quantity_Tab_StructureSheet" },
{ id: "earthwork", label: "B08_Quantity_Tab_Earthwork" },
{ id: "hydrology", label: "B08_Quantity_Tab_Hydrology" },
] as const;
type TabId = (typeof TABS)[number]["id"];
/** 탭마다 새 몸통 — 늦게 온 응답이 다른 탭 화면을 덮지 않게(떨어진 몸통에만 그림). */
function renderTab(host: HTMLElement, tab: TabId, projectId: string | null): void {
const view = document.createElement("div");
host.replaceChildren(view);
if (tab === "summary" && projectId) {
void renderStructureSummary(view, projectId);
return;
}
if (tab === "hydrology" && projectId) {
void renderHydro(view, projectId);
return;
}
if (tab === "sheet" && projectId) return void renderStructureSheets(view, projectId);
if (tab === "earthwork" && projectId) return void renderEarthwork(view, projectId);
const pending = document.createElement("p");
pending.className = "ui-general-block__empty";
pending.textContent = L("B08_Quantity_Tab_Pending");
view.append(pending);
}
export function renderB08Quantity(root: HTMLElement): void {
const projectId = localStorage.getItem(CURRENT_PROJECT_ID_KEY);
const tabBar = document.createElement("div");
tabBar.className = "b08-quantity__tabs";
tabBar.setAttribute("role", "tablist");
const panel = document.createElement("div");
panel.className = "b08-quantity__panel";
panel.setAttribute("role", "tabpanel");
const select = (tab: TabId): void => {
tabBar.replaceChildren(
...TABS.map(({ id, label }) => {
const button = createButton({
label: L(label),
variant: id === tab ? "filled" : "ghost",
size: "sm",
onClick: () => id !== tab && select(id),
});
button.setAttribute("role", "tab");
button.setAttribute("aria-selected", String(id === tab));
button.dataset.b08Tab = id;
return button;
}),
);
renderTab(panel, tab, projectId);
};
const body = document.createElement("div");
body.className = "b08-quantity";
body.append(tabBar, panel);
select("summary");
const layout = createWorkflowLayout({
title: L("B08_Quantity_Title"),
steps: workflowSteps(),
activeStep: 5,
mainContent: body,
routes: WORKFLOW_STEP_ROUTES,
onStepClick: (stepIndex: number) => {
if (projectId) goToWorkflowStage(projectId, WORKFLOW_STEP_ROUTES[stepIndex]);
},
});
root.append(layout.root);
}