executable-stories-react 0.15.0 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +142 -63
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +131 -52
- package/dist/index.js.map +1 -1
- package/dist/interactive.cjs +399 -320
- package/dist/interactive.cjs.map +1 -1
- package/dist/interactive.js +357 -278
- package/dist/interactive.js.map +1 -1
- package/dist/report-island.global.js +55 -54
- package/dist/ssr.cjs +105 -24
- package/dist/ssr.cjs.map +1 -1
- package/dist/ssr.js +92 -11
- package/dist/ssr.js.map +1 -1
- package/dist/tailwind.css +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -522,12 +522,29 @@ function DocVideo({ entry }) {
|
|
|
522
522
|
}
|
|
523
523
|
|
|
524
524
|
// src/components/doc/DocHtml.tsx
|
|
525
|
+
import { useEffect, useRef, useState } from "react";
|
|
525
526
|
import { jsx as jsx14, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
527
|
+
var MEASURE_SCRIPT = "<script>(function(){if(parent===window)return;var last=0,queued=false;var measure=function(){var kids=document.body.children,h=0;for(var i=0;i<kids.length;i++)h=Math.max(h,kids[i].getBoundingClientRect().bottom);return Math.ceil(h||document.body.getBoundingClientRect().bottom)};var post=function(){queued=false;var h=measure();if(h===last)return;last=h;parent.postMessage({__esHtmlHeight:h},'*')};var schedule=function(){if(queued)return;queued=true;requestAnimationFrame(post)};var start=function(){new ResizeObserver(schedule).observe(document.body);new MutationObserver(schedule).observe(document.body,{subtree:true,childList:true,attributes:true,characterData:true});addEventListener('load',schedule);post()};if(document.body)start();else addEventListener('DOMContentLoaded',start)})();</script>";
|
|
528
|
+
var MAX_MEASURED_HEIGHT = 5e3;
|
|
526
529
|
function DocHtml({ entry }) {
|
|
527
|
-
const
|
|
530
|
+
const declaredHeight = typeof entry.height === "number" ? `${entry.height}px` : entry.height ?? "400px";
|
|
528
531
|
const title = entry.title ?? "Embedded HTML";
|
|
529
532
|
const safeHref = safeUrl(entry.url ?? entry.path);
|
|
530
|
-
const
|
|
533
|
+
const frameRef = useRef(null);
|
|
534
|
+
const [measuredHeight, setMeasuredHeight] = useState();
|
|
535
|
+
useEffect(() => {
|
|
536
|
+
if (entry.content === void 0) return;
|
|
537
|
+
const onMessage = (event) => {
|
|
538
|
+
if (event.source !== frameRef.current?.contentWindow) return;
|
|
539
|
+
const reported = event.data?.__esHtmlHeight;
|
|
540
|
+
if (typeof reported !== "number" || !Number.isFinite(reported) || reported <= 0) return;
|
|
541
|
+
setMeasuredHeight(Math.min(reported, MAX_MEASURED_HEIGHT));
|
|
542
|
+
};
|
|
543
|
+
window.addEventListener("message", onMessage);
|
|
544
|
+
return () => window.removeEventListener("message", onMessage);
|
|
545
|
+
}, [entry.content]);
|
|
546
|
+
const height = measuredHeight === void 0 ? declaredHeight : `${measuredHeight}px`;
|
|
547
|
+
const frameProps = entry.content !== void 0 ? { srcDoc: entry.content + MEASURE_SCRIPT } : { src: safeHref ?? "" };
|
|
531
548
|
return /* @__PURE__ */ jsxs9("figure", { className: "my-3 overflow-hidden rounded-md border border-border", children: [
|
|
532
549
|
/* @__PURE__ */ jsxs9("figcaption", { className: "flex items-center justify-between border-b border-border bg-muted/40 px-3 py-1.5 text-xs font-medium text-muted-foreground", children: [
|
|
533
550
|
/* @__PURE__ */ jsx14("span", { children: entry.title ?? "HTML" }),
|
|
@@ -547,6 +564,7 @@ function DocHtml({ entry }) {
|
|
|
547
564
|
/* @__PURE__ */ jsx14(
|
|
548
565
|
"iframe",
|
|
549
566
|
{
|
|
567
|
+
ref: frameRef,
|
|
550
568
|
...frameProps,
|
|
551
569
|
sandbox: "allow-scripts",
|
|
552
570
|
loading: "lazy",
|
|
@@ -1095,7 +1113,7 @@ function ScenarioRunHistory({ scenarioId }) {
|
|
|
1095
1113
|
}
|
|
1096
1114
|
|
|
1097
1115
|
// src/components/ScenarioStaleness.tsx
|
|
1098
|
-
import { useEffect, useState } from "react";
|
|
1116
|
+
import { useEffect as useEffect2, useState as useState2 } from "react";
|
|
1099
1117
|
|
|
1100
1118
|
// src/lib/provenance.ts
|
|
1101
1119
|
function reportLastRunMs(report) {
|
|
@@ -1163,8 +1181,8 @@ import { jsxs as jsxs16 } from "react/jsx-runtime";
|
|
|
1163
1181
|
function ScenarioStaleness({ scenario }) {
|
|
1164
1182
|
const freshness = useScenarioFreshness();
|
|
1165
1183
|
const fixedNow = freshness?.nowMs;
|
|
1166
|
-
const [now, setNow] =
|
|
1167
|
-
|
|
1184
|
+
const [now, setNow] = useState2(fixedNow);
|
|
1185
|
+
useEffect2(() => {
|
|
1168
1186
|
if (fixedNow === void 0) setNow(Date.now());
|
|
1169
1187
|
}, [fixedNow]);
|
|
1170
1188
|
if (!freshness || now === void 0) return null;
|
|
@@ -1178,7 +1196,7 @@ function ScenarioStaleness({ scenario }) {
|
|
|
1178
1196
|
}
|
|
1179
1197
|
|
|
1180
1198
|
// src/interactive/collapse-context.ts
|
|
1181
|
-
import { createContext as createContext4, useCallback, useContext as useContext5, useState as
|
|
1199
|
+
import { createContext as createContext4, useCallback, useContext as useContext5, useState as useState3 } from "react";
|
|
1182
1200
|
var CollapseContext = createContext4(null);
|
|
1183
1201
|
var CollapseProvider = CollapseContext.Provider;
|
|
1184
1202
|
function useCollapse() {
|
|
@@ -1752,25 +1770,86 @@ function ReportErrorShell({
|
|
|
1752
1770
|
return /* @__PURE__ */ jsx36("main", { className: cn("es-report", className), "aria-label": title ?? "Test report", "data-theme": dataTheme, children: /* @__PURE__ */ jsx36(ReportSchemaError, { error }) });
|
|
1753
1771
|
}
|
|
1754
1772
|
|
|
1755
|
-
// src/components/
|
|
1773
|
+
// src/components/ReportSpanGraph.tsx
|
|
1774
|
+
import { deriveSpanGraph, spanGraphNodeMark, spanGraphToMermaid } from "executable-stories-core/span-graph";
|
|
1775
|
+
import { useMemo as useMemo2 } from "react";
|
|
1756
1776
|
import { jsx as jsx37, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
1777
|
+
var LANE_LABEL = {
|
|
1778
|
+
edge: "Edge",
|
|
1779
|
+
service: "Service",
|
|
1780
|
+
queue: "Queue",
|
|
1781
|
+
datastore: "Data"
|
|
1782
|
+
};
|
|
1783
|
+
var MARK_LABEL = {
|
|
1784
|
+
failing: "Failing",
|
|
1785
|
+
added: "New",
|
|
1786
|
+
changed: "Changed"
|
|
1787
|
+
};
|
|
1788
|
+
var MARK_CLASS = {
|
|
1789
|
+
failing: "text-fail",
|
|
1790
|
+
added: "text-pass",
|
|
1791
|
+
changed: "text-pend"
|
|
1792
|
+
};
|
|
1793
|
+
function MarkBadge({ node }) {
|
|
1794
|
+
const mark = spanGraphNodeMark(node);
|
|
1795
|
+
if (!mark) return null;
|
|
1796
|
+
return /* @__PURE__ */ jsx37("span", { className: cn("ml-2 text-xs font-medium", MARK_CLASS[mark]), children: MARK_LABEL[mark] });
|
|
1797
|
+
}
|
|
1798
|
+
function ReportSpanGraph() {
|
|
1799
|
+
const report = useReport();
|
|
1800
|
+
const { code, graph, titleById } = useMemo2(() => {
|
|
1801
|
+
const scenarios = report.features.flatMap((feature) => feature.scenarios);
|
|
1802
|
+
const derived = deriveSpanGraph(scenarios);
|
|
1803
|
+
return {
|
|
1804
|
+
graph: derived,
|
|
1805
|
+
code: spanGraphToMermaid(derived),
|
|
1806
|
+
titleById: new Map(scenarios.map((scenario) => [scenario.id, scenario.title]))
|
|
1807
|
+
};
|
|
1808
|
+
}, [report]);
|
|
1809
|
+
if (code === "") return null;
|
|
1810
|
+
return /* @__PURE__ */ jsxs25("section", { className: "es-span-graph mt-6", "aria-labelledby": "es-span-graph-heading", children: [
|
|
1811
|
+
/* @__PURE__ */ jsx37("h2", { id: "es-span-graph-heading", className: "text-base font-semibold text-foreground", children: "Architecture, as it ran" }),
|
|
1812
|
+
/* @__PURE__ */ jsx37("p", { className: "mt-1 text-sm text-muted-foreground", children: "Derived from this run\u2019s traces. Every component was named by a span while a scenario ran, so nothing here is inferred from the code. Instrumented, exercised paths only: a component no scenario reaches does not appear." }),
|
|
1813
|
+
/* @__PURE__ */ jsx37(DocMermaid, { entry: { kind: "mermaid", phase: "static", code } }),
|
|
1814
|
+
/* @__PURE__ */ jsxs25("table", { className: "mt-2 w-full text-left text-sm", children: [
|
|
1815
|
+
/* @__PURE__ */ jsx37("caption", { className: "sr-only", children: "Each component and the scenarios that exercised it" }),
|
|
1816
|
+
/* @__PURE__ */ jsx37("thead", { children: /* @__PURE__ */ jsxs25("tr", { className: "text-xs text-muted-foreground", children: [
|
|
1817
|
+
/* @__PURE__ */ jsx37("th", { scope: "col", className: "py-1 pr-4 font-medium", children: "Component" }),
|
|
1818
|
+
/* @__PURE__ */ jsx37("th", { scope: "col", className: "py-1 pr-4 font-medium", children: "Lane" }),
|
|
1819
|
+
/* @__PURE__ */ jsx37("th", { scope: "col", className: "py-1 font-medium", children: "Covered by" })
|
|
1820
|
+
] }) }),
|
|
1821
|
+
/* @__PURE__ */ jsx37("tbody", { children: graph.nodes.map((node) => /* @__PURE__ */ jsxs25("tr", { className: "border-t border-border align-top", children: [
|
|
1822
|
+
/* @__PURE__ */ jsxs25("th", { scope: "row", className: "py-1.5 pr-4 font-mono text-xs font-normal", children: [
|
|
1823
|
+
node.id,
|
|
1824
|
+
/* @__PURE__ */ jsx37(MarkBadge, { node })
|
|
1825
|
+
] }),
|
|
1826
|
+
/* @__PURE__ */ jsx37("td", { className: "py-1.5 pr-4 text-xs text-muted-foreground", children: LANE_LABEL[node.kind] }),
|
|
1827
|
+
/* @__PURE__ */ jsx37("td", { className: "py-1.5", children: /* @__PURE__ */ jsx37("ul", { className: "flex flex-col gap-0.5", children: node.scenarioIds.map((id) => /* @__PURE__ */ jsx37("li", { children: /* @__PURE__ */ jsx37("a", { href: `#${id}`, className: "text-xs underline underline-offset-2", children: titleById.get(id) ?? id }) }, id)) }) })
|
|
1828
|
+
] }, node.id)) })
|
|
1829
|
+
] })
|
|
1830
|
+
] });
|
|
1831
|
+
}
|
|
1832
|
+
|
|
1833
|
+
// src/components/Report.tsx
|
|
1834
|
+
import { jsx as jsx38, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
1757
1835
|
function Report(props) {
|
|
1758
1836
|
const { report, customRenderers, renderers, className, title, dataTheme } = props;
|
|
1759
1837
|
const result = unwrapReport(report);
|
|
1760
1838
|
if (!result.ok) {
|
|
1761
|
-
return /* @__PURE__ */
|
|
1839
|
+
return /* @__PURE__ */ jsx38(ReportErrorShell, { error: result.error, className, title, dataTheme });
|
|
1762
1840
|
}
|
|
1763
1841
|
const data = result.data;
|
|
1764
1842
|
const hasContent = data.features.length > 0;
|
|
1765
|
-
return /* @__PURE__ */
|
|
1766
|
-
/* @__PURE__ */
|
|
1767
|
-
|
|
1843
|
+
return /* @__PURE__ */ jsx38(ReportRoot, { report: data, customRenderers, renderers, children: /* @__PURE__ */ jsxs26("main", { className: cn("es-report", className), "aria-label": title ?? "Test report", "data-theme": dataTheme, children: [
|
|
1844
|
+
/* @__PURE__ */ jsx38("header", { className: "es-report-header", children: /* @__PURE__ */ jsx38(ReportTitleBlock, { title }) }),
|
|
1845
|
+
/* @__PURE__ */ jsx38(ReportSpanGraph, {}),
|
|
1846
|
+
hasContent ? /* @__PURE__ */ jsx38(ReportFeatureList, {}) : /* @__PURE__ */ jsx38(ReportEmpty, {})
|
|
1768
1847
|
] }) });
|
|
1769
1848
|
}
|
|
1770
1849
|
|
|
1771
1850
|
// src/components/doc/MermaidView.tsx
|
|
1772
|
-
import { useEffect as
|
|
1773
|
-
import { Fragment as Fragment11, jsx as
|
|
1851
|
+
import { useEffect as useEffect3, useRef as useRef2, useState as useState4 } from "react";
|
|
1852
|
+
import { Fragment as Fragment11, jsx as jsx39, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
1774
1853
|
function prefersDark(el) {
|
|
1775
1854
|
const themed = el?.closest("[data-theme]");
|
|
1776
1855
|
if (themed?.dataset.theme === "dark") return true;
|
|
@@ -1778,10 +1857,10 @@ function prefersDark(el) {
|
|
|
1778
1857
|
return typeof window !== "undefined" && !!window.matchMedia?.("(prefers-color-scheme: dark)").matches;
|
|
1779
1858
|
}
|
|
1780
1859
|
function MermaidView({ entry, load }) {
|
|
1781
|
-
const ref =
|
|
1782
|
-
const [svg, setSvg] =
|
|
1783
|
-
const [error, setError] =
|
|
1784
|
-
|
|
1860
|
+
const ref = useRef2(null);
|
|
1861
|
+
const [svg, setSvg] = useState4(null);
|
|
1862
|
+
const [error, setError] = useState4(null);
|
|
1863
|
+
useEffect3(() => {
|
|
1785
1864
|
let cancelled = false;
|
|
1786
1865
|
const draw = async () => {
|
|
1787
1866
|
let mermaid;
|
|
@@ -1824,9 +1903,9 @@ function MermaidView({ entry, load }) {
|
|
|
1824
1903
|
};
|
|
1825
1904
|
}, [entry.code, load]);
|
|
1826
1905
|
if (svg) {
|
|
1827
|
-
return /* @__PURE__ */
|
|
1828
|
-
entry.title ? /* @__PURE__ */
|
|
1829
|
-
/* @__PURE__ */
|
|
1906
|
+
return /* @__PURE__ */ jsxs27("figure", { ref, className: "my-3", children: [
|
|
1907
|
+
entry.title ? /* @__PURE__ */ jsx39("figcaption", { className: "mb-1.5 text-xs font-medium text-muted-foreground", children: entry.title }) : null,
|
|
1908
|
+
/* @__PURE__ */ jsx39(
|
|
1830
1909
|
"div",
|
|
1831
1910
|
{
|
|
1832
1911
|
role: "img",
|
|
@@ -1837,8 +1916,8 @@ function MermaidView({ entry, load }) {
|
|
|
1837
1916
|
)
|
|
1838
1917
|
] });
|
|
1839
1918
|
}
|
|
1840
|
-
return /* @__PURE__ */
|
|
1841
|
-
error ? /* @__PURE__ */
|
|
1919
|
+
return /* @__PURE__ */ jsxs27(Fragment11, { children: [
|
|
1920
|
+
error ? /* @__PURE__ */ jsxs27(
|
|
1842
1921
|
"p",
|
|
1843
1922
|
{
|
|
1844
1923
|
role: "alert",
|
|
@@ -1850,34 +1929,34 @@ function MermaidView({ entry, load }) {
|
|
|
1850
1929
|
]
|
|
1851
1930
|
}
|
|
1852
1931
|
) : null,
|
|
1853
|
-
/* @__PURE__ */
|
|
1932
|
+
/* @__PURE__ */ jsx39(MermaidSource, { entry, ref })
|
|
1854
1933
|
] });
|
|
1855
1934
|
}
|
|
1856
1935
|
|
|
1857
1936
|
// src/components/doc/MermaidDiagram.tsx
|
|
1858
|
-
import { jsx as
|
|
1937
|
+
import { jsx as jsx40 } from "react/jsx-runtime";
|
|
1859
1938
|
var mermaidLoader;
|
|
1860
1939
|
function loadMermaid() {
|
|
1861
1940
|
mermaidLoader ??= import("mermaid").then((m) => m.default);
|
|
1862
1941
|
return mermaidLoader;
|
|
1863
1942
|
}
|
|
1864
1943
|
function MermaidDiagram({ entry, load = loadMermaid }) {
|
|
1865
|
-
return /* @__PURE__ */
|
|
1944
|
+
return /* @__PURE__ */ jsx40(MermaidView, { entry, load });
|
|
1866
1945
|
}
|
|
1867
1946
|
|
|
1868
1947
|
// src/components/ScenarioExplorer.tsx
|
|
1869
|
-
import { useState as
|
|
1948
|
+
import { useState as useState5 } from "react";
|
|
1870
1949
|
|
|
1871
1950
|
// src/components/ui/command.tsx
|
|
1872
1951
|
import "react";
|
|
1873
1952
|
import { Command as CommandPrimitive } from "cmdk";
|
|
1874
1953
|
import { SearchIcon } from "lucide-react";
|
|
1875
|
-
import { jsx as
|
|
1954
|
+
import { jsx as jsx41, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
1876
1955
|
function Command({
|
|
1877
1956
|
className,
|
|
1878
1957
|
...props
|
|
1879
1958
|
}) {
|
|
1880
|
-
return /* @__PURE__ */
|
|
1959
|
+
return /* @__PURE__ */ jsx41(
|
|
1881
1960
|
CommandPrimitive,
|
|
1882
1961
|
{
|
|
1883
1962
|
"data-slot": "command",
|
|
@@ -1893,14 +1972,14 @@ function CommandInput({
|
|
|
1893
1972
|
className,
|
|
1894
1973
|
...props
|
|
1895
1974
|
}) {
|
|
1896
|
-
return /* @__PURE__ */
|
|
1975
|
+
return /* @__PURE__ */ jsxs28(
|
|
1897
1976
|
"div",
|
|
1898
1977
|
{
|
|
1899
1978
|
"data-slot": "command-input-wrapper",
|
|
1900
1979
|
className: "flex h-9 items-center gap-2 border-b px-3",
|
|
1901
1980
|
children: [
|
|
1902
|
-
/* @__PURE__ */
|
|
1903
|
-
/* @__PURE__ */
|
|
1981
|
+
/* @__PURE__ */ jsx41(SearchIcon, { className: "size-4 shrink-0 opacity-50" }),
|
|
1982
|
+
/* @__PURE__ */ jsx41(
|
|
1904
1983
|
CommandPrimitive.Input,
|
|
1905
1984
|
{
|
|
1906
1985
|
"data-slot": "command-input",
|
|
@@ -1919,7 +1998,7 @@ function CommandList({
|
|
|
1919
1998
|
className,
|
|
1920
1999
|
...props
|
|
1921
2000
|
}) {
|
|
1922
|
-
return /* @__PURE__ */
|
|
2001
|
+
return /* @__PURE__ */ jsx41(
|
|
1923
2002
|
CommandPrimitive.List,
|
|
1924
2003
|
{
|
|
1925
2004
|
"data-slot": "command-list",
|
|
@@ -1934,7 +2013,7 @@ function CommandList({
|
|
|
1934
2013
|
function CommandEmpty({
|
|
1935
2014
|
...props
|
|
1936
2015
|
}) {
|
|
1937
|
-
return /* @__PURE__ */
|
|
2016
|
+
return /* @__PURE__ */ jsx41(
|
|
1938
2017
|
CommandPrimitive.Empty,
|
|
1939
2018
|
{
|
|
1940
2019
|
"data-slot": "command-empty",
|
|
@@ -1947,7 +2026,7 @@ function CommandGroup({
|
|
|
1947
2026
|
className,
|
|
1948
2027
|
...props
|
|
1949
2028
|
}) {
|
|
1950
|
-
return /* @__PURE__ */
|
|
2029
|
+
return /* @__PURE__ */ jsx41(
|
|
1951
2030
|
CommandPrimitive.Group,
|
|
1952
2031
|
{
|
|
1953
2032
|
"data-slot": "command-group",
|
|
@@ -1963,7 +2042,7 @@ function CommandItem({
|
|
|
1963
2042
|
className,
|
|
1964
2043
|
...props
|
|
1965
2044
|
}) {
|
|
1966
|
-
return /* @__PURE__ */
|
|
2045
|
+
return /* @__PURE__ */ jsx41(
|
|
1967
2046
|
CommandPrimitive.Item,
|
|
1968
2047
|
{
|
|
1969
2048
|
"data-slot": "command-item",
|
|
@@ -1977,7 +2056,7 @@ function CommandItem({
|
|
|
1977
2056
|
}
|
|
1978
2057
|
|
|
1979
2058
|
// src/components/ScenarioExplorer.tsx
|
|
1980
|
-
import { jsx as
|
|
2059
|
+
import { jsx as jsx42, jsxs as jsxs29 } from "react/jsx-runtime";
|
|
1981
2060
|
var STATUS_FILTERS = [
|
|
1982
2061
|
{ value: "all", label: "All" },
|
|
1983
2062
|
{ value: "passed", label: "Passed" },
|
|
@@ -1986,24 +2065,24 @@ var STATUS_FILTERS = [
|
|
|
1986
2065
|
{ value: "pending", label: "Pending" }
|
|
1987
2066
|
];
|
|
1988
2067
|
function ScenarioExplorer({ scenarios, summary }) {
|
|
1989
|
-
const [status, setStatus] =
|
|
2068
|
+
const [status, setStatus] = useState5("all");
|
|
1990
2069
|
const visible = status === "all" ? scenarios : scenarios.filter((s) => s.status === status);
|
|
1991
|
-
return /* @__PURE__ */
|
|
1992
|
-
summary ? /* @__PURE__ */
|
|
2070
|
+
return /* @__PURE__ */ jsxs29("div", { className: "font-sans text-foreground", children: [
|
|
2071
|
+
summary ? /* @__PURE__ */ jsxs29("p", { className: "mb-3 text-sm text-muted-foreground", children: [
|
|
1993
2072
|
summary.total,
|
|
1994
2073
|
" scenarios \xB7 ",
|
|
1995
|
-
/* @__PURE__ */
|
|
2074
|
+
/* @__PURE__ */ jsxs29("span", { className: "text-pass", children: [
|
|
1996
2075
|
summary.passed,
|
|
1997
2076
|
" passed"
|
|
1998
2077
|
] }),
|
|
1999
2078
|
" \xB7",
|
|
2000
2079
|
" ",
|
|
2001
|
-
/* @__PURE__ */
|
|
2080
|
+
/* @__PURE__ */ jsxs29("span", { className: "text-fail", children: [
|
|
2002
2081
|
summary.failed,
|
|
2003
2082
|
" failed"
|
|
2004
2083
|
] })
|
|
2005
2084
|
] }) : null,
|
|
2006
|
-
/* @__PURE__ */
|
|
2085
|
+
/* @__PURE__ */ jsx42("div", { className: "mb-2 flex flex-wrap gap-1.5", role: "group", "aria-label": "Filter by status", children: STATUS_FILTERS.map((f) => /* @__PURE__ */ jsx42(
|
|
2007
2086
|
"button",
|
|
2008
2087
|
{
|
|
2009
2088
|
type: "button",
|
|
@@ -2018,26 +2097,26 @@ function ScenarioExplorer({ scenarios, summary }) {
|
|
|
2018
2097
|
},
|
|
2019
2098
|
f.value
|
|
2020
2099
|
)) }),
|
|
2021
|
-
/* @__PURE__ */
|
|
2100
|
+
/* @__PURE__ */ jsxs29(
|
|
2022
2101
|
Command,
|
|
2023
2102
|
{
|
|
2024
2103
|
className: "rounded-lg border border-border bg-card",
|
|
2025
2104
|
filter: (value, search) => value.toLowerCase().includes(search.toLowerCase()) ? 1 : 0,
|
|
2026
2105
|
children: [
|
|
2027
|
-
/* @__PURE__ */
|
|
2028
|
-
/* @__PURE__ */
|
|
2029
|
-
/* @__PURE__ */
|
|
2030
|
-
/* @__PURE__ */
|
|
2106
|
+
/* @__PURE__ */ jsx42(CommandInput, { placeholder: "Search scenarios\u2026" }),
|
|
2107
|
+
/* @__PURE__ */ jsxs29(CommandList, { className: "max-h-none", children: [
|
|
2108
|
+
/* @__PURE__ */ jsx42(CommandEmpty, { children: "No scenarios match your filters." }),
|
|
2109
|
+
/* @__PURE__ */ jsx42(CommandGroup, { children: visible.map((s) => /* @__PURE__ */ jsx42(
|
|
2031
2110
|
CommandItem,
|
|
2032
2111
|
{
|
|
2033
2112
|
value: `${s.title} ${s.feature} ${s.tags.join(" ")}`,
|
|
2034
2113
|
asChild: true,
|
|
2035
2114
|
className: "cursor-pointer",
|
|
2036
|
-
children: /* @__PURE__ */
|
|
2037
|
-
/* @__PURE__ */
|
|
2038
|
-
/* @__PURE__ */
|
|
2039
|
-
s.tags.slice(0, 3).map((t) => /* @__PURE__ */
|
|
2040
|
-
/* @__PURE__ */
|
|
2115
|
+
children: /* @__PURE__ */ jsxs29("a", { href: s.href, className: "flex items-center gap-3", children: [
|
|
2116
|
+
/* @__PURE__ */ jsx42(Badge, { variant: s.status, children: s.status }),
|
|
2117
|
+
/* @__PURE__ */ jsx42("span", { className: "min-w-0 flex-1 truncate font-medium", children: s.title }),
|
|
2118
|
+
s.tags.slice(0, 3).map((t) => /* @__PURE__ */ jsx42(Badge, { variant: "tag", className: "hidden sm:inline-flex", children: t }, t)),
|
|
2119
|
+
/* @__PURE__ */ jsx42("code", { className: "hidden font-mono text-xs text-muted-foreground md:inline", children: s.feature })
|
|
2041
2120
|
] })
|
|
2042
2121
|
},
|
|
2043
2122
|
s.id
|