- 수량 칸(요구 701-1) = 늘 식 글 칸(Q_특별인부) + 출처 꼬리표(표 = 표 고르기) · 눌러도 안 바뀜 · 표 값 기호에 수 = 그 값만(직접 입력) · 꼬리표 한 곳(sourceTag) - 글꼴(701-2) = 줄 쌓기 화면이 정함(14px · M02 가 부모 16px 을 받던 것) - M02 머리(701-3) = [초기화] 와 [되돌림] 뜻 다름 → [초기화] 이름 「M01 값으로」 · [단가 갱신][재생성] = 보기 고르기 옆 머리 칸(수식 보기만) - 일위대가 단가산출 줄 모달(701-5) = 페이지 머리와 같음(보기 고르기 · [단가 갱신] · [재생성] · [저장]) - 일위대가 로직 줄 모달(701-4 · 5) = 옛 [옵션] · [단가산출로도 저장] · [항목 추가] · [율 줄 추가] 걷음 · 보기 고르기 없이 상세만 + 안내(온 단가산출) · 줄 문서 키 SK-000000 이 수식 문서를 읽어 404 · 「못 읽음」 이던 것 고침 - 시험: test_804_7 낡은 소스 기대(꼬리표 조건 글) 고침 + 808-1 · test_806_1 808-1 모달 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
102 lines
4.3 KiB
TypeScript
102 lines
4.3 KiB
TypeScript
/* =============================================================================
|
|
* M02_MasterTemplete_Labor_RowSk.ts
|
|
* 일위대가 줄 모달 안 단가산출 상세 = 717-2b 단가산출(SK) 상세 「줄 모드」(PLAN 723-3 · 정함 4 · 5).
|
|
* · 줄 → 이름 없는 SK 문서(`lineDoc` · 고름 · 자재표시 = 바탕 줄 정체 cid) → `mountSangeunDetail` 그대로 얹음
|
|
* (보기 넷 · 공용 상세(724-1 `LogicLab_Ho`) 줄 모달 품 · 단가 덮개 · 줄 빼기 · 더하기 · 박스 옵션 · 입력 칩)
|
|
* · `take()` = [적용] 때 그 줄에 남길 것 — 패치 `{덮개, 뺀줄, 더한줄}`(M02 변경 항목 · M01 안 바뀜 · 내역 17-2) +
|
|
* 옵션(시험 입력 → 그 줄 `입력값` · 정함 5)
|
|
* · 옛 [단가산출로도 저장] 걷음(808-1 · 요구 701-4 — 일위대가 줄은 단가산출을 담아서만)
|
|
* ========================================================================== */
|
|
|
|
import { el } from "@ui/ui_template_elements";
|
|
import { createText } from "@ui/ui_template_text";
|
|
import { fetchAuto } from "../M01_MasterData/M01_MasterData_UI_Logic_Api";
|
|
import type { LaborRow } from "./M02_MasterTemplete_Labor_Api";
|
|
import { calcSangeun, type SkScope } from "./M02_MasterTemplete_Sangeun_Cover";
|
|
import { mountSangeunDetail } from "./M02_MasterTemplete_Sangeun_Detail";
|
|
import { cleanPatch, lineDoc, needsIds, type LinePatch } from "./logic/M02_Sangeun_Cover_Model";
|
|
|
|
export interface RowSkHandle {
|
|
/** 고친 것(패치 · 옵션) — 없으면 null */
|
|
take: () => { patch: LinePatch | null; values: Record<string, string> } | null;
|
|
destroy: () => void;
|
|
}
|
|
|
|
const same = (a: unknown, b: unknown): boolean => JSON.stringify(a) === JSON.stringify(b);
|
|
|
|
/** 줄 모드 SK 상세를 `host` 에 — 바탕 줄 정체가 필요하면 먼저 셈 */
|
|
export function mountRowSk(
|
|
host: HTMLElement,
|
|
o: {
|
|
row: LaborRow;
|
|
scope: SkScope;
|
|
title: string;
|
|
unit: string;
|
|
readOnly: boolean;
|
|
/** 모달 머리 칸(808-1) — 보기 고르기 · 수식 단추(옛 [항목 추가] · [율 줄 추가] 줄 없음) */
|
|
slot?: HTMLElement;
|
|
},
|
|
): RowSkHandle {
|
|
let handle: ReturnType<typeof mountSangeunDetail> | null = null;
|
|
let alive = true;
|
|
/** 자동값(상세가 빈 입력에 채움) — 손대지 않은 자동값은 줄에 안 남김(빈 값 = 자동값 그대로) */
|
|
let auto: Record<string, unknown> = {};
|
|
const before = cleanPatch(o.row.패치);
|
|
const values0 = Object.fromEntries(
|
|
Object.entries(o.row.입력값 ?? {}).map(([k, v]) => [k, String(v)]),
|
|
);
|
|
host.replaceChildren(createText("…", "muted"));
|
|
void (async () => {
|
|
let ids: string[] | null = null;
|
|
try {
|
|
if (needsIds(o.row))
|
|
ids = (await calcSangeun(o.scope, lineDoc(o.row, null, null))).정체 ?? null;
|
|
} catch {
|
|
ids = null; // 정체 못 받음 = 고름 · 자재표시 없이(셈 까닭은 상세가 보임)
|
|
}
|
|
if (!alive) return;
|
|
const doc = {
|
|
...lineDoc(o.row, ids, before),
|
|
...(before?.뺀더한줄 ? { 뺀더한줄: before.뺀더한줄 } : {}), // 되살림 기억(744-1 · 셈엔 안 듦)
|
|
이름: o.title,
|
|
단위: o.unit || "식",
|
|
};
|
|
const box = el("div", { attrs: { "data-row-sk": "" } });
|
|
host.replaceChildren(box);
|
|
handle = mountSangeunDetail(box, doc, {
|
|
layer: o.scope.layer,
|
|
owner: o.scope.owner,
|
|
readOnly: o.readOnly,
|
|
onChanged: () => undefined,
|
|
slot: o.slot,
|
|
});
|
|
if (o.row.로직 && !o.row.참조) auto = await fetchAuto(o.row.로직).catch(() => ({}));
|
|
})();
|
|
return {
|
|
take: () => {
|
|
if (!handle) return null;
|
|
const d = handle.getDoc();
|
|
const patch = cleanPatch({
|
|
덮개: d.덮개 as LinePatch["덮개"],
|
|
뺀줄: d.뺀줄,
|
|
더한줄: d.더한줄,
|
|
뺀더한줄: d.뺀더한줄,
|
|
});
|
|
const values = o.row.참조
|
|
? values0
|
|
: Object.fromEntries(
|
|
Object.entries(handle.getValues()).filter(
|
|
([k, v]) =>
|
|
String(v).trim() !== "" &&
|
|
(k in values0 || auto[k] == null || String(auto[k]) !== String(v)),
|
|
),
|
|
);
|
|
return same(patch, before) && same(values, values0) ? null : { patch, values };
|
|
},
|
|
destroy: () => {
|
|
alive = false;
|
|
handle?.destroy();
|
|
},
|
|
};
|
|
}
|