@tangle-network/sandbox-ui 0.22.1 → 0.23.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets.d.ts +276 -0
- package/dist/assets.js +946 -0
- package/dist/{chunk-7X2DHDQ6.js → chunk-CB3KBKYN.js} +546 -425
- package/dist/dashboard.d.ts +95 -4
- package/dist/dashboard.js +3 -1
- package/dist/globals.css +102 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +3 -1
- package/dist/styles.css +102 -0
- package/package.json +5 -1
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
} from "./chunk-EI44GEQ5.js";
|
|
8
8
|
|
|
9
9
|
// src/dashboard/app-sidebar.tsx
|
|
10
|
+
import * as React2 from "react";
|
|
10
11
|
import { Avatar, AvatarFallback, AvatarImage } from "@tangle-network/ui/primitives";
|
|
11
12
|
import {
|
|
12
13
|
DropdownMenu,
|
|
@@ -27,6 +28,7 @@ var SIDEBAR_RAIL_WIDTH = 64;
|
|
|
27
28
|
var SIDEBAR_PANEL_WIDTH = 260;
|
|
28
29
|
var SIDEBAR_TOTAL_WIDTH = SIDEBAR_RAIL_WIDTH + SIDEBAR_PANEL_WIDTH;
|
|
29
30
|
var SIDEBAR_MOBILE_WIDTH = 256;
|
|
31
|
+
var SIDEBAR_RAIL_LABELED_WIDTH = 224;
|
|
30
32
|
var SidebarContext = React.createContext(null);
|
|
31
33
|
function readStorage(key, fallback) {
|
|
32
34
|
if (typeof window === "undefined") return fallback;
|
|
@@ -47,49 +49,44 @@ function SidebarProvider({
|
|
|
47
49
|
defaultPanelOpen = true,
|
|
48
50
|
defaultMode = "projects",
|
|
49
51
|
hasPanels = true,
|
|
52
|
+
railWidth = SIDEBAR_RAIL_WIDTH,
|
|
53
|
+
panelOpen: controlledPanelOpen,
|
|
54
|
+
onPanelOpenChange,
|
|
50
55
|
children
|
|
51
56
|
}) {
|
|
52
|
-
const
|
|
53
|
-
|
|
57
|
+
const isControlled = controlledPanelOpen !== void 0;
|
|
58
|
+
const [uncontrolledPanelOpen, setUncontrolledPanelOpen] = React.useState(
|
|
59
|
+
() => isControlled ? controlledPanelOpen : readStorage(PANEL_OPEN_KEY, String(defaultPanelOpen)) === "true"
|
|
54
60
|
);
|
|
61
|
+
const panelOpen = isControlled ? controlledPanelOpen : uncontrolledPanelOpen;
|
|
55
62
|
const [mode, setModeState] = React.useState(
|
|
56
|
-
() => readStorage(SIDEBAR_MODE_KEY, defaultMode)
|
|
63
|
+
() => isControlled ? defaultMode : readStorage(SIDEBAR_MODE_KEY, defaultMode)
|
|
57
64
|
);
|
|
58
65
|
const [hidden, setHidden] = React.useState(false);
|
|
59
66
|
const setPanelOpen = React.useCallback((open) => {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
67
|
+
if (!isControlled) {
|
|
68
|
+
setUncontrolledPanelOpen(open);
|
|
69
|
+
writeStorage(PANEL_OPEN_KEY, String(open));
|
|
70
|
+
}
|
|
71
|
+
onPanelOpenChange?.(open);
|
|
72
|
+
}, [isControlled, onPanelOpenChange]);
|
|
63
73
|
const togglePanel = React.useCallback(() => {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
writeStorage(PANEL_OPEN_KEY, String(next));
|
|
67
|
-
return next;
|
|
68
|
-
});
|
|
69
|
-
}, []);
|
|
74
|
+
setPanelOpen(!panelOpen);
|
|
75
|
+
}, [setPanelOpen, panelOpen]);
|
|
70
76
|
const setMode = React.useCallback((m) => {
|
|
71
77
|
setModeState(m);
|
|
72
|
-
writeStorage(SIDEBAR_MODE_KEY, m);
|
|
73
|
-
}, []);
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
setPanelOpenState(() => {
|
|
85
|
-
writeStorage(PANEL_OPEN_KEY, "true");
|
|
86
|
-
return true;
|
|
87
|
-
});
|
|
88
|
-
writeStorage(SIDEBAR_MODE_KEY, m);
|
|
89
|
-
return m;
|
|
90
|
-
});
|
|
91
|
-
}, []);
|
|
92
|
-
const contentMargin = hidden ? 0 : panelOpen && hasPanels ? SIDEBAR_TOTAL_WIDTH : SIDEBAR_RAIL_WIDTH;
|
|
78
|
+
if (!isControlled) writeStorage(SIDEBAR_MODE_KEY, m);
|
|
79
|
+
}, [isControlled]);
|
|
80
|
+
const switchMode = React.useCallback((m) => {
|
|
81
|
+
if (mode === m) {
|
|
82
|
+
setPanelOpen(!panelOpen);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
setModeState(m);
|
|
86
|
+
if (!isControlled) writeStorage(SIDEBAR_MODE_KEY, m);
|
|
87
|
+
setPanelOpen(true);
|
|
88
|
+
}, [mode, panelOpen, isControlled, setPanelOpen]);
|
|
89
|
+
const contentMargin = hidden ? 0 : panelOpen && hasPanels ? railWidth + SIDEBAR_PANEL_WIDTH : railWidth;
|
|
93
90
|
const value = React.useMemo(
|
|
94
91
|
() => ({
|
|
95
92
|
panelOpen,
|
|
@@ -97,13 +94,14 @@ function SidebarProvider({
|
|
|
97
94
|
togglePanel,
|
|
98
95
|
mode,
|
|
99
96
|
setMode,
|
|
100
|
-
switchMode
|
|
97
|
+
switchMode,
|
|
101
98
|
hidden,
|
|
102
99
|
setHidden,
|
|
103
100
|
contentMargin,
|
|
104
|
-
hasPanels
|
|
101
|
+
hasPanels,
|
|
102
|
+
railWidth
|
|
105
103
|
}),
|
|
106
|
-
[panelOpen, setPanelOpen, togglePanel, mode, setMode,
|
|
104
|
+
[panelOpen, setPanelOpen, togglePanel, mode, setMode, switchMode, hidden, setHidden, contentMargin, hasPanels, railWidth]
|
|
107
105
|
);
|
|
108
106
|
return /* @__PURE__ */ jsx(SidebarContext.Provider, { value, children });
|
|
109
107
|
}
|
|
@@ -145,7 +143,7 @@ function LogOutIcon({ className }) {
|
|
|
145
143
|
] });
|
|
146
144
|
}
|
|
147
145
|
function Sidebar({ children, className, style }) {
|
|
148
|
-
const { panelOpen, hidden, hasPanels } = useSidebar();
|
|
146
|
+
const { panelOpen, hidden, hasPanels, railWidth } = useSidebar();
|
|
149
147
|
return /* @__PURE__ */ jsx2(
|
|
150
148
|
"div",
|
|
151
149
|
{
|
|
@@ -155,20 +153,22 @@ function Sidebar({ children, className, style }) {
|
|
|
155
153
|
hidden && "-translate-x-full",
|
|
156
154
|
className
|
|
157
155
|
),
|
|
158
|
-
style: { width: panelOpen && hasPanels ?
|
|
156
|
+
style: { width: panelOpen && hasPanels ? railWidth + SIDEBAR_PANEL_WIDTH : railWidth, ...style },
|
|
159
157
|
children
|
|
160
158
|
}
|
|
161
159
|
);
|
|
162
160
|
}
|
|
163
161
|
function SidebarRail({ children, className, wide = false }) {
|
|
162
|
+
const { railWidth } = useSidebar();
|
|
164
163
|
return /* @__PURE__ */ jsx2(
|
|
165
164
|
"div",
|
|
166
165
|
{
|
|
167
166
|
className: cn(
|
|
168
167
|
"flex flex-col h-full shrink-0 bg-transparent",
|
|
169
|
-
wide
|
|
168
|
+
wide && "w-full",
|
|
170
169
|
className
|
|
171
170
|
),
|
|
171
|
+
style: wide ? void 0 : { width: railWidth },
|
|
172
172
|
children
|
|
173
173
|
}
|
|
174
174
|
);
|
|
@@ -185,30 +185,31 @@ function SidebarRailFooter({ children, className }) {
|
|
|
185
185
|
function RailSeparator({ className }) {
|
|
186
186
|
return /* @__PURE__ */ jsx2("div", { className: cn("my-2 h-px w-10 bg-[var(--md3-outline-variant)]", className) });
|
|
187
187
|
}
|
|
188
|
-
function RailButton({ icon: Icon, label, isActive, badge, onClick, className, showLabel }) {
|
|
189
|
-
|
|
190
|
-
"
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
"hover:bg-[var(--accent-surface-soft)] hover:text-[var(--accent-text)]",
|
|
199
|
-
"active:scale-95",
|
|
200
|
-
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary",
|
|
201
|
-
isActive && "bg-[var(--accent-surface-strong)] text-[var(--accent-text)]",
|
|
202
|
-
!isActive && "text-muted-foreground",
|
|
203
|
-
className
|
|
204
|
-
),
|
|
205
|
-
children: [
|
|
206
|
-
/* @__PURE__ */ jsx2(Icon, { className: "h-5 w-5 shrink-0" }),
|
|
207
|
-
showLabel && /* @__PURE__ */ jsx2("span", { className: "text-sm font-medium", children: label }),
|
|
208
|
-
badge !== void 0 && badge > 0 && /* @__PURE__ */ jsx2("span", { className: "absolute -top-1 -right-1 flex h-4 min-w-4 items-center justify-center rounded-full bg-primary text-[9px] font-bold text-[var(--md3-on-primary)] px-1 shadow-sm", children: badge > 99 ? "99+" : badge })
|
|
209
|
-
]
|
|
210
|
-
}
|
|
188
|
+
function RailButton({ icon: Icon, label, isActive, badge, onClick, className, showLabel, asChild, children }) {
|
|
189
|
+
const classes = cn(
|
|
190
|
+
"group relative flex items-center justify-center rounded-xl transition-all duration-200",
|
|
191
|
+
showLabel ? "w-full justify-start px-3 h-11 gap-3" : "w-11 h-11 justify-center",
|
|
192
|
+
"hover:bg-[var(--accent-surface-soft)] hover:text-[var(--accent-text)]",
|
|
193
|
+
"active:scale-95",
|
|
194
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary",
|
|
195
|
+
isActive && "bg-[var(--accent-surface-strong)] text-[var(--accent-text)]",
|
|
196
|
+
!isActive && "text-muted-foreground",
|
|
197
|
+
className
|
|
211
198
|
);
|
|
199
|
+
const content = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
200
|
+
/* @__PURE__ */ jsx2(Icon, { className: "h-5 w-5 shrink-0" }),
|
|
201
|
+
showLabel && /* @__PURE__ */ jsx2("span", { className: "text-sm font-medium", children: label }),
|
|
202
|
+
badge !== void 0 && badge > 0 && /* @__PURE__ */ jsx2("span", { className: "absolute -top-1 -right-1 flex h-4 min-w-4 items-center justify-center rounded-full bg-primary text-[9px] font-bold text-[var(--md3-on-primary)] px-1 shadow-sm", children: badge > 99 ? "99+" : badge })
|
|
203
|
+
] });
|
|
204
|
+
if (asChild && React2.isValidElement(children)) {
|
|
205
|
+
const child = children;
|
|
206
|
+
return React2.cloneElement(
|
|
207
|
+
child,
|
|
208
|
+
{ className: cn(classes, child.props.className), title: child.props.title ?? label },
|
|
209
|
+
content
|
|
210
|
+
);
|
|
211
|
+
}
|
|
212
|
+
return /* @__PURE__ */ jsx2("button", { type: "button", onClick, title: label, className: classes, children: content });
|
|
212
213
|
}
|
|
213
214
|
function RailModeButton({ mode, icon, label, badge, className, showLabel }) {
|
|
214
215
|
const { panelOpen, mode: currentMode, switchMode } = useSidebar();
|
|
@@ -267,24 +268,35 @@ function ProfileAvatar({
|
|
|
267
268
|
settingsHref = "/dashboard/settings",
|
|
268
269
|
children,
|
|
269
270
|
className,
|
|
271
|
+
showDetails = false,
|
|
270
272
|
LinkComponent
|
|
271
273
|
}) {
|
|
272
274
|
const Link = LinkComponent ?? DefaultLink;
|
|
273
275
|
return /* @__PURE__ */ jsxs(DropdownMenu, { children: [
|
|
274
|
-
/* @__PURE__ */ jsx2(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */
|
|
276
|
+
/* @__PURE__ */ jsx2(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
|
|
275
277
|
"button",
|
|
276
278
|
{
|
|
277
279
|
type: "button",
|
|
278
280
|
className: cn(
|
|
279
|
-
"flex items-center
|
|
281
|
+
"flex items-center rounded-lg transition-colors hover:bg-[var(--accent-surface-soft)]",
|
|
280
282
|
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary",
|
|
283
|
+
showDetails ? "w-full gap-2.5 px-3 py-2 text-left" : "justify-center w-12 h-12",
|
|
281
284
|
className
|
|
282
285
|
),
|
|
283
286
|
"aria-label": "User menu",
|
|
284
|
-
children:
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
287
|
+
children: [
|
|
288
|
+
isLoading ? /* @__PURE__ */ jsx2(Skeleton, { className: "h-7 w-7 shrink-0 rounded-full" }) : /* @__PURE__ */ jsxs(Avatar, { className: "h-7 w-7 shrink-0", children: [
|
|
289
|
+
user?.avatarUrl && /* @__PURE__ */ jsx2(AvatarImage, { src: user.avatarUrl, alt: "" }),
|
|
290
|
+
/* @__PURE__ */ jsx2(AvatarFallback, { className: "text-[10px] bg-violet-500/20 text-violet-300", children: getInitials(user?.name, user?.email) })
|
|
291
|
+
] }),
|
|
292
|
+
showDetails && /* @__PURE__ */ jsx2("div", { className: "min-w-0 flex-1", children: isLoading ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
293
|
+
/* @__PURE__ */ jsx2(Skeleton, { className: "mb-1 h-3.5 w-20" }),
|
|
294
|
+
/* @__PURE__ */ jsx2(Skeleton, { className: "h-3 w-28" })
|
|
295
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
296
|
+
/* @__PURE__ */ jsx2("p", { className: "truncate text-sm font-medium text-foreground", children: user?.name ?? user?.email ?? "Not signed in" }),
|
|
297
|
+
user?.email && user?.name && /* @__PURE__ */ jsx2("p", { className: "truncate text-xs text-muted-foreground", children: user.email })
|
|
298
|
+
] }) })
|
|
299
|
+
]
|
|
288
300
|
}
|
|
289
301
|
) }),
|
|
290
302
|
/* @__PURE__ */ jsxs(DropdownMenuContent, { side: "right", align: "end", sideOffset: 8, className: "w-72", children: [
|
|
@@ -326,7 +338,7 @@ function ProfileAvatar({
|
|
|
326
338
|
}
|
|
327
339
|
|
|
328
340
|
// src/dashboard/credit-balance.tsx
|
|
329
|
-
import * as
|
|
341
|
+
import * as React3 from "react";
|
|
330
342
|
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
331
343
|
function CreditBalance({
|
|
332
344
|
amount,
|
|
@@ -335,7 +347,7 @@ function CreditBalance({
|
|
|
335
347
|
quickAmounts = [10, 25, 100],
|
|
336
348
|
className
|
|
337
349
|
}) {
|
|
338
|
-
const [topUpValue, setTopUpValue] =
|
|
350
|
+
const [topUpValue, setTopUpValue] = React3.useState("50.00");
|
|
339
351
|
return /* @__PURE__ */ jsxs2(
|
|
340
352
|
"div",
|
|
341
353
|
{
|
|
@@ -558,7 +570,7 @@ function ResourceSnapshot({
|
|
|
558
570
|
}
|
|
559
571
|
|
|
560
572
|
// src/dashboard/activity-feed.tsx
|
|
561
|
-
import * as
|
|
573
|
+
import * as React4 from "react";
|
|
562
574
|
import { Skeleton as Skeleton3 } from "@tangle-network/ui/primitives";
|
|
563
575
|
import { timeAgo } from "@tangle-network/ui/utils";
|
|
564
576
|
import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
@@ -571,7 +583,7 @@ function ActivityFeed({
|
|
|
571
583
|
emptyLabel = "No recent activity",
|
|
572
584
|
className
|
|
573
585
|
}) {
|
|
574
|
-
const sorted =
|
|
586
|
+
const sorted = React4.useMemo(
|
|
575
587
|
() => [...items].sort((a, b) => (b.timestamp ?? 0) - (a.timestamp ?? 0)).slice(0, maxItems),
|
|
576
588
|
[items, maxItems]
|
|
577
589
|
);
|
|
@@ -813,7 +825,7 @@ function NewSandboxCard({ onClick, className }) {
|
|
|
813
825
|
}
|
|
814
826
|
|
|
815
827
|
// src/dashboard/sandbox-table.tsx
|
|
816
|
-
import * as
|
|
828
|
+
import * as React5 from "react";
|
|
817
829
|
import {
|
|
818
830
|
Activity as Activity2,
|
|
819
831
|
BarChart2 as BarChart22,
|
|
@@ -1088,7 +1100,7 @@ function SandboxTable({
|
|
|
1088
1100
|
children: /* @__PURE__ */ jsx10(MoreVertical2, { className: "h-4 w-4" })
|
|
1089
1101
|
}
|
|
1090
1102
|
) }),
|
|
1091
|
-
/* @__PURE__ */ jsx10(DropdownMenuContent3, { align: "end", className: "min-w-[180px]", children: overflowSections.map((section, sectionIdx) => /* @__PURE__ */ jsxs9(
|
|
1103
|
+
/* @__PURE__ */ jsx10(DropdownMenuContent3, { align: "end", className: "min-w-[180px]", children: overflowSections.map((section, sectionIdx) => /* @__PURE__ */ jsxs9(React5.Fragment, { children: [
|
|
1092
1104
|
sectionIdx > 0 && /* @__PURE__ */ jsx10(DropdownMenuSeparator3, {}),
|
|
1093
1105
|
section
|
|
1094
1106
|
] }, sectionIdx)) })
|
|
@@ -1225,7 +1237,7 @@ function PlanCards({ plans, className }) {
|
|
|
1225
1237
|
}
|
|
1226
1238
|
|
|
1227
1239
|
// src/dashboard/dashboard-layout.tsx
|
|
1228
|
-
import * as
|
|
1240
|
+
import * as React6 from "react";
|
|
1229
1241
|
import { Plus as Plus2, Bell } from "lucide-react";
|
|
1230
1242
|
import { Fragment as Fragment7, jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
1231
1243
|
function SettingsIconSmall({ className }) {
|
|
@@ -1288,10 +1300,10 @@ function DashboardLayoutInner({
|
|
|
1288
1300
|
notifications: notifData
|
|
1289
1301
|
}) {
|
|
1290
1302
|
const Link = LinkComponent;
|
|
1291
|
-
const [mobileMenuOpen, setMobileMenuOpen] =
|
|
1292
|
-
const [notificationsOpen, setNotificationsOpen] =
|
|
1293
|
-
const notifRef =
|
|
1294
|
-
|
|
1303
|
+
const [mobileMenuOpen, setMobileMenuOpen] = React6.useState(false);
|
|
1304
|
+
const [notificationsOpen, setNotificationsOpen] = React6.useState(false);
|
|
1305
|
+
const notifRef = React6.useRef(null);
|
|
1306
|
+
React6.useEffect(() => {
|
|
1295
1307
|
if (!notificationsOpen) return;
|
|
1296
1308
|
const handler = (e) => {
|
|
1297
1309
|
if (notifRef.current && !notifRef.current.contains(e.target)) {
|
|
@@ -1309,13 +1321,13 @@ function DashboardLayoutInner({
|
|
|
1309
1321
|
};
|
|
1310
1322
|
}, [notificationsOpen]);
|
|
1311
1323
|
const { contentMargin, hidden, mode, hasPanels, panelOpen } = useSidebar();
|
|
1312
|
-
const modeSet =
|
|
1313
|
-
const sidebarUser =
|
|
1324
|
+
const modeSet = React6.useMemo(() => new Set(modeItems), [modeItems]);
|
|
1325
|
+
const sidebarUser = React6.useMemo(
|
|
1314
1326
|
() => user ? { email: user.email, name: user.name, tier: user.tier, avatarUrl: user.avatarUrl } : void 0,
|
|
1315
1327
|
[user?.email, user?.name, user?.tier, user?.avatarUrl]
|
|
1316
1328
|
);
|
|
1317
1329
|
const activePanel = panels.find((p) => p.mode === mode);
|
|
1318
|
-
const buildSidebarContent =
|
|
1330
|
+
const buildSidebarContent = React6.useCallback(
|
|
1319
1331
|
(showLabels) => /* @__PURE__ */ jsxs12(Fragment7, { children: [
|
|
1320
1332
|
/* @__PURE__ */ jsxs12(SidebarRail, { wide: showLabels, children: [
|
|
1321
1333
|
/* @__PURE__ */ jsx13(SidebarRailHeader, { children: /* @__PURE__ */ jsx13(Link, { href: "/", to: "/", className: "p-1 rounded-md transition-colors hover:bg-muted/50", children: /* @__PURE__ */ jsx13(Logo, { variant, size: "sm", iconOnly: true }) }) }),
|
|
@@ -1323,7 +1335,7 @@ function DashboardLayoutInner({
|
|
|
1323
1335
|
const isMode = modeSet.has(item.id);
|
|
1324
1336
|
const prevIsMode = i > 0 && modeSet.has(navItems[i - 1].id);
|
|
1325
1337
|
const showSep = i > 0 && isMode && !prevIsMode;
|
|
1326
|
-
return /* @__PURE__ */ jsxs12(
|
|
1338
|
+
return /* @__PURE__ */ jsxs12(React6.Fragment, { children: [
|
|
1327
1339
|
showSep && /* @__PURE__ */ jsx13(RailSeparator, {}),
|
|
1328
1340
|
isMode ? /* @__PURE__ */ jsx13(
|
|
1329
1341
|
RailModeButton,
|
|
@@ -1388,8 +1400,8 @@ function DashboardLayoutInner({
|
|
|
1388
1400
|
mode
|
|
1389
1401
|
]
|
|
1390
1402
|
);
|
|
1391
|
-
const sidebarContent =
|
|
1392
|
-
const mobileSidebarContent =
|
|
1403
|
+
const sidebarContent = React6.useMemo(() => buildSidebarContent(false), [buildSidebarContent]);
|
|
1404
|
+
const mobileSidebarContent = React6.useMemo(() => buildSidebarContent(true), [buildSidebarContent]);
|
|
1393
1405
|
return /* @__PURE__ */ jsxs12("div", { className: cn("min-h-screen bg-background text-foreground", className), children: [
|
|
1394
1406
|
/* @__PURE__ */ jsxs12(
|
|
1395
1407
|
"nav",
|
|
@@ -1522,6 +1534,114 @@ function DashboardLayout({ defaultPanelOpen, defaultMode, ...props }) {
|
|
|
1522
1534
|
return /* @__PURE__ */ jsx13(SidebarProvider, { defaultPanelOpen, defaultMode, hasPanels: (props.panels?.length ?? 0) > 0, children: /* @__PURE__ */ jsx13(DashboardLayoutInner, { defaultPanelOpen, defaultMode, ...props }) });
|
|
1523
1535
|
}
|
|
1524
1536
|
|
|
1537
|
+
// src/dashboard/sidebar-layout.tsx
|
|
1538
|
+
import { jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
1539
|
+
var HIDE_BELOW_CLASS = {
|
|
1540
|
+
md: "max-md:hidden",
|
|
1541
|
+
lg: "max-lg:hidden"
|
|
1542
|
+
};
|
|
1543
|
+
function DefaultLink3({
|
|
1544
|
+
href,
|
|
1545
|
+
to,
|
|
1546
|
+
className,
|
|
1547
|
+
children,
|
|
1548
|
+
...rest
|
|
1549
|
+
}) {
|
|
1550
|
+
return /* @__PURE__ */ jsx14("a", { href: href ?? to, className, ...rest, children });
|
|
1551
|
+
}
|
|
1552
|
+
function SidebarLayoutInner({
|
|
1553
|
+
children,
|
|
1554
|
+
navItems,
|
|
1555
|
+
activeId,
|
|
1556
|
+
panel,
|
|
1557
|
+
logo,
|
|
1558
|
+
logoHref,
|
|
1559
|
+
user,
|
|
1560
|
+
isLoading = false,
|
|
1561
|
+
onLogout,
|
|
1562
|
+
onSettingsClick,
|
|
1563
|
+
settingsHref,
|
|
1564
|
+
profileMenuItems,
|
|
1565
|
+
railFooter,
|
|
1566
|
+
LinkComponent,
|
|
1567
|
+
hideBelow,
|
|
1568
|
+
railLabels = false,
|
|
1569
|
+
closePanelOnNavigate = false,
|
|
1570
|
+
className,
|
|
1571
|
+
sidebarClassName,
|
|
1572
|
+
contentClassName
|
|
1573
|
+
}) {
|
|
1574
|
+
const Link = LinkComponent ?? DefaultLink3;
|
|
1575
|
+
const { panelOpen, togglePanel, setPanelOpen } = useSidebar();
|
|
1576
|
+
const handleNavClick = closePanelOnNavigate && panelOpen ? () => setPanelOpen(false) : void 0;
|
|
1577
|
+
const hasProfile = user !== void 0 || onLogout !== void 0 || onSettingsClick !== void 0;
|
|
1578
|
+
return /* @__PURE__ */ jsxs13("div", { className: cn("min-h-screen bg-background text-foreground", className), children: [
|
|
1579
|
+
/* @__PURE__ */ jsx14("div", { className: cn(hideBelow && HIDE_BELOW_CLASS[hideBelow]), children: /* @__PURE__ */ jsxs13(Sidebar, { className: sidebarClassName, children: [
|
|
1580
|
+
/* @__PURE__ */ jsxs13(SidebarRail, { children: [
|
|
1581
|
+
logo !== void 0 && /* @__PURE__ */ jsx14(SidebarRailHeader, { className: railLabels ? "justify-start px-4" : void 0, children: /* @__PURE__ */ jsx14(
|
|
1582
|
+
Link,
|
|
1583
|
+
{
|
|
1584
|
+
href: logoHref,
|
|
1585
|
+
to: logoHref,
|
|
1586
|
+
className: "flex items-center justify-center rounded-lg p-1 transition-colors hover:bg-muted/50",
|
|
1587
|
+
children: logo
|
|
1588
|
+
}
|
|
1589
|
+
) }),
|
|
1590
|
+
/* @__PURE__ */ jsx14(SidebarRailNav, { className: railLabels ? "px-2" : void 0, children: navItems.map(
|
|
1591
|
+
(item) => item.togglesPanel ? /* @__PURE__ */ jsx14(
|
|
1592
|
+
RailButton,
|
|
1593
|
+
{
|
|
1594
|
+
icon: item.icon,
|
|
1595
|
+
label: item.label,
|
|
1596
|
+
badge: item.badge,
|
|
1597
|
+
isActive: panelOpen,
|
|
1598
|
+
onClick: togglePanel,
|
|
1599
|
+
showLabel: railLabels
|
|
1600
|
+
},
|
|
1601
|
+
item.id
|
|
1602
|
+
) : /* @__PURE__ */ jsx14(RailButton, { icon: item.icon, label: item.label, badge: item.badge, isActive: activeId === item.id, showLabel: railLabels, asChild: true, children: /* @__PURE__ */ jsx14(Link, { href: item.href, to: item.href, onClick: handleNavClick }) }, item.id)
|
|
1603
|
+
) }),
|
|
1604
|
+
(railFooter !== void 0 || hasProfile) && /* @__PURE__ */ jsxs13(SidebarRailFooter, { className: cn("border-t border-border pt-2", railLabels && "items-stretch px-2"), children: [
|
|
1605
|
+
railFooter,
|
|
1606
|
+
hasProfile && /* @__PURE__ */ jsx14(
|
|
1607
|
+
ProfileAvatar,
|
|
1608
|
+
{
|
|
1609
|
+
user: user ?? void 0,
|
|
1610
|
+
isLoading,
|
|
1611
|
+
onLogout,
|
|
1612
|
+
onSettingsClick,
|
|
1613
|
+
settingsHref,
|
|
1614
|
+
showDetails: railLabels,
|
|
1615
|
+
LinkComponent: Link,
|
|
1616
|
+
children: profileMenuItems
|
|
1617
|
+
}
|
|
1618
|
+
)
|
|
1619
|
+
] })
|
|
1620
|
+
] }),
|
|
1621
|
+
panel != null && /* @__PURE__ */ jsx14(SidebarPanel, { children: panel })
|
|
1622
|
+
] }) }),
|
|
1623
|
+
/* @__PURE__ */ jsx14(SidebarContent, { className: contentClassName, children })
|
|
1624
|
+
] });
|
|
1625
|
+
}
|
|
1626
|
+
function SidebarLayout({
|
|
1627
|
+
panelOpen,
|
|
1628
|
+
onPanelOpenChange,
|
|
1629
|
+
defaultPanelOpen,
|
|
1630
|
+
...props
|
|
1631
|
+
}) {
|
|
1632
|
+
return /* @__PURE__ */ jsx14(
|
|
1633
|
+
SidebarProvider,
|
|
1634
|
+
{
|
|
1635
|
+
panelOpen,
|
|
1636
|
+
onPanelOpenChange,
|
|
1637
|
+
defaultPanelOpen,
|
|
1638
|
+
hasPanels: props.panel != null,
|
|
1639
|
+
railWidth: props.railLabels ? SIDEBAR_RAIL_LABELED_WIDTH : void 0,
|
|
1640
|
+
children: /* @__PURE__ */ jsx14(SidebarLayoutInner, { ...props })
|
|
1641
|
+
}
|
|
1642
|
+
);
|
|
1643
|
+
}
|
|
1644
|
+
|
|
1525
1645
|
// src/dashboard/profile-selector.tsx
|
|
1526
1646
|
import { Check as Check2, ChevronDown, Plus as Plus3, Settings } from "lucide-react";
|
|
1527
1647
|
import { Button as Button2 } from "@tangle-network/ui/primitives";
|
|
@@ -1534,7 +1654,7 @@ import {
|
|
|
1534
1654
|
DropdownMenuSeparator as DropdownMenuSeparator4,
|
|
1535
1655
|
DropdownMenuTrigger as DropdownMenuTrigger4
|
|
1536
1656
|
} from "@tangle-network/ui/primitives";
|
|
1537
|
-
import { Fragment as Fragment8, jsx as
|
|
1657
|
+
import { Fragment as Fragment8, jsx as jsx15, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1538
1658
|
function ProfileSelector({
|
|
1539
1659
|
profiles,
|
|
1540
1660
|
selectedId,
|
|
@@ -1549,77 +1669,77 @@ function ProfileSelector({
|
|
|
1549
1669
|
const selected = profiles.find((p) => p.id === selectedId);
|
|
1550
1670
|
const builtinProfiles = profiles.filter((p) => p.is_builtin);
|
|
1551
1671
|
const customProfiles = profiles.filter((p) => !p.is_builtin);
|
|
1552
|
-
return /* @__PURE__ */
|
|
1553
|
-
label && /* @__PURE__ */
|
|
1554
|
-
/* @__PURE__ */
|
|
1555
|
-
/* @__PURE__ */
|
|
1556
|
-
/* @__PURE__ */
|
|
1557
|
-
/* @__PURE__ */
|
|
1672
|
+
return /* @__PURE__ */ jsxs14("div", { className, children: [
|
|
1673
|
+
label && /* @__PURE__ */ jsx15("label", { className: "mb-2 block font-medium text-sm", children: label }),
|
|
1674
|
+
/* @__PURE__ */ jsxs14(DropdownMenu4, { children: [
|
|
1675
|
+
/* @__PURE__ */ jsx15(DropdownMenuTrigger4, { asChild: true, children: /* @__PURE__ */ jsxs14(Button2, { variant: "outline", className: "w-full justify-between", children: [
|
|
1676
|
+
/* @__PURE__ */ jsx15("span", { className: "truncate", children: selected ? selected.name : placeholder }),
|
|
1677
|
+
/* @__PURE__ */ jsx15(ChevronDown, { className: "ml-2 h-4 w-4 shrink-0 opacity-50" })
|
|
1558
1678
|
] }) }),
|
|
1559
|
-
/* @__PURE__ */
|
|
1560
|
-
/* @__PURE__ */
|
|
1679
|
+
/* @__PURE__ */ jsxs14(DropdownMenuContent4, { className: "w-[300px]", align: "start", children: [
|
|
1680
|
+
/* @__PURE__ */ jsxs14(
|
|
1561
1681
|
DropdownMenuItem4,
|
|
1562
1682
|
{
|
|
1563
1683
|
onClick: () => onSelect(null),
|
|
1564
1684
|
className: "flex items-center justify-between",
|
|
1565
1685
|
children: [
|
|
1566
|
-
/* @__PURE__ */
|
|
1567
|
-
!selectedId && /* @__PURE__ */
|
|
1686
|
+
/* @__PURE__ */ jsx15("span", { children: placeholder }),
|
|
1687
|
+
!selectedId && /* @__PURE__ */ jsx15(Check2, { className: "h-4 w-4 text-[var(--surface-success-text)]" })
|
|
1568
1688
|
]
|
|
1569
1689
|
}
|
|
1570
1690
|
),
|
|
1571
|
-
builtinProfiles.length > 0 && /* @__PURE__ */
|
|
1572
|
-
/* @__PURE__ */
|
|
1573
|
-
/* @__PURE__ */
|
|
1574
|
-
builtinProfiles.map((profile) => /* @__PURE__ */
|
|
1691
|
+
builtinProfiles.length > 0 && /* @__PURE__ */ jsxs14(Fragment8, { children: [
|
|
1692
|
+
/* @__PURE__ */ jsx15(DropdownMenuSeparator4, {}),
|
|
1693
|
+
/* @__PURE__ */ jsx15(DropdownMenuLabel2, { children: "Built-in Profiles" }),
|
|
1694
|
+
builtinProfiles.map((profile) => /* @__PURE__ */ jsxs14(
|
|
1575
1695
|
DropdownMenuItem4,
|
|
1576
1696
|
{
|
|
1577
1697
|
onClick: () => onSelect(profile),
|
|
1578
1698
|
className: "flex flex-col items-start gap-1",
|
|
1579
1699
|
children: [
|
|
1580
|
-
/* @__PURE__ */
|
|
1581
|
-
/* @__PURE__ */
|
|
1582
|
-
/* @__PURE__ */
|
|
1583
|
-
profile.extends && /* @__PURE__ */
|
|
1700
|
+
/* @__PURE__ */ jsxs14("div", { className: "flex w-full items-center justify-between", children: [
|
|
1701
|
+
/* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-2", children: [
|
|
1702
|
+
/* @__PURE__ */ jsx15("span", { className: "font-medium", children: profile.name }),
|
|
1703
|
+
profile.extends && /* @__PURE__ */ jsxs14(Badge, { variant: "secondary", className: "border-0 text-xs", children: [
|
|
1584
1704
|
"extends ",
|
|
1585
1705
|
profile.extends
|
|
1586
1706
|
] })
|
|
1587
1707
|
] }),
|
|
1588
|
-
selectedId === profile.id && /* @__PURE__ */
|
|
1708
|
+
selectedId === profile.id && /* @__PURE__ */ jsx15(Check2, { className: "h-4 w-4 text-[var(--surface-success-text)]" })
|
|
1589
1709
|
] }),
|
|
1590
|
-
profile.description && /* @__PURE__ */
|
|
1710
|
+
profile.description && /* @__PURE__ */ jsx15("span", { className: "line-clamp-1 text-muted-foreground text-xs", children: profile.description })
|
|
1591
1711
|
]
|
|
1592
1712
|
},
|
|
1593
1713
|
profile.id
|
|
1594
1714
|
))
|
|
1595
1715
|
] }),
|
|
1596
|
-
customProfiles.length > 0 && /* @__PURE__ */
|
|
1597
|
-
/* @__PURE__ */
|
|
1598
|
-
/* @__PURE__ */
|
|
1599
|
-
customProfiles.map((profile) => /* @__PURE__ */
|
|
1716
|
+
customProfiles.length > 0 && /* @__PURE__ */ jsxs14(Fragment8, { children: [
|
|
1717
|
+
/* @__PURE__ */ jsx15(DropdownMenuSeparator4, {}),
|
|
1718
|
+
/* @__PURE__ */ jsx15(DropdownMenuLabel2, { children: "Custom Profiles" }),
|
|
1719
|
+
customProfiles.map((profile) => /* @__PURE__ */ jsxs14(
|
|
1600
1720
|
DropdownMenuItem4,
|
|
1601
1721
|
{
|
|
1602
1722
|
onClick: () => onSelect(profile),
|
|
1603
1723
|
className: "flex flex-col items-start gap-1",
|
|
1604
1724
|
children: [
|
|
1605
|
-
/* @__PURE__ */
|
|
1606
|
-
/* @__PURE__ */
|
|
1607
|
-
/* @__PURE__ */
|
|
1608
|
-
profile.model && /* @__PURE__ */
|
|
1725
|
+
/* @__PURE__ */ jsxs14("div", { className: "flex w-full items-center justify-between", children: [
|
|
1726
|
+
/* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-2", children: [
|
|
1727
|
+
/* @__PURE__ */ jsx15("span", { className: "font-medium", children: profile.name }),
|
|
1728
|
+
profile.model && /* @__PURE__ */ jsx15(Badge, { variant: "secondary", className: "border-0 text-xs", children: profile.model.split("/").pop() })
|
|
1609
1729
|
] }),
|
|
1610
|
-
selectedId === profile.id && /* @__PURE__ */
|
|
1730
|
+
selectedId === profile.id && /* @__PURE__ */ jsx15(Check2, { className: "h-4 w-4 text-[var(--surface-success-text)]" })
|
|
1611
1731
|
] }),
|
|
1612
|
-
profile.description && /* @__PURE__ */
|
|
1613
|
-
showMetrics && profile.metrics && profile.metrics.total_runs > 0 && /* @__PURE__ */
|
|
1614
|
-
/* @__PURE__ */
|
|
1732
|
+
profile.description && /* @__PURE__ */ jsx15("span", { className: "line-clamp-1 text-muted-foreground text-xs", children: profile.description }),
|
|
1733
|
+
showMetrics && profile.metrics && profile.metrics.total_runs > 0 && /* @__PURE__ */ jsxs14("div", { className: "flex gap-3 text-muted-foreground text-xs", children: [
|
|
1734
|
+
/* @__PURE__ */ jsxs14("span", { children: [
|
|
1615
1735
|
profile.metrics.total_runs,
|
|
1616
1736
|
" runs"
|
|
1617
1737
|
] }),
|
|
1618
|
-
/* @__PURE__ */
|
|
1738
|
+
/* @__PURE__ */ jsxs14("span", { children: [
|
|
1619
1739
|
profile.metrics.success_rate.toFixed(0),
|
|
1620
1740
|
"% success"
|
|
1621
1741
|
] }),
|
|
1622
|
-
/* @__PURE__ */
|
|
1742
|
+
/* @__PURE__ */ jsxs14("span", { children: [
|
|
1623
1743
|
"~",
|
|
1624
1744
|
(profile.metrics.avg_duration_ms / 1e3).toFixed(1),
|
|
1625
1745
|
"s avg"
|
|
@@ -1630,26 +1750,26 @@ function ProfileSelector({
|
|
|
1630
1750
|
profile.id
|
|
1631
1751
|
))
|
|
1632
1752
|
] }),
|
|
1633
|
-
(onCreateClick || onManageClick) && /* @__PURE__ */
|
|
1634
|
-
/* @__PURE__ */
|
|
1635
|
-
onCreateClick && /* @__PURE__ */
|
|
1753
|
+
(onCreateClick || onManageClick) && /* @__PURE__ */ jsxs14(Fragment8, { children: [
|
|
1754
|
+
/* @__PURE__ */ jsx15(DropdownMenuSeparator4, {}),
|
|
1755
|
+
onCreateClick && /* @__PURE__ */ jsxs14(
|
|
1636
1756
|
DropdownMenuItem4,
|
|
1637
1757
|
{
|
|
1638
1758
|
onClick: onCreateClick,
|
|
1639
1759
|
className: "text-[var(--surface-info-text)]",
|
|
1640
1760
|
children: [
|
|
1641
|
-
/* @__PURE__ */
|
|
1761
|
+
/* @__PURE__ */ jsx15(Plus3, { className: "mr-2 h-4 w-4" }),
|
|
1642
1762
|
"Create New Profile"
|
|
1643
1763
|
]
|
|
1644
1764
|
}
|
|
1645
1765
|
),
|
|
1646
|
-
onManageClick && /* @__PURE__ */
|
|
1766
|
+
onManageClick && /* @__PURE__ */ jsxs14(
|
|
1647
1767
|
DropdownMenuItem4,
|
|
1648
1768
|
{
|
|
1649
1769
|
onClick: onManageClick,
|
|
1650
1770
|
className: "text-muted-foreground",
|
|
1651
1771
|
children: [
|
|
1652
|
-
/* @__PURE__ */
|
|
1772
|
+
/* @__PURE__ */ jsx15(Settings, { className: "mr-2 h-4 w-4" }),
|
|
1653
1773
|
"Manage Profiles"
|
|
1654
1774
|
]
|
|
1655
1775
|
}
|
|
@@ -1675,26 +1795,26 @@ function ProfileComparison({
|
|
|
1675
1795
|
const fastestProfile = profilesWithMetrics.reduce(
|
|
1676
1796
|
(best, p) => (p.metrics?.avg_duration_ms ?? Number.POSITIVE_INFINITY) < (best.metrics?.avg_duration_ms ?? Number.POSITIVE_INFINITY) ? p : best
|
|
1677
1797
|
);
|
|
1678
|
-
return /* @__PURE__ */
|
|
1679
|
-
/* @__PURE__ */
|
|
1680
|
-
/* @__PURE__ */
|
|
1798
|
+
return /* @__PURE__ */ jsxs14("div", { className: `rounded-lg border border-border p-4 ${className ?? ""}`, children: [
|
|
1799
|
+
/* @__PURE__ */ jsx15("h4", { className: "mb-3 font-medium text-sm", children: "Profile Performance" }),
|
|
1800
|
+
/* @__PURE__ */ jsx15("div", { className: "space-y-3", children: profilesWithMetrics.map((profile) => {
|
|
1681
1801
|
const isBestSuccess = profile.id === bestSuccess.id;
|
|
1682
1802
|
const isFastest = profile.id === fastestProfile.id;
|
|
1683
|
-
return /* @__PURE__ */
|
|
1803
|
+
return /* @__PURE__ */ jsxs14(
|
|
1684
1804
|
"div",
|
|
1685
1805
|
{
|
|
1686
1806
|
className: "flex items-center justify-between gap-4",
|
|
1687
1807
|
children: [
|
|
1688
|
-
/* @__PURE__ */
|
|
1689
|
-
/* @__PURE__ */
|
|
1690
|
-
isBestSuccess && /* @__PURE__ */
|
|
1691
|
-
isFastest && !isBestSuccess && /* @__PURE__ */
|
|
1808
|
+
/* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-2", children: [
|
|
1809
|
+
/* @__PURE__ */ jsx15("span", { className: "font-medium", children: profile.name }),
|
|
1810
|
+
isBestSuccess && /* @__PURE__ */ jsx15(Badge, { className: "border border-[var(--surface-success-border)] bg-[var(--surface-success-bg)] text-[var(--surface-success-text)] text-xs", children: "Best Success" }),
|
|
1811
|
+
isFastest && !isBestSuccess && /* @__PURE__ */ jsx15(Badge, { className: "border border-[var(--surface-info-border)] bg-[var(--surface-info-bg)] text-[var(--surface-info-text)] text-xs", children: "Fastest" })
|
|
1692
1812
|
] }),
|
|
1693
|
-
/* @__PURE__ */
|
|
1694
|
-
/* @__PURE__ */
|
|
1695
|
-
/* @__PURE__ */
|
|
1813
|
+
/* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-4 text-sm", children: [
|
|
1814
|
+
/* @__PURE__ */ jsxs14("span", { children: [
|
|
1815
|
+
/* @__PURE__ */ jsx15("span", { className: "text-muted-foreground", children: "Success:" }),
|
|
1696
1816
|
" ",
|
|
1697
|
-
/* @__PURE__ */
|
|
1817
|
+
/* @__PURE__ */ jsxs14(
|
|
1698
1818
|
"span",
|
|
1699
1819
|
{
|
|
1700
1820
|
className: (profile.metrics?.success_rate ?? 0) >= 80 ? "text-[var(--surface-success-text)]" : (profile.metrics?.success_rate ?? 0) >= 50 ? "text-[var(--surface-warning-text)]" : "text-[var(--surface-danger-text)]",
|
|
@@ -1705,13 +1825,13 @@ function ProfileComparison({
|
|
|
1705
1825
|
}
|
|
1706
1826
|
)
|
|
1707
1827
|
] }),
|
|
1708
|
-
/* @__PURE__ */
|
|
1709
|
-
/* @__PURE__ */
|
|
1828
|
+
/* @__PURE__ */ jsxs14("span", { children: [
|
|
1829
|
+
/* @__PURE__ */ jsx15("span", { className: "text-muted-foreground", children: "Avg:" }),
|
|
1710
1830
|
" ",
|
|
1711
1831
|
((profile.metrics?.avg_duration_ms ?? 0) / 1e3).toFixed(1),
|
|
1712
1832
|
"s"
|
|
1713
1833
|
] }),
|
|
1714
|
-
/* @__PURE__ */
|
|
1834
|
+
/* @__PURE__ */ jsxs14("span", { className: "text-muted-foreground", children: [
|
|
1715
1835
|
profile.metrics?.total_runs,
|
|
1716
1836
|
" runs"
|
|
1717
1837
|
] })
|
|
@@ -1725,8 +1845,8 @@ function ProfileComparison({
|
|
|
1725
1845
|
}
|
|
1726
1846
|
|
|
1727
1847
|
// src/dashboard/metric-area-chart.tsx
|
|
1728
|
-
import * as
|
|
1729
|
-
import { jsx as
|
|
1848
|
+
import * as React7 from "react";
|
|
1849
|
+
import { jsx as jsx16, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
1730
1850
|
var TONE_VARS = {
|
|
1731
1851
|
primary: "var(--brand-primary, hsl(var(--primary)))",
|
|
1732
1852
|
success: "var(--status-running, #22c55e)",
|
|
@@ -1772,7 +1892,7 @@ function MetricAreaChart({
|
|
|
1772
1892
|
emptyState,
|
|
1773
1893
|
className
|
|
1774
1894
|
}) {
|
|
1775
|
-
const gradientId =
|
|
1895
|
+
const gradientId = React7.useId();
|
|
1776
1896
|
const width = 400;
|
|
1777
1897
|
const values = points.map((p) => p.value).filter((v) => v !== null);
|
|
1778
1898
|
const latest = values.length > 0 ? values[values.length - 1] : null;
|
|
@@ -1780,7 +1900,7 @@ function MetricAreaChart({
|
|
|
1780
1900
|
const yMax = maxValue ?? (observedMax > 0 ? observedMax * 1.1 : 1);
|
|
1781
1901
|
const segments = buildSegments(points, width, height, yMax);
|
|
1782
1902
|
const color = TONE_VARS[tone];
|
|
1783
|
-
return /* @__PURE__ */
|
|
1903
|
+
return /* @__PURE__ */ jsxs15(
|
|
1784
1904
|
"div",
|
|
1785
1905
|
{
|
|
1786
1906
|
className: cn(
|
|
@@ -1789,21 +1909,21 @@ function MetricAreaChart({
|
|
|
1789
1909
|
),
|
|
1790
1910
|
"data-testid": `metric-chart-${label.toLowerCase().replace(/\s+/g, "-")}`,
|
|
1791
1911
|
children: [
|
|
1792
|
-
/* @__PURE__ */
|
|
1793
|
-
/* @__PURE__ */
|
|
1794
|
-
/* @__PURE__ */
|
|
1795
|
-
/* @__PURE__ */
|
|
1796
|
-
detail && /* @__PURE__ */
|
|
1912
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex items-baseline justify-between gap-3", children: [
|
|
1913
|
+
/* @__PURE__ */ jsx16("p", { className: "font-medium text-muted-foreground text-xs uppercase tracking-[0.12em]", children: label }),
|
|
1914
|
+
/* @__PURE__ */ jsxs15("div", { className: "text-right", children: [
|
|
1915
|
+
/* @__PURE__ */ jsx16("span", { className: "font-semibold text-foreground text-xl tabular-nums tracking-tight", children: latest === null ? "\u2014" : formatValue(latest) }),
|
|
1916
|
+
detail && /* @__PURE__ */ jsx16("span", { className: "ml-1.5 text-muted-foreground text-xs", children: detail })
|
|
1797
1917
|
] })
|
|
1798
1918
|
] }),
|
|
1799
|
-
/* @__PURE__ */
|
|
1919
|
+
/* @__PURE__ */ jsx16("div", { className: "mt-3", children: values.length === 0 ? /* @__PURE__ */ jsx16(
|
|
1800
1920
|
"div",
|
|
1801
1921
|
{
|
|
1802
1922
|
className: "flex items-center justify-center text-muted-foreground text-xs",
|
|
1803
1923
|
style: { height },
|
|
1804
1924
|
children: emptyState ?? "Waiting for samples\u2026"
|
|
1805
1925
|
}
|
|
1806
|
-
) : /* @__PURE__ */
|
|
1926
|
+
) : /* @__PURE__ */ jsxs15(
|
|
1807
1927
|
"svg",
|
|
1808
1928
|
{
|
|
1809
1929
|
viewBox: `0 0 ${width} ${height}`,
|
|
@@ -1813,7 +1933,7 @@ function MetricAreaChart({
|
|
|
1813
1933
|
role: "img",
|
|
1814
1934
|
"aria-label": `${label} chart`,
|
|
1815
1935
|
children: [
|
|
1816
|
-
[0.25, 0.5, 0.75].map((fraction) => /* @__PURE__ */
|
|
1936
|
+
[0.25, 0.5, 0.75].map((fraction) => /* @__PURE__ */ jsx16(
|
|
1817
1937
|
"line",
|
|
1818
1938
|
{
|
|
1819
1939
|
x1: 0,
|
|
@@ -1828,13 +1948,13 @@ function MetricAreaChart({
|
|
|
1828
1948
|
},
|
|
1829
1949
|
fraction
|
|
1830
1950
|
)),
|
|
1831
|
-
/* @__PURE__ */
|
|
1832
|
-
/* @__PURE__ */
|
|
1833
|
-
/* @__PURE__ */
|
|
1951
|
+
/* @__PURE__ */ jsx16("defs", { children: /* @__PURE__ */ jsxs15("linearGradient", { id: gradientId, x1: "0", y1: "0", x2: "0", y2: "1", children: [
|
|
1952
|
+
/* @__PURE__ */ jsx16("stop", { offset: "0%", stopColor: color, stopOpacity: 0.28 }),
|
|
1953
|
+
/* @__PURE__ */ jsx16("stop", { offset: "100%", stopColor: color, stopOpacity: 0.02 })
|
|
1834
1954
|
] }) }),
|
|
1835
|
-
segments.map((segment) => /* @__PURE__ */
|
|
1836
|
-
/* @__PURE__ */
|
|
1837
|
-
/* @__PURE__ */
|
|
1955
|
+
segments.map((segment) => /* @__PURE__ */ jsxs15(React7.Fragment, { children: [
|
|
1956
|
+
/* @__PURE__ */ jsx16("path", { d: segment.area, fill: `url(#${gradientId})` }),
|
|
1957
|
+
/* @__PURE__ */ jsx16(
|
|
1838
1958
|
"path",
|
|
1839
1959
|
{
|
|
1840
1960
|
d: segment.path,
|
|
@@ -1850,9 +1970,9 @@ function MetricAreaChart({
|
|
|
1850
1970
|
]
|
|
1851
1971
|
}
|
|
1852
1972
|
) }),
|
|
1853
|
-
/* @__PURE__ */
|
|
1854
|
-
/* @__PURE__ */
|
|
1855
|
-
/* @__PURE__ */
|
|
1973
|
+
/* @__PURE__ */ jsxs15("div", { className: "mt-1.5 flex justify-between text-[10px] text-muted-foreground tabular-nums", children: [
|
|
1974
|
+
/* @__PURE__ */ jsx16("span", { children: values.length > 0 ? formatValue(0) : "" }),
|
|
1975
|
+
/* @__PURE__ */ jsx16("span", { children: values.length > 0 ? formatValue(yMax) : "" })
|
|
1856
1976
|
] })
|
|
1857
1977
|
]
|
|
1858
1978
|
}
|
|
@@ -1872,7 +1992,7 @@ import {
|
|
|
1872
1992
|
} from "lucide-react";
|
|
1873
1993
|
import { Button as Button3 } from "@tangle-network/ui/primitives";
|
|
1874
1994
|
import { Badge as Badge2 } from "@tangle-network/ui/primitives";
|
|
1875
|
-
import { Fragment as Fragment10, jsx as
|
|
1995
|
+
import { Fragment as Fragment10, jsx as jsx17, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
1876
1996
|
var statusConfig = {
|
|
1877
1997
|
pending: {
|
|
1878
1998
|
icon: Clock3,
|
|
@@ -1956,19 +2076,19 @@ function VariantList({
|
|
|
1956
2076
|
isActioning,
|
|
1957
2077
|
className
|
|
1958
2078
|
}) {
|
|
1959
|
-
return /* @__PURE__ */
|
|
2079
|
+
return /* @__PURE__ */ jsx17("div", { className: `space-y-2 ${className || ""}`, children: variants.map((variant) => {
|
|
1960
2080
|
const status = statusConfig[variant.status];
|
|
1961
2081
|
const StatusIcon = status.icon;
|
|
1962
2082
|
const isSelected = variant.id === selectedId;
|
|
1963
|
-
return /* @__PURE__ */
|
|
2083
|
+
return /* @__PURE__ */ jsxs16(
|
|
1964
2084
|
"div",
|
|
1965
2085
|
{
|
|
1966
2086
|
className: `cursor-pointer rounded-lg border px-3 py-2.5 transition-colors ${isSelected ? "border-primary/30 bg-[var(--accent-surface-soft)]" : "border-border bg-card hover:border-primary/20 hover:bg-muted/50"}`,
|
|
1967
2087
|
onClick: () => onSelect?.(variant.id),
|
|
1968
2088
|
children: [
|
|
1969
|
-
/* @__PURE__ */
|
|
1970
|
-
/* @__PURE__ */
|
|
1971
|
-
/* @__PURE__ */
|
|
2089
|
+
/* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-2", children: [
|
|
2090
|
+
/* @__PURE__ */ jsxs16(Badge2, { className: `shrink-0 ${status.bg} ${status.border} ${status.color}`, children: [
|
|
2091
|
+
/* @__PURE__ */ jsx17(
|
|
1972
2092
|
StatusIcon,
|
|
1973
2093
|
{
|
|
1974
2094
|
className: `mr-1 h-3 w-3 ${status.animate ? "animate-spin" : ""}`
|
|
@@ -1976,27 +2096,27 @@ function VariantList({
|
|
|
1976
2096
|
),
|
|
1977
2097
|
status.label
|
|
1978
2098
|
] }),
|
|
1979
|
-
/* @__PURE__ */
|
|
1980
|
-
variant.sublabel && /* @__PURE__ */
|
|
2099
|
+
/* @__PURE__ */ jsx17("span", { className: "truncate text-sm font-medium text-foreground", children: variant.label }),
|
|
2100
|
+
variant.sublabel && /* @__PURE__ */ jsxs16("span", { className: "shrink-0 text-xs text-muted-foreground", children: [
|
|
1981
2101
|
"(",
|
|
1982
2102
|
variant.sublabel,
|
|
1983
2103
|
")"
|
|
1984
2104
|
] }),
|
|
1985
|
-
variant.durationMs && /* @__PURE__ */
|
|
1986
|
-
/* @__PURE__ */
|
|
2105
|
+
variant.durationMs && /* @__PURE__ */ jsxs16("span", { className: "flex shrink-0 items-center gap-1 text-xs text-muted-foreground", children: [
|
|
2106
|
+
/* @__PURE__ */ jsx17(Timer, { className: "h-3 w-3" }),
|
|
1987
2107
|
(variant.durationMs / 1e3).toFixed(1),
|
|
1988
2108
|
"s"
|
|
1989
2109
|
] }),
|
|
1990
|
-
/* @__PURE__ */
|
|
1991
|
-
variant.outcome && /* @__PURE__ */
|
|
2110
|
+
/* @__PURE__ */ jsxs16("div", { className: "ml-auto flex shrink-0 items-center gap-1.5", children: [
|
|
2111
|
+
variant.outcome && /* @__PURE__ */ jsx17(
|
|
1992
2112
|
Badge2,
|
|
1993
2113
|
{
|
|
1994
2114
|
className: `${outcomeConfig[variant.outcome].bg} ${outcomeConfig[variant.outcome].border} ${outcomeConfig[variant.outcome].color}`,
|
|
1995
2115
|
children: outcomeConfig[variant.outcome].label
|
|
1996
2116
|
}
|
|
1997
2117
|
),
|
|
1998
|
-
variant.status === "completed" && variant.outcome === "pending_review" && onAccept && onReject && /* @__PURE__ */
|
|
1999
|
-
/* @__PURE__ */
|
|
2118
|
+
variant.status === "completed" && variant.outcome === "pending_review" && onAccept && onReject && /* @__PURE__ */ jsxs16(Fragment10, { children: [
|
|
2119
|
+
/* @__PURE__ */ jsxs16(
|
|
2000
2120
|
Button3,
|
|
2001
2121
|
{
|
|
2002
2122
|
variant: "outline",
|
|
@@ -2008,12 +2128,12 @@ function VariantList({
|
|
|
2008
2128
|
},
|
|
2009
2129
|
disabled: isActioning === variant.id,
|
|
2010
2130
|
children: [
|
|
2011
|
-
/* @__PURE__ */
|
|
2131
|
+
/* @__PURE__ */ jsx17(Check3, { className: "mr-1 h-3 w-3" }),
|
|
2012
2132
|
"Accept"
|
|
2013
2133
|
]
|
|
2014
2134
|
}
|
|
2015
2135
|
),
|
|
2016
|
-
/* @__PURE__ */
|
|
2136
|
+
/* @__PURE__ */ jsxs16(
|
|
2017
2137
|
Button3,
|
|
2018
2138
|
{
|
|
2019
2139
|
variant: "outline",
|
|
@@ -2025,13 +2145,13 @@ function VariantList({
|
|
|
2025
2145
|
},
|
|
2026
2146
|
disabled: isActioning === variant.id,
|
|
2027
2147
|
children: [
|
|
2028
|
-
/* @__PURE__ */
|
|
2148
|
+
/* @__PURE__ */ jsx17(X, { className: "mr-1 h-3 w-3" }),
|
|
2029
2149
|
"Reject"
|
|
2030
2150
|
]
|
|
2031
2151
|
}
|
|
2032
2152
|
)
|
|
2033
2153
|
] }),
|
|
2034
|
-
variant.detailsUrl && /* @__PURE__ */
|
|
2154
|
+
variant.detailsUrl && /* @__PURE__ */ jsx17(
|
|
2035
2155
|
Button3,
|
|
2036
2156
|
{
|
|
2037
2157
|
variant: "ghost",
|
|
@@ -2041,13 +2161,13 @@ function VariantList({
|
|
|
2041
2161
|
e.stopPropagation();
|
|
2042
2162
|
window.open(variant.detailsUrl, "_blank");
|
|
2043
2163
|
},
|
|
2044
|
-
children: /* @__PURE__ */
|
|
2164
|
+
children: /* @__PURE__ */ jsx17(ExternalLink2, { className: "h-3.5 w-3.5" })
|
|
2045
2165
|
}
|
|
2046
2166
|
)
|
|
2047
2167
|
] })
|
|
2048
2168
|
] }),
|
|
2049
|
-
variant.error && /* @__PURE__ */
|
|
2050
|
-
variant.summary && /* @__PURE__ */
|
|
2169
|
+
variant.error && /* @__PURE__ */ jsx17("p", { className: "mt-1.5 text-xs text-[var(--surface-danger-text)]", children: variant.error }),
|
|
2170
|
+
variant.summary && /* @__PURE__ */ jsx17("p", { className: "mt-1.5 line-clamp-2 text-xs text-muted-foreground", children: variant.summary })
|
|
2051
2171
|
]
|
|
2052
2172
|
},
|
|
2053
2173
|
variant.id
|
|
@@ -2058,7 +2178,7 @@ function VariantList({
|
|
|
2058
2178
|
// src/dashboard/system-logs.tsx
|
|
2059
2179
|
import { Terminal as Terminal3 } from "lucide-react";
|
|
2060
2180
|
import { useEffect as useEffect2, useRef as useRef2, useState as useState4 } from "react";
|
|
2061
|
-
import { jsx as
|
|
2181
|
+
import { jsx as jsx18, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
2062
2182
|
function SystemLogsViewer({ apiUrl, token, className }) {
|
|
2063
2183
|
const [logs, setLogs] = useState4([]);
|
|
2064
2184
|
const [error, setError] = useState4(null);
|
|
@@ -2111,18 +2231,18 @@ function SystemLogsViewer({ apiUrl, token, className }) {
|
|
|
2111
2231
|
const isAtBottom = scrollHeight - scrollTop - clientHeight < 20;
|
|
2112
2232
|
setIsFollowing((prev) => prev === isAtBottom ? prev : isAtBottom);
|
|
2113
2233
|
};
|
|
2114
|
-
return /* @__PURE__ */
|
|
2115
|
-
/* @__PURE__ */
|
|
2116
|
-
/* @__PURE__ */
|
|
2117
|
-
/* @__PURE__ */
|
|
2118
|
-
/* @__PURE__ */
|
|
2234
|
+
return /* @__PURE__ */ jsxs17("div", { className: cn("flex flex-col h-full bg-background text-foreground font-mono text-sm leading-relaxed overflow-hidden rounded-lg border border-border", className), children: [
|
|
2235
|
+
/* @__PURE__ */ jsxs17("div", { className: "flex-none flex items-center justify-between border-b border-border bg-muted/50 backdrop-blur-md px-4 py-2", children: [
|
|
2236
|
+
/* @__PURE__ */ jsxs17("div", { className: "flex items-center gap-2", children: [
|
|
2237
|
+
/* @__PURE__ */ jsx18(Terminal3, { className: "h-4 w-4 text-primary animate-pulse" }),
|
|
2238
|
+
/* @__PURE__ */ jsx18("span", { className: "font-bold text-xs uppercase tracking-widest text-muted-foreground", children: "System Traces" })
|
|
2119
2239
|
] }),
|
|
2120
|
-
/* @__PURE__ */
|
|
2121
|
-
error && /* @__PURE__ */
|
|
2122
|
-
/* @__PURE__ */
|
|
2240
|
+
/* @__PURE__ */ jsxs17("div", { className: "flex items-center gap-3", children: [
|
|
2241
|
+
error && /* @__PURE__ */ jsxs17("span", { className: "text-destructive text-xs flex items-center gap-1", children: [
|
|
2242
|
+
/* @__PURE__ */ jsx18("span", { className: "w-2 h-2 rounded-full bg-destructive animate-ping" }),
|
|
2123
2243
|
" Error fetching logs"
|
|
2124
2244
|
] }),
|
|
2125
|
-
/* @__PURE__ */
|
|
2245
|
+
/* @__PURE__ */ jsx18(
|
|
2126
2246
|
"button",
|
|
2127
2247
|
{
|
|
2128
2248
|
onClick: () => {
|
|
@@ -2137,29 +2257,29 @@ function SystemLogsViewer({ apiUrl, token, className }) {
|
|
|
2137
2257
|
)
|
|
2138
2258
|
] })
|
|
2139
2259
|
] }),
|
|
2140
|
-
/* @__PURE__ */
|
|
2260
|
+
/* @__PURE__ */ jsx18(
|
|
2141
2261
|
"div",
|
|
2142
2262
|
{
|
|
2143
2263
|
ref: scrollRef,
|
|
2144
2264
|
onScroll: handleScroll,
|
|
2145
2265
|
className: "flex-1 overflow-y-auto p-4 space-y-1",
|
|
2146
|
-
children: logs.length === 0 && !error ? /* @__PURE__ */
|
|
2147
|
-
/* @__PURE__ */
|
|
2266
|
+
children: logs.length === 0 && !error ? /* @__PURE__ */ jsx18("div", { className: "flex h-full items-center justify-center text-muted-foreground italic", children: "Waiting for orchestrator logs..." }) : logs.map((log, i) => /* @__PURE__ */ jsxs17("div", { className: "break-words", children: [
|
|
2267
|
+
/* @__PURE__ */ jsxs17("span", { className: "text-muted-foreground mr-3 select-none", children: [
|
|
2148
2268
|
"[",
|
|
2149
2269
|
log.timestamp || i.toString().padStart(4, "0"),
|
|
2150
2270
|
"]"
|
|
2151
2271
|
] }),
|
|
2152
|
-
/* @__PURE__ */
|
|
2272
|
+
/* @__PURE__ */ jsxs17("span", { className: "text-primary/70 mr-2", children: [
|
|
2153
2273
|
"[",
|
|
2154
2274
|
log.level,
|
|
2155
2275
|
"]"
|
|
2156
2276
|
] }),
|
|
2157
|
-
/* @__PURE__ */
|
|
2277
|
+
/* @__PURE__ */ jsxs17("span", { className: "text-muted-foreground mr-2", children: [
|
|
2158
2278
|
"[",
|
|
2159
2279
|
log.scope,
|
|
2160
2280
|
"]"
|
|
2161
2281
|
] }),
|
|
2162
|
-
/* @__PURE__ */
|
|
2282
|
+
/* @__PURE__ */ jsx18("span", { className: log.level.toUpperCase() === "ERROR" || log.message.toLowerCase().includes("failed") ? "text-destructive" : log.level.toUpperCase() === "WARN" ? "text-warning" : "text-foreground", children: log.message })
|
|
2163
2283
|
] }, `${log.timestamp}-${log.scope}-${i}`))
|
|
2164
2284
|
}
|
|
2165
2285
|
)
|
|
@@ -2170,50 +2290,50 @@ function SystemLogsViewer({ apiUrl, token, className }) {
|
|
|
2170
2290
|
import { Clock as Clock4, Layers, MessageSquare, DollarSign } from "lucide-react";
|
|
2171
2291
|
import { StatCard } from "@tangle-network/ui/primitives";
|
|
2172
2292
|
import { Skeleton as Skeleton4 } from "@tangle-network/ui/primitives";
|
|
2173
|
-
import { jsx as
|
|
2293
|
+
import { jsx as jsx19, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
2174
2294
|
function UsageSummary({ data, loading = false, className }) {
|
|
2175
2295
|
if (loading || !data) {
|
|
2176
|
-
return /* @__PURE__ */
|
|
2296
|
+
return /* @__PURE__ */ jsx19("div", { className: cn("grid grid-cols-2 gap-4 lg:grid-cols-4", className), children: Array.from({ length: 4 }).map((_, i) => /* @__PURE__ */ jsx19(Skeleton4, { className: "h-28 rounded-xl" }, i)) });
|
|
2177
2297
|
}
|
|
2178
|
-
return /* @__PURE__ */
|
|
2179
|
-
/* @__PURE__ */
|
|
2298
|
+
return /* @__PURE__ */ jsxs18("div", { className: cn("grid grid-cols-2 gap-4 lg:grid-cols-4", className), children: [
|
|
2299
|
+
/* @__PURE__ */ jsx19(
|
|
2180
2300
|
StatCard,
|
|
2181
2301
|
{
|
|
2182
2302
|
variant: "sandbox",
|
|
2183
2303
|
title: "Compute Hours",
|
|
2184
2304
|
value: data.computeHours.toFixed(1),
|
|
2185
2305
|
subtitle: "This billing period",
|
|
2186
|
-
icon: /* @__PURE__ */
|
|
2306
|
+
icon: /* @__PURE__ */ jsx19(Clock4, { className: "h-5 w-5" })
|
|
2187
2307
|
}
|
|
2188
2308
|
),
|
|
2189
|
-
/* @__PURE__ */
|
|
2309
|
+
/* @__PURE__ */ jsx19(
|
|
2190
2310
|
StatCard,
|
|
2191
2311
|
{
|
|
2192
2312
|
variant: "sandbox",
|
|
2193
2313
|
title: "Active Sessions",
|
|
2194
2314
|
value: data.activeSessions,
|
|
2195
2315
|
subtitle: "Currently running",
|
|
2196
|
-
icon: /* @__PURE__ */
|
|
2316
|
+
icon: /* @__PURE__ */ jsx19(Layers, { className: "h-5 w-5" })
|
|
2197
2317
|
}
|
|
2198
2318
|
),
|
|
2199
|
-
/* @__PURE__ */
|
|
2319
|
+
/* @__PURE__ */ jsx19(
|
|
2200
2320
|
StatCard,
|
|
2201
2321
|
{
|
|
2202
2322
|
variant: "sandbox",
|
|
2203
2323
|
title: "Messages Sent",
|
|
2204
2324
|
value: data.messagesSent.toLocaleString(),
|
|
2205
2325
|
subtitle: "Agent interactions",
|
|
2206
|
-
icon: /* @__PURE__ */
|
|
2326
|
+
icon: /* @__PURE__ */ jsx19(MessageSquare, { className: "h-5 w-5" })
|
|
2207
2327
|
}
|
|
2208
2328
|
),
|
|
2209
|
-
/* @__PURE__ */
|
|
2329
|
+
/* @__PURE__ */ jsx19(
|
|
2210
2330
|
StatCard,
|
|
2211
2331
|
{
|
|
2212
2332
|
variant: "sandbox",
|
|
2213
2333
|
title: "Estimated Cost",
|
|
2214
2334
|
value: `$${data.estimatedCost.toFixed(2)}`,
|
|
2215
2335
|
subtitle: "This billing period",
|
|
2216
|
-
icon: /* @__PURE__ */
|
|
2336
|
+
icon: /* @__PURE__ */ jsx19(DollarSign, { className: "h-5 w-5" })
|
|
2217
2337
|
}
|
|
2218
2338
|
)
|
|
2219
2339
|
] });
|
|
@@ -2221,66 +2341,66 @@ function UsageSummary({ data, loading = false, className }) {
|
|
|
2221
2341
|
|
|
2222
2342
|
// src/dashboard/git-panel.tsx
|
|
2223
2343
|
import { GitBranch, GitCommit, FileEdit, FilePlus, File } from "lucide-react";
|
|
2224
|
-
import { jsx as
|
|
2344
|
+
import { jsx as jsx20, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
2225
2345
|
function GitPanel({ status, log, loading = false, onRefresh, className }) {
|
|
2226
2346
|
if (loading) {
|
|
2227
|
-
return /* @__PURE__ */
|
|
2228
|
-
/* @__PURE__ */
|
|
2347
|
+
return /* @__PURE__ */ jsx20("div", { className: cn("rounded-lg border border-border bg-card p-5", className), children: /* @__PURE__ */ jsxs19("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [
|
|
2348
|
+
/* @__PURE__ */ jsx20("div", { className: "h-4 w-4 animate-spin rounded-full border-2 border-primary border-t-transparent" }),
|
|
2229
2349
|
"Loading git info..."
|
|
2230
2350
|
] }) });
|
|
2231
2351
|
}
|
|
2232
2352
|
if (!status) {
|
|
2233
|
-
return /* @__PURE__ */
|
|
2234
|
-
/* @__PURE__ */
|
|
2353
|
+
return /* @__PURE__ */ jsx20("div", { className: cn("rounded-lg border border-border bg-card p-5", className), children: /* @__PURE__ */ jsxs19("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [
|
|
2354
|
+
/* @__PURE__ */ jsx20(GitBranch, { className: "h-4 w-4" }),
|
|
2235
2355
|
"No git repository detected"
|
|
2236
2356
|
] }) });
|
|
2237
2357
|
}
|
|
2238
2358
|
const changedCount = status.staged.length + status.modified.length + status.untracked.length;
|
|
2239
|
-
return /* @__PURE__ */
|
|
2240
|
-
/* @__PURE__ */
|
|
2241
|
-
/* @__PURE__ */
|
|
2242
|
-
/* @__PURE__ */
|
|
2243
|
-
/* @__PURE__ */
|
|
2244
|
-
status.isDirty && /* @__PURE__ */
|
|
2359
|
+
return /* @__PURE__ */ jsxs19("div", { className: cn("rounded-lg border border-border bg-card overflow-hidden", className), children: [
|
|
2360
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex items-center justify-between border-b border-border bg-muted/30 px-4 py-3", children: [
|
|
2361
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex items-center gap-2", children: [
|
|
2362
|
+
/* @__PURE__ */ jsx20(GitBranch, { className: "h-4 w-4 text-primary" }),
|
|
2363
|
+
/* @__PURE__ */ jsx20("span", { className: "text-sm font-bold text-foreground", children: status.branch }),
|
|
2364
|
+
status.isDirty && /* @__PURE__ */ jsxs19("span", { className: "rounded-full bg-[var(--surface-warning-bg)] px-1.5 py-0.5 text-[10px] font-bold text-[var(--surface-warning-text)]", children: [
|
|
2245
2365
|
changedCount,
|
|
2246
2366
|
" change",
|
|
2247
2367
|
changedCount !== 1 ? "s" : ""
|
|
2248
2368
|
] })
|
|
2249
2369
|
] }),
|
|
2250
|
-
onRefresh && /* @__PURE__ */
|
|
2370
|
+
onRefresh && /* @__PURE__ */ jsx20("button", { type: "button", onClick: onRefresh, className: "text-xs text-muted-foreground hover:text-foreground transition-colors", children: "Refresh" })
|
|
2251
2371
|
] }),
|
|
2252
|
-
changedCount > 0 && /* @__PURE__ */
|
|
2253
|
-
status.staged.map((f) => /* @__PURE__ */
|
|
2254
|
-
/* @__PURE__ */
|
|
2255
|
-
/* @__PURE__ */
|
|
2256
|
-
/* @__PURE__ */
|
|
2372
|
+
changedCount > 0 && /* @__PURE__ */ jsx20("div", { className: "border-b border-border px-4 py-3", children: /* @__PURE__ */ jsxs19("div", { className: "space-y-1.5", children: [
|
|
2373
|
+
status.staged.map((f) => /* @__PURE__ */ jsxs19("div", { className: "flex items-center gap-2 text-xs", children: [
|
|
2374
|
+
/* @__PURE__ */ jsx20(FilePlus, { className: "h-3 w-3 text-[var(--surface-success-text)]" }),
|
|
2375
|
+
/* @__PURE__ */ jsx20("span", { className: "font-mono text-foreground truncate", children: f }),
|
|
2376
|
+
/* @__PURE__ */ jsx20("span", { className: "text-[var(--surface-success-text)] text-[10px] font-bold ml-auto", children: "STAGED" })
|
|
2257
2377
|
] }, `s-${f}`)),
|
|
2258
|
-
status.modified.map((f) => /* @__PURE__ */
|
|
2259
|
-
/* @__PURE__ */
|
|
2260
|
-
/* @__PURE__ */
|
|
2378
|
+
status.modified.map((f) => /* @__PURE__ */ jsxs19("div", { className: "flex items-center gap-2 text-xs", children: [
|
|
2379
|
+
/* @__PURE__ */ jsx20(FileEdit, { className: "h-3 w-3 text-[var(--surface-warning-text)]" }),
|
|
2380
|
+
/* @__PURE__ */ jsx20("span", { className: "font-mono text-foreground truncate", children: f })
|
|
2261
2381
|
] }, `m-${f}`)),
|
|
2262
|
-
status.untracked.map((f) => /* @__PURE__ */
|
|
2263
|
-
/* @__PURE__ */
|
|
2264
|
-
/* @__PURE__ */
|
|
2382
|
+
status.untracked.map((f) => /* @__PURE__ */ jsxs19("div", { className: "flex items-center gap-2 text-xs", children: [
|
|
2383
|
+
/* @__PURE__ */ jsx20(File, { className: "h-3 w-3 text-muted-foreground" }),
|
|
2384
|
+
/* @__PURE__ */ jsx20("span", { className: "font-mono text-muted-foreground truncate", children: f })
|
|
2265
2385
|
] }, `u-${f}`))
|
|
2266
2386
|
] }) }),
|
|
2267
|
-
log.length > 0 && /* @__PURE__ */
|
|
2268
|
-
/* @__PURE__ */
|
|
2269
|
-
/* @__PURE__ */
|
|
2270
|
-
/* @__PURE__ */
|
|
2271
|
-
/* @__PURE__ */
|
|
2272
|
-
/* @__PURE__ */
|
|
2273
|
-
/* @__PURE__ */
|
|
2387
|
+
log.length > 0 && /* @__PURE__ */ jsxs19("div", { className: "px-4 py-3", children: [
|
|
2388
|
+
/* @__PURE__ */ jsx20("div", { className: "mb-2 text-[10px] font-bold uppercase tracking-widest text-muted-foreground", children: "Recent Commits" }),
|
|
2389
|
+
/* @__PURE__ */ jsx20("div", { className: "space-y-2", children: log.slice(0, 5).map((commit) => /* @__PURE__ */ jsxs19("div", { className: "flex items-start gap-2 text-xs", children: [
|
|
2390
|
+
/* @__PURE__ */ jsx20(GitCommit, { className: "h-3 w-3 text-muted-foreground mt-0.5 shrink-0" }),
|
|
2391
|
+
/* @__PURE__ */ jsxs19("div", { className: "min-w-0", children: [
|
|
2392
|
+
/* @__PURE__ */ jsx20("span", { className: "font-mono text-primary mr-1.5", children: commit.shortSha }),
|
|
2393
|
+
/* @__PURE__ */ jsx20("span", { className: "text-foreground", children: commit.message })
|
|
2274
2394
|
] })
|
|
2275
2395
|
] }, commit.shortSha)) })
|
|
2276
2396
|
] }),
|
|
2277
|
-
(status.ahead > 0 || status.behind > 0) && /* @__PURE__ */
|
|
2278
|
-
status.ahead > 0 && /* @__PURE__ */
|
|
2397
|
+
(status.ahead > 0 || status.behind > 0) && /* @__PURE__ */ jsxs19("div", { className: "border-t border-border px-4 py-2 flex items-center gap-3 text-xs text-muted-foreground", children: [
|
|
2398
|
+
status.ahead > 0 && /* @__PURE__ */ jsxs19("span", { children: [
|
|
2279
2399
|
"\u2191 ",
|
|
2280
2400
|
status.ahead,
|
|
2281
2401
|
" ahead"
|
|
2282
2402
|
] }),
|
|
2283
|
-
status.behind > 0 && /* @__PURE__ */
|
|
2403
|
+
status.behind > 0 && /* @__PURE__ */ jsxs19("span", { children: [
|
|
2284
2404
|
"\u2193 ",
|
|
2285
2405
|
status.behind,
|
|
2286
2406
|
" behind"
|
|
@@ -2290,14 +2410,14 @@ function GitPanel({ status, log, loading = false, onRefresh, className }) {
|
|
|
2290
2410
|
}
|
|
2291
2411
|
|
|
2292
2412
|
// src/dashboard/ports-list.tsx
|
|
2293
|
-
import * as
|
|
2413
|
+
import * as React9 from "react";
|
|
2294
2414
|
import { Copy as Copy3, Check as Check4, Globe, Plus as Plus4, Trash2 as Trash23 } from "lucide-react";
|
|
2295
|
-
import { jsx as
|
|
2415
|
+
import { jsx as jsx21, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
2296
2416
|
function PortsList({ ports, onExposePort, onRemovePort, isExposing = false, className }) {
|
|
2297
|
-
const [newPort, setNewPort] =
|
|
2298
|
-
const [copiedPort, setCopiedPort] =
|
|
2299
|
-
const copyTimerRef =
|
|
2300
|
-
|
|
2417
|
+
const [newPort, setNewPort] = React9.useState("");
|
|
2418
|
+
const [copiedPort, setCopiedPort] = React9.useState(null);
|
|
2419
|
+
const copyTimerRef = React9.useRef(null);
|
|
2420
|
+
React9.useEffect(() => {
|
|
2301
2421
|
return () => {
|
|
2302
2422
|
if (copyTimerRef.current) clearTimeout(copyTimerRef.current);
|
|
2303
2423
|
};
|
|
@@ -2319,48 +2439,48 @@ function PortsList({ ports, onExposePort, onRemovePort, isExposing = false, clas
|
|
|
2319
2439
|
setNewPort("");
|
|
2320
2440
|
}
|
|
2321
2441
|
};
|
|
2322
|
-
return /* @__PURE__ */
|
|
2323
|
-
ports.length > 0 ? /* @__PURE__ */
|
|
2324
|
-
/* @__PURE__ */
|
|
2325
|
-
/* @__PURE__ */
|
|
2326
|
-
/* @__PURE__ */
|
|
2327
|
-
/* @__PURE__ */
|
|
2328
|
-
/* @__PURE__ */
|
|
2442
|
+
return /* @__PURE__ */ jsxs20("div", { className: cn("space-y-4", className), children: [
|
|
2443
|
+
ports.length > 0 ? /* @__PURE__ */ jsx21("div", { className: "rounded-lg border border-border overflow-hidden", children: /* @__PURE__ */ jsxs20("table", { className: "w-full text-sm", children: [
|
|
2444
|
+
/* @__PURE__ */ jsx21("thead", { className: "bg-muted/30 border-b border-border", children: /* @__PURE__ */ jsxs20("tr", { children: [
|
|
2445
|
+
/* @__PURE__ */ jsx21("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "Port" }),
|
|
2446
|
+
/* @__PURE__ */ jsx21("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "Public URL" }),
|
|
2447
|
+
/* @__PURE__ */ jsx21("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "Status" }),
|
|
2448
|
+
/* @__PURE__ */ jsx21("th", { className: "px-4 py-2.5 text-right text-xs font-medium text-muted-foreground w-20" })
|
|
2329
2449
|
] }) }),
|
|
2330
|
-
/* @__PURE__ */
|
|
2331
|
-
/* @__PURE__ */
|
|
2332
|
-
/* @__PURE__ */
|
|
2450
|
+
/* @__PURE__ */ jsx21("tbody", { className: "divide-y divide-border", children: ports.map((p) => /* @__PURE__ */ jsxs20("tr", { children: [
|
|
2451
|
+
/* @__PURE__ */ jsx21("td", { className: "px-4 py-3 font-mono text-xs text-foreground", children: p.port }),
|
|
2452
|
+
/* @__PURE__ */ jsx21("td", { className: "px-4 py-3", children: /* @__PURE__ */ jsxs20(
|
|
2333
2453
|
"button",
|
|
2334
2454
|
{
|
|
2335
2455
|
type: "button",
|
|
2336
2456
|
onClick: () => handleCopy(p.url, p.port),
|
|
2337
2457
|
className: "flex items-center gap-2 font-mono text-xs text-primary hover:underline cursor-pointer group",
|
|
2338
2458
|
children: [
|
|
2339
|
-
/* @__PURE__ */
|
|
2340
|
-
copiedPort === p.port ? /* @__PURE__ */
|
|
2459
|
+
/* @__PURE__ */ jsx21("span", { className: "truncate max-w-[300px]", children: p.url }),
|
|
2460
|
+
copiedPort === p.port ? /* @__PURE__ */ jsx21(Check4, { className: "h-3 w-3 text-[var(--surface-success-text)] shrink-0" }) : /* @__PURE__ */ jsx21(Copy3, { className: "h-3 w-3 opacity-0 group-hover:opacity-100 transition-opacity shrink-0" })
|
|
2341
2461
|
]
|
|
2342
2462
|
}
|
|
2343
2463
|
) }),
|
|
2344
|
-
/* @__PURE__ */
|
|
2464
|
+
/* @__PURE__ */ jsx21("td", { className: "px-4 py-3", children: /* @__PURE__ */ jsx21("span", { className: cn(
|
|
2345
2465
|
"inline-flex items-center gap-1.5 rounded-full px-2 py-0.5 text-[10px] font-bold uppercase tracking-wider",
|
|
2346
2466
|
p.status === "active" ? "bg-[var(--surface-success-bg)] text-[var(--surface-success-text)]" : "bg-[var(--surface-warning-bg)] text-[var(--surface-warning-text)]"
|
|
2347
2467
|
), children: p.status }) }),
|
|
2348
|
-
/* @__PURE__ */
|
|
2468
|
+
/* @__PURE__ */ jsx21("td", { className: "px-4 py-3 text-right", children: onRemovePort && /* @__PURE__ */ jsx21(
|
|
2349
2469
|
"button",
|
|
2350
2470
|
{
|
|
2351
2471
|
type: "button",
|
|
2352
2472
|
onClick: () => onRemovePort(p.port),
|
|
2353
2473
|
className: "p-1 text-muted-foreground hover:text-destructive transition-colors rounded",
|
|
2354
|
-
children: /* @__PURE__ */
|
|
2474
|
+
children: /* @__PURE__ */ jsx21(Trash23, { className: "h-3.5 w-3.5" })
|
|
2355
2475
|
}
|
|
2356
2476
|
) })
|
|
2357
2477
|
] }, p.port)) })
|
|
2358
|
-
] }) }) : /* @__PURE__ */
|
|
2359
|
-
/* @__PURE__ */
|
|
2360
|
-
/* @__PURE__ */
|
|
2478
|
+
] }) }) : /* @__PURE__ */ jsxs20("div", { className: "rounded-lg border border-border bg-muted/20 p-6 text-center", children: [
|
|
2479
|
+
/* @__PURE__ */ jsx21(Globe, { className: "mx-auto h-8 w-8 text-muted-foreground mb-2" }),
|
|
2480
|
+
/* @__PURE__ */ jsx21("p", { className: "text-sm text-muted-foreground", children: "No ports exposed yet" })
|
|
2361
2481
|
] }),
|
|
2362
|
-
/* @__PURE__ */
|
|
2363
|
-
/* @__PURE__ */
|
|
2482
|
+
/* @__PURE__ */ jsxs20("div", { className: "flex items-center gap-3", children: [
|
|
2483
|
+
/* @__PURE__ */ jsx21(
|
|
2364
2484
|
"input",
|
|
2365
2485
|
{
|
|
2366
2486
|
type: "number",
|
|
@@ -2373,7 +2493,7 @@ function PortsList({ ports, onExposePort, onRemovePort, isExposing = false, clas
|
|
|
2373
2493
|
className: "flex-1 rounded-lg border border-border bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring"
|
|
2374
2494
|
}
|
|
2375
2495
|
),
|
|
2376
|
-
/* @__PURE__ */
|
|
2496
|
+
/* @__PURE__ */ jsxs20(
|
|
2377
2497
|
"button",
|
|
2378
2498
|
{
|
|
2379
2499
|
type: "button",
|
|
@@ -2381,7 +2501,7 @@ function PortsList({ ports, onExposePort, onRemovePort, isExposing = false, clas
|
|
|
2381
2501
|
disabled: !newPort || isExposing,
|
|
2382
2502
|
className: "inline-flex items-center gap-2 rounded-lg bg-primary/20 border border-primary/30 px-4 py-2 text-sm font-medium text-primary hover:bg-primary hover:text-primary-foreground transition-colors disabled:opacity-50",
|
|
2383
2503
|
children: [
|
|
2384
|
-
/* @__PURE__ */
|
|
2504
|
+
/* @__PURE__ */ jsx21(Plus4, { className: "h-4 w-4" }),
|
|
2385
2505
|
"Expose"
|
|
2386
2506
|
]
|
|
2387
2507
|
}
|
|
@@ -2391,9 +2511,9 @@ function PortsList({ ports, onExposePort, onRemovePort, isExposing = false, clas
|
|
|
2391
2511
|
}
|
|
2392
2512
|
|
|
2393
2513
|
// src/dashboard/process-list.tsx
|
|
2394
|
-
import * as
|
|
2514
|
+
import * as React10 from "react";
|
|
2395
2515
|
import { Activity as Activity3, Plus as Plus5, Skull, Terminal as Terminal4 } from "lucide-react";
|
|
2396
|
-
import { jsx as
|
|
2516
|
+
import { jsx as jsx22, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
2397
2517
|
function formatUptime(startedAt) {
|
|
2398
2518
|
if (!startedAt) return "-";
|
|
2399
2519
|
const ms = Date.now() - new Date(startedAt).getTime();
|
|
@@ -2403,7 +2523,7 @@ function formatUptime(startedAt) {
|
|
|
2403
2523
|
return `${Math.floor(ms / 36e5)}h ${Math.floor(ms % 36e5 / 6e4)}m`;
|
|
2404
2524
|
}
|
|
2405
2525
|
function ProcessList({ processes, onSpawn, onKill, loading = false, className }) {
|
|
2406
|
-
const [newCommand, setNewCommand] =
|
|
2526
|
+
const [newCommand, setNewCommand] = React10.useState("");
|
|
2407
2527
|
const handleSpawn = () => {
|
|
2408
2528
|
const cmd = newCommand.trim();
|
|
2409
2529
|
if (cmd) {
|
|
@@ -2411,43 +2531,43 @@ function ProcessList({ processes, onSpawn, onKill, loading = false, className })
|
|
|
2411
2531
|
setNewCommand("");
|
|
2412
2532
|
}
|
|
2413
2533
|
};
|
|
2414
|
-
return /* @__PURE__ */
|
|
2415
|
-
loading ? /* @__PURE__ */
|
|
2416
|
-
/* @__PURE__ */
|
|
2417
|
-
/* @__PURE__ */
|
|
2418
|
-
] }) : processes.length > 0 ? /* @__PURE__ */
|
|
2419
|
-
/* @__PURE__ */
|
|
2420
|
-
/* @__PURE__ */
|
|
2421
|
-
/* @__PURE__ */
|
|
2422
|
-
/* @__PURE__ */
|
|
2423
|
-
/* @__PURE__ */
|
|
2424
|
-
/* @__PURE__ */
|
|
2534
|
+
return /* @__PURE__ */ jsxs21("div", { className: cn("space-y-4", className), children: [
|
|
2535
|
+
loading ? /* @__PURE__ */ jsxs21("div", { className: "rounded-lg border border-border bg-muted/20 p-6 text-center", children: [
|
|
2536
|
+
/* @__PURE__ */ jsx22(Activity3, { className: "mx-auto h-6 w-6 text-muted-foreground animate-spin mb-2" }),
|
|
2537
|
+
/* @__PURE__ */ jsx22("p", { className: "text-sm text-muted-foreground", children: "Loading processes..." })
|
|
2538
|
+
] }) : processes.length > 0 ? /* @__PURE__ */ jsx22("div", { className: "rounded-lg border border-border overflow-hidden", children: /* @__PURE__ */ jsxs21("table", { className: "w-full text-sm", children: [
|
|
2539
|
+
/* @__PURE__ */ jsx22("thead", { className: "bg-muted/30 border-b border-border", children: /* @__PURE__ */ jsxs21("tr", { children: [
|
|
2540
|
+
/* @__PURE__ */ jsx22("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "PID" }),
|
|
2541
|
+
/* @__PURE__ */ jsx22("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "Command" }),
|
|
2542
|
+
/* @__PURE__ */ jsx22("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "Status" }),
|
|
2543
|
+
/* @__PURE__ */ jsx22("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "Uptime" }),
|
|
2544
|
+
/* @__PURE__ */ jsx22("th", { className: "px-4 py-2.5 text-right text-xs font-medium text-muted-foreground w-20" })
|
|
2425
2545
|
] }) }),
|
|
2426
|
-
/* @__PURE__ */
|
|
2427
|
-
/* @__PURE__ */
|
|
2428
|
-
/* @__PURE__ */
|
|
2429
|
-
/* @__PURE__ */
|
|
2546
|
+
/* @__PURE__ */ jsx22("tbody", { className: "divide-y divide-border", children: processes.map((p) => /* @__PURE__ */ jsxs21("tr", { children: [
|
|
2547
|
+
/* @__PURE__ */ jsx22("td", { className: "px-4 py-3 font-mono text-xs text-foreground", children: p.pid }),
|
|
2548
|
+
/* @__PURE__ */ jsx22("td", { className: "px-4 py-3 font-mono text-xs text-foreground truncate max-w-[250px]", children: p.command }),
|
|
2549
|
+
/* @__PURE__ */ jsx22("td", { className: "px-4 py-3", children: /* @__PURE__ */ jsx22("span", { className: cn(
|
|
2430
2550
|
"inline-flex items-center gap-1.5 rounded-full px-2 py-0.5 text-[10px] font-bold uppercase tracking-wider",
|
|
2431
2551
|
p.running ? "bg-[var(--surface-success-bg)] text-[var(--surface-success-text)]" : "bg-muted text-muted-foreground"
|
|
2432
2552
|
), children: p.running ? "running" : `exited (${p.exitCode ?? "?"})` }) }),
|
|
2433
|
-
/* @__PURE__ */
|
|
2434
|
-
/* @__PURE__ */
|
|
2553
|
+
/* @__PURE__ */ jsx22("td", { className: "px-4 py-3 font-mono text-xs text-muted-foreground", children: formatUptime(p.startedAt) }),
|
|
2554
|
+
/* @__PURE__ */ jsx22("td", { className: "px-4 py-3 text-right", children: p.running && /* @__PURE__ */ jsx22(
|
|
2435
2555
|
"button",
|
|
2436
2556
|
{
|
|
2437
2557
|
type: "button",
|
|
2438
2558
|
onClick: () => onKill(p.pid),
|
|
2439
2559
|
className: "p-1 text-muted-foreground hover:text-destructive transition-colors rounded",
|
|
2440
2560
|
title: "Kill process",
|
|
2441
|
-
children: /* @__PURE__ */
|
|
2561
|
+
children: /* @__PURE__ */ jsx22(Skull, { className: "h-3.5 w-3.5" })
|
|
2442
2562
|
}
|
|
2443
2563
|
) })
|
|
2444
2564
|
] }, `${p.pid}-${p.startedAt ?? p.command}`)) })
|
|
2445
|
-
] }) }) : /* @__PURE__ */
|
|
2446
|
-
/* @__PURE__ */
|
|
2447
|
-
/* @__PURE__ */
|
|
2565
|
+
] }) }) : /* @__PURE__ */ jsxs21("div", { className: "rounded-lg border border-border bg-muted/20 p-6 text-center", children: [
|
|
2566
|
+
/* @__PURE__ */ jsx22(Terminal4, { className: "mx-auto h-8 w-8 text-muted-foreground mb-2" }),
|
|
2567
|
+
/* @__PURE__ */ jsx22("p", { className: "text-sm text-muted-foreground", children: "No processes running" })
|
|
2448
2568
|
] }),
|
|
2449
|
-
/* @__PURE__ */
|
|
2450
|
-
/* @__PURE__ */
|
|
2569
|
+
/* @__PURE__ */ jsxs21("div", { className: "flex items-center gap-3", children: [
|
|
2570
|
+
/* @__PURE__ */ jsx22(
|
|
2451
2571
|
"input",
|
|
2452
2572
|
{
|
|
2453
2573
|
type: "text",
|
|
@@ -2458,7 +2578,7 @@ function ProcessList({ processes, onSpawn, onKill, loading = false, className })
|
|
|
2458
2578
|
className: "flex-1 rounded-lg border border-border bg-background px-3 py-2 text-sm font-mono text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring"
|
|
2459
2579
|
}
|
|
2460
2580
|
),
|
|
2461
|
-
/* @__PURE__ */
|
|
2581
|
+
/* @__PURE__ */ jsxs21(
|
|
2462
2582
|
"button",
|
|
2463
2583
|
{
|
|
2464
2584
|
type: "button",
|
|
@@ -2466,7 +2586,7 @@ function ProcessList({ processes, onSpawn, onKill, loading = false, className })
|
|
|
2466
2586
|
disabled: !newCommand.trim(),
|
|
2467
2587
|
className: "inline-flex items-center gap-2 rounded-lg bg-primary/20 border border-primary/30 px-4 py-2 text-sm font-medium text-primary hover:bg-primary hover:text-primary-foreground transition-colors disabled:opacity-50",
|
|
2468
2588
|
children: [
|
|
2469
|
-
/* @__PURE__ */
|
|
2589
|
+
/* @__PURE__ */ jsx22(Plus5, { className: "h-4 w-4" }),
|
|
2470
2590
|
"Spawn"
|
|
2471
2591
|
]
|
|
2472
2592
|
}
|
|
@@ -2476,11 +2596,11 @@ function ProcessList({ processes, onSpawn, onKill, loading = false, className })
|
|
|
2476
2596
|
}
|
|
2477
2597
|
|
|
2478
2598
|
// src/dashboard/network-config.tsx
|
|
2479
|
-
import * as
|
|
2599
|
+
import * as React11 from "react";
|
|
2480
2600
|
import { Network as Network2, Plus as Plus6, Trash2 as Trash24, ShieldAlert } from "lucide-react";
|
|
2481
|
-
import { jsx as
|
|
2601
|
+
import { jsx as jsx23, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
2482
2602
|
function NetworkConfig({ config, onUpdate, loading = false, className }) {
|
|
2483
|
-
const [newCidr, setNewCidr] =
|
|
2603
|
+
const [newCidr, setNewCidr] = React11.useState("");
|
|
2484
2604
|
const isValidCidr = (value) => {
|
|
2485
2605
|
const match = value.match(/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\/(\d{1,2})$/);
|
|
2486
2606
|
if (!match) return false;
|
|
@@ -2501,21 +2621,21 @@ function NetworkConfig({ config, onUpdate, loading = false, className }) {
|
|
|
2501
2621
|
}
|
|
2502
2622
|
};
|
|
2503
2623
|
if (loading || !config) {
|
|
2504
|
-
return /* @__PURE__ */
|
|
2505
|
-
/* @__PURE__ */
|
|
2506
|
-
/* @__PURE__ */
|
|
2624
|
+
return /* @__PURE__ */ jsxs22("div", { className: cn("rounded-lg border border-border bg-muted/20 p-6 text-center", className), children: [
|
|
2625
|
+
/* @__PURE__ */ jsx23(Network2, { className: "mx-auto h-6 w-6 text-muted-foreground animate-pulse mb-2" }),
|
|
2626
|
+
/* @__PURE__ */ jsx23("p", { className: "text-sm text-muted-foreground", children: "Loading network configuration..." })
|
|
2507
2627
|
] });
|
|
2508
2628
|
}
|
|
2509
|
-
return /* @__PURE__ */
|
|
2510
|
-
/* @__PURE__ */
|
|
2511
|
-
/* @__PURE__ */
|
|
2512
|
-
/* @__PURE__ */
|
|
2513
|
-
/* @__PURE__ */
|
|
2514
|
-
/* @__PURE__ */
|
|
2515
|
-
/* @__PURE__ */
|
|
2629
|
+
return /* @__PURE__ */ jsxs22("div", { className: cn("space-y-4", className), children: [
|
|
2630
|
+
/* @__PURE__ */ jsxs22("div", { className: "flex items-center justify-between rounded-lg border border-border bg-card px-4 py-3", children: [
|
|
2631
|
+
/* @__PURE__ */ jsxs22("div", { className: "flex items-center gap-3", children: [
|
|
2632
|
+
/* @__PURE__ */ jsx23(ShieldAlert, { className: "h-4 w-4 text-muted-foreground" }),
|
|
2633
|
+
/* @__PURE__ */ jsxs22("div", { children: [
|
|
2634
|
+
/* @__PURE__ */ jsx23("p", { className: "text-sm font-medium text-foreground", children: "Block Outbound Traffic" }),
|
|
2635
|
+
/* @__PURE__ */ jsx23("p", { className: "text-xs text-muted-foreground", children: "Prevent the sandbox from making external network requests" })
|
|
2516
2636
|
] })
|
|
2517
2637
|
] }),
|
|
2518
|
-
/* @__PURE__ */
|
|
2638
|
+
/* @__PURE__ */ jsx23(
|
|
2519
2639
|
"button",
|
|
2520
2640
|
{
|
|
2521
2641
|
type: "button",
|
|
@@ -2527,7 +2647,7 @@ function NetworkConfig({ config, onUpdate, loading = false, className }) {
|
|
|
2527
2647
|
"relative inline-flex h-6 w-11 items-center rounded-full transition-colors",
|
|
2528
2648
|
config.blockOutbound ? "bg-destructive" : "bg-muted"
|
|
2529
2649
|
),
|
|
2530
|
-
children: /* @__PURE__ */
|
|
2650
|
+
children: /* @__PURE__ */ jsx23(
|
|
2531
2651
|
"span",
|
|
2532
2652
|
{
|
|
2533
2653
|
className: cn(
|
|
@@ -2539,22 +2659,22 @@ function NetworkConfig({ config, onUpdate, loading = false, className }) {
|
|
|
2539
2659
|
}
|
|
2540
2660
|
)
|
|
2541
2661
|
] }),
|
|
2542
|
-
/* @__PURE__ */
|
|
2543
|
-
/* @__PURE__ */
|
|
2544
|
-
config.allowList.length > 0 ? /* @__PURE__ */
|
|
2545
|
-
/* @__PURE__ */
|
|
2546
|
-
/* @__PURE__ */
|
|
2662
|
+
/* @__PURE__ */ jsxs22("div", { children: [
|
|
2663
|
+
/* @__PURE__ */ jsx23("h4", { className: "text-xs font-medium text-muted-foreground mb-2 uppercase tracking-wider", children: "Allowlist (CIDR)" }),
|
|
2664
|
+
config.allowList.length > 0 ? /* @__PURE__ */ jsx23("div", { className: "space-y-1.5 mb-3", children: config.allowList.map((cidr) => /* @__PURE__ */ jsxs22("div", { className: "flex items-center justify-between rounded border border-border bg-muted/20 px-3 py-2", children: [
|
|
2665
|
+
/* @__PURE__ */ jsx23("span", { className: "font-mono text-xs text-foreground", children: cidr }),
|
|
2666
|
+
/* @__PURE__ */ jsx23(
|
|
2547
2667
|
"button",
|
|
2548
2668
|
{
|
|
2549
2669
|
type: "button",
|
|
2550
2670
|
onClick: () => handleRemoveCidr(cidr),
|
|
2551
2671
|
className: "p-1 text-muted-foreground hover:text-destructive transition-colors rounded",
|
|
2552
|
-
children: /* @__PURE__ */
|
|
2672
|
+
children: /* @__PURE__ */ jsx23(Trash24, { className: "h-3 w-3" })
|
|
2553
2673
|
}
|
|
2554
2674
|
)
|
|
2555
|
-
] }, cidr)) }) : /* @__PURE__ */
|
|
2556
|
-
/* @__PURE__ */
|
|
2557
|
-
/* @__PURE__ */
|
|
2675
|
+
] }, cidr)) }) : /* @__PURE__ */ jsx23("p", { className: "text-xs text-muted-foreground mb-3", children: "No CIDR rules configured. All traffic is allowed." }),
|
|
2676
|
+
/* @__PURE__ */ jsxs22("div", { className: "flex items-center gap-3", children: [
|
|
2677
|
+
/* @__PURE__ */ jsx23(
|
|
2558
2678
|
"input",
|
|
2559
2679
|
{
|
|
2560
2680
|
type: "text",
|
|
@@ -2565,7 +2685,7 @@ function NetworkConfig({ config, onUpdate, loading = false, className }) {
|
|
|
2565
2685
|
className: "flex-1 rounded-lg border border-border bg-background px-3 py-2 text-sm font-mono text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring"
|
|
2566
2686
|
}
|
|
2567
2687
|
),
|
|
2568
|
-
/* @__PURE__ */
|
|
2688
|
+
/* @__PURE__ */ jsxs22(
|
|
2569
2689
|
"button",
|
|
2570
2690
|
{
|
|
2571
2691
|
type: "button",
|
|
@@ -2573,7 +2693,7 @@ function NetworkConfig({ config, onUpdate, loading = false, className }) {
|
|
|
2573
2693
|
disabled: !newCidr.trim(),
|
|
2574
2694
|
className: "inline-flex items-center gap-2 rounded-lg bg-primary/20 border border-primary/30 px-4 py-2 text-sm font-medium text-primary hover:bg-primary hover:text-primary-foreground transition-colors disabled:opacity-50",
|
|
2575
2695
|
children: [
|
|
2576
|
-
/* @__PURE__ */
|
|
2696
|
+
/* @__PURE__ */ jsx23(Plus6, { className: "h-4 w-4" }),
|
|
2577
2697
|
"Add"
|
|
2578
2698
|
]
|
|
2579
2699
|
}
|
|
@@ -2584,9 +2704,9 @@ function NetworkConfig({ config, onUpdate, loading = false, className }) {
|
|
|
2584
2704
|
}
|
|
2585
2705
|
|
|
2586
2706
|
// src/dashboard/backend-config.tsx
|
|
2587
|
-
import * as
|
|
2707
|
+
import * as React12 from "react";
|
|
2588
2708
|
import { Bot, Plus as Plus7, RefreshCw as RefreshCw2, Trash2 as Trash25, Server, Wrench } from "lucide-react";
|
|
2589
|
-
import { Fragment as Fragment11, jsx as
|
|
2709
|
+
import { Fragment as Fragment11, jsx as jsx24, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
2590
2710
|
function BackendConfig({
|
|
2591
2711
|
status,
|
|
2592
2712
|
mcpServers,
|
|
@@ -2596,10 +2716,10 @@ function BackendConfig({
|
|
|
2596
2716
|
loading = false,
|
|
2597
2717
|
className
|
|
2598
2718
|
}) {
|
|
2599
|
-
const [showAddMcp, setShowAddMcp] =
|
|
2600
|
-
const [mcpName, setMcpName] =
|
|
2601
|
-
const [mcpCommand, setMcpCommand] =
|
|
2602
|
-
const [mcpArgs, setMcpArgs] =
|
|
2719
|
+
const [showAddMcp, setShowAddMcp] = React12.useState(false);
|
|
2720
|
+
const [mcpName, setMcpName] = React12.useState("");
|
|
2721
|
+
const [mcpCommand, setMcpCommand] = React12.useState("");
|
|
2722
|
+
const [mcpArgs, setMcpArgs] = React12.useState("");
|
|
2603
2723
|
const handleAddMcp = () => {
|
|
2604
2724
|
const name = mcpName.trim();
|
|
2605
2725
|
const command = mcpCommand.trim();
|
|
@@ -2616,91 +2736,91 @@ function BackendConfig({
|
|
|
2616
2736
|
}
|
|
2617
2737
|
};
|
|
2618
2738
|
if (loading || !status) {
|
|
2619
|
-
return /* @__PURE__ */
|
|
2620
|
-
/* @__PURE__ */
|
|
2621
|
-
/* @__PURE__ */
|
|
2739
|
+
return /* @__PURE__ */ jsxs23("div", { className: cn("rounded-lg border border-border bg-muted/20 p-6 text-center", className), children: [
|
|
2740
|
+
/* @__PURE__ */ jsx24(Bot, { className: "mx-auto h-6 w-6 text-muted-foreground animate-pulse mb-2" }),
|
|
2741
|
+
/* @__PURE__ */ jsx24("p", { className: "text-sm text-muted-foreground", children: "Loading backend status..." })
|
|
2622
2742
|
] });
|
|
2623
2743
|
}
|
|
2624
|
-
return /* @__PURE__ */
|
|
2625
|
-
/* @__PURE__ */
|
|
2626
|
-
/* @__PURE__ */
|
|
2627
|
-
/* @__PURE__ */
|
|
2628
|
-
/* @__PURE__ */
|
|
2744
|
+
return /* @__PURE__ */ jsxs23("div", { className: cn("space-y-4", className), children: [
|
|
2745
|
+
/* @__PURE__ */ jsxs23("div", { className: "rounded-lg border border-border bg-card overflow-hidden", children: [
|
|
2746
|
+
/* @__PURE__ */ jsxs23("div", { className: "px-4 py-3 border-b border-border bg-muted/30 flex items-center justify-between", children: [
|
|
2747
|
+
/* @__PURE__ */ jsx24("h4", { className: "text-xs font-medium text-muted-foreground uppercase tracking-wider", children: "Agent Status" }),
|
|
2748
|
+
/* @__PURE__ */ jsxs23(
|
|
2629
2749
|
"button",
|
|
2630
2750
|
{
|
|
2631
2751
|
type: "button",
|
|
2632
2752
|
onClick: onRestart,
|
|
2633
2753
|
className: "inline-flex items-center gap-1.5 rounded-md bg-muted px-2.5 py-1 text-xs font-medium text-foreground hover:bg-muted/80 transition-colors border border-border",
|
|
2634
2754
|
children: [
|
|
2635
|
-
/* @__PURE__ */
|
|
2755
|
+
/* @__PURE__ */ jsx24(RefreshCw2, { className: "h-3 w-3" }),
|
|
2636
2756
|
"Restart"
|
|
2637
2757
|
]
|
|
2638
2758
|
}
|
|
2639
2759
|
)
|
|
2640
2760
|
] }),
|
|
2641
|
-
/* @__PURE__ */
|
|
2642
|
-
/* @__PURE__ */
|
|
2643
|
-
/* @__PURE__ */
|
|
2761
|
+
/* @__PURE__ */ jsx24("div", { className: "p-4", children: /* @__PURE__ */ jsxs23("dl", { className: "grid grid-cols-[100px_1fr] gap-y-3 text-sm", children: [
|
|
2762
|
+
/* @__PURE__ */ jsx24("dt", { className: "text-muted-foreground", children: "Status" }),
|
|
2763
|
+
/* @__PURE__ */ jsx24("dd", { children: /* @__PURE__ */ jsx24("span", { className: cn(
|
|
2644
2764
|
"inline-flex items-center gap-1.5 rounded-full px-2 py-0.5 text-[10px] font-bold uppercase tracking-wider",
|
|
2645
2765
|
status.running ? "bg-[var(--surface-success-bg)] text-[var(--surface-success-text)]" : "bg-destructive/10 text-destructive"
|
|
2646
2766
|
), children: status.running ? "Running" : "Stopped" }) }),
|
|
2647
|
-
/* @__PURE__ */
|
|
2648
|
-
/* @__PURE__ */
|
|
2649
|
-
status.provider && /* @__PURE__ */
|
|
2650
|
-
/* @__PURE__ */
|
|
2651
|
-
/* @__PURE__ */
|
|
2767
|
+
/* @__PURE__ */ jsx24("dt", { className: "text-muted-foreground", children: "Model" }),
|
|
2768
|
+
/* @__PURE__ */ jsx24("dd", { className: "font-mono text-xs", children: status.model ?? "Default" }),
|
|
2769
|
+
status.provider && /* @__PURE__ */ jsxs23(Fragment11, { children: [
|
|
2770
|
+
/* @__PURE__ */ jsx24("dt", { className: "text-muted-foreground", children: "Provider" }),
|
|
2771
|
+
/* @__PURE__ */ jsx24("dd", { className: "font-mono text-xs", children: status.provider })
|
|
2652
2772
|
] })
|
|
2653
2773
|
] }) })
|
|
2654
2774
|
] }),
|
|
2655
|
-
/* @__PURE__ */
|
|
2656
|
-
/* @__PURE__ */
|
|
2657
|
-
/* @__PURE__ */
|
|
2658
|
-
/* @__PURE__ */
|
|
2775
|
+
/* @__PURE__ */ jsxs23("div", { className: "rounded-lg border border-border bg-card overflow-hidden", children: [
|
|
2776
|
+
/* @__PURE__ */ jsxs23("div", { className: "px-4 py-3 border-b border-border bg-muted/30 flex items-center justify-between", children: [
|
|
2777
|
+
/* @__PURE__ */ jsxs23("h4", { className: "text-xs font-medium text-muted-foreground uppercase tracking-wider flex items-center gap-2", children: [
|
|
2778
|
+
/* @__PURE__ */ jsx24(Wrench, { className: "h-3.5 w-3.5" }),
|
|
2659
2779
|
"MCP Servers"
|
|
2660
2780
|
] }),
|
|
2661
|
-
/* @__PURE__ */
|
|
2781
|
+
/* @__PURE__ */ jsxs23(
|
|
2662
2782
|
"button",
|
|
2663
2783
|
{
|
|
2664
2784
|
type: "button",
|
|
2665
2785
|
onClick: () => setShowAddMcp(!showAddMcp),
|
|
2666
2786
|
className: "inline-flex items-center gap-1.5 rounded-md bg-primary/20 border border-primary/30 px-2.5 py-1 text-xs font-medium text-primary hover:bg-primary hover:text-primary-foreground transition-colors",
|
|
2667
2787
|
children: [
|
|
2668
|
-
/* @__PURE__ */
|
|
2788
|
+
/* @__PURE__ */ jsx24(Plus7, { className: "h-3 w-3" }),
|
|
2669
2789
|
"Add"
|
|
2670
2790
|
]
|
|
2671
2791
|
}
|
|
2672
2792
|
)
|
|
2673
2793
|
] }),
|
|
2674
|
-
mcpServers.length > 0 ? /* @__PURE__ */
|
|
2675
|
-
/* @__PURE__ */
|
|
2676
|
-
/* @__PURE__ */
|
|
2677
|
-
/* @__PURE__ */
|
|
2678
|
-
/* @__PURE__ */
|
|
2679
|
-
/* @__PURE__ */
|
|
2794
|
+
mcpServers.length > 0 ? /* @__PURE__ */ jsx24("div", { className: "divide-y divide-border", children: mcpServers.map((s) => /* @__PURE__ */ jsxs23("div", { className: "flex items-center justify-between px-4 py-3", children: [
|
|
2795
|
+
/* @__PURE__ */ jsxs23("div", { className: "flex items-center gap-3 min-w-0", children: [
|
|
2796
|
+
/* @__PURE__ */ jsx24(Server, { className: "h-3.5 w-3.5 text-muted-foreground shrink-0" }),
|
|
2797
|
+
/* @__PURE__ */ jsxs23("div", { className: "min-w-0", children: [
|
|
2798
|
+
/* @__PURE__ */ jsx24("p", { className: "text-sm font-medium text-foreground truncate", children: s.name }),
|
|
2799
|
+
/* @__PURE__ */ jsxs23("p", { className: "text-xs font-mono text-muted-foreground truncate", children: [
|
|
2680
2800
|
s.command,
|
|
2681
2801
|
" ",
|
|
2682
2802
|
s.args?.join(" ") ?? ""
|
|
2683
2803
|
] })
|
|
2684
2804
|
] })
|
|
2685
2805
|
] }),
|
|
2686
|
-
/* @__PURE__ */
|
|
2687
|
-
s.status && /* @__PURE__ */
|
|
2806
|
+
/* @__PURE__ */ jsxs23("div", { className: "flex items-center gap-2 shrink-0", children: [
|
|
2807
|
+
s.status && /* @__PURE__ */ jsx24("span", { className: cn(
|
|
2688
2808
|
"inline-flex items-center rounded-full px-1.5 py-0.5 text-[9px] font-bold uppercase",
|
|
2689
2809
|
s.status === "running" ? "bg-[var(--surface-success-bg)] text-[var(--surface-success-text)]" : s.status === "error" ? "bg-destructive/10 text-destructive" : "bg-muted text-muted-foreground"
|
|
2690
2810
|
), children: s.status }),
|
|
2691
|
-
/* @__PURE__ */
|
|
2811
|
+
/* @__PURE__ */ jsx24(
|
|
2692
2812
|
"button",
|
|
2693
2813
|
{
|
|
2694
2814
|
type: "button",
|
|
2695
2815
|
onClick: () => onRemoveMcp(s.name),
|
|
2696
2816
|
className: "p-1 text-muted-foreground hover:text-destructive transition-colors rounded",
|
|
2697
|
-
children: /* @__PURE__ */
|
|
2817
|
+
children: /* @__PURE__ */ jsx24(Trash25, { className: "h-3.5 w-3.5" })
|
|
2698
2818
|
}
|
|
2699
2819
|
)
|
|
2700
2820
|
] })
|
|
2701
|
-
] }, s.name)) }) : /* @__PURE__ */
|
|
2702
|
-
showAddMcp && /* @__PURE__ */
|
|
2703
|
-
/* @__PURE__ */
|
|
2821
|
+
] }, s.name)) }) : /* @__PURE__ */ jsx24("div", { className: "p-4 text-center", children: /* @__PURE__ */ jsx24("p", { className: "text-xs text-muted-foreground", children: "No MCP servers configured" }) }),
|
|
2822
|
+
showAddMcp && /* @__PURE__ */ jsxs23("div", { className: "p-4 border-t border-border bg-muted/10 space-y-2", children: [
|
|
2823
|
+
/* @__PURE__ */ jsx24(
|
|
2704
2824
|
"input",
|
|
2705
2825
|
{
|
|
2706
2826
|
type: "text",
|
|
@@ -2710,7 +2830,7 @@ function BackendConfig({
|
|
|
2710
2830
|
className: "w-full rounded-lg border border-border bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring"
|
|
2711
2831
|
}
|
|
2712
2832
|
),
|
|
2713
|
-
/* @__PURE__ */
|
|
2833
|
+
/* @__PURE__ */ jsx24(
|
|
2714
2834
|
"input",
|
|
2715
2835
|
{
|
|
2716
2836
|
type: "text",
|
|
@@ -2720,7 +2840,7 @@ function BackendConfig({
|
|
|
2720
2840
|
className: "w-full rounded-lg border border-border bg-background px-3 py-2 text-sm font-mono text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring"
|
|
2721
2841
|
}
|
|
2722
2842
|
),
|
|
2723
|
-
/* @__PURE__ */
|
|
2843
|
+
/* @__PURE__ */ jsx24(
|
|
2724
2844
|
"input",
|
|
2725
2845
|
{
|
|
2726
2846
|
type: "text",
|
|
@@ -2730,8 +2850,8 @@ function BackendConfig({
|
|
|
2730
2850
|
className: "w-full rounded-lg border border-border bg-background px-3 py-2 text-sm font-mono text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring"
|
|
2731
2851
|
}
|
|
2732
2852
|
),
|
|
2733
|
-
/* @__PURE__ */
|
|
2734
|
-
/* @__PURE__ */
|
|
2853
|
+
/* @__PURE__ */ jsxs23("div", { className: "flex justify-end gap-2 pt-1", children: [
|
|
2854
|
+
/* @__PURE__ */ jsx24(
|
|
2735
2855
|
"button",
|
|
2736
2856
|
{
|
|
2737
2857
|
type: "button",
|
|
@@ -2740,7 +2860,7 @@ function BackendConfig({
|
|
|
2740
2860
|
children: "Cancel"
|
|
2741
2861
|
}
|
|
2742
2862
|
),
|
|
2743
|
-
/* @__PURE__ */
|
|
2863
|
+
/* @__PURE__ */ jsx24(
|
|
2744
2864
|
"button",
|
|
2745
2865
|
{
|
|
2746
2866
|
type: "button",
|
|
@@ -2757,9 +2877,9 @@ function BackendConfig({
|
|
|
2757
2877
|
}
|
|
2758
2878
|
|
|
2759
2879
|
// src/dashboard/snapshot-list.tsx
|
|
2760
|
-
import * as
|
|
2880
|
+
import * as React13 from "react";
|
|
2761
2881
|
import { Camera, Clock as Clock5, HardDrive, Plus as Plus8, RotateCcw } from "lucide-react";
|
|
2762
|
-
import { jsx as
|
|
2882
|
+
import { jsx as jsx25, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
2763
2883
|
function formatBytes(bytes) {
|
|
2764
2884
|
if (bytes == null || bytes < 0) return "-";
|
|
2765
2885
|
if (bytes === 0) return "0 B";
|
|
@@ -2774,33 +2894,33 @@ function formatDate(dateStr) {
|
|
|
2774
2894
|
return d.toLocaleDateString(void 0, { month: "short", day: "numeric", hour: "2-digit", minute: "2-digit" });
|
|
2775
2895
|
}
|
|
2776
2896
|
function SnapshotList({ snapshots, onCreate, onRestore, onSaveAsTemplate, loading = false, className }) {
|
|
2777
|
-
const [showCreate, setShowCreate] =
|
|
2778
|
-
const [tags, setTags] =
|
|
2897
|
+
const [showCreate, setShowCreate] = React13.useState(false);
|
|
2898
|
+
const [tags, setTags] = React13.useState("");
|
|
2779
2899
|
const handleCreate = () => {
|
|
2780
2900
|
const tagList = tags.trim() ? tags.trim().split(",").map((t) => t.trim()).filter(Boolean) : void 0;
|
|
2781
2901
|
onCreate(tagList);
|
|
2782
2902
|
setTags("");
|
|
2783
2903
|
setShowCreate(false);
|
|
2784
2904
|
};
|
|
2785
|
-
return /* @__PURE__ */
|
|
2786
|
-
/* @__PURE__ */
|
|
2787
|
-
/* @__PURE__ */
|
|
2788
|
-
/* @__PURE__ */
|
|
2905
|
+
return /* @__PURE__ */ jsxs24("div", { className: cn("space-y-4", className), children: [
|
|
2906
|
+
/* @__PURE__ */ jsxs24("div", { className: "flex items-center justify-between", children: [
|
|
2907
|
+
/* @__PURE__ */ jsx25("h3", { className: "text-sm font-bold text-foreground", children: "Snapshots" }),
|
|
2908
|
+
/* @__PURE__ */ jsxs24(
|
|
2789
2909
|
"button",
|
|
2790
2910
|
{
|
|
2791
2911
|
type: "button",
|
|
2792
2912
|
onClick: () => setShowCreate(!showCreate),
|
|
2793
2913
|
className: "inline-flex items-center gap-1.5 rounded-lg bg-primary/20 border border-primary/30 px-3 py-1.5 text-xs font-medium text-primary hover:bg-primary hover:text-primary-foreground transition-colors",
|
|
2794
2914
|
children: [
|
|
2795
|
-
/* @__PURE__ */
|
|
2915
|
+
/* @__PURE__ */ jsx25(Plus8, { className: "h-3.5 w-3.5" }),
|
|
2796
2916
|
"Create Snapshot"
|
|
2797
2917
|
]
|
|
2798
2918
|
}
|
|
2799
2919
|
)
|
|
2800
2920
|
] }),
|
|
2801
|
-
showCreate && /* @__PURE__ */
|
|
2802
|
-
/* @__PURE__ */
|
|
2803
|
-
/* @__PURE__ */
|
|
2921
|
+
showCreate && /* @__PURE__ */ jsxs24("div", { className: "rounded-lg border border-primary/20 bg-primary/5 p-4 space-y-3", children: [
|
|
2922
|
+
/* @__PURE__ */ jsx25("p", { className: "text-sm text-foreground font-medium", children: "Create a new snapshot of the current sandbox state." }),
|
|
2923
|
+
/* @__PURE__ */ jsx25(
|
|
2804
2924
|
"input",
|
|
2805
2925
|
{
|
|
2806
2926
|
type: "text",
|
|
@@ -2811,8 +2931,8 @@ function SnapshotList({ snapshots, onCreate, onRestore, onSaveAsTemplate, loadin
|
|
|
2811
2931
|
className: "w-full rounded-lg border border-border bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring"
|
|
2812
2932
|
}
|
|
2813
2933
|
),
|
|
2814
|
-
/* @__PURE__ */
|
|
2815
|
-
/* @__PURE__ */
|
|
2934
|
+
/* @__PURE__ */ jsxs24("div", { className: "flex justify-end gap-2", children: [
|
|
2935
|
+
/* @__PURE__ */ jsx25(
|
|
2816
2936
|
"button",
|
|
2817
2937
|
{
|
|
2818
2938
|
type: "button",
|
|
@@ -2821,44 +2941,44 @@ function SnapshotList({ snapshots, onCreate, onRestore, onSaveAsTemplate, loadin
|
|
|
2821
2941
|
children: "Cancel"
|
|
2822
2942
|
}
|
|
2823
2943
|
),
|
|
2824
|
-
/* @__PURE__ */
|
|
2944
|
+
/* @__PURE__ */ jsxs24(
|
|
2825
2945
|
"button",
|
|
2826
2946
|
{
|
|
2827
2947
|
type: "button",
|
|
2828
2948
|
onClick: handleCreate,
|
|
2829
2949
|
className: "rounded-md bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90 transition-colors",
|
|
2830
2950
|
children: [
|
|
2831
|
-
/* @__PURE__ */
|
|
2951
|
+
/* @__PURE__ */ jsx25(Camera, { className: "h-3 w-3 mr-1.5 inline" }),
|
|
2832
2952
|
"Create"
|
|
2833
2953
|
]
|
|
2834
2954
|
}
|
|
2835
2955
|
)
|
|
2836
2956
|
] })
|
|
2837
2957
|
] }),
|
|
2838
|
-
loading ? /* @__PURE__ */
|
|
2839
|
-
/* @__PURE__ */
|
|
2840
|
-
/* @__PURE__ */
|
|
2841
|
-
] }) : snapshots.length > 0 ? /* @__PURE__ */
|
|
2842
|
-
/* @__PURE__ */
|
|
2843
|
-
/* @__PURE__ */
|
|
2844
|
-
/* @__PURE__ */
|
|
2845
|
-
/* @__PURE__ */
|
|
2846
|
-
/* @__PURE__ */
|
|
2847
|
-
/* @__PURE__ */
|
|
2958
|
+
loading ? /* @__PURE__ */ jsxs24("div", { className: "rounded-lg border border-border bg-muted/20 p-6 text-center", children: [
|
|
2959
|
+
/* @__PURE__ */ jsx25(Camera, { className: "mx-auto h-6 w-6 text-muted-foreground animate-pulse mb-2" }),
|
|
2960
|
+
/* @__PURE__ */ jsx25("p", { className: "text-sm text-muted-foreground", children: "Loading snapshots..." })
|
|
2961
|
+
] }) : snapshots.length > 0 ? /* @__PURE__ */ jsx25("div", { className: "rounded-lg border border-border overflow-hidden", children: /* @__PURE__ */ jsxs24("table", { className: "w-full text-sm", children: [
|
|
2962
|
+
/* @__PURE__ */ jsx25("thead", { className: "bg-muted/30 border-b border-border", children: /* @__PURE__ */ jsxs24("tr", { children: [
|
|
2963
|
+
/* @__PURE__ */ jsx25("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "ID" }),
|
|
2964
|
+
/* @__PURE__ */ jsx25("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "Created" }),
|
|
2965
|
+
/* @__PURE__ */ jsx25("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "Size" }),
|
|
2966
|
+
/* @__PURE__ */ jsx25("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "Tags" }),
|
|
2967
|
+
/* @__PURE__ */ jsx25("th", { className: "px-4 py-2.5 text-right text-xs font-medium text-muted-foreground w-24" })
|
|
2848
2968
|
] }) }),
|
|
2849
|
-
/* @__PURE__ */
|
|
2850
|
-
/* @__PURE__ */
|
|
2851
|
-
/* @__PURE__ */
|
|
2852
|
-
/* @__PURE__ */
|
|
2969
|
+
/* @__PURE__ */ jsx25("tbody", { className: "divide-y divide-border", children: snapshots.map((s) => /* @__PURE__ */ jsxs24("tr", { children: [
|
|
2970
|
+
/* @__PURE__ */ jsx25("td", { className: "px-4 py-3 font-mono text-xs text-foreground", children: s.id.slice(0, 12) }),
|
|
2971
|
+
/* @__PURE__ */ jsx25("td", { className: "px-4 py-3 text-xs text-muted-foreground", children: /* @__PURE__ */ jsxs24("span", { className: "inline-flex items-center gap-1.5", children: [
|
|
2972
|
+
/* @__PURE__ */ jsx25(Clock5, { className: "h-3 w-3" }),
|
|
2853
2973
|
formatDate(s.createdAt)
|
|
2854
2974
|
] }) }),
|
|
2855
|
-
/* @__PURE__ */
|
|
2856
|
-
/* @__PURE__ */
|
|
2975
|
+
/* @__PURE__ */ jsx25("td", { className: "px-4 py-3 text-xs text-muted-foreground", children: /* @__PURE__ */ jsxs24("span", { className: "inline-flex items-center gap-1.5", children: [
|
|
2976
|
+
/* @__PURE__ */ jsx25(HardDrive, { className: "h-3 w-3" }),
|
|
2857
2977
|
formatBytes(s.sizeBytes)
|
|
2858
2978
|
] }) }),
|
|
2859
|
-
/* @__PURE__ */
|
|
2860
|
-
/* @__PURE__ */
|
|
2861
|
-
/* @__PURE__ */
|
|
2979
|
+
/* @__PURE__ */ jsx25("td", { className: "px-4 py-3", children: s.tags?.length ? /* @__PURE__ */ jsx25("div", { className: "flex items-center gap-1 flex-wrap", children: s.tags.map((tag) => /* @__PURE__ */ jsx25("span", { className: "rounded-full bg-muted px-2 py-0.5 text-[10px] font-medium text-muted-foreground border border-border", children: tag }, tag)) }) : /* @__PURE__ */ jsx25("span", { className: "text-xs text-muted-foreground", children: "-" }) }),
|
|
2980
|
+
/* @__PURE__ */ jsx25("td", { className: "px-4 py-3 text-right", children: /* @__PURE__ */ jsxs24("div", { className: "flex items-center justify-end gap-2", children: [
|
|
2981
|
+
/* @__PURE__ */ jsxs24(
|
|
2862
2982
|
"button",
|
|
2863
2983
|
{
|
|
2864
2984
|
type: "button",
|
|
@@ -2866,12 +2986,12 @@ function SnapshotList({ snapshots, onCreate, onRestore, onSaveAsTemplate, loadin
|
|
|
2866
2986
|
className: "inline-flex items-center gap-1.5 rounded-md bg-muted px-2.5 py-1 text-xs font-medium text-foreground hover:bg-muted/80 transition-colors border border-border",
|
|
2867
2987
|
title: "Restore to new sandbox",
|
|
2868
2988
|
children: [
|
|
2869
|
-
/* @__PURE__ */
|
|
2989
|
+
/* @__PURE__ */ jsx25(RotateCcw, { className: "h-3 w-3" }),
|
|
2870
2990
|
"Restore"
|
|
2871
2991
|
]
|
|
2872
2992
|
}
|
|
2873
2993
|
),
|
|
2874
|
-
onSaveAsTemplate && /* @__PURE__ */
|
|
2994
|
+
onSaveAsTemplate && /* @__PURE__ */ jsx25(
|
|
2875
2995
|
"button",
|
|
2876
2996
|
{
|
|
2877
2997
|
type: "button",
|
|
@@ -2883,16 +3003,16 @@ function SnapshotList({ snapshots, onCreate, onRestore, onSaveAsTemplate, loadin
|
|
|
2883
3003
|
)
|
|
2884
3004
|
] }) })
|
|
2885
3005
|
] }, s.id)) })
|
|
2886
|
-
] }) }) : /* @__PURE__ */
|
|
2887
|
-
/* @__PURE__ */
|
|
2888
|
-
/* @__PURE__ */
|
|
2889
|
-
/* @__PURE__ */
|
|
3006
|
+
] }) }) : /* @__PURE__ */ jsxs24("div", { className: "rounded-lg border border-border bg-muted/20 p-6 text-center", children: [
|
|
3007
|
+
/* @__PURE__ */ jsx25(Camera, { className: "mx-auto h-8 w-8 text-muted-foreground mb-2" }),
|
|
3008
|
+
/* @__PURE__ */ jsx25("p", { className: "text-sm text-muted-foreground", children: "No snapshots yet" }),
|
|
3009
|
+
/* @__PURE__ */ jsx25("p", { className: "text-xs text-muted-foreground mt-1", children: "Create a snapshot to save the current state of your sandbox." })
|
|
2890
3010
|
] })
|
|
2891
3011
|
] });
|
|
2892
3012
|
}
|
|
2893
3013
|
|
|
2894
3014
|
// src/dashboard/promo-banner.tsx
|
|
2895
|
-
import { Fragment as Fragment12, jsx as
|
|
3015
|
+
import { Fragment as Fragment12, jsx as jsx26, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
2896
3016
|
function PromoBanner({
|
|
2897
3017
|
title,
|
|
2898
3018
|
description,
|
|
@@ -2907,21 +3027,21 @@ function PromoBanner({
|
|
|
2907
3027
|
"mt-6 inline-flex items-center gap-2 rounded-md border border-white/20 bg-[var(--btn-primary-bg)] px-4 py-2 text-sm font-medium text-[var(--btn-primary-text)] transition-colors",
|
|
2908
3028
|
disabled ? "opacity-50 cursor-not-allowed" : "hover:bg-[var(--btn-primary-hover)]"
|
|
2909
3029
|
);
|
|
2910
|
-
const buttonContent = /* @__PURE__ */
|
|
3030
|
+
const buttonContent = /* @__PURE__ */ jsxs25(Fragment12, { children: [
|
|
2911
3031
|
buttonLabel,
|
|
2912
|
-
/* @__PURE__ */
|
|
2913
|
-
/* @__PURE__ */
|
|
2914
|
-
/* @__PURE__ */
|
|
3032
|
+
/* @__PURE__ */ jsxs25("svg", { "aria-hidden": "true", xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className: "h-4 w-4", children: [
|
|
3033
|
+
/* @__PURE__ */ jsx26("path", { d: "M5 12h14" }),
|
|
3034
|
+
/* @__PURE__ */ jsx26("path", { d: "m12 5 7 7-7 7" })
|
|
2915
3035
|
] })
|
|
2916
3036
|
] });
|
|
2917
|
-
return /* @__PURE__ */
|
|
2918
|
-
/* @__PURE__ */
|
|
2919
|
-
/* @__PURE__ */
|
|
2920
|
-
/* @__PURE__ */
|
|
2921
|
-
href && !disabled ? /* @__PURE__ */
|
|
3037
|
+
return /* @__PURE__ */ jsxs25("div", { className: cn("relative overflow-hidden rounded-xl bg-[var(--brand-strong)] p-8 md:flex md:items-center md:justify-between", className), children: [
|
|
3038
|
+
/* @__PURE__ */ jsxs25("div", { className: "relative z-10", children: [
|
|
3039
|
+
/* @__PURE__ */ jsx26("h3", { className: "text-xl font-bold text-[var(--brand-strong-text)]", children: title }),
|
|
3040
|
+
/* @__PURE__ */ jsx26("p", { className: "mt-2 max-w-md text-sm text-[var(--brand-strong-text-muted)]", children: description }),
|
|
3041
|
+
href && !disabled ? /* @__PURE__ */ jsx26("a", { href, target: "_blank", rel: "noopener noreferrer", onClick, className: buttonClasses, children: buttonContent }) : /* @__PURE__ */ jsx26("button", { type: "button", onClick, disabled, className: buttonClasses, children: buttonContent })
|
|
2922
3042
|
] }),
|
|
2923
|
-
icon && /* @__PURE__ */
|
|
2924
|
-
/* @__PURE__ */
|
|
3043
|
+
icon && /* @__PURE__ */ jsx26("div", { className: "relative z-10 mt-6 flex items-center md:mt-0", children: /* @__PURE__ */ jsx26("div", { className: "flex h-16 w-16 items-center justify-center rounded-2xl border border-white/10 bg-white/10", children: icon }) }),
|
|
3044
|
+
/* @__PURE__ */ jsx26("div", { className: "pointer-events-none absolute inset-y-0 right-0 w-1/3 bg-gradient-to-l from-white/5 to-transparent" })
|
|
2925
3045
|
] });
|
|
2926
3046
|
}
|
|
2927
3047
|
|
|
@@ -2960,6 +3080,7 @@ export {
|
|
|
2960
3080
|
InvoiceTable,
|
|
2961
3081
|
PlanCards,
|
|
2962
3082
|
DashboardLayout,
|
|
3083
|
+
SidebarLayout,
|
|
2963
3084
|
ProfileSelector,
|
|
2964
3085
|
ProfileComparison,
|
|
2965
3086
|
MetricAreaChart,
|