/* ============================================================================= * M01_MasterData_UI_Test.ts * 로직 테스트 컨테이너 틀 — 공종(로직) 10 개 고르기 + 방식 탭 A·B·C * 읽기와 시험 계산만 — 저장 없음 · 정본 로직은 안 고침 · 계산은 로직 화면과 같은 `/calc` * 접속 계약 — 방식 파일마다 `render(host, logicKey)` 하나 * ========================================================================== */ import { createButton, createSelectField, el, showToast } from "@ui/ui_template_elements"; import { fetchLogics } from "./M01_MasterData_UI_Logic_Api"; import { openLogicWizard } from "./M01_MasterData_UI_Logic_Wizard"; import { render as renderA } from "./M01_MasterData_UI_Test_A"; import { render as renderB } from "./M01_MasterData_UI_Test_B"; import { render as renderC } from "./M01_MasterData_UI_Logic_Flow"; import { tt } from "./M01_MasterData_UI_Test_Text"; import "./M01_MasterData_UI_Test_Style.css"; /** 시험 대상 산림품셈 로직 10 개 — 복잡도(입력·표 찾기·로직 부르기·덧줄·재료)로 잰 순서. * 재는 법 `resources/master_data/scripts/로직_복잡도_재기.py` · 메쌓기·노체·트럭 운반은 끝까지 눌러 보는 세 개. */ export const TEST_KEYS: readonly string[] = [ "GF000181", // 12-16 맨홀 "GF000177", // 12-12 날개벽 "GF000173", // 12-11-1 VR관(소켓식) 부설 "GF000174", // 12-11-2-1 흄관 부설 "GF000160", // 12-4 합판거푸집 "GF000182", // 12-17-1 펌프카 타설 "GF000069", // 7-11 동력상하차기 집재 "GF000219", // 13-4-1 돌쌓기 메쌓기(인력) "GF000119", // 9-16-1 노체포설 "GF000137", // 10-4 중기운반 트레일러 ]; type Render = (host: HTMLElement, logicKey: string) => void; /** 방식 파일이 오면 여기 한 줄씩 잇는다 — null 은 준비 중 */ const METHODS: { id: string; label: () => string; render: Render | null }[] = [ { id: "A", label: () => tt("Tab_A"), render: renderA }, { id: "B", label: () => tt("Tab_B"), render: renderB }, { id: "C", label: () => tt("Tab_C"), render: renderC }, ]; export function mountM01Test(host: HTMLElement): void { let logicKey = TEST_KEYS[0]; let method = METHODS[0].id; const body = el("div", { className: "m01-test__body" }); const tabs = el("div", { className: "m01-test__tabs" }); const select = createSelectField({ label: tt("Pick_Logic"), options: TEST_KEYS.map((k) => ({ value: k, text: k })), value: logicKey, onChange: (v) => { logicKey = v; draw(); }, }); const draw = (): void => { tabs.replaceChildren( ...METHODS.map((m) => el("button", { className: `m01-test__tab${m.id === method ? " is-active" : ""}`, text: m.label(), attrs: { type: "button", "data-method": m.id }, }), ), ); tabs.querySelectorAll("button").forEach((b) => b.addEventListener("click", () => { method = b.dataset.method ?? "A"; draw(); }), ); const one = METHODS.find((m) => m.id === method); if (one?.render) one.render(body, logicKey); else body.replaceChildren(el("p", { className: "m01-test__muted", text: tt("Soon") })); }; host.replaceChildren( el("div", { className: "m01-test", children: [ el("div", { className: "m01-test__bar", children: [ el("h2", { text: tt("Title") }), select.root, tabs, createButton({ label: tt("New_Logic"), onClick: () => openLogicWizard() }), ], }), el("p", { className: "m01-test__muted", text: tt("Read_Only") }), body, ], }), ); // 목록에서 이름을 받아 「번호 이름」 으로 바꿈 — 못 받아도 키로 쓸 수 있음 fetchLogics() .then((all) => { const label = new Map(all.map((r) => [r.키, `${r.원문번호} ${r.이름}`])); select.setOptions( TEST_KEYS.map((k) => ({ value: k, text: label.get(k) ?? k })), logicKey, ); }) .catch((error) => showToast(error instanceof Error ? error.message : tt("Failed"), "error")); draw(); }