feat(729-3): 불러오기 마법사 안 이은 줄 고르기 · [끝내기] 막음 · 단가산출 단계 · 일위대가표 띠 · 목록 열
- 새 Hopyo_Left: 안 만든 호표마다 /hopyo-unlinked 남은 줄 표 · 줄마다 고름(고르기 창 · 찾기 = 기초 · 노임 · 자재 · 기계 EQ · % 밑수 · 우리에 없음 · 고름 대기 후보 → SK 만들기) = 확인 창 캐시 → [저장] · 생성 몸 그대로
- 마법사: 단가산출 칸(새 Hopyo_WizardSk — 기초 · SK 차이 있음 갈래 표 · 고름 대기 후보 고름 → 고른 기초로 만들기 · 별칭 제안 + M01 별칭 장부 링크) · 안 이은 줄 띠 · [끝내기] = 다시 셈 → 남으면 막음 + 표
- 확인 창 · 엑셀 보기 창: 만들기 409 {까닭, 남은줄} → 고름 표 · [고르기 (n)] · 대상 꼴 노임 · 기계 · 비율 · % 줄 밑수 고른 것만 체크
- Api_Fetch StaleError.detail(409 몸) · 까닭 글
- 새 Labor_Unlinked: 일위대가표 「M01 연결 없음 n 줄(옛 자료)」 띠 · [연결] = 고정 줄 이음(노임 · 자재 · 기계)만 · 목록 열 「안 이은 줄」
- 시험: 새 test_729_3_hopyo_left_screen(409 → 남은 줄 · 만든 호표 안 물음 · 고름 → 몸 · 0 · 띠 줄 · 소스) · 낡은 시험 고침 — test_m02_hopyo_screen(마법사 /sangeun 부름이 단가산출 칸으로 옮김) · 헬퍼 셋(새 Hopyo_Left 를 대역 — DOM · 찾기 창)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
/* =============================================================================
|
||||
* M02_MasterTemplete_Labor_Unlinked.ts
|
||||
* 일위대가표 안 이은 줄 띠 · [연결](PLAN 729-3 · 요구서 내역19 1장 8 · 분석 19-B D-2) —
|
||||
* · 안 이은 줄 = 고정 줄 중 비율 줄 아님 · 이음(노임 · 자재 · 기계) 모두 빈 것(서버 목록 summary `안이은줄` 과 같은 규칙)
|
||||
* · 띠 = 「M01 연결 없음 n 줄(옛 자료)」 · 고칠 수 있으면 [연결] → 줄마다 [찾기](노임 LB · 자재 MT · 721 찾아 넣기 창) ·
|
||||
* [기계](M01 기계 EQ) — 고정 줄 이름 · 규격 · 엑셀 숫자(출처)는 그대로 · 이음만 붙임 → 상세 고침(저장은 [저장])
|
||||
* 계산은 서버(이음 = 단가 책 값) — 화면은 고름만.
|
||||
* ========================================================================== */
|
||||
|
||||
import { createBanner } from "@ui/ui_template_banner";
|
||||
import { createButton, el, showToast } from "@ui/ui_template_elements";
|
||||
import { t as L } from "@ui/ui_template_locale";
|
||||
import { openModal } from "@ui/ui_template_modal";
|
||||
import { createTable } from "@ui/ui_template_table";
|
||||
import { getActiveLayer, getActiveOwner } from "./M02_MasterTemplete_Api_Fetch";
|
||||
import { openFindPicker } from "./M02_MasterTemplete_Find_Pick";
|
||||
import { pickMachine } from "./M02_MasterTemplete_Hopyo_Left";
|
||||
import type { LaborDoc } from "./M02_MasterTemplete_Labor_Api";
|
||||
import type { LaborFixed } from "./M02_MasterTemplete_Labor_Calc";
|
||||
|
||||
/** 안 이은 고정 줄 */
|
||||
export const unlinkedFixes = (doc: LaborDoc): LaborFixed[] =>
|
||||
doc.담은로직
|
||||
.map((row) => row.고정)
|
||||
.filter(
|
||||
(fx): fx is LaborFixed => !!fx && !fx.비율 && !Object.values(fx.이음 ?? {}).some(Boolean),
|
||||
);
|
||||
|
||||
/** 이음 붙임 — 하나만(노임 · 자재 · 기계) */
|
||||
const linkTo = (fx: LaborFixed, kind: "노임" | "자재" | "기계", code: string): void => {
|
||||
fx.이음 = { 노임: null, 자재: null, 기계: null, [kind]: code };
|
||||
};
|
||||
|
||||
/** [연결] 창 — 줄마다 찾기 · 기계 · 고르면 `changed` */
|
||||
function openLink(doc: LaborDoc, changed: () => void): void {
|
||||
openModal({
|
||||
title: L("M02_GridLinkTitle"),
|
||||
closeLabel: L("M02_Close"),
|
||||
width: "960px",
|
||||
dialogClass: "m02-modal",
|
||||
mount: (body) => {
|
||||
const draw = (): void => {
|
||||
const rows = unlinkedFixes(doc).map((fx) => {
|
||||
const done = (kind: "노임" | "자재" | "기계", code: string): void => {
|
||||
linkTo(fx, kind, code);
|
||||
changed();
|
||||
draw();
|
||||
};
|
||||
const find = createButton({
|
||||
label: L("M02_LeftFind"),
|
||||
size: 24,
|
||||
variant: "ghost",
|
||||
onClick: () =>
|
||||
openFindPicker({
|
||||
layer: getActiveLayer(),
|
||||
owner: getActiveOwner(),
|
||||
title: `${fx.이름} ${fx.규격 ?? ""}`.trim(),
|
||||
logic: () => showToast(L("M02_GridLinkNoLogic"), "info"),
|
||||
element: (e) => done(e.종류 === "인력" ? "노임" : "자재", e.코드),
|
||||
}),
|
||||
});
|
||||
const machine = createButton({
|
||||
label: L("M02_LeftMachine"),
|
||||
size: 24,
|
||||
variant: "ghost",
|
||||
onClick: () => pickMachine(fx, (code) => done("기계", code)),
|
||||
});
|
||||
return [
|
||||
fx.이름,
|
||||
fx.규격 ?? "",
|
||||
fx.단위 ?? "",
|
||||
el("div", { className: "ui-toolbar", children: [find, machine] }),
|
||||
];
|
||||
});
|
||||
body.replaceChildren(
|
||||
createTable(
|
||||
[
|
||||
{ label: L("M02_SangeunColName") },
|
||||
{ label: L("M02_LeftSpec") },
|
||||
{ label: L("M02_SangeunColUnit"), width: "64px" },
|
||||
{ label: L("M02_LeftPick"), width: "180px" },
|
||||
],
|
||||
rows,
|
||||
{ density: "data", empty: L("M02_LeftZero") },
|
||||
),
|
||||
);
|
||||
};
|
||||
draw();
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/** 띠 — 안 이은 줄이 없으면 null · `edit` 있으면 [연결] */
|
||||
export function unlinkedBar(
|
||||
doc: LaborDoc,
|
||||
edit?: ((qtyOnly: boolean) => void) | false,
|
||||
): HTMLElement | null {
|
||||
const n = unlinkedFixes(doc).length;
|
||||
if (!n) return null;
|
||||
const go = edit
|
||||
? [createButton({ label: L("M02_GridLink"), size: 24, onClick: () => openLink(doc, () => edit(false)) })]
|
||||
: []; // prettier-ignore
|
||||
const bar = createBanner({
|
||||
tone: "warning",
|
||||
text: L("M02_GridUnlinked").replace("{n}", String(n)),
|
||||
actions: go,
|
||||
});
|
||||
bar.dataset.laborUnlinked = String(n);
|
||||
return bar;
|
||||
}
|
||||
Reference in New Issue
Block a user