Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015KYZ2HWWdUwZWYnn3tQz7X
72 lines
2.6 KiB
TypeScript
72 lines
2.6 KiB
TypeScript
/* =============================================================================
|
|
* M02_MasterTemplete_DetailNav.ts
|
|
* 상세 머리 제목과 [?] 사이 [도면][일위대가][면적산출] 묶음(105-4) — 같은 열의 다른 상세로 옮겨 감.
|
|
* 지금 상세 = 눌림(aria-pressed) · 그 열 문서가 없으면 그 단추 꺼짐(번호 목록에 번호 없음).
|
|
* 보임 조건 · 옮겨 가기(confirmLeave → open)는 부른 쪽(`UI_Main`) 몫.
|
|
* ========================================================================== */
|
|
|
|
import { createButton, el } from "@ui/ui_template_elements";
|
|
import {
|
|
fetchStructureNumbers,
|
|
getActiveLayer,
|
|
type Kind,
|
|
type Layer,
|
|
type StructureNumbers,
|
|
} from "./M02_MasterTemplete_Api_Fetch";
|
|
|
|
type DetailKind = "structure" | "labor" | "area";
|
|
|
|
const ITEMS: [DetailKind, string, keyof StructureNumbers][] = [
|
|
["structure", "도면", "도번"],
|
|
["labor", "일위대가", "일위대가번"],
|
|
["area", "면적산출", "면적번"],
|
|
];
|
|
const TIP = "같은 열의 다른 상세로 — 저장 안 한 고침이 있으면 물음";
|
|
const NONE = "이 열은 문서가 없음";
|
|
|
|
export interface DetailNav {
|
|
root: HTMLElement;
|
|
/** 연 상세 — null 이면 숨김 · 눌림 · 꺼짐을 새로 */
|
|
update: (at: { layer: Layer; kind: Kind; name: string } | null) => void;
|
|
}
|
|
|
|
export function createDetailNav(go: (kind: DetailKind) => void): DetailNav {
|
|
const buttons = ITEMS.map(([kind, label]) => {
|
|
const button = createButton({ label, size: "sm", variant: "ghost", onClick: () => go(kind) });
|
|
button.dataset.detailNav = kind;
|
|
return button;
|
|
});
|
|
const root = el("div", {
|
|
className: "ui-btn-group m02-main__nav",
|
|
attrs: { role: "group", "aria-label": TIP },
|
|
children: buttons,
|
|
});
|
|
let ask = 0;
|
|
|
|
const update: DetailNav["update"] = (at) => {
|
|
root.hidden = !at;
|
|
const mine = ++ask;
|
|
buttons.forEach((button, i) => {
|
|
const on = ITEMS[i][0] === at?.kind;
|
|
button.setAttribute("aria-pressed", String(on)); // 눌림 = 지금 상세(누르면 그대로)
|
|
button.disabled = false;
|
|
button.title = on ? "" : TIP;
|
|
});
|
|
// 번호 목록은 지금 층만(프로젝트 층 · 남의 층이면 안 끔)
|
|
if (!at || at.layer === "project" || at.layer !== getActiveLayer()) return;
|
|
void fetchStructureNumbers().then(
|
|
(numbers) => {
|
|
if (mine !== ask) return;
|
|
buttons.forEach((button, i) => {
|
|
const [kind, , field] = ITEMS[i];
|
|
if (kind === at.kind || numbers[at.name]?.[field]) return;
|
|
button.disabled = true;
|
|
button.title = NONE;
|
|
});
|
|
},
|
|
() => undefined,
|
|
);
|
|
};
|
|
return { root, update };
|
|
}
|