refactor(M02): 새 항목 일위대가 고르기 없앰 — 항목 추가 창 줄 · pickCombo · 서버가 받는 일위대가 키 · 열 칸 새로 쓰기 · /combos/all · fetchUsableCombos 지움 · 새 구조물 일위대가 = 빈 labor 문서(39-1d)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013rJwJMVL4EE31y77TB11AP
This commit is contained in:
2026-10-04 21:04:48 +09:00
co-authored by Claude Opus 5.5
parent 5066c6bb27
commit 8087c73060
11 changed files with 24 additions and 230 deletions
@@ -68,22 +68,20 @@ export function askText(
});
}
/** 항목 추가 창이 돌려줌 — `path` = 넣을 폴더(종류 · 고른 폴더) · `combo` = 고른 일위대가 키(없으면 null) */
/** 항목 추가 창이 돌려줌 — `path` = 넣을 폴더(종류 · 고른 폴더) */
export interface NewItem {
path: string[];
name: string;
combo: string | null;
}
/** 항목 추가(PLAN 31-2) — 구조물 종류(맨 위 폴더 · 있는 것 고르거나 새 이름 · 나무에서 폴더를 골라 두었으면
* 그 안이라 안 물음) + 이름 + 일위대가(`pickCombo` 고르기 창 · 비워도 됨 — 표에서 나중에) · 단위는 안 받음 */
* 그 안이라 안 물음) + 이름 · 단위는 안 받음 · 일위대가는 늘 빈 문서로 생기고 카드에서 담음(39-1d) */
export function askNewItem(opt: {
title: string;
/** 있는 종류(맨 위 폴더 이름) — 칸에 글을 치면 목록에서 고름 */
kinds: string[];
/** 나무에서 골라 둔 폴더 — 있으면 종류 칸 없음 */
at: string[];
pickCombo?: () => Promise<{ key: string; label: string } | null>;
}): Promise<NewItem | null> {
return new Promise((resolve) => {
let done = false;
@@ -114,28 +112,6 @@ export function askNewItem(opt: {
})
: null;
const name = createInputField({ label: L("M02_TreeItemName") });
let combo: { key: string; label: string } | null = null;
const shown = el("span", {
className: "m02-treedlg__combo",
text: L("M02_NewItemNoCombo"),
});
const pick = createButton({
label: L("M02_NewItemPickCombo"),
variant: "ghost",
size: "sm",
});
pick.addEventListener("click", async () => {
const got = await opt.pickCombo?.();
if (got === null || got === undefined) return; // 닫음 = 그대로
combo = got.key ? got : null; // 「비움」 = 없앰
shown.textContent = combo ? `${combo.key} ${combo.label}` : L("M02_NewItemNoCombo");
});
const comboRow = opt.pickCombo
? el("div", {
className: "m02-treedlg__row",
children: [el("span", { text: L("M02_NewItemCombo") }), shown, pick],
})
: null;
const ok = createButton({ label: L("M02_TreeOk"), variant: "filled" });
const need = (field: typeof name, label: string): boolean => {
const empty = !field.input.value.trim();
@@ -148,7 +124,7 @@ export function askNewItem(opt: {
const badName = need(name, L("M02_TreeItemName"));
if (badKind || badName) return;
const path = kind ? [kind.input.value.trim()] : opt.at;
finish({ path, name: name.input.value.trim(), combo: combo?.key ?? null });
finish({ path, name: name.input.value.trim() });
close();
};
ok.addEventListener("click", submit);
@@ -159,10 +135,7 @@ export function askNewItem(opt: {
if (event.key === "Enter" && !event.isComposing) submit();
});
}
body.append(
...[where, kind?.root, name.root, comboRow].filter((n): n is HTMLDivElement => !!n),
ok,
);
body.append(...[where, kind?.root, name.root].filter((n): n is HTMLDivElement => !!n), ok);
(kind ?? name).input.focus();
},
});