feat(z01): 좌측을 둘로 가름 — ①기초단가 다섯(얼마인가 · 시장이 정함) ②품셈 기준 아홉(얼마나 드나 · 품셈이 해마다 한 번 · 토량환산·자재할증·거푸집·철근·목구조·돌쌓기 경사·뒷길이·돌종류·갈래) · 축 칸 잠금·구간 이름은 서버가 준 대로 그대로(사용자 ①② 지시)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016VBGFXB9AbJBwXP19z75Qq
This commit is contained in:
2026-09-16 14:03:03 +09:00
co-authored by Claude Opus 5
parent ede97d30fb
commit 566e0c885e
3 changed files with 62 additions and 21 deletions
+32 -19
View File
@@ -15,9 +15,11 @@ import {
fetchMasterRows,
fetchOverrides,
type MasterGroup,
type BasePriceKind,
type MasterRows,
type RowsQuery,
saveBasePrice,
SPEC_KINDS,
VALUES_TABLE_ID,
} from "./Z01_MasterData_Api_Fetch";
import { valueWithUnit, type OverrideState } from "./Z01_MasterData_UI_Cells";
@@ -31,25 +33,32 @@ export function buildSidePanel(groups: MasterGroup[], view: RowsView): HTMLEleme
};
const baseTitle = L("Z01_MasterData_BasePrices");
const baseGrid = el("div", { className: "z01-master__base-grid" });
for (const kind of BASE_PRICE_KINDS) {
const label = L(`Z01_MasterData_Base_${kind}` as const);
const button = el("button", {
className: "z01-master__base",
attrs: { type: "button" },
text: label,
});
button.addEventListener("click", () => {
activate(button);
view.show({
title: `${baseTitle} › ${label}`,
key: `base-prices/${kind}`,
load: (query) => fetchBasePrices(kind, query),
save: (rowId, values) => saveBasePrice(kind, rowId, values),
const specTitle = L("Z01_MasterData_SpecValues");
/** 한 상자 몫 단추들 — ①얼마인가 ②얼마나 드나 로 갈라 세움(성격도 갱신 주기도 다름). */
const kindGrid = (boxTitle: string, kinds: readonly BasePriceKind[]): HTMLElement => {
const grid = el("div", { className: "z01-master__base-grid" });
for (const kind of kinds) {
const label = L(`Z01_MasterData_Base_${kind}` as const);
const button = el("button", {
className: "z01-master__base",
attrs: { type: "button" },
text: label,
});
});
baseGrid.append(button);
}
button.addEventListener("click", () => {
activate(button);
view.show({
title: `${boxTitle} › ${label}`,
key: `base-prices/${kind}`,
load: (query) => fetchBasePrices(kind, query),
save: (rowId, values) => saveBasePrice(kind, rowId, values),
});
});
grid.append(button);
}
return grid;
};
const baseGrid = kindGrid(baseTitle, BASE_PRICE_KINDS);
const specGrid = kindGrid(specTitle, SPEC_KINDS);
const overridesButton = el("button", {
className: "z01-master__base z01-master__base--wide",
attrs: { type: "button" },
@@ -113,7 +122,11 @@ export function buildSidePanel(groups: MasterGroup[], view: RowsView): HTMLEleme
tree.append(groupBox);
}
panel.append(section(baseTitle, baseGrid), section(L("Z01_MasterData_Tree"), tree));
panel.append(
section(baseTitle, baseGrid),
section(specTitle, specGrid),
section(L("Z01_MasterData_Tree"), tree),
);
attachCollapsible(panel);
return panel;
}