executable-stories-react 0.4.1 → 0.6.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 +303 -240
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +301 -238
- package/dist/index.js.map +1 -1
- package/dist/interactive.cjs +982 -483
- package/dist/interactive.cjs.map +1 -1
- package/dist/interactive.d.cts +10 -1
- package/dist/interactive.d.ts +10 -1
- package/dist/interactive.js +945 -455
- package/dist/interactive.js.map +1 -1
- package/dist/report-island.global.js +108 -59
- package/dist/ssr.cjs +269 -206
- package/dist/ssr.cjs.map +1 -1
- package/dist/ssr.js +269 -206
- package/dist/ssr.js.map +1 -1
- package/dist/styles.css +18 -42
- package/dist/tailwind.css +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -98,11 +98,15 @@ var badgeVariants = cva(
|
|
|
98
98
|
outline: "border-border text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground",
|
|
99
99
|
ghost: "[a&]:hover:bg-accent [a&]:hover:text-accent-foreground",
|
|
100
100
|
link: "text-primary underline-offset-4 [a&]:hover:underline",
|
|
101
|
-
|
|
101
|
+
// Pass/skip/pending are the quiet states: outline + coloured text, no
|
|
102
|
+
// fill, so a green report reads calm. Only `failed` keeps a tinted
|
|
103
|
+
// fill, making it the single loud badge on the page, so red pops the
|
|
104
|
+
// instant something breaks. Colour-as-accent, matching the KPI cards.
|
|
105
|
+
passed: "border-pass-border text-pass font-mono uppercase",
|
|
102
106
|
failed: "border-fail-border bg-fail-bg text-fail font-mono uppercase",
|
|
103
|
-
skipped: "border-skip-border
|
|
104
|
-
pending: "border-pend-border
|
|
105
|
-
tag: "border-
|
|
107
|
+
skipped: "border-skip-border text-skip font-mono uppercase",
|
|
108
|
+
pending: "border-pend-border text-pend font-mono uppercase",
|
|
109
|
+
tag: "border-border text-muted-foreground font-mono font-medium [a&]:hover:bg-muted"
|
|
106
110
|
}
|
|
107
111
|
},
|
|
108
112
|
defaultVariants: {
|
|
@@ -655,7 +659,7 @@ function ReportTrace({ spans }) {
|
|
|
655
659
|
{
|
|
656
660
|
className: "min-w-0 flex-1 truncate text-foreground",
|
|
657
661
|
style: { paddingLeft: `${row.depth * 12}px` },
|
|
658
|
-
title: row.statusMessage ? `${row.name}
|
|
662
|
+
title: row.statusMessage ? `${row.name}: ${row.statusMessage}` : row.name,
|
|
659
663
|
children: row.name
|
|
660
664
|
}
|
|
661
665
|
),
|
|
@@ -792,7 +796,7 @@ function Card({ className, ...props }) {
|
|
|
792
796
|
{
|
|
793
797
|
"data-slot": "card",
|
|
794
798
|
className: cn(
|
|
795
|
-
"flex flex-col gap-6 rounded-xl border bg-card py-6 text-card-foreground shadow-
|
|
799
|
+
"flex flex-col gap-6 rounded-xl border bg-card py-6 text-card-foreground shadow-xs",
|
|
796
800
|
className
|
|
797
801
|
),
|
|
798
802
|
...props
|
|
@@ -823,52 +827,89 @@ function CardContent({ className, ...props }) {
|
|
|
823
827
|
);
|
|
824
828
|
}
|
|
825
829
|
|
|
826
|
-
// src/components/
|
|
830
|
+
// src/components/ui/dropdown-menu.tsx
|
|
831
|
+
import "react";
|
|
832
|
+
import { Menu as MenuPrimitive } from "@base-ui/react/menu";
|
|
833
|
+
import { CheckIcon } from "lucide-react";
|
|
827
834
|
import { jsx as jsx22, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
828
|
-
var
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
};
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
835
|
+
var itemClasses = "relative flex cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 [&_svg:not([class*='text-'])]:text-muted-foreground";
|
|
836
|
+
function DropdownMenu(props) {
|
|
837
|
+
return /* @__PURE__ */ jsx22(MenuPrimitive.Root, { "data-slot": "dropdown-menu", ...props });
|
|
838
|
+
}
|
|
839
|
+
function DropdownMenuTrigger(props) {
|
|
840
|
+
return /* @__PURE__ */ jsx22(MenuPrimitive.Trigger, { "data-slot": "dropdown-menu-trigger", ...props });
|
|
841
|
+
}
|
|
842
|
+
function DropdownMenuContent({
|
|
843
|
+
className,
|
|
844
|
+
align = "end",
|
|
845
|
+
sideOffset = 4,
|
|
846
|
+
...props
|
|
847
|
+
}) {
|
|
848
|
+
return /* @__PURE__ */ jsx22(MenuPrimitive.Portal, { children: /* @__PURE__ */ jsx22(
|
|
849
|
+
MenuPrimitive.Positioner,
|
|
850
|
+
{
|
|
851
|
+
"data-slot": "dropdown-menu-positioner",
|
|
852
|
+
className: "z-50",
|
|
853
|
+
align,
|
|
854
|
+
sideOffset,
|
|
855
|
+
children: /* @__PURE__ */ jsx22(
|
|
856
|
+
MenuPrimitive.Popup,
|
|
857
|
+
{
|
|
858
|
+
"data-slot": "dropdown-menu-content",
|
|
859
|
+
className: cn(
|
|
860
|
+
"z-50 min-w-[11rem] origin-[var(--transform-origin)] overflow-hidden rounded-md border border-border bg-popover p-1 font-sans text-sm text-popover-foreground shadow-md transition-[opacity,transform] data-[ending-style]:scale-95 data-[ending-style]:opacity-0 data-[starting-style]:scale-95 data-[starting-style]:opacity-0",
|
|
861
|
+
className
|
|
862
|
+
),
|
|
863
|
+
...props
|
|
864
|
+
}
|
|
865
|
+
)
|
|
866
|
+
}
|
|
867
|
+
) });
|
|
868
|
+
}
|
|
869
|
+
function DropdownMenuItem({
|
|
870
|
+
className,
|
|
871
|
+
...props
|
|
872
|
+
}) {
|
|
873
|
+
return /* @__PURE__ */ jsx22(
|
|
874
|
+
MenuPrimitive.Item,
|
|
875
|
+
{
|
|
876
|
+
"data-slot": "dropdown-menu-item",
|
|
877
|
+
className: cn(itemClasses, className),
|
|
878
|
+
...props
|
|
879
|
+
}
|
|
880
|
+
);
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
// src/components/ReportScenario.tsx
|
|
884
|
+
import { LinkIcon, FileTextIcon, SparklesIcon, MoreHorizontalIcon } from "lucide-react";
|
|
885
|
+
import { jsx as jsx23, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
886
|
+
var STATUS_META = {
|
|
887
|
+
passed: { label: "Passed", glyph: "\u2713", glyphColor: "text-pass", badgeVariant: "passed", showPill: false },
|
|
888
|
+
failed: { label: "Failed", glyph: "\u2717", glyphColor: "text-fail", badgeVariant: "failed", showPill: true },
|
|
889
|
+
skipped: { label: "Skipped", glyph: "\u25CB", glyphColor: "text-skip", badgeVariant: "skipped", showPill: true },
|
|
890
|
+
pending: { label: "Pending", glyph: "\u25CB", glyphColor: "text-pend", badgeVariant: "pending", showPill: true }
|
|
851
891
|
};
|
|
852
892
|
function ReportScenario({ scenario, hideTitle = false }) {
|
|
853
893
|
const titleId = `${scenario.id}-title`;
|
|
854
894
|
const bodyId = `${scenario.id}-body`;
|
|
855
|
-
const
|
|
895
|
+
const meta = STATUS_META[scenario.status];
|
|
896
|
+
const label = scenario.planned ? "Planned" : meta.label;
|
|
856
897
|
const collapse = useCollapse();
|
|
857
898
|
const collapsible = collapse !== null && !hideTitle;
|
|
858
899
|
const collapsed = collapsible ? collapse.isCollapsed(scenario.id) : false;
|
|
859
900
|
const actions = useScenarioActions();
|
|
860
|
-
return /* @__PURE__ */
|
|
901
|
+
return /* @__PURE__ */ jsxs15(
|
|
861
902
|
Card,
|
|
862
903
|
{
|
|
863
904
|
id: scenario.id,
|
|
864
905
|
"data-status": scenario.status,
|
|
865
|
-
...hideTitle ? { "aria-label": `${scenario.title}
|
|
906
|
+
...hideTitle ? { "aria-label": `${scenario.title}, ${label}` } : { "aria-labelledby": titleId },
|
|
866
907
|
className: "gap-0 py-0",
|
|
867
908
|
children: [
|
|
868
|
-
/* @__PURE__ */
|
|
869
|
-
/* @__PURE__ */
|
|
870
|
-
hideTitle ? null : /* @__PURE__ */
|
|
871
|
-
collapsible ? /* @__PURE__ */
|
|
909
|
+
/* @__PURE__ */ jsxs15(CardHeader, { className: "px-4 py-3", children: [
|
|
910
|
+
/* @__PURE__ */ jsxs15("div", { className: cn("flex items-start gap-4", hideTitle ? "justify-end" : "justify-between"), children: [
|
|
911
|
+
hideTitle ? null : /* @__PURE__ */ jsxs15("h3", { id: titleId, className: "flex items-center gap-2 text-sm font-medium text-foreground", children: [
|
|
912
|
+
collapsible ? /* @__PURE__ */ jsx23(
|
|
872
913
|
"button",
|
|
873
914
|
{
|
|
874
915
|
type: "button",
|
|
@@ -877,60 +918,49 @@ function ReportScenario({ scenario, hideTitle = false }) {
|
|
|
877
918
|
"aria-controls": bodyId,
|
|
878
919
|
"aria-label": `Toggle ${scenario.title}`,
|
|
879
920
|
className: "shrink-0 cursor-pointer text-muted-foreground hover:text-foreground",
|
|
880
|
-
children: /* @__PURE__ */
|
|
921
|
+
children: /* @__PURE__ */ jsx23("span", { "aria-hidden": true, className: cn("inline-block text-xs transition-transform", !collapsed && "rotate-90"), children: "\u25B8" })
|
|
881
922
|
}
|
|
882
923
|
) : null,
|
|
883
|
-
/* @__PURE__ */
|
|
884
|
-
/* @__PURE__ */
|
|
924
|
+
/* @__PURE__ */ jsx23("span", { "aria-hidden": true, className: cn("text-sm leading-none", meta.glyphColor), children: meta.glyph }),
|
|
925
|
+
/* @__PURE__ */ jsx23("span", { children: scenario.title })
|
|
885
926
|
] }),
|
|
886
|
-
/* @__PURE__ */
|
|
887
|
-
/* @__PURE__ */
|
|
888
|
-
scenario.durationMs > 0 ? /* @__PURE__ */
|
|
889
|
-
/* @__PURE__ */
|
|
890
|
-
actions ? /* @__PURE__ */
|
|
891
|
-
/* @__PURE__ */
|
|
892
|
-
|
|
927
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex shrink-0 items-center gap-2", children: [
|
|
928
|
+
/* @__PURE__ */ jsx23(ScenarioRunHistory, { scenarioId: scenario.id }),
|
|
929
|
+
scenario.durationMs > 0 ? /* @__PURE__ */ jsx23("span", { className: "whitespace-nowrap font-mono text-[0.6875rem] text-muted-foreground", children: formatDuration(scenario.durationMs) }) : null,
|
|
930
|
+
meta.showPill ? /* @__PURE__ */ jsx23(Badge, { variant: meta.badgeVariant, "aria-label": `Status: ${label}`, children: label }) : /* @__PURE__ */ jsx23("span", { className: "sr-only", children: `Status: ${label}` }),
|
|
931
|
+
actions ? /* @__PURE__ */ jsxs15(DropdownMenu, { children: [
|
|
932
|
+
/* @__PURE__ */ jsx23(
|
|
933
|
+
DropdownMenuTrigger,
|
|
893
934
|
{
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
"aria-
|
|
897
|
-
title: "Copy permalink",
|
|
898
|
-
className: "cursor-pointer rounded px-1 py-0.5 font-mono text-[0.625rem] text-muted-foreground hover:bg-muted hover:text-foreground",
|
|
899
|
-
children: "link"
|
|
935
|
+
"aria-label": `Actions for ${scenario.title}`,
|
|
936
|
+
className: "cursor-pointer rounded p-1 text-muted-foreground hover:bg-muted hover:text-foreground [&_svg]:size-4",
|
|
937
|
+
children: /* @__PURE__ */ jsx23(MoreHorizontalIcon, { "aria-hidden": true })
|
|
900
938
|
}
|
|
901
939
|
),
|
|
902
|
-
/* @__PURE__ */
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
type: "button",
|
|
917
|
-
onClick: () => actions.copyPrompt(scenario),
|
|
918
|
-
"aria-label": `Copy ${scenario.title} as an AI investigation prompt`,
|
|
919
|
-
title: "Copy as AI prompt",
|
|
920
|
-
className: "cursor-pointer rounded px-1 py-0.5 font-mono text-[0.625rem] text-muted-foreground hover:bg-muted hover:text-foreground",
|
|
921
|
-
children: "ai"
|
|
922
|
-
}
|
|
923
|
-
)
|
|
940
|
+
/* @__PURE__ */ jsxs15(DropdownMenuContent, { align: "end", children: [
|
|
941
|
+
/* @__PURE__ */ jsxs15(DropdownMenuItem, { onClick: () => actions.copyLink(scenario), children: [
|
|
942
|
+
/* @__PURE__ */ jsx23(LinkIcon, {}),
|
|
943
|
+
" Copy link"
|
|
944
|
+
] }),
|
|
945
|
+
/* @__PURE__ */ jsxs15(DropdownMenuItem, { onClick: () => actions.copyMarkdown(scenario), children: [
|
|
946
|
+
/* @__PURE__ */ jsx23(FileTextIcon, {}),
|
|
947
|
+
" Copy as Markdown"
|
|
948
|
+
] }),
|
|
949
|
+
/* @__PURE__ */ jsxs15(DropdownMenuItem, { onClick: () => actions.copyPrompt(scenario), children: [
|
|
950
|
+
/* @__PURE__ */ jsx23(SparklesIcon, {}),
|
|
951
|
+
" Explain with AI"
|
|
952
|
+
] })
|
|
953
|
+
] })
|
|
924
954
|
] }) : null
|
|
925
955
|
] })
|
|
926
956
|
] }),
|
|
927
|
-
scenario.tags.length > 0 || (scenario.tickets?.length ?? 0) > 0 ? /* @__PURE__ */
|
|
928
|
-
scenario.tags.map((t) => /* @__PURE__ */
|
|
929
|
-
(scenario.tickets ?? []).map((ticket) => /* @__PURE__ */
|
|
957
|
+
scenario.tags.length > 0 || (scenario.tickets?.length ?? 0) > 0 ? /* @__PURE__ */ jsxs15("ul", { "aria-label": "Tags and tickets", className: "flex flex-wrap gap-1.5", children: [
|
|
958
|
+
scenario.tags.map((t) => /* @__PURE__ */ jsx23("li", { children: /* @__PURE__ */ jsx23(Badge, { variant: "tag", children: t }) }, `tag-${t}`)),
|
|
959
|
+
(scenario.tickets ?? []).map((ticket) => /* @__PURE__ */ jsx23("li", { children: ticket.url ? /* @__PURE__ */ jsx23("a", { href: ticket.url, target: "_blank", rel: "noreferrer noopener", children: /* @__PURE__ */ jsx23(Badge, { variant: "outline", children: ticket.id }) }) : /* @__PURE__ */ jsx23(Badge, { variant: "outline", children: ticket.id }) }, `ticket-${ticket.id}`))
|
|
930
960
|
] }) : null
|
|
931
961
|
] }),
|
|
932
|
-
/* @__PURE__ */
|
|
933
|
-
scenario.errorMessage ? /* @__PURE__ */
|
|
962
|
+
/* @__PURE__ */ jsxs15(CardContent, { id: bodyId, hidden: collapsed, className: "px-4 pt-0 pb-4", children: [
|
|
963
|
+
scenario.errorMessage ? /* @__PURE__ */ jsx23(
|
|
934
964
|
"pre",
|
|
935
965
|
{
|
|
936
966
|
role: "alert",
|
|
@@ -938,10 +968,10 @@ function ReportScenario({ scenario, hideTitle = false }) {
|
|
|
938
968
|
children: scenario.errorMessage
|
|
939
969
|
}
|
|
940
970
|
) : null,
|
|
941
|
-
/* @__PURE__ */
|
|
942
|
-
scenario.docEntries.length > 0 ? /* @__PURE__ */
|
|
943
|
-
/* @__PURE__ */
|
|
944
|
-
/* @__PURE__ */
|
|
971
|
+
/* @__PURE__ */ jsx23(ReportSteps, { scenario }),
|
|
972
|
+
scenario.docEntries.length > 0 ? /* @__PURE__ */ jsx23("div", { "data-es-docs": true, className: "mt-3", children: /* @__PURE__ */ jsx23(ReportDocEntries, { entries: scenario.docEntries }) }) : null,
|
|
973
|
+
/* @__PURE__ */ jsx23(ReportAttachments, { attachments: scenario.attachments }),
|
|
974
|
+
/* @__PURE__ */ jsx23(ReportTrace, { spans: scenario.otelSpans })
|
|
945
975
|
] })
|
|
946
976
|
]
|
|
947
977
|
}
|
|
@@ -949,13 +979,13 @@ function ReportScenario({ scenario, hideTitle = false }) {
|
|
|
949
979
|
}
|
|
950
980
|
|
|
951
981
|
// src/components/ReportScenarioList.tsx
|
|
952
|
-
import { Fragment as Fragment8, jsx as
|
|
982
|
+
import { Fragment as Fragment8, jsx as jsx24 } from "react/jsx-runtime";
|
|
953
983
|
function ReportScenarioList({ feature }) {
|
|
954
|
-
return /* @__PURE__ */
|
|
984
|
+
return /* @__PURE__ */ jsx24(Fragment8, { children: feature.scenarios.map((scenario) => /* @__PURE__ */ jsx24(ReportScenario, { scenario }, scenario.id)) });
|
|
955
985
|
}
|
|
956
986
|
|
|
957
987
|
// src/components/ReportFeature.tsx
|
|
958
|
-
import { jsx as
|
|
988
|
+
import { Fragment as Fragment9, jsx as jsx25, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
959
989
|
function ReportFeature({ feature }) {
|
|
960
990
|
const titleId = `${feature.id}-title`;
|
|
961
991
|
const bodyId = `${feature.id}-body`;
|
|
@@ -963,74 +993,80 @@ function ReportFeature({ feature }) {
|
|
|
963
993
|
const skipped = s.skipped + s.pending;
|
|
964
994
|
const collapse = useCollapse();
|
|
965
995
|
const collapsed = collapse?.isCollapsed(feature.id) ?? false;
|
|
966
|
-
return
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
"
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
996
|
+
return (
|
|
997
|
+
// Suite = a section heading + a divider, NOT another bordered card. Drops a
|
|
998
|
+
// layer of nesting so the scenario cards below read as the primary unit.
|
|
999
|
+
/* @__PURE__ */ jsxs16(
|
|
1000
|
+
"section",
|
|
1001
|
+
{
|
|
1002
|
+
id: feature.id,
|
|
1003
|
+
"data-slot": "feature",
|
|
1004
|
+
"aria-labelledby": titleId,
|
|
1005
|
+
className: "flex flex-col gap-3",
|
|
1006
|
+
children: [
|
|
1007
|
+
/* @__PURE__ */ jsxs16("div", { className: "flex items-end justify-between gap-4 border-b border-border pb-2", children: [
|
|
1008
|
+
/* @__PURE__ */ jsxs16("div", { className: "min-w-0", children: [
|
|
1009
|
+
/* @__PURE__ */ jsx25("h2", { id: titleId, className: "text-base font-semibold tracking-tight text-foreground", children: collapse ? /* @__PURE__ */ jsxs16(
|
|
1010
|
+
"button",
|
|
1011
|
+
{
|
|
1012
|
+
type: "button",
|
|
1013
|
+
onClick: () => collapse.toggle(feature.id),
|
|
1014
|
+
"aria-expanded": !collapsed,
|
|
1015
|
+
"aria-controls": bodyId,
|
|
1016
|
+
className: "flex w-full cursor-pointer items-center gap-2 text-left hover:text-foreground/80",
|
|
1017
|
+
children: [
|
|
1018
|
+
/* @__PURE__ */ jsx25("span", { "aria-hidden": true, className: cn("shrink-0 text-xs text-muted-foreground transition-transform", !collapsed && "rotate-90"), children: "\u25B8" }),
|
|
1019
|
+
/* @__PURE__ */ jsx25("span", { className: "truncate", children: feature.title })
|
|
1020
|
+
]
|
|
1021
|
+
}
|
|
1022
|
+
) : feature.title }),
|
|
1023
|
+
/* @__PURE__ */ jsx25("p", { className: cn("mt-0.5 truncate font-mono text-xs text-muted-foreground", collapse && "pl-5"), children: feature.sourceFile })
|
|
1024
|
+
] }),
|
|
1025
|
+
/* @__PURE__ */ jsxs16(
|
|
1026
|
+
"p",
|
|
978
1027
|
{
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
1028
|
+
className: "flex shrink-0 items-center gap-1.5 text-xs text-muted-foreground",
|
|
1029
|
+
"aria-label": `${s.passed} passed, ${s.failed} failed, ${skipped} skipped`,
|
|
1030
|
+
children: [
|
|
1031
|
+
/* @__PURE__ */ jsxs16("span", { children: [
|
|
1032
|
+
s.passed,
|
|
1033
|
+
" passed"
|
|
1034
|
+
] }),
|
|
1035
|
+
/* @__PURE__ */ jsx25("span", { "aria-hidden": true, children: "\xB7" }),
|
|
1036
|
+
/* @__PURE__ */ jsxs16("span", { className: cn(s.failed > 0 && "font-medium text-fail"), children: [
|
|
1037
|
+
s.failed,
|
|
1038
|
+
" failed"
|
|
1039
|
+
] }),
|
|
1040
|
+
skipped > 0 ? /* @__PURE__ */ jsxs16(Fragment9, { children: [
|
|
1041
|
+
/* @__PURE__ */ jsx25("span", { "aria-hidden": true, children: "\xB7" }),
|
|
1042
|
+
/* @__PURE__ */ jsxs16("span", { children: [
|
|
1043
|
+
skipped,
|
|
1044
|
+
" skipped"
|
|
1045
|
+
] })
|
|
1046
|
+
] }) : null
|
|
1047
|
+
]
|
|
986
1048
|
}
|
|
987
|
-
)
|
|
988
|
-
/* @__PURE__ */ jsxs15("div", { className: "min-w-0", children: [
|
|
989
|
-
/* @__PURE__ */ jsx24("h2", { id: titleId, className: "text-sm font-semibold tracking-tight text-foreground", children: feature.title }),
|
|
990
|
-
/* @__PURE__ */ jsx24("p", { className: "mt-0.5 truncate font-mono text-xs text-muted-foreground", children: feature.sourceFile })
|
|
991
|
-
] })
|
|
1049
|
+
)
|
|
992
1050
|
] }),
|
|
993
|
-
/* @__PURE__ */
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
className: "flex shrink-0 items-center gap-2.5 font-mono text-xs font-medium",
|
|
998
|
-
"aria-label": `${s.passed} passed, ${s.failed} failed, ${skipped} skipped`,
|
|
999
|
-
children: [
|
|
1000
|
-
/* @__PURE__ */ jsxs15("span", { "aria-hidden": true, className: "text-pass", children: [
|
|
1001
|
-
"\u2713",
|
|
1002
|
-
s.passed
|
|
1003
|
-
] }),
|
|
1004
|
-
/* @__PURE__ */ jsxs15("span", { "aria-hidden": true, className: "text-fail", children: [
|
|
1005
|
-
"\u2717",
|
|
1006
|
-
s.failed
|
|
1007
|
-
] }),
|
|
1008
|
-
/* @__PURE__ */ jsxs15("span", { "aria-hidden": true, className: "text-skip", children: [
|
|
1009
|
-
"\u25CB",
|
|
1010
|
-
skipped
|
|
1011
|
-
] })
|
|
1012
|
-
]
|
|
1013
|
-
}
|
|
1014
|
-
)
|
|
1015
|
-
] }),
|
|
1016
|
-
/* @__PURE__ */ jsx24("div", { id: bodyId, hidden: collapsed, className: "flex flex-col gap-2 p-3", children: /* @__PURE__ */ jsx24(ReportScenarioList, { feature }) })
|
|
1017
|
-
]
|
|
1018
|
-
}
|
|
1051
|
+
/* @__PURE__ */ jsx25("div", { id: bodyId, hidden: collapsed, className: "flex flex-col gap-3", children: /* @__PURE__ */ jsx25(ReportScenarioList, { feature }) })
|
|
1052
|
+
]
|
|
1053
|
+
}
|
|
1054
|
+
)
|
|
1019
1055
|
);
|
|
1020
1056
|
}
|
|
1021
1057
|
|
|
1022
1058
|
// src/components/ReportFeatureList.tsx
|
|
1023
|
-
import {
|
|
1059
|
+
import { jsx as jsx26 } from "react/jsx-runtime";
|
|
1024
1060
|
function ReportFeatureList() {
|
|
1025
1061
|
const report = useReport();
|
|
1026
|
-
return /* @__PURE__ */
|
|
1062
|
+
return /* @__PURE__ */ jsx26("div", { className: "flex flex-col gap-8", children: report.features.map((feature) => /* @__PURE__ */ jsx26(ReportFeature, { feature }, feature.id)) });
|
|
1027
1063
|
}
|
|
1028
1064
|
|
|
1029
1065
|
// src/components/ui/empty.tsx
|
|
1030
1066
|
import { cva as cva2 } from "class-variance-authority";
|
|
1031
|
-
import { jsx as
|
|
1067
|
+
import { jsx as jsx27 } from "react/jsx-runtime";
|
|
1032
1068
|
function Empty({ className, ...props }) {
|
|
1033
|
-
return /* @__PURE__ */
|
|
1069
|
+
return /* @__PURE__ */ jsx27(
|
|
1034
1070
|
"div",
|
|
1035
1071
|
{
|
|
1036
1072
|
"data-slot": "empty",
|
|
@@ -1043,7 +1079,7 @@ function Empty({ className, ...props }) {
|
|
|
1043
1079
|
);
|
|
1044
1080
|
}
|
|
1045
1081
|
function EmptyHeader({ className, ...props }) {
|
|
1046
|
-
return /* @__PURE__ */
|
|
1082
|
+
return /* @__PURE__ */ jsx27(
|
|
1047
1083
|
"div",
|
|
1048
1084
|
{
|
|
1049
1085
|
"data-slot": "empty-header",
|
|
@@ -1070,7 +1106,7 @@ var emptyMediaVariants = cva2(
|
|
|
1070
1106
|
}
|
|
1071
1107
|
);
|
|
1072
1108
|
function EmptyTitle({ className, ...props }) {
|
|
1073
|
-
return /* @__PURE__ */
|
|
1109
|
+
return /* @__PURE__ */ jsx27(
|
|
1074
1110
|
"div",
|
|
1075
1111
|
{
|
|
1076
1112
|
"data-slot": "empty-title",
|
|
@@ -1081,16 +1117,16 @@ function EmptyTitle({ className, ...props }) {
|
|
|
1081
1117
|
}
|
|
1082
1118
|
|
|
1083
1119
|
// src/components/ReportEmpty.tsx
|
|
1084
|
-
import { jsx as
|
|
1120
|
+
import { jsx as jsx28 } from "react/jsx-runtime";
|
|
1085
1121
|
function ReportEmpty({ message }) {
|
|
1086
|
-
return /* @__PURE__ */
|
|
1122
|
+
return /* @__PURE__ */ jsx28(Empty, { "aria-live": "polite", className: "border", children: /* @__PURE__ */ jsx28(EmptyHeader, { children: /* @__PURE__ */ jsx28(EmptyTitle, { children: message ?? "No scenarios in this report." }) }) });
|
|
1087
1123
|
}
|
|
1088
1124
|
|
|
1089
1125
|
// src/components/ReportSummary.tsx
|
|
1090
|
-
import {
|
|
1126
|
+
import { jsx as jsx29, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
1091
1127
|
function ReportSummary({ className }) {
|
|
1092
1128
|
const report = useReport();
|
|
1093
|
-
return /* @__PURE__ */
|
|
1129
|
+
return /* @__PURE__ */ jsx29(
|
|
1094
1130
|
ReportSummaryView,
|
|
1095
1131
|
{
|
|
1096
1132
|
summary: report.summary,
|
|
@@ -1099,38 +1135,54 @@ function ReportSummary({ className }) {
|
|
|
1099
1135
|
}
|
|
1100
1136
|
);
|
|
1101
1137
|
}
|
|
1138
|
+
var TONE = {
|
|
1139
|
+
total: { num: "text-foreground", dot: "bg-muted-foreground/50" },
|
|
1140
|
+
passed: { num: "text-pass", dot: "bg-pass" },
|
|
1141
|
+
failed: { num: "text-fail", dot: "bg-fail" },
|
|
1142
|
+
skipped: { num: "text-skip", dot: "bg-skip" },
|
|
1143
|
+
pending: { num: "text-pend", dot: "bg-pend" }
|
|
1144
|
+
};
|
|
1102
1145
|
function ReportSummaryView({ summary, className, ariaLabel }) {
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1146
|
+
const cards = [
|
|
1147
|
+
{ status: "total", label: "Total", value: summary.total },
|
|
1148
|
+
{ status: "passed", label: "Passed", value: summary.passed },
|
|
1149
|
+
{ status: "failed", label: "Failed", value: summary.failed },
|
|
1150
|
+
{ status: "skipped", label: "Skipped", value: summary.skipped }
|
|
1151
|
+
];
|
|
1152
|
+
if (summary.pending > 0) {
|
|
1153
|
+
cards.push({ status: "pending", label: "Pending", value: summary.pending });
|
|
1154
|
+
}
|
|
1155
|
+
return /* @__PURE__ */ jsx29(
|
|
1156
|
+
"dl",
|
|
1157
|
+
{
|
|
1158
|
+
className: cn(
|
|
1159
|
+
"grid grid-cols-2 gap-3",
|
|
1160
|
+
// Columns follow the card count so the row is always full — 5 statuses
|
|
1161
|
+
// (pending present) never leave a lone orphan card below a row of four.
|
|
1162
|
+
cards.length === 5 ? "sm:grid-cols-5" : "sm:grid-cols-4",
|
|
1163
|
+
className
|
|
1164
|
+
),
|
|
1165
|
+
"aria-label": ariaLabel,
|
|
1166
|
+
children: cards.map((c) => {
|
|
1167
|
+
const tone = TONE[c.status];
|
|
1168
|
+
return /* @__PURE__ */ jsxs17(
|
|
1169
|
+
"div",
|
|
1170
|
+
{
|
|
1171
|
+
"data-status": c.status,
|
|
1172
|
+
className: "rounded-lg border bg-card px-4 py-3",
|
|
1173
|
+
children: [
|
|
1174
|
+
/* @__PURE__ */ jsxs17("dt", { className: "flex items-center gap-1.5 font-mono text-[11px] font-medium uppercase tracking-wider text-muted-foreground", children: [
|
|
1175
|
+
/* @__PURE__ */ jsx29("span", { className: cn("size-1.5 shrink-0 rounded-full", tone.dot), "aria-hidden": "true" }),
|
|
1176
|
+
c.label
|
|
1177
|
+
] }),
|
|
1178
|
+
/* @__PURE__ */ jsx29("dd", { className: cn("mt-2 text-3xl font-semibold leading-none tracking-tight tabular-nums", tone.num), children: c.value })
|
|
1179
|
+
]
|
|
1180
|
+
},
|
|
1181
|
+
c.status
|
|
1182
|
+
);
|
|
1183
|
+
})
|
|
1184
|
+
}
|
|
1185
|
+
);
|
|
1134
1186
|
}
|
|
1135
1187
|
|
|
1136
1188
|
// src/lib/provenance.ts
|
|
@@ -1183,7 +1235,7 @@ function prUrl(ci) {
|
|
|
1183
1235
|
}
|
|
1184
1236
|
|
|
1185
1237
|
// src/components/ReportMeta.tsx
|
|
1186
|
-
import { jsx as
|
|
1238
|
+
import { jsx as jsx30, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
1187
1239
|
function ReportMeta() {
|
|
1188
1240
|
const report = useReport();
|
|
1189
1241
|
const items = [];
|
|
@@ -1206,13 +1258,13 @@ function ReportMeta() {
|
|
|
1206
1258
|
const short = sha.slice(0, 8);
|
|
1207
1259
|
items.push({
|
|
1208
1260
|
label: "Commit",
|
|
1209
|
-
value: url ? /* @__PURE__ */
|
|
1261
|
+
value: url ? /* @__PURE__ */ jsx30("a", { href: url, target: "_blank", rel: "noreferrer noopener", className: linkClass, children: short }) : short
|
|
1210
1262
|
});
|
|
1211
1263
|
}
|
|
1212
1264
|
if (report.ci) {
|
|
1213
1265
|
items.push({
|
|
1214
1266
|
label: "CI",
|
|
1215
|
-
value: report.ci.url ? /* @__PURE__ */
|
|
1267
|
+
value: report.ci.url ? /* @__PURE__ */ jsxs18("a", { href: report.ci.url, target: "_blank", rel: "noreferrer noopener", className: linkClass, children: [
|
|
1216
1268
|
ciDisplayName(report.ci.name),
|
|
1217
1269
|
report.ci.buildNumber ? ` #${report.ci.buildNumber}` : ""
|
|
1218
1270
|
] }) : `${ciDisplayName(report.ci.name)}${report.ci.buildNumber ? ` #${report.ci.buildNumber}` : ""}`
|
|
@@ -1223,45 +1275,56 @@ function ReportMeta() {
|
|
|
1223
1275
|
const label = `#${report.ci.prNumber}`;
|
|
1224
1276
|
items.push({
|
|
1225
1277
|
label: "PR",
|
|
1226
|
-
value: url ? /* @__PURE__ */
|
|
1278
|
+
value: url ? /* @__PURE__ */ jsx30("a", { href: url, target: "_blank", rel: "noreferrer noopener", className: linkClass, children: label }) : label
|
|
1227
1279
|
});
|
|
1228
1280
|
}
|
|
1229
1281
|
if (items.length === 0) return null;
|
|
1230
|
-
return
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1282
|
+
return (
|
|
1283
|
+
// Run metadata is useful but secondary to "what failed" — tuck it into a
|
|
1284
|
+
// collapsed disclosure so it doesn't push the result down. Native <details>
|
|
1285
|
+
// so it works with no JS (the SSR/no-hydration report still toggles).
|
|
1286
|
+
/* @__PURE__ */ jsxs18("details", { "data-es-meta-card": true, className: "es-run-details group rounded-lg border border-border bg-card text-xs", children: [
|
|
1287
|
+
/* @__PURE__ */ jsxs18("summary", { className: "flex cursor-pointer list-none select-none items-center gap-1.5 px-4 py-2 font-medium text-muted-foreground [&::-webkit-details-marker]:hidden", children: [
|
|
1288
|
+
/* @__PURE__ */ jsx30("span", { "aria-hidden": true, className: "text-xs transition-transform group-open:rotate-90", children: "\u25B8" }),
|
|
1289
|
+
"Run details"
|
|
1290
|
+
] }),
|
|
1291
|
+
/* @__PURE__ */ jsx30("dl", { className: "flex flex-wrap gap-x-5 gap-y-2 border-t border-border px-4 py-3 text-muted-foreground", "aria-label": "Run metadata", children: items.map((item) => /* @__PURE__ */ jsxs18("div", { className: "flex items-baseline gap-1.5", children: [
|
|
1292
|
+
/* @__PURE__ */ jsx30("dt", { className: "font-medium", children: item.label }),
|
|
1293
|
+
/* @__PURE__ */ jsx30("dd", { className: "font-mono text-foreground", children: item.value })
|
|
1294
|
+
] }, item.label)) })
|
|
1295
|
+
] })
|
|
1296
|
+
);
|
|
1234
1297
|
}
|
|
1235
1298
|
|
|
1236
1299
|
// src/components/ReportSchemaError.tsx
|
|
1237
|
-
import { jsx as
|
|
1300
|
+
import { jsx as jsx31, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
1238
1301
|
function ReportSchemaError({ error }) {
|
|
1239
|
-
return /* @__PURE__ */
|
|
1240
|
-
/* @__PURE__ */
|
|
1241
|
-
/* @__PURE__ */
|
|
1242
|
-
error.code === "SCHEMA_VERSION_MISMATCH" ? /* @__PURE__ */
|
|
1302
|
+
return /* @__PURE__ */ jsxs19("section", { className: "es-schema-error", role: "alert", "aria-live": "assertive", children: [
|
|
1303
|
+
/* @__PURE__ */ jsx31("p", { children: /* @__PURE__ */ jsx31("strong", { children: "Report could not be displayed." }) }),
|
|
1304
|
+
/* @__PURE__ */ jsx31("p", { children: error.message }),
|
|
1305
|
+
error.code === "SCHEMA_VERSION_MISMATCH" ? /* @__PURE__ */ jsxs19("p", { children: [
|
|
1243
1306
|
"The report bundle is newer than this version of ",
|
|
1244
|
-
/* @__PURE__ */
|
|
1307
|
+
/* @__PURE__ */ jsx31("code", { children: "executable-stories-react" }),
|
|
1245
1308
|
". Upgrade the package, or regenerate the report with an older formatters CLI."
|
|
1246
1309
|
] }) : null,
|
|
1247
|
-
error.issues && error.issues.length > 0 ? /* @__PURE__ */
|
|
1248
|
-
/* @__PURE__ */
|
|
1310
|
+
error.issues && error.issues.length > 0 ? /* @__PURE__ */ jsxs19("details", { children: [
|
|
1311
|
+
/* @__PURE__ */ jsxs19("summary", { children: [
|
|
1249
1312
|
error.issues.length,
|
|
1250
1313
|
" validation issue",
|
|
1251
1314
|
error.issues.length === 1 ? "" : "s"
|
|
1252
1315
|
] }),
|
|
1253
|
-
/* @__PURE__ */
|
|
1316
|
+
/* @__PURE__ */ jsx31("pre", { children: error.issues.slice(0, 20).map((i) => `${i.path}: ${i.message}`).join("\n") })
|
|
1254
1317
|
] }) : null
|
|
1255
1318
|
] });
|
|
1256
1319
|
}
|
|
1257
1320
|
|
|
1258
1321
|
// src/components/ReportShell.tsx
|
|
1259
|
-
import { Fragment as
|
|
1322
|
+
import { Fragment as Fragment10, jsx as jsx32, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
1260
1323
|
function ReportTitleBlock({ title }) {
|
|
1261
|
-
return /* @__PURE__ */
|
|
1262
|
-
/* @__PURE__ */
|
|
1263
|
-
/* @__PURE__ */
|
|
1264
|
-
/* @__PURE__ */
|
|
1324
|
+
return /* @__PURE__ */ jsxs20(Fragment10, { children: [
|
|
1325
|
+
/* @__PURE__ */ jsx32("h1", { children: title ?? "Story Report" }),
|
|
1326
|
+
/* @__PURE__ */ jsx32(ReportSummary, {}),
|
|
1327
|
+
/* @__PURE__ */ jsx32(ReportMeta, {})
|
|
1265
1328
|
] });
|
|
1266
1329
|
}
|
|
1267
1330
|
function ReportErrorShell({
|
|
@@ -1270,28 +1333,28 @@ function ReportErrorShell({
|
|
|
1270
1333
|
title,
|
|
1271
1334
|
dataTheme
|
|
1272
1335
|
}) {
|
|
1273
|
-
return /* @__PURE__ */
|
|
1336
|
+
return /* @__PURE__ */ jsx32("main", { className: cn("es-report", className), "aria-label": title ?? "Test report", "data-theme": dataTheme, children: /* @__PURE__ */ jsx32(ReportSchemaError, { error }) });
|
|
1274
1337
|
}
|
|
1275
1338
|
|
|
1276
1339
|
// src/components/Report.tsx
|
|
1277
|
-
import { jsx as
|
|
1340
|
+
import { jsx as jsx33, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
1278
1341
|
function Report(props) {
|
|
1279
1342
|
const { report, customRenderers, renderers, className, title, dataTheme } = props;
|
|
1280
1343
|
const result = unwrapReport(report);
|
|
1281
1344
|
if (!result.ok) {
|
|
1282
|
-
return /* @__PURE__ */
|
|
1345
|
+
return /* @__PURE__ */ jsx33(ReportErrorShell, { error: result.error, className, title, dataTheme });
|
|
1283
1346
|
}
|
|
1284
1347
|
const data = result.data;
|
|
1285
1348
|
const hasContent = data.features.length > 0;
|
|
1286
|
-
return /* @__PURE__ */
|
|
1287
|
-
/* @__PURE__ */
|
|
1288
|
-
hasContent ? /* @__PURE__ */
|
|
1349
|
+
return /* @__PURE__ */ jsx33(ReportRoot, { report: data, customRenderers, renderers, children: /* @__PURE__ */ jsxs21("main", { className: cn("es-report", className), "aria-label": title ?? "Test report", "data-theme": dataTheme, children: [
|
|
1350
|
+
/* @__PURE__ */ jsx33("header", { className: "es-report-header", children: /* @__PURE__ */ jsx33(ReportTitleBlock, { title }) }),
|
|
1351
|
+
hasContent ? /* @__PURE__ */ jsx33(ReportFeatureList, {}) : /* @__PURE__ */ jsx33(ReportEmpty, {})
|
|
1289
1352
|
] }) });
|
|
1290
1353
|
}
|
|
1291
1354
|
|
|
1292
1355
|
// src/components/doc/MermaidView.tsx
|
|
1293
1356
|
import { useEffect, useRef, useState as useState2 } from "react";
|
|
1294
|
-
import { jsx as
|
|
1357
|
+
import { jsx as jsx34, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
1295
1358
|
function prefersDark(el) {
|
|
1296
1359
|
const themed = el?.closest("[data-theme]");
|
|
1297
1360
|
if (themed?.dataset.theme === "dark") return true;
|
|
@@ -1328,9 +1391,9 @@ function MermaidView({ entry, load }) {
|
|
|
1328
1391
|
};
|
|
1329
1392
|
}, [entry.code, load]);
|
|
1330
1393
|
if (svg) {
|
|
1331
|
-
return /* @__PURE__ */
|
|
1332
|
-
entry.title ? /* @__PURE__ */
|
|
1333
|
-
/* @__PURE__ */
|
|
1394
|
+
return /* @__PURE__ */ jsxs22("figure", { ref, className: "my-3", children: [
|
|
1395
|
+
entry.title ? /* @__PURE__ */ jsx34("figcaption", { className: "mb-1.5 text-xs font-medium text-muted-foreground", children: entry.title }) : null,
|
|
1396
|
+
/* @__PURE__ */ jsx34(
|
|
1334
1397
|
"div",
|
|
1335
1398
|
{
|
|
1336
1399
|
role: "img",
|
|
@@ -1341,18 +1404,18 @@ function MermaidView({ entry, load }) {
|
|
|
1341
1404
|
)
|
|
1342
1405
|
] });
|
|
1343
1406
|
}
|
|
1344
|
-
return /* @__PURE__ */
|
|
1407
|
+
return /* @__PURE__ */ jsx34(MermaidSource, { entry, ref });
|
|
1345
1408
|
}
|
|
1346
1409
|
|
|
1347
1410
|
// src/components/doc/MermaidDiagram.tsx
|
|
1348
|
-
import { jsx as
|
|
1411
|
+
import { jsx as jsx35 } from "react/jsx-runtime";
|
|
1349
1412
|
var mermaidLoader;
|
|
1350
1413
|
function loadMermaid() {
|
|
1351
1414
|
mermaidLoader ??= import("mermaid").then((m) => m.default);
|
|
1352
1415
|
return mermaidLoader;
|
|
1353
1416
|
}
|
|
1354
1417
|
function MermaidDiagram({ entry, load = loadMermaid }) {
|
|
1355
|
-
return /* @__PURE__ */
|
|
1418
|
+
return /* @__PURE__ */ jsx35(MermaidView, { entry, load });
|
|
1356
1419
|
}
|
|
1357
1420
|
|
|
1358
1421
|
// src/components/ScenarioExplorer.tsx
|
|
@@ -1362,12 +1425,12 @@ import { useState as useState3 } from "react";
|
|
|
1362
1425
|
import "react";
|
|
1363
1426
|
import { Command as CommandPrimitive } from "cmdk";
|
|
1364
1427
|
import { SearchIcon } from "lucide-react";
|
|
1365
|
-
import { jsx as
|
|
1428
|
+
import { jsx as jsx36, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
1366
1429
|
function Command({
|
|
1367
1430
|
className,
|
|
1368
1431
|
...props
|
|
1369
1432
|
}) {
|
|
1370
|
-
return /* @__PURE__ */
|
|
1433
|
+
return /* @__PURE__ */ jsx36(
|
|
1371
1434
|
CommandPrimitive,
|
|
1372
1435
|
{
|
|
1373
1436
|
"data-slot": "command",
|
|
@@ -1383,14 +1446,14 @@ function CommandInput({
|
|
|
1383
1446
|
className,
|
|
1384
1447
|
...props
|
|
1385
1448
|
}) {
|
|
1386
|
-
return /* @__PURE__ */
|
|
1449
|
+
return /* @__PURE__ */ jsxs23(
|
|
1387
1450
|
"div",
|
|
1388
1451
|
{
|
|
1389
1452
|
"data-slot": "command-input-wrapper",
|
|
1390
1453
|
className: "flex h-9 items-center gap-2 border-b px-3",
|
|
1391
1454
|
children: [
|
|
1392
|
-
/* @__PURE__ */
|
|
1393
|
-
/* @__PURE__ */
|
|
1455
|
+
/* @__PURE__ */ jsx36(SearchIcon, { className: "size-4 shrink-0 opacity-50" }),
|
|
1456
|
+
/* @__PURE__ */ jsx36(
|
|
1394
1457
|
CommandPrimitive.Input,
|
|
1395
1458
|
{
|
|
1396
1459
|
"data-slot": "command-input",
|
|
@@ -1409,7 +1472,7 @@ function CommandList({
|
|
|
1409
1472
|
className,
|
|
1410
1473
|
...props
|
|
1411
1474
|
}) {
|
|
1412
|
-
return /* @__PURE__ */
|
|
1475
|
+
return /* @__PURE__ */ jsx36(
|
|
1413
1476
|
CommandPrimitive.List,
|
|
1414
1477
|
{
|
|
1415
1478
|
"data-slot": "command-list",
|
|
@@ -1424,7 +1487,7 @@ function CommandList({
|
|
|
1424
1487
|
function CommandEmpty({
|
|
1425
1488
|
...props
|
|
1426
1489
|
}) {
|
|
1427
|
-
return /* @__PURE__ */
|
|
1490
|
+
return /* @__PURE__ */ jsx36(
|
|
1428
1491
|
CommandPrimitive.Empty,
|
|
1429
1492
|
{
|
|
1430
1493
|
"data-slot": "command-empty",
|
|
@@ -1437,7 +1500,7 @@ function CommandGroup({
|
|
|
1437
1500
|
className,
|
|
1438
1501
|
...props
|
|
1439
1502
|
}) {
|
|
1440
|
-
return /* @__PURE__ */
|
|
1503
|
+
return /* @__PURE__ */ jsx36(
|
|
1441
1504
|
CommandPrimitive.Group,
|
|
1442
1505
|
{
|
|
1443
1506
|
"data-slot": "command-group",
|
|
@@ -1453,7 +1516,7 @@ function CommandItem({
|
|
|
1453
1516
|
className,
|
|
1454
1517
|
...props
|
|
1455
1518
|
}) {
|
|
1456
|
-
return /* @__PURE__ */
|
|
1519
|
+
return /* @__PURE__ */ jsx36(
|
|
1457
1520
|
CommandPrimitive.Item,
|
|
1458
1521
|
{
|
|
1459
1522
|
"data-slot": "command-item",
|
|
@@ -1467,7 +1530,7 @@ function CommandItem({
|
|
|
1467
1530
|
}
|
|
1468
1531
|
|
|
1469
1532
|
// src/components/ScenarioExplorer.tsx
|
|
1470
|
-
import { jsx as
|
|
1533
|
+
import { jsx as jsx37, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
1471
1534
|
var STATUS_FILTERS = [
|
|
1472
1535
|
{ value: "all", label: "All" },
|
|
1473
1536
|
{ value: "passed", label: "Passed" },
|
|
@@ -1478,22 +1541,22 @@ var STATUS_FILTERS = [
|
|
|
1478
1541
|
function ScenarioExplorer({ scenarios, summary }) {
|
|
1479
1542
|
const [status, setStatus] = useState3("all");
|
|
1480
1543
|
const visible = status === "all" ? scenarios : scenarios.filter((s) => s.status === status);
|
|
1481
|
-
return /* @__PURE__ */
|
|
1482
|
-
summary ? /* @__PURE__ */
|
|
1544
|
+
return /* @__PURE__ */ jsxs24("div", { className: "font-sans text-foreground", children: [
|
|
1545
|
+
summary ? /* @__PURE__ */ jsxs24("p", { className: "mb-3 text-sm text-muted-foreground", children: [
|
|
1483
1546
|
summary.total,
|
|
1484
1547
|
" scenarios \xB7 ",
|
|
1485
|
-
/* @__PURE__ */
|
|
1548
|
+
/* @__PURE__ */ jsxs24("span", { className: "text-pass", children: [
|
|
1486
1549
|
summary.passed,
|
|
1487
1550
|
" passed"
|
|
1488
1551
|
] }),
|
|
1489
1552
|
" \xB7",
|
|
1490
1553
|
" ",
|
|
1491
|
-
/* @__PURE__ */
|
|
1554
|
+
/* @__PURE__ */ jsxs24("span", { className: "text-fail", children: [
|
|
1492
1555
|
summary.failed,
|
|
1493
1556
|
" failed"
|
|
1494
1557
|
] })
|
|
1495
1558
|
] }) : null,
|
|
1496
|
-
/* @__PURE__ */
|
|
1559
|
+
/* @__PURE__ */ jsx37("div", { className: "mb-2 flex flex-wrap gap-1.5", role: "group", "aria-label": "Filter by status", children: STATUS_FILTERS.map((f) => /* @__PURE__ */ jsx37(
|
|
1497
1560
|
"button",
|
|
1498
1561
|
{
|
|
1499
1562
|
type: "button",
|
|
@@ -1508,26 +1571,26 @@ function ScenarioExplorer({ scenarios, summary }) {
|
|
|
1508
1571
|
},
|
|
1509
1572
|
f.value
|
|
1510
1573
|
)) }),
|
|
1511
|
-
/* @__PURE__ */
|
|
1574
|
+
/* @__PURE__ */ jsxs24(
|
|
1512
1575
|
Command,
|
|
1513
1576
|
{
|
|
1514
1577
|
className: "rounded-lg border border-border bg-card",
|
|
1515
1578
|
filter: (value, search) => value.toLowerCase().includes(search.toLowerCase()) ? 1 : 0,
|
|
1516
1579
|
children: [
|
|
1517
|
-
/* @__PURE__ */
|
|
1518
|
-
/* @__PURE__ */
|
|
1519
|
-
/* @__PURE__ */
|
|
1520
|
-
/* @__PURE__ */
|
|
1580
|
+
/* @__PURE__ */ jsx37(CommandInput, { placeholder: "Search scenarios\u2026" }),
|
|
1581
|
+
/* @__PURE__ */ jsxs24(CommandList, { className: "max-h-none", children: [
|
|
1582
|
+
/* @__PURE__ */ jsx37(CommandEmpty, { children: "No scenarios match your filters." }),
|
|
1583
|
+
/* @__PURE__ */ jsx37(CommandGroup, { children: visible.map((s) => /* @__PURE__ */ jsx37(
|
|
1521
1584
|
CommandItem,
|
|
1522
1585
|
{
|
|
1523
1586
|
value: `${s.title} ${s.feature} ${s.tags.join(" ")}`,
|
|
1524
1587
|
asChild: true,
|
|
1525
1588
|
className: "cursor-pointer",
|
|
1526
|
-
children: /* @__PURE__ */
|
|
1527
|
-
/* @__PURE__ */
|
|
1528
|
-
/* @__PURE__ */
|
|
1529
|
-
s.tags.slice(0, 3).map((t) => /* @__PURE__ */
|
|
1530
|
-
/* @__PURE__ */
|
|
1589
|
+
children: /* @__PURE__ */ jsxs24("a", { href: s.href, className: "flex items-center gap-3", children: [
|
|
1590
|
+
/* @__PURE__ */ jsx37(Badge, { variant: s.status, children: s.status }),
|
|
1591
|
+
/* @__PURE__ */ jsx37("span", { className: "min-w-0 flex-1 truncate font-medium", children: s.title }),
|
|
1592
|
+
s.tags.slice(0, 3).map((t) => /* @__PURE__ */ jsx37(Badge, { variant: "tag", className: "hidden sm:inline-flex", children: t }, t)),
|
|
1593
|
+
/* @__PURE__ */ jsx37("code", { className: "hidden font-mono text-xs text-muted-foreground md:inline", children: s.feature })
|
|
1531
1594
|
] })
|
|
1532
1595
|
},
|
|
1533
1596
|
s.id
|