feat(M01): B01 마스터 데이터 단추 하나로 · 시중물가 「조달 찾기」 모달 · 찾기 API

- B01 옛 「마스터 데이터」(Z01) 단추 제거 · 「마스터 요소」 이름을 「마스터 데이터」 로
- 재료 › 시중물가 줄마다 「조달 찾기」 — 나라장터자재 + 시중물가 조달 줄을 이름·규격으로 찾아 「나라장터:<열쇠>」 연결 · 노랑 표시 · 연결 끊기
- GET /api/m01/procurement 추가 · 값 묶음(조달{…}) 확정 전이라 연결은 조달›연결 칸에 임시로 담음

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016WRFJmmhPi4exAzHgPZHMT
This commit is contained in:
2026-09-19 23:29:17 +09:00
co-authored by Claude Sonnet 5
parent dd120ce44b
commit f80046e4ae
9 changed files with 203 additions and 8 deletions
+27 -2
View File
@@ -5,6 +5,7 @@
import { createButton, el, showToast } from "@ui/ui_template_elements";
import { t as L } from "@ui/ui_template_locale";
import { openProcureModal } from "./M01_MasterData_UI_Procure";
import { fetchRows, type Row, type RowsPage } from "./M01_MasterData_Api_Fetch";
import {
addRow,
@@ -22,11 +23,14 @@ import {
coerce,
flatten,
isScalar,
SEP,
show,
withCell,
} from "./M01_MasterData_UI_Cells";
const SIZE = 50;
const MARKET = "재료_시중물가.json";
const LINK = `조달${SEP}연결`;
const FALLBACK: Row = { 열쇠: "", 이름: "", 규격: "", 단위: "", 값: null, 출처: "" };
/** 새 줄 바탕 — 본 줄과 같은 칸 · 글 칸은 "" · 수·값 칸은 null. */
@@ -51,9 +55,16 @@ export function renderRows(host: HTMLElement, file: string, q: string): () => vo
const adds = draft?.adds ?? [];
const cols: string[] = [];
for (const row of [...adds, ...d.rows]) {
for (const k of Object.keys(flatten(row))) if (!cols.includes(k)) cols.push(k);
for (const k of Object.keys(flatten(row))) if (k !== LINK && !cols.includes(k)) cols.push(k);
}
const head = el("tr", { children: [el("th"), ...cols.map((c) => el("th", { text: c }))] });
const market = file === MARKET;
const head = el("tr", {
children: [
el("th"),
...cols.map((c) => el("th", { text: c })),
...(market ? [el("th", { text: L("M01_ProcureCol") })] : []),
],
});
const body = el("tbody");
adds.forEach((row, i) => {
@@ -96,6 +107,20 @@ export function renderRows(host: HTMLElement, file: string, q: string): () => vo
}),
);
}
if (market) {
const link = String(now[LINK] ?? "");
const pick = (ref: string | null): void =>
editRow(file, d.version, key, row, withCell(cur, LINK, ref));
const btn = el("button", {
className: "m01-master__row-btn",
text: L("M01_ProcureFind"),
attrs: { type: "button" },
});
btn.addEventListener("click", () => openProcureModal(link, pick));
const td = buildCell(link, { changed: link !== String(orig[LINK] ?? "") });
td.append(btn);
tr.append(td);
}
body.append(tr);
}