/* ============================================================================= * M02_MasterTemplete_Labor_Unlinked.ts * 일위대가표 안 이은 줄 띠 · [연결](PLAN 729-3 · 요구서 내역19 1장 8 · 분석 19-B D-2) — * · 안 이은 줄 = 고정 줄 중 비율 줄 아님 · 이음(노임 · 자재 · 기계) 모두 빈 것(서버 목록 summary `안이은줄` 과 같은 규칙) * · 띠 = 「M01 연결 없음 n 줄(옛 자료)」 · 고칠 수 있으면 [연결] → 줄마다 [찾기](노임 LB · 자재 MT · 721 찾아 넣기 창) · * [기계](M01 기계 EQ) — 고정 줄 이름 · 규격 · 엑셀 숫자(출처)는 그대로 · 이음만 붙임 → 상세 고침(저장은 [저장]) * 계산은 서버(이음 = 단가 책 값) — 화면은 고름만. * ========================================================================== */ import { createBanner } from "@ui/ui_template_banner"; import { createButton, el, showToast } from "@ui/ui_template_elements"; import { t as L } from "@ui/ui_template_locale"; import { openModal } from "@ui/ui_template_modal"; import { createTable } from "@ui/ui_template_table"; import { getActiveLayer, getActiveOwner } from "./M02_MasterTemplete_Api_Fetch"; import { openFindPicker } from "./M02_MasterTemplete_Find_Pick"; import type { LaborDoc } from "./M02_MasterTemplete_Labor_Api"; import type { LaborFixed } from "./M02_MasterTemplete_Labor_Calc"; /** 안 이은 고정 줄 */ export const unlinkedFixes = (doc: LaborDoc): LaborFixed[] => doc.담은로직 .map((row) => row.고정) .filter( (fx): fx is LaborFixed => !!fx && !fx.비율 && !Object.values(fx.이음 ?? {}).some(Boolean), ); /** 이음 붙임 — 하나만(노임 · 자재 · 기계) */ const linkTo = (fx: LaborFixed, kind: "노임" | "자재" | "기계", code: string): void => { fx.이음 = { 노임: null, 자재: null, 기계: null, [kind]: code }; }; /** [연결] 창 — 줄마다 찾기 · 기계 · 고르면 `changed` */ function openLink(doc: LaborDoc, changed: () => void): void { openModal({ title: L("M02_GridLinkTitle"), closeLabel: L("M02_Close"), width: "960px", dialogClass: "m02-modal", mount: (body) => { const draw = (): void => { const rows = unlinkedFixes(doc).map((fx) => { const done = (kind: "노임" | "자재" | "기계", code: string): void => { linkTo(fx, kind, code); changed(); draw(); }; const find = createButton({ label: L("M02_LeftFind"), size: 24, variant: "ghost", onClick: () => openFindPicker({ layer: getActiveLayer(), owner: getActiveOwner(), title: `${fx.이름} ${fx.규격 ?? ""}`.trim(), logic: () => showToast(L("M02_GridLinkNoLogic"), "info"), element: (e) => done(e.종류 === "인력" ? "노임" : "자재", e.코드), machine: (e) => done("기계", e.코드), // 736-2 기계도 같은 창 탭 }), }); return [ fx.이름, fx.규격 ?? "", fx.단위 ?? "", el("div", { className: "ui-toolbar", children: [find] }), ]; }); body.replaceChildren( createTable( [ { label: L("M02_SangeunColName") }, { label: L("M02_LeftSpec") }, { label: L("M02_SangeunColUnit"), width: "64px" }, { label: L("M02_LeftPick"), width: "180px" }, ], rows, { density: "data", empty: L("M02_LeftZero") }, ), ); }; draw(); }, }); } /** 띠 — 안 이은 줄이 없으면 null · `edit` 있으면 [연결] */ export function unlinkedBar( doc: LaborDoc, edit?: ((qtyOnly: boolean) => void) | false, ): HTMLElement | null { const n = unlinkedFixes(doc).length; if (!n) return null; const go = edit ? [createButton({ label: L("M02_GridLink"), size: 24, onClick: () => openLink(doc, () => edit(false)) })] : []; // prettier-ignore const bar = createBanner({ tone: "warning", text: L("M02_GridUnlinked").replace("{n}", String(n)), actions: go, }); bar.dataset.laborUnlinked = String(n); return bar; }