- B01 옛 「마스터 데이터」(Z01) 단추 제거 · 「마스터 요소」 이름을 「마스터 데이터」 로
- 재료 › 시중물가 줄마다 「조달 찾기」 — 나라장터자재 + 시중물가 조달 줄을 이름·규격으로 찾아 「나라장터:<열쇠>」 연결 · 노랑 표시 · 연결 끊기
- GET /api/m01/procurement 추가 · 값 묶음(조달{…}) 확정 전이라 연결은 조달›연결 칸에 임시로 담음
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016WRFJmmhPi4exAzHgPZHMT
87 lines
3.2 KiB
TypeScript
87 lines
3.2 KiB
TypeScript
/* =============================================================================
|
|
* M01_MasterData_UI_Procure.ts
|
|
* 재료 › 시중물가 「조달 찾기」 모달 — 조달 자료를 이름·규격으로 찾아 고르면 ref 를 돌려줌
|
|
* ========================================================================== */
|
|
|
|
import { el, showToast } from "@ui/ui_template_elements";
|
|
import { t as L } from "@ui/ui_template_locale";
|
|
import { fetchProcurement, type ProcureItem } from "./M01_MasterData_Api_Fetch";
|
|
import { show } from "./M01_MasterData_UI_Cells";
|
|
|
|
const button = (text: string): HTMLButtonElement =>
|
|
el("button", { className: "m01-master__row-btn", text, attrs: { type: "button" } });
|
|
|
|
/** 고르면 `onPick(ref)` · 연결 끊기 = `onPick(null)`. */
|
|
export function openProcureModal(current: string, onPick: (ref: string | null) => void): void {
|
|
const close = (): void => back.remove();
|
|
const input = el("input", {
|
|
className: "m01-master__search",
|
|
attrs: { type: "search", placeholder: L("M01_ProcureSearch") },
|
|
});
|
|
const list = el("div", { className: "m01-procure__list" });
|
|
const cut = button(L("M01_ProcureCut"));
|
|
cut.disabled = !current;
|
|
cut.addEventListener("click", () => {
|
|
onPick(null);
|
|
close();
|
|
});
|
|
const shut = button(L("M01_ProcureClose"));
|
|
shut.addEventListener("click", close);
|
|
const box = el("div", {
|
|
className: "m01-procure__box",
|
|
children: [
|
|
el("h3", { text: L("M01_ProcureTitle") }),
|
|
el("p", { className: "m01-master__muted", text: current }),
|
|
input,
|
|
list,
|
|
el("div", { className: "m01-procure__foot", children: [cut, shut] }),
|
|
],
|
|
});
|
|
const back = el("div", { className: "m01-procure", children: [box] });
|
|
back.addEventListener("click", (e) => {
|
|
if (e.target === back) close();
|
|
});
|
|
document.body.append(back);
|
|
|
|
const paint = (items: ProcureItem[], total: number): void => {
|
|
list.replaceChildren(
|
|
...(items.length
|
|
? items.map((it) => {
|
|
const b = el("button", {
|
|
className: "m01-procure__item",
|
|
attrs: { type: "button" },
|
|
children: [
|
|
el("strong", { text: it.이름 }),
|
|
el("span", { text: `${it.규격} · ${it.단위} · ${show(it.값)}` }),
|
|
el("span", { className: "m01-master__muted", text: it.ref }),
|
|
],
|
|
});
|
|
b.addEventListener("click", () => {
|
|
onPick(it.ref);
|
|
close();
|
|
});
|
|
return b;
|
|
})
|
|
: [el("p", { className: "m01-master__empty", text: L("M01_NoRows") })]),
|
|
...(total > items.length
|
|
? [el("p", { className: "m01-master__muted", text: `${items.length} / ${total}` })]
|
|
: []),
|
|
);
|
|
};
|
|
let timer: number | undefined;
|
|
const run = async (): Promise<void> => {
|
|
try {
|
|
const r = await fetchProcurement(input.value.trim());
|
|
paint(r.items, r.total);
|
|
} catch (error) {
|
|
showToast(error instanceof Error ? error.message : L("M01_LoadFailed"), "error");
|
|
}
|
|
};
|
|
input.addEventListener("input", () => {
|
|
window.clearTimeout(timer);
|
|
timer = window.setTimeout(() => void run(), 300);
|
|
});
|
|
void run();
|
|
input.focus();
|
|
}
|