feat(736-1): 일위대가 [항목 추가] 하나 · 찾아 넣기 창 하나로 — 자재 추가 단추 걷음 · 엑셀 연결 · 별칭 장부 · 견본

- 일위대가표 · 구조물 조합 상세 [로직 추가] → [항목 추가] · [자재 추가] 걷음 · 재료 고름 = 자재 목록(로직 안 자재 · 이미 있는 자재 막힘 그대로)
- 찾아 넣기 창 탭 막기(kinds) · 찾기 칸 미리 넣기(query) · 재료 길(material)
- 불러오기 엑셀 연결 = 「다른 항목 검색…」 한 창(기초 · 재료) · 별칭 장부 = 기초 · 재료 둘
- 부품 모음 단추 견본에 갈래 색(옵션값 · 요소 연결) 칸
- 낡은 시험 고침: 175(머리 단추) · 721(부르는 곳) · 자재 개인(상세 단추) · 호표 화면(장부 단추 글) · 헬퍼 넷(Find_Pick 대역)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-11-02 16:50:34 +09:00
co-authored by Claude Sonnet 5.5
parent f82e64ce29
commit f97ea96c08
18 changed files with 152 additions and 79 deletions
@@ -64,7 +64,6 @@ 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 { mountLaborTable } from "./M02_MasterTemplete_Labor_Table";
import "../M01_MasterData/M01_MasterData_UI_Logic_Style.css";
@@ -79,8 +78,8 @@ export interface LaborDetailOptions {
readOnly: boolean;
/** 저장 안 한 고침이 생기거나 사라짐 */
onChanged: (dirty: boolean) => void;
/** 구조물 조합 카드 갈래(43-4) — 단가산출 로직 표 + 자재목록만 · 위로 · 아래로 · 로직 추가 ·
* 자재 추가 · 정보(단위 · 본뜬) · 다이어그램 없음 · 옵션 · 삭제 · 줄 · 수량 모달은 상세와 같음 */
/** 구조물 조합 카드 갈래(43-4) — 단가산출 로직 표 + 자재목록만 · 위로 · 아래로 · 항목 추가 ·
* 정보(단위 · 본뜬) · 다이어그램 없음 · 옵션 · 삭제 · 줄 · 수량 모달은 상세와 같음 */
card?: boolean;
/** 일위대가 사전조합 서고(50-3) — 사전조합 문서(`column` = 키) */
mode?: "precombo";
@@ -515,6 +514,20 @@ export function mountLaborDetail(
cur.담은로직.push({ 로직: "", 참조: ref, 별칭, 메모: null, 입력값: {}, 수량: null });
changed();
},
/** 736-1 찾아 넣기 창에서 재료를 고름 — 「자재 목록」 줄 · 로직 안 자재 · 이미 있는 자재는 막음 */
material: (m: {
코드: string;
이름: string | null;
규격: string | null;
단위: string | null;
}) => {
const why = insideKeys((calc ?? last)?.줄).has(m.코드)
? "Labor_InLogicMat"
: cur.자재.some((x) => x.코드 === m.코드) && "Labor_AlreadyMat";
if (why) return showToast(tc(why).replace("{value}", `${m.코드} ${m.이름 ?? ""}`), "error");
cur.자재.push({ 코드: m.코드, 이름: m.이름, 규격: m.규격, 단위: m.단위, 수량: null });
changed();
},
};
const addLogic = createButton({
label: tc("AddLogic"),
@@ -531,18 +544,6 @@ export function mountLaborDetail(
withHopyo(library),
),
});
const addMat = addMaterialButton(
tc("Labor_AddMat"),
(m) => {
const why = insideKeys((calc ?? last)?.줄).has(m.코드)
? "Labor_InLogicMat"
: cur.자재.some((x) => x.코드 === m.코드) && "Labor_AlreadyMat";
if (why) return showToast(tc(why).replace("{value}", `${m.코드} ${m.이름 ?? ""}`), "error");
cur.자재.push({ 코드: m.코드, 이름: m.이름, 규격: m.규격, 단위: m.단위, 수량: null });
changed();
},
opt.layer === "personal" ? { owner: library.owner } : undefined, // 개인 층만 신규 자재(148-3)
);
// 단위 = 표준 단위 목록에서 고르기(지금 값이 목록에 없어도 선택지로 둠) · 저장은 [저장]
const unit = {
@@ -602,11 +603,11 @@ export function mountLaborDetail(
],
}),
]),
// 사전조합 = 같은 [로직 추가](51-11)
// 사전조합 = 같은 [항목 추가](51-11)
section(tc("Grid_Title"), null, gridHost),
...[
section(tc("Logics_Title"), opt.card ? null : addLogic, logicHost),
section(tc("Labor_Mats"), opt.card ? null : addMat, matHost),
section(tc("Labor_Mats"), null, matHost),
].filter(() => edit || !opt.card), // 읽기만 카드 = 격자만
...(opt.card ? [] : [dgBox]),
],