feat(720-3): 단가산출 · 일위대가 나무 문서 줄 [이름 바꾸기] — 읽고 이름만 갈아 저장 · 저장 뒤 상세 머리 제목 새 이름

- 열린 문서면 저장 안 한 고침 물음 뒤 새 이름으로 다시 엶 · 서버 새 길 없음
- 새 지킴 시험 test_720_m02_folder_layer(임시 storage 이름 바꾸기 왕복 · 화면 글 대조)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-11-01 21:25:12 +09:00
co-authored by Claude Opus 5.5
parent 194e1a9c39
commit a0c2db507f
3 changed files with 112 additions and 0 deletions
@@ -9,6 +9,7 @@
* Delete 가 고른 것 전부에 · 복사는 읽을 수 있는 층 어디서나 → 쓸 수 있는 층에 붙여넣기(새 키).
* 문서 누름 = 편집 칸 · 켜진 층 단추 다시 누름 = 목록표(페이지 몫).
* 최상위 폴더(720-2) — 층 단추 옆 「+」(맨 위 메뉴) · 폴더 · 문서 줄 [최상위 폴더 만들기] = 같은 `addFolder([])`.
* 문서 줄 [이름 바꾸기](720-3) — 읽고 문서 `이름` 만 갈아 저장(서버 새 길 없음) · 열린 문서면 새 이름으로 다시 엶.
* ========================================================================== */
import { isCtrlKey } from "../A00_Common/key_shortcut";
@@ -29,6 +30,8 @@ import {
listTemplates,
newLibrary,
pasteLibraryTree,
readTemplate,
saveTemplate,
type Layer,
type LibraryKind,
type PrecomboTree,
@@ -219,6 +222,34 @@ export function buildLibrarySection(opt: LibraryOptions): LibraryHandle {
if (got && got.name !== was) await edit({ op: "rename", 경로: path, 이름: got.name });
};
/** 문서 이름 바꾸기(720-3) — 열린 문서면 저장 안 한 고침 물음 → 읽고 `이름` 만 갈아 저장 → 나무 · 상세 새 이름 */
const renameDoc = async (row: LibraryRow): Promise<void> => {
const at = opt.scope();
const was = row.제목 || row.이름;
const got = await askText(L("M02_TreeRename"), [
{ key: "name", label: L("M02_TreeItemName"), value: was },
]);
const name = got?.name.trim();
if (!name || name === was) return;
const cur = opt.getOpen();
const shown =
cur?.kind === kind &&
cur.name === row.이름 &&
cur.layer === at.layer &&
(cur.owner ?? null) === at.owner;
if (shown && !(await opt.confirmLeave())) return;
try {
const doc = await readTemplate(at.layer, kind, row.이름, null, at.owner);
const body = { ...(doc.문서 as Record<string, unknown>), 이름: name };
await saveTemplate(at.layer, kind, row.이름, null, doc.판 ?? "", body, at.owner);
showToast(L("M02_TreeDone"), "success");
await refresh(true);
if (shown) await open({ ...row, 제목: name });
} catch (error) {
showToast(L("M02_ActionFailed").replace("{value}", why(error)), "error");
}
};
/* --- 지우기 · 여럿 · 복사 붙여넣기(구조물 조합 나무 꼴) --- */
const pickedTargets = (): Target[] =>
[...picked].map((id) => targets.get(id)).filter((t): t is Target => !!t);
@@ -302,6 +333,7 @@ export function buildLibrarySection(opt: LibraryOptions): LibraryHandle {
const off = (): string | undefined => (opt.scope().canWrite ? undefined : tc("ReadOnly"));
const single = (): TreeMenuItem[] => [
{ label: L("M02_TreeAddTopFolder"), run: () => void addFolder([]), disabledReason: off() },
{ label: L("M02_TreeRename"), run: () => void renameDoc(row), disabledReason: off() },
{ label: L("M02_TreeCopy").replace("{n}", "1"), run: () => copy([target]) },
{
label: L("M02_Delete"),