feat(m02): 사전조합 목록표 미분류 표기 · 고르기 창 새 분류 거름(149-2)

- 목록표 빈 구분 = 「미분류」(나무와 같은 말)
- [로직 추가] 고르기 창 구분 거름 = 단가산출 로직 품셈 분류 + 사전조합 새 분류(구조물군 › 공통 + 종류)
- 일위조합 줄 작은 글 = 새 분류 · 빈 값은 미분류

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SE9MxeXTu2uaDZ55BJowAY
This commit is contained in:
2026-10-09 19:03:22 +09:00
co-authored by Claude Opus 5.5
parent 124a216a2c
commit 549e0fea69
3 changed files with 28 additions and 5 deletions
@@ -2,7 +2,7 @@
* M02_MasterTemplete_Labor_Pick.ts
* [로직 더하기] 창 — 한 목록에 구분(단가산출 · 단가승격 · 일위조합) 칸 · 치는 대로 걸러짐(찾기 단추 없음) ·
* 단가승격 · 일위조합 줄은 층 단추(위 층만 · 짝 `M02_Labor_Ref.readable`) 층의 서고 · 고르면 참조 {층 · 주인 · 키} ·
* 프로젝트 · 카드엔 서고 줄 없음
* 프로젝트 · 카드엔 서고 줄 없음 · 거름 = 로직 품셈 분류 + 사전조합 새 분류(149-2 · 구조물군 › 공통 + 종류)
* ========================================================================== */
import { createButton, createSelectField, el, showToast } from "@ui/ui_template_elements";
@@ -20,6 +20,8 @@ import {
import type { LaborRef } from "./M02_MasterTemplete_Labor_Calc";
import { ownOwner } from "./M02_MasterTemplete_Layer";
import { tc } from "./M02_MasterTemplete_Labor_Text";
import { precomboClasses } from "./M02_MasterTemplete_UI_Side_Precombo";
import { fetchStructureDef } from "./StructOptions/M02_SO_Api";
import "../M01_MasterData/M01_MasterData_UI_Logic_Style.css"; // 창 겉틀
import "./M02_MasterTemplete_Labor.css";
@@ -54,6 +56,7 @@ const LAYER_TEXT = {
export function openLogicPicker(done: (logic: LogicSummary) => void, lib?: LibraryPick): void {
const subs: SubBrief[] = [];
let classes: ReturnType<typeof precomboClasses> = []; // 사전조합 새 분류(149-2) — 서고 줄이 있을 때만
let all: LogicSummary[] = [];
const sub = createSelectField({ options: opts([]), compact: true, label: tc("Sub") });
const detail = createSelectField({ options: opts([]), compact: true, label: tc("Detail") });
@@ -113,7 +116,7 @@ export function openLogicPicker(done: (logic: LogicSummary) => void, lib?: Libra
key: x.row.이름,
tag: tc(x.kind),
name: x.row.제목 || x.row.이름,
sub: [x.row.이름, `${x.row.구분 ?? ""} ${x.row.상세구분 ?? ""}`.trim()]
sub: [x.row.이름, `${x.row.구분 || tc("Lib_Unsorted")} ${x.row.상세구분 ?? ""}`.trim()]
.filter(Boolean)
.join(" · "),
unit: x.row.단위 ?? "",
@@ -158,9 +161,9 @@ export function openLogicPicker(done: (logic: LogicSummary) => void, lib?: Libra
}),
),
);
/** 구분 → 상세구분 — 로직 구분에 서고 줄(승격 · 조합) 것을 더함 · 같은 값은 한 칸 */
/** 구분 → 상세구분 — 로직 품셈 구분 + 사전조합 새 분류 + 서고 줄 지금 값 · 같은 값은 한 칸 */
const subMap = (): Map<string, Set<string>> => {
const m = new Map(subs.map((s) => [s.name, new Set(s.details)]));
const m = new Map([...subs, ...classes].map((s) => [s.name, new Set(s.details)]));
for (const { row } of libRows) {
if (!row.구분) continue;
if (!m.has(row.구분)) m.set(row.구분, new Set());
@@ -194,6 +197,13 @@ export function openLogicPicker(done: (logic: LogicSummary) => void, lib?: Libra
layerBar.style.display = "";
drawLayers();
void loadLib();
void fetchStructureDef().then(
(def) => {
classes = precomboClasses(def);
drawSubs();
},
() => undefined, // 못 받으면 서고 줄 지금 값만
);
});
const dialog = el("div", {
@@ -144,7 +144,7 @@ export function mountLibraryList(
pick,
...[
row.이름,
row.구분 ?? "",
row.구분 || tc("Lib_Unsorted"), // 빈 구분 = 미분류(149-2 · 나무와 같은 말)
row.상세구분 ?? "",
row.제목 ?? "",
row.단위 ?? "",
@@ -130,3 +130,16 @@ def test_나무_폴더_문서수_처음_펼침_폴더_메뉴_생성():
assert 'newLibrary(at.layer, "precombo", { 문서 }, at.owner)' in make
lib = _text("M02_MasterTemplete_Library_List.ts")
assert "export const nameDialog = (" in lib
def test_목록표_빈_구분_미분류_고르기_창_새_분류_거름():
"""149-2 — 목록표 빈 구분 = 미분류 · 고르기 창 거름 = 품셈 구분 + 사전조합 새 분류"""
lib = _text("M02_MasterTemplete_Library_List.ts")
assert 'row.구분 || tc("Lib_Unsorted"),' in lib
pick = _text("M02_MasterTemplete_Labor_Pick.ts")
assert "new Map([...subs, ...classes].map((s) => [s.name, new Set(s.details)]))" in pick
assert "classes = precomboClasses(def);" in pick
assert 'x.row.구분 || tc("Lib_Unsorted")' in pick # 서고 줄 작은 글 = 새 분류 · 빈 값 미분류
# 거름은 칸 값 그대로 — 품셈 구분을 고르면 서고 줄 빠지고 새 분류를 고르면 로직 줄 빠짐
assert "(!sub.select.value || x.row.구분 === sub.select.value)" in pick
assert "(!sub.select.value || x.구분 === sub.select.value)" in pick