/* ============================================================================= * M02_Material_Pick.ts * M01 자재 하나 고르기 창 — 이름 · 규격 · 코드 낱말로 찾아 하나 고름(일위대가 자재목록 · 자재 추가가 씀). * 모양(`m02-pick*`)은 `M02_MasterTemplete_Structure.css`. * ========================================================================== */ import { createInputField, el, showToast } from "@ui/ui_template_elements"; import { openModal } from "@ui/ui_template_modal"; import { searchMaterials } from "../M01_MasterData/M01_MasterData_Api_Fetch"; /** 고른 자재 한 줄 — M01 자재(키 `MT`) */ export interface MaterialItem { 코드: string; 이름: string | null; 규격: string | null; 단위: string | null; } const TEXT = { pickTitle: "자재 추가", pickClose: "닫기", search: "자재 이름 · 규격 · 코드", searching: "찾는 중…", noMatch: "맞는 자재 없음", searchFailed: "자재 목록을 못 받음", }; /** 자재 고르기 창 — 고르면 `done` 부르고 닫음 */ export function pickMaterial(done: (item: MaterialItem) => void): void { openModal({ title: TEXT.pickTitle, closeLabel: TEXT.pickClose, dialogClass: "m02-modal m02-pick", mount: (body, close) => { const search = createInputField({ placeholder: TEXT.search, type: "search" }); const list = el("div", { className: "m02-pick__list" }); let seq = 0; const paint = async (): Promise => { const mine = ++seq; list.replaceChildren(el("p", { className: "m02-struct__empty", text: TEXT.searching })); try { const hits = await searchMaterials(search.input.value.trim()); if (mine !== seq) return; list.replaceChildren( ...(hits.length ? hits.map((m) => { const row = el("button", { className: "m02-pick__item", attrs: { type: "button", "data-material": m.코드 }, children: [ el("span", { className: "m02-pick__key", text: m.코드 }), `${m.이름} ${m.규격} ${m.단위}`.replace(/\s+/g, " "), ], }); row.addEventListener("click", () => { done(m); close(); }); return row; }) : [el("p", { className: "m02-struct__empty", text: TEXT.noMatch })]), ); } catch { if (mine === seq) showToast(TEXT.searchFailed, "error"); } }; let timer = 0; search.input.addEventListener("input", () => { window.clearTimeout(timer); timer = window.setTimeout(() => void paint(), 250); }); body.append(search.root, list); void paint(); search.input.focus(); }, }); }