Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015sDZSjFvoiDjdGpgj3muc3
79 lines
2.9 KiB
TypeScript
79 lines
2.9 KiB
TypeScript
/* =============================================================================
|
|
* M02_MasterTemplete_Labor_MatMarks.ts
|
|
* 자재목록 세 칸(148-4) — 자재구분(일반 · 관급 · 사급) · 별도계상(별도계상 · 직접계산) · 운반비(포함 · 미포함)
|
|
* · 고칠 수 있으면 드롭다운(처음 값 빈 「—」 · 줄 누름과 따로) · 아니면 글 · 금액 무관
|
|
* · 사용자 자재 = 줄 덧칸 · 로직 자재 = 로직 줄 `자재표시 {호표 차례: 세 칸}`(`Labor_Api` 정리 · 서버 `clean`)
|
|
* ========================================================================== */
|
|
|
|
import { createSelectField, el } from "@ui/ui_template_elements";
|
|
import {
|
|
MAT_MARKS,
|
|
type LaborRow,
|
|
type MatMarkKey,
|
|
type MatMarks,
|
|
} from "./M02_MasterTemplete_Labor_Api";
|
|
import { tc, type ComboTextKey } from "./M02_MasterTemplete_Labor_Text";
|
|
|
|
const HEAD: Record<MatMarkKey, ComboTextKey> = {
|
|
자재구분: "Mark_Kind",
|
|
별도계상: "Mark_Separate",
|
|
운반비: "Mark_Haul",
|
|
};
|
|
/** 선택지 글(저장 값은 한국어 그대로) */
|
|
const WORD: Record<string, ComboTextKey> = {
|
|
일반: "Mark_General",
|
|
관급: "Mark_Gov",
|
|
사급: "Mark_Private",
|
|
별도계상: "Mark_Separate",
|
|
직접계산: "Mark_Direct",
|
|
포함: "Mark_In",
|
|
미포함: "Mark_Out",
|
|
};
|
|
const KEYS = Object.keys(MAT_MARKS) as MatMarkKey[];
|
|
|
|
export const markHeads = (): string[] => KEYS.map((k) => tc(HEAD[k]));
|
|
|
|
/** 세 칸 — `set` 없으면 글만(빈 = 「—」) */
|
|
export function markCells(
|
|
value: MatMarks,
|
|
set?: (key: MatMarkKey, v: string) => void,
|
|
): HTMLElement[] {
|
|
return KEYS.map((key) => {
|
|
const now = value[key] ?? "";
|
|
const attrs = { "data-label": tc(HEAD[key]), "data-mat-mark": key };
|
|
if (!set)
|
|
return el("td", {
|
|
className: "m02-labrow__mark",
|
|
text: now ? tc(WORD[now]) : "—",
|
|
attrs,
|
|
});
|
|
const pick = createSelectField({
|
|
options: [
|
|
{ value: "", text: "—" },
|
|
...MAT_MARKS[key].map((v) => ({ value: v, text: tc(WORD[v]) })),
|
|
],
|
|
value: now,
|
|
compact: true,
|
|
ariaLabel: tc(HEAD[key]),
|
|
onChange: (v) => set(key, v),
|
|
});
|
|
pick.root.addEventListener("click", (e) => e.stopPropagation()); // 줄 누름과 따로
|
|
return el("td", { className: "m02-labrow__mark", attrs, children: [pick.root] });
|
|
});
|
|
}
|
|
|
|
/** 한 칸 바꿈 — 빈 값 = 칸 지움 */
|
|
export function setMark(target: MatMarks, key: MatMarkKey, v: string): void {
|
|
if (v) (target as Record<string, string>)[key] = v;
|
|
else delete target[key];
|
|
}
|
|
|
|
/** 로직 줄 `자재표시` 한 차례 한 칸 — 빈 차례 · 빈 묶음은 뺌 */
|
|
export function setLogicMark(row: LaborRow, at: number, key: MatMarkKey, v: string): void {
|
|
const all = (row.자재표시 ??= {});
|
|
const one = (all[String(at)] ??= {});
|
|
setMark(one, key, v);
|
|
if (!Object.keys(one).length) delete all[String(at)];
|
|
if (!Object.keys(all).length) delete row.자재표시;
|
|
}
|