feat(M02): 구조물 조합 일위대가 카드 = 상세 그대로 — 단가산출 로직 2행 표 + 자재목록(Labor_Detail 카드 갈래 · 순서 · 로직 추가 · 다이어그램 · 정보 칸 없음 · 빼기 · 자재 추가 그대로) · 카드 [저장] · Ctrl+S
43-4 — 줄 누름 = 넣을 값 모달 · 수량산출 칸 = 수량 모달(상세와 같은 함수) · 저장 차례 = 면적 먼저 → 일위대가 · 표 감싸개 안 가로 스크롤 · 40-2 한 줄 표(compactTable · Labor_View compact · m02-labline css) 지움 · 빼기만 있는 줄도 끝 칸 · 화면 시나리오 ui_checks/43-4. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016PSXsvyDxjNmufteN5bqmt
This commit is contained in:
@@ -170,7 +170,8 @@ export interface LogicTableData {
|
||||
export function logicTable(data: LogicTableData, on?: RowHandlers): HTMLElement {
|
||||
const wait = !data.calc && !data.fail;
|
||||
const { move, remove } = on ?? {};
|
||||
const tools = !!(move && remove);
|
||||
// 빼기만(구조물 조합 카드 · 43-4)이어도 끝 칸 — 순서 단추는 `move` 가 있을 때만
|
||||
const tools = !!(move || remove);
|
||||
const lineOf = (key: string): LaborCalcLine | undefined =>
|
||||
data.calc?.줄.find((l) => l.로직 === key);
|
||||
const trs = data.rows.map((row, i) => {
|
||||
@@ -222,14 +223,15 @@ export function logicTable(data: LogicTableData, on?: RowHandlers): HTMLElement
|
||||
qtyCell(line, data.cells, on?.qty ? () => on.qty?.(i) : null),
|
||||
el("td", { className: "m02-labrow__unit", text: unit }),
|
||||
...COSTS.map((c) => moneyCell(line?.기준?.[c], line?.반영?.[c], wait, tc(HEAD[c]))),
|
||||
...(move && remove
|
||||
...(tools
|
||||
? [
|
||||
el("td", {
|
||||
className: "m02-labrow__move",
|
||||
children: [
|
||||
small(tc("Up"), () => move(i, -1)),
|
||||
small(tc("Down"), () => move(i, 1)),
|
||||
small(tc("Remove"), () => remove(i)),
|
||||
...(move
|
||||
? [small(tc("Up"), () => move(i, -1)), small(tc("Down"), () => move(i, 1))]
|
||||
: []),
|
||||
...(remove ? [small(tc("Remove"), () => remove(i))] : []),
|
||||
],
|
||||
}),
|
||||
]
|
||||
@@ -361,115 +363,3 @@ export function matTable(data: MatTableData, on?: Omit<RowHandlers, "move">): HT
|
||||
? table(heads, trs, [])
|
||||
: el("p", { className: "m02-labrow__muted", text: tc("Labor_NoMat") });
|
||||
}
|
||||
|
||||
export interface CompactData {
|
||||
rows: LaborRow[];
|
||||
mats: LaborMat[];
|
||||
logics: Map<string, ItemLogic>;
|
||||
calc: LaborCalc | null;
|
||||
fail?: string | null;
|
||||
cells?: ReadonlyMap<string, string>;
|
||||
}
|
||||
|
||||
/** 한 줄 표(카드용 · 40-1) — 항목 · 수량산출 · 단위 · 노무비 · 재료비 · 경비 · 합계 · 금액 = 수량 반영 값 ·
|
||||
* 반영이 없으면 기준 값 흐리게(`is-base`) · 자재 줄은 같은 표 아래(재료비 · 합계만) · 맨 아래 합계 줄 */
|
||||
export function compactTable(data: CompactData): HTMLElement {
|
||||
const wait = !data.calc && !data.fail;
|
||||
const cell = (v: number | null | undefined, base: boolean, label: string): HTMLElement =>
|
||||
el("td", {
|
||||
className: `m02-labrow__num${base ? " is-base" : ""}`,
|
||||
text: wait ? "…" : v === null || v === undefined ? "—" : formatMoney(v),
|
||||
attrs: { "data-label": label, ...(base ? { title: tc("Labor_Base") } : {}) },
|
||||
});
|
||||
// 머리 글 = 사용자 글 그대로(40-1 · 항목 · 수량산출 · 단위 · 노무비 · 재료비 · 경비 · 합계)
|
||||
const heads = [
|
||||
tc("Labor_Item"),
|
||||
tc("Labor_QtyCol"),
|
||||
tc("Labor_Unit"),
|
||||
...COSTS.map((c) => tc(HEAD[c])),
|
||||
];
|
||||
const lines = data.rows.map((row) => {
|
||||
const line = data.calc?.줄.find((l) => l.로직 === row.로직);
|
||||
const money = line?.반영 ?? line?.기준;
|
||||
const base = !line?.반영 && !!line?.기준;
|
||||
const logic = data.logics.get(row.로직);
|
||||
return el("tr", {
|
||||
className: "m02-labrow__row",
|
||||
attrs: { "data-labor-logic": row.로직 },
|
||||
children: [
|
||||
el("td", {
|
||||
className: "m02-labrow__name",
|
||||
text: logic?.이름 ?? row.로직,
|
||||
attrs: { title: `${row.로직}${line?.까닭 ? ` · ${line.까닭}` : ""}` },
|
||||
}),
|
||||
el("td", {
|
||||
className: "m02-labrow__qty",
|
||||
text: qtyShort(line, line?.분모 ?? "", data.cells),
|
||||
attrs: { "data-label": tc("Labor_QtyCol") },
|
||||
}),
|
||||
el("td", { className: "m02-labrow__unit", text: logic?.결과단위 ?? "" }),
|
||||
...COSTS.map((c) => cell(money?.[c], base, tc(HEAD[c]))),
|
||||
],
|
||||
});
|
||||
});
|
||||
const mats = data.mats.map((mat) => {
|
||||
const line = data.calc?.자재.find((m) => m.코드 === mat.코드);
|
||||
const has = line?.반영 !== null && line?.반영 !== undefined;
|
||||
const v = has ? line?.반영 : line?.기준단가;
|
||||
return el("tr", {
|
||||
className: "m02-labrow__row is-mat",
|
||||
attrs: { "data-labor-mat": mat.코드 },
|
||||
children: [
|
||||
el("td", {
|
||||
className: "m02-labrow__name",
|
||||
text: mat.이름 ?? mat.코드,
|
||||
attrs: { title: [mat.코드, mat.규격].filter(Boolean).join(" · ") },
|
||||
}),
|
||||
el("td", {
|
||||
className: "m02-labrow__qty",
|
||||
text: qtyShort(line, mat.단위 ?? "", data.cells),
|
||||
attrs: { "data-label": tc("Labor_QtyCol") },
|
||||
}),
|
||||
el("td", { className: "m02-labrow__unit", text: mat.단위 ?? "" }),
|
||||
el("td", { className: "m02-labrow__num", attrs: { "data-label": tc(HEAD.노무비) } }),
|
||||
cell(v, !has && v !== null && v !== undefined, tc(HEAD.재료비)),
|
||||
el("td", { className: "m02-labrow__num", attrs: { "data-label": tc(HEAD.경비) } }),
|
||||
cell(v, !has && v !== null && v !== undefined, tc(HEAD.계)),
|
||||
],
|
||||
});
|
||||
});
|
||||
const applied = data.calc?.반영합;
|
||||
const anyApplied = !!applied && (applied.계 ?? 0) !== 0;
|
||||
const total = anyApplied ? applied : data.calc?.기준합;
|
||||
const foot =
|
||||
data.rows.length + data.mats.length
|
||||
? [
|
||||
el("tr", {
|
||||
className: "m02-labrow__sum",
|
||||
children: [
|
||||
el("td", { className: "m02-labrow__name", text: tc("Prev_Sum") }),
|
||||
el("td", { className: "m02-labrow__qty", text: "" }),
|
||||
el("td", { className: "m02-labrow__unit", text: "" }),
|
||||
...COSTS.map((c) => cell(total?.[c], !anyApplied && !!total, tc(HEAD[c]))),
|
||||
],
|
||||
}),
|
||||
]
|
||||
: [];
|
||||
return data.rows.length + data.mats.length
|
||||
? el("div", {
|
||||
className: "ui-general-block__table-wrap m02-labcompact",
|
||||
children: [
|
||||
el("table", {
|
||||
className: "ui-general-block__table m02-labline",
|
||||
children: [
|
||||
el("thead", {
|
||||
children: [el("tr", { children: heads.map((t) => el("th", { text: t })) })],
|
||||
}),
|
||||
el("tbody", { children: [...lines, ...mats] }),
|
||||
...(foot.length ? [el("tfoot", { children: foot })] : []),
|
||||
],
|
||||
}),
|
||||
],
|
||||
})
|
||||
: el("p", { className: "m02-labrow__muted", text: tc("NoLogic") });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user