executable-stories-react 0.15.0 → 0.17.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 +147 -65
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +136 -54
- package/dist/index.js.map +1 -1
- package/dist/interactive.cjs +439 -332
- package/dist/interactive.cjs.map +1 -1
- package/dist/interactive.d.cts +6 -0
- package/dist/interactive.d.ts +6 -0
- package/dist/interactive.js +397 -290
- package/dist/interactive.js.map +1 -1
- package/dist/report-island.global.js +55 -54
- package/dist/ssr.cjs +111 -28
- package/dist/ssr.cjs.map +1 -1
- package/dist/ssr.d.cts +2 -0
- package/dist/ssr.d.ts +2 -0
- package/dist/ssr.js +99 -16
- package/dist/ssr.js.map +1 -1
- package/dist/tailwind.css +1 -1
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -611,12 +611,29 @@ function DocVideo({ entry }) {
|
|
|
611
611
|
}
|
|
612
612
|
|
|
613
613
|
// src/components/doc/DocHtml.tsx
|
|
614
|
+
var import_react5 = require("react");
|
|
614
615
|
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
616
|
+
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>";
|
|
617
|
+
var MAX_MEASURED_HEIGHT = 5e3;
|
|
615
618
|
function DocHtml({ entry }) {
|
|
616
|
-
const
|
|
619
|
+
const declaredHeight = typeof entry.height === "number" ? `${entry.height}px` : entry.height ?? "400px";
|
|
617
620
|
const title = entry.title ?? "Embedded HTML";
|
|
618
621
|
const safeHref = (0, import_url.safeUrl)(entry.url ?? entry.path);
|
|
619
|
-
const
|
|
622
|
+
const frameRef = (0, import_react5.useRef)(null);
|
|
623
|
+
const [measuredHeight, setMeasuredHeight] = (0, import_react5.useState)();
|
|
624
|
+
(0, import_react5.useEffect)(() => {
|
|
625
|
+
if (entry.content === void 0) return;
|
|
626
|
+
const onMessage = (event) => {
|
|
627
|
+
if (event.source !== frameRef.current?.contentWindow) return;
|
|
628
|
+
const reported = event.data?.__esHtmlHeight;
|
|
629
|
+
if (typeof reported !== "number" || !Number.isFinite(reported) || reported <= 0) return;
|
|
630
|
+
setMeasuredHeight(Math.min(reported, MAX_MEASURED_HEIGHT));
|
|
631
|
+
};
|
|
632
|
+
window.addEventListener("message", onMessage);
|
|
633
|
+
return () => window.removeEventListener("message", onMessage);
|
|
634
|
+
}, [entry.content]);
|
|
635
|
+
const height = measuredHeight === void 0 ? declaredHeight : `${measuredHeight}px`;
|
|
636
|
+
const frameProps = entry.content !== void 0 ? { srcDoc: entry.content + MEASURE_SCRIPT } : { src: safeHref ?? "" };
|
|
620
637
|
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("figure", { className: "my-3 overflow-hidden rounded-md border border-border", children: [
|
|
621
638
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("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: [
|
|
622
639
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: entry.title ?? "HTML" }),
|
|
@@ -636,6 +653,7 @@ function DocHtml({ entry }) {
|
|
|
636
653
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
637
654
|
"iframe",
|
|
638
655
|
{
|
|
656
|
+
ref: frameRef,
|
|
639
657
|
...frameProps,
|
|
640
658
|
sandbox: "allow-scripts",
|
|
641
659
|
loading: "lazy",
|
|
@@ -1089,11 +1107,11 @@ function ReportTrace({ spans }) {
|
|
|
1089
1107
|
}
|
|
1090
1108
|
|
|
1091
1109
|
// src/interactive/scenario-history-context.ts
|
|
1092
|
-
var
|
|
1093
|
-
var ScenarioHistoryContext = (0,
|
|
1110
|
+
var import_react6 = require("react");
|
|
1111
|
+
var ScenarioHistoryContext = (0, import_react6.createContext)(null);
|
|
1094
1112
|
var ScenarioHistoryProvider = ScenarioHistoryContext.Provider;
|
|
1095
1113
|
function useScenarioHistory() {
|
|
1096
|
-
return (0,
|
|
1114
|
+
return (0, import_react6.useContext)(ScenarioHistoryContext);
|
|
1097
1115
|
}
|
|
1098
1116
|
|
|
1099
1117
|
// src/lib/run-history.ts
|
|
@@ -1184,7 +1202,7 @@ function ScenarioRunHistory({ scenarioId }) {
|
|
|
1184
1202
|
}
|
|
1185
1203
|
|
|
1186
1204
|
// src/components/ScenarioStaleness.tsx
|
|
1187
|
-
var
|
|
1205
|
+
var import_react8 = require("react");
|
|
1188
1206
|
|
|
1189
1207
|
// src/lib/provenance.ts
|
|
1190
1208
|
function reportLastRunMs(report) {
|
|
@@ -1240,11 +1258,11 @@ function prUrl(ci) {
|
|
|
1240
1258
|
}
|
|
1241
1259
|
|
|
1242
1260
|
// src/interactive/scenario-freshness-context.tsx
|
|
1243
|
-
var
|
|
1244
|
-
var ScenarioFreshnessContext = (0,
|
|
1261
|
+
var import_react7 = require("react");
|
|
1262
|
+
var ScenarioFreshnessContext = (0, import_react7.createContext)(null);
|
|
1245
1263
|
var ScenarioFreshnessProvider = ScenarioFreshnessContext.Provider;
|
|
1246
1264
|
function useScenarioFreshness() {
|
|
1247
|
-
return (0,
|
|
1265
|
+
return (0, import_react7.useContext)(ScenarioFreshnessContext);
|
|
1248
1266
|
}
|
|
1249
1267
|
|
|
1250
1268
|
// src/components/ScenarioStaleness.tsx
|
|
@@ -1252,8 +1270,8 @@ var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
|
1252
1270
|
function ScenarioStaleness({ scenario }) {
|
|
1253
1271
|
const freshness = useScenarioFreshness();
|
|
1254
1272
|
const fixedNow = freshness?.nowMs;
|
|
1255
|
-
const [now, setNow] = (0,
|
|
1256
|
-
(0,
|
|
1273
|
+
const [now, setNow] = (0, import_react8.useState)(fixedNow);
|
|
1274
|
+
(0, import_react8.useEffect)(() => {
|
|
1257
1275
|
if (fixedNow === void 0) setNow(Date.now());
|
|
1258
1276
|
}, [fixedNow]);
|
|
1259
1277
|
if (!freshness || now === void 0) return null;
|
|
@@ -1267,20 +1285,20 @@ function ScenarioStaleness({ scenario }) {
|
|
|
1267
1285
|
}
|
|
1268
1286
|
|
|
1269
1287
|
// src/interactive/collapse-context.ts
|
|
1270
|
-
var
|
|
1271
|
-
var CollapseContext = (0,
|
|
1288
|
+
var import_react9 = require("react");
|
|
1289
|
+
var CollapseContext = (0, import_react9.createContext)(null);
|
|
1272
1290
|
var CollapseProvider = CollapseContext.Provider;
|
|
1273
1291
|
function useCollapse() {
|
|
1274
|
-
return (0,
|
|
1292
|
+
return (0, import_react9.useContext)(CollapseContext);
|
|
1275
1293
|
}
|
|
1276
1294
|
|
|
1277
1295
|
// src/interactive/scenario-actions.tsx
|
|
1278
|
-
var
|
|
1296
|
+
var import_react10 = require("react");
|
|
1279
1297
|
var import_scenario_markdown = require("executable-stories-core/utils/scenario-markdown");
|
|
1280
|
-
var ScenarioActionsContext = (0,
|
|
1298
|
+
var ScenarioActionsContext = (0, import_react10.createContext)(null);
|
|
1281
1299
|
var ScenarioActionsProvider = ScenarioActionsContext.Provider;
|
|
1282
1300
|
function useScenarioActions() {
|
|
1283
|
-
return (0,
|
|
1301
|
+
return (0, import_react10.useContext)(ScenarioActionsContext);
|
|
1284
1302
|
}
|
|
1285
1303
|
|
|
1286
1304
|
// src/components/ui/card.tsx
|
|
@@ -1841,25 +1859,86 @@ function ReportErrorShell({
|
|
|
1841
1859
|
return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("main", { className: cn("es-report", className), "aria-label": title ?? "Test report", "data-theme": dataTheme, children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(ReportSchemaError, { error }) });
|
|
1842
1860
|
}
|
|
1843
1861
|
|
|
1844
|
-
// src/components/
|
|
1862
|
+
// src/components/ReportSpanGraph.tsx
|
|
1863
|
+
var import_span_graph = require("executable-stories-core/span-graph");
|
|
1864
|
+
var import_react11 = require("react");
|
|
1845
1865
|
var import_jsx_runtime38 = require("react/jsx-runtime");
|
|
1866
|
+
var LANE_LABEL = {
|
|
1867
|
+
edge: "Edge",
|
|
1868
|
+
service: "Service",
|
|
1869
|
+
queue: "Queue",
|
|
1870
|
+
datastore: "Data"
|
|
1871
|
+
};
|
|
1872
|
+
var MARK_LABEL = {
|
|
1873
|
+
failing: "Failing",
|
|
1874
|
+
added: "New",
|
|
1875
|
+
changed: "Changed"
|
|
1876
|
+
};
|
|
1877
|
+
var MARK_CLASS = {
|
|
1878
|
+
failing: "text-fail",
|
|
1879
|
+
added: "text-pass",
|
|
1880
|
+
changed: "text-pend"
|
|
1881
|
+
};
|
|
1882
|
+
function MarkBadge({ node }) {
|
|
1883
|
+
const mark = (0, import_span_graph.spanGraphNodeMark)(node);
|
|
1884
|
+
if (!mark) return null;
|
|
1885
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: cn("ml-2 text-xs font-medium", MARK_CLASS[mark]), children: MARK_LABEL[mark] });
|
|
1886
|
+
}
|
|
1887
|
+
function ReportSpanGraph() {
|
|
1888
|
+
const report = useReport();
|
|
1889
|
+
const { code, graph, titleById } = (0, import_react11.useMemo)(() => {
|
|
1890
|
+
const scenarios = report.features.flatMap((feature) => feature.scenarios);
|
|
1891
|
+
const derived = (0, import_span_graph.deriveSpanGraph)(scenarios);
|
|
1892
|
+
return {
|
|
1893
|
+
graph: derived,
|
|
1894
|
+
code: (0, import_span_graph.spanGraphToMermaid)(derived),
|
|
1895
|
+
titleById: new Map(scenarios.map((scenario) => [scenario.id, scenario.title]))
|
|
1896
|
+
};
|
|
1897
|
+
}, [report]);
|
|
1898
|
+
if (code === "") return null;
|
|
1899
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("section", { className: "es-span-graph mt-6", "aria-labelledby": "es-span-graph-heading", children: [
|
|
1900
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("h2", { id: "es-span-graph-heading", className: "text-base font-semibold text-foreground", children: "Architecture, as it ran" }),
|
|
1901
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("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." }),
|
|
1902
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(DocMermaid, { entry: { kind: "mermaid", phase: "static", code } }),
|
|
1903
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("table", { className: "mt-2 w-full border-collapse text-left text-sm", children: [
|
|
1904
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("caption", { className: "sr-only", children: "Each component and the scenarios that exercised it" }),
|
|
1905
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("tr", { className: "text-xs text-muted-foreground", children: [
|
|
1906
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("th", { scope: "col", className: "py-1 pr-4 font-medium", children: "Component" }),
|
|
1907
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("th", { scope: "col", className: "py-1 pr-4 font-medium", children: "Lane" }),
|
|
1908
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("th", { scope: "col", className: "py-1 font-medium", children: "Covered by" })
|
|
1909
|
+
] }) }),
|
|
1910
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("tbody", { children: graph.nodes.map((node) => /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("tr", { className: "border-t border-border align-top", children: [
|
|
1911
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("th", { scope: "row", className: "py-1.5 pr-4 font-mono text-xs font-normal", children: [
|
|
1912
|
+
node.id,
|
|
1913
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(MarkBadge, { node })
|
|
1914
|
+
] }),
|
|
1915
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("td", { className: "py-1.5 pr-4 text-xs text-muted-foreground", children: LANE_LABEL[node.kind] }),
|
|
1916
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("td", { className: "py-1.5", children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("ul", { className: "flex flex-col gap-0.5", children: node.scenarioIds.map((id) => /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("a", { href: `#${id}`, className: "text-xs text-link underline underline-offset-2 hover:text-foreground", children: titleById.get(id) ?? id }) }, id)) }) })
|
|
1917
|
+
] }, node.id)) })
|
|
1918
|
+
] })
|
|
1919
|
+
] });
|
|
1920
|
+
}
|
|
1921
|
+
|
|
1922
|
+
// src/components/Report.tsx
|
|
1923
|
+
var import_jsx_runtime39 = require("react/jsx-runtime");
|
|
1846
1924
|
function Report(props) {
|
|
1847
|
-
const { report, customRenderers, renderers, className, title, dataTheme } = props;
|
|
1925
|
+
const { report, customRenderers, renderers, className, title, dataTheme, architecture = false } = props;
|
|
1848
1926
|
const result = unwrapReport(report);
|
|
1849
1927
|
if (!result.ok) {
|
|
1850
|
-
return /* @__PURE__ */ (0,
|
|
1928
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(ReportErrorShell, { error: result.error, className, title, dataTheme });
|
|
1851
1929
|
}
|
|
1852
1930
|
const data = result.data;
|
|
1853
1931
|
const hasContent = data.features.length > 0;
|
|
1854
|
-
return /* @__PURE__ */ (0,
|
|
1855
|
-
/* @__PURE__ */ (0,
|
|
1856
|
-
|
|
1932
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(ReportRoot, { report: data, customRenderers, renderers, children: /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("main", { className: cn("es-report", className), "aria-label": title ?? "Test report", "data-theme": dataTheme, children: [
|
|
1933
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("header", { className: "es-report-header", children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(ReportTitleBlock, { title }) }),
|
|
1934
|
+
architecture ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(ReportSpanGraph, {}) : null,
|
|
1935
|
+
hasContent ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(ReportFeatureList, {}) : /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(ReportEmpty, {})
|
|
1857
1936
|
] }) });
|
|
1858
1937
|
}
|
|
1859
1938
|
|
|
1860
1939
|
// src/components/doc/MermaidView.tsx
|
|
1861
|
-
var
|
|
1862
|
-
var
|
|
1940
|
+
var import_react12 = require("react");
|
|
1941
|
+
var import_jsx_runtime40 = require("react/jsx-runtime");
|
|
1863
1942
|
function prefersDark(el) {
|
|
1864
1943
|
const themed = el?.closest("[data-theme]");
|
|
1865
1944
|
if (themed?.dataset.theme === "dark") return true;
|
|
@@ -1867,10 +1946,10 @@ function prefersDark(el) {
|
|
|
1867
1946
|
return typeof window !== "undefined" && !!window.matchMedia?.("(prefers-color-scheme: dark)").matches;
|
|
1868
1947
|
}
|
|
1869
1948
|
function MermaidView({ entry, load }) {
|
|
1870
|
-
const ref = (0,
|
|
1871
|
-
const [svg, setSvg] = (0,
|
|
1872
|
-
const [error, setError] = (0,
|
|
1873
|
-
(0,
|
|
1949
|
+
const ref = (0, import_react12.useRef)(null);
|
|
1950
|
+
const [svg, setSvg] = (0, import_react12.useState)(null);
|
|
1951
|
+
const [error, setError] = (0, import_react12.useState)(null);
|
|
1952
|
+
(0, import_react12.useEffect)(() => {
|
|
1874
1953
|
let cancelled = false;
|
|
1875
1954
|
const draw = async () => {
|
|
1876
1955
|
let mermaid;
|
|
@@ -1887,7 +1966,10 @@ function MermaidView({ entry, load }) {
|
|
|
1887
1966
|
mermaid.initialize({
|
|
1888
1967
|
startOnLoad: false,
|
|
1889
1968
|
securityLevel: "strict",
|
|
1890
|
-
|
|
1969
|
+
// "neutral" in light: the same theme the static, no-JS render uses
|
|
1970
|
+
// in ssr-entry, so a diagram keeps its colours when the island takes
|
|
1971
|
+
// over.
|
|
1972
|
+
theme: prefersDark(ref.current) ? "dark" : "neutral"
|
|
1891
1973
|
});
|
|
1892
1974
|
await mermaid.parse(entry.code);
|
|
1893
1975
|
const id = `es-mermaid-${Math.random().toString(36).slice(2)}`;
|
|
@@ -1913,9 +1995,9 @@ function MermaidView({ entry, load }) {
|
|
|
1913
1995
|
};
|
|
1914
1996
|
}, [entry.code, load]);
|
|
1915
1997
|
if (svg) {
|
|
1916
|
-
return /* @__PURE__ */ (0,
|
|
1917
|
-
entry.title ? /* @__PURE__ */ (0,
|
|
1918
|
-
/* @__PURE__ */ (0,
|
|
1998
|
+
return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("figure", { ref, className: "my-3", children: [
|
|
1999
|
+
entry.title ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("figcaption", { className: "mb-1.5 text-xs font-medium text-muted-foreground", children: entry.title }) : null,
|
|
2000
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
1919
2001
|
"div",
|
|
1920
2002
|
{
|
|
1921
2003
|
role: "img",
|
|
@@ -1926,8 +2008,8 @@ function MermaidView({ entry, load }) {
|
|
|
1926
2008
|
)
|
|
1927
2009
|
] });
|
|
1928
2010
|
}
|
|
1929
|
-
return /* @__PURE__ */ (0,
|
|
1930
|
-
error ? /* @__PURE__ */ (0,
|
|
2011
|
+
return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_jsx_runtime40.Fragment, { children: [
|
|
2012
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
|
|
1931
2013
|
"p",
|
|
1932
2014
|
{
|
|
1933
2015
|
role: "alert",
|
|
@@ -1939,34 +2021,34 @@ function MermaidView({ entry, load }) {
|
|
|
1939
2021
|
]
|
|
1940
2022
|
}
|
|
1941
2023
|
) : null,
|
|
1942
|
-
/* @__PURE__ */ (0,
|
|
2024
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(MermaidSource, { entry, ref })
|
|
1943
2025
|
] });
|
|
1944
2026
|
}
|
|
1945
2027
|
|
|
1946
2028
|
// src/components/doc/MermaidDiagram.tsx
|
|
1947
|
-
var
|
|
2029
|
+
var import_jsx_runtime41 = require("react/jsx-runtime");
|
|
1948
2030
|
var mermaidLoader;
|
|
1949
2031
|
function loadMermaid() {
|
|
1950
2032
|
mermaidLoader ??= import("mermaid").then((m) => m.default);
|
|
1951
2033
|
return mermaidLoader;
|
|
1952
2034
|
}
|
|
1953
2035
|
function MermaidDiagram({ entry, load = loadMermaid }) {
|
|
1954
|
-
return /* @__PURE__ */ (0,
|
|
2036
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(MermaidView, { entry, load });
|
|
1955
2037
|
}
|
|
1956
2038
|
|
|
1957
2039
|
// src/components/ScenarioExplorer.tsx
|
|
1958
|
-
var
|
|
2040
|
+
var import_react13 = require("react");
|
|
1959
2041
|
|
|
1960
2042
|
// src/components/ui/command.tsx
|
|
1961
2043
|
var React4 = require("react");
|
|
1962
2044
|
var import_cmdk = require("cmdk");
|
|
1963
2045
|
var import_lucide_react3 = require("lucide-react");
|
|
1964
|
-
var
|
|
2046
|
+
var import_jsx_runtime42 = require("react/jsx-runtime");
|
|
1965
2047
|
function Command({
|
|
1966
2048
|
className,
|
|
1967
2049
|
...props
|
|
1968
2050
|
}) {
|
|
1969
|
-
return /* @__PURE__ */ (0,
|
|
2051
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
1970
2052
|
import_cmdk.Command,
|
|
1971
2053
|
{
|
|
1972
2054
|
"data-slot": "command",
|
|
@@ -1982,14 +2064,14 @@ function CommandInput({
|
|
|
1982
2064
|
className,
|
|
1983
2065
|
...props
|
|
1984
2066
|
}) {
|
|
1985
|
-
return /* @__PURE__ */ (0,
|
|
2067
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
|
|
1986
2068
|
"div",
|
|
1987
2069
|
{
|
|
1988
2070
|
"data-slot": "command-input-wrapper",
|
|
1989
2071
|
className: "flex h-9 items-center gap-2 border-b px-3",
|
|
1990
2072
|
children: [
|
|
1991
|
-
/* @__PURE__ */ (0,
|
|
1992
|
-
/* @__PURE__ */ (0,
|
|
2073
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_lucide_react3.SearchIcon, { className: "size-4 shrink-0 opacity-50" }),
|
|
2074
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
1993
2075
|
import_cmdk.Command.Input,
|
|
1994
2076
|
{
|
|
1995
2077
|
"data-slot": "command-input",
|
|
@@ -2008,7 +2090,7 @@ function CommandList({
|
|
|
2008
2090
|
className,
|
|
2009
2091
|
...props
|
|
2010
2092
|
}) {
|
|
2011
|
-
return /* @__PURE__ */ (0,
|
|
2093
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
2012
2094
|
import_cmdk.Command.List,
|
|
2013
2095
|
{
|
|
2014
2096
|
"data-slot": "command-list",
|
|
@@ -2023,7 +2105,7 @@ function CommandList({
|
|
|
2023
2105
|
function CommandEmpty({
|
|
2024
2106
|
...props
|
|
2025
2107
|
}) {
|
|
2026
|
-
return /* @__PURE__ */ (0,
|
|
2108
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
2027
2109
|
import_cmdk.Command.Empty,
|
|
2028
2110
|
{
|
|
2029
2111
|
"data-slot": "command-empty",
|
|
@@ -2036,7 +2118,7 @@ function CommandGroup({
|
|
|
2036
2118
|
className,
|
|
2037
2119
|
...props
|
|
2038
2120
|
}) {
|
|
2039
|
-
return /* @__PURE__ */ (0,
|
|
2121
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
2040
2122
|
import_cmdk.Command.Group,
|
|
2041
2123
|
{
|
|
2042
2124
|
"data-slot": "command-group",
|
|
@@ -2052,7 +2134,7 @@ function CommandItem({
|
|
|
2052
2134
|
className,
|
|
2053
2135
|
...props
|
|
2054
2136
|
}) {
|
|
2055
|
-
return /* @__PURE__ */ (0,
|
|
2137
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
2056
2138
|
import_cmdk.Command.Item,
|
|
2057
2139
|
{
|
|
2058
2140
|
"data-slot": "command-item",
|
|
@@ -2066,7 +2148,7 @@ function CommandItem({
|
|
|
2066
2148
|
}
|
|
2067
2149
|
|
|
2068
2150
|
// src/components/ScenarioExplorer.tsx
|
|
2069
|
-
var
|
|
2151
|
+
var import_jsx_runtime43 = require("react/jsx-runtime");
|
|
2070
2152
|
var STATUS_FILTERS = [
|
|
2071
2153
|
{ value: "all", label: "All" },
|
|
2072
2154
|
{ value: "passed", label: "Passed" },
|
|
@@ -2075,24 +2157,24 @@ var STATUS_FILTERS = [
|
|
|
2075
2157
|
{ value: "pending", label: "Pending" }
|
|
2076
2158
|
];
|
|
2077
2159
|
function ScenarioExplorer({ scenarios, summary }) {
|
|
2078
|
-
const [status, setStatus] = (0,
|
|
2160
|
+
const [status, setStatus] = (0, import_react13.useState)("all");
|
|
2079
2161
|
const visible = status === "all" ? scenarios : scenarios.filter((s) => s.status === status);
|
|
2080
|
-
return /* @__PURE__ */ (0,
|
|
2081
|
-
summary ? /* @__PURE__ */ (0,
|
|
2162
|
+
return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "font-sans text-foreground", children: [
|
|
2163
|
+
summary ? /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("p", { className: "mb-3 text-sm text-muted-foreground", children: [
|
|
2082
2164
|
summary.total,
|
|
2083
2165
|
" scenarios \xB7 ",
|
|
2084
|
-
/* @__PURE__ */ (0,
|
|
2166
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("span", { className: "text-pass", children: [
|
|
2085
2167
|
summary.passed,
|
|
2086
2168
|
" passed"
|
|
2087
2169
|
] }),
|
|
2088
2170
|
" \xB7",
|
|
2089
2171
|
" ",
|
|
2090
|
-
/* @__PURE__ */ (0,
|
|
2172
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("span", { className: "text-fail", children: [
|
|
2091
2173
|
summary.failed,
|
|
2092
2174
|
" failed"
|
|
2093
2175
|
] })
|
|
2094
2176
|
] }) : null,
|
|
2095
|
-
/* @__PURE__ */ (0,
|
|
2177
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: "mb-2 flex flex-wrap gap-1.5", role: "group", "aria-label": "Filter by status", children: STATUS_FILTERS.map((f) => /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
2096
2178
|
"button",
|
|
2097
2179
|
{
|
|
2098
2180
|
type: "button",
|
|
@@ -2107,26 +2189,26 @@ function ScenarioExplorer({ scenarios, summary }) {
|
|
|
2107
2189
|
},
|
|
2108
2190
|
f.value
|
|
2109
2191
|
)) }),
|
|
2110
|
-
/* @__PURE__ */ (0,
|
|
2192
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
|
|
2111
2193
|
Command,
|
|
2112
2194
|
{
|
|
2113
2195
|
className: "rounded-lg border border-border bg-card",
|
|
2114
2196
|
filter: (value, search) => value.toLowerCase().includes(search.toLowerCase()) ? 1 : 0,
|
|
2115
2197
|
children: [
|
|
2116
|
-
/* @__PURE__ */ (0,
|
|
2117
|
-
/* @__PURE__ */ (0,
|
|
2118
|
-
/* @__PURE__ */ (0,
|
|
2119
|
-
/* @__PURE__ */ (0,
|
|
2198
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(CommandInput, { placeholder: "Search scenarios\u2026" }),
|
|
2199
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(CommandList, { className: "max-h-none", children: [
|
|
2200
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(CommandEmpty, { children: "No scenarios match your filters." }),
|
|
2201
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(CommandGroup, { children: visible.map((s) => /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
2120
2202
|
CommandItem,
|
|
2121
2203
|
{
|
|
2122
2204
|
value: `${s.title} ${s.feature} ${s.tags.join(" ")}`,
|
|
2123
2205
|
asChild: true,
|
|
2124
2206
|
className: "cursor-pointer",
|
|
2125
|
-
children: /* @__PURE__ */ (0,
|
|
2126
|
-
/* @__PURE__ */ (0,
|
|
2127
|
-
/* @__PURE__ */ (0,
|
|
2128
|
-
s.tags.slice(0, 3).map((t) => /* @__PURE__ */ (0,
|
|
2129
|
-
/* @__PURE__ */ (0,
|
|
2207
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("a", { href: s.href, className: "flex items-center gap-3", children: [
|
|
2208
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Badge, { variant: s.status, children: s.status }),
|
|
2209
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: "min-w-0 flex-1 truncate font-medium", children: s.title }),
|
|
2210
|
+
s.tags.slice(0, 3).map((t) => /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Badge, { variant: "tag", className: "hidden sm:inline-flex", children: t }, t)),
|
|
2211
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("code", { className: "hidden font-mono text-xs text-muted-foreground md:inline", children: s.feature })
|
|
2130
2212
|
] })
|
|
2131
2213
|
},
|
|
2132
2214
|
s.id
|