- 새 M02_Library_Delete: 쓰는 줄 미리 보기(종류 · 이름 · 키 · 줄 · 층) · 권한 밖 409 막힘 목록 ·
확인 몸이면 쓰는 문서의 그 줄 지움(store.write 정본 다시 셈) 뒤 문서 지움 · _합친것/ 기록
(지운 문서 · 자리 · 고친 문서 앞판) · 되돌림(그새 고친 문서는 건너뜀) · 단가산출 바탕 · 더한줄 열쇠 당김
- 미리 보기 길 POST {kind}-tree/delete-check · undo 길이 지움 기록도 되돌림 · 합친 것 목록에 「지움」
- 나무 고침 몸 확인 칸 · 세션을 나무 고침에 넘김 · 옛 _refuse_used 걷음
- 화면: 지우기 앞 경고 창(쓰는 곳 N · 표 · 프로젝트 사본 영향 없음 · 되돌림 자리) · 부품 상자
확인창에 detail 칸(넓은 판 · 안 스크롤)
- 시험: 새 test_735_1 · test_716_4 의 쓰는 곳 409 시험을 확인 없음 409 + 목록 꼴로 고침
(지움이 막힘에서 경고 뒤 지움으로 바뀜)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
110 lines
4.3 KiB
TypeScript
110 lines
4.3 KiB
TypeScript
/* =============================================================================
|
||
* M02_MasterTemplete_Library_Delete.ts
|
||
* 서고 나무 지우기 경고(735-1 · 요구 574) — 좌측 일위대가 · 단가산출 나무 [지우기] 앞에 부름.
|
||
* 서버 미리 보기(`{kind}-tree/delete-check`) → 쓰는 곳 없음 = 원래 확인 글 · 있음 = 경고 「이 항목을 쓰는 곳 N —
|
||
* 지우면 그 줄도 지워짐」 + 표(종류 · 이름 · 키 · 줄 · 지울 키 · 층) + [삭제] [취소] · 권한 밖이 있으면
|
||
* 못 지움 알림 + 그 목록만. 확인 = 나무 고침 몸 `확인: true`(서버가 그 줄 지움 · 금액 다시 셈 · 되돌림 기록).
|
||
* 되돌림 = 나무 맨 위 메뉴 [중복 찾기] › 합친 것 · 지운 것.
|
||
* ========================================================================== */
|
||
|
||
import { el } from "@ui/ui_template_elements";
|
||
import { currentLanguageIndex } from "@ui/ui_template_locale";
|
||
import { askConfirm } from "@ui/ui_template_modal";
|
||
import { createTable, type Cell } from "@ui/ui_template_table";
|
||
import { createText } from "@ui/ui_template_text";
|
||
import {
|
||
checkLibraryDelete,
|
||
type Layer,
|
||
type LibraryKind,
|
||
type TreeRef,
|
||
} from "./M02_MasterTemplete_Api_Fetch";
|
||
|
||
const TEXT = {
|
||
Title: ["쓰는 곳이 있음", "In use"],
|
||
Warn: [
|
||
"이 항목을 쓰는 곳 {n} — 지우면 그 줄도 지워짐(금액 다시 셈)",
|
||
"Used in {n} place(s) — deleting also removes those lines (amounts recalculated)",
|
||
],
|
||
Blocked: [
|
||
"권한 밖 쓰는 곳 {n} — 지울 수 없음(그 층 주인이 먼저 줄을 뺌)",
|
||
"{n} use(s) outside your permission — cannot delete (their owner must remove the lines first)",
|
||
],
|
||
Note: [
|
||
"프로젝트 사본 · B09 공사는 굳힌 값이라 영향 없음 · 되돌림 = 나무 맨 위 메뉴 [중복 찾기] › 되돌림",
|
||
"Project copies and B09 estimates keep frozen values · Undo = tree top menu [Find duplicates] › Undo",
|
||
],
|
||
Kind: ["종류", "Type"],
|
||
Name: ["이름", "Name"],
|
||
Key: ["키", "Key"],
|
||
Line: ["줄", "Line"],
|
||
Gone: ["지울 키", "Deleting"],
|
||
Layer: ["층", "Layer"],
|
||
Ok: ["확인", "OK"],
|
||
} as const;
|
||
const tx = (key: keyof typeof TEXT, n = 0): string =>
|
||
String(TEXT[key][currentLanguageIndex as 0 | 1] ?? TEXT[key][0]).replace("{n}", String(n));
|
||
|
||
/** 쓰는 줄 하나(서버 `M02_Library_Delete.users`) */
|
||
export interface DeleteUser {
|
||
층: Layer;
|
||
주인: string | null;
|
||
어디: string;
|
||
종류: string;
|
||
문서: string;
|
||
이름: string;
|
||
키: string;
|
||
줄: string;
|
||
쓰기: boolean;
|
||
}
|
||
interface DeleteCheck {
|
||
문서: string[];
|
||
쓰는곳: DeleteUser[];
|
||
}
|
||
|
||
const table = (rows: DeleteUser[]): HTMLElement => {
|
||
const columns = [
|
||
{ label: tx("Kind"), width: "96px" },
|
||
{ label: tx("Name") },
|
||
{ label: tx("Key"), width: "112px" },
|
||
{ label: tx("Line"), width: "88px" },
|
||
{ label: tx("Gone"), width: "112px" },
|
||
{ label: tx("Layer"), width: "96px" },
|
||
];
|
||
const cells: Cell[][] = rows.map((r) => [r.종류, r.이름, r.문서, r.줄, r.키, r.어디]);
|
||
return el("div", {
|
||
attrs: { "data-library-delete": "" },
|
||
children: [createTable(columns, cells, { density: "data" }), createText(tx("Note"), "muted")],
|
||
});
|
||
};
|
||
|
||
/** 지우기 물음 — 쓰는 곳 없음 = `ask` 글 · 있음 = 경고 + 표 · 권한 밖 = 알림만(false).
|
||
* `{ok, sure}` — ok = 지움 · sure = 쓰는 곳까지 지움(나무 고침 `확인`). */
|
||
export async function askLibraryDelete(
|
||
kind: LibraryKind,
|
||
layer: Layer,
|
||
owner: string | null,
|
||
picks: TreeRef[],
|
||
ask: string,
|
||
okLabel: string,
|
||
): Promise<{ ok: boolean; sure: boolean }> {
|
||
const got = await checkLibraryDelete<DeleteCheck>(kind, layer, owner, picks);
|
||
const used = got.쓰는곳;
|
||
if (!used.length)
|
||
return { ok: await askConfirm({ message: ask, okLabel, danger: true }), sure: false };
|
||
const blocked = used.filter((r) => !r.쓰기);
|
||
if (blocked.length) {
|
||
const message = tx("Blocked", blocked.length);
|
||
await askConfirm({ title: tx("Title"), message, okLabel: tx("Ok"), detail: table(blocked) });
|
||
return { ok: false, sure: false };
|
||
}
|
||
const message = `${ask}\n${tx("Warn", used.length)}`;
|
||
const ok = await askConfirm({
|
||
title: tx("Title"),
|
||
message,
|
||
okLabel,
|
||
danger: true,
|
||
detail: table(used),
|
||
});
|
||
return { ok, sure: ok };
|
||
}
|