import { StatusField } from "../../../widgets/status-field.js"; /** * Run the user-facing Markdown and JSON export actions for one CMap. * * Export generation is supplied by the workspace. This controller owns export * options, progress messages, clipboard handling and browser downloads. */ export class CmapExportDialog { constructor(dialog, tr, buildMarkdown, buildJson) { this.dialog = dialog; this.tr = tr; this.buildMarkdown = buildMarkdown; this.buildJson = buildJson; this.form = dialog.querySelector("form"); this.depth = dialog.querySelector("#cmap-export-depth"); this.pages = dialog.querySelector("#cmap-export-pages"); this.status = new StatusField(dialog.querySelector("#cmap-export-status")); this.conceptMapSlug = "concept-map"; dialog.querySelector("#cmap-export-cancel").addEventListener("click", () => dialog.close()); dialog.querySelector("#cmap-export-copy").addEventListener("click", () => { this.exportMarkdown(false); }); dialog.querySelector("#cmap-export-json").addEventListener("click", () => { this.exportJson(); }); this.form.addEventListener("submit", (event) => { event.preventDefault(); this.exportMarkdown(true); }); } open(conceptMapSlug) { this.conceptMapSlug = conceptMapSlug; this.status.clear(); this.dialog.showModal(); this.depth.focus(); } options() { return { depth: Math.max(0, Math.min(10, Number(this.depth.value) || 0)), includeWikiPages: this.pages.checked }; } async exportJson() { this.status.set(this.tr("preparing-cmap-json", "Preparing complete CMap JSON…")); try { const bundle = await this.buildJson(this.options().depth); this.download(`${JSON.stringify(bundle, null, 2)}\n`, `${bundle.rootCmapSlug}-cmap.json`, "application/json;charset=utf-8"); this.status.set(this.tr("cmap-json-downloaded", "CMap JSON downloaded.")); return true; } catch (error) { this.status.set(error.message); return false; } } async exportMarkdown(download) { this.status.set(this.tr("preparing-markdown-export", "Preparing Markdown export…")); try { const markdown = await this.buildMarkdown(this.options()); if (download) { this.download(markdown, `${this.conceptMapSlug}-report.md`, "text/markdown;charset=utf-8"); this.status.set(this.tr("markdown-export-downloaded", "Markdown export downloaded.")); } else { await this.copy(markdown); this.status.set(this.tr("markdown-export-copied", "Markdown export copied.")); } return true; } catch (error) { this.status.set(error.message); return false; } } download(text, filename, contentType) { const blob = new Blob([text], { type: contentType }); const url = URL.createObjectURL(blob); const link = document.createElement("a"); link.href = url; link.download = filename; document.body.append(link); link.click(); link.remove(); window.setTimeout(() => URL.revokeObjectURL(url), 0); } async copy(text) { try { await navigator.clipboard.writeText(text); } catch (_error) { const input = document.createElement("textarea"); input.value = text; input.style.position = "fixed"; input.style.left = "-10000px"; document.body.append(input); input.select(); document.execCommand("copy"); input.remove(); } } }