+ This dashboard requires values for the following filter{missingRequiredFilters.length > + 1 + ? "s" + : ""}: +
+- This dashboard requires values for the following filter{missingRequiredFilters.length > - 1 - ? "s" - : ""}: -
-{errorMessage}
diff --git a/web-common/src/features/canvas/toc/CanvasTableOfContents.svelte b/web-common/src/features/canvas/toc/CanvasTableOfContents.svelte new file mode 100644 index 000000000000..0824ae8a1b1d --- /dev/null +++ b/web-common/src/features/canvas/toc/CanvasTableOfContents.svelte @@ -0,0 +1,148 @@ + + +{#if toc && toc.entries.length > 1} + + +{/if} + + diff --git a/web-common/src/features/canvas/toc/toc-controller.svelte.spec.ts b/web-common/src/features/canvas/toc/toc-controller.svelte.spec.ts new file mode 100644 index 000000000000..8503fb14d2e8 --- /dev/null +++ b/web-common/src/features/canvas/toc/toc-controller.svelte.spec.ts @@ -0,0 +1,157 @@ +import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; +import { CanvasTocController } from "./toc-controller.svelte"; +import { CANVAS_TOC_REFRESH_EVENT } from "./toc"; + +// Controllable IntersectionObserver mock: capture the callback so tests can drive intersections. +let ioCallback: IntersectionObserverCallback; +const observe = vi.fn(); +const disconnect = vi.fn(); + +class MockIntersectionObserver { + constructor(cb: IntersectionObserverCallback) { + ioCallback = cb; + } + observe = observe; + unobserve = vi.fn(); + disconnect = disconnect; + takeRecords = vi.fn(); +} + +function fireIntersections(states: Recordno headings
"))).toEqual([]); + }); + + it("only picks up headings inside .canvas-markdown", () => { + const root = buildRoot(` +