Files
Aislo/M02_MasterTemplete/M02_MasterTemplete_Hopyo_ToItem.ts
eomsangdonandClaude Opus 5.5 56b73b79b8 fix(786-2): 화면 검증 흠 고침 — [구조물 조합으로] 참조 주인 · 실패 되돌림 · 표 머리 칸 · 이름 칸 덧글 줄
- ToItem: SC 참조 주인 = 실제 주인 id(개인 「회사/사용자」 · Find_Pick.upper 와 같은 ownOwner 길) — null 이면 서버 400
  「참조 층 · 주인 꼴이 틀림」 · 일위대가 못 담으면 방금 더한 항목 지움(빈 항목 안 남김)
- CheckRows: [확인] · 행 머리 칸 = 표마다 새 노드(두 표가 같은 노드를 써 로직 표 머리가 두 칸 밀림)
- Hopyo.css: 이름 칸 덧글(셈 못 함 · 입력 필요) 한 줄씩

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 07:41:33 +09:00

97 lines
4.3 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* =============================================================================
* M02_MasterTemplete_Hopyo_ToItem.ts
* [구조물 조합으로](PLAN 786-2 · 옛 704-4 꼴 되살림) — [수정] 모달에서 이 호표가 옮겨진 일위대가(SC)를 담은
* 구조물 조합 항목을 만듦. 창 = 항목 이름(기본 = 호표 이름 · 규격) · [만들기].
* 길 = 구조물 조합 나무 항목 더하기(`editTree` add-item · 「실무자료」 폴더) → 그 항목 일위대가 문서에 SC 참조 한 줄
* (`readTemplate` · `saveTemplate` — 서버가 정리 · 셈) · 구조물 조합 공용 파일 · 길은 부르기만.
* ========================================================================== */
import { createButton, showToast } from "@ui/ui_template_elements";
import { createInputField } from "@ui/ui_template_input";
import { t as L } from "@ui/ui_template_locale";
import { openModal } from "@ui/ui_template_modal";
import { createText } from "@ui/ui_template_text";
import { fetchSessionUser } from "../A06_Login/A06_Login_Api_Fetch";
import { editTree, fetchTree, readTemplate, saveTemplate } from "./M02_MasterTemplete_Api_Fetch";
import type { HopyoScope } from "./M02_MasterTemplete_Hopyo_Api";
import { ownOwner } from "./M02_MasterTemplete_Layer";
/** 만든 항목이 놓이는 폴더 */
export const ITEM_PATH = ["실무자료"];
export interface ToItemOptions {
/** 만들 층(일위대가 SC 가 있는 층) */
target: HopyoScope;
/** 이 호표가 옮겨진 일위대가 키(SC-…) */
sc: string;
name: string;
unit: string;
}
/** 항목 더하기 → 일위대가 문서에 SC 참조 한 줄 → 새 열 id */
export async function makeItem(o: ToItemOptions, label: string): Promise<string> {
const { layer, owner } = o.target;
const tree = await fetchTree(layer, owner);
const made = await editTree(layer, { op: "add-item", 경로: ITEM_PATH, 이름: label, 단위: o.unit }, tree.판, owner); // prettier-ignore
const col = [made.알림?.열].flat()[0];
if (!col) throw new Error(L("M02_CheckToItemFail"));
try {
await fillLabor(o, col);
} catch (e) {
// 일위대가 못 담음 = 빈 항목 남기지 않음(방금 더한 항목만 지움)
await editTree(layer, { op: "delete", 키: col }, made.판, owner).catch(() => null);
throw e;
}
return col;
}
/** 새 항목 일위대가 문서 = SC 참조 한 줄 */
async function fillLabor(o: ToItemOptions, col: string): Promise<void> {
const { layer, owner } = o.target;
const now = await readTemplate(layer, "labor", col, null, owner);
const doc = (now.문서 ?? {}) as Record<string, unknown>;
// 참조 주인 = 실제 주인 id(개인 「회사/사용자」 · 자기 층이면 세션에서 · `Find_Pick.upper` 와 같은 길)
const who =
layer === "system" || layer === "project"
? null
: (owner ?? ownOwner(layer, await fetchSessionUser()));
const line = {
참조: { 층: layer, 주인: who, 키: o.sc },
별칭: null,
메모: null,
수량: { 손: 1 },
};
await saveTemplate(layer, "labor", col, null, now.판 ?? "", { ...doc, 담은로직: [line], 단위: o.unit || doc.단위 || null }, owner); // prettier-ignore
}
export function toItem(o: ToItemOptions): void {
const name = createInputField({ label: L("M02_CheckItemName"), value: o.name });
openModal({
title: `${L("M02_CheckToItem")} — ${o.sc}`,
closeLabel: L("Common_Btn_Cancel"),
width: "40rem",
mount: (body, close, actions) => {
const go = createButton({
label: L("M02_CheckItemMake"),
onClick: async () => {
const label = name.input.value.trim();
if (!label) return name.setError(L("M02_CheckItemEmpty"));
go.disabled = true;
try {
await makeItem(o, label);
close();
showToast(L("M02_CheckItemMade").replace("{name}", label).replace("{path}", ITEM_PATH.join(" › ")), "success", 6000); // prettier-ignore
} catch (e) {
showToast(`${L("M02_CheckToItemFail")} — ${e instanceof Error ? e.message : String(e)}`, "error"); // prettier-ignore
} finally {
go.disabled = false;
}
},
});
go.dataset.hopyoItemMake = "";
actions.append(go);
body.append(createText(L("M02_CheckItemHint"), "muted"), name.root);
},
});
}