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:
@@ -7,9 +7,11 @@
|
||||
* · M02 단가산출 · 일위대가 = 위 층(마스터 › 회사 › 개인) 서고 목록(`/layers/{층}/templates`) · 고름 = 참조 {층 · 주인 · 키}
|
||||
* · 인력 · 재료 고름 = `element` · 일위대가 고정 줄 꼴 = `fixedOf`(705-1 이음 노임 LB · 자재 MT · 수량 1 은 부르는 쪽) ·
|
||||
* `element` 없으면 그 줄 회색 막힘(까닭 = 일위대가 표 개편 뒤 · 723)
|
||||
* · 부르는 곳 = M02 단가산출 [항목 추가](`Sangeun_Pick`) · 일위대가 [로직 추가]
|
||||
* · 부르는 곳 = M02 단가산출 [항목 추가](`Sangeun_Pick`) · 일위대가 [항목 추가]
|
||||
* (`Labor_Pick` 이 `lib.sangeun` 이면 이 창) — B09 · 불러오기는 옛 창(`Labor_Pick`)
|
||||
* · (727-1) 기초 = 로직마다 한 줄(`logicHeads` · 옵션은 넣은 뒤 고름 · 옛 창도 같이) · 서버 목록 그대로
|
||||
* · (736-1) `kinds` = 탭 막기(자리마다 고를 수 있는 종류만 · 불러오기 엑셀 연결 · 별칭 장부) · `material` = 재료 고름을
|
||||
* 일위대가 「자재 목록」 자리로(`element` 대신) · `query` = 찾기 칸 미리 넣기 · 부르는 곳 = 일위대가 [항목 추가]
|
||||
* · (728-2) 돈 아닌 기초(결과단위가 「원」 아님 · ㎥/시간 등 21 개) = 목록에서 뺌
|
||||
* ========================================================================== */
|
||||
|
||||
@@ -46,10 +48,19 @@ export interface M01Element {
|
||||
값: number | null;
|
||||
}
|
||||
|
||||
/** 고를 수 있는 종류 — logic = M01 단가산출 · 기초 로직 · labor = 인력 · material = 재료 · sk = M02 단가산출 · pre = 일위대가 */
|
||||
export type FindKind = "logic" | "labor" | "material" | "sk" | "pre";
|
||||
|
||||
export interface FindPickOptions {
|
||||
layer: Layer;
|
||||
owner: string | null;
|
||||
title?: string;
|
||||
/** 736-1 탭 막기 — 이 종류만 보임(없으면 다 · 탭 하나만 남으면 탭 줄 감춤) */
|
||||
kinds?: FindKind[];
|
||||
/** 찾기 칸에 미리 넣을 글 */
|
||||
query?: string;
|
||||
/** 재료 고름 — 있으면 재료는 `element` 대신 이쪽(일위대가 「자재 목록」 자리) */
|
||||
material?: (e: M01Element) => void;
|
||||
/** M01 단가산출 로직 고름 */
|
||||
logic: (x: LogicSummary) => void;
|
||||
/** M02 단가산출 · 일위대가 고름(참조) */
|
||||
@@ -117,7 +128,17 @@ interface Line {
|
||||
}
|
||||
|
||||
export function openFindPicker(opt: FindPickOptions): void {
|
||||
let tab: Tab = "m01";
|
||||
const ok = (k: FindKind): boolean => !opt.kinds || opt.kinds.includes(k);
|
||||
const allowed = (
|
||||
[
|
||||
["m01", ok("logic") || ok("labor") || ok("material")],
|
||||
["sk", ok("sk")],
|
||||
["pre", ok("pre")],
|
||||
] as const
|
||||
)
|
||||
.filter(([, on]) => on)
|
||||
.map(([k]) => k as Tab);
|
||||
let tab: Tab = allowed[0] ?? "m01";
|
||||
let close = (): void => {};
|
||||
let logics: LogicSummary[] = [];
|
||||
let std: StandardRow[] | null = null;
|
||||
@@ -182,7 +203,7 @@ export function openFindPicker(opt: FindPickOptions): void {
|
||||
단위: unitOf(m.단위 ?? ""),
|
||||
값: Number.isFinite(Number(m.값)) && m.값 !== null ? Number(m.값) : null,
|
||||
};
|
||||
const put = opt.element;
|
||||
const put = kind === "재료" && opt.material ? opt.material : opt.element;
|
||||
return {
|
||||
품명: m.이름,
|
||||
규격: e.규격,
|
||||
@@ -208,7 +229,11 @@ export function openFindPicker(opt: FindPickOptions): void {
|
||||
function draw(): void {
|
||||
const q = search.input.value.trim();
|
||||
if (tab === "m01") {
|
||||
shown = [...logicLines(q), ...elementLines("인력", people), ...elementLines("재료", goods)];
|
||||
shown = [
|
||||
...(ok("logic") ? logicLines(q) : []),
|
||||
...(ok("labor") ? elementLines("인력", people) : []),
|
||||
...(ok("material") ? elementLines("재료", goods) : []),
|
||||
];
|
||||
} else {
|
||||
const words = q.toLowerCase().split(/\s+/).filter(Boolean);
|
||||
const kind = tab === "sk" ? L("M02_PickSangeun") : L("M02_PrecomboTitle");
|
||||
@@ -231,7 +256,10 @@ export function openFindPicker(opt: FindPickOptions): void {
|
||||
`/logic-lib/pick?kind=${kind}&q=${encodeURIComponent(q)}&limit=200`,
|
||||
).then((d) => d.items);
|
||||
try {
|
||||
const [p, g] = await Promise.all([get("job"), q ? get("price") : Promise.resolve([])]);
|
||||
const [p, g] = await Promise.all([
|
||||
ok("labor") ? get("job") : Promise.resolve([]),
|
||||
q && ok("material") ? get("price") : Promise.resolve([]),
|
||||
]);
|
||||
if (mine !== seq) return;
|
||||
[people, goods] = [p, g];
|
||||
} catch (error) {
|
||||
@@ -252,7 +280,7 @@ export function openFindPicker(opt: FindPickOptions): void {
|
||||
{ key: "m01", label: L("M02_FindM01") },
|
||||
{ key: "sk", label: L("M02_PickSangeun") },
|
||||
{ key: "pre", label: L("M02_PrecomboTitle") },
|
||||
],
|
||||
].filter((x) => allowed.includes(x.key as Tab)),
|
||||
value: tab,
|
||||
kind: "line",
|
||||
onChange: (key) => {
|
||||
@@ -272,10 +300,11 @@ export function openFindPicker(opt: FindPickOptions): void {
|
||||
el("div", {
|
||||
className: "m02-std-pick",
|
||||
attrs: { "data-find-pick": "" },
|
||||
children: [tabs.root, search.root, hint, table.root],
|
||||
children: [...(allowed.length > 1 ? [tabs.root] : []), search.root, hint, table.root],
|
||||
}),
|
||||
),
|
||||
}));
|
||||
if (opt.query) search.input.value = opt.query;
|
||||
search.input.focus();
|
||||
draw();
|
||||
|
||||
@@ -292,7 +321,7 @@ export function openFindPicker(opt: FindPickOptions): void {
|
||||
void upper(opt.layer, opt.owner)
|
||||
.then((scopes) =>
|
||||
Promise.all(
|
||||
(["sk", "pre"] as const).map((t) =>
|
||||
(["sk", "pre"] as const).filter(ok).map((t) =>
|
||||
listLayerDocs(scopes, t === "sk" ? SANGEUN_KIND : "precombo").then((rows) => {
|
||||
lists[t] = rows;
|
||||
tabs.setBadge(t, rows.length);
|
||||
|
||||
Reference in New Issue
Block a user