@bugbug-io/cli 13.39.2 → 14.0.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/{NavigatorApp-6ZB6F4RF.js → NavigatorApp-3SRWEK5J.js} +1341 -445
- package/dist/{app-L5OYLEKP.js → app-UMUDDKR3.js} +3 -3
- package/dist/{chunk-GNCJ7Y4W.js → chunk-4IJVD32G.js} +146 -985
- package/dist/index.js +65 -78
- package/dist/{chunk-UZVYEMEZ.js → render-U36YSDSA.js} +3 -2
- package/package.json +2 -2
- package/dist/render-RAJK5JCO.js +0 -8
|
@@ -1,28 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
|
-
BaseSuiteRunDetails,
|
|
3
|
-
BaseTestRunDetails,
|
|
4
|
-
DEFAULT_RESERVED_TERMINAL_ROWS,
|
|
5
|
-
EscProvider,
|
|
6
|
-
MenuList,
|
|
7
|
-
ROUTES,
|
|
8
|
-
SelectableOption,
|
|
9
|
-
SelectionPrefix,
|
|
10
|
-
ShortcutProvider,
|
|
11
|
-
Status,
|
|
12
|
-
ViewLayout,
|
|
13
|
-
VirtualizedList,
|
|
14
2
|
analytics,
|
|
15
3
|
defaultJunitReportPath,
|
|
16
4
|
detectFormat,
|
|
17
5
|
exportProject,
|
|
18
6
|
exportTest,
|
|
19
7
|
formatCwd,
|
|
20
|
-
formatDuration,
|
|
21
8
|
formatErrorMessage,
|
|
9
|
+
formatFinalResults,
|
|
22
10
|
formatRunStatus,
|
|
23
11
|
getCliConfig,
|
|
24
12
|
getIdentity,
|
|
25
13
|
getProjectById,
|
|
14
|
+
getRunErrorMessage,
|
|
26
15
|
getSuite,
|
|
27
16
|
getSuiteDetails,
|
|
28
17
|
getSuiteRunDetails,
|
|
@@ -38,6 +27,8 @@ import {
|
|
|
38
27
|
initProject,
|
|
39
28
|
isAuthenticationError,
|
|
40
29
|
isAuthorizationError,
|
|
30
|
+
isCompletedStatus,
|
|
31
|
+
isRunningStatus,
|
|
41
32
|
listProfiles,
|
|
42
33
|
listProjects,
|
|
43
34
|
listSuiteRuns,
|
|
@@ -52,18 +43,16 @@ import {
|
|
|
52
43
|
runTest,
|
|
53
44
|
switchProject,
|
|
54
45
|
updateSdkConfig,
|
|
55
|
-
useEscHandler,
|
|
56
|
-
useShortcutBlocker,
|
|
57
|
-
useShortcutHandler,
|
|
58
|
-
useTheme,
|
|
59
46
|
userCwd,
|
|
47
|
+
waitForSuiteRun,
|
|
48
|
+
waitForTestRun,
|
|
60
49
|
writeReportXml
|
|
61
|
-
} from "./chunk-
|
|
50
|
+
} from "./chunk-4IJVD32G.js";
|
|
62
51
|
import "./chunk-BSHFIPEX.js";
|
|
63
52
|
import "./chunk-PR4QN5HX.js";
|
|
64
53
|
|
|
65
54
|
// src/app/NavigatorApp.tsx
|
|
66
|
-
import { useState as
|
|
55
|
+
import { useState as useState21 } from "react";
|
|
67
56
|
import { RouterProvider } from "react-router";
|
|
68
57
|
|
|
69
58
|
// src/app/contexts/navigatorSession/NavigatorSessionContext.tsx
|
|
@@ -131,6 +120,14 @@ var NavigatorSessionProvider = ({ children }) => {
|
|
|
131
120
|
setAuthState({});
|
|
132
121
|
setAuthError(null);
|
|
133
122
|
}, []);
|
|
123
|
+
const adoptTokenProject = useCallback((projectId) => {
|
|
124
|
+
const trimmedProjectId = projectId.trim();
|
|
125
|
+
if (!trimmedProjectId) return;
|
|
126
|
+
updateSdkConfig({ projectId: trimmedProjectId });
|
|
127
|
+
setAuthState(
|
|
128
|
+
(current) => current.projectId ? current : { ...current, projectId: trimmedProjectId }
|
|
129
|
+
);
|
|
130
|
+
}, []);
|
|
134
131
|
const setSessionProject = useCallback((projectId) => {
|
|
135
132
|
try {
|
|
136
133
|
const trimmedProjectId = projectId.trim();
|
|
@@ -147,7 +144,15 @@ var NavigatorSessionProvider = ({ children }) => {
|
|
|
147
144
|
return /* @__PURE__ */ jsx(
|
|
148
145
|
NavigatorSessionContext.Provider,
|
|
149
146
|
{
|
|
150
|
-
value: {
|
|
147
|
+
value: {
|
|
148
|
+
auth,
|
|
149
|
+
config,
|
|
150
|
+
authError,
|
|
151
|
+
completeSession,
|
|
152
|
+
clearSession,
|
|
153
|
+
setSessionProject,
|
|
154
|
+
adoptTokenProject
|
|
155
|
+
},
|
|
151
156
|
children
|
|
152
157
|
}
|
|
153
158
|
);
|
|
@@ -164,7 +169,7 @@ var useNavigatorSession = () => {
|
|
|
164
169
|
import { createMemoryRouter, createRoutesFromElements, Route } from "react-router";
|
|
165
170
|
|
|
166
171
|
// src/app/Navigator.tsx
|
|
167
|
-
import { Box as Box4, useApp, useInput } from "ink";
|
|
172
|
+
import { Box as Box4, useApp, useInput as useInput3 } from "ink";
|
|
168
173
|
import { useState as useState4 } from "react";
|
|
169
174
|
import { Outlet, useLocation as useLocation3, useNavigate as useNavigate2 } from "react-router";
|
|
170
175
|
|
|
@@ -216,15 +221,21 @@ var useConnectionStatus = (enabled) => {
|
|
|
216
221
|
import { Fragment, jsx as jsx2 } from "react/jsx-runtime";
|
|
217
222
|
var INIT_ROUTE = "/init";
|
|
218
223
|
var AuthGate = ({ children }) => {
|
|
219
|
-
const { auth } = useNavigatorSession();
|
|
224
|
+
const { auth, adoptTokenProject } = useNavigatorSession();
|
|
220
225
|
const location = useLocation();
|
|
221
226
|
const navigate = useNavigate();
|
|
222
227
|
const onInitRoute = location.pathname === INIT_ROUTE;
|
|
223
|
-
const hasConfiguredAuth = auth.
|
|
228
|
+
const hasConfiguredAuth = Boolean(auth.token);
|
|
224
229
|
const connectionStatus = useConnectionStatus(hasConfiguredAuth);
|
|
230
|
+
const identity = connectionStatus.identity;
|
|
231
|
+
const tokenProjectId = identity?.tokenType === "project" ? identity.projectId : null;
|
|
232
|
+
const projectId = auth.projectId ?? tokenProjectId;
|
|
225
233
|
const authCheckPending = hasConfiguredAuth && connectionStatus.state === "checking";
|
|
226
234
|
const authRejected = hasConfiguredAuth && connectionStatus.state === "unauthenticated";
|
|
227
|
-
const authenticated = hasConfiguredAuth && !authRejected;
|
|
235
|
+
const authenticated = hasConfiguredAuth && !authRejected && Boolean(projectId);
|
|
236
|
+
useEffect2(() => {
|
|
237
|
+
if (tokenProjectId && !auth.projectId) adoptTokenProject(tokenProjectId);
|
|
238
|
+
}, [adoptTokenProject, auth.projectId, tokenProjectId]);
|
|
228
239
|
useEffect2(() => {
|
|
229
240
|
if (!authCheckPending && !authenticated && !onInitRoute) {
|
|
230
241
|
navigate(INIT_ROUTE, {
|
|
@@ -246,6 +257,90 @@ var AuthGate = ({ children }) => {
|
|
|
246
257
|
// src/app/components/Header/Header.tsx
|
|
247
258
|
import { Box, Text } from "ink";
|
|
248
259
|
|
|
260
|
+
// src/features/tui/theme.ts
|
|
261
|
+
var colors = {
|
|
262
|
+
brand: "#4c2b8b",
|
|
263
|
+
primary: "#521ec9",
|
|
264
|
+
primarySoft: "#8466CA",
|
|
265
|
+
accent: "#ffcd1c",
|
|
266
|
+
accentSoft: "#FFF8EA",
|
|
267
|
+
primaryActive: "#6029df",
|
|
268
|
+
primaryInactive: "#a489e2",
|
|
269
|
+
common: {
|
|
270
|
+
transparent: "transparent",
|
|
271
|
+
white: "#ffffff",
|
|
272
|
+
black: "#000000",
|
|
273
|
+
muted: "#f4f3fb"
|
|
274
|
+
},
|
|
275
|
+
background: {
|
|
276
|
+
primary: "#E8E9FF",
|
|
277
|
+
primary97: "#F4F3FB",
|
|
278
|
+
primary99: "#F9F9FF",
|
|
279
|
+
accent: "#FFF8EA",
|
|
280
|
+
surface: "#FFFFFF",
|
|
281
|
+
success: "#D1FBE2",
|
|
282
|
+
failure: "#FFF0F0",
|
|
283
|
+
neutral: "#FAFAFA",
|
|
284
|
+
highlight: "#F4F3FB",
|
|
285
|
+
highlightLight: "#F9F9FF"
|
|
286
|
+
},
|
|
287
|
+
text: {
|
|
288
|
+
normal: "#2b2b2b",
|
|
289
|
+
secondary: "#666666",
|
|
290
|
+
subtle: "#7A7F86",
|
|
291
|
+
lighter: "#8B8B8B",
|
|
292
|
+
secondaryAllCaps: "#A2A1A1",
|
|
293
|
+
emptyState: "#999999"
|
|
294
|
+
},
|
|
295
|
+
border: {
|
|
296
|
+
normal: "#2B2B2B",
|
|
297
|
+
dark: "#AAAAAA",
|
|
298
|
+
important: "#CCC9C9",
|
|
299
|
+
medium: "#E5E5E5",
|
|
300
|
+
semi: "#EBEBEB",
|
|
301
|
+
light: "#EFEFEF",
|
|
302
|
+
superLight: "#F1F1F3"
|
|
303
|
+
},
|
|
304
|
+
neutrals: {
|
|
305
|
+
"40": "#666666",
|
|
306
|
+
"80": "#CCCBCB",
|
|
307
|
+
"92": "#EAEAEA",
|
|
308
|
+
"94": "#EFEFEF",
|
|
309
|
+
"96": "#F5F5F5",
|
|
310
|
+
"97": "#F7F7F7"
|
|
311
|
+
},
|
|
312
|
+
status: {
|
|
313
|
+
success: "#4dbf8b",
|
|
314
|
+
success90: "#D1FBE2",
|
|
315
|
+
failure: "#e85b5b",
|
|
316
|
+
stopped: "#898989",
|
|
317
|
+
info: "blue",
|
|
318
|
+
debugging: "#ffcd1c",
|
|
319
|
+
warning: "#FFB100",
|
|
320
|
+
initialized: "#999999",
|
|
321
|
+
recording: "#EF2E51",
|
|
322
|
+
paused: "#ffcd1c",
|
|
323
|
+
skipped: "#8A8A8A"
|
|
324
|
+
},
|
|
325
|
+
code: {
|
|
326
|
+
blue: "#82aaff",
|
|
327
|
+
violet: "#c792ea",
|
|
328
|
+
yellow: "#d4c612",
|
|
329
|
+
red: "#ff5370",
|
|
330
|
+
ruby: "#f17c83"
|
|
331
|
+
},
|
|
332
|
+
block: {
|
|
333
|
+
if: {
|
|
334
|
+
background: "#f2f8fc",
|
|
335
|
+
marker: "#cfeeff"
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
};
|
|
339
|
+
var theme = {
|
|
340
|
+
colors
|
|
341
|
+
};
|
|
342
|
+
var useTheme = () => ({ theme });
|
|
343
|
+
|
|
249
344
|
// src/app/hooks/useFeatureQuery.ts
|
|
250
345
|
import { useCallback as useCallback2, useEffect as useEffect3, useState as useState3 } from "react";
|
|
251
346
|
var useFeatureQuery = (fn, deps) => {
|
|
@@ -326,14 +421,14 @@ var STATUS_COLOR = {
|
|
|
326
421
|
// src/app/components/Header/Header.tsx
|
|
327
422
|
import { jsx as jsx3, jsxs } from "react/jsx-runtime";
|
|
328
423
|
var Header = ({ authenticated }) => {
|
|
329
|
-
const { theme } = useTheme();
|
|
424
|
+
const { theme: theme2 } = useTheme();
|
|
330
425
|
const status = useConnectionStatus(authenticated);
|
|
331
426
|
const project = useCurrentProject(authenticated);
|
|
332
427
|
const identity = authenticated ? status.identity : void 0;
|
|
333
428
|
const state = authenticated ? status.state : "unauthenticated";
|
|
334
429
|
const showDetail = authenticated && (status.state === "error" || status.state === "unauthenticated") && !!status.message;
|
|
335
430
|
return /* @__PURE__ */ jsxs(Box, { marginBottom: 1, children: [
|
|
336
|
-
/* @__PURE__ */ jsx3(Box, { marginRight: 1, children: /* @__PURE__ */ jsx3(Text, { color:
|
|
431
|
+
/* @__PURE__ */ jsx3(Box, { marginRight: 1, children: /* @__PURE__ */ jsx3(Text, { color: theme2.colors.brand, children: BUGBUG_LOGO_ASCII }) }),
|
|
337
432
|
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
338
433
|
/* @__PURE__ */ jsxs(Text, { children: [
|
|
339
434
|
/* @__PURE__ */ jsx3(Text, { bold: true, children: "BugBug" }),
|
|
@@ -489,15 +584,152 @@ var ShortcutsGrid = () => /* @__PURE__ */ jsxs2(Box3, { marginTop: 1, borderStyl
|
|
|
489
584
|
/* @__PURE__ */ jsx5(ShortcutColumn, { title: "Actions", items: ACTION_SHORTCUTS })
|
|
490
585
|
] });
|
|
491
586
|
|
|
587
|
+
// src/features/tui/EscController.tsx
|
|
588
|
+
import { useInput } from "ink";
|
|
589
|
+
import { createContext as createContext2, useContext as useContext2, useEffect as useEffect4, useRef } from "react";
|
|
590
|
+
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
591
|
+
var EscContext = createContext2(null);
|
|
592
|
+
var EscProvider = ({
|
|
593
|
+
onUnhandled,
|
|
594
|
+
canGoBack = true,
|
|
595
|
+
children
|
|
596
|
+
}) => {
|
|
597
|
+
const handlersRef = useRef([]);
|
|
598
|
+
const register = (handler) => {
|
|
599
|
+
handlersRef.current.push(handler);
|
|
600
|
+
return () => {
|
|
601
|
+
handlersRef.current = handlersRef.current.filter((h) => h !== handler);
|
|
602
|
+
};
|
|
603
|
+
};
|
|
604
|
+
useInput((_input, key) => {
|
|
605
|
+
if (!key.escape) return;
|
|
606
|
+
for (let i = handlersRef.current.length - 1; i >= 0; i -= 1) {
|
|
607
|
+
if (handlersRef.current[i]()) return;
|
|
608
|
+
}
|
|
609
|
+
onUnhandled();
|
|
610
|
+
});
|
|
611
|
+
return /* @__PURE__ */ jsx6(EscContext.Provider, { value: { register, canGoBack }, children });
|
|
612
|
+
};
|
|
613
|
+
var useEscHandler = (handler) => {
|
|
614
|
+
const registry = useContext2(EscContext);
|
|
615
|
+
const handlerRef = useRef(handler);
|
|
616
|
+
handlerRef.current = handler;
|
|
617
|
+
useEffect4(() => {
|
|
618
|
+
if (!registry) return void 0;
|
|
619
|
+
return registry.register(() => handlerRef.current());
|
|
620
|
+
}, [registry]);
|
|
621
|
+
};
|
|
622
|
+
var useCanGoBack = () => {
|
|
623
|
+
const registry = useContext2(EscContext);
|
|
624
|
+
return registry?.canGoBack ?? false;
|
|
625
|
+
};
|
|
626
|
+
|
|
627
|
+
// src/features/tui/ShortcutController.tsx
|
|
628
|
+
import { useInput as useInput2 } from "ink";
|
|
629
|
+
import { createContext as createContext3, useContext as useContext3, useEffect as useEffect5, useRef as useRef2 } from "react";
|
|
630
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
631
|
+
var ShortcutContext = createContext3(null);
|
|
632
|
+
var ShortcutProvider = ({ children }) => {
|
|
633
|
+
const entriesRef = useRef2([]);
|
|
634
|
+
const blockerCountRef = useRef2(0);
|
|
635
|
+
const nextOrderRef = useRef2(0);
|
|
636
|
+
const register = (handler, options = {}) => {
|
|
637
|
+
const entry = {
|
|
638
|
+
handler,
|
|
639
|
+
priority: options.priority ?? 0,
|
|
640
|
+
order: nextOrderRef.current
|
|
641
|
+
};
|
|
642
|
+
nextOrderRef.current += 1;
|
|
643
|
+
entriesRef.current.push(entry);
|
|
644
|
+
return () => {
|
|
645
|
+
entriesRef.current = entriesRef.current.filter((current) => current !== entry);
|
|
646
|
+
};
|
|
647
|
+
};
|
|
648
|
+
const block = () => {
|
|
649
|
+
blockerCountRef.current += 1;
|
|
650
|
+
return () => {
|
|
651
|
+
blockerCountRef.current = Math.max(0, blockerCountRef.current - 1);
|
|
652
|
+
};
|
|
653
|
+
};
|
|
654
|
+
useInput2((input, key) => {
|
|
655
|
+
if (blockerCountRef.current > 0) return;
|
|
656
|
+
const entries = entriesRef.current.toSorted((a, b) => {
|
|
657
|
+
if (a.priority !== b.priority) return b.priority - a.priority;
|
|
658
|
+
return b.order - a.order;
|
|
659
|
+
});
|
|
660
|
+
for (const entry of entries) {
|
|
661
|
+
if (entry.handler({ input, key })) return;
|
|
662
|
+
}
|
|
663
|
+
});
|
|
664
|
+
return /* @__PURE__ */ jsx7(ShortcutContext.Provider, { value: { register, block }, children });
|
|
665
|
+
};
|
|
666
|
+
var useShortcutHandler = (handler, options = {}) => {
|
|
667
|
+
const registry = useContext3(ShortcutContext);
|
|
668
|
+
const handlerRef = useRef2(handler);
|
|
669
|
+
const priorityRef = useRef2(options.priority);
|
|
670
|
+
handlerRef.current = handler;
|
|
671
|
+
priorityRef.current = options.priority;
|
|
672
|
+
useEffect5(() => {
|
|
673
|
+
if (!registry) return void 0;
|
|
674
|
+
return registry.register((event) => handlerRef.current(event), {
|
|
675
|
+
priority: priorityRef.current
|
|
676
|
+
});
|
|
677
|
+
}, [registry]);
|
|
678
|
+
};
|
|
679
|
+
var useShortcutBlocker = (enabled = true) => {
|
|
680
|
+
const registry = useContext3(ShortcutContext);
|
|
681
|
+
useEffect5(() => {
|
|
682
|
+
if (!registry || !enabled) return void 0;
|
|
683
|
+
return registry.block();
|
|
684
|
+
}, [registry, enabled]);
|
|
685
|
+
};
|
|
686
|
+
|
|
492
687
|
// src/features/tui/ShortcutController.constants.ts
|
|
493
688
|
var GLOBAL_SHORTCUT_PRIORITY = -100;
|
|
494
689
|
var HELP_SHORTCUT_PRIORITY = 100;
|
|
495
690
|
|
|
691
|
+
// src/app/routes.ts
|
|
692
|
+
var ROUTES = {
|
|
693
|
+
root: () => "/",
|
|
694
|
+
view: (viewKey) => `/${viewKey}`,
|
|
695
|
+
action: (viewKey, actionKey) => `/${viewKey}/${actionKey}`,
|
|
696
|
+
tests: {
|
|
697
|
+
list: () => "/tests/list",
|
|
698
|
+
details: (testId) => `/tests/${testId}`,
|
|
699
|
+
run: (testId) => `/tests/${testId}/run`,
|
|
700
|
+
lastRun: (testId) => `/tests/${testId}/lastRun`,
|
|
701
|
+
export: (testId) => `/tests/${testId}/export`,
|
|
702
|
+
open: (testId) => `/tests/${testId}/open`
|
|
703
|
+
},
|
|
704
|
+
testRuns: {
|
|
705
|
+
root: () => "/testruns",
|
|
706
|
+
list: () => "/testruns/list",
|
|
707
|
+
details: (runId) => `/testruns/${runId}`,
|
|
708
|
+
debugArtifacts: (runId) => `/testruns/${runId}/debugArtifacts`,
|
|
709
|
+
junitReport: (runId) => `/testruns/${runId}/junitReport`,
|
|
710
|
+
open: (runId) => `/testruns/${runId}/open`
|
|
711
|
+
},
|
|
712
|
+
suites: {
|
|
713
|
+
list: () => "/suites/list",
|
|
714
|
+
details: (suiteId) => `/suites/${suiteId}`,
|
|
715
|
+
run: (suiteId) => `/suites/${suiteId}/run`,
|
|
716
|
+
lastRun: (suiteId) => `/suites/${suiteId}/lastRun`,
|
|
717
|
+
open: (suiteId) => `/suites/${suiteId}/open`
|
|
718
|
+
},
|
|
719
|
+
suiteRuns: {
|
|
720
|
+
root: () => "/suiteruns",
|
|
721
|
+
list: () => "/suiteruns/list",
|
|
722
|
+
details: (runId) => `/suiteruns/${runId}`,
|
|
723
|
+
showTestRuns: (runId) => `/suiteruns/${runId}/showTestRuns`,
|
|
724
|
+
open: (runId) => `/suiteruns/${runId}/open`
|
|
725
|
+
}
|
|
726
|
+
};
|
|
727
|
+
|
|
496
728
|
// src/app/Navigator.tsx
|
|
497
|
-
import { jsx as
|
|
729
|
+
import { jsx as jsx8, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
498
730
|
var Navigator = () => {
|
|
499
731
|
const [shortcutsVisible, setShortcutsVisible] = useState4(false);
|
|
500
|
-
return /* @__PURE__ */
|
|
732
|
+
return /* @__PURE__ */ jsx8(ShortcutProvider, { children: /* @__PURE__ */ jsx8(
|
|
501
733
|
NavigatorShell,
|
|
502
734
|
{
|
|
503
735
|
shortcutsVisible,
|
|
@@ -513,7 +745,7 @@ var NavigatorShell = ({
|
|
|
513
745
|
const navigate = useNavigate2();
|
|
514
746
|
const location = useLocation3();
|
|
515
747
|
const atRoot = location.pathname === ROUTES.root();
|
|
516
|
-
|
|
748
|
+
useInput3((input, key) => {
|
|
517
749
|
if (key.ctrl && input === "c") {
|
|
518
750
|
exit();
|
|
519
751
|
return;
|
|
@@ -546,7 +778,7 @@ var NavigatorShell = ({
|
|
|
546
778
|
},
|
|
547
779
|
{ priority: GLOBAL_SHORTCUT_PRIORITY }
|
|
548
780
|
);
|
|
549
|
-
return /* @__PURE__ */
|
|
781
|
+
return /* @__PURE__ */ jsx8(Box4, { flexDirection: "column", padding: 1, children: /* @__PURE__ */ jsx8(AuthGate, { children: (authenticated) => /* @__PURE__ */ jsxs3(
|
|
550
782
|
EscProvider,
|
|
551
783
|
{
|
|
552
784
|
canGoBack: !atRoot,
|
|
@@ -554,10 +786,10 @@ var NavigatorShell = ({
|
|
|
554
786
|
if (!atRoot) navigate(-1);
|
|
555
787
|
},
|
|
556
788
|
children: [
|
|
557
|
-
/* @__PURE__ */
|
|
558
|
-
authenticated && /* @__PURE__ */
|
|
559
|
-
/* @__PURE__ */
|
|
560
|
-
shortcutsVisible && /* @__PURE__ */
|
|
789
|
+
/* @__PURE__ */ jsx8(Header, { authenticated }),
|
|
790
|
+
authenticated && /* @__PURE__ */ jsx8(Breadcrumb, {}),
|
|
791
|
+
/* @__PURE__ */ jsx8(Outlet, {}),
|
|
792
|
+
shortcutsVisible && /* @__PURE__ */ jsx8(ShortcutsGrid, {})
|
|
561
793
|
]
|
|
562
794
|
}
|
|
563
795
|
) }) });
|
|
@@ -566,12 +798,115 @@ var NavigatorShell = ({
|
|
|
566
798
|
// src/app/views/logout/Logout.tsx
|
|
567
799
|
import { StatusMessage } from "@inkjs/ui";
|
|
568
800
|
import { useApp as useApp2 } from "ink";
|
|
569
|
-
import { useEffect as
|
|
570
|
-
|
|
801
|
+
import { useEffect as useEffect7, useState as useState6 } from "react";
|
|
802
|
+
|
|
803
|
+
// src/features/tui/layouts/ViewLayout/ViewLayout.tsx
|
|
804
|
+
import { Box as Box5, Text as Text4, useInput as useInput4 } from "ink";
|
|
805
|
+
import { useEffect as useEffect6, useState as useState5 } from "react";
|
|
806
|
+
|
|
807
|
+
// src/features/tui/layouts/ViewLayout/ViewLayout.constants.ts
|
|
808
|
+
var GO_BACK = "Esc to go back";
|
|
809
|
+
var CLOSE = "q to close";
|
|
810
|
+
var NAVIGATION = "\u2191/\u2193 to navigate";
|
|
811
|
+
var SELECT = "Enter to select";
|
|
812
|
+
var SEARCH = "/ search";
|
|
813
|
+
var HELP = "? for shortcuts";
|
|
814
|
+
var VIEW_HINTS = {
|
|
815
|
+
GO_BACK,
|
|
816
|
+
CLOSE,
|
|
817
|
+
SELECT,
|
|
818
|
+
SEARCH,
|
|
819
|
+
HELP,
|
|
820
|
+
SEARCH_MODE_DEFAULT: "type to search \xB7 Enter to search \xB7 Esc to clear",
|
|
821
|
+
NAVIGATION_SELECT: `${NAVIGATION} \xB7 ${SELECT}`,
|
|
822
|
+
CONFIRM: "Enter to confirm",
|
|
823
|
+
NAVIGATION_OPEN_SELECT: `${NAVIGATION} \xB7 Enter to open/select`
|
|
824
|
+
};
|
|
825
|
+
var HINT_TEXT = {
|
|
826
|
+
confirm: VIEW_HINTS.CONFIRM,
|
|
827
|
+
navigationOpenSelect: VIEW_HINTS.NAVIGATION_OPEN_SELECT,
|
|
828
|
+
navigationSelect: VIEW_HINTS.NAVIGATION_SELECT
|
|
829
|
+
};
|
|
830
|
+
|
|
831
|
+
// src/features/tui/layouts/ViewLayout/ViewLayout.tsx
|
|
832
|
+
import { jsx as jsx9, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
833
|
+
var ViewLayout = ({
|
|
834
|
+
title,
|
|
835
|
+
hints: hintsOverride,
|
|
836
|
+
hintsHidden = false,
|
|
837
|
+
hintsPosition = "top",
|
|
838
|
+
searchable = false,
|
|
839
|
+
onSearch,
|
|
840
|
+
onSearchModeChange,
|
|
841
|
+
children
|
|
842
|
+
}) => {
|
|
843
|
+
const canGoBack = useCanGoBack();
|
|
844
|
+
const [searchMode, setSearchMode] = useState5(false);
|
|
845
|
+
const [searchText, setSearchText] = useState5("");
|
|
846
|
+
const defaultHints = [VIEW_HINTS.NAVIGATION_SELECT, searchable ? VIEW_HINTS.SEARCH : null];
|
|
847
|
+
const localHints = hintsOverride === "none" ? [] : hintsOverride !== void 0 ? [HINT_TEXT[hintsOverride]] : defaultHints;
|
|
848
|
+
const hintsParts = [
|
|
849
|
+
...hintsHidden ? [] : localHints,
|
|
850
|
+
VIEW_HINTS.HELP,
|
|
851
|
+
canGoBack ? VIEW_HINTS.GO_BACK : VIEW_HINTS.CLOSE
|
|
852
|
+
];
|
|
853
|
+
const hints = hintsHidden ? hintsParts.filter(Boolean).join(" \xB7 ") : searchMode ? VIEW_HINTS.SEARCH_MODE_DEFAULT : hintsParts.filter(Boolean).join(" \xB7 ");
|
|
854
|
+
const showSearch = searchable && (searchMode || searchText);
|
|
855
|
+
const showTopHints = hints && hintsPosition === "top";
|
|
856
|
+
const showBottomHints = hints && hintsPosition === "bottom";
|
|
857
|
+
useEffect6(() => {
|
|
858
|
+
onSearchModeChange?.(searchMode);
|
|
859
|
+
}, [onSearchModeChange, searchMode]);
|
|
860
|
+
useShortcutBlocker(searchMode);
|
|
861
|
+
useEscHandler(() => {
|
|
862
|
+
if (!searchable) return false;
|
|
863
|
+
if (searchMode) {
|
|
864
|
+
setSearchMode(false);
|
|
865
|
+
setSearchText("");
|
|
866
|
+
if (onSearch && searchText) onSearch("");
|
|
867
|
+
return true;
|
|
868
|
+
}
|
|
869
|
+
if (searchText) {
|
|
870
|
+
setSearchText("");
|
|
871
|
+
onSearch?.("");
|
|
872
|
+
return true;
|
|
873
|
+
}
|
|
874
|
+
return false;
|
|
875
|
+
});
|
|
876
|
+
useInput4((input, key) => {
|
|
877
|
+
if (!searchable) return;
|
|
878
|
+
if (searchMode) {
|
|
879
|
+
if (key.return) {
|
|
880
|
+
setSearchMode(false);
|
|
881
|
+
onSearch?.(searchText);
|
|
882
|
+
return;
|
|
883
|
+
}
|
|
884
|
+
if (key.backspace || key.delete) {
|
|
885
|
+
setSearchText((current) => current.slice(0, -1));
|
|
886
|
+
return;
|
|
887
|
+
}
|
|
888
|
+
if (input && !key.ctrl && !key.meta && !key.escape) {
|
|
889
|
+
setSearchText((current) => current + input);
|
|
890
|
+
}
|
|
891
|
+
return;
|
|
892
|
+
}
|
|
893
|
+
if (input === "/") setSearchMode(true);
|
|
894
|
+
});
|
|
895
|
+
return /* @__PURE__ */ jsxs4(Box5, { flexDirection: "column", children: [
|
|
896
|
+
title && /* @__PURE__ */ jsx9(Box5, { marginBottom: 1, children: /* @__PURE__ */ jsx9(Text4, { bold: true, children: title }) }),
|
|
897
|
+
showTopHints && /* @__PURE__ */ jsx9(Box5, { marginBottom: 1, children: /* @__PURE__ */ jsx9(Text4, { dimColor: true, children: hints }) }),
|
|
898
|
+
showSearch && /* @__PURE__ */ jsx9(Box5, { marginBottom: 1, children: /* @__PURE__ */ jsx9(Text4, { children: `Search: ${searchText}${searchMode ? "\u2588" : ""}` }) }),
|
|
899
|
+
/* @__PURE__ */ jsx9(Box5, { flexDirection: "column", children }),
|
|
900
|
+
showBottomHints && /* @__PURE__ */ jsx9(Box5, { marginTop: 1, children: /* @__PURE__ */ jsx9(Text4, { dimColor: true, children: hints }) })
|
|
901
|
+
] });
|
|
902
|
+
};
|
|
903
|
+
|
|
904
|
+
// src/app/views/logout/Logout.tsx
|
|
905
|
+
import { jsx as jsx10 } from "react/jsx-runtime";
|
|
571
906
|
var Logout = () => {
|
|
572
907
|
const { exit } = useApp2();
|
|
573
|
-
const [error, setError] =
|
|
574
|
-
|
|
908
|
+
const [error, setError] = useState6(null);
|
|
909
|
+
useEffect7(() => {
|
|
575
910
|
let cleared;
|
|
576
911
|
try {
|
|
577
912
|
({ cleared } = logout());
|
|
@@ -582,7 +917,7 @@ var Logout = () => {
|
|
|
582
917
|
process.stdout.write(cleared ? "Logged out.\n" : "Already logged out.\n");
|
|
583
918
|
exit();
|
|
584
919
|
}, [exit]);
|
|
585
|
-
return /* @__PURE__ */
|
|
920
|
+
return /* @__PURE__ */ jsx10(ViewLayout, { title: "Logout", hintsHidden: true, children: error && /* @__PURE__ */ jsx10(StatusMessage, { variant: "error", children: `Error: ${error}` }) });
|
|
586
921
|
};
|
|
587
922
|
|
|
588
923
|
// src/app/hooks/useIsUserToken.ts
|
|
@@ -596,8 +931,162 @@ var useIsUserToken = () => {
|
|
|
596
931
|
return auth.isUserToken || query.data === "user";
|
|
597
932
|
};
|
|
598
933
|
|
|
934
|
+
// src/features/tui/components/MenuList/MenuList.tsx
|
|
935
|
+
import { useNavigate as useNavigate3 } from "react-router";
|
|
936
|
+
|
|
937
|
+
// src/features/tui/components/VirtualizedList/VirtualizedList.tsx
|
|
938
|
+
import { Box as Box6, Text as Text5, useInput as useInput5, useStdout } from "ink";
|
|
939
|
+
import { useRef as useRef3, useState as useState7 } from "react";
|
|
940
|
+
|
|
941
|
+
// src/features/tui/components/VirtualizedList/VirtualizedList.constants.ts
|
|
942
|
+
var DEFAULT_RESERVED_TERMINAL_ROWS = 13;
|
|
943
|
+
var MIN_VIEWPORT_ROWS = 3;
|
|
944
|
+
var FALLBACK_TERMINAL_ROWS = 24;
|
|
945
|
+
|
|
946
|
+
// src/features/tui/components/VirtualizedList/VirtualizedList.utils.ts
|
|
947
|
+
var getVirtualizedListRange = ({
|
|
948
|
+
itemCount,
|
|
949
|
+
activeIndex,
|
|
950
|
+
viewportSize,
|
|
951
|
+
previousStart = 0
|
|
952
|
+
}) => {
|
|
953
|
+
const maxStart = Math.max(0, itemCount - viewportSize);
|
|
954
|
+
let start = Math.min(previousStart, maxStart);
|
|
955
|
+
if (activeIndex < start) start = activeIndex;
|
|
956
|
+
else if (activeIndex >= start + viewportSize) start = activeIndex - viewportSize + 1;
|
|
957
|
+
start = Math.max(0, Math.min(start, maxStart));
|
|
958
|
+
const end = Math.min(itemCount, start + viewportSize);
|
|
959
|
+
return {
|
|
960
|
+
start,
|
|
961
|
+
end,
|
|
962
|
+
hiddenAbove: start,
|
|
963
|
+
hiddenBelow: itemCount - end
|
|
964
|
+
};
|
|
965
|
+
};
|
|
966
|
+
|
|
967
|
+
// src/features/tui/components/VirtualizedList/VirtualizedList.tsx
|
|
968
|
+
import { jsx as jsx11, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
969
|
+
var VirtualizedList = ({
|
|
970
|
+
items,
|
|
971
|
+
initialSelectedIndex = 0,
|
|
972
|
+
getKey,
|
|
973
|
+
renderItem,
|
|
974
|
+
onSelect,
|
|
975
|
+
reservedTerminalRows = DEFAULT_RESERVED_TERMINAL_ROWS,
|
|
976
|
+
navigationDisabled = false
|
|
977
|
+
}) => {
|
|
978
|
+
const [internalIndex, setInternalIndex] = useState7(initialSelectedIndex);
|
|
979
|
+
const activeIndex = internalIndex;
|
|
980
|
+
useInput5((_input, key) => {
|
|
981
|
+
if (navigationDisabled) return;
|
|
982
|
+
if (key.upArrow) {
|
|
983
|
+
setInternalIndex((index) => Math.max(0, index - 1));
|
|
984
|
+
} else if (key.downArrow) {
|
|
985
|
+
setInternalIndex((index) => Math.min(Math.max(0, items.length - 1), index + 1));
|
|
986
|
+
} else if (key.return && onSelect) {
|
|
987
|
+
const item = items[activeIndex];
|
|
988
|
+
if (item) onSelect(item, activeIndex);
|
|
989
|
+
}
|
|
990
|
+
});
|
|
991
|
+
const { stdout } = useStdout();
|
|
992
|
+
const terminalRows = stdout?.rows ?? FALLBACK_TERMINAL_ROWS;
|
|
993
|
+
const viewportSize = Math.max(
|
|
994
|
+
MIN_VIEWPORT_ROWS,
|
|
995
|
+
Math.min(items.length, terminalRows - reservedTerminalRows)
|
|
996
|
+
);
|
|
997
|
+
const startRef = useRef3(0);
|
|
998
|
+
const { start, end, hiddenAbove, hiddenBelow } = getVirtualizedListRange({
|
|
999
|
+
itemCount: items.length,
|
|
1000
|
+
activeIndex,
|
|
1001
|
+
viewportSize,
|
|
1002
|
+
previousStart: startRef.current
|
|
1003
|
+
});
|
|
1004
|
+
startRef.current = start;
|
|
1005
|
+
const visibleItems = items.slice(start, end);
|
|
1006
|
+
return /* @__PURE__ */ jsxs5(Box6, { flexDirection: "column", children: [
|
|
1007
|
+
hiddenAbove > 0 && /* @__PURE__ */ jsx11(Text5, { dimColor: true, children: ` \u2191 ${hiddenAbove} more` }, "virtualized-list-hidden-above"),
|
|
1008
|
+
visibleItems.map((item, offset) => {
|
|
1009
|
+
const index = start + offset;
|
|
1010
|
+
return /* @__PURE__ */ jsx11(Box6, { children: renderItem(item, index, index === activeIndex) }, getKey(item, index));
|
|
1011
|
+
}),
|
|
1012
|
+
hiddenBelow > 0 && /* @__PURE__ */ jsx11(Text5, { dimColor: true, children: ` \u2193 ${hiddenBelow} more` }, "virtualized-list-hidden-below")
|
|
1013
|
+
] });
|
|
1014
|
+
};
|
|
1015
|
+
|
|
1016
|
+
// src/features/tui/components/MenuList/MenuListItem.tsx
|
|
1017
|
+
import { Box as Box7, Text as Text8 } from "ink";
|
|
1018
|
+
|
|
1019
|
+
// src/features/tui/components/SelectableOption/SelectableOption.tsx
|
|
1020
|
+
import { Text as Text7 } from "ink";
|
|
1021
|
+
|
|
1022
|
+
// src/features/tui/components/SelectableOption/SelectableOption.utils.ts
|
|
1023
|
+
var SELECTION_PREFIX = "\u25BA ";
|
|
1024
|
+
var SELECTION_PREFIX_EMPTY = " ";
|
|
1025
|
+
var getSelectableColors = (selected, theme2) => ({
|
|
1026
|
+
color: selected ? "white" : void 0,
|
|
1027
|
+
backgroundColor: selected ? theme2.colors.primary : void 0
|
|
1028
|
+
});
|
|
1029
|
+
|
|
1030
|
+
// src/features/tui/components/SelectableOption/SelectionPrefix.tsx
|
|
1031
|
+
import { Text as Text6 } from "ink";
|
|
1032
|
+
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
1033
|
+
var SelectionPrefix = ({ selected }) => {
|
|
1034
|
+
const { theme: theme2 } = useTheme();
|
|
1035
|
+
const { color, backgroundColor } = getSelectableColors(selected, theme2);
|
|
1036
|
+
return /* @__PURE__ */ jsx12(Text6, { color, backgroundColor, children: selected ? SELECTION_PREFIX : SELECTION_PREFIX_EMPTY });
|
|
1037
|
+
};
|
|
1038
|
+
|
|
1039
|
+
// src/features/tui/components/SelectableOption/SelectableOption.tsx
|
|
1040
|
+
import { Fragment as Fragment2, jsx as jsx13, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1041
|
+
var SelectableOption = ({ selected, children }) => {
|
|
1042
|
+
const { theme: theme2 } = useTheme();
|
|
1043
|
+
const { color, backgroundColor } = getSelectableColors(selected, theme2);
|
|
1044
|
+
if (typeof children === "function") {
|
|
1045
|
+
return /* @__PURE__ */ jsx13(Fragment2, { children: children({ selected, color, backgroundColor }) });
|
|
1046
|
+
}
|
|
1047
|
+
return /* @__PURE__ */ jsxs6(Text7, { color, backgroundColor, children: [
|
|
1048
|
+
/* @__PURE__ */ jsx13(SelectionPrefix, { selected }),
|
|
1049
|
+
children
|
|
1050
|
+
] });
|
|
1051
|
+
};
|
|
1052
|
+
|
|
1053
|
+
// src/features/tui/components/MenuList/MenuListItem.tsx
|
|
1054
|
+
import { jsx as jsx14, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1055
|
+
var MenuListItem = ({ item, selected }) => /* @__PURE__ */ jsxs7(Box7, { children: [
|
|
1056
|
+
SelectableOption({ selected, children: item.label }),
|
|
1057
|
+
item.description && selected && /* @__PURE__ */ jsx14(Text8, { dimColor: true, children: ` \u2014 ${item.description}` })
|
|
1058
|
+
] });
|
|
1059
|
+
|
|
1060
|
+
// src/features/tui/components/MenuList/MenuList.tsx
|
|
1061
|
+
import { jsx as jsx15 } from "react/jsx-runtime";
|
|
1062
|
+
var MenuList = ({ options, onSelect }) => {
|
|
1063
|
+
const navigate = useNavigate3();
|
|
1064
|
+
const handleSelectItem = (item) => {
|
|
1065
|
+
if (item.to) {
|
|
1066
|
+
navigate(item.to, { state: item.state });
|
|
1067
|
+
return;
|
|
1068
|
+
}
|
|
1069
|
+
onSelect?.(item);
|
|
1070
|
+
};
|
|
1071
|
+
useShortcutHandler(({ input }) => {
|
|
1072
|
+
const item = options.find((option) => option.shortcut === input);
|
|
1073
|
+
if (!item) return false;
|
|
1074
|
+
handleSelectItem(item);
|
|
1075
|
+
return true;
|
|
1076
|
+
});
|
|
1077
|
+
return /* @__PURE__ */ jsx15(
|
|
1078
|
+
VirtualizedList,
|
|
1079
|
+
{
|
|
1080
|
+
items: options,
|
|
1081
|
+
getKey: (item) => item.key ?? item.to ?? item.label,
|
|
1082
|
+
renderItem: (item, _index, selected) => /* @__PURE__ */ jsx15(MenuListItem, { item, selected }),
|
|
1083
|
+
onSelect: handleSelectItem
|
|
1084
|
+
}
|
|
1085
|
+
);
|
|
1086
|
+
};
|
|
1087
|
+
|
|
599
1088
|
// src/app/views/MainMenu.tsx
|
|
600
|
-
import { jsx as
|
|
1089
|
+
import { jsx as jsx16 } from "react/jsx-runtime";
|
|
601
1090
|
var MainMenu = () => {
|
|
602
1091
|
const isUserToken = useIsUserToken();
|
|
603
1092
|
const canSwitchProject = !hasProjectConfigFile();
|
|
@@ -650,7 +1139,7 @@ var MainMenu = () => {
|
|
|
650
1139
|
}
|
|
651
1140
|
] : []
|
|
652
1141
|
];
|
|
653
|
-
return /* @__PURE__ */
|
|
1142
|
+
return /* @__PURE__ */ jsx16(ViewLayout, { children: /* @__PURE__ */ jsx16(MenuList, { options }) });
|
|
654
1143
|
};
|
|
655
1144
|
|
|
656
1145
|
// src/app/hooks/useProfiles.ts
|
|
@@ -672,11 +1161,11 @@ var getProfileRow = (profile) => ({
|
|
|
672
1161
|
|
|
673
1162
|
// src/features/tui/components/BaseResourceListScreen/BaseResourceListScreen.tsx
|
|
674
1163
|
import { Spinner, StatusMessage as StatusMessage2 } from "@inkjs/ui";
|
|
675
|
-
import { Box as
|
|
676
|
-
import { useState as
|
|
1164
|
+
import { Box as Box10 } from "ink";
|
|
1165
|
+
import { useState as useState8 } from "react";
|
|
677
1166
|
|
|
678
1167
|
// src/features/tui/components/TableList/TableList.tsx
|
|
679
|
-
import { Box as
|
|
1168
|
+
import { Box as Box9, Text as Text10 } from "ink";
|
|
680
1169
|
|
|
681
1170
|
// src/features/tui/components/TableList/TableList.utils.ts
|
|
682
1171
|
var fitCell = (value, width) => {
|
|
@@ -686,21 +1175,21 @@ var fitCell = (value, width) => {
|
|
|
686
1175
|
};
|
|
687
1176
|
|
|
688
1177
|
// src/features/tui/components/TableList/TableListRow.tsx
|
|
689
|
-
import { Box as
|
|
690
|
-
import { jsx as
|
|
1178
|
+
import { Box as Box8, Text as Text9 } from "ink";
|
|
1179
|
+
import { jsx as jsx17, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
691
1180
|
var TableListRow = ({
|
|
692
1181
|
columns,
|
|
693
1182
|
row,
|
|
694
1183
|
selected
|
|
695
|
-
}) => /* @__PURE__ */
|
|
696
|
-
/* @__PURE__ */
|
|
1184
|
+
}) => /* @__PURE__ */ jsx17(SelectableOption, { selected, children: ({ color, backgroundColor }) => /* @__PURE__ */ jsxs8(Box8, { children: [
|
|
1185
|
+
/* @__PURE__ */ jsx17(SelectionPrefix, { selected }),
|
|
697
1186
|
columns.map((column, i) => {
|
|
698
1187
|
const sep = i === 0 ? "" : " ";
|
|
699
1188
|
const cell = row.cells[column.key];
|
|
700
1189
|
if (column.render) {
|
|
701
|
-
return /* @__PURE__ */
|
|
702
|
-
sep ? /* @__PURE__ */
|
|
703
|
-
/* @__PURE__ */
|
|
1190
|
+
return /* @__PURE__ */ jsxs8(Box8, { children: [
|
|
1191
|
+
sep ? /* @__PURE__ */ jsx17(Text9, { backgroundColor, children: sep }) : null,
|
|
1192
|
+
/* @__PURE__ */ jsx17(Box8, { width: column.width, children: column.render(cell, row, {
|
|
704
1193
|
selected,
|
|
705
1194
|
width: column.width,
|
|
706
1195
|
color,
|
|
@@ -708,7 +1197,7 @@ var TableListRow = ({
|
|
|
708
1197
|
}) })
|
|
709
1198
|
] }, column.key);
|
|
710
1199
|
}
|
|
711
|
-
return /* @__PURE__ */
|
|
1200
|
+
return /* @__PURE__ */ jsxs8(Text9, { color, backgroundColor, children: [
|
|
712
1201
|
sep,
|
|
713
1202
|
fitCell(cell, column.width)
|
|
714
1203
|
] }, column.key);
|
|
@@ -716,32 +1205,32 @@ var TableListRow = ({
|
|
|
716
1205
|
] }) });
|
|
717
1206
|
|
|
718
1207
|
// src/features/tui/components/TableList/TableList.tsx
|
|
719
|
-
import { jsx as
|
|
1208
|
+
import { jsx as jsx18, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
720
1209
|
var TableList = ({
|
|
721
1210
|
columns,
|
|
722
1211
|
rows,
|
|
723
1212
|
navigationDisabled = false,
|
|
724
1213
|
onSelect
|
|
725
|
-
}) => /* @__PURE__ */
|
|
726
|
-
/* @__PURE__ */
|
|
1214
|
+
}) => /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", children: [
|
|
1215
|
+
/* @__PURE__ */ jsx18(Box9, { children: /* @__PURE__ */ jsxs9(Text10, { dimColor: true, children: [
|
|
727
1216
|
" ",
|
|
728
1217
|
columns.map((column) => fitCell(column.label, column.width)).join(" ")
|
|
729
1218
|
] }) }),
|
|
730
|
-
/* @__PURE__ */
|
|
1219
|
+
/* @__PURE__ */ jsx18(
|
|
731
1220
|
VirtualizedList,
|
|
732
1221
|
{
|
|
733
1222
|
items: rows,
|
|
734
1223
|
reservedTerminalRows: DEFAULT_RESERVED_TERMINAL_ROWS + 1,
|
|
735
1224
|
navigationDisabled,
|
|
736
1225
|
getKey: (row) => row.key,
|
|
737
|
-
renderItem: (row, _rowIndex, selected) => /* @__PURE__ */
|
|
1226
|
+
renderItem: (row, _rowIndex, selected) => /* @__PURE__ */ jsx18(TableListRow, { columns, row, selected: !navigationDisabled && selected }),
|
|
738
1227
|
onSelect: (row) => onSelect?.(row)
|
|
739
1228
|
}
|
|
740
1229
|
)
|
|
741
1230
|
] });
|
|
742
1231
|
|
|
743
1232
|
// src/features/tui/components/BaseResourceListScreen/BaseResourceListScreen.tsx
|
|
744
|
-
import { jsx as
|
|
1233
|
+
import { jsx as jsx19, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
745
1234
|
var BaseResourceListScreen = ({
|
|
746
1235
|
title,
|
|
747
1236
|
loadingLabel,
|
|
@@ -758,11 +1247,11 @@ var BaseResourceListScreen = ({
|
|
|
758
1247
|
onSelectResource
|
|
759
1248
|
}) => {
|
|
760
1249
|
const rows = resources ?? [];
|
|
761
|
-
const [searchMode, setSearchMode] =
|
|
1250
|
+
const [searchMode, setSearchMode] = useState8(false);
|
|
762
1251
|
const handleSelect = (row) => {
|
|
763
1252
|
if (row.value !== void 0 && onSelectResource) onSelectResource(row.value);
|
|
764
1253
|
};
|
|
765
|
-
return /* @__PURE__ */
|
|
1254
|
+
return /* @__PURE__ */ jsxs10(
|
|
766
1255
|
ViewLayout,
|
|
767
1256
|
{
|
|
768
1257
|
title: query ? `Search: "${query}"` : title,
|
|
@@ -770,10 +1259,10 @@ var BaseResourceListScreen = ({
|
|
|
770
1259
|
onSearch,
|
|
771
1260
|
onSearchModeChange: setSearchMode,
|
|
772
1261
|
children: [
|
|
773
|
-
isLoading && /* @__PURE__ */
|
|
774
|
-
isError && /* @__PURE__ */
|
|
775
|
-
!isLoading && !isError && rows.length === 0 && !query && /* @__PURE__ */
|
|
776
|
-
!isLoading && !isError && (rows.length > 0 || query) && /* @__PURE__ */
|
|
1262
|
+
isLoading && /* @__PURE__ */ jsx19(Box10, { children: /* @__PURE__ */ jsx19(Spinner, { label: loadingLabel }) }),
|
|
1263
|
+
isError && /* @__PURE__ */ jsx19(StatusMessage2, { variant: "error", children: error }),
|
|
1264
|
+
!isLoading && !isError && rows.length === 0 && !query && /* @__PURE__ */ jsx19(StatusMessage2, { variant: "warning", children: emptyMessage }),
|
|
1265
|
+
!isLoading && !isError && (rows.length > 0 || query) && /* @__PURE__ */ jsx19(
|
|
777
1266
|
TableList,
|
|
778
1267
|
{
|
|
779
1268
|
columns,
|
|
@@ -788,10 +1277,10 @@ var BaseResourceListScreen = ({
|
|
|
788
1277
|
};
|
|
789
1278
|
|
|
790
1279
|
// src/app/views/profiles/ProfilesList.tsx
|
|
791
|
-
import { jsx as
|
|
1280
|
+
import { jsx as jsx20 } from "react/jsx-runtime";
|
|
792
1281
|
var ProfilesList = () => {
|
|
793
1282
|
const request = useProfilesList();
|
|
794
|
-
return /* @__PURE__ */
|
|
1283
|
+
return /* @__PURE__ */ jsx20(
|
|
795
1284
|
BaseResourceListScreen,
|
|
796
1285
|
{
|
|
797
1286
|
title: "Profiles",
|
|
@@ -809,27 +1298,27 @@ var ProfilesList = () => {
|
|
|
809
1298
|
|
|
810
1299
|
// src/app/views/profiles/ProfilesMenu.tsx
|
|
811
1300
|
import { Spinner as Spinner2 } from "@inkjs/ui";
|
|
812
|
-
import { useEffect as
|
|
813
|
-
import { useNavigate as
|
|
814
|
-
import { jsx as
|
|
1301
|
+
import { useEffect as useEffect8 } from "react";
|
|
1302
|
+
import { useNavigate as useNavigate4 } from "react-router";
|
|
1303
|
+
import { jsx as jsx21 } from "react/jsx-runtime";
|
|
815
1304
|
var ProfilesMenu = () => {
|
|
816
|
-
const navigate =
|
|
817
|
-
|
|
1305
|
+
const navigate = useNavigate4();
|
|
1306
|
+
useEffect8(() => {
|
|
818
1307
|
navigate("/profiles/list", { replace: true });
|
|
819
1308
|
}, [navigate]);
|
|
820
|
-
return /* @__PURE__ */
|
|
1309
|
+
return /* @__PURE__ */ jsx21(Spinner2, { label: "Loading..." });
|
|
821
1310
|
};
|
|
822
1311
|
|
|
823
1312
|
// src/app/views/project/ProjectExport.tsx
|
|
824
1313
|
import { Spinner as Spinner3, StatusMessage as StatusMessage3 } from "@inkjs/ui";
|
|
825
|
-
import { useEffect as
|
|
1314
|
+
import { useEffect as useEffect9, useState as useState10 } from "react";
|
|
826
1315
|
|
|
827
1316
|
// src/app/hooks/useFeatureMutation.ts
|
|
828
|
-
import { useCallback as useCallback3, useRef, useState as
|
|
1317
|
+
import { useCallback as useCallback3, useRef as useRef4, useState as useState9 } from "react";
|
|
829
1318
|
var useFeatureMutation = (fn) => {
|
|
830
|
-
const fnRef =
|
|
831
|
-
const activeMutationRef =
|
|
832
|
-
const [state, setState] =
|
|
1319
|
+
const fnRef = useRef4(fn);
|
|
1320
|
+
const activeMutationRef = useRef4(0);
|
|
1321
|
+
const [state, setState] = useState9({
|
|
833
1322
|
data: void 0,
|
|
834
1323
|
error: void 0,
|
|
835
1324
|
status: "idle"
|
|
@@ -870,48 +1359,48 @@ var useFeatureMutation = (fn) => {
|
|
|
870
1359
|
};
|
|
871
1360
|
|
|
872
1361
|
// src/features/tui/components/TextInput/TextInput.tsx
|
|
873
|
-
import { Box as
|
|
1362
|
+
import { Box as Box11, Text as Text11 } from "ink";
|
|
874
1363
|
import InkTextInput from "ink-text-input";
|
|
875
|
-
import { jsx as
|
|
1364
|
+
import { jsx as jsx22, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
876
1365
|
var TextInput = (props) => {
|
|
877
1366
|
useShortcutBlocker();
|
|
878
|
-
return /* @__PURE__ */
|
|
879
|
-
/* @__PURE__ */
|
|
880
|
-
/* @__PURE__ */
|
|
1367
|
+
return /* @__PURE__ */ jsxs11(Box11, { children: [
|
|
1368
|
+
/* @__PURE__ */ jsx22(Text11, { color: "cyan", children: "\u203A " }),
|
|
1369
|
+
/* @__PURE__ */ jsx22(InkTextInput, { ...props })
|
|
881
1370
|
] });
|
|
882
1371
|
};
|
|
883
1372
|
|
|
884
1373
|
// src/app/views/project/ProjectExport.tsx
|
|
885
|
-
import { jsx as
|
|
1374
|
+
import { jsx as jsx23, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
886
1375
|
var ProjectExport = () => {
|
|
887
|
-
const [outputValue, setOutputValue] =
|
|
888
|
-
const [output, setOutput] =
|
|
1376
|
+
const [outputValue, setOutputValue] = useState10("");
|
|
1377
|
+
const [output, setOutput] = useState10(null);
|
|
889
1378
|
const [exportProjectMutation, exportProjectResult] = useFeatureMutation(
|
|
890
1379
|
(outputPath) => exportProject(outputPath || void 0)
|
|
891
1380
|
);
|
|
892
|
-
|
|
1381
|
+
useEffect9(() => {
|
|
893
1382
|
if (output !== null) void exportProjectMutation(output);
|
|
894
1383
|
}, [exportProjectMutation, output]);
|
|
895
1384
|
if (output === null) {
|
|
896
|
-
return /* @__PURE__ */
|
|
1385
|
+
return /* @__PURE__ */ jsx23(ViewLayout, { title: "Output file (blank = auto)", hints: "confirm", hintsPosition: "bottom", children: /* @__PURE__ */ jsx23(TextInput, { value: outputValue, onChange: setOutputValue, onSubmit: setOutput }) });
|
|
897
1386
|
}
|
|
898
|
-
return /* @__PURE__ */
|
|
899
|
-
exportProjectResult.isLoading && /* @__PURE__ */
|
|
900
|
-
exportProjectResult.isError && /* @__PURE__ */
|
|
901
|
-
exportProjectResult.data && /* @__PURE__ */
|
|
1387
|
+
return /* @__PURE__ */ jsxs12(ViewLayout, { hintsHidden: true, children: [
|
|
1388
|
+
exportProjectResult.isLoading && /* @__PURE__ */ jsx23(Spinner3, { label: "Exporting project..." }),
|
|
1389
|
+
exportProjectResult.isError && /* @__PURE__ */ jsx23(StatusMessage3, { variant: "error", children: exportProjectResult.error }),
|
|
1390
|
+
exportProjectResult.data && /* @__PURE__ */ jsx23(StatusMessage3, { variant: "success", children: `Exported project to ${exportProjectResult.data.outPath} (${exportProjectResult.data.size} bytes)` })
|
|
902
1391
|
] });
|
|
903
1392
|
};
|
|
904
1393
|
|
|
905
1394
|
// src/app/views/project/ProjectImport.tsx
|
|
906
1395
|
import { Spinner as Spinner4, StatusMessage as StatusMessage4 } from "@inkjs/ui";
|
|
907
|
-
import { useEffect as
|
|
908
|
-
import { useNavigate as
|
|
1396
|
+
import { useEffect as useEffect10, useState as useState12 } from "react";
|
|
1397
|
+
import { useNavigate as useNavigate5 } from "react-router";
|
|
909
1398
|
|
|
910
1399
|
// src/features/tui/components/FilePicker/FilePicker.tsx
|
|
911
1400
|
import { readdirSync } from "fs";
|
|
912
1401
|
import { dirname, join, resolve } from "path";
|
|
913
|
-
import { Box as
|
|
914
|
-
import { useMemo, useState as
|
|
1402
|
+
import { Box as Box12, Text as Text12 } from "ink";
|
|
1403
|
+
import { useMemo, useState as useState11 } from "react";
|
|
915
1404
|
|
|
916
1405
|
// src/utils/filePicker.ts
|
|
917
1406
|
import { extname } from "path";
|
|
@@ -937,7 +1426,7 @@ var toFilePickerItems = (entries, allowedExtensions) => {
|
|
|
937
1426
|
};
|
|
938
1427
|
|
|
939
1428
|
// src/features/tui/components/FilePicker/FilePicker.tsx
|
|
940
|
-
import { jsx as
|
|
1429
|
+
import { jsx as jsx24, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
941
1430
|
var FilePicker = ({
|
|
942
1431
|
label,
|
|
943
1432
|
extensions,
|
|
@@ -945,7 +1434,7 @@ var FilePicker = ({
|
|
|
945
1434
|
onSubmit,
|
|
946
1435
|
onBack
|
|
947
1436
|
}) => {
|
|
948
|
-
const [currentDir, setCurrentDir] =
|
|
1437
|
+
const [currentDir, setCurrentDir] = useState11(() => resolve(userCwd(), initialDir));
|
|
949
1438
|
useEscHandler(() => {
|
|
950
1439
|
onBack();
|
|
951
1440
|
return true;
|
|
@@ -981,8 +1470,8 @@ var FilePicker = ({
|
|
|
981
1470
|
}
|
|
982
1471
|
onSubmit(join(currentDir, selected.name));
|
|
983
1472
|
};
|
|
984
|
-
return /* @__PURE__ */
|
|
985
|
-
/* @__PURE__ */
|
|
1473
|
+
return /* @__PURE__ */ jsx24(Box12, { flexDirection: "column", children: /* @__PURE__ */ jsxs13(ViewLayout, { title: `${label}: ${currentDir}`, hints: "navigationOpenSelect", children: [
|
|
1474
|
+
/* @__PURE__ */ jsx24(
|
|
986
1475
|
MenuList,
|
|
987
1476
|
{
|
|
988
1477
|
options: items.map((item) => ({ label: item.label, value: item })),
|
|
@@ -990,22 +1479,22 @@ var FilePicker = ({
|
|
|
990
1479
|
},
|
|
991
1480
|
currentDir
|
|
992
1481
|
),
|
|
993
|
-
items.length === 0 && /* @__PURE__ */
|
|
994
|
-
error && /* @__PURE__ */
|
|
1482
|
+
items.length === 0 && /* @__PURE__ */ jsx24(Box12, { marginTop: 1, children: /* @__PURE__ */ jsx24(Text12, { dimColor: true, children: "No matching files in this directory." }) }),
|
|
1483
|
+
error && /* @__PURE__ */ jsx24(Box12, { marginTop: 1, children: /* @__PURE__ */ jsx24(Text12, { color: "red", children: error }) })
|
|
995
1484
|
] }) });
|
|
996
1485
|
};
|
|
997
1486
|
|
|
998
1487
|
// src/app/views/project/ProjectImport.tsx
|
|
999
|
-
import { jsx as
|
|
1488
|
+
import { jsx as jsx25, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1000
1489
|
var ProjectImport = () => {
|
|
1001
|
-
const navigate =
|
|
1002
|
-
const [file, setFile] =
|
|
1490
|
+
const navigate = useNavigate5();
|
|
1491
|
+
const [file, setFile] = useState12(null);
|
|
1003
1492
|
const [importProjectMutation, importProjectResult] = useFeatureMutation(importProject);
|
|
1004
|
-
|
|
1493
|
+
useEffect10(() => {
|
|
1005
1494
|
if (file) importProjectMutation(file);
|
|
1006
1495
|
}, [file, importProjectMutation]);
|
|
1007
1496
|
if (!file) {
|
|
1008
|
-
return /* @__PURE__ */
|
|
1497
|
+
return /* @__PURE__ */ jsx25(
|
|
1009
1498
|
FilePicker,
|
|
1010
1499
|
{
|
|
1011
1500
|
label: "Select .zip file",
|
|
@@ -1015,29 +1504,29 @@ var ProjectImport = () => {
|
|
|
1015
1504
|
}
|
|
1016
1505
|
);
|
|
1017
1506
|
}
|
|
1018
|
-
return /* @__PURE__ */
|
|
1019
|
-
importProjectResult.isLoading && /* @__PURE__ */
|
|
1020
|
-
importProjectResult.isError && /* @__PURE__ */
|
|
1021
|
-
importProjectResult.data && /* @__PURE__ */
|
|
1507
|
+
return /* @__PURE__ */ jsxs14(ViewLayout, { hintsHidden: true, children: [
|
|
1508
|
+
importProjectResult.isLoading && /* @__PURE__ */ jsx25(Spinner4, { label: `Importing project from ${file}...` }),
|
|
1509
|
+
importProjectResult.isError && /* @__PURE__ */ jsx25(StatusMessage4, { variant: "error", children: importProjectResult.error }),
|
|
1510
|
+
importProjectResult.data && /* @__PURE__ */ jsx25(StatusMessage4, { variant: "success", children: `Project import started from ${importProjectResult.data.path} (${importProjectResult.data.size} bytes)` })
|
|
1022
1511
|
] });
|
|
1023
1512
|
};
|
|
1024
1513
|
|
|
1025
1514
|
// src/app/views/project/ProjectInit.tsx
|
|
1026
1515
|
import { useApp as useApp3 } from "ink";
|
|
1027
|
-
import { useEffect as
|
|
1028
|
-
import { useLocation as useLocation4, useNavigate as
|
|
1516
|
+
import { useEffect as useEffect11, useState as useState14 } from "react";
|
|
1517
|
+
import { useLocation as useLocation4, useNavigate as useNavigate6 } from "react-router";
|
|
1029
1518
|
|
|
1030
1519
|
// src/app/components/ProjectPicker/ProjectPicker.tsx
|
|
1031
1520
|
import { Spinner as Spinner5, StatusMessage as StatusMessage5 } from "@inkjs/ui";
|
|
1032
|
-
import { jsx as
|
|
1521
|
+
import { jsx as jsx26, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
1033
1522
|
var ProjectPicker = ({ onSelect, currentProjectId }) => {
|
|
1034
1523
|
const projectsQuery = useFeatureQuery(listProjects, []);
|
|
1035
1524
|
const projects = projectsQuery.data ?? [];
|
|
1036
|
-
return /* @__PURE__ */
|
|
1037
|
-
projectsQuery.isLoading && /* @__PURE__ */
|
|
1038
|
-
projectsQuery.isError && /* @__PURE__ */
|
|
1039
|
-
!projectsQuery.isLoading && !projectsQuery.isError && projects.length === 0 && /* @__PURE__ */
|
|
1040
|
-
!projectsQuery.isLoading && !projectsQuery.isError && projects.length > 0 && /* @__PURE__ */
|
|
1525
|
+
return /* @__PURE__ */ jsxs15(ViewLayout, { title: "Choose BugBug project", hints: "navigationSelect", children: [
|
|
1526
|
+
projectsQuery.isLoading && /* @__PURE__ */ jsx26(Spinner5, { label: "Loading projects..." }),
|
|
1527
|
+
projectsQuery.isError && /* @__PURE__ */ jsx26(StatusMessage5, { variant: "error", children: `Error: ${projectsQuery.error ?? "Unknown error"}` }),
|
|
1528
|
+
!projectsQuery.isLoading && !projectsQuery.isError && projects.length === 0 && /* @__PURE__ */ jsx26(StatusMessage5, { variant: "warning", children: "No projects found" }),
|
|
1529
|
+
!projectsQuery.isLoading && !projectsQuery.isError && projects.length > 0 && /* @__PURE__ */ jsx26(
|
|
1041
1530
|
MenuList,
|
|
1042
1531
|
{
|
|
1043
1532
|
options: projects.map((project) => ({
|
|
@@ -1055,15 +1544,15 @@ var ProjectPicker = ({ onSelect, currentProjectId }) => {
|
|
|
1055
1544
|
|
|
1056
1545
|
// src/app/views/project/ProjectInitAuth.tsx
|
|
1057
1546
|
import { StatusMessage as StatusMessage6 } from "@inkjs/ui";
|
|
1058
|
-
import { useState as
|
|
1059
|
-
import { jsx as
|
|
1547
|
+
import { useState as useState13 } from "react";
|
|
1548
|
+
import { jsx as jsx27, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
1060
1549
|
var ProjectInitAuth = ({
|
|
1061
1550
|
onTokenReceive,
|
|
1062
1551
|
onTokenError,
|
|
1063
1552
|
message
|
|
1064
1553
|
}) => {
|
|
1065
|
-
const [method, setMethod] =
|
|
1066
|
-
const [tokenInput, setTokenInput] =
|
|
1554
|
+
const [method, setMethod] = useState13("choose");
|
|
1555
|
+
const [tokenInput, setTokenInput] = useState13("");
|
|
1067
1556
|
const handleLogin = () => {
|
|
1068
1557
|
void (async () => {
|
|
1069
1558
|
try {
|
|
@@ -1089,8 +1578,8 @@ var ProjectInitAuth = ({
|
|
|
1089
1578
|
}
|
|
1090
1579
|
};
|
|
1091
1580
|
if (method === "token") {
|
|
1092
|
-
return /* @__PURE__ */
|
|
1093
|
-
/* @__PURE__ */
|
|
1581
|
+
return /* @__PURE__ */ jsx27(EscProvider, { onUnhandled: () => setMethod("choose"), children: /* @__PURE__ */ jsxs16(ViewLayout, { title: "BugBug project API token", hints: "confirm", hintsPosition: "bottom", children: [
|
|
1582
|
+
/* @__PURE__ */ jsx27(
|
|
1094
1583
|
TextInput,
|
|
1095
1584
|
{
|
|
1096
1585
|
value: tokenInput,
|
|
@@ -1099,11 +1588,11 @@ var ProjectInitAuth = ({
|
|
|
1099
1588
|
mask: "*"
|
|
1100
1589
|
}
|
|
1101
1590
|
),
|
|
1102
|
-
message && /* @__PURE__ */
|
|
1591
|
+
message && /* @__PURE__ */ jsx27(StatusMessage6, { variant: "error", children: `Error: ${message}` })
|
|
1103
1592
|
] }) });
|
|
1104
1593
|
}
|
|
1105
|
-
return /* @__PURE__ */
|
|
1106
|
-
/* @__PURE__ */
|
|
1594
|
+
return /* @__PURE__ */ jsxs16(ViewLayout, { title: "How do you want to authenticate?", hints: "navigationSelect", children: [
|
|
1595
|
+
/* @__PURE__ */ jsx27(
|
|
1107
1596
|
MenuList,
|
|
1108
1597
|
{
|
|
1109
1598
|
options: [
|
|
@@ -1124,27 +1613,27 @@ var ProjectInitAuth = ({
|
|
|
1124
1613
|
}
|
|
1125
1614
|
}
|
|
1126
1615
|
),
|
|
1127
|
-
message && /* @__PURE__ */
|
|
1616
|
+
message && /* @__PURE__ */ jsx27(StatusMessage6, { variant: "error", children: `Error: ${message}` })
|
|
1128
1617
|
] });
|
|
1129
1618
|
};
|
|
1130
1619
|
|
|
1131
1620
|
// src/app/views/project/ProjectInit.tsx
|
|
1132
|
-
import { jsx as
|
|
1621
|
+
import { jsx as jsx28, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
1133
1622
|
var ProjectInit = () => {
|
|
1134
1623
|
const { exit } = useApp3();
|
|
1135
|
-
const navigate =
|
|
1624
|
+
const navigate = useNavigate6();
|
|
1136
1625
|
const location = useLocation4();
|
|
1137
1626
|
const state = location.state;
|
|
1138
1627
|
const redirectUrl = state?.redirectUrl ?? "/";
|
|
1139
1628
|
const onlyThisSession = state?.onlyThisSession ?? false;
|
|
1140
1629
|
const ignoreConfiguredAuth = state?.ignoreConfiguredAuth ?? false;
|
|
1141
1630
|
const { auth, config, authError, completeSession } = useNavigatorSession();
|
|
1142
|
-
const [token, setToken] =
|
|
1631
|
+
const [token, setToken] = useState14(
|
|
1143
1632
|
ignoreConfiguredAuth ? null : auth.token ?? null
|
|
1144
1633
|
);
|
|
1145
|
-
const [usingUserToken, setUsingUserToken] =
|
|
1146
|
-
const [error, setError] =
|
|
1147
|
-
|
|
1634
|
+
const [usingUserToken, setUsingUserToken] = useState14(false);
|
|
1635
|
+
const [error, setError] = useState14(null);
|
|
1636
|
+
useEffect11(() => {
|
|
1148
1637
|
if (auth.kind !== "ready" || ignoreConfiguredAuth) return;
|
|
1149
1638
|
if (onlyThisSession) {
|
|
1150
1639
|
navigate(redirectUrl, { replace: true });
|
|
@@ -1181,8 +1670,8 @@ var ProjectInit = () => {
|
|
|
1181
1670
|
})();
|
|
1182
1671
|
};
|
|
1183
1672
|
const message = error ?? authError;
|
|
1184
|
-
return /* @__PURE__ */
|
|
1185
|
-
!token && /* @__PURE__ */
|
|
1673
|
+
return /* @__PURE__ */ jsxs17(EscProvider, { onUnhandled: exit, children: [
|
|
1674
|
+
!token && /* @__PURE__ */ jsx28(
|
|
1186
1675
|
ProjectInitAuth,
|
|
1187
1676
|
{
|
|
1188
1677
|
onTokenReceive: handleTokenReceive,
|
|
@@ -1190,15 +1679,15 @@ var ProjectInit = () => {
|
|
|
1190
1679
|
message
|
|
1191
1680
|
}
|
|
1192
1681
|
),
|
|
1193
|
-
token && /* @__PURE__ */
|
|
1682
|
+
token && /* @__PURE__ */ jsx28(ProjectPicker, { onSelect: handleProjectSelectAndFinish, currentProjectId: auth.projectId })
|
|
1194
1683
|
] });
|
|
1195
1684
|
};
|
|
1196
1685
|
|
|
1197
1686
|
// src/app/views/project/ProjectMenu.tsx
|
|
1198
|
-
import { jsx as
|
|
1687
|
+
import { jsx as jsx29 } from "react/jsx-runtime";
|
|
1199
1688
|
var ProjectMenu = () => {
|
|
1200
1689
|
const canSwitchProject = !hasProjectConfigFile();
|
|
1201
|
-
return /* @__PURE__ */
|
|
1690
|
+
return /* @__PURE__ */ jsx29(ViewLayout, { children: /* @__PURE__ */ jsx29(
|
|
1202
1691
|
MenuList,
|
|
1203
1692
|
{
|
|
1204
1693
|
options: [
|
|
@@ -1210,21 +1699,21 @@ var ProjectMenu = () => {
|
|
|
1210
1699
|
};
|
|
1211
1700
|
|
|
1212
1701
|
// src/app/views/project/ProjectSwitch.tsx
|
|
1213
|
-
import { useNavigate as
|
|
1214
|
-
import { jsx as
|
|
1702
|
+
import { useNavigate as useNavigate7 } from "react-router";
|
|
1703
|
+
import { jsx as jsx30 } from "react/jsx-runtime";
|
|
1215
1704
|
var ProjectSwitch = () => {
|
|
1216
|
-
const navigate =
|
|
1705
|
+
const navigate = useNavigate7();
|
|
1217
1706
|
const { config, setSessionProject } = useNavigatorSession();
|
|
1218
1707
|
const handleSelect = (project) => {
|
|
1219
1708
|
switchProject(project.id, { currentProjectId: config.projectId });
|
|
1220
1709
|
setSessionProject(project.id);
|
|
1221
1710
|
navigate("/", { replace: true });
|
|
1222
1711
|
};
|
|
1223
|
-
return /* @__PURE__ */
|
|
1712
|
+
return /* @__PURE__ */ jsx30(ProjectPicker, { onSelect: handleSelect, currentProjectId: config.projectId });
|
|
1224
1713
|
};
|
|
1225
1714
|
|
|
1226
1715
|
// src/app/views/settings/SettingsMenu.tsx
|
|
1227
|
-
import { jsx as
|
|
1716
|
+
import { jsx as jsx31 } from "react/jsx-runtime";
|
|
1228
1717
|
var SettingsMenu = () => {
|
|
1229
1718
|
const isUserToken = useIsUserToken();
|
|
1230
1719
|
const options = [
|
|
@@ -1240,19 +1729,19 @@ var SettingsMenu = () => {
|
|
|
1240
1729
|
}
|
|
1241
1730
|
] : []
|
|
1242
1731
|
];
|
|
1243
|
-
return /* @__PURE__ */
|
|
1732
|
+
return /* @__PURE__ */ jsx31(ViewLayout, { children: /* @__PURE__ */ jsx31(MenuList, { options }) });
|
|
1244
1733
|
};
|
|
1245
1734
|
|
|
1246
1735
|
// src/app/views/settings/SettingsSetSessionToken.tsx
|
|
1247
1736
|
import { StatusMessage as StatusMessage7 } from "@inkjs/ui";
|
|
1248
|
-
import { useState as
|
|
1249
|
-
import { jsx as
|
|
1737
|
+
import { useState as useState15 } from "react";
|
|
1738
|
+
import { jsx as jsx32, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
1250
1739
|
var SettingsSetSessionToken = () => {
|
|
1251
1740
|
const { auth, completeSession } = useNavigatorSession();
|
|
1252
|
-
const [tokenValue, setTokenValue] =
|
|
1253
|
-
const [token, setToken] =
|
|
1254
|
-
const [error, setError] =
|
|
1255
|
-
const [saved, setSaved] =
|
|
1741
|
+
const [tokenValue, setTokenValue] = useState15("");
|
|
1742
|
+
const [token, setToken] = useState15(null);
|
|
1743
|
+
const [error, setError] = useState15(null);
|
|
1744
|
+
const [saved, setSaved] = useState15(false);
|
|
1256
1745
|
const handleTokenSubmit = (value) => {
|
|
1257
1746
|
const trimmed = value.trim();
|
|
1258
1747
|
if (!trimmed) {
|
|
@@ -1274,8 +1763,8 @@ var SettingsSetSessionToken = () => {
|
|
|
1274
1763
|
setSaved(true);
|
|
1275
1764
|
};
|
|
1276
1765
|
if (token === null) {
|
|
1277
|
-
return /* @__PURE__ */
|
|
1278
|
-
/* @__PURE__ */
|
|
1766
|
+
return /* @__PURE__ */ jsxs18(ViewLayout, { title: "Project API token", hints: "confirm", hintsPosition: "bottom", children: [
|
|
1767
|
+
/* @__PURE__ */ jsx32(
|
|
1279
1768
|
TextInput,
|
|
1280
1769
|
{
|
|
1281
1770
|
value: tokenValue,
|
|
@@ -1284,20 +1773,330 @@ var SettingsSetSessionToken = () => {
|
|
|
1284
1773
|
mask: "*"
|
|
1285
1774
|
}
|
|
1286
1775
|
),
|
|
1287
|
-
error && /* @__PURE__ */
|
|
1776
|
+
error && /* @__PURE__ */ jsx32(StatusMessage7, { variant: "error", children: `Error: ${error}` })
|
|
1288
1777
|
] });
|
|
1289
1778
|
}
|
|
1290
1779
|
if (!saved) {
|
|
1291
|
-
return /* @__PURE__ */
|
|
1780
|
+
return /* @__PURE__ */ jsx32(ProjectPicker, { onSelect: handleProjectSelect, currentProjectId: auth.projectId });
|
|
1292
1781
|
}
|
|
1293
|
-
return /* @__PURE__ */
|
|
1782
|
+
return /* @__PURE__ */ jsx32(ViewLayout, { hintsHidden: true, children: /* @__PURE__ */ jsx32(StatusMessage7, { variant: "success", children: "Token saved and valid only for this session" }) });
|
|
1294
1783
|
};
|
|
1295
1784
|
|
|
1296
1785
|
// src/app/views/suiteRuns/SuiteRunDetails.tsx
|
|
1297
|
-
import { Spinner as
|
|
1298
|
-
import { Text as
|
|
1786
|
+
import { Spinner as Spinner8, StatusMessage as StatusMessage9 } from "@inkjs/ui";
|
|
1787
|
+
import { Text as Text17 } from "ink";
|
|
1299
1788
|
import { useLocation as useLocation5, useParams } from "react-router";
|
|
1300
1789
|
|
|
1790
|
+
// src/app/components/BaseSuiteRunDetails/BaseSuiteRunDetails.tsx
|
|
1791
|
+
import { Spinner as Spinner7, StatusMessage as StatusMessage8 } from "@inkjs/ui";
|
|
1792
|
+
import { Box as Box17, useApp as useApp4 } from "ink";
|
|
1793
|
+
import { useEffect as useEffect12, useState as useState16 } from "react";
|
|
1794
|
+
|
|
1795
|
+
// ../core/dist/utils/duration.js
|
|
1796
|
+
var formatDuration = (duration, fallback) => {
|
|
1797
|
+
let totalSeconds = null;
|
|
1798
|
+
if (duration != null && duration !== "") {
|
|
1799
|
+
totalSeconds = typeof duration === "number" ? duration : parseDurationString(duration);
|
|
1800
|
+
}
|
|
1801
|
+
if (totalSeconds == null && fallback?.started && fallback?.ended) {
|
|
1802
|
+
const start = Date.parse(fallback.started);
|
|
1803
|
+
const end = Date.parse(fallback.ended);
|
|
1804
|
+
if (Number.isFinite(start) && Number.isFinite(end) && end >= start) {
|
|
1805
|
+
totalSeconds = (end - start) / 1e3;
|
|
1806
|
+
}
|
|
1807
|
+
}
|
|
1808
|
+
if (totalSeconds == null || !Number.isFinite(totalSeconds) || totalSeconds < 0) {
|
|
1809
|
+
return "-";
|
|
1810
|
+
}
|
|
1811
|
+
const hours = Math.floor(totalSeconds / 3600);
|
|
1812
|
+
const minutes = Math.floor(totalSeconds % 3600 / 60);
|
|
1813
|
+
const seconds = totalSeconds - hours * 3600 - minutes * 60;
|
|
1814
|
+
const secondsStr = `${seconds.toFixed(2).padStart(5, "0")}s`;
|
|
1815
|
+
if (hours > 0) {
|
|
1816
|
+
return `${String(hours).padStart(2, "0")}h ${String(minutes).padStart(2, "0")}m ${secondsStr}`;
|
|
1817
|
+
}
|
|
1818
|
+
if (minutes > 0) {
|
|
1819
|
+
return `${String(minutes).padStart(2, "0")}m ${secondsStr}`;
|
|
1820
|
+
}
|
|
1821
|
+
return secondsStr;
|
|
1822
|
+
};
|
|
1823
|
+
var parseDurationString = (value) => {
|
|
1824
|
+
const trimmed = value.trim();
|
|
1825
|
+
if (trimmed === "") {
|
|
1826
|
+
return null;
|
|
1827
|
+
}
|
|
1828
|
+
const numeric = Number(trimmed);
|
|
1829
|
+
if (Number.isFinite(numeric)) {
|
|
1830
|
+
return numeric;
|
|
1831
|
+
}
|
|
1832
|
+
const iso = /^P(?:(\d+(?:\.\d+)?)D)?(?:T(?:(\d+(?:\.\d+)?)H)?(?:(\d+(?:\.\d+)?)M)?(?:(\d+(?:\.\d+)?)S)?)?$/i.exec(trimmed);
|
|
1833
|
+
if (iso) {
|
|
1834
|
+
const days = Number(iso[1] ?? 0);
|
|
1835
|
+
const hours = Number(iso[2] ?? 0);
|
|
1836
|
+
const minutes = Number(iso[3] ?? 0);
|
|
1837
|
+
const seconds = Number(iso[4] ?? 0);
|
|
1838
|
+
return days * 86400 + hours * 3600 + minutes * 60 + seconds;
|
|
1839
|
+
}
|
|
1840
|
+
const hms = /^(?:(\d+):)?(\d{1,2}):(\d{1,2}(?:\.\d+)?)$/.exec(trimmed);
|
|
1841
|
+
if (hms) {
|
|
1842
|
+
const hours = Number(hms[1] ?? 0);
|
|
1843
|
+
const minutes = Number(hms[2]);
|
|
1844
|
+
const seconds = Number(hms[3]);
|
|
1845
|
+
return hours * 3600 + minutes * 60 + seconds;
|
|
1846
|
+
}
|
|
1847
|
+
return null;
|
|
1848
|
+
};
|
|
1849
|
+
|
|
1850
|
+
// src/app/components/RunBody/RunBody.tsx
|
|
1851
|
+
import { Box as Box16, Text as Text16 } from "ink";
|
|
1852
|
+
|
|
1853
|
+
// src/app/components/RunProgress/RunProgress.tsx
|
|
1854
|
+
import { Box as Box13, Text as Text13 } from "ink";
|
|
1855
|
+
|
|
1856
|
+
// src/app/components/RunProgress/RunProgress.constants.ts
|
|
1857
|
+
var BAR_WIDTH = 20;
|
|
1858
|
+
|
|
1859
|
+
// src/app/components/RunProgress/RunProgress.utils.ts
|
|
1860
|
+
var renderBar = (finished, total) => {
|
|
1861
|
+
if (!total) return "";
|
|
1862
|
+
const filled = Math.min(BAR_WIDTH, Math.round(finished / total * BAR_WIDTH));
|
|
1863
|
+
return `[${"\u2588".repeat(filled)}${"\u2591".repeat(BAR_WIDTH - filled)}]`;
|
|
1864
|
+
};
|
|
1865
|
+
|
|
1866
|
+
// src/app/components/RunProgress/RunProgress.tsx
|
|
1867
|
+
import { jsx as jsx33, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
1868
|
+
var RunProgress = ({ runState, isRunning }) => {
|
|
1869
|
+
if (!isRunning) return null;
|
|
1870
|
+
const { progress, resultsSummary: summary } = runState;
|
|
1871
|
+
if (progress && progress.total > 0) {
|
|
1872
|
+
const pct = Math.round(progress.finished / progress.total * 100);
|
|
1873
|
+
return /* @__PURE__ */ jsx33(Box13, { marginTop: 1, flexDirection: "column", children: /* @__PURE__ */ jsxs19(Text13, { children: [
|
|
1874
|
+
progress.unit === "steps" ? "Steps" : "Tests",
|
|
1875
|
+
": ",
|
|
1876
|
+
progress.finished,
|
|
1877
|
+
"/",
|
|
1878
|
+
progress.total,
|
|
1879
|
+
" ",
|
|
1880
|
+
renderBar(progress.finished, progress.total),
|
|
1881
|
+
" ",
|
|
1882
|
+
pct,
|
|
1883
|
+
"%"
|
|
1884
|
+
] }) });
|
|
1885
|
+
}
|
|
1886
|
+
if (!summary) return null;
|
|
1887
|
+
const passed = summary.passedSteps ?? 0;
|
|
1888
|
+
const failed = summary.failedSteps ?? 0;
|
|
1889
|
+
const skipped = summary.skippedSteps ?? 0;
|
|
1890
|
+
const total = summary.totalSteps;
|
|
1891
|
+
return /* @__PURE__ */ jsxs19(Box13, { marginTop: 1, flexDirection: "column", children: [
|
|
1892
|
+
/* @__PURE__ */ jsxs19(Text13, { children: [
|
|
1893
|
+
"Progress: ",
|
|
1894
|
+
passed,
|
|
1895
|
+
" passed",
|
|
1896
|
+
failed ? `, ${failed} failed` : "",
|
|
1897
|
+
skipped ? `, ${skipped} skipped` : "",
|
|
1898
|
+
total ? ` / ${total} total` : ""
|
|
1899
|
+
] }),
|
|
1900
|
+
total ? /* @__PURE__ */ jsxs19(Text13, { dimColor: true, children: [
|
|
1901
|
+
"Completion: ",
|
|
1902
|
+
Math.round((passed + failed) / total * 100),
|
|
1903
|
+
"%"
|
|
1904
|
+
] }) : null
|
|
1905
|
+
] });
|
|
1906
|
+
};
|
|
1907
|
+
|
|
1908
|
+
// src/app/components/Status/Status.tsx
|
|
1909
|
+
import { Box as Box15, Text as Text15 } from "ink";
|
|
1910
|
+
|
|
1911
|
+
// src/app/components/StatusIndicator/StatusIndicator.tsx
|
|
1912
|
+
import { Spinner as Spinner6 } from "@inkjs/ui";
|
|
1913
|
+
import { Box as Box14, Text as Text14 } from "ink";
|
|
1914
|
+
|
|
1915
|
+
// src/app/components/StatusIndicator/StatusIndicator.constants.ts
|
|
1916
|
+
var DOT = "\u25CF";
|
|
1917
|
+
|
|
1918
|
+
// src/app/components/StatusIndicator/StatusIndicator.tsx
|
|
1919
|
+
import { jsx as jsx34 } from "react/jsx-runtime";
|
|
1920
|
+
var StatusIndicator = ({ status, autoRetried = false }) => {
|
|
1921
|
+
const { theme: theme2 } = useTheme();
|
|
1922
|
+
if (autoRetried) {
|
|
1923
|
+
return /* @__PURE__ */ jsx34(Text14, { color: theme2.colors.status.failure, children: DOT });
|
|
1924
|
+
}
|
|
1925
|
+
switch (status) {
|
|
1926
|
+
case "running":
|
|
1927
|
+
case "queued":
|
|
1928
|
+
case "recording":
|
|
1929
|
+
case "auto_retrying":
|
|
1930
|
+
return /* @__PURE__ */ jsx34(Box14, { children: /* @__PURE__ */ jsx34(Spinner6, {}) });
|
|
1931
|
+
case "passed":
|
|
1932
|
+
return /* @__PURE__ */ jsx34(Text14, { color: theme2.colors.status.success, children: DOT });
|
|
1933
|
+
case "failed":
|
|
1934
|
+
case "error":
|
|
1935
|
+
return /* @__PURE__ */ jsx34(Text14, { color: theme2.colors.status.failure, children: DOT });
|
|
1936
|
+
case "skipped":
|
|
1937
|
+
case "stopped":
|
|
1938
|
+
return /* @__PURE__ */ jsx34(Text14, { color: theme2.colors.status.stopped, children: DOT });
|
|
1939
|
+
case "paused":
|
|
1940
|
+
return /* @__PURE__ */ jsx34(Text14, { color: theme2.colors.status.paused, children: DOT });
|
|
1941
|
+
default:
|
|
1942
|
+
return /* @__PURE__ */ jsx34(Text14, { color: theme2.colors.status.info, children: DOT });
|
|
1943
|
+
}
|
|
1944
|
+
};
|
|
1945
|
+
|
|
1946
|
+
// src/app/components/Status/Status.tsx
|
|
1947
|
+
import { Fragment as Fragment3, jsx as jsx35, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
1948
|
+
var ERROR_CODE_STATUSES = /* @__PURE__ */ new Set([
|
|
1949
|
+
"failed",
|
|
1950
|
+
"error",
|
|
1951
|
+
"passed-with-issues",
|
|
1952
|
+
"passed_with_issues"
|
|
1953
|
+
]);
|
|
1954
|
+
var Status = ({
|
|
1955
|
+
status,
|
|
1956
|
+
color,
|
|
1957
|
+
backgroundColor,
|
|
1958
|
+
autoRetried = false,
|
|
1959
|
+
errorCode
|
|
1960
|
+
}) => {
|
|
1961
|
+
const label = status ? formatRunStatus(status, autoRetried) : "-";
|
|
1962
|
+
const shouldShowErrorCode = Boolean(errorCode) && status !== void 0 && (autoRetried || ERROR_CODE_STATUSES.has(status));
|
|
1963
|
+
return /* @__PURE__ */ jsxs20(Box15, { backgroundColor, width: "100%", children: [
|
|
1964
|
+
status && /* @__PURE__ */ jsxs20(Fragment3, { children: [
|
|
1965
|
+
/* @__PURE__ */ jsx35(StatusIndicator, { status, autoRetried }),
|
|
1966
|
+
/* @__PURE__ */ jsx35(Text15, { backgroundColor, children: " " })
|
|
1967
|
+
] }),
|
|
1968
|
+
/* @__PURE__ */ jsxs20(Text15, { color, backgroundColor, children: [
|
|
1969
|
+
label,
|
|
1970
|
+
shouldShowErrorCode ? ` (${errorCode})` : ""
|
|
1971
|
+
] })
|
|
1972
|
+
] });
|
|
1973
|
+
};
|
|
1974
|
+
|
|
1975
|
+
// src/app/components/RunBody/RunBody.tsx
|
|
1976
|
+
import { jsx as jsx36, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
1977
|
+
var RunBody = ({ runState, isRunning, isCompleted = !isRunning }) => {
|
|
1978
|
+
const duration = formatDuration(runState.duration, {
|
|
1979
|
+
started: runState.started,
|
|
1980
|
+
ended: runState.ended
|
|
1981
|
+
});
|
|
1982
|
+
const finalResults = isCompleted ? formatFinalResults(runState) : null;
|
|
1983
|
+
const errorMessage = isCompleted ? getRunErrorMessage(runState) : null;
|
|
1984
|
+
return /* @__PURE__ */ jsxs21(Box16, { flexDirection: "column", children: [
|
|
1985
|
+
/* @__PURE__ */ jsxs21(Box16, { flexDirection: "column", children: [
|
|
1986
|
+
/* @__PURE__ */ jsx36(Box16, { children: /* @__PURE__ */ jsxs21(Text16, { children: [
|
|
1987
|
+
"Run id: ",
|
|
1988
|
+
runState.id
|
|
1989
|
+
] }) }),
|
|
1990
|
+
/* @__PURE__ */ jsxs21(Box16, { flexDirection: "row", rowGap: 2, children: [
|
|
1991
|
+
/* @__PURE__ */ jsx36(Text16, { children: "Status: " }),
|
|
1992
|
+
/* @__PURE__ */ jsx36(
|
|
1993
|
+
Status,
|
|
1994
|
+
{
|
|
1995
|
+
status: runState.status,
|
|
1996
|
+
autoRetried: runState.isAutoRetried,
|
|
1997
|
+
errorCode: runState.errorCode
|
|
1998
|
+
}
|
|
1999
|
+
)
|
|
2000
|
+
] }),
|
|
2001
|
+
/* @__PURE__ */ jsx36(Box16, { children: /* @__PURE__ */ jsxs21(Text16, { dimColor: true, children: [
|
|
2002
|
+
"Duration: ",
|
|
2003
|
+
duration
|
|
2004
|
+
] }) }),
|
|
2005
|
+
finalResults ? /* @__PURE__ */ jsx36(Box16, { children: /* @__PURE__ */ jsx36(Text16, { children: finalResults }) }) : null,
|
|
2006
|
+
errorMessage ? /* @__PURE__ */ jsx36(Box16, { children: /* @__PURE__ */ jsxs21(Text16, { children: [
|
|
2007
|
+
"Error: ",
|
|
2008
|
+
errorMessage
|
|
2009
|
+
] }) }) : null
|
|
2010
|
+
] }),
|
|
2011
|
+
/* @__PURE__ */ jsx36(RunProgress, { runState, isRunning })
|
|
2012
|
+
] });
|
|
2013
|
+
};
|
|
2014
|
+
|
|
2015
|
+
// src/app/components/BaseSuiteRunDetails/BaseSuiteRunDetails.tsx
|
|
2016
|
+
import { jsx as jsx37, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
2017
|
+
var menuOptions = (runId, state) => [
|
|
2018
|
+
{
|
|
2019
|
+
label: "Show test runs",
|
|
2020
|
+
shortcut: "t",
|
|
2021
|
+
description: "Drill into the test runs that belong to this suite run",
|
|
2022
|
+
to: ROUTES.suiteRuns.showTestRuns(runId),
|
|
2023
|
+
state
|
|
2024
|
+
},
|
|
2025
|
+
{
|
|
2026
|
+
label: "Open in BugBug",
|
|
2027
|
+
shortcut: "o",
|
|
2028
|
+
description: "Open the suite run page in your browser",
|
|
2029
|
+
to: ROUTES.suiteRuns.open(runId),
|
|
2030
|
+
state
|
|
2031
|
+
}
|
|
2032
|
+
];
|
|
2033
|
+
var BaseSuiteRunDetails = ({
|
|
2034
|
+
runId,
|
|
2035
|
+
title,
|
|
2036
|
+
menuState,
|
|
2037
|
+
headless = false,
|
|
2038
|
+
intervalMs = 4e3,
|
|
2039
|
+
timeoutMs,
|
|
2040
|
+
exitDelayMs = 300,
|
|
2041
|
+
onComplete,
|
|
2042
|
+
onError
|
|
2043
|
+
}) => {
|
|
2044
|
+
const { exit } = useApp4();
|
|
2045
|
+
const [runState, setRunState] = useState16(null);
|
|
2046
|
+
const [error, setError] = useState16(null);
|
|
2047
|
+
useEffect12(() => {
|
|
2048
|
+
let cancelled = false;
|
|
2049
|
+
void (async () => {
|
|
2050
|
+
try {
|
|
2051
|
+
const finalStatus = await waitForSuiteRun(
|
|
2052
|
+
runId,
|
|
2053
|
+
intervalMs,
|
|
2054
|
+
(status) => {
|
|
2055
|
+
if (!cancelled) setRunState(status);
|
|
2056
|
+
},
|
|
2057
|
+
timeoutMs
|
|
2058
|
+
);
|
|
2059
|
+
if (!cancelled) {
|
|
2060
|
+
setRunState(finalStatus);
|
|
2061
|
+
onComplete?.(finalStatus);
|
|
2062
|
+
if (headless) setTimeout(exit, exitDelayMs);
|
|
2063
|
+
}
|
|
2064
|
+
} catch (err) {
|
|
2065
|
+
if (!cancelled) {
|
|
2066
|
+
const nextError = err instanceof Error ? err : new Error("Unknown error occurred");
|
|
2067
|
+
setError(nextError.message);
|
|
2068
|
+
onError?.(nextError);
|
|
2069
|
+
if (headless) setTimeout(exit, exitDelayMs);
|
|
2070
|
+
}
|
|
2071
|
+
}
|
|
2072
|
+
})();
|
|
2073
|
+
return () => {
|
|
2074
|
+
cancelled = true;
|
|
2075
|
+
};
|
|
2076
|
+
}, [runId, intervalMs, timeoutMs, headless, exitDelayMs, exit, onComplete, onError]);
|
|
2077
|
+
const isRunning = runState ? isRunningStatus(runState.status) : false;
|
|
2078
|
+
const isCompleted = runState ? isCompletedStatus(runState.status) : false;
|
|
2079
|
+
const body = /* @__PURE__ */ jsxs22(Box17, { flexDirection: "column", children: [
|
|
2080
|
+
error && /* @__PURE__ */ jsx37(StatusMessage8, { variant: "error", children: `Failed to complete suite run: ${error}` }),
|
|
2081
|
+
!error && !runState && /* @__PURE__ */ jsx37(Spinner7, { label: "Initializing..." }),
|
|
2082
|
+
!error && runState && /* @__PURE__ */ jsx37(RunBody, { runState, isRunning, isCompleted })
|
|
2083
|
+
] });
|
|
2084
|
+
if (headless) return body;
|
|
2085
|
+
return /* @__PURE__ */ jsxs22(
|
|
2086
|
+
ViewLayout,
|
|
2087
|
+
{
|
|
2088
|
+
title,
|
|
2089
|
+
hints: isCompleted ? "navigationSelect" : "none",
|
|
2090
|
+
hintsHidden: !isCompleted,
|
|
2091
|
+
hintsPosition: "bottom",
|
|
2092
|
+
children: [
|
|
2093
|
+
body,
|
|
2094
|
+
isCompleted && /* @__PURE__ */ jsx37(MenuList, { options: menuOptions(runId, menuState) })
|
|
2095
|
+
]
|
|
2096
|
+
}
|
|
2097
|
+
);
|
|
2098
|
+
};
|
|
2099
|
+
|
|
1301
2100
|
// src/app/hooks/useSuiteRuns.ts
|
|
1302
2101
|
var useSuiteRunsList = () => useFeatureQuery(() => listSuiteRuns(), []);
|
|
1303
2102
|
var useSuiteRunDetails = (runId) => useFeatureQuery(async () => {
|
|
@@ -1309,7 +2108,7 @@ var useSuiteRunDetails = (runId) => useFeatureQuery(async () => {
|
|
|
1309
2108
|
var getSuiteRunName = (run) => run.name || run.id;
|
|
1310
2109
|
|
|
1311
2110
|
// src/app/views/suiteRuns/SuiteRunDetails.tsx
|
|
1312
|
-
import { jsx as
|
|
2111
|
+
import { jsx as jsx38, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
1313
2112
|
var SuiteRunDetails = () => {
|
|
1314
2113
|
const { runId } = useParams();
|
|
1315
2114
|
const location = useLocation5();
|
|
@@ -1318,37 +2117,37 @@ var SuiteRunDetails = () => {
|
|
|
1318
2117
|
const title = request.data ? getSuiteRunName(request.data) : state?.suiteRunName;
|
|
1319
2118
|
const menuState = title ? { suiteRunName: title } : void 0;
|
|
1320
2119
|
if (!request.data || !runId) {
|
|
1321
|
-
return /* @__PURE__ */
|
|
1322
|
-
request.isLoading && /* @__PURE__ */
|
|
1323
|
-
request.isError && /* @__PURE__ */
|
|
1324
|
-
!request.isLoading && !request.isError && !request.data && /* @__PURE__ */
|
|
2120
|
+
return /* @__PURE__ */ jsxs23(ViewLayout, { title, hintsHidden: true, hintsPosition: "bottom", children: [
|
|
2121
|
+
request.isLoading && /* @__PURE__ */ jsx38(Spinner8, { label: "Loading suite run..." }),
|
|
2122
|
+
request.isError && /* @__PURE__ */ jsx38(StatusMessage9, { variant: "error", children: request.error }),
|
|
2123
|
+
!request.isLoading && !request.isError && !request.data && /* @__PURE__ */ jsx38(Text17, { color: "yellow", children: "Suite run not found." })
|
|
1325
2124
|
] });
|
|
1326
2125
|
}
|
|
1327
|
-
return /* @__PURE__ */
|
|
2126
|
+
return /* @__PURE__ */ jsx38(BaseSuiteRunDetails, { runId, title, menuState });
|
|
1328
2127
|
};
|
|
1329
2128
|
|
|
1330
2129
|
// src/app/views/suiteRuns/SuiteRunOpen.tsx
|
|
1331
|
-
import { Spinner as
|
|
1332
|
-
import { Box as
|
|
1333
|
-
import { useEffect as
|
|
2130
|
+
import { Spinner as Spinner9, StatusMessage as StatusMessage10 } from "@inkjs/ui";
|
|
2131
|
+
import { Box as Box18, Text as Text18 } from "ink";
|
|
2132
|
+
import { useEffect as useEffect13 } from "react";
|
|
1334
2133
|
import { useLocation as useLocation6, useParams as useParams2 } from "react-router";
|
|
1335
|
-
import { Fragment as
|
|
1336
|
-
var WebUrlUnavailableMessage = () => /* @__PURE__ */
|
|
2134
|
+
import { Fragment as Fragment4, jsx as jsx39, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
2135
|
+
var WebUrlUnavailableMessage = () => /* @__PURE__ */ jsx39(StatusMessage10, { variant: "warning", children: "No web URL available for this run" });
|
|
1337
2136
|
var OpenSuiteRun = ({ url }) => {
|
|
1338
2137
|
const [openSuiteRun, openSuiteRunResult] = useFeatureMutation(async (url2) => {
|
|
1339
2138
|
await openExternalUrl(url2);
|
|
1340
2139
|
return url2;
|
|
1341
2140
|
});
|
|
1342
|
-
|
|
2141
|
+
useEffect13(() => {
|
|
1343
2142
|
if (url) void openSuiteRun(url);
|
|
1344
2143
|
}, [openSuiteRun, url]);
|
|
1345
|
-
if (!url) return /* @__PURE__ */
|
|
1346
|
-
return /* @__PURE__ */
|
|
1347
|
-
openSuiteRunResult.isLoading && /* @__PURE__ */
|
|
1348
|
-
openSuiteRunResult.isError && /* @__PURE__ */
|
|
1349
|
-
openSuiteRunResult.data && /* @__PURE__ */
|
|
1350
|
-
/* @__PURE__ */
|
|
1351
|
-
/* @__PURE__ */
|
|
2144
|
+
if (!url) return /* @__PURE__ */ jsx39(WebUrlUnavailableMessage, {});
|
|
2145
|
+
return /* @__PURE__ */ jsxs24(Fragment4, { children: [
|
|
2146
|
+
openSuiteRunResult.isLoading && /* @__PURE__ */ jsx39(Spinner9, { label: "Opening BugBug..." }),
|
|
2147
|
+
openSuiteRunResult.isError && /* @__PURE__ */ jsx39(StatusMessage10, { variant: "error", children: openSuiteRunResult.error }),
|
|
2148
|
+
openSuiteRunResult.data && /* @__PURE__ */ jsxs24(Box18, { flexDirection: "column", children: [
|
|
2149
|
+
/* @__PURE__ */ jsx39(StatusMessage10, { variant: "success", children: "Opened in BugBug" }),
|
|
2150
|
+
/* @__PURE__ */ jsx39(Text18, { dimColor: true, children: openSuiteRunResult.data })
|
|
1352
2151
|
] })
|
|
1353
2152
|
] });
|
|
1354
2153
|
};
|
|
@@ -1358,20 +2157,20 @@ var SuiteRunOpen = () => {
|
|
|
1358
2157
|
const state = location.state;
|
|
1359
2158
|
const request = useSuiteRunDetails(runId);
|
|
1360
2159
|
const title = request.data ? getSuiteRunName(request.data) : state?.suiteRunName ?? runId;
|
|
1361
|
-
return /* @__PURE__ */
|
|
1362
|
-
request.isLoading && /* @__PURE__ */
|
|
1363
|
-
request.isError && /* @__PURE__ */
|
|
1364
|
-
!request.isLoading && !request.isError && /* @__PURE__ */
|
|
2160
|
+
return /* @__PURE__ */ jsxs24(ViewLayout, { title, hintsHidden: true, hintsPosition: "bottom", children: [
|
|
2161
|
+
request.isLoading && /* @__PURE__ */ jsx39(Spinner9, { label: "Loading..." }),
|
|
2162
|
+
request.isError && /* @__PURE__ */ jsx39(Text18, { color: "red", children: request.error }),
|
|
2163
|
+
!request.isLoading && !request.isError && /* @__PURE__ */ jsx39(OpenSuiteRun, { url: request.data?.webappUrl })
|
|
1365
2164
|
] });
|
|
1366
2165
|
};
|
|
1367
2166
|
|
|
1368
2167
|
// src/app/views/suiteRuns/SuiteRunShowTestRuns.tsx
|
|
1369
|
-
import { Spinner as
|
|
1370
|
-
import { StatusMessage as
|
|
2168
|
+
import { Spinner as Spinner10 } from "@inkjs/ui";
|
|
2169
|
+
import { StatusMessage as StatusMessage11 } from "@inkjs/ui";
|
|
1371
2170
|
import { useLocation as useLocation7, useParams as useParams3 } from "react-router";
|
|
1372
2171
|
|
|
1373
2172
|
// src/features/testRuns/components/TestRunsList.tsx
|
|
1374
|
-
import { useNavigate as
|
|
2173
|
+
import { useNavigate as useNavigate8 } from "react-router";
|
|
1375
2174
|
|
|
1376
2175
|
// src/features/testRuns/testRuns.utils.ts
|
|
1377
2176
|
var getTestRunName = (run) => run.name || run.id;
|
|
@@ -1387,7 +2186,7 @@ var DEBUG_ARTIFACT_LABELS = {
|
|
|
1387
2186
|
var getDebugArtifactLabel = (artifact) => DEBUG_ARTIFACT_LABELS[artifact.kind];
|
|
1388
2187
|
|
|
1389
2188
|
// src/features/testRuns/components/TestRunsList.constants.tsx
|
|
1390
|
-
import { jsx as
|
|
2189
|
+
import { jsx as jsx40 } from "react/jsx-runtime";
|
|
1391
2190
|
var TEST_RUN_LIST_COLUMNS = [
|
|
1392
2191
|
{ key: "name", label: "Name", width: 30 },
|
|
1393
2192
|
{ key: "duration", label: "Duration", width: 8 },
|
|
@@ -1398,7 +2197,7 @@ var TEST_RUN_LIST_COLUMNS = [
|
|
|
1398
2197
|
key: "status",
|
|
1399
2198
|
label: "Status",
|
|
1400
2199
|
width: 15,
|
|
1401
|
-
render: (_cell, row, ctx) => /* @__PURE__ */
|
|
2200
|
+
render: (_cell, row, ctx) => /* @__PURE__ */ jsx40(
|
|
1402
2201
|
Status,
|
|
1403
2202
|
{
|
|
1404
2203
|
status: row.value?.status,
|
|
@@ -1428,7 +2227,7 @@ var getTestRunRow = (run) => {
|
|
|
1428
2227
|
};
|
|
1429
2228
|
|
|
1430
2229
|
// src/features/testRuns/components/TestRunsList.tsx
|
|
1431
|
-
import { jsx as
|
|
2230
|
+
import { jsx as jsx41 } from "react/jsx-runtime";
|
|
1432
2231
|
var TestRunsList = ({
|
|
1433
2232
|
title,
|
|
1434
2233
|
loadingLabel = "Loading test runs...",
|
|
@@ -1438,8 +2237,8 @@ var TestRunsList = ({
|
|
|
1438
2237
|
isError,
|
|
1439
2238
|
error
|
|
1440
2239
|
}) => {
|
|
1441
|
-
const navigate =
|
|
1442
|
-
return /* @__PURE__ */
|
|
2240
|
+
const navigate = useNavigate8();
|
|
2241
|
+
return /* @__PURE__ */ jsx41(
|
|
1443
2242
|
BaseResourceListScreen,
|
|
1444
2243
|
{
|
|
1445
2244
|
title,
|
|
@@ -1457,10 +2256,10 @@ var TestRunsList = ({
|
|
|
1457
2256
|
};
|
|
1458
2257
|
|
|
1459
2258
|
// src/app/views/suiteRuns/SuiteRunShowTestRuns.tsx
|
|
1460
|
-
import { jsx as
|
|
2259
|
+
import { jsx as jsx42, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
1461
2260
|
var SuiteRunTestRuns = ({ run, title }) => {
|
|
1462
2261
|
const request = useFeatureQuery(() => getSuiteRunTestRuns(run.id), [run.id]);
|
|
1463
|
-
return /* @__PURE__ */
|
|
2262
|
+
return /* @__PURE__ */ jsx42(
|
|
1464
2263
|
TestRunsList,
|
|
1465
2264
|
{
|
|
1466
2265
|
title,
|
|
@@ -1480,20 +2279,20 @@ var SuiteRunShowTestRuns = () => {
|
|
|
1480
2279
|
const request = useSuiteRunDetails(runId);
|
|
1481
2280
|
const title = request.data ? `Test runs in "${getSuiteRunName(request.data)}"` : state?.suiteRunName ? `Test runs in "${state.suiteRunName}"` : void 0;
|
|
1482
2281
|
if (!request.data) {
|
|
1483
|
-
return /* @__PURE__ */
|
|
1484
|
-
request.isLoading && /* @__PURE__ */
|
|
1485
|
-
request.isError && /* @__PURE__ */
|
|
1486
|
-
!request.isLoading && !request.isError && /* @__PURE__ */
|
|
2282
|
+
return /* @__PURE__ */ jsxs25(ViewLayout, { title, hintsHidden: true, hintsPosition: "bottom", children: [
|
|
2283
|
+
request.isLoading && /* @__PURE__ */ jsx42(Spinner10, { label: "Loading..." }),
|
|
2284
|
+
request.isError && /* @__PURE__ */ jsx42(StatusMessage11, { variant: "error", children: request.error }),
|
|
2285
|
+
!request.isLoading && !request.isError && /* @__PURE__ */ jsx42(StatusMessage11, { variant: "warning", children: "No test runs available" })
|
|
1487
2286
|
] });
|
|
1488
2287
|
}
|
|
1489
|
-
return /* @__PURE__ */
|
|
2288
|
+
return /* @__PURE__ */ jsx42(SuiteRunTestRuns, { run: request.data, title: title ?? "" });
|
|
1490
2289
|
};
|
|
1491
2290
|
|
|
1492
2291
|
// src/app/views/suiteRuns/SuiteRunsList.tsx
|
|
1493
|
-
import { useNavigate as
|
|
2292
|
+
import { useNavigate as useNavigate9 } from "react-router";
|
|
1494
2293
|
|
|
1495
2294
|
// src/app/views/suiteRuns/SuiteRunsList.constants.tsx
|
|
1496
|
-
import { jsx as
|
|
2295
|
+
import { jsx as jsx43 } from "react/jsx-runtime";
|
|
1497
2296
|
var SUITE_RUN_LIST_COLUMNS = [
|
|
1498
2297
|
{ key: "name", label: "Name", width: 30 },
|
|
1499
2298
|
{ key: "duration", label: "Duration", width: 10 },
|
|
@@ -1504,7 +2303,7 @@ var SUITE_RUN_LIST_COLUMNS = [
|
|
|
1504
2303
|
key: "status",
|
|
1505
2304
|
label: "Status",
|
|
1506
2305
|
width: 10,
|
|
1507
|
-
render: (_cell, row, ctx) => /* @__PURE__ */
|
|
2306
|
+
render: (_cell, row, ctx) => /* @__PURE__ */ jsx43(Status, { status: row.value?.status, color: ctx.color, backgroundColor: ctx.backgroundColor })
|
|
1508
2307
|
}
|
|
1509
2308
|
];
|
|
1510
2309
|
|
|
@@ -1532,11 +2331,11 @@ var getSuiteRunRow = (run) => {
|
|
|
1532
2331
|
};
|
|
1533
2332
|
|
|
1534
2333
|
// src/app/views/suiteRuns/SuiteRunsList.tsx
|
|
1535
|
-
import { jsx as
|
|
2334
|
+
import { jsx as jsx44 } from "react/jsx-runtime";
|
|
1536
2335
|
var SuiteRunsList = () => {
|
|
1537
|
-
const navigate =
|
|
2336
|
+
const navigate = useNavigate9();
|
|
1538
2337
|
const request = useSuiteRunsList();
|
|
1539
|
-
return /* @__PURE__ */
|
|
2338
|
+
return /* @__PURE__ */ jsx44(
|
|
1540
2339
|
BaseResourceListScreen,
|
|
1541
2340
|
{
|
|
1542
2341
|
loadingLabel: "Loading suite runs...",
|
|
@@ -1555,21 +2354,21 @@ var SuiteRunsList = () => {
|
|
|
1555
2354
|
};
|
|
1556
2355
|
|
|
1557
2356
|
// src/app/views/suiteRuns/SuiteRunsMenu.tsx
|
|
1558
|
-
import { useEffect as
|
|
1559
|
-
import { useNavigate as
|
|
2357
|
+
import { useEffect as useEffect14 } from "react";
|
|
2358
|
+
import { useNavigate as useNavigate10 } from "react-router";
|
|
1560
2359
|
var SuiteRunsMenu = () => {
|
|
1561
|
-
const navigate =
|
|
1562
|
-
|
|
2360
|
+
const navigate = useNavigate10();
|
|
2361
|
+
useEffect14(() => {
|
|
1563
2362
|
navigate(ROUTES.suiteRuns.list(), { replace: true });
|
|
1564
2363
|
}, [navigate]);
|
|
1565
2364
|
return null;
|
|
1566
2365
|
};
|
|
1567
2366
|
|
|
1568
2367
|
// src/app/views/suites/RunSuite.tsx
|
|
1569
|
-
import { useNavigate as
|
|
2368
|
+
import { useNavigate as useNavigate11 } from "react-router";
|
|
1570
2369
|
|
|
1571
2370
|
// src/app/views/suites/BaseSuitesList.tsx
|
|
1572
|
-
import { useState as
|
|
2371
|
+
import { useState as useState17 } from "react";
|
|
1573
2372
|
|
|
1574
2373
|
// src/app/hooks/useSuites.ts
|
|
1575
2374
|
var useSuitesList = (query) => useFeatureQuery(() => loadSuiteTableResources(query), [query]);
|
|
@@ -1579,14 +2378,14 @@ var useSuiteDetails = (suiteId) => useFeatureQuery(async () => {
|
|
|
1579
2378
|
}, [suiteId]);
|
|
1580
2379
|
|
|
1581
2380
|
// src/features/suites/suites.constants.tsx
|
|
1582
|
-
import { jsx as
|
|
2381
|
+
import { jsx as jsx45 } from "react/jsx-runtime";
|
|
1583
2382
|
var SUITE_COLUMNS = [
|
|
1584
2383
|
{ key: "name", label: "Name", width: 42 },
|
|
1585
2384
|
{
|
|
1586
2385
|
key: "status",
|
|
1587
2386
|
label: "Status",
|
|
1588
2387
|
width: 14,
|
|
1589
|
-
render: (_cell, row, ctx) => /* @__PURE__ */
|
|
2388
|
+
render: (_cell, row, ctx) => /* @__PURE__ */ jsx45(Status, { status: row.value?.status, color: ctx.color, backgroundColor: ctx.backgroundColor })
|
|
1590
2389
|
}
|
|
1591
2390
|
];
|
|
1592
2391
|
|
|
@@ -1602,15 +2401,15 @@ var getSuiteRow = (suite) => ({
|
|
|
1602
2401
|
var getSuiteName = (suite) => suite.name || suite.id || "Untitled";
|
|
1603
2402
|
|
|
1604
2403
|
// src/app/views/suites/BaseSuitesList.tsx
|
|
1605
|
-
import { jsx as
|
|
2404
|
+
import { jsx as jsx46 } from "react/jsx-runtime";
|
|
1606
2405
|
var BaseSuitesList = ({
|
|
1607
2406
|
title,
|
|
1608
2407
|
emptyMessage = "No suites found",
|
|
1609
2408
|
onSelectSuite
|
|
1610
2409
|
}) => {
|
|
1611
|
-
const [query, setQuery] =
|
|
2410
|
+
const [query, setQuery] = useState17("");
|
|
1612
2411
|
const request = useSuitesList(query);
|
|
1613
|
-
return /* @__PURE__ */
|
|
2412
|
+
return /* @__PURE__ */ jsx46(
|
|
1614
2413
|
BaseResourceListScreen,
|
|
1615
2414
|
{
|
|
1616
2415
|
title,
|
|
@@ -1631,10 +2430,10 @@ var BaseSuitesList = ({
|
|
|
1631
2430
|
};
|
|
1632
2431
|
|
|
1633
2432
|
// src/app/views/suites/RunSuite.tsx
|
|
1634
|
-
import { jsx as
|
|
2433
|
+
import { jsx as jsx47 } from "react/jsx-runtime";
|
|
1635
2434
|
var RunSuite = () => {
|
|
1636
|
-
const navigate =
|
|
1637
|
-
return /* @__PURE__ */
|
|
2435
|
+
const navigate = useNavigate11();
|
|
2436
|
+
return /* @__PURE__ */ jsx47(
|
|
1638
2437
|
BaseSuitesList,
|
|
1639
2438
|
{
|
|
1640
2439
|
title: "Select a suite to run:",
|
|
@@ -1645,10 +2444,10 @@ var RunSuite = () => {
|
|
|
1645
2444
|
};
|
|
1646
2445
|
|
|
1647
2446
|
// src/app/views/suites/SuiteDetails.tsx
|
|
1648
|
-
import { Spinner as
|
|
1649
|
-
import { Box as
|
|
2447
|
+
import { Spinner as Spinner11, StatusMessage as StatusMessage12 } from "@inkjs/ui";
|
|
2448
|
+
import { Box as Box19 } from "ink";
|
|
1650
2449
|
import { useLocation as useLocation8, useParams as useParams4 } from "react-router";
|
|
1651
|
-
import { jsx as
|
|
2450
|
+
import { jsx as jsx48, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
1652
2451
|
var SuiteDetails = () => {
|
|
1653
2452
|
const { suiteId } = useParams4();
|
|
1654
2453
|
const location = useLocation8();
|
|
@@ -1682,19 +2481,19 @@ var SuiteDetails = () => {
|
|
|
1682
2481
|
to: ROUTES.suites.open(suiteId ?? "")
|
|
1683
2482
|
}
|
|
1684
2483
|
];
|
|
1685
|
-
return /* @__PURE__ */
|
|
1686
|
-
request.isLoading && /* @__PURE__ */
|
|
1687
|
-
request.isError && /* @__PURE__ */
|
|
1688
|
-
isNotFound && /* @__PURE__ */
|
|
1689
|
-
isReady && /* @__PURE__ */
|
|
2484
|
+
return /* @__PURE__ */ jsxs26(ViewLayout, { title, hints, children: [
|
|
2485
|
+
request.isLoading && /* @__PURE__ */ jsx48(Box19, { children: /* @__PURE__ */ jsx48(Spinner11, { label: "Loading suite..." }) }),
|
|
2486
|
+
request.isError && /* @__PURE__ */ jsx48(StatusMessage12, { variant: "error", children: request.error }),
|
|
2487
|
+
isNotFound && /* @__PURE__ */ jsx48(StatusMessage12, { variant: "warning", children: "Suite not found" }),
|
|
2488
|
+
isReady && /* @__PURE__ */ jsx48(MenuList, { options })
|
|
1690
2489
|
] });
|
|
1691
2490
|
};
|
|
1692
2491
|
|
|
1693
2492
|
// src/app/views/suites/SuiteDetailsLastRun.tsx
|
|
1694
|
-
import { Spinner as
|
|
1695
|
-
import { Text as
|
|
2493
|
+
import { Spinner as Spinner12, StatusMessage as StatusMessage13 } from "@inkjs/ui";
|
|
2494
|
+
import { Text as Text19 } from "ink";
|
|
1696
2495
|
import { useLocation as useLocation9, useParams as useParams5 } from "react-router";
|
|
1697
|
-
import { jsx as
|
|
2496
|
+
import { jsx as jsx49, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
1698
2497
|
var SuiteDetailsLastRun = () => {
|
|
1699
2498
|
const { suiteId } = useParams5();
|
|
1700
2499
|
const location = useLocation9();
|
|
@@ -1704,13 +2503,13 @@ var SuiteDetailsLastRun = () => {
|
|
|
1704
2503
|
const isReady = !request.isLoading && !request.isError;
|
|
1705
2504
|
const title = suite ? getSuiteName(suite) : state?.suiteName ?? suiteId;
|
|
1706
2505
|
if (!isReady || !suite?.lastRunId) {
|
|
1707
|
-
return /* @__PURE__ */
|
|
1708
|
-
request.isLoading && /* @__PURE__ */
|
|
1709
|
-
request.isError && /* @__PURE__ */
|
|
1710
|
-
isReady && !suite?.lastRunId && /* @__PURE__ */
|
|
2506
|
+
return /* @__PURE__ */ jsxs27(ViewLayout, { title, hintsHidden: true, hintsPosition: "bottom", children: [
|
|
2507
|
+
request.isLoading && /* @__PURE__ */ jsx49(Spinner12, { label: "Loading..." }),
|
|
2508
|
+
request.isError && /* @__PURE__ */ jsx49(Text19, { color: "red", children: request.error }),
|
|
2509
|
+
isReady && !suite?.lastRunId && /* @__PURE__ */ jsx49(StatusMessage13, { variant: "warning", children: `No previous run found for ${suite ? getSuiteName(suite) : suiteId ?? "suite"}` })
|
|
1711
2510
|
] });
|
|
1712
2511
|
}
|
|
1713
|
-
return /* @__PURE__ */
|
|
2512
|
+
return /* @__PURE__ */ jsx49(
|
|
1714
2513
|
BaseSuiteRunDetails,
|
|
1715
2514
|
{
|
|
1716
2515
|
runId: suite.lastRunId,
|
|
@@ -1721,13 +2520,13 @@ var SuiteDetailsLastRun = () => {
|
|
|
1721
2520
|
};
|
|
1722
2521
|
|
|
1723
2522
|
// src/app/views/suites/SuiteDetailsOpen.tsx
|
|
1724
|
-
import { StatusMessage as
|
|
1725
|
-
import { Spinner as
|
|
1726
|
-
import { Box as
|
|
1727
|
-
import { useEffect as
|
|
2523
|
+
import { StatusMessage as StatusMessage14 } from "@inkjs/ui";
|
|
2524
|
+
import { Spinner as Spinner13 } from "@inkjs/ui";
|
|
2525
|
+
import { Box as Box20, Text as Text20 } from "ink";
|
|
2526
|
+
import { useEffect as useEffect15 } from "react";
|
|
1728
2527
|
import { useParams as useParams6 } from "react-router";
|
|
1729
|
-
import { jsx as
|
|
1730
|
-
var WebUrlUnavailableMessage2 = () => /* @__PURE__ */
|
|
2528
|
+
import { jsx as jsx50, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
2529
|
+
var WebUrlUnavailableMessage2 = () => /* @__PURE__ */ jsx50(StatusMessage14, { variant: "warning", children: "No web URL available for this suite" });
|
|
1731
2530
|
var SuiteDetailsOpen = () => {
|
|
1732
2531
|
const { suiteId } = useParams6();
|
|
1733
2532
|
const request = useFeatureQuery(async () => {
|
|
@@ -1740,41 +2539,41 @@ var SuiteDetailsOpen = () => {
|
|
|
1740
2539
|
await openExternalUrl(url2);
|
|
1741
2540
|
return url2;
|
|
1742
2541
|
});
|
|
1743
|
-
|
|
2542
|
+
useEffect15(() => {
|
|
1744
2543
|
if (isReady && url) void openSuite(url);
|
|
1745
2544
|
}, [isReady, openSuite, url]);
|
|
1746
|
-
return /* @__PURE__ */
|
|
1747
|
-
request.isLoading && /* @__PURE__ */
|
|
1748
|
-
request.isError && /* @__PURE__ */
|
|
1749
|
-
isReady && !url && /* @__PURE__ */
|
|
1750
|
-
isReady && url && openSuiteResult.isLoading && /* @__PURE__ */
|
|
1751
|
-
isReady && url && openSuiteResult.isError && /* @__PURE__ */
|
|
1752
|
-
isReady && url && openSuiteResult.data && /* @__PURE__ */
|
|
1753
|
-
/* @__PURE__ */
|
|
1754
|
-
/* @__PURE__ */
|
|
2545
|
+
return /* @__PURE__ */ jsxs28(ViewLayout, { hintsHidden: true, children: [
|
|
2546
|
+
request.isLoading && /* @__PURE__ */ jsx50(Spinner13, { label: "Loading..." }),
|
|
2547
|
+
request.isError && /* @__PURE__ */ jsx50(Text20, { color: "red", children: request.error }),
|
|
2548
|
+
isReady && !url && /* @__PURE__ */ jsx50(WebUrlUnavailableMessage2, {}),
|
|
2549
|
+
isReady && url && openSuiteResult.isLoading && /* @__PURE__ */ jsx50(Spinner13, { label: "Opening BugBug..." }),
|
|
2550
|
+
isReady && url && openSuiteResult.isError && /* @__PURE__ */ jsx50(StatusMessage14, { variant: "error", children: openSuiteResult.error }),
|
|
2551
|
+
isReady && url && openSuiteResult.data && /* @__PURE__ */ jsxs28(Box20, { flexDirection: "column", children: [
|
|
2552
|
+
/* @__PURE__ */ jsx50(StatusMessage14, { variant: "success", children: "Opened in BugBug" }),
|
|
2553
|
+
/* @__PURE__ */ jsx50(Text20, { dimColor: true, children: openSuiteResult.data })
|
|
1755
2554
|
] })
|
|
1756
2555
|
] });
|
|
1757
2556
|
};
|
|
1758
2557
|
|
|
1759
2558
|
// src/app/views/suites/SuiteDetailsRun.tsx
|
|
1760
|
-
import { Spinner as
|
|
1761
|
-
import { useEffect as
|
|
1762
|
-
import { useLocation as useLocation10, useNavigate as
|
|
1763
|
-
import { jsx as
|
|
2559
|
+
import { Spinner as Spinner14, StatusMessage as StatusMessage15 } from "@inkjs/ui";
|
|
2560
|
+
import { useEffect as useEffect16 } from "react";
|
|
2561
|
+
import { useLocation as useLocation10, useNavigate as useNavigate12, useParams as useParams7 } from "react-router";
|
|
2562
|
+
import { jsx as jsx51, jsxs as jsxs29 } from "react/jsx-runtime";
|
|
1764
2563
|
var SuiteDetailsRun = () => {
|
|
1765
2564
|
const { suiteId } = useParams7();
|
|
1766
2565
|
const location = useLocation10();
|
|
1767
|
-
const navigate =
|
|
2566
|
+
const navigate = useNavigate12();
|
|
1768
2567
|
const state = location.state;
|
|
1769
2568
|
const title = state?.suiteName ?? suiteId;
|
|
1770
2569
|
const [runSuiteMutation, runSuiteResult] = useFeatureMutation((id) => runSuite(id, {}));
|
|
1771
|
-
|
|
2570
|
+
useEffect16(() => {
|
|
1772
2571
|
if (!suiteId) return;
|
|
1773
2572
|
const startRun = async () => {
|
|
1774
2573
|
try {
|
|
1775
2574
|
const result = await runSuiteMutation(suiteId);
|
|
1776
2575
|
if ("data" in result) {
|
|
1777
|
-
navigate(ROUTES.
|
|
2576
|
+
navigate(ROUTES.suiteRuns.details(result.data.id), { replace: true, state });
|
|
1778
2577
|
}
|
|
1779
2578
|
} catch {
|
|
1780
2579
|
}
|
|
@@ -1782,20 +2581,20 @@ var SuiteDetailsRun = () => {
|
|
|
1782
2581
|
startRun();
|
|
1783
2582
|
}, [navigate, runSuiteMutation, state, suiteId]);
|
|
1784
2583
|
if (!runSuiteResult.data) {
|
|
1785
|
-
return /* @__PURE__ */
|
|
1786
|
-
runSuiteResult.isError && /* @__PURE__ */
|
|
1787
|
-
!runSuiteResult.isError && /* @__PURE__ */
|
|
2584
|
+
return /* @__PURE__ */ jsxs29(ViewLayout, { title, hintsHidden: true, hintsPosition: "bottom", children: [
|
|
2585
|
+
runSuiteResult.isError && /* @__PURE__ */ jsx51(StatusMessage15, { variant: "error", children: runSuiteResult.error }),
|
|
2586
|
+
!runSuiteResult.isError && /* @__PURE__ */ jsx51(Spinner14, { label: "Initializing..." })
|
|
1788
2587
|
] });
|
|
1789
2588
|
}
|
|
1790
|
-
return /* @__PURE__ */
|
|
2589
|
+
return /* @__PURE__ */ jsx51(BaseSuiteRunDetails, { runId: runSuiteResult.data.id, title, menuState: state });
|
|
1791
2590
|
};
|
|
1792
2591
|
|
|
1793
2592
|
// src/app/views/suites/SuitesList.tsx
|
|
1794
|
-
import { useNavigate as
|
|
1795
|
-
import { jsx as
|
|
2593
|
+
import { useNavigate as useNavigate13 } from "react-router";
|
|
2594
|
+
import { jsx as jsx52 } from "react/jsx-runtime";
|
|
1796
2595
|
var SuitesList = () => {
|
|
1797
|
-
const navigate =
|
|
1798
|
-
return /* @__PURE__ */
|
|
2596
|
+
const navigate = useNavigate13();
|
|
2597
|
+
return /* @__PURE__ */ jsx52(
|
|
1799
2598
|
BaseSuitesList,
|
|
1800
2599
|
{
|
|
1801
2600
|
onSelectSuite: (suite) => navigate(ROUTES.suites.details(suite.id), { state: { suiteName: getSuiteName(suite) } })
|
|
@@ -1804,9 +2603,9 @@ var SuitesList = () => {
|
|
|
1804
2603
|
};
|
|
1805
2604
|
|
|
1806
2605
|
// src/app/views/suites/SuitesMenu.tsx
|
|
1807
|
-
import { jsx as
|
|
2606
|
+
import { jsx as jsx53 } from "react/jsx-runtime";
|
|
1808
2607
|
var SuitesMenu = () => {
|
|
1809
|
-
return /* @__PURE__ */
|
|
2608
|
+
return /* @__PURE__ */ jsx53(ViewLayout, { children: /* @__PURE__ */ jsx53(
|
|
1810
2609
|
MenuList,
|
|
1811
2610
|
{
|
|
1812
2611
|
options: [
|
|
@@ -1818,7 +2617,7 @@ var SuitesMenu = () => {
|
|
|
1818
2617
|
};
|
|
1819
2618
|
|
|
1820
2619
|
// src/app/views/testRuns/TestRunDebugArtifacts.tsx
|
|
1821
|
-
import { Spinner as
|
|
2620
|
+
import { Spinner as Spinner15, StatusMessage as StatusMessage16 } from "@inkjs/ui";
|
|
1822
2621
|
import { useLocation as useLocation11, useParams as useParams8 } from "react-router";
|
|
1823
2622
|
|
|
1824
2623
|
// src/app/hooks/useTestRuns.ts
|
|
@@ -1829,20 +2628,20 @@ var useTestRunDetails = (runId) => useFeatureQuery(async () => {
|
|
|
1829
2628
|
}, [runId]);
|
|
1830
2629
|
|
|
1831
2630
|
// src/app/views/testRuns/TestRunDebugArtifacts.tsx
|
|
1832
|
-
import { jsx as
|
|
1833
|
-
var ArtifactsUnavailableMessage = () => /* @__PURE__ */
|
|
2631
|
+
import { jsx as jsx54 } from "react/jsx-runtime";
|
|
2632
|
+
var ArtifactsUnavailableMessage = () => /* @__PURE__ */ jsx54(StatusMessage16, { variant: "warning", children: "No debug artifacts available" });
|
|
1834
2633
|
var DebugArtifacts = ({ runId }) => {
|
|
1835
2634
|
const request = useFeatureQuery(() => listTestRunDebugArtifacts(runId), [runId]);
|
|
1836
2635
|
if (request.isLoading) {
|
|
1837
|
-
return /* @__PURE__ */
|
|
2636
|
+
return /* @__PURE__ */ jsx54(Spinner15, { label: `Loading debug artifacts for ${runId}...` });
|
|
1838
2637
|
}
|
|
1839
2638
|
if (request.isError) {
|
|
1840
|
-
return /* @__PURE__ */
|
|
2639
|
+
return /* @__PURE__ */ jsx54(StatusMessage16, { variant: "error", children: request.error });
|
|
1841
2640
|
}
|
|
1842
2641
|
if (!request.data || request.data.length === 0) {
|
|
1843
|
-
return /* @__PURE__ */
|
|
2642
|
+
return /* @__PURE__ */ jsx54(ArtifactsUnavailableMessage, {});
|
|
1844
2643
|
}
|
|
1845
|
-
return /* @__PURE__ */
|
|
2644
|
+
return /* @__PURE__ */ jsx54(
|
|
1846
2645
|
MenuList,
|
|
1847
2646
|
{
|
|
1848
2647
|
options: request.data.map((artifact) => ({
|
|
@@ -1864,22 +2663,119 @@ var TestRunDebugArtifacts = () => {
|
|
|
1864
2663
|
const state = location.state;
|
|
1865
2664
|
const detailsRequest = useTestRunDetails(runId);
|
|
1866
2665
|
const title = detailsRequest.data ? getTestRunName(detailsRequest.data) : state?.testRunName ?? "Debug artifacts";
|
|
1867
|
-
return /* @__PURE__ */
|
|
2666
|
+
return /* @__PURE__ */ jsx54(
|
|
1868
2667
|
ViewLayout,
|
|
1869
2668
|
{
|
|
1870
2669
|
title,
|
|
1871
2670
|
hints: runId ? "navigationOpenSelect" : "none",
|
|
1872
2671
|
hintsPosition: "bottom",
|
|
1873
|
-
children: runId ? /* @__PURE__ */
|
|
2672
|
+
children: runId ? /* @__PURE__ */ jsx54(DebugArtifacts, { runId }) : /* @__PURE__ */ jsx54(ArtifactsUnavailableMessage, {})
|
|
1874
2673
|
}
|
|
1875
2674
|
);
|
|
1876
2675
|
};
|
|
1877
2676
|
|
|
1878
2677
|
// src/app/views/testRuns/TestRunDetails.tsx
|
|
1879
|
-
import { Spinner as
|
|
1880
|
-
import { Text as
|
|
2678
|
+
import { Spinner as Spinner17, StatusMessage as StatusMessage18 } from "@inkjs/ui";
|
|
2679
|
+
import { Text as Text21 } from "ink";
|
|
1881
2680
|
import { useLocation as useLocation12, useParams as useParams9 } from "react-router";
|
|
1882
|
-
|
|
2681
|
+
|
|
2682
|
+
// src/app/components/BaseTestRunDetails/BaseTestRunDetails.tsx
|
|
2683
|
+
import { Spinner as Spinner16, StatusMessage as StatusMessage17 } from "@inkjs/ui";
|
|
2684
|
+
import { Box as Box21, useApp as useApp5 } from "ink";
|
|
2685
|
+
import { useEffect as useEffect17, useState as useState18 } from "react";
|
|
2686
|
+
import { jsx as jsx55, jsxs as jsxs30 } from "react/jsx-runtime";
|
|
2687
|
+
var getMenuOptions = (runId, state) => [
|
|
2688
|
+
{
|
|
2689
|
+
label: "Show run artifacts",
|
|
2690
|
+
shortcut: "a",
|
|
2691
|
+
description: "Browse console logs and downloadable debug artifacts",
|
|
2692
|
+
to: ROUTES.testRuns.debugArtifacts(runId),
|
|
2693
|
+
state
|
|
2694
|
+
},
|
|
2695
|
+
{
|
|
2696
|
+
label: "Download JUnit report",
|
|
2697
|
+
shortcut: "j",
|
|
2698
|
+
description: "Save the JUnit XML report to the current directory",
|
|
2699
|
+
to: ROUTES.testRuns.junitReport(runId),
|
|
2700
|
+
state
|
|
2701
|
+
},
|
|
2702
|
+
{
|
|
2703
|
+
label: "Open in BugBug",
|
|
2704
|
+
shortcut: "o",
|
|
2705
|
+
description: "Open the run page in your browser",
|
|
2706
|
+
to: ROUTES.testRuns.open(runId),
|
|
2707
|
+
state
|
|
2708
|
+
}
|
|
2709
|
+
];
|
|
2710
|
+
var BaseTestRunDetails = ({
|
|
2711
|
+
runId,
|
|
2712
|
+
title,
|
|
2713
|
+
menuState,
|
|
2714
|
+
headless = false,
|
|
2715
|
+
intervalMs = 4e3,
|
|
2716
|
+
timeoutMs,
|
|
2717
|
+
exitDelayMs = 300,
|
|
2718
|
+
onComplete,
|
|
2719
|
+
onError
|
|
2720
|
+
}) => {
|
|
2721
|
+
const { exit } = useApp5();
|
|
2722
|
+
const [runState, setRunState] = useState18(null);
|
|
2723
|
+
const [error, setError] = useState18(null);
|
|
2724
|
+
useEffect17(() => {
|
|
2725
|
+
let cancelled = false;
|
|
2726
|
+
void (async () => {
|
|
2727
|
+
try {
|
|
2728
|
+
const finalStatus = await waitForTestRun(
|
|
2729
|
+
runId,
|
|
2730
|
+
intervalMs,
|
|
2731
|
+
(status) => {
|
|
2732
|
+
if (!cancelled) setRunState(status);
|
|
2733
|
+
},
|
|
2734
|
+
timeoutMs
|
|
2735
|
+
);
|
|
2736
|
+
if (!cancelled) {
|
|
2737
|
+
setRunState(finalStatus);
|
|
2738
|
+
onComplete?.(finalStatus);
|
|
2739
|
+
if (headless) setTimeout(exit, exitDelayMs);
|
|
2740
|
+
}
|
|
2741
|
+
} catch (err) {
|
|
2742
|
+
if (!cancelled) {
|
|
2743
|
+
const nextError = err instanceof Error ? err : new Error("Unknown error occurred");
|
|
2744
|
+
setError(nextError.message);
|
|
2745
|
+
onError?.(nextError);
|
|
2746
|
+
if (headless) setTimeout(exit, exitDelayMs);
|
|
2747
|
+
}
|
|
2748
|
+
}
|
|
2749
|
+
})();
|
|
2750
|
+
return () => {
|
|
2751
|
+
cancelled = true;
|
|
2752
|
+
};
|
|
2753
|
+
}, [runId, intervalMs, timeoutMs, headless, exitDelayMs, exit, onComplete, onError]);
|
|
2754
|
+
const isRunning = runState ? isRunningStatus(runState.status) : false;
|
|
2755
|
+
const isCompleted = runState ? isCompletedStatus(runState.status) : false;
|
|
2756
|
+
const body = /* @__PURE__ */ jsxs30(Box21, { flexDirection: "column", children: [
|
|
2757
|
+
error && /* @__PURE__ */ jsx55(StatusMessage17, { variant: "error", children: `Failed to complete test run: ${error}` }),
|
|
2758
|
+
!error && !runState && /* @__PURE__ */ jsx55(Spinner16, { label: "Initializing..." }),
|
|
2759
|
+
!error && runState && /* @__PURE__ */ jsx55(RunBody, { runState, isRunning })
|
|
2760
|
+
] });
|
|
2761
|
+
if (headless) return body;
|
|
2762
|
+
return /* @__PURE__ */ jsxs30(
|
|
2763
|
+
ViewLayout,
|
|
2764
|
+
{
|
|
2765
|
+
title,
|
|
2766
|
+
hints: isCompleted ? "navigationSelect" : "none",
|
|
2767
|
+
hintsHidden: !isCompleted,
|
|
2768
|
+
hintsPosition: "bottom",
|
|
2769
|
+
children: [
|
|
2770
|
+
body,
|
|
2771
|
+
isCompleted && /* @__PURE__ */ jsx55(Box21, { marginTop: 1, children: /* @__PURE__ */ jsx55(MenuList, { options: getMenuOptions(runId, menuState) }) })
|
|
2772
|
+
]
|
|
2773
|
+
}
|
|
2774
|
+
);
|
|
2775
|
+
};
|
|
2776
|
+
|
|
2777
|
+
// src/app/views/testRuns/TestRunDetails.tsx
|
|
2778
|
+
import { jsx as jsx56, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
1883
2779
|
var TestRunDetails = () => {
|
|
1884
2780
|
const { runId } = useParams9();
|
|
1885
2781
|
const location = useLocation12();
|
|
@@ -1888,33 +2784,33 @@ var TestRunDetails = () => {
|
|
|
1888
2784
|
const title = request.data ? getTestRunName(request.data) : state?.testRunName;
|
|
1889
2785
|
const menuState = title ? { testRunName: title } : void 0;
|
|
1890
2786
|
if (!request.data || !runId) {
|
|
1891
|
-
return /* @__PURE__ */
|
|
1892
|
-
request.isLoading && /* @__PURE__ */
|
|
1893
|
-
request.isError && /* @__PURE__ */
|
|
1894
|
-
!request.isLoading && !request.isError && !request.data && /* @__PURE__ */
|
|
2787
|
+
return /* @__PURE__ */ jsxs31(ViewLayout, { title, hintsHidden: true, children: [
|
|
2788
|
+
request.isLoading && /* @__PURE__ */ jsx56(Spinner17, { label: "Loading test run..." }),
|
|
2789
|
+
request.isError && /* @__PURE__ */ jsx56(StatusMessage18, { variant: "error", children: request.error }),
|
|
2790
|
+
!request.isLoading && !request.isError && !request.data && /* @__PURE__ */ jsx56(Text21, { color: "yellow", children: "Test run not found." })
|
|
1895
2791
|
] });
|
|
1896
2792
|
}
|
|
1897
|
-
return /* @__PURE__ */
|
|
2793
|
+
return /* @__PURE__ */ jsx56(BaseTestRunDetails, { runId, title, menuState });
|
|
1898
2794
|
};
|
|
1899
2795
|
|
|
1900
2796
|
// src/app/views/testRuns/TestRunJunitReport.tsx
|
|
1901
|
-
import { Spinner as
|
|
1902
|
-
import { Text as
|
|
1903
|
-
import { useEffect as
|
|
2797
|
+
import { Spinner as Spinner18, StatusMessage as StatusMessage19 } from "@inkjs/ui";
|
|
2798
|
+
import { Text as Text22 } from "ink";
|
|
2799
|
+
import { useEffect as useEffect18 } from "react";
|
|
1904
2800
|
import { useLocation as useLocation13, useParams as useParams10 } from "react-router";
|
|
1905
|
-
import { Fragment as
|
|
2801
|
+
import { Fragment as Fragment5, jsx as jsx57, jsxs as jsxs32 } from "react/jsx-runtime";
|
|
1906
2802
|
var DownloadReport = ({ runId }) => {
|
|
1907
2803
|
const [downloadReport, downloadReportResult] = useFeatureMutation(async (runId2) => {
|
|
1908
2804
|
const xml = await getTestRunJunitReport(runId2);
|
|
1909
2805
|
return writeReportXml(xml, defaultJunitReportPath("test", runId2));
|
|
1910
2806
|
});
|
|
1911
|
-
|
|
2807
|
+
useEffect18(() => {
|
|
1912
2808
|
void downloadReport(runId);
|
|
1913
2809
|
}, [downloadReport, runId]);
|
|
1914
|
-
return /* @__PURE__ */
|
|
1915
|
-
downloadReportResult.isLoading && /* @__PURE__ */
|
|
1916
|
-
downloadReportResult.isError && /* @__PURE__ */
|
|
1917
|
-
downloadReportResult.data?.outPath && /* @__PURE__ */
|
|
2810
|
+
return /* @__PURE__ */ jsxs32(Fragment5, { children: [
|
|
2811
|
+
downloadReportResult.isLoading && /* @__PURE__ */ jsx57(Spinner18, { label: "Downloading JUnit report..." }),
|
|
2812
|
+
downloadReportResult.isError && /* @__PURE__ */ jsx57(StatusMessage19, { variant: "error", children: downloadReportResult.error }),
|
|
2813
|
+
downloadReportResult.data?.outPath && /* @__PURE__ */ jsx57(StatusMessage19, { variant: "success", children: `Saved JUnit report to ${downloadReportResult.data.outPath} (${downloadReportResult.data.size} chars)` })
|
|
1918
2814
|
] });
|
|
1919
2815
|
};
|
|
1920
2816
|
var TestRunJunitReport = () => {
|
|
@@ -1923,36 +2819,36 @@ var TestRunJunitReport = () => {
|
|
|
1923
2819
|
const state = location.state;
|
|
1924
2820
|
const request = useTestRunDetails(runId);
|
|
1925
2821
|
const title = request.data ? getTestRunName(request.data) : state?.testRunName ?? runId;
|
|
1926
|
-
return /* @__PURE__ */
|
|
1927
|
-
request.isLoading && /* @__PURE__ */
|
|
1928
|
-
request.isError && /* @__PURE__ */
|
|
1929
|
-
!request.isLoading && !request.isError && runId && /* @__PURE__ */
|
|
1930
|
-
!request.isLoading && !request.isError && !runId && /* @__PURE__ */
|
|
2822
|
+
return /* @__PURE__ */ jsxs32(ViewLayout, { title, hintsHidden: true, hintsPosition: "bottom", children: [
|
|
2823
|
+
request.isLoading && /* @__PURE__ */ jsx57(Spinner18, { label: "Loading..." }),
|
|
2824
|
+
request.isError && /* @__PURE__ */ jsx57(Text22, { color: "red", children: request.error }),
|
|
2825
|
+
!request.isLoading && !request.isError && runId && /* @__PURE__ */ jsx57(DownloadReport, { runId }),
|
|
2826
|
+
!request.isLoading && !request.isError && !runId && /* @__PURE__ */ jsx57(StatusMessage19, { variant: "warning", children: "No test run selected" })
|
|
1931
2827
|
] });
|
|
1932
2828
|
};
|
|
1933
2829
|
|
|
1934
2830
|
// src/app/views/testRuns/TestRunOpen.tsx
|
|
1935
|
-
import { Spinner as
|
|
1936
|
-
import { Box as
|
|
1937
|
-
import { useEffect as
|
|
2831
|
+
import { Spinner as Spinner19, StatusMessage as StatusMessage20 } from "@inkjs/ui";
|
|
2832
|
+
import { Box as Box22, Text as Text23 } from "ink";
|
|
2833
|
+
import { useEffect as useEffect19 } from "react";
|
|
1938
2834
|
import { useLocation as useLocation14, useParams as useParams11 } from "react-router";
|
|
1939
|
-
import { Fragment as
|
|
1940
|
-
var WebUrlUnavailableMessage3 = () => /* @__PURE__ */
|
|
2835
|
+
import { Fragment as Fragment6, jsx as jsx58, jsxs as jsxs33 } from "react/jsx-runtime";
|
|
2836
|
+
var WebUrlUnavailableMessage3 = () => /* @__PURE__ */ jsx58(StatusMessage20, { variant: "warning", children: "No web URL available for this run" });
|
|
1941
2837
|
var OpenRun = ({ url }) => {
|
|
1942
2838
|
const [openRun, openRunResult] = useFeatureMutation(async (url2) => {
|
|
1943
2839
|
await openExternalUrl(url2);
|
|
1944
2840
|
return url2;
|
|
1945
2841
|
});
|
|
1946
|
-
|
|
2842
|
+
useEffect19(() => {
|
|
1947
2843
|
if (url) void openRun(url);
|
|
1948
2844
|
}, [openRun, url]);
|
|
1949
|
-
if (!url) return /* @__PURE__ */
|
|
1950
|
-
return /* @__PURE__ */
|
|
1951
|
-
openRunResult.isLoading && /* @__PURE__ */
|
|
1952
|
-
openRunResult.isError && /* @__PURE__ */
|
|
1953
|
-
openRunResult.data && /* @__PURE__ */
|
|
1954
|
-
/* @__PURE__ */
|
|
1955
|
-
/* @__PURE__ */
|
|
2845
|
+
if (!url) return /* @__PURE__ */ jsx58(WebUrlUnavailableMessage3, {});
|
|
2846
|
+
return /* @__PURE__ */ jsxs33(Fragment6, { children: [
|
|
2847
|
+
openRunResult.isLoading && /* @__PURE__ */ jsx58(Spinner19, { label: "Opening BugBug..." }),
|
|
2848
|
+
openRunResult.isError && /* @__PURE__ */ jsx58(StatusMessage20, { variant: "error", children: openRunResult.error }),
|
|
2849
|
+
openRunResult.data && /* @__PURE__ */ jsxs33(Box22, { flexDirection: "column", children: [
|
|
2850
|
+
/* @__PURE__ */ jsx58(StatusMessage20, { variant: "success", children: "Opened in BugBug" }),
|
|
2851
|
+
/* @__PURE__ */ jsx58(Text23, { dimColor: true, children: openRunResult.data })
|
|
1956
2852
|
] })
|
|
1957
2853
|
] });
|
|
1958
2854
|
};
|
|
@@ -1962,18 +2858,18 @@ var TestRunOpen = () => {
|
|
|
1962
2858
|
const state = location.state;
|
|
1963
2859
|
const request = useTestRunDetails(runId);
|
|
1964
2860
|
const title = request.data ? getTestRunName(request.data) : state?.testRunName ?? runId;
|
|
1965
|
-
return /* @__PURE__ */
|
|
1966
|
-
request.isLoading && /* @__PURE__ */
|
|
1967
|
-
request.isError && /* @__PURE__ */
|
|
1968
|
-
!request.isLoading && !request.isError && /* @__PURE__ */
|
|
2861
|
+
return /* @__PURE__ */ jsxs33(ViewLayout, { title, hintsHidden: true, hintsPosition: "bottom", children: [
|
|
2862
|
+
request.isLoading && /* @__PURE__ */ jsx58(Spinner19, { label: "Loading..." }),
|
|
2863
|
+
request.isError && /* @__PURE__ */ jsx58(Text23, { color: "red", children: request.error }),
|
|
2864
|
+
!request.isLoading && !request.isError && /* @__PURE__ */ jsx58(OpenRun, { url: request.data?.webappUrl })
|
|
1969
2865
|
] });
|
|
1970
2866
|
};
|
|
1971
2867
|
|
|
1972
2868
|
// src/app/views/testRuns/TestRunsList.tsx
|
|
1973
|
-
import { jsx as
|
|
2869
|
+
import { jsx as jsx59 } from "react/jsx-runtime";
|
|
1974
2870
|
var TestRunsList2 = () => {
|
|
1975
2871
|
const request = useTestRunsList();
|
|
1976
|
-
return /* @__PURE__ */
|
|
2872
|
+
return /* @__PURE__ */ jsx59(
|
|
1977
2873
|
TestRunsList,
|
|
1978
2874
|
{
|
|
1979
2875
|
testRuns: request.data,
|
|
@@ -1985,21 +2881,21 @@ var TestRunsList2 = () => {
|
|
|
1985
2881
|
};
|
|
1986
2882
|
|
|
1987
2883
|
// src/app/views/testRuns/TestRunsMenu.tsx
|
|
1988
|
-
import { useEffect as
|
|
1989
|
-
import { useNavigate as
|
|
2884
|
+
import { useEffect as useEffect20 } from "react";
|
|
2885
|
+
import { useNavigate as useNavigate14 } from "react-router";
|
|
1990
2886
|
var TestRunsMenu = () => {
|
|
1991
|
-
const navigate =
|
|
1992
|
-
|
|
2887
|
+
const navigate = useNavigate14();
|
|
2888
|
+
useEffect20(() => {
|
|
1993
2889
|
navigate(ROUTES.testRuns.list(), { replace: true });
|
|
1994
2890
|
}, [navigate]);
|
|
1995
2891
|
return null;
|
|
1996
2892
|
};
|
|
1997
2893
|
|
|
1998
2894
|
// src/app/views/tests/RunTest.tsx
|
|
1999
|
-
import { useNavigate as
|
|
2895
|
+
import { useNavigate as useNavigate15 } from "react-router";
|
|
2000
2896
|
|
|
2001
2897
|
// src/app/views/tests/BaseTestsList.tsx
|
|
2002
|
-
import { useState as
|
|
2898
|
+
import { useState as useState19 } from "react";
|
|
2003
2899
|
|
|
2004
2900
|
// src/app/hooks/useTests.ts
|
|
2005
2901
|
var useTestsList = (query) => useFeatureQuery(() => loadTestTableResources(query), [query]);
|
|
@@ -2009,14 +2905,14 @@ var useTestDetails = (testId) => useFeatureQuery(async () => {
|
|
|
2009
2905
|
}, [testId]);
|
|
2010
2906
|
|
|
2011
2907
|
// src/features/tests/tests.constants.tsx
|
|
2012
|
-
import { jsx as
|
|
2908
|
+
import { jsx as jsx60 } from "react/jsx-runtime";
|
|
2013
2909
|
var TEST_COLUMNS = [
|
|
2014
2910
|
{ key: "name", label: "Name", width: 42 },
|
|
2015
2911
|
{
|
|
2016
2912
|
key: "status",
|
|
2017
2913
|
label: "Status",
|
|
2018
2914
|
width: 14,
|
|
2019
|
-
render: (_cell, row, ctx) => /* @__PURE__ */
|
|
2915
|
+
render: (_cell, row, ctx) => /* @__PURE__ */ jsx60(Status, { status: row.value?.status, color: ctx.color, backgroundColor: ctx.backgroundColor })
|
|
2020
2916
|
}
|
|
2021
2917
|
];
|
|
2022
2918
|
|
|
@@ -2032,15 +2928,15 @@ var getTestRow = (test) => ({
|
|
|
2032
2928
|
var getTestName = (test) => test.name || test.id || "Untitled";
|
|
2033
2929
|
|
|
2034
2930
|
// src/app/views/tests/BaseTestsList.tsx
|
|
2035
|
-
import { jsx as
|
|
2931
|
+
import { jsx as jsx61 } from "react/jsx-runtime";
|
|
2036
2932
|
var BaseTestsList = ({
|
|
2037
2933
|
title,
|
|
2038
2934
|
emptyMessage = "No tests found",
|
|
2039
2935
|
onSelectTest
|
|
2040
2936
|
}) => {
|
|
2041
|
-
const [query, setQuery] =
|
|
2937
|
+
const [query, setQuery] = useState19("");
|
|
2042
2938
|
const request = useTestsList(query);
|
|
2043
|
-
return /* @__PURE__ */
|
|
2939
|
+
return /* @__PURE__ */ jsx61(
|
|
2044
2940
|
BaseResourceListScreen,
|
|
2045
2941
|
{
|
|
2046
2942
|
title,
|
|
@@ -2061,10 +2957,10 @@ var BaseTestsList = ({
|
|
|
2061
2957
|
};
|
|
2062
2958
|
|
|
2063
2959
|
// src/app/views/tests/RunTest.tsx
|
|
2064
|
-
import { jsx as
|
|
2960
|
+
import { jsx as jsx62 } from "react/jsx-runtime";
|
|
2065
2961
|
var RunTest = () => {
|
|
2066
|
-
const navigate =
|
|
2067
|
-
return /* @__PURE__ */
|
|
2962
|
+
const navigate = useNavigate15();
|
|
2963
|
+
return /* @__PURE__ */ jsx62(
|
|
2068
2964
|
BaseTestsList,
|
|
2069
2965
|
{
|
|
2070
2966
|
title: "Select a test to run:",
|
|
@@ -2075,10 +2971,10 @@ var RunTest = () => {
|
|
|
2075
2971
|
};
|
|
2076
2972
|
|
|
2077
2973
|
// src/app/views/tests/TestDetails.tsx
|
|
2078
|
-
import { Spinner as
|
|
2079
|
-
import { Box as
|
|
2974
|
+
import { Spinner as Spinner20, StatusMessage as StatusMessage21 } from "@inkjs/ui";
|
|
2975
|
+
import { Box as Box23 } from "ink";
|
|
2080
2976
|
import { useLocation as useLocation15, useParams as useParams12 } from "react-router";
|
|
2081
|
-
import { jsx as
|
|
2977
|
+
import { jsx as jsx63, jsxs as jsxs34 } from "react/jsx-runtime";
|
|
2082
2978
|
var TestDetails = () => {
|
|
2083
2979
|
const { testId } = useParams12();
|
|
2084
2980
|
const location = useLocation15();
|
|
@@ -2118,40 +3014,40 @@ var TestDetails = () => {
|
|
|
2118
3014
|
to: ROUTES.tests.open(testId ?? "")
|
|
2119
3015
|
}
|
|
2120
3016
|
];
|
|
2121
|
-
return /* @__PURE__ */
|
|
2122
|
-
request.isLoading && /* @__PURE__ */
|
|
2123
|
-
request.isError && /* @__PURE__ */
|
|
2124
|
-
isNotFound && /* @__PURE__ */
|
|
2125
|
-
isReady && /* @__PURE__ */
|
|
3017
|
+
return /* @__PURE__ */ jsxs34(ViewLayout, { title, hints, children: [
|
|
3018
|
+
request.isLoading && /* @__PURE__ */ jsx63(Box23, { children: /* @__PURE__ */ jsx63(Spinner20, { label: "Loading test..." }) }),
|
|
3019
|
+
request.isError && /* @__PURE__ */ jsx63(StatusMessage21, { variant: "error", children: request.error }),
|
|
3020
|
+
isNotFound && /* @__PURE__ */ jsx63(StatusMessage21, { variant: "warning", children: "Test not found." }),
|
|
3021
|
+
isReady && /* @__PURE__ */ jsx63(MenuList, { options })
|
|
2126
3022
|
] });
|
|
2127
3023
|
};
|
|
2128
3024
|
|
|
2129
3025
|
// src/app/views/tests/TestDetailsExport.tsx
|
|
2130
|
-
import { StatusMessage as
|
|
2131
|
-
import { Spinner as
|
|
2132
|
-
import { useEffect as
|
|
3026
|
+
import { StatusMessage as StatusMessage22 } from "@inkjs/ui";
|
|
3027
|
+
import { Spinner as Spinner21 } from "@inkjs/ui";
|
|
3028
|
+
import { useEffect as useEffect21 } from "react";
|
|
2133
3029
|
import { useParams as useParams13 } from "react-router";
|
|
2134
|
-
import { jsx as
|
|
3030
|
+
import { jsx as jsx64, jsxs as jsxs35 } from "react/jsx-runtime";
|
|
2135
3031
|
var TestDetailsExport = () => {
|
|
2136
3032
|
const { testId } = useParams13();
|
|
2137
3033
|
const [exportTestMutation, exportTestResult] = useFeatureMutation(
|
|
2138
3034
|
(id) => exportTest(id, "yaml")
|
|
2139
3035
|
);
|
|
2140
|
-
|
|
3036
|
+
useEffect21(() => {
|
|
2141
3037
|
if (testId) void exportTestMutation(testId);
|
|
2142
3038
|
}, [exportTestMutation, testId]);
|
|
2143
|
-
return /* @__PURE__ */
|
|
2144
|
-
exportTestResult.isLoading && /* @__PURE__ */
|
|
2145
|
-
exportTestResult.isError && /* @__PURE__ */
|
|
2146
|
-
exportTestResult.data && /* @__PURE__ */
|
|
3039
|
+
return /* @__PURE__ */ jsxs35(ViewLayout, { hintsHidden: true, children: [
|
|
3040
|
+
exportTestResult.isLoading && /* @__PURE__ */ jsx64(Spinner21, { label: `Exporting ${testId}...` }),
|
|
3041
|
+
exportTestResult.isError && /* @__PURE__ */ jsx64(StatusMessage22, { variant: "error", children: exportTestResult.error }),
|
|
3042
|
+
exportTestResult.data && /* @__PURE__ */ jsx64(StatusMessage22, { variant: "success", children: `Exported to ${exportTestResult.data.outPath} (${exportTestResult.data.size} chars)` })
|
|
2147
3043
|
] });
|
|
2148
3044
|
};
|
|
2149
3045
|
|
|
2150
3046
|
// src/app/views/tests/TestDetailsLastRun.tsx
|
|
2151
|
-
import { Spinner as
|
|
2152
|
-
import { Text as
|
|
3047
|
+
import { Spinner as Spinner22, StatusMessage as StatusMessage23 } from "@inkjs/ui";
|
|
3048
|
+
import { Text as Text24 } from "ink";
|
|
2153
3049
|
import { useLocation as useLocation16, useParams as useParams14 } from "react-router";
|
|
2154
|
-
import { jsx as
|
|
3050
|
+
import { jsx as jsx65, jsxs as jsxs36 } from "react/jsx-runtime";
|
|
2155
3051
|
var TestDetailsLastRun = () => {
|
|
2156
3052
|
const { testId } = useParams14();
|
|
2157
3053
|
const location = useLocation16();
|
|
@@ -2161,23 +3057,23 @@ var TestDetailsLastRun = () => {
|
|
|
2161
3057
|
const isReady = !request.isLoading && !request.isError;
|
|
2162
3058
|
const title = test ? getTestName(test) : state?.testName ?? testId;
|
|
2163
3059
|
if (!isReady || !test?.lastRunId) {
|
|
2164
|
-
return /* @__PURE__ */
|
|
2165
|
-
request.isLoading && /* @__PURE__ */
|
|
2166
|
-
request.isError && /* @__PURE__ */
|
|
2167
|
-
isReady && !test?.lastRunId && /* @__PURE__ */
|
|
3060
|
+
return /* @__PURE__ */ jsxs36(ViewLayout, { title, hintsHidden: true, hintsPosition: "bottom", children: [
|
|
3061
|
+
request.isLoading && /* @__PURE__ */ jsx65(Spinner22, { label: "Loading..." }),
|
|
3062
|
+
request.isError && /* @__PURE__ */ jsx65(Text24, { color: "red", children: request.error }),
|
|
3063
|
+
isReady && !test?.lastRunId && /* @__PURE__ */ jsx65(StatusMessage23, { variant: "warning", children: `No previous run found for ${test ? getTestName(test) : testId ?? "test"}` })
|
|
2168
3064
|
] });
|
|
2169
3065
|
}
|
|
2170
|
-
return /* @__PURE__ */
|
|
3066
|
+
return /* @__PURE__ */ jsx65(BaseTestRunDetails, { runId: test.lastRunId, title, menuState: { testRunName: title } });
|
|
2171
3067
|
};
|
|
2172
3068
|
|
|
2173
3069
|
// src/app/views/tests/TestDetailsOpen.tsx
|
|
2174
|
-
import { StatusMessage as
|
|
2175
|
-
import { Spinner as
|
|
2176
|
-
import { Box as
|
|
2177
|
-
import { useEffect as
|
|
3070
|
+
import { StatusMessage as StatusMessage24 } from "@inkjs/ui";
|
|
3071
|
+
import { Spinner as Spinner23 } from "@inkjs/ui";
|
|
3072
|
+
import { Box as Box24, Text as Text25 } from "ink";
|
|
3073
|
+
import { useEffect as useEffect22 } from "react";
|
|
2178
3074
|
import { useParams as useParams15 } from "react-router";
|
|
2179
|
-
import { jsx as
|
|
2180
|
-
var WebUrlUnavailableMessage4 = () => /* @__PURE__ */
|
|
3075
|
+
import { jsx as jsx66, jsxs as jsxs37 } from "react/jsx-runtime";
|
|
3076
|
+
var WebUrlUnavailableMessage4 = () => /* @__PURE__ */ jsx66(StatusMessage24, { variant: "warning", children: "No web URL available for this test" });
|
|
2181
3077
|
var TestDetailsOpen = () => {
|
|
2182
3078
|
const { testId } = useParams15();
|
|
2183
3079
|
const request = useFeatureQuery(async () => {
|
|
@@ -2190,41 +3086,41 @@ var TestDetailsOpen = () => {
|
|
|
2190
3086
|
await openExternalUrl(url2);
|
|
2191
3087
|
return url2;
|
|
2192
3088
|
});
|
|
2193
|
-
|
|
3089
|
+
useEffect22(() => {
|
|
2194
3090
|
if (isReady && url) void openTest(url);
|
|
2195
3091
|
}, [isReady, openTest, url]);
|
|
2196
|
-
return /* @__PURE__ */
|
|
2197
|
-
request.isLoading && /* @__PURE__ */
|
|
2198
|
-
request.isError && /* @__PURE__ */
|
|
2199
|
-
isReady && !url && /* @__PURE__ */
|
|
2200
|
-
isReady && url && openTestResult.isLoading && /* @__PURE__ */
|
|
2201
|
-
isReady && url && openTestResult.isError && /* @__PURE__ */
|
|
2202
|
-
isReady && url && openTestResult.data && /* @__PURE__ */
|
|
2203
|
-
/* @__PURE__ */
|
|
2204
|
-
/* @__PURE__ */
|
|
3092
|
+
return /* @__PURE__ */ jsxs37(ViewLayout, { hintsHidden: true, children: [
|
|
3093
|
+
request.isLoading && /* @__PURE__ */ jsx66(Spinner23, { label: "Loading..." }),
|
|
3094
|
+
request.isError && /* @__PURE__ */ jsx66(Text25, { color: "red", children: request.error }),
|
|
3095
|
+
isReady && !url && /* @__PURE__ */ jsx66(WebUrlUnavailableMessage4, {}),
|
|
3096
|
+
isReady && url && openTestResult.isLoading && /* @__PURE__ */ jsx66(Spinner23, { label: "Opening BugBug..." }),
|
|
3097
|
+
isReady && url && openTestResult.isError && /* @__PURE__ */ jsx66(StatusMessage24, { variant: "error", children: openTestResult.error }),
|
|
3098
|
+
isReady && url && openTestResult.data && /* @__PURE__ */ jsxs37(Box24, { flexDirection: "column", children: [
|
|
3099
|
+
/* @__PURE__ */ jsx66(StatusMessage24, { variant: "success", children: "Opened in BugBug" }),
|
|
3100
|
+
/* @__PURE__ */ jsx66(Text25, { dimColor: true, children: openTestResult.data })
|
|
2205
3101
|
] })
|
|
2206
3102
|
] });
|
|
2207
3103
|
};
|
|
2208
3104
|
|
|
2209
3105
|
// src/app/views/tests/TestDetailsRun.tsx
|
|
2210
|
-
import { Spinner as
|
|
2211
|
-
import { useEffect as
|
|
2212
|
-
import { useLocation as useLocation17, useNavigate as
|
|
2213
|
-
import { jsx as
|
|
3106
|
+
import { Spinner as Spinner24, StatusMessage as StatusMessage25 } from "@inkjs/ui";
|
|
3107
|
+
import { useEffect as useEffect23 } from "react";
|
|
3108
|
+
import { useLocation as useLocation17, useNavigate as useNavigate16, useParams as useParams16 } from "react-router";
|
|
3109
|
+
import { jsx as jsx67, jsxs as jsxs38 } from "react/jsx-runtime";
|
|
2214
3110
|
var TestDetailsRun = () => {
|
|
2215
3111
|
const { testId } = useParams16();
|
|
2216
3112
|
const location = useLocation17();
|
|
2217
|
-
const navigate =
|
|
3113
|
+
const navigate = useNavigate16();
|
|
2218
3114
|
const state = location.state;
|
|
2219
3115
|
const title = state?.testName ?? testId;
|
|
2220
3116
|
const [runTestMutation, runTestResult] = useFeatureMutation((id) => runTest(id, {}));
|
|
2221
|
-
|
|
3117
|
+
useEffect23(() => {
|
|
2222
3118
|
if (!testId) return;
|
|
2223
3119
|
const startRun = async () => {
|
|
2224
3120
|
try {
|
|
2225
3121
|
const result = await runTestMutation(testId);
|
|
2226
3122
|
if ("data" in result) {
|
|
2227
|
-
navigate(ROUTES.
|
|
3123
|
+
navigate(ROUTES.testRuns.details(result.data.id), { replace: true, state });
|
|
2228
3124
|
}
|
|
2229
3125
|
} catch {
|
|
2230
3126
|
}
|
|
@@ -2232,23 +3128,23 @@ var TestDetailsRun = () => {
|
|
|
2232
3128
|
startRun();
|
|
2233
3129
|
}, [navigate, runTestMutation, state, testId]);
|
|
2234
3130
|
if (!runTestResult.data) {
|
|
2235
|
-
return /* @__PURE__ */
|
|
2236
|
-
runTestResult.isError && /* @__PURE__ */
|
|
2237
|
-
!runTestResult.isError && /* @__PURE__ */
|
|
3131
|
+
return /* @__PURE__ */ jsxs38(ViewLayout, { title, hintsHidden: true, hintsPosition: "bottom", children: [
|
|
3132
|
+
runTestResult.isError && /* @__PURE__ */ jsx67(StatusMessage25, { variant: "error", children: runTestResult.error }),
|
|
3133
|
+
!runTestResult.isError && /* @__PURE__ */ jsx67(Spinner24, { label: "Initializing..." })
|
|
2238
3134
|
] });
|
|
2239
3135
|
}
|
|
2240
|
-
return /* @__PURE__ */
|
|
3136
|
+
return /* @__PURE__ */ jsx67(BaseTestRunDetails, { runId: runTestResult.data.id, title, menuState: state });
|
|
2241
3137
|
};
|
|
2242
3138
|
|
|
2243
3139
|
// src/app/views/tests/TestImport.tsx
|
|
2244
|
-
import { Spinner as
|
|
2245
|
-
import { useEffect as
|
|
2246
|
-
import { useNavigate as
|
|
2247
|
-
import { jsx as
|
|
3140
|
+
import { Spinner as Spinner25, StatusMessage as StatusMessage26 } from "@inkjs/ui";
|
|
3141
|
+
import { useEffect as useEffect24, useState as useState20 } from "react";
|
|
3142
|
+
import { useNavigate as useNavigate17 } from "react-router";
|
|
3143
|
+
import { jsx as jsx68, jsxs as jsxs39 } from "react/jsx-runtime";
|
|
2248
3144
|
var TestImport = ({ initialDirectory } = {}) => {
|
|
2249
|
-
const navigate =
|
|
2250
|
-
const [file, setFile] =
|
|
2251
|
-
const [conflictMode, setConflictMode] =
|
|
3145
|
+
const navigate = useNavigate17();
|
|
3146
|
+
const [file, setFile] = useState20(null);
|
|
3147
|
+
const [conflictMode, setConflictMode] = useState20(null);
|
|
2252
3148
|
const [importTestMutation, importTestResult] = useFeatureMutation(
|
|
2253
3149
|
async ({ file: file2, conflictMode: conflictMode2 }) => {
|
|
2254
3150
|
detectFormat(file2);
|
|
@@ -2257,7 +3153,7 @@ var TestImport = ({ initialDirectory } = {}) => {
|
|
|
2257
3153
|
});
|
|
2258
3154
|
}
|
|
2259
3155
|
);
|
|
2260
|
-
|
|
3156
|
+
useEffect24(() => {
|
|
2261
3157
|
if (file && conflictMode !== null) {
|
|
2262
3158
|
void importTestMutation({ file, conflictMode });
|
|
2263
3159
|
}
|
|
@@ -2268,7 +3164,7 @@ var TestImport = ({ initialDirectory } = {}) => {
|
|
|
2268
3164
|
return true;
|
|
2269
3165
|
});
|
|
2270
3166
|
if (!file) {
|
|
2271
|
-
return /* @__PURE__ */
|
|
3167
|
+
return /* @__PURE__ */ jsx68(
|
|
2272
3168
|
FilePicker,
|
|
2273
3169
|
{
|
|
2274
3170
|
label: "Select .yaml/.yml/.zip file",
|
|
@@ -2280,7 +3176,7 @@ var TestImport = ({ initialDirectory } = {}) => {
|
|
|
2280
3176
|
);
|
|
2281
3177
|
}
|
|
2282
3178
|
if (conflictMode === null) {
|
|
2283
|
-
return /* @__PURE__ */
|
|
3179
|
+
return /* @__PURE__ */ jsx68(ViewLayout, { title: "Conflict mode (blank = API default)", children: /* @__PURE__ */ jsx68(
|
|
2284
3180
|
MenuList,
|
|
2285
3181
|
{
|
|
2286
3182
|
options: [
|
|
@@ -2291,19 +3187,19 @@ var TestImport = ({ initialDirectory } = {}) => {
|
|
|
2291
3187
|
}
|
|
2292
3188
|
) });
|
|
2293
3189
|
}
|
|
2294
|
-
return /* @__PURE__ */
|
|
2295
|
-
importTestResult.isLoading && /* @__PURE__ */
|
|
2296
|
-
importTestResult.isError && /* @__PURE__ */
|
|
2297
|
-
importTestResult.data && /* @__PURE__ */
|
|
3190
|
+
return /* @__PURE__ */ jsxs39(ViewLayout, { hintsHidden: true, hintsPosition: "bottom", children: [
|
|
3191
|
+
importTestResult.isLoading && /* @__PURE__ */ jsx68(Spinner25, { label: `Importing ${file}...` }),
|
|
3192
|
+
importTestResult.isError && /* @__PURE__ */ jsx68(StatusMessage26, { variant: "error", children: importTestResult.error }),
|
|
3193
|
+
importTestResult.data && /* @__PURE__ */ jsx68(StatusMessage26, { variant: "success", children: `Imported test: ${importTestResult.data.id ?? "(unknown)"}${importTestResult.data.name ? ` (${importTestResult.data.name})` : ""}` })
|
|
2298
3194
|
] });
|
|
2299
3195
|
};
|
|
2300
3196
|
|
|
2301
3197
|
// src/app/views/tests/TestsList.tsx
|
|
2302
|
-
import { useNavigate as
|
|
2303
|
-
import { jsx as
|
|
3198
|
+
import { useNavigate as useNavigate18 } from "react-router";
|
|
3199
|
+
import { jsx as jsx69 } from "react/jsx-runtime";
|
|
2304
3200
|
var TestsList = () => {
|
|
2305
|
-
const navigate =
|
|
2306
|
-
return /* @__PURE__ */
|
|
3201
|
+
const navigate = useNavigate18();
|
|
3202
|
+
return /* @__PURE__ */ jsx69(
|
|
2307
3203
|
BaseTestsList,
|
|
2308
3204
|
{
|
|
2309
3205
|
onSelectTest: (test) => navigate(ROUTES.tests.details(test.id), { state: { testName: getTestName(test) } })
|
|
@@ -2312,9 +3208,9 @@ var TestsList = () => {
|
|
|
2312
3208
|
};
|
|
2313
3209
|
|
|
2314
3210
|
// src/app/views/tests/TestsMenu.tsx
|
|
2315
|
-
import { jsx as
|
|
3211
|
+
import { jsx as jsx70 } from "react/jsx-runtime";
|
|
2316
3212
|
var TestsMenu = () => {
|
|
2317
|
-
return /* @__PURE__ */
|
|
3213
|
+
return /* @__PURE__ */ jsx70(ViewLayout, { children: /* @__PURE__ */ jsx70(
|
|
2318
3214
|
MenuList,
|
|
2319
3215
|
{
|
|
2320
3216
|
options: [
|
|
@@ -2332,7 +3228,7 @@ var TestsMenu = () => {
|
|
|
2332
3228
|
};
|
|
2333
3229
|
|
|
2334
3230
|
// src/app/router.tsx
|
|
2335
|
-
import { jsx as
|
|
3231
|
+
import { jsx as jsx71, jsxs as jsxs40 } from "react/jsx-runtime";
|
|
2336
3232
|
var createNavigatorRouter = ({
|
|
2337
3233
|
initialRoute,
|
|
2338
3234
|
initialRouteState
|
|
@@ -2347,45 +3243,45 @@ var createNavigatorRouter = ({
|
|
|
2347
3243
|
const initialEntries = getInitialEntries();
|
|
2348
3244
|
const router = createMemoryRouter(
|
|
2349
3245
|
createRoutesFromElements(
|
|
2350
|
-
/* @__PURE__ */
|
|
2351
|
-
/* @__PURE__ */
|
|
2352
|
-
/* @__PURE__ */
|
|
2353
|
-
/* @__PURE__ */
|
|
2354
|
-
/* @__PURE__ */
|
|
2355
|
-
/* @__PURE__ */
|
|
2356
|
-
/* @__PURE__ */
|
|
2357
|
-
/* @__PURE__ */
|
|
2358
|
-
/* @__PURE__ */
|
|
2359
|
-
/* @__PURE__ */
|
|
2360
|
-
/* @__PURE__ */
|
|
2361
|
-
/* @__PURE__ */
|
|
2362
|
-
/* @__PURE__ */
|
|
2363
|
-
/* @__PURE__ */
|
|
2364
|
-
/* @__PURE__ */
|
|
2365
|
-
/* @__PURE__ */
|
|
2366
|
-
/* @__PURE__ */
|
|
2367
|
-
/* @__PURE__ */
|
|
2368
|
-
/* @__PURE__ */
|
|
2369
|
-
/* @__PURE__ */
|
|
2370
|
-
/* @__PURE__ */
|
|
2371
|
-
/* @__PURE__ */
|
|
2372
|
-
/* @__PURE__ */
|
|
2373
|
-
/* @__PURE__ */
|
|
2374
|
-
/* @__PURE__ */
|
|
2375
|
-
/* @__PURE__ */
|
|
2376
|
-
/* @__PURE__ */
|
|
2377
|
-
/* @__PURE__ */
|
|
2378
|
-
/* @__PURE__ */
|
|
2379
|
-
/* @__PURE__ */
|
|
2380
|
-
/* @__PURE__ */
|
|
2381
|
-
/* @__PURE__ */
|
|
2382
|
-
/* @__PURE__ */
|
|
2383
|
-
/* @__PURE__ */
|
|
2384
|
-
/* @__PURE__ */
|
|
2385
|
-
/* @__PURE__ */
|
|
2386
|
-
/* @__PURE__ */
|
|
2387
|
-
/* @__PURE__ */
|
|
2388
|
-
/* @__PURE__ */
|
|
3246
|
+
/* @__PURE__ */ jsxs40(Route, { element: /* @__PURE__ */ jsx71(Navigator, {}), children: [
|
|
3247
|
+
/* @__PURE__ */ jsx71(Route, { index: true, element: /* @__PURE__ */ jsx71(MainMenu, {}) }),
|
|
3248
|
+
/* @__PURE__ */ jsx71(Route, { path: "/init", element: /* @__PURE__ */ jsx71(ProjectInit, {}) }),
|
|
3249
|
+
/* @__PURE__ */ jsx71(Route, { path: "/tests", element: /* @__PURE__ */ jsx71(TestsMenu, {}) }),
|
|
3250
|
+
/* @__PURE__ */ jsx71(Route, { path: "/tests/list", element: /* @__PURE__ */ jsx71(TestsList, {}) }),
|
|
3251
|
+
/* @__PURE__ */ jsx71(Route, { path: "/tests/import", element: /* @__PURE__ */ jsx71(TestImport, {}) }),
|
|
3252
|
+
/* @__PURE__ */ jsx71(Route, { path: "/tests/run", element: /* @__PURE__ */ jsx71(RunTest, {}) }),
|
|
3253
|
+
/* @__PURE__ */ jsx71(Route, { path: "/tests/:testId", element: /* @__PURE__ */ jsx71(TestDetails, {}) }),
|
|
3254
|
+
/* @__PURE__ */ jsx71(Route, { path: "/tests/:testId/run", element: /* @__PURE__ */ jsx71(TestDetailsRun, {}) }),
|
|
3255
|
+
/* @__PURE__ */ jsx71(Route, { path: "/tests/:testId/lastRun", element: /* @__PURE__ */ jsx71(TestDetailsLastRun, {}) }),
|
|
3256
|
+
/* @__PURE__ */ jsx71(Route, { path: "/tests/:testId/export", element: /* @__PURE__ */ jsx71(TestDetailsExport, {}) }),
|
|
3257
|
+
/* @__PURE__ */ jsx71(Route, { path: "/tests/:testId/open", element: /* @__PURE__ */ jsx71(TestDetailsOpen, {}) }),
|
|
3258
|
+
/* @__PURE__ */ jsx71(Route, { path: "/testruns", element: /* @__PURE__ */ jsx71(TestRunsMenu, {}) }),
|
|
3259
|
+
/* @__PURE__ */ jsx71(Route, { path: "/testruns/list", element: /* @__PURE__ */ jsx71(TestRunsList2, {}) }),
|
|
3260
|
+
/* @__PURE__ */ jsx71(Route, { path: "/testruns/:runId", element: /* @__PURE__ */ jsx71(TestRunDetails, {}) }),
|
|
3261
|
+
/* @__PURE__ */ jsx71(Route, { path: "/testruns/:runId/debugArtifacts", element: /* @__PURE__ */ jsx71(TestRunDebugArtifacts, {}) }),
|
|
3262
|
+
/* @__PURE__ */ jsx71(Route, { path: "/testruns/:runId/junitReport", element: /* @__PURE__ */ jsx71(TestRunJunitReport, {}) }),
|
|
3263
|
+
/* @__PURE__ */ jsx71(Route, { path: "/testruns/:runId/open", element: /* @__PURE__ */ jsx71(TestRunOpen, {}) }),
|
|
3264
|
+
/* @__PURE__ */ jsx71(Route, { path: "/suites", element: /* @__PURE__ */ jsx71(SuitesMenu, {}) }),
|
|
3265
|
+
/* @__PURE__ */ jsx71(Route, { path: "/suites/list", element: /* @__PURE__ */ jsx71(SuitesList, {}) }),
|
|
3266
|
+
/* @__PURE__ */ jsx71(Route, { path: "/suites/run", element: /* @__PURE__ */ jsx71(RunSuite, {}) }),
|
|
3267
|
+
/* @__PURE__ */ jsx71(Route, { path: "/suites/:suiteId", element: /* @__PURE__ */ jsx71(SuiteDetails, {}) }),
|
|
3268
|
+
/* @__PURE__ */ jsx71(Route, { path: "/suites/:suiteId/run", element: /* @__PURE__ */ jsx71(SuiteDetailsRun, {}) }),
|
|
3269
|
+
/* @__PURE__ */ jsx71(Route, { path: "/suites/:suiteId/lastRun", element: /* @__PURE__ */ jsx71(SuiteDetailsLastRun, {}) }),
|
|
3270
|
+
/* @__PURE__ */ jsx71(Route, { path: "/suites/:suiteId/open", element: /* @__PURE__ */ jsx71(SuiteDetailsOpen, {}) }),
|
|
3271
|
+
/* @__PURE__ */ jsx71(Route, { path: "/suiteruns", element: /* @__PURE__ */ jsx71(SuiteRunsMenu, {}) }),
|
|
3272
|
+
/* @__PURE__ */ jsx71(Route, { path: "/suiteruns/list", element: /* @__PURE__ */ jsx71(SuiteRunsList, {}) }),
|
|
3273
|
+
/* @__PURE__ */ jsx71(Route, { path: "/suiteruns/:runId", element: /* @__PURE__ */ jsx71(SuiteRunDetails, {}) }),
|
|
3274
|
+
/* @__PURE__ */ jsx71(Route, { path: "/suiteruns/:runId/showTestRuns", element: /* @__PURE__ */ jsx71(SuiteRunShowTestRuns, {}) }),
|
|
3275
|
+
/* @__PURE__ */ jsx71(Route, { path: "/suiteruns/:runId/open", element: /* @__PURE__ */ jsx71(SuiteRunOpen, {}) }),
|
|
3276
|
+
/* @__PURE__ */ jsx71(Route, { path: "/profiles", element: /* @__PURE__ */ jsx71(ProfilesMenu, {}) }),
|
|
3277
|
+
/* @__PURE__ */ jsx71(Route, { path: "/profiles/list", element: /* @__PURE__ */ jsx71(ProfilesList, {}) }),
|
|
3278
|
+
/* @__PURE__ */ jsx71(Route, { path: "/project", element: /* @__PURE__ */ jsx71(ProjectMenu, {}) }),
|
|
3279
|
+
/* @__PURE__ */ jsx71(Route, { path: "/project/switch", element: /* @__PURE__ */ jsx71(ProjectSwitch, {}) }),
|
|
3280
|
+
/* @__PURE__ */ jsx71(Route, { path: "/project/export", element: /* @__PURE__ */ jsx71(ProjectExport, {}) }),
|
|
3281
|
+
/* @__PURE__ */ jsx71(Route, { path: "/project/import", element: /* @__PURE__ */ jsx71(ProjectImport, {}) }),
|
|
3282
|
+
/* @__PURE__ */ jsx71(Route, { path: "/settings", element: /* @__PURE__ */ jsx71(SettingsMenu, {}) }),
|
|
3283
|
+
/* @__PURE__ */ jsx71(Route, { path: "/settings/setSessionToken", element: /* @__PURE__ */ jsx71(SettingsSetSessionToken, {}) }),
|
|
3284
|
+
/* @__PURE__ */ jsx71(Route, { path: "/logout", element: /* @__PURE__ */ jsx71(Logout, {}) })
|
|
2389
3285
|
] })
|
|
2390
3286
|
),
|
|
2391
3287
|
{ initialEntries, initialIndex: initialEntries.length - 1 }
|
|
@@ -2394,12 +3290,12 @@ var createNavigatorRouter = ({
|
|
|
2394
3290
|
};
|
|
2395
3291
|
|
|
2396
3292
|
// src/app/NavigatorApp.tsx
|
|
2397
|
-
import { jsx as
|
|
3293
|
+
import { jsx as jsx72 } from "react/jsx-runtime";
|
|
2398
3294
|
var NavigatorApp = ({ initialRoute, initialRouteState }) => {
|
|
2399
|
-
const [router] =
|
|
2400
|
-
return /* @__PURE__ */
|
|
3295
|
+
const [router] = useState21(() => createNavigatorRouter({ initialRoute, initialRouteState }));
|
|
3296
|
+
return /* @__PURE__ */ jsx72(NavigatorSessionProvider, { children: /* @__PURE__ */ jsx72(RouterProvider, { router }) });
|
|
2401
3297
|
};
|
|
2402
3298
|
export {
|
|
2403
3299
|
NavigatorApp
|
|
2404
3300
|
};
|
|
2405
|
-
//# sourceMappingURL=NavigatorApp-
|
|
3301
|
+
//# sourceMappingURL=NavigatorApp-3SRWEK5J.js.map
|