/* ============================================================================= * M02_MasterTemplete_Labor_QtyModal.ts * 일위대가 수량산출 모달(43-1) — 수량산출 칸 누름(로직 줄 · 자재 줄 같음) = 모달 하나. * · 위 = 지금 수량(손 · 칸 · —) · 손 입력 칸 · [연결 풀기] * · 아래 = 그 열 면적산출 시트를 모달 안에 바로(읽기만 · 실제 값 · 이은 칸 색 · `mountAreaSheet`) · * 칸 누름 = 그 칸을 고름(함께 잇기 · 바꾸기 물음 그대로) * · [확인] = 손 값이 있으면 손 · 아니면 고른 칸으로 잇기 · 풀기 · [닫기] = 그대로 * 잇기 · 풀기는 화면 문서만(저장은 일위대가 [저장] 때 면적 문서와 함께 · `Labor_Detail`). * ========================================================================== */ import { createButton, el, showToast } from "@ui/ui_template_elements"; import { openModal } from "@ui/ui_template_modal"; import type { Workbook } from "../A00_Common/spreadsheet/spreadsheet"; import type { Layer } from "./M02_MasterTemplete_Api_Fetch"; import { mountAreaSheet, type AreaCellPick } from "./M02_MasterTemplete_AreaCellPick"; import type { GoArea } from "./M02_MasterTemplete_Labor_Input"; import { tc } from "./M02_MasterTemplete_Labor_Text"; import "./M02_Labor_Values.css"; import "./M02_MasterTemplete_Labor.css"; /** 모달 답 — 손 · 칸 따름(손 지움) · 고른 칸으로 잇기 · 연결 풀기 · 그대로 */ export type QtyResult = | { kind: "hand"; 손: number } | { kind: "follow" } | { kind: "cell"; pick: AreaCellPick } | { kind: "unlink" } | { kind: "keep" }; export interface QtyModalOptions { /** 「GF000219 돌쌓기 메쌓기(인력)」 */ title: string; /** 지금 수량 글(「손 5 ㎥」 · 「B6 = 12.5」 · 「—」) */ now: string; /** 지금 칸에 이어져 있나 — [연결 풀기] */ linked: boolean; /** 지금 손 값(없으면 null) */ hand: number | null; /** 손 입력 단위(분모 · 자재 단위) */ unit: string; readOnly: boolean; /** 그 열 면적산출 — `pill` 이 없으면(계산 전) 시트 대신 안내 */ sheet: { doc: Workbook | null; layer: Layer; column: string; pill: string | null }; /** [면적산출 상세로] — 없으면 단추 없음 */ goArea: GoArea | null; /** 손 입력만(서고 사전조합 줄 · 51-6) — 면적산출 시트 없음 */ handOnly?: boolean; done: (result: QtyResult) => void; } export function openQtyModal(opt: QtyModalOptions): void { let pending: QtyResult = { kind: "keep" }; let sheet: { destroy: () => void } | null = null; openModal({ title: `${tc("Labor_QtyCol")} — ${opt.title}`, closeLabel: tc("In_Close"), dialogClass: "m02-modal m02-labin m02-labqty", beforeClose: () => (sheet?.destroy(), true), mount: (body, closeNow) => { const finish = (): void => { sheet?.destroy(); closeNow(); }; const now = el("span", { className: "m02-labqty__now", text: opt.now, attrs: { "data-labor-qty-now": "" }, }); const state = el("small", { className: "m02-labin__muted", attrs: { "data-labor-qty-state": "" }, }); const hand = el("input", { className: "ui-input m02-inputval__control", attrs: { type: "number", step: "any", "data-labor-qty": "hand", "aria-label": tc("In_QtyHand"), }, }) as HTMLInputElement; hand.readOnly = opt.readOnly; if (opt.hand !== null) hand.value = String(opt.hand); const unlink = opt.linked && !opt.readOnly ? createButton({ label: tc("Labor_Unlink"), variant: "ghost", onClick: () => { pending = { kind: "unlink" }; hand.value = ""; state.textContent = tc("Labor_UnlinkPending"); }, }) : null; const go = opt.goArea ? createButton({ label: tc("In_QtyGoArea"), variant: "ghost", onClick: () => void opt.goArea?.().then((moved) => { if (moved) finish(); }), }) : null; const host = el("div", { className: "m02-cellpick__sheet", attrs: { "data-labor-qty-sheet": "" }, }); if (opt.handOnly) { // 시트 없음 } else if (opt.sheet.pill) { sheet = mountAreaSheet(host, { doc: opt.sheet.doc, layer: opt.sheet.layer, column: opt.sheet.column, pill: opt.sheet.pill, onPick: (pick) => { if (opt.readOnly) return; pending = { kind: "cell", pick }; hand.value = ""; // 칸을 고르면 손 값은 지움(칸을 따름) state.textContent = tc("Labor_CellPending").replace("{value}", pick.칸); }, }); } else host.replaceChildren( el("p", { className: "m02-labin__muted", text: tc("Labor_PickWait") }), ); hand.addEventListener("input", () => { if (hand.value.trim() !== "") state.textContent = ""; }); const ok = (): void => { const raw = hand.value.trim(); if (raw !== "") { const v = Number(raw); if (!Number.isFinite(v)) return showToast(tc("In_QtyNeed"), "error"); opt.done({ kind: "hand", 손: v }); } else if (pending.kind !== "keep") opt.done(pending); else if (opt.hand !== null) opt.done({ kind: "follow" }); // 손 값을 지움 = 칸을 따름 finish(); }; body.append( el("div", { className: "m02-labqty__head", children: [ el("span", { className: "m02-inputval__name", text: tc("Labor_QtyNow") }), now, el("label", { className: "m02-labin__qty-line", children: [ el("span", { text: tc("In_QtyHand") }), hand, el("small", { text: opt.unit }), ], }), ...(unlink ? [unlink] : []), ...(go ? [go] : []), ], }), state, ...(opt.handOnly ? [] : [el("p", { className: "m02-cellpick__hint", text: tc("Labor_SheetHint") }), host]), el("div", { className: "m02-labin__foot", children: opt.readOnly ? [createButton({ label: tc("In_Close"), variant: "ghost", onClick: finish })] : [ createButton({ label: tc("In_Close"), variant: "ghost", onClick: finish }), createButton({ label: tc("In_Ok"), variant: "filled", onClick: ok }), ], }), ); }, }); }