Merge remote-tracking branch 'origin/sub_laptop_2' into sub_laptop_5 (선택 입력 카드 sub2 판 · Structure.ts 는 ItemCards 위에 다시 얹음)
This commit is contained in:
@@ -42,6 +42,7 @@ import {
|
||||
type SheetKind,
|
||||
} from "./M02_MasterTemplete_ItemCards";
|
||||
import { layerSource } from "./M02_MasterTemplete_ItemSource";
|
||||
import { createInputsCard, inputPills, type InputsCardHandle } from "./M02_MasterTemplete_Inputs";
|
||||
import "./M02_MasterTemplete_Structure.css";
|
||||
|
||||
export type { EditKind, SheetKind } from "./M02_MasterTemplete_ItemCards";
|
||||
@@ -193,8 +194,12 @@ export async function pillsFor(
|
||||
kind: SheetKind,
|
||||
column: string,
|
||||
): Promise<{ links: LinkOptions; notice?: string }> {
|
||||
if (kind === "material") return { links: { 항목: [], 모드: "자재", 자재찾기: searchMaterials } };
|
||||
const none = (notice: string) => ({ links: { 항목: [], 모드: "입력" as const }, notice });
|
||||
if (kind === "material") {
|
||||
const own = await inputPills(column, "재료");
|
||||
return { links: { 항목: own, 모드: "자재", 자재찾기: searchMaterials } };
|
||||
}
|
||||
const own = await inputPills(column, "면적"); // 선택 입력 카드가 면적산출로 고른 입력
|
||||
const none = (notice: string) => ({ links: { 항목: own, 모드: "입력" as const }, notice });
|
||||
const table = await readTemplate(getActiveLayer(), "table", STRUCTURE_TABLE, null).catch(
|
||||
() => null,
|
||||
);
|
||||
@@ -203,7 +208,7 @@ export async function pillsFor(
|
||||
if (!combo) return none(TEXT.noPrice);
|
||||
try {
|
||||
const got = await fetchComboInputs(combo);
|
||||
const 항목 = got.물량.map((q) => ({ 키: q.키, 이름: q.이름, 단위: q.단위 }));
|
||||
const 항목 = [...got.물량.map((q) => ({ 키: q.키, 이름: q.이름, 단위: q.단위 })), ...own];
|
||||
return 항목.length ? { links: { 항목, 모드: "입력" } } : none(fill(TEXT.noInputs, combo));
|
||||
} catch (error) {
|
||||
return none(fill(TEXT.inputsFailed, why(error)));
|
||||
@@ -218,6 +223,8 @@ export interface StructurePanelOptions {
|
||||
onEdit: (column: string, label: string, kind: EditKind) => void;
|
||||
/** 집계표에 저장 안 한 고침이 있으면 버릴지 물음 — 취소면 false */
|
||||
confirmLeave: () => Promise<boolean>;
|
||||
/** 「선택 입력」 카드에서 자리를 골랐음 — 저장 안 한 고침 표시 */
|
||||
onDirty?: () => void;
|
||||
}
|
||||
|
||||
export interface StructurePanelHandle {
|
||||
@@ -226,6 +233,8 @@ export interface StructurePanelHandle {
|
||||
numbers: () => ColumnNumbers;
|
||||
/** 번호 목록 다시 받기 */
|
||||
reload: () => Promise<void>;
|
||||
/** 「선택 입력」 카드에서 고른 자리를 서버에 저장 — 집계표 [저장] 뒤에 부름(실패하면 던짐) */
|
||||
saveInputs: () => Promise<void>;
|
||||
/** 고른 열이 바뀜 — 같은 열이면 이름만 새로(CAD 를 다시 안 띄움) */
|
||||
show: (colId: string | null, columns: StructureColumn[]) => void;
|
||||
/** 보던 열을 다시 읽음 — 집계표 [저장] 뒤(서버가 새 열 파일 · 번호를 만듦) */
|
||||
@@ -242,6 +251,10 @@ export function createStructurePanel(opts: StructurePanelOptions): StructurePane
|
||||
let column: string | null = null;
|
||||
let columnLabel = "";
|
||||
|
||||
const inputs: InputsCardHandle = createInputsCard({
|
||||
isAdmin: opts.isAdmin,
|
||||
onDirty: () => opts.onDirty?.(),
|
||||
});
|
||||
// 카드 셋은 항목 카드 한 벌(`ItemCards`) — 여기서는 지금 층에서 열 하나를 읽어 넘기기만.
|
||||
const cards = createItemCards({
|
||||
source: layerSource,
|
||||
@@ -250,6 +263,7 @@ export function createStructurePanel(opts: StructurePanelOptions): StructurePane
|
||||
numberOf: (kind, id) => numbers[id]?.[PART_FIELD[kind]],
|
||||
// 도번 목록에 있는 열인데 못 읽으면 알림 — 없는 열은 그냥 「도면 없음」
|
||||
warnOnFail: (id) => !!numbers[id],
|
||||
extraCards: [inputs.root],
|
||||
});
|
||||
const root = cards.root;
|
||||
|
||||
@@ -257,6 +271,9 @@ export function createStructurePanel(opts: StructurePanelOptions): StructurePane
|
||||
shown = col;
|
||||
column = col?.id ?? null;
|
||||
columnLabel = col ? columnHead(col) : "";
|
||||
if (!col) void inputs.show(null, null);
|
||||
// 집계표에 지금 고른 일위대가(저장 전일 수 있음) — 카드가 「먼저 저장」 안내를 고름
|
||||
else void inputs.show(col.id, (col as { 일위대가?: string | null }).일위대가 ?? null);
|
||||
return cards.load(col ? { id: col.id, label: columnLabel } : null);
|
||||
}
|
||||
|
||||
@@ -347,7 +364,9 @@ export function createStructurePanel(opts: StructurePanelOptions): StructurePane
|
||||
numbers: () => numbers,
|
||||
reload: async () => {
|
||||
numbers = await fetchStructureNumbers().catch(() => ({}));
|
||||
inputs.invalidate(); // 새 열 · 바뀐 일위대가를 서버 항목 목록에서 다시 찾게
|
||||
},
|
||||
saveInputs: () => inputs.save(),
|
||||
show,
|
||||
refresh: (columns) => {
|
||||
const at = column;
|
||||
@@ -355,6 +374,9 @@ export function createStructurePanel(opts: StructurePanelOptions): StructurePane
|
||||
show(at, columns);
|
||||
},
|
||||
pick,
|
||||
destroy: () => cards.destroy(),
|
||||
destroy: () => {
|
||||
inputs.destroy();
|
||||
cards.destroy();
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user