Files
Aislo/M02_MasterTemplete/M02_Material_Pick.ts
T

78 lines
2.9 KiB
TypeScript

/* =============================================================================
* 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<void> => {
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();
},
});
}