Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SE9MxeXTu2uaDZ55BJowAY
105 lines
4.7 KiB
TypeScript
105 lines
4.7 KiB
TypeScript
/* =============================================================================
|
|
* B09_Estimation_UI_Tabs_Bill_Link.ts
|
|
* B09 설계내역서 연결 고르기(166-2 · 184-3) — 있는 호표(일위대가목록표 dg · 단가산출근거목록표 sg) ·
|
|
* M01 로직(새 산근 = 서버 셈 · [저장] 뒤 단가) · 로직 입력값 고치기 · 연결 풀기.
|
|
*
|
|
* 줄에 적는 일 = 부르는 쪽 `apply(ref, from)`(`…_UI_Tabs_Bill_Edit` · 저장 꼴 모름)
|
|
* 로직 고르기 · 입력값 = M02 창 재사용
|
|
* ========================================================================== */
|
|
|
|
import { showToast } from "@ui/ui_template_elements";
|
|
import { createFindList } from "@ui/ui_template_find_list";
|
|
import { openModal } from "@ui/ui_template_modal";
|
|
import { fetchLogicInputs } from "../M02_MasterTemplete/M02_MasterTemplete_Labor_Api";
|
|
import { openLaborInput } from "../M02_MasterTemplete/M02_MasterTemplete_Labor_Input";
|
|
import { openLogicPicker } from "../M02_MasterTemplete/M02_MasterTemplete_Labor_Pick";
|
|
import type { Row } from "./B09_Estimation_Calc_Base";
|
|
import type { TabContext } from "./B09_Estimation_UI_Tabs";
|
|
|
|
/** 연결 적용 — ref = null 이면 풀기 · from = 고른 호표(명칭 · 규격 · 단위 채움) */
|
|
export type ApplyRef = (ref: Row | null, from?: Row) => void;
|
|
export type Leaf = [string, () => void];
|
|
|
|
/** 있는 호표 고르기 창 — 일위대가목록표(dg) · 단가산출근거목록표(sg) */
|
|
function pickHopyo(ctx: TabContext, apply: ApplyRef, tab: "dg" | "sg"): void {
|
|
const listing: Row[] = (tab === "dg" ? ctx.sheets.daega : ctx.sheets.sg_list) || [];
|
|
if (!listing.length) return showToast("고를 호표 없음 — 연결된 구조물 조합 사본이 없음", "error");
|
|
const label = (r: Row): string => (tab === "dg" ? `대가${r.no}` : `산근 ${r.no}호표`);
|
|
openModal({
|
|
title: tab === "dg" ? "일위대가 호표 고르기" : "단가산출 호표 고르기",
|
|
closeLabel: "닫기",
|
|
mount: (body, close) => {
|
|
const finder = createFindList({ placeholder: "호표 · 명칭 · 규격 찾기" });
|
|
const find = (): void => {
|
|
const q = finder.search.value.trim().toLowerCase();
|
|
const found = listing.filter(
|
|
(r) => !q || `${label(r)} ${r.name} ${r.spec}`.toLowerCase().includes(q),
|
|
);
|
|
finder.hint.textContent = `${found.length} / ${listing.length}`;
|
|
finder.setRows(
|
|
found.map((r) => ({
|
|
key: String(r.key),
|
|
tag: label(r),
|
|
name: String(r.name || ""),
|
|
sub: String(r.spec || ""),
|
|
unit: String(r.unit || ""),
|
|
onPick: () => {
|
|
close();
|
|
apply({ tab, key: r.key }, r);
|
|
},
|
|
})),
|
|
);
|
|
};
|
|
finder.search.addEventListener("input", find);
|
|
find();
|
|
body.append(finder.root);
|
|
requestAnimationFrame(() => finder.search.focus());
|
|
},
|
|
});
|
|
}
|
|
|
|
/** M01 로직 → 입력값 창 → 연결(새 산근 · 단가는 [저장] 뒤 서버 셈) */
|
|
function askInputs(apply: ApplyRef, code: string, name: string, old?: Row): void {
|
|
fetchLogicInputs([code]).then(
|
|
(got) => {
|
|
const logic = got.로직[0] ?? null;
|
|
openLaborInput({
|
|
title: `${code} ${name}`.trim(),
|
|
logic,
|
|
values: old?.given || {},
|
|
memo: null,
|
|
rate: old?.rate ?? null,
|
|
readOnly: false,
|
|
okLabel: "연결",
|
|
notice: "새 산근 = 단가산출근거 뒤 번호 · 단가는 [저장] 뒤 서버가 셈",
|
|
done: (next) => {
|
|
const unit = String(logic?.결과단위 || "")
|
|
.replace(/^원\//, "")
|
|
.replace(/^[\d.]+/, "");
|
|
const ref = { tab: "logic", code, name, given: next.입력값, rate: next.켜쌓기율 };
|
|
apply({ ...ref, picks: old?.picks ?? null }, { name, unit });
|
|
showToast("연결함 — 새 산근 단가는 [저장] 뒤에 채워짐", "success");
|
|
},
|
|
});
|
|
},
|
|
(error: unknown) => showToast(`로직 입력을 못 읽음 — ${String(error)}`, "error"),
|
|
);
|
|
}
|
|
|
|
/** 항목 줄 연결 메뉴 — [고르기 셋, 그 밖(로직 입력값 · 연결 풀기)] · ref = 지금 연결 */
|
|
export function linkItems(ctx: TabContext, ref: Row | null, apply: ApplyRef): [Leaf[], Leaf[]] {
|
|
const more: Leaf[] = [];
|
|
if (ref?.tab === "logic")
|
|
more.push(["로직 입력값 고치기", () => askInputs(apply, ref.code, ref.name || "", ref)]);
|
|
if (ref) more.push(["연결 풀기", () => apply(null)]);
|
|
const picks: Leaf[] = [
|
|
["일위대가 호표", () => pickHopyo(ctx, apply, "dg")],
|
|
["단가산출 호표", () => pickHopyo(ctx, apply, "sg")],
|
|
[
|
|
"단가산출 로직(M01 · 새 산근)",
|
|
() => openLogicPicker((logic) => askInputs(apply, logic.키, logic.이름)),
|
|
],
|
|
];
|
|
return [picks, more];
|
|
}
|