refactor(717-3): 일위대가 상세 · 줄 표 나눔 — 자재목록 표(Labor_MatTable) · 서고 구분 고르기(Labor_LibMeta) 떼어 냄 · 동작 같음

- Labor_Rows 671 → 566 줄 · Labor_Detail 700 → 650 줄(717-3 모달 단추 자리)
- 낡은 시험 셋 고침: mat_marks · precombo_class = 옮긴 파일을 읽음 · hopyo_screen 의 Detail 「꼭 700 줄」 = 「700 줄 넘지 않음」(나눔으로 줄어듦)
- 시험 158 통과 · 1 실패(test_175 B09 겹 대가 = Store_Combo._PER 없음 · 나눔 전부터 · 719-2 몫)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-11-01 16:32:32 +09:00
co-authored by Claude Opus 5.5
parent 1765901ad2
commit f8338194c6
8 changed files with 199 additions and 172 deletions
@@ -16,13 +16,7 @@
* · 맨 위 엑셀 꼴 격자(704-3 · `Labor_Grid`) · 읽기만 카드는 격자만 · 규격 표(704-4 · `Labor_Spec`)
* ========================================================================== */
import {
createButton,
createInputField,
createSelectField,
el,
showToast,
} from "@ui/ui_template_elements";
import { createButton, createInputField, el, showToast } from "@ui/ui_template_elements";
import { createSidePanels } from "@ui/ui_template_side_panels";
import { ROUTES } from "@config/config_frontend";
import { navigateTo } from "../A00_Common/router";
@@ -64,15 +58,15 @@ import { afterRowDrag } from "./M02_MasterTemplete_Labor_RowDrag";
import { openLogicPicker, withHopyo } from "./M02_MasterTemplete_Labor_Pick";
import { logicMatRows } from "./M02_MasterTemplete_Labor_LogicMats";
import { setLogicMark, setMark } from "./M02_MasterTemplete_Labor_MatMarks";
import { logicTable, matTable, qtyShort } from "./M02_MasterTemplete_Labor_Rows";
import { logicTable, qtyShort } from "./M02_MasterTemplete_Labor_Rows";
import { matTable } from "./M02_MasterTemplete_Labor_MatTable";
import { laborGrid } from "./M02_MasterTemplete_Labor_Grid";
import { tc } from "./M02_MasterTemplete_Labor_Text";
import { insideKeys, releaseTied } from "./M02_Labor_LogicMats_Model";
import { keepKnown } from "./M02_Labor_Values_Model";
import { addMaterialButton } from "./M02_Material_Pick";
import { createUnitPick, NO_UNIT } from "./DataFlow/M02_DF_UnitPick";
import { fetchStructureDef } from "./StructOptions/M02_SO_Api";
import { precomboClasses } from "./M02_MasterTemplete_UI_Side_Precombo";
import { libMeta } from "./M02_MasterTemplete_Labor_LibMeta";
import "../M01_MasterData/M01_MasterData_UI_Logic_Style.css";
import "../M01_MasterData/M01_MasterData_UI_LogicLab_Style.css";
import "@ui/ui_template_general_layout.css";
@@ -574,52 +568,6 @@ export function mountLaborDetail(
opt.onChanged(dirty());
});
/** 서고 구분 · 상세구분(51-12 · 134-5) — 구조물군 › 종류 + 공통(`precomboClasses`)에서 고름 ·
* 구분 바꾸면 상세구분 = 그 첫 줄(공통) · 빈 값 = 미분류 */
const meta = cur as { 구분?: string | null; 상세구분?: string | null };
const libMeta = (): HTMLElement[] => {
const sub = createSelectField({ options: [], label: tc("Sub"), disabled: !edit });
const detail = createSelectField({ options: [], label: tc("Detail"), disabled: !edit });
sub.root.dataset.laborField = "구분";
detail.root.dataset.laborField = "상세구분";
let subs: { name: string; details: string[] }[] = [];
// 목록에 없는 지금 값(빈 것 = 「—」 · 옛 문서)도 선택지로 둠
const opts = (names: string[], now: string | null | undefined) =>
[...new Set([now ?? "", ...names])]
.filter((v, i) => v || i === 0)
.map((v) => ({ value: v, text: v || "—" }));
const fill = (): void => {
sub.setOptions(
opts(
subs.map((s) => s.name),
meta.구분,
),
meta.구분 ?? "",
);
const details = subs.find((s) => s.name === meta.구분)?.details ?? [];
detail.setOptions(opts(details, meta.상세구분), meta.상세구분 ?? "");
};
sub.select.addEventListener("change", () => {
meta.구분 = sub.select.value;
meta.상세구분 = subs.find((s) => s.name === meta.구분)?.details[0] ?? null;
fill();
opt.onChanged(dirty());
});
detail.select.addEventListener("change", () => {
meta.상세구분 = detail.select.value;
opt.onChanged(dirty());
});
fill();
void fetchStructureDef().then(
(def) => {
subs = precomboClasses(def);
fill();
},
() => undefined,
);
return [sub.root, detail.root];
};
const editor = (body: HTMLElement): HTMLElement =>
side ? el("div", { className: "ui-side-panels-row", children: [body, side.root] }) : body;
host.replaceChildren(
@@ -637,7 +585,9 @@ export function mountLaborDetail(
el("div", {
className: "m01lab__info",
children: [
...(lib ? [nameField.root, ...libMeta()] : []),
...(lib
? [nameField.root, ...libMeta(cur, edit, () => opt.onChanged(dirty()))]
: []),
unit.root,
origin.root,
],