feat(z01): 마스터 화면에 공종 축 산림·건설 상자 — base-prices 목록·한 표가 공종 축 둘을 포함 · 거르기 인자 · WorkItems 읽기 모듈 신설
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -26,6 +26,8 @@ export function columnTitle(column: MasterColumn): string {
|
||||
export function cellText(value: unknown, unit?: string | null): string {
|
||||
if (value === null || value === undefined) return "";
|
||||
if (typeof value === "boolean") return value ? "예" : "아니오";
|
||||
// 목록 칸(갈래 키 · 딸린 품셈 표) — 괄호·따옴표 없이 쉼표로 · 빈 목록은 빈칸.
|
||||
if (Array.isArray(value)) return value.map((each) => cellText(each, unit)).join(", ");
|
||||
if (typeof value === "number" && unit) {
|
||||
return value.toLocaleString("ko-KR", { maximumFractionDigits: 10 });
|
||||
}
|
||||
@@ -88,18 +90,22 @@ export function outdatedBanner(sources?: TableSource[]): string[] {
|
||||
/** 서버가 주는 표 한 벌 — 갈래·kind·한글 이름·줄 수. 화면은 제 목록을 안 가짐(늘면 저절로 섬). */
|
||||
export interface ServedKind {
|
||||
group: string;
|
||||
/** 갈래 한글 이름(이름표 `base_price_groups`) — 안 오면 group 키가 그대로 떠 빠진 것이 드러남 */
|
||||
group_label?: string;
|
||||
kind: string;
|
||||
label: string;
|
||||
rows: number;
|
||||
}
|
||||
|
||||
type KindBox = { group: string; label: string; items: ServedKind[] };
|
||||
|
||||
/** 받은 차례 그대로 갈래별로 묶음 — 갈래 차례도 서버가 낸 순서를 따름. */
|
||||
export function groupKinds(kinds: ServedKind[]): { group: string; items: ServedKind[] }[] {
|
||||
const boxes: { group: string; items: ServedKind[] }[] = [];
|
||||
export function groupKinds(kinds: ServedKind[]): KindBox[] {
|
||||
const boxes: KindBox[] = [];
|
||||
for (const kind of kinds) {
|
||||
const box = boxes.find((each) => each.group === kind.group);
|
||||
if (box) box.items.push(kind);
|
||||
else boxes.push({ group: kind.group, items: [kind] });
|
||||
else boxes.push({ group: kind.group, label: kind.group_label ?? kind.group, items: [kind] });
|
||||
}
|
||||
return boxes;
|
||||
}
|
||||
@@ -130,8 +136,26 @@ export function boldSegments(text: string): { text: string; bold: boolean }[] {
|
||||
.filter((part) => part.text !== "");
|
||||
}
|
||||
|
||||
/**
|
||||
* 서버가 주는 거르기 한 벌(건설품셈 「임도가 쓰는 것」 따위) — 이름·선택지·줄 수·기본값 모두 서버 것.
|
||||
* 어느 줄을 거를지도 서버가 판정함 — 화면은 고른 값을 `key=value` 로 보내기만(2026-09-17 브레인).
|
||||
*/
|
||||
export interface TableFilter {
|
||||
key: string;
|
||||
label: string;
|
||||
options: { value: string; label: string; rows?: number }[];
|
||||
/** 값을 안 보냈을 때 서버가 쓴 선택지 — 화면이 이것을 보여야 보이는 것과 걸린 것이 같음 */
|
||||
default: string;
|
||||
}
|
||||
|
||||
/** 거르기 상자에 보일 값 — 사람이 고른 것 · 안 골랐으면 서버가 이미 건 기본값. */
|
||||
export function filterValue(filter: TableFilter, picked: Record<string, string>): string {
|
||||
return picked[filter.key] ?? filter.default;
|
||||
}
|
||||
|
||||
/** 기초단가 표 머리 — 열 하나에 한 문장이라 표에 한 번만 옴(2026-09-15 브레인 ④). */
|
||||
export interface TableMeta {
|
||||
filters?: TableFilter[];
|
||||
/** 한 표가 모은 원본마다 한 줄 */
|
||||
source?: TableSource[];
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user