@sudobility/testomniac_ui 0.0.1

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.
Files changed (266) hide show
  1. package/README.md +83 -0
  2. package/dist/components/bundles/AddToBundleButton.d.ts +8 -0
  3. package/dist/components/bundles/AddToBundleButton.d.ts.map +1 -0
  4. package/dist/components/bundles/AddToBundleButton.js +64 -0
  5. package/dist/components/bundles/AddToBundleButton.js.map +1 -0
  6. package/dist/components/cells/BundleCell.d.ts +10 -0
  7. package/dist/components/cells/BundleCell.d.ts.map +1 -0
  8. package/dist/components/cells/BundleCell.js +8 -0
  9. package/dist/components/cells/BundleCell.js.map +1 -0
  10. package/dist/components/cells/InteractionCell.d.ts +17 -0
  11. package/dist/components/cells/InteractionCell.d.ts.map +1 -0
  12. package/dist/components/cells/InteractionCell.js +13 -0
  13. package/dist/components/cells/InteractionCell.js.map +1 -0
  14. package/dist/components/cells/ListCell.d.ts +29 -0
  15. package/dist/components/cells/ListCell.d.ts.map +1 -0
  16. package/dist/components/cells/ListCell.js +19 -0
  17. package/dist/components/cells/ListCell.js.map +1 -0
  18. package/dist/components/cells/PersonaCell.d.ts +10 -0
  19. package/dist/components/cells/PersonaCell.d.ts.map +1 -0
  20. package/dist/components/cells/PersonaCell.js +7 -0
  21. package/dist/components/cells/PersonaCell.js.map +1 -0
  22. package/dist/components/cells/ScaffoldCell.d.ts +12 -0
  23. package/dist/components/cells/ScaffoldCell.d.ts.map +1 -0
  24. package/dist/components/cells/ScaffoldCell.js +10 -0
  25. package/dist/components/cells/ScaffoldCell.js.map +1 -0
  26. package/dist/components/cells/ScenarioCell.d.ts +12 -0
  27. package/dist/components/cells/ScenarioCell.d.ts.map +1 -0
  28. package/dist/components/cells/ScenarioCell.js +8 -0
  29. package/dist/components/cells/ScenarioCell.js.map +1 -0
  30. package/dist/components/cells/SurfaceCell.d.ts +14 -0
  31. package/dist/components/cells/SurfaceCell.d.ts.map +1 -0
  32. package/dist/components/cells/SurfaceCell.js +23 -0
  33. package/dist/components/cells/SurfaceCell.js.map +1 -0
  34. package/dist/components/cells/index.d.ts +9 -0
  35. package/dist/components/cells/index.d.ts.map +1 -0
  36. package/dist/components/cells/index.js +9 -0
  37. package/dist/components/cells/index.js.map +1 -0
  38. package/dist/components/cells/scaffoldMeta.d.ts +6 -0
  39. package/dist/components/cells/scaffoldMeta.d.ts.map +1 -0
  40. package/dist/components/cells/scaffoldMeta.js +47 -0
  41. package/dist/components/cells/scaffoldMeta.js.map +1 -0
  42. package/dist/components/dashboard/DashboardSidebar.d.ts +6 -0
  43. package/dist/components/dashboard/DashboardSidebar.d.ts.map +1 -0
  44. package/dist/components/dashboard/DashboardSidebar.js +163 -0
  45. package/dist/components/dashboard/DashboardSidebar.js.map +1 -0
  46. package/dist/components/data/DataTable.d.ts +16 -0
  47. package/dist/components/data/DataTable.d.ts.map +1 -0
  48. package/dist/components/data/DataTable.js +54 -0
  49. package/dist/components/data/DataTable.js.map +1 -0
  50. package/dist/components/data/JsonViewer.d.ts +6 -0
  51. package/dist/components/data/JsonViewer.d.ts.map +1 -0
  52. package/dist/components/data/JsonViewer.js +5 -0
  53. package/dist/components/data/JsonViewer.js.map +1 -0
  54. package/dist/components/data/index.d.ts +3 -0
  55. package/dist/components/data/index.d.ts.map +1 -0
  56. package/dist/components/data/index.js +3 -0
  57. package/dist/components/data/index.js.map +1 -0
  58. package/dist/components/forms/SelectField.d.ts +22 -0
  59. package/dist/components/forms/SelectField.d.ts.map +1 -0
  60. package/dist/components/forms/SelectField.js +14 -0
  61. package/dist/components/forms/SelectField.js.map +1 -0
  62. package/dist/components/navigation/BackLink.d.ts +7 -0
  63. package/dist/components/navigation/BackLink.d.ts.map +1 -0
  64. package/dist/components/navigation/BackLink.js +6 -0
  65. package/dist/components/navigation/BackLink.js.map +1 -0
  66. package/dist/components/pages/PagesListView.d.ts +12 -0
  67. package/dist/components/pages/PagesListView.d.ts.map +1 -0
  68. package/dist/components/pages/PagesListView.js +19 -0
  69. package/dist/components/pages/PagesListView.js.map +1 -0
  70. package/dist/components/pages/PagesMapView.d.ts +15 -0
  71. package/dist/components/pages/PagesMapView.d.ts.map +1 -0
  72. package/dist/components/pages/PagesMapView.js +232 -0
  73. package/dist/components/pages/PagesMapView.js.map +1 -0
  74. package/dist/components/scanner/EventLog.d.ts +8 -0
  75. package/dist/components/scanner/EventLog.d.ts.map +1 -0
  76. package/dist/components/scanner/EventLog.js +18 -0
  77. package/dist/components/scanner/EventLog.js.map +1 -0
  78. package/dist/components/scanner/LiveCounters.d.ts +9 -0
  79. package/dist/components/scanner/LiveCounters.d.ts.map +1 -0
  80. package/dist/components/scanner/LiveCounters.js +33 -0
  81. package/dist/components/scanner/LiveCounters.js.map +1 -0
  82. package/dist/components/scanner/PhaseIndicator.d.ts +6 -0
  83. package/dist/components/scanner/PhaseIndicator.d.ts.map +1 -0
  84. package/dist/components/scanner/PhaseIndicator.js +31 -0
  85. package/dist/components/scanner/PhaseIndicator.js.map +1 -0
  86. package/dist/components/scanner/RunSummaryCard.d.ts +12 -0
  87. package/dist/components/scanner/RunSummaryCard.d.ts.map +1 -0
  88. package/dist/components/scanner/RunSummaryCard.js +7 -0
  89. package/dist/components/scanner/RunSummaryCard.js.map +1 -0
  90. package/dist/components/scanner/ScanForm.d.ts +9 -0
  91. package/dist/components/scanner/ScanForm.d.ts.map +1 -0
  92. package/dist/components/scanner/ScanForm.js +31 -0
  93. package/dist/components/scanner/ScanForm.js.map +1 -0
  94. package/dist/components/scanner/ScanProgressPanel.d.ts +16 -0
  95. package/dist/components/scanner/ScanProgressPanel.d.ts.map +1 -0
  96. package/dist/components/scanner/ScanProgressPanel.js +8 -0
  97. package/dist/components/scanner/ScanProgressPanel.js.map +1 -0
  98. package/dist/components/scanner/StatusBadge.d.ts +7 -0
  99. package/dist/components/scanner/StatusBadge.d.ts.map +1 -0
  100. package/dist/components/scanner/StatusBadge.js +65 -0
  101. package/dist/components/scanner/StatusBadge.js.map +1 -0
  102. package/dist/components/scanner/index.d.ts +8 -0
  103. package/dist/components/scanner/index.d.ts.map +1 -0
  104. package/dist/components/scanner/index.js +8 -0
  105. package/dist/components/scanner/index.js.map +1 -0
  106. package/dist/components/scenarios/AddScenarioForm.d.ts +14 -0
  107. package/dist/components/scenarios/AddScenarioForm.d.ts.map +1 -0
  108. package/dist/components/scenarios/AddScenarioForm.js +43 -0
  109. package/dist/components/scenarios/AddScenarioForm.js.map +1 -0
  110. package/dist/components/scripts/ScriptPanel.d.ts +17 -0
  111. package/dist/components/scripts/ScriptPanel.d.ts.map +1 -0
  112. package/dist/components/scripts/ScriptPanel.js +32 -0
  113. package/dist/components/scripts/ScriptPanel.js.map +1 -0
  114. package/dist/components/states/index.d.ts +19 -0
  115. package/dist/components/states/index.d.ts.map +1 -0
  116. package/dist/components/states/index.js +16 -0
  117. package/dist/components/states/index.js.map +1 -0
  118. package/dist/config/priorityConfig.d.ts +12 -0
  119. package/dist/config/priorityConfig.d.ts.map +1 -0
  120. package/dist/config/priorityConfig.js +39 -0
  121. package/dist/config/priorityConfig.js.map +1 -0
  122. package/dist/context/config.d.ts +53 -0
  123. package/dist/context/config.d.ts.map +1 -0
  124. package/dist/context/config.js +32 -0
  125. package/dist/context/config.js.map +1 -0
  126. package/dist/context/routing.d.ts +42 -0
  127. package/dist/context/routing.d.ts.map +1 -0
  128. package/dist/context/routing.js +33 -0
  129. package/dist/context/routing.js.map +1 -0
  130. package/dist/hooks/useDashboardEnvironmentContext.d.ts +15 -0
  131. package/dist/hooks/useDashboardEnvironmentContext.d.ts.map +1 -0
  132. package/dist/hooks/useDashboardEnvironmentContext.js +89 -0
  133. package/dist/hooks/useDashboardEnvironmentContext.js.map +1 -0
  134. package/dist/hooks/useEnvBasePath.d.ts +8 -0
  135. package/dist/hooks/useEnvBasePath.d.ts.map +1 -0
  136. package/dist/hooks/useEnvBasePath.js +12 -0
  137. package/dist/hooks/useEnvBasePath.js.map +1 -0
  138. package/dist/hooks/useLocalizedNavigate.d.ts +12 -0
  139. package/dist/hooks/useLocalizedNavigate.d.ts.map +1 -0
  140. package/dist/hooks/useLocalizedNavigate.js +14 -0
  141. package/dist/hooks/useLocalizedNavigate.js.map +1 -0
  142. package/dist/index.d.ts +49 -0
  143. package/dist/index.d.ts.map +1 -0
  144. package/dist/index.js +66 -0
  145. package/dist/index.js.map +1 -0
  146. package/dist/pages/BundleDetailPage.d.ts +2 -0
  147. package/dist/pages/BundleDetailPage.d.ts.map +1 -0
  148. package/dist/pages/BundleDetailPage.js +155 -0
  149. package/dist/pages/BundleDetailPage.js.map +1 -0
  150. package/dist/pages/BundlesPage.d.ts +2 -0
  151. package/dist/pages/BundlesPage.d.ts.map +1 -0
  152. package/dist/pages/BundlesPage.js +61 -0
  153. package/dist/pages/BundlesPage.js.map +1 -0
  154. package/dist/pages/DashboardOverview.d.ts +2 -0
  155. package/dist/pages/DashboardOverview.d.ts.map +1 -0
  156. package/dist/pages/DashboardOverview.js +179 -0
  157. package/dist/pages/DashboardOverview.js.map +1 -0
  158. package/dist/pages/FindingsListPage.d.ts +2 -0
  159. package/dist/pages/FindingsListPage.d.ts.map +1 -0
  160. package/dist/pages/FindingsListPage.js +160 -0
  161. package/dist/pages/FindingsListPage.js.map +1 -0
  162. package/dist/pages/PageDetailPage.d.ts +2 -0
  163. package/dist/pages/PageDetailPage.d.ts.map +1 -0
  164. package/dist/pages/PageDetailPage.js +120 -0
  165. package/dist/pages/PageDetailPage.js.map +1 -0
  166. package/dist/pages/PageGraphPage.d.ts +3 -0
  167. package/dist/pages/PageGraphPage.d.ts.map +1 -0
  168. package/dist/pages/PageGraphPage.js +72 -0
  169. package/dist/pages/PageGraphPage.js.map +1 -0
  170. package/dist/pages/PageStateDetailPage.d.ts +2 -0
  171. package/dist/pages/PageStateDetailPage.d.ts.map +1 -0
  172. package/dist/pages/PageStateDetailPage.js +69 -0
  173. package/dist/pages/PageStateDetailPage.js.map +1 -0
  174. package/dist/pages/PagesPage.d.ts +2 -0
  175. package/dist/pages/PagesPage.d.ts.map +1 -0
  176. package/dist/pages/PagesPage.js +83 -0
  177. package/dist/pages/PagesPage.js.map +1 -0
  178. package/dist/pages/PatternsPage.d.ts +2 -0
  179. package/dist/pages/PatternsPage.d.ts.map +1 -0
  180. package/dist/pages/PatternsPage.js +102 -0
  181. package/dist/pages/PatternsPage.js.map +1 -0
  182. package/dist/pages/PersonasPage.d.ts +2 -0
  183. package/dist/pages/PersonasPage.d.ts.map +1 -0
  184. package/dist/pages/PersonasPage.js +151 -0
  185. package/dist/pages/PersonasPage.js.map +1 -0
  186. package/dist/pages/RunRedirect.d.ts +2 -0
  187. package/dist/pages/RunRedirect.d.ts.map +1 -0
  188. package/dist/pages/RunRedirect.js +25 -0
  189. package/dist/pages/RunRedirect.js.map +1 -0
  190. package/dist/pages/RunSurfaceRunDetailPage.d.ts +2 -0
  191. package/dist/pages/RunSurfaceRunDetailPage.d.ts.map +1 -0
  192. package/dist/pages/RunSurfaceRunDetailPage.js +38 -0
  193. package/dist/pages/RunSurfaceRunDetailPage.js.map +1 -0
  194. package/dist/pages/RunSurfaceRunsPage.d.ts +2 -0
  195. package/dist/pages/RunSurfaceRunsPage.d.ts.map +1 -0
  196. package/dist/pages/RunSurfaceRunsPage.js +35 -0
  197. package/dist/pages/RunSurfaceRunsPage.js.map +1 -0
  198. package/dist/pages/RunTestInteractionRunDetailPage.d.ts +2 -0
  199. package/dist/pages/RunTestInteractionRunDetailPage.d.ts.map +1 -0
  200. package/dist/pages/RunTestInteractionRunDetailPage.js +55 -0
  201. package/dist/pages/RunTestInteractionRunDetailPage.js.map +1 -0
  202. package/dist/pages/RunTestInteractionRunsPage.d.ts +2 -0
  203. package/dist/pages/RunTestInteractionRunsPage.d.ts.map +1 -0
  204. package/dist/pages/RunTestInteractionRunsPage.js +38 -0
  205. package/dist/pages/RunTestInteractionRunsPage.js.map +1 -0
  206. package/dist/pages/RunnerGraphPage.d.ts +3 -0
  207. package/dist/pages/RunnerGraphPage.d.ts.map +1 -0
  208. package/dist/pages/RunnerGraphPage.js +86 -0
  209. package/dist/pages/RunnerGraphPage.js.map +1 -0
  210. package/dist/pages/ScaffoldDetailPage.d.ts +2 -0
  211. package/dist/pages/ScaffoldDetailPage.d.ts.map +1 -0
  212. package/dist/pages/ScaffoldDetailPage.js +56 -0
  213. package/dist/pages/ScaffoldDetailPage.js.map +1 -0
  214. package/dist/pages/ScaffoldsPage.d.ts +2 -0
  215. package/dist/pages/ScaffoldsPage.d.ts.map +1 -0
  216. package/dist/pages/ScaffoldsPage.js +35 -0
  217. package/dist/pages/ScaffoldsPage.js.map +1 -0
  218. package/dist/pages/ScanProgressPage.d.ts +2 -0
  219. package/dist/pages/ScanProgressPage.d.ts.map +1 -0
  220. package/dist/pages/ScanProgressPage.js +30 -0
  221. package/dist/pages/ScanProgressPage.js.map +1 -0
  222. package/dist/pages/SchedulesPage.d.ts +2 -0
  223. package/dist/pages/SchedulesPage.d.ts.map +1 -0
  224. package/dist/pages/SchedulesPage.js +165 -0
  225. package/dist/pages/SchedulesPage.js.map +1 -0
  226. package/dist/pages/StartScanPage.d.ts +2 -0
  227. package/dist/pages/StartScanPage.d.ts.map +1 -0
  228. package/dist/pages/StartScanPage.js +97 -0
  229. package/dist/pages/StartScanPage.js.map +1 -0
  230. package/dist/pages/TestInteractionDetailPage.d.ts +2 -0
  231. package/dist/pages/TestInteractionDetailPage.d.ts.map +1 -0
  232. package/dist/pages/TestInteractionDetailPage.js +60 -0
  233. package/dist/pages/TestInteractionDetailPage.js.map +1 -0
  234. package/dist/pages/TestInteractionsPage.d.ts +2 -0
  235. package/dist/pages/TestInteractionsPage.d.ts.map +1 -0
  236. package/dist/pages/TestInteractionsPage.js +96 -0
  237. package/dist/pages/TestInteractionsPage.js.map +1 -0
  238. package/dist/pages/TestRunDetailPage.d.ts +2 -0
  239. package/dist/pages/TestRunDetailPage.d.ts.map +1 -0
  240. package/dist/pages/TestRunDetailPage.js +81 -0
  241. package/dist/pages/TestRunDetailPage.js.map +1 -0
  242. package/dist/pages/TestRunsListPage.d.ts +2 -0
  243. package/dist/pages/TestRunsListPage.d.ts.map +1 -0
  244. package/dist/pages/TestRunsListPage.js +18 -0
  245. package/dist/pages/TestRunsListPage.js.map +1 -0
  246. package/dist/pages/TestScenarioDetailPage.d.ts +2 -0
  247. package/dist/pages/TestScenarioDetailPage.d.ts.map +1 -0
  248. package/dist/pages/TestScenarioDetailPage.js +101 -0
  249. package/dist/pages/TestScenarioDetailPage.js.map +1 -0
  250. package/dist/pages/TestScenariosPage.d.ts +2 -0
  251. package/dist/pages/TestScenariosPage.d.ts.map +1 -0
  252. package/dist/pages/TestScenariosPage.js +73 -0
  253. package/dist/pages/TestScenariosPage.js.map +1 -0
  254. package/dist/pages/TestSurfaceDetailPage.d.ts +2 -0
  255. package/dist/pages/TestSurfaceDetailPage.d.ts.map +1 -0
  256. package/dist/pages/TestSurfaceDetailPage.js +33 -0
  257. package/dist/pages/TestSurfaceDetailPage.js.map +1 -0
  258. package/dist/pages/TestSurfacesListPage.d.ts +2 -0
  259. package/dist/pages/TestSurfacesListPage.d.ts.map +1 -0
  260. package/dist/pages/TestSurfacesListPage.js +73 -0
  261. package/dist/pages/TestSurfacesListPage.js.map +1 -0
  262. package/dist/utils/formatDateTime.d.ts +13 -0
  263. package/dist/utils/formatDateTime.d.ts.map +1 -0
  264. package/dist/utils/formatDateTime.js +27 -0
  265. package/dist/utils/formatDateTime.js.map +1 -0
  266. package/package.json +72 -0
@@ -0,0 +1,163 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useMemo, useState } from 'react';
3
+ import { Select, SelectTrigger, SelectContent, SelectItem, SelectValue, } from '@sudobility/components';
4
+ import { useEntityProducts, useProductEnvironments } from '@sudobility/testomniac_client';
5
+ import { useLocalizedNavigate } from '../../hooks/useLocalizedNavigate';
6
+ import { useTestomniacApi } from '../../context/config';
7
+ import { useRouteParams, useTestomniacRouting } from '../../context/routing';
8
+ /* ------------------------------------------------------------------ */
9
+ /* Inline SVG icons (16x16, stroke-based, currentColor) */
10
+ /* ------------------------------------------------------------------ */
11
+ const iconProps = {
12
+ width: 16,
13
+ height: 16,
14
+ viewBox: '0 0 16 16',
15
+ fill: 'none',
16
+ stroke: 'currentColor',
17
+ strokeWidth: 1.5,
18
+ strokeLinecap: 'round',
19
+ strokeLinejoin: 'round',
20
+ };
21
+ /** 4-square grid */
22
+ const BundlesIcon = () => (_jsxs("svg", { ...iconProps, children: [_jsx("rect", { x: "2", y: "2", width: "5", height: "5", rx: "1" }), _jsx("rect", { x: "9", y: "2", width: "5", height: "5", rx: "1" }), _jsx("rect", { x: "2", y: "9", width: "5", height: "5", rx: "1" }), _jsx("rect", { x: "9", y: "9", width: "5", height: "5", rx: "1" })] }));
23
+ /** Document stack */
24
+ const PagesIcon = () => (_jsxs("svg", { ...iconProps, children: [_jsx("path", { d: "M4 2h6l3 3v9a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V3a1 1 0 0 1 1-1z" }), _jsx("path", { d: "M10 2v3h3" }), _jsx("path", { d: "M6 9h4" }), _jsx("path", { d: "M6 11.5h3" })] }));
25
+ /** Layers / surfaces */
26
+ const SurfacesIcon = () => (_jsxs("svg", { ...iconProps, children: [_jsx("path", { d: "M2 8l6-4 6 4-6 4-6-4z" }), _jsx("path", { d: "M2 10.5l6 4 6-4" }), _jsx("path", { d: "M2 13l6 4 6-4" })] }));
27
+ /** Pointer click / interaction */
28
+ const InteractionsIcon = () => (_jsx("svg", { ...iconProps, children: _jsx("path", { d: "M5 2v8l2.5-2.5L10 12l1.5-1-2.5-4.5H13L5 2z" }) }));
29
+ /** Branching path / scenario */
30
+ const ScenariosIcon = () => (_jsxs("svg", { ...iconProps, children: [_jsx("circle", { cx: "4", cy: "4", r: "1.5" }), _jsx("circle", { cx: "12", cy: "4", r: "1.5" }), _jsx("circle", { cx: "12", cy: "12", r: "1.5" }), _jsx("path", { d: "M5.5 4h5" }), _jsx("path", { d: "M4 5.5v3.5a2 2 0 0 0 2 2h4.5" })] }));
31
+ /** Person silhouette / personas */
32
+ const PersonasIcon = () => (_jsxs("svg", { ...iconProps, children: [_jsx("circle", { cx: "8", cy: "5", r: "2.5" }), _jsx("path", { d: "M3 14.5c0-2.8 2.2-5 5-5s5 2.2 5 5" })] }));
33
+ /** Play-circle / runs */
34
+ const RunsIcon = () => (_jsxs("svg", { ...iconProps, children: [_jsx("circle", { cx: "8", cy: "8", r: "6" }), _jsx("path", { d: "M6.5 5.5l4 2.5-4 2.5V5.5z" })] }));
35
+ /** Template / scaffold */
36
+ const ScaffoldsIcon = () => (_jsxs("svg", { ...iconProps, children: [_jsx("rect", { x: "2", y: "2", width: "12", height: "12", rx: "1.5" }), _jsx("path", { d: "M2 6h12" }), _jsx("path", { d: "M6 6v8" })] }));
37
+ /** Grid / patterns */
38
+ const PatternsIcon = () => (_jsxs("svg", { ...iconProps, children: [_jsx("rect", { x: "2", y: "2", width: "5", height: "5", rx: "0.5" }), _jsx("rect", { x: "9", y: "2", width: "5", height: "5", rx: "0.5" }), _jsx("rect", { x: "2", y: "9", width: "5", height: "5", rx: "0.5" }), _jsx("rect", { x: "9", y: "9", width: "5", height: "5", rx: "0.5" })] }));
39
+ /** Warning triangle / issues */
40
+ const IssuesIcon = () => (_jsxs("svg", { ...iconProps, children: [_jsx("path", { d: "M8 2L1.5 13.5h13L8 2z" }), _jsx("path", { d: "M8 7v3" }), _jsx("circle", { cx: "8", cy: "11.5", r: "0.5", fill: "currentColor", stroke: "none" })] }));
41
+ /** Clock / schedules */
42
+ const SchedulesIcon = () => (_jsxs("svg", { ...iconProps, children: [_jsx("circle", { cx: "8", cy: "8", r: "6" }), _jsx("path", { d: "M8 4.5v3.5l2.5 2" })] }));
43
+ /** Gear / settings */
44
+ const SettingsIcon = () => (_jsxs("svg", { ...iconProps, children: [_jsx("circle", { cx: "8", cy: "8", r: "2.5" }), _jsx("path", { d: "M8 1.5v1.5M8 13v1.5M1.5 8H3M13 8h1.5M3.05 3.05l1.1 1.1M11.85 11.85l1.1 1.1M3.05 12.95l1.1-1.1M11.85 4.15l1.1-1.1" })] }));
45
+ const MENU_SECTIONS = [
46
+ {
47
+ title: 'OVERVIEW',
48
+ items: [
49
+ { label: 'Bundles', path: 'bundles', icon: BundlesIcon },
50
+ { label: 'Runs', path: 'runs', icon: RunsIcon },
51
+ { label: 'Schedules', path: 'schedules', icon: SchedulesIcon },
52
+ ],
53
+ },
54
+ {
55
+ title: 'DISCOVERY',
56
+ items: [
57
+ { label: 'Pages', path: 'pages', icon: PagesIcon },
58
+ { label: 'Surfaces', path: 'test-surfaces', icon: SurfacesIcon },
59
+ { label: 'Test Interactions', path: 'test-interactions', icon: InteractionsIcon },
60
+ { label: 'Personas', path: 'personas', icon: PersonasIcon },
61
+ { label: 'Scenarios', path: 'test-scenarios', icon: ScenariosIcon },
62
+ ],
63
+ },
64
+ {
65
+ title: 'ANALYSIS',
66
+ items: [
67
+ { label: 'Issues', path: 'issues', icon: IssuesIcon },
68
+ { label: 'Scaffolds', path: 'scaffolds', icon: ScaffoldsIcon },
69
+ { label: 'Patterns', path: 'patterns', icon: PatternsIcon },
70
+ ],
71
+ },
72
+ {
73
+ title: 'WORKSPACE',
74
+ items: [{ label: 'Settings', path: 'settings', icon: SettingsIcon }],
75
+ },
76
+ ];
77
+ /* ------------------------------------------------------------------ */
78
+ /* Component */
79
+ /* ------------------------------------------------------------------ */
80
+ export function DashboardSidebar({ entitySlug }) {
81
+ const { envId: routeEnvId } = useRouteParams();
82
+ const { networkClient, token, baseUrl } = useTestomniacApi();
83
+ const { navigate } = useLocalizedNavigate();
84
+ const { pathname } = useTestomniacRouting();
85
+ const { products, isLoading: productsLoading } = useEntityProducts({
86
+ networkClient,
87
+ baseUrl,
88
+ entitySlug,
89
+ token: token ?? '',
90
+ enabled: !!token,
91
+ });
92
+ // Tracks explicit user selection; null means "no manual choice yet"
93
+ const [userSelectedProductId, setUserSelectedProductId] = useState(null);
94
+ // Effective selection: user's choice if still valid, otherwise auto-select single product
95
+ const selectedProductId = useMemo(() => {
96
+ if (userSelectedProductId && products.some(p => String(p.id) === userSelectedProductId)) {
97
+ return userSelectedProductId;
98
+ }
99
+ if (products.length === 1)
100
+ return String(products[0].id);
101
+ return null;
102
+ }, [products, userSelectedProductId]);
103
+ const { environments, isLoading: environmentsLoading } = useProductEnvironments({
104
+ networkClient,
105
+ baseUrl,
106
+ productId: Number(selectedProductId),
107
+ token: token ?? '',
108
+ enabled: !!selectedProductId && !!token,
109
+ });
110
+ // Auto-select environment if only one exists and no environment in route
111
+ useEffect(() => {
112
+ if (environments.length === 1 && !routeEnvId) {
113
+ navigate(`/dashboard/${entitySlug}/environments/${environments[0].id}/bundles`);
114
+ }
115
+ }, [environments, routeEnvId, entitySlug, navigate]);
116
+ const handleProductChange = (value) => {
117
+ if (value === 'new') {
118
+ navigate(`/dashboard/${entitySlug}/products/new`);
119
+ return;
120
+ }
121
+ setUserSelectedProductId(value);
122
+ // Clear any environment selected for a previously-chosen product so the
123
+ // navigation sections stay hidden until an environment for this product is
124
+ // selected. If the new product has exactly one environment, the auto-select
125
+ // effect below will navigate straight into it.
126
+ if (routeEnvId) {
127
+ navigate(`/dashboard/${entitySlug}`);
128
+ }
129
+ };
130
+ const handleEnvironmentChange = (value) => {
131
+ if (value === 'new') {
132
+ navigate(`/dashboard/${entitySlug}/environments/new`);
133
+ return;
134
+ }
135
+ navigate(`/dashboard/${entitySlug}/environments/${value}/bundles`);
136
+ };
137
+ // Active path detection
138
+ const currentPath = useMemo(() => {
139
+ const langPrefix = pathname.match(/^\/[a-z]{2}(-[a-z]+)?\//)?.[0] || '/';
140
+ return pathname.slice(langPrefix.length - 1);
141
+ }, [pathname]);
142
+ const envBasePath = `/dashboard/${entitySlug}/environments/${routeEnvId}`;
143
+ const isActive = (menuPath) => {
144
+ const full = `${envBasePath}/${menuPath}`;
145
+ return currentPath === full || currentPath.startsWith(full + '/');
146
+ };
147
+ return (_jsxs("div", { className: "flex flex-col h-full bg-white dark:bg-gray-950 border-r border-gray-200 dark:border-gray-800", children: [_jsxs("div", { className: "p-4 space-y-3 border-b border-gray-100 dark:border-gray-800", children: [_jsxs("div", { children: [_jsx("span", { className: "block text-[10px] font-semibold uppercase tracking-widest text-gray-400 dark:text-gray-500 mb-1.5 px-0.5", children: "Product" }), _jsx("div", { className: "rounded-lg border border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900 p-0.5", children: _jsxs(Select, { value: selectedProductId ?? '', onValueChange: handleProductChange, children: [_jsx(SelectTrigger, { className: "w-full border-0 bg-transparent shadow-none text-[13px] font-medium", children: _jsx(SelectValue, { placeholder: productsLoading ? 'Loading...' : 'Select product' }) }), _jsxs(SelectContent, { children: [products.map(p => (_jsx(SelectItem, { value: String(p.id), children: p.title }, p.id))), _jsx(SelectItem, { value: "new", children: "+ Create New..." })] })] }) })] }), _jsxs("div", { children: [_jsx("span", { className: "block text-[10px] font-semibold uppercase tracking-widest text-gray-400 dark:text-gray-500 mb-1.5 px-0.5", children: "Environment" }), _jsx("div", { className: "rounded-lg border border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900 p-0.5", children: _jsxs(Select, { value: routeEnvId ?? '', onValueChange: handleEnvironmentChange, disabled: !selectedProductId, children: [_jsx(SelectTrigger, { className: "w-full border-0 bg-transparent shadow-none text-[13px] font-medium", children: _jsx(SelectValue, { placeholder: environmentsLoading ? 'Loading...' : 'Select environment' }) }), _jsxs(SelectContent, { children: [environments.map(a => (_jsx(SelectItem, { value: String(a.id), children: a.title }, a.id))), _jsx(SelectItem, { value: "new", children: "+ Create New..." })] })] }) })] })] }), routeEnvId && (_jsx("nav", { className: "flex-1 overflow-y-auto py-3 px-3", children: MENU_SECTIONS.map((section, sectionIdx) => (_jsxs("div", { children: [sectionIdx > 0 && (_jsx("div", { className: "mx-2 my-2 border-t border-gray-100 dark:border-gray-800" })), _jsx("span", { className: "block text-[10px] font-semibold uppercase tracking-widest text-gray-400 dark:text-gray-500 px-2 pt-1.5 pb-1", children: section.title }), section.items.map(item => {
148
+ const active = isActive(item.path);
149
+ const Icon = item.icon;
150
+ return (_jsxs("button", { onClick: () => navigate(`${envBasePath}/${item.path}`), className: [
151
+ 'group relative flex w-full items-center gap-2.5 rounded-md px-2 py-1.5 text-[13px] font-medium transition-all duration-150',
152
+ active
153
+ ? 'bg-blue-50 text-blue-700 dark:bg-blue-950/50 dark:text-blue-300'
154
+ : 'text-gray-600 dark:text-gray-400 hover:bg-gray-50 hover:text-gray-900 dark:hover:bg-gray-900 dark:hover:text-gray-200',
155
+ ].join(' '), children: [active && (_jsx("span", { className: "absolute left-0 top-1 bottom-1 w-[3px] rounded-full bg-blue-600 dark:bg-blue-400" })), _jsx("span", { className: [
156
+ 'flex-shrink-0 transition-colors duration-150',
157
+ active
158
+ ? 'text-blue-600 dark:text-blue-400'
159
+ : 'text-gray-400 dark:text-gray-500 group-hover:text-gray-600 dark:group-hover:text-gray-300',
160
+ ].join(' '), children: _jsx(Icon, {}) }), _jsx("span", { children: item.label })] }, item.path));
161
+ })] }, section.title))) })), !routeEnvId && (_jsx("div", { className: "flex-1 flex items-center justify-center p-6", children: _jsx("p", { className: "text-[13px] text-gray-400 dark:text-gray-500 text-center leading-relaxed", children: "Select a product and environment to get started" }) }))] }));
162
+ }
163
+ //# sourceMappingURL=DashboardSidebar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DashboardSidebar.js","sourceRoot":"","sources":["../../../src/components/dashboard/DashboardSidebar.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import { type ColumnDef, type SortingState } from '@tanstack/react-table';
2
+ interface DataTableProps<T> {
3
+ data: T[];
4
+ columns: ColumnDef<T, unknown>[];
5
+ pageSize?: number;
6
+ isLoading?: boolean;
7
+ initialSorting?: SortingState;
8
+ emptyMessage?: string;
9
+ globalFilter?: string;
10
+ onGlobalFilterChange?: (value: string) => void;
11
+ /** When provided, rows become clickable and invoke this with the row data. */
12
+ onRowClick?: (row: T) => void;
13
+ }
14
+ export declare function DataTable<T>({ data, columns, pageSize, isLoading, initialSorting, emptyMessage, globalFilter: externalFilter, onGlobalFilterChange: onExternalFilterChange, onRowClick, }: DataTableProps<T>): import("react").JSX.Element;
15
+ export {};
16
+ //# sourceMappingURL=DataTable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DataTable.d.ts","sourceRoot":"","sources":["../../../src/components/data/DataTable.tsx"],"names":[],"mappings":"AACA,OAAO,EAOL,KAAK,SAAS,EACd,KAAK,YAAY,EAClB,MAAM,uBAAuB,CAAC;AAG/B,UAAU,cAAc,CAAC,CAAC;IACxB,IAAI,EAAE,CAAC,EAAE,CAAC;IACV,OAAO,EAAE,SAAS,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,CAAC;IACjC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,cAAc,CAAC,EAAE,YAAY,CAAC;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oBAAoB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,8EAA8E;IAC9E,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,IAAI,CAAC;CAC/B;AA6CD,wBAAgB,SAAS,CAAC,CAAC,EAAE,EAC3B,IAAI,EACJ,OAAO,EACP,QAAa,EACb,SAAS,EACT,cAAc,EACd,YAA8B,EAC9B,YAAY,EAAE,cAAc,EAC5B,oBAAoB,EAAE,sBAAsB,EAC5C,UAAU,GACX,EAAE,cAAc,CAAC,CAAC,CAAC,+BA+MnB"}
@@ -0,0 +1,54 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /* eslint-disable react-hooks/incompatible-library */
3
+ import { useReactTable, getCoreRowModel, getSortedRowModel, getFilteredRowModel, getPaginationRowModel, flexRender, } from '@tanstack/react-table';
4
+ import { useState } from 'react';
5
+ function SkeletonRows({ columnCount }) {
6
+ const widths = ['w-3/4', 'w-1/2', 'w-2/3', 'w-5/6'];
7
+ return (_jsx(_Fragment, { children: Array.from({ length: 5 }).map((_, rowIdx) => (_jsx("tr", { className: `border-b border-gray-100 dark:border-gray-800 ${rowIdx % 2 === 0 ? 'bg-gray-50/50 dark:bg-gray-800/20' : ''}`, children: Array.from({ length: columnCount }).map((_, colIdx) => (_jsx("td", { className: "px-3 py-2.5", children: _jsx("div", { className: `h-4 ${widths[(rowIdx + colIdx) % widths.length]} rounded bg-gray-200 dark:bg-gray-700 animate-pulse` }) }, colIdx))) }, rowIdx))) }));
8
+ }
9
+ function EmptyState({ message }) {
10
+ return (_jsxs("div", { className: "flex flex-col items-center justify-center py-16 text-gray-400 dark:text-gray-500", children: [_jsx("svg", { className: "mb-3 h-10 w-10", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 1.5, children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M20.25 7.5l-.625 10.632a2.25 2.25 0 01-2.247 2.118H6.622a2.25 2.25 0 01-2.247-2.118L3.75 7.5m6 4.125l2.25 2.25m0 0l2.25 2.25M12 11.625l2.25-2.25M12 11.625l-2.25 2.25M3.375 7.5h17.25c.621 0 1.125-.504 1.125-1.125v-1.5c0-.621-.504-1.125-1.125-1.125H3.375c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125z" }) }), _jsx("p", { className: "text-sm font-medium", children: message })] }));
11
+ }
12
+ export function DataTable({ data, columns, pageSize = 20, isLoading, initialSorting, emptyMessage = 'No data found', globalFilter: externalFilter, onGlobalFilterChange: onExternalFilterChange, onRowClick, }) {
13
+ const [sorting, setSorting] = useState(initialSorting ?? []);
14
+ const [internalFilter, setInternalFilter] = useState('');
15
+ const globalFilter = externalFilter ?? internalFilter;
16
+ const setGlobalFilter = onExternalFilterChange ?? setInternalFilter;
17
+ const table = useReactTable({
18
+ data,
19
+ columns,
20
+ state: { sorting, globalFilter },
21
+ onSortingChange: setSorting,
22
+ onGlobalFilterChange: setGlobalFilter,
23
+ getCoreRowModel: getCoreRowModel(),
24
+ getSortedRowModel: getSortedRowModel(),
25
+ getFilteredRowModel: getFilteredRowModel(),
26
+ getPaginationRowModel: getPaginationRowModel(),
27
+ initialState: { pagination: { pageSize } },
28
+ });
29
+ const totalRows = table.getFilteredRowModel().rows.length;
30
+ const pageIndex = table.getState().pagination.pageIndex;
31
+ const currentPageSize = table.getState().pagination.pageSize;
32
+ const startRow = totalRows === 0 ? 0 : pageIndex * currentPageSize + 1;
33
+ const endRow = Math.min((pageIndex + 1) * currentPageSize, totalRows);
34
+ const pageCount = table.getPageCount();
35
+ return (_jsxs("div", { className: "overflow-x-auto", children: [!isLoading && data.length > 0 && (_jsxs("div", { className: "flex items-center justify-between px-3 py-2 mb-1", children: [_jsxs("span", { className: "text-xs text-gray-500 dark:text-gray-400", children: ["Showing ", startRow, "\u2013", endRow, " of ", totalRows] }), _jsxs("div", { className: "relative", children: [_jsx("svg", { className: "pointer-events-none absolute left-2.5 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-gray-400 dark:text-gray-500", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M21 21l-5.197-5.197m0 0A7.5 7.5 0 105.196 5.196a7.5 7.5 0 0010.607 10.607z" }) }), _jsx("input", { type: "text", value: globalFilter, onChange: e => setGlobalFilter(e.target.value), placeholder: "Filter...", className: "h-7 w-48 rounded border border-gray-300 bg-white pl-8 pr-2 text-xs text-gray-700 placeholder-gray-400 focus:border-blue-400 focus:outline-none focus:ring-1 focus:ring-blue-400 dark:border-gray-600 dark:bg-gray-800 dark:text-gray-200 dark:placeholder-gray-500" })] })] })), !isLoading && data.length === 0 && _jsx(EmptyState, { message: emptyMessage }), (isLoading || data.length > 0) && (_jsxs("table", { className: "w-full text-sm", children: [_jsx("thead", { children: table.getHeaderGroups().map(headerGroup => (_jsx("tr", { className: "border-b border-gray-200 dark:border-gray-700", children: headerGroup.headers.map(header => {
36
+ const isSorted = header.column.getIsSorted();
37
+ return (_jsx("th", { className: `px-3 py-2 text-left text-xs font-medium uppercase tracking-wider cursor-pointer select-none ${isSorted
38
+ ? 'text-blue-600 dark:text-blue-400'
39
+ : 'text-gray-500 dark:text-gray-400'}`, onClick: header.column.getToggleSortingHandler(), children: _jsxs("span", { className: "inline-flex items-center gap-1", children: [flexRender(header.column.columnDef.header, header.getContext()), isSorted === 'asc' ? (_jsx("svg", { className: "h-3 w-3", viewBox: "0 0 20 20", fill: "currentColor", children: _jsx("path", { fillRule: "evenodd", d: "M14.707 12.707a1 1 0 01-1.414 0L10 9.414l-3.293 3.293a1 1 0 01-1.414-1.414l4-4a1 1 0 011.414 0l4 4a1 1 0 010 1.414z", clipRule: "evenodd" }) })) : isSorted === 'desc' ? (_jsx("svg", { className: "h-3 w-3", viewBox: "0 0 20 20", fill: "currentColor", children: _jsx("path", { fillRule: "evenodd", d: "M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z", clipRule: "evenodd" }) })) : null] }) }, header.id));
40
+ }) }, headerGroup.id))) }), _jsx("tbody", { children: isLoading ? (_jsx(SkeletonRows, { columnCount: columns.length })) : (table.getRowModel().rows.map(row => (_jsx("tr", { onClick: onRowClick ? () => onRowClick(row.original) : undefined, className: `border-b border-gray-100 dark:border-gray-800 even:bg-gray-50 dark:even:bg-gray-800/30 hover:bg-gray-100/70 dark:hover:bg-gray-800/50 transition-colors ${onRowClick ? 'cursor-pointer' : ''}`, children: row.getVisibleCells().map(cell => (_jsx("td", { className: "px-3 py-2.5 text-gray-900 dark:text-gray-100", children: flexRender(cell.column.columnDef.cell, cell.getContext()) }, cell.id))) }, row.id)))) })] })), !isLoading && pageCount > 1 && (_jsxs("div", { className: "flex items-center justify-between px-3 py-2.5 border-t border-gray-200 dark:border-gray-700", children: [_jsxs("span", { className: "text-xs text-gray-500 dark:text-gray-400", children: ["Showing ", startRow, "\u2013", endRow, " of ", totalRows] }), _jsxs("div", { className: "flex items-center gap-1", children: [_jsx("button", { onClick: () => table.setPageIndex(0), disabled: !table.getCanPreviousPage(), className: "px-2 py-1 text-xs rounded border border-gray-300 dark:border-gray-600 disabled:opacity-30 disabled:cursor-not-allowed hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors", "aria-label": "First page", children: "\u00AB" }), _jsx("button", { onClick: () => table.previousPage(), disabled: !table.getCanPreviousPage(), className: "px-2 py-1 text-xs rounded border border-gray-300 dark:border-gray-600 disabled:opacity-30 disabled:cursor-not-allowed hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors", "aria-label": "Previous page", children: "\u2039" }), Array.from({ length: pageCount }).map((_, i) => {
41
+ // Show first, last, current, and neighbors
42
+ const show = i === 0 || i === pageCount - 1 || Math.abs(i - pageIndex) <= 1;
43
+ const showEllipsis = !show && (i === 1 || i === pageCount - 2) && Math.abs(i - pageIndex) > 1;
44
+ if (showEllipsis) {
45
+ return (_jsx("span", { className: "px-1 text-xs text-gray-400 dark:text-gray-500", children: "..." }, i));
46
+ }
47
+ if (!show)
48
+ return null;
49
+ return (_jsx("button", { onClick: () => table.setPageIndex(i), className: `min-w-[28px] px-2 py-1 text-xs rounded border transition-colors ${i === pageIndex
50
+ ? 'border-blue-500 bg-blue-50 text-blue-700 font-medium dark:border-blue-400 dark:bg-blue-900/30 dark:text-blue-300'
51
+ : 'border-gray-300 dark:border-gray-600 hover:bg-gray-100 dark:hover:bg-gray-700'}`, children: i + 1 }, i));
52
+ }), _jsx("button", { onClick: () => table.nextPage(), disabled: !table.getCanNextPage(), className: "px-2 py-1 text-xs rounded border border-gray-300 dark:border-gray-600 disabled:opacity-30 disabled:cursor-not-allowed hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors", "aria-label": "Next page", children: "\u203A" }), _jsx("button", { onClick: () => table.setPageIndex(pageCount - 1), disabled: !table.getCanNextPage(), className: "px-2 py-1 text-xs rounded border border-gray-300 dark:border-gray-600 disabled:opacity-30 disabled:cursor-not-allowed hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors", "aria-label": "Last page", children: "\u00BB" })] })] }))] }));
53
+ }
54
+ //# sourceMappingURL=DataTable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DataTable.js","sourceRoot":"","sources":["../../../src/components/data/DataTable.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ interface JsonViewerProps {
2
+ data: unknown;
3
+ }
4
+ export declare function JsonViewer({ data }: JsonViewerProps): import("react").JSX.Element;
5
+ export {};
6
+ //# sourceMappingURL=JsonViewer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"JsonViewer.d.ts","sourceRoot":"","sources":["../../../src/components/data/JsonViewer.tsx"],"names":[],"mappings":"AAAA,UAAU,eAAe;IACvB,IAAI,EAAE,OAAO,CAAC;CACf;AAED,wBAAgB,UAAU,CAAC,EAAE,IAAI,EAAE,EAAE,eAAe,+BAMnD"}
@@ -0,0 +1,5 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ export function JsonViewer({ data }) {
3
+ return (_jsx("pre", { className: "p-3 rounded-lg bg-gray-50 dark:bg-gray-900 text-xs font-mono overflow-x-auto text-gray-700 dark:text-gray-300", children: JSON.stringify(data, null, 2) }));
4
+ }
5
+ //# sourceMappingURL=JsonViewer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"JsonViewer.js","sourceRoot":"","sources":["../../../src/components/data/JsonViewer.tsx"],"names":[],"mappings":";AAIA,MAAM,UAAU,UAAU,CAAC,EAAE,IAAI,EAAmB;IAClD,OAAO,CACL,cAAK,SAAS,EAAC,+GAA+G,YAC3H,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,GAC1B,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { DataTable } from './DataTable';
2
+ export { JsonViewer } from './JsonViewer';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/data/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { DataTable } from './DataTable';
2
+ export { JsonViewer } from './JsonViewer';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/data/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,22 @@
1
+ export interface SelectOption {
2
+ value: string;
3
+ label: string;
4
+ }
5
+ interface SelectFieldProps {
6
+ value: string;
7
+ onChange: (value: string) => void;
8
+ options: SelectOption[];
9
+ placeholder?: string;
10
+ disabled?: boolean;
11
+ /** Classes for the trigger (e.g. width). */
12
+ className?: string;
13
+ }
14
+ /**
15
+ * Thin adapter over the shared `@sudobility/components` `Select` that keeps the
16
+ * familiar native-`<select>` API (`value`/`onChange(value)`/`options`) and
17
+ * safely maps the empty-string value (used by "All …" filters) to a sentinel,
18
+ * since Radix's `SelectItem` rejects `value=""`.
19
+ */
20
+ export declare function SelectField({ value, onChange, options, placeholder, disabled, className, }: SelectFieldProps): import("react").JSX.Element;
21
+ export {};
22
+ //# sourceMappingURL=SelectField.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SelectField.d.ts","sourceRoot":"","sources":["../../../src/components/forms/SelectField.tsx"],"names":[],"mappings":"AAWA,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,UAAU,gBAAgB;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,4CAA4C;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,QAAQ,EACR,OAAO,EACP,WAAW,EACX,QAAQ,EACR,SAAS,GACV,EAAE,gBAAgB,+BAmBlB"}
@@ -0,0 +1,14 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@sudobility/components';
3
+ /** Sentinel for an empty-string option value — Radix `SelectItem` forbids `""`. */
4
+ const EMPTY_VALUE = '__empty__';
5
+ /**
6
+ * Thin adapter over the shared `@sudobility/components` `Select` that keeps the
7
+ * familiar native-`<select>` API (`value`/`onChange(value)`/`options`) and
8
+ * safely maps the empty-string value (used by "All …" filters) to a sentinel,
9
+ * since Radix's `SelectItem` rejects `value=""`.
10
+ */
11
+ export function SelectField({ value, onChange, options, placeholder, disabled, className, }) {
12
+ return (_jsxs(Select, { value: value === '' ? EMPTY_VALUE : value, onValueChange: v => onChange(v === EMPTY_VALUE ? '' : v), disabled: disabled, children: [_jsx(SelectTrigger, { className: className, children: _jsx(SelectValue, { placeholder: placeholder }) }), _jsx(SelectContent, { children: options.map(option => (_jsx(SelectItem, { value: option.value === '' ? EMPTY_VALUE : option.value, children: option.label }, option.value))) })] }));
13
+ }
14
+ //# sourceMappingURL=SelectField.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SelectField.js","sourceRoot":"","sources":["../../../src/components/forms/SelectField.tsx"],"names":[],"mappings":";AAAA,OAAO,EACL,MAAM,EACN,aAAa,EACb,UAAU,EACV,aAAa,EACb,WAAW,GACZ,MAAM,wBAAwB,CAAC;AAEhC,mFAAmF;AACnF,MAAM,WAAW,GAAG,WAAW,CAAC;AAiBhC;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,EAC1B,KAAK,EACL,QAAQ,EACR,OAAO,EACP,WAAW,EACX,QAAQ,EACR,SAAS,GACQ;IACjB,OAAO,CACL,MAAC,MAAM,IACL,KAAK,EAAE,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,EACzC,aAAa,EAAE,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,KAAK,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EACxD,QAAQ,EAAE,QAAQ,aAElB,KAAC,aAAa,IAAC,SAAS,EAAE,SAAS,YACjC,KAAC,WAAW,IAAC,WAAW,EAAE,WAAW,GAAI,GAC3B,EAChB,KAAC,aAAa,cACX,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CACrB,KAAC,UAAU,IAAoB,KAAK,EAAE,MAAM,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,YACnF,MAAM,CAAC,KAAK,IADE,MAAM,CAAC,KAAK,CAEhB,CACd,CAAC,GACY,IACT,CACV,CAAC;AACJ,CAAC"}
@@ -0,0 +1,7 @@
1
+ interface BackLinkProps {
2
+ label: string;
3
+ onClick: () => void;
4
+ }
5
+ export default function BackLink({ label, onClick }: BackLinkProps): import("react").JSX.Element;
6
+ export {};
7
+ //# sourceMappingURL=BackLink.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BackLink.d.ts","sourceRoot":"","sources":["../../../src/components/navigation/BackLink.tsx"],"names":[],"mappings":"AAEA,UAAU,aAAa;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,aAAa,+BAUjE"}
@@ -0,0 +1,6 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { ChevronLeftIcon } from '@heroicons/react/20/solid';
3
+ export default function BackLink({ label, onClick }) {
4
+ return (_jsxs("button", { onClick: onClick, className: "mb-4 inline-flex items-center gap-1 text-sm font-medium text-gray-600 transition-colors hover:text-blue-600 dark:text-gray-300 dark:hover:text-blue-400", children: [_jsx(ChevronLeftIcon, { className: "h-4 w-4" }), _jsx("span", { children: label })] }));
5
+ }
6
+ //# sourceMappingURL=BackLink.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BackLink.js","sourceRoot":"","sources":["../../../src/components/navigation/BackLink.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAO5D,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,EAAE,KAAK,EAAE,OAAO,EAAiB;IAChE,OAAO,CACL,kBACE,OAAO,EAAE,OAAO,EAChB,SAAS,EAAC,yJAAyJ,aAEnK,KAAC,eAAe,IAAC,SAAS,EAAC,SAAS,GAAG,EACvC,yBAAO,KAAK,GAAQ,IACb,CACV,CAAC;AACJ,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { PageResponse } from '@sudobility/testomniac_types';
2
+ interface PagesListViewProps {
3
+ pages: PageResponse[];
4
+ envId: string;
5
+ entitySlug: string;
6
+ runId?: string;
7
+ screenshotsByPageId?: Map<number, string>;
8
+ apiUrl?: string;
9
+ }
10
+ export declare function PagesListView({ pages, envId, entitySlug, runId, screenshotsByPageId, apiUrl, }: PagesListViewProps): import("react").JSX.Element;
11
+ export {};
12
+ //# sourceMappingURL=PagesListView.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PagesListView.d.ts","sourceRoot":"","sources":["../../../src/components/pages/PagesListView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAIjE,UAAU,kBAAkB;IAC1B,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,mBAAmB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,aAAa,CAAC,EAC5B,KAAK,EACL,KAAK,EACL,UAAU,EACV,KAAK,EACL,mBAAmB,EACnB,MAAM,GACP,EAAE,kBAAkB,+BAgGpB"}
@@ -0,0 +1,19 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { buildArtifactUrl } from '@sudobility/testomniac_client';
3
+ import { useLocalizedNavigate } from '../../hooks/useLocalizedNavigate';
4
+ export function PagesListView({ pages, envId, entitySlug, runId, screenshotsByPageId, apiUrl, }) {
5
+ const { navigate } = useLocalizedNavigate();
6
+ const basePath = runId
7
+ ? `/dashboard/${entitySlug}/environments/${envId}/runs/${runId}/pages`
8
+ : `/dashboard/${entitySlug}/environments/${envId}/pages`;
9
+ const sorted = [...pages].sort((a, b) => a.relativePath.localeCompare(b.relativePath));
10
+ if (sorted.length === 0) {
11
+ return (_jsx("div", { className: "py-8 text-center text-gray-500 dark:text-gray-400", children: "No pages discovered." }));
12
+ }
13
+ return (_jsx("div", { className: "overflow-x-auto", children: _jsxs("table", { className: "w-full text-sm", children: [_jsx("thead", { children: _jsxs("tr", { className: "border-b border-gray-200 dark:border-gray-700", children: [_jsx("th", { className: "px-3 py-2 text-left text-xs font-medium uppercase tracking-wider text-gray-500 dark:text-gray-400 w-16", children: "Preview" }), _jsx("th", { className: "px-3 py-2 text-left text-xs font-medium uppercase tracking-wider text-gray-500 dark:text-gray-400", children: "Path" }), _jsx("th", { className: "px-3 py-2 text-left text-xs font-medium uppercase tracking-wider text-gray-500 dark:text-gray-400", children: "Route Key" }), _jsx("th", { className: "px-3 py-2 text-left text-xs font-medium uppercase tracking-wider text-gray-500 dark:text-gray-400", children: "Status" })] }) }), _jsx("tbody", { children: sorted.map(page => {
14
+ const isExternal = page.relativePath.startsWith('http');
15
+ const screenshotPath = screenshotsByPageId?.get(page.id);
16
+ return (_jsxs("tr", { onClick: () => navigate(`${basePath}/${page.id}`), className: "cursor-pointer border-b border-gray-100 dark:border-gray-800 hover:bg-gray-50 dark:hover:bg-gray-800/50 transition-colors", children: [_jsx("td", { className: "px-3 py-3", children: _jsx("div", { className: "w-12 h-8 rounded overflow-hidden bg-gray-100 dark:bg-gray-800 flex items-center justify-center", children: screenshotPath && apiUrl ? (_jsx("img", { src: buildArtifactUrl(apiUrl, screenshotPath, { thumbnail: true }), alt: "", className: "w-full h-full object-cover object-top", loading: "lazy" })) : (_jsxs("svg", { className: "w-4 h-4 text-gray-300 dark:text-gray-600", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: [_jsx("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2" }), _jsx("path", { d: "M3 15l5-5 4 4 3-3 6 6" })] })) }) }), _jsx("td", { className: "px-3 py-3 text-gray-900 dark:text-gray-100", children: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "truncate max-w-md", children: page.relativePath }), isExternal && (_jsx("span", { className: "shrink-0 rounded bg-gray-100 px-1.5 py-0.5 text-[11px] text-gray-500 dark:bg-gray-800 dark:text-gray-400", children: "external" }))] }) }), _jsx("td", { className: "px-3 py-3 text-gray-600 dark:text-gray-300", children: page.routeKey ?? (_jsx("span", { className: "text-gray-400 dark:text-gray-600", children: "\u2014" })) }), _jsx("td", { className: "px-3 py-3", children: page.requiresLogin && (_jsx("span", { className: "rounded bg-yellow-100 px-1.5 py-0.5 text-xs text-yellow-700 dark:bg-yellow-900/30 dark:text-yellow-300", children: "Login" })) })] }, page.id));
17
+ }) })] }) }));
18
+ }
19
+ //# sourceMappingURL=PagesListView.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PagesListView.js","sourceRoot":"","sources":["../../../src/components/pages/PagesListView.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { PageResponse, TestInteractionResponse } from '@sudobility/testomniac_types';
2
+ import '@xyflow/react/dist/style.css';
3
+ interface PagesMapViewProps {
4
+ pages: PageResponse[];
5
+ testInteractions: TestInteractionResponse[];
6
+ envId: string;
7
+ entitySlug: string;
8
+ runId?: string;
9
+ /** Map of pageId → screenshot artifact path (from page states) */
10
+ screenshotsByPageId?: Map<number, string>;
11
+ apiUrl?: string;
12
+ }
13
+ export declare function PagesMapView({ pages, testInteractions, envId, entitySlug, runId, screenshotsByPageId, apiUrl, }: PagesMapViewProps): import("react").JSX.Element;
14
+ export {};
15
+ //# sourceMappingURL=PagesMapView.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PagesMapView.d.ts","sourceRoot":"","sources":["../../../src/components/pages/PagesMapView.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAkB1F,OAAO,8BAA8B,CAAC;AA4HtC,UAAU,iBAAiB;IACzB,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,gBAAgB,EAAE,uBAAuB,EAAE,CAAC;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kEAAkE;IAClE,mBAAmB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,YAAY,CAAC,EAC3B,KAAK,EACL,gBAAgB,EAChB,KAAK,EACL,UAAU,EACV,KAAK,EACL,mBAAmB,EACnB,MAAM,GACP,EAAE,iBAAiB,+BAkOnB"}