/* =============================================================================
* ui_template_help.ts
* [?] 설명서(54-2) — 좌측 패널 아래 단추 묶음 맨 왼쪽 단추 + 모달(왼쪽 차례 · 오른쪽 글). B02~B09 공용.
* 글 = `resources/help/<페이지>/*.md` — 서버가 열 때마다 읽음(파일만 고치면 다음에 열 때 바뀜).
* 페이지 = 주소(#/b05-…)의 B0N · 먼저 여는 항목 = 좌측 패널에서 보이는 `[data-help-topic]` 중 마지막
* (지금 연 상자 · 구조물 종류) · 없으면 첫 파일(00_설명서).
* 단추 자리 = `.ui-sidebar-actions` 안 `[data-help-row]`(없으면 그 줄 자신)의 맨 앞.
* ========================================================================== */
import "./ui_template_help.css";
import { API_BASE_URL } from "@config/config_frontend";
import { createButton, el } from "./ui_template_elements";
import { openModal } from "./ui_template_modal";
interface HelpItem {
key: string;
title: string;
text: string;
}
const TEXT = { button: "?", tip: "설명서", title: "설명서", close: "닫기", empty: "설명 글 없음" };
function currentPage(): string {
const n = /^#\/b0(\d)/i.exec(location.hash)?.[1];
return n ? `B0${n}` : "";
}
function escapeHtml(text: string): string {
return text.replace(
/[&<>"]/g,
(c) => `&${{ "&": "amp", "<": "lt", ">": "gt", '"': "quot" }[c]};`,
);
}
function inline(text: string): string {
return escapeHtml(text)
.replace(/\*\*(.+?)\*\*/g, "$1")
.replace(/`(.+?)`/g, "$1");
}
/** 메모장 글에 쓸 만큼만 — 제목(#) · 목록(- · 1.) · 문단 · **굵게** · `코드` */
export function renderHelpMarkdown(text: string): string {
const out: string[] = [];
let list: "ul" | "ol" | null = null;
let para: string[] = [];
const flush = (): void => {
if (para.length) out.push(`
${para.map(inline).join("
")}
${TEXT.empty}
`; article.dataset.helpKey = key; toc .querySelectorAll("button") .forEach((b) => b.classList.toggle("is-active", b.dataset.helpKey === key)); }; for (const item of items) { const link = el("button", { className: "ui-help__link", text: item.title, attrs: { type: "button" }, }); link.dataset.helpKey = item.key; link.addEventListener("click", () => show(item.key)); toc.append(link); } body.append(el("div", { className: "ui-help__grid", children: [toc, article] })); show(first ?? items[0]?.key ?? ""); }, }); } export function createHelpButton(): HTMLButtonElement { const button = createButton({ label: TEXT.button, variant: "ghost", onClick: () => void openHelp(), }); button.classList.add("ui-help-btn"); button.title = button.ariaLabel = TEXT.tip; return button; } /** 아래 단추 묶음에 [?] 를 한 번 — `[data-help-row]` 가 있으면 그 줄 · 없으면 묶음 자신의 맨 앞 */ export function placeHelpButton(actions: HTMLElement): void { if (actions.querySelector(".ui-help-btn")) return; (actions.querySelector