feat(dashboard): nav restructure, full context-help coverage, 11 new ref docs

Navigation:
- New order: Overview · Todo · Domains · Repos · Workstreams (collapsible,
  open:false, with atomic sub-entries: Decisions, Tasks, Debt, Extends,
  Dependencies) · Contributions · SBOM · Progress · Reference (collapsible)
- Reference section gains path:/reference landing page; all 18 doc pages
  listed in nav (alphabetical) and in reference.md table

New pages:
- todo.md — Internal / Ecosystem / Third-party todo classification
- dependencies.md — dependency edge table derived from state/summary
- reference.md — Reference landing page with full doc index

New reference doc pages (11):
  contributions, debt, dependencies, domains, extensions, overview,
  repos, tasks, todo + reference (meta) already added previously

doc-overlay.js — lazy bubblehelp tooltip:
- _titleCache Map + _fetchDocTitle(docPath): on first hover of any ?
  button, fetches the target doc page, parses <h1>, sets btn.title
- Native browser tooltip appears exactly on the ? circle on subsequent hover

Context-help wired on all 14 dashboard pages:
- h1 withDocHelp added to: index, todo, domains, repos, tasks, techdept,
  extensions, dependencies (contributions/workstreams/decisions/sbom/
  progress/reference were already wired)
- domains.md + repos.md: added missing withDocHelp import and live-data link
- tasks/techdept/extensions: removed duplicate _h1 const that caused
  SyntaxError: Identifier '_h1' has already been declared

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-01 23:46:26 +01:00
parent 70c8e3cd51
commit 947c2e8824
22 changed files with 1468 additions and 25 deletions

View File

@@ -12,7 +12,21 @@
* The ? button is invisible until the user hovers over the element.
*/
const _STYLE_ID = "doc-overlay-styles";
const _STYLE_ID = "doc-overlay-styles";
const _titleCache = new Map();
async function _fetchDocTitle(docPath) {
if (_titleCache.has(docPath)) return _titleCache.get(docPath);
try {
const res = await fetch(docPath);
if (!res.ok) return null;
const parser = new DOMParser();
const doc = parser.parseFromString(await res.text(), "text/html");
const title = doc.querySelector("h1")?.textContent?.trim() ?? null;
if (title) _titleCache.set(docPath, title);
return title;
} catch { return null; }
}
function _ensureStyles() {
if (typeof document === "undefined" || document.getElementById(_STYLE_ID)) return;
@@ -195,6 +209,14 @@ export function withDocHelp(element, docPath) {
btn.setAttribute("aria-label", "Open documentation");
btn.addEventListener("click", e => { e.stopPropagation(); _openOverlay(docPath); });
// Lazy-load the h1 of the target doc page as a native tooltip (bubblehelp)
btn.addEventListener("mouseenter", async () => {
if (btn.dataset.titleFetched) return;
btn.dataset.titleFetched = "1";
const title = await _fetchDocTitle(docPath);
if (title) btn.title = title;
}, {once: true});
element.append(btn);
return element;
}