Files
Aislo/B08_Quantity/B08_Quantity_UI_Earthwork.ts
T
eomsangdonandClaude Sonnet 5.5 361ce51659 refactor(B08·B09): 자체 변종 → 부품 상자 — 탭 줄 · 분할 고르기 · 배지 칩 · 도구줄 · 떠 있는 판 · 보조 글 (PLAN 553-3)
- 위 · 보조 탭 줄 = 부품 탭(fillTabs · 밑줄 · 알약) · B09 좌측 스위치 = 분할 고르기
- 연결 칩 · 검사 탭 이름 · 끌기 태그 = 배지 · 이정표 도구 · 머리 줄 · 저장 줄 = 도구줄 · 구간 고침 · 행 고름 창 = 떠 있는 판
- 안내 · 빈 줄 · 상태 글 = 보조 글 · 운반 칸 = 카드 · 인쇄 미리보기 좌측 줄 = B09 dock 한 벌 · 쪽 체크 = 라디오 · 체크 부품
- 시험 흉내 틀 · 문구 맞춤

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-26 22:33:35 +09:00

104 lines
4.4 KiB
TypeScript

/* =============================================================================
* B08_Quantity_UI_Earthwork.ts
* 토공 탭(PLAN 61-3 · 69-2 · 69-3) — 보조 탭 넷 = 토공집계표 · 토적표 · 평균운반거리 · 종방향 무대운반거리.
*
* GET …/quantity/earthwork 한 번(서버 단독 · 읽기만) — 네 장이 같은 응답을 나눠 그림.
* 토적표 = 줄 측점 · 칸 = 사용자 견본(절토 토사 · 연암 · 측구파기 토사 · 암 각 단면적 · 입적 ·
* 보정량 · 보정량계 · 성토 · 유용토 · 차인토량 · 누가토량 · 면고르기 · 지장목제거 · 제근 · 노면정리 각
* 거리 · 면적) · 맨 아래 합계 줄. 첫 측점은 앞이 없어 입적 · 면적이 빈 값(—).
* 표 = 공용 많은 자료 표(`ui_template_data_table` · PLAN 70) · 카드 안 · 나머지 셋은 `…_Earthwork_Sheets`.
* 절토 연암 · 경암 = 암 × 좌측 패널 비율 · 암 C = 비율 가중 — 조작 중 같은 식으로 바로 다시 셈
* (`…_Options_Calc` · PLAN 122 · 125-1).
* 자료 읽기 · 표 짜기 = `B08_Quantity_Earthwork_Tables`(화면 없음 · 인쇄 미리보기도 씀 · 302-3)
* ========================================================================== */
import { createCard } from "@ui/ui_template_elements";
import { createText } from "@ui/ui_template_text";
import { createDataTable } from "@ui/ui_template_data_table";
import { fillTabs } from "../A00_Common/b_page_tabs";
import { footNote } from "./B08_Quantity_UI_Foot";
import {
EARTHWORK_SHEETS,
earthworkSheetOptions,
loadEarthwork,
type EarthworkTable,
} from "./B08_Quantity_Earthwork_Tables";
import {
renderEarthworkSummary,
renderFreeHaul,
renderHaulDistance,
} from "./B08_Quantity_UI_Earthwork_Sheets";
import { onOptionsChange } from "./B08_Quantity_UI_Options";
export function note(text: string): HTMLElement {
return createText(text, "muted", 14);
}
/** 표 한 장 — 공용 컨테이너(카드) 안에 공용 표 · 아래 줄 · 맨 아래 안내 · 경고 줄(202-1) */
export function tableCard(
info: HTMLElement[],
table: HTMLElement,
after: HTMLElement[] = [],
): HTMLElement {
return createCard({ body: [table, ...after, ...info] });
}
function renderSheet(host: HTMLElement, table: EarthworkTable, interval: number): void {
if (!table.rows.length) {
host.replaceChildren(note("측점 단면적이 아직 없습니다 — 횡단 설계를 먼저 마치세요."));
return;
}
const flagged = table.rows.filter((row) => row.notes.length);
const info = [
footNote(
`노선 ${table.route_id}${table.confirmed ? "(확정)" : "(확정 전 최신 노선)"} · ` +
`측점 ${table.station_count} · 단위 m · ㎡ · ㎥`,
),
...(flagged.length ? [footNote(`* ${flagged[0].notes[0]} — ${flagged.length}곳`)] : []),
];
const grid = createDataTable({ ...earthworkSheetOptions(table, interval), fillViewport: true });
grid.root.dataset.b08Earthwork = "table";
host.replaceChildren(tableCard(info, grid.root));
}
const SHEETS = EARTHWORK_SHEETS;
type SheetId = (typeof SHEETS)[number]["id"];
export async function renderEarthwork(host: HTMLElement, projectId: string): Promise<void> {
host.replaceChildren(note("토공 수량을 만드는 중…"));
let loaded: Awaited<ReturnType<typeof loadEarthwork>>;
try {
loaded = await loadEarthwork(projectId);
} catch (error) {
host.replaceChildren(note(`토공 수량을 불러오지 못했습니다 — ${String(error)}`));
return;
}
const { table, interval, applyRock } = loaded;
const tabs = document.createElement("div");
tabs.className = "b08-quantity__tabs b08-earthwork__tabs";
const view = document.createElement("div");
let current: SheetId = "summary";
const select = (picked: SheetId): void => {
current = picked;
fillTabs(tabs, {
tabs: SHEETS.map(({ id, label }) => ({ key: id, label })),
value: picked,
kind: "pill",
data: "b08EarthworkSheet",
onChange: (id) => select(id as SheetId),
});
if (picked === "sheet") renderSheet(view, table, interval);
else if (picked === "summary") renderEarthworkSummary(view, table);
else if (picked === "haul") renderHaulDistance(view, table);
else renderFreeHaul(view, table);
};
host.replaceChildren(tabs, view);
select("summary");
onOptionsChange(host, () => {
applyRock();
select(current);
});
}