@tangle-network/sandbox-ui 0.3.11 → 0.3.13
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/README.md +7 -1
- package/dist/auth.js +2 -3
- package/dist/{chunk-CREVWUCA.js → chunk-DJEZKF5A.js} +3 -2
- package/dist/chunk-DLCFZDGX.js +182 -0
- package/dist/{chunk-FOQTE67I.js → chunk-FJLS7PNT.js} +9 -4
- package/dist/chunk-HXEA7L2T.js +1401 -0
- package/dist/{chunk-6NYG2R7V.js → chunk-HYLTXGOI.js} +1 -1
- package/dist/{chunk-MCGKDCOR.js → chunk-IW2JZCOC.js} +55 -14
- package/dist/{chunk-PCTEG6HR.js → chunk-OHMO7NUX.js} +2 -4
- package/dist/{chunk-DMYYQXPN.js → chunk-SMBF6HB5.js} +646 -465
- package/dist/dashboard.d.ts +1 -1
- package/dist/dashboard.js +40 -6
- package/dist/{document-editor-pane-AFBP2KFT.js → document-editor-pane-5TN2VWGZ.js} +1 -1
- package/dist/{document-editor-pane-Xnl8SmA7.d.ts → document-editor-pane-A70-EhdQ.d.ts} +1 -1
- package/dist/editor.d.ts +2 -2
- package/dist/editor.js +1 -1
- package/dist/files.d.ts +1 -1
- package/dist/files.js +1 -1
- package/dist/hooks.d.ts +1 -1
- package/dist/hooks.js +2 -2
- package/dist/index-D7_ZDkwB.d.ts +375 -0
- package/dist/index.d.ts +5 -3
- package/dist/index.js +74 -16
- package/dist/pages.d.ts +12 -2
- package/dist/pages.js +60 -5
- package/dist/primitives.js +4 -6
- package/dist/sdk-hooks.js +1 -1
- package/dist/terminal.d.ts +2 -2
- package/dist/terminal.js +9 -39
- package/dist/{use-pty-session-DeZSxOCN.d.ts → use-pty-session-COzVkhtc.d.ts} +1 -1
- package/dist/workspace.d.ts +3 -1
- package/dist/workspace.js +2 -2
- package/package.json +1 -1
- package/dist/chunk-B26TQ7SA.js +0 -47
- package/dist/chunk-BOBXH6CH.js +0 -10981
- package/dist/chunk-GRYHFH5O.js +0 -110
- package/dist/index-BJIPTCKk.d.ts +0 -264
|
@@ -2,13 +2,16 @@ import {
|
|
|
2
2
|
Logo
|
|
3
3
|
} from "./chunk-OKCIKTXQ.js";
|
|
4
4
|
import {
|
|
5
|
+
Avatar,
|
|
6
|
+
AvatarFallback,
|
|
7
|
+
AvatarImage,
|
|
5
8
|
DropdownMenu,
|
|
6
9
|
DropdownMenuContent,
|
|
7
10
|
DropdownMenuItem,
|
|
8
11
|
DropdownMenuLabel,
|
|
9
12
|
DropdownMenuSeparator,
|
|
10
13
|
DropdownMenuTrigger
|
|
11
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-IW2JZCOC.js";
|
|
12
15
|
import {
|
|
13
16
|
Skeleton
|
|
14
17
|
} from "./chunk-FRGMMANX.js";
|
|
@@ -22,18 +25,103 @@ import {
|
|
|
22
25
|
cn
|
|
23
26
|
} from "./chunk-RQHJBTEU.js";
|
|
24
27
|
|
|
25
|
-
// src/dashboard/
|
|
26
|
-
import
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
28
|
+
// src/dashboard/sidebar-context.tsx
|
|
29
|
+
import * as React from "react";
|
|
30
|
+
import { jsx } from "react/jsx-runtime";
|
|
31
|
+
var PANEL_OPEN_KEY = "sandbox-sidebar-panel-open";
|
|
32
|
+
var SIDEBAR_MODE_KEY = "sandbox-sidebar-mode";
|
|
33
|
+
var SIDEBAR_RAIL_WIDTH = 64;
|
|
34
|
+
var SIDEBAR_PANEL_WIDTH = 260;
|
|
35
|
+
var SIDEBAR_TOTAL_WIDTH = SIDEBAR_RAIL_WIDTH + SIDEBAR_PANEL_WIDTH;
|
|
36
|
+
var SidebarContext = React.createContext(null);
|
|
37
|
+
function readStorage(key, fallback) {
|
|
38
|
+
if (typeof window === "undefined") return fallback;
|
|
39
|
+
try {
|
|
40
|
+
return localStorage.getItem(key) ?? fallback;
|
|
41
|
+
} catch {
|
|
42
|
+
return fallback;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
function SidebarProvider({
|
|
46
|
+
defaultPanelOpen = true,
|
|
47
|
+
defaultMode = "projects",
|
|
48
|
+
children
|
|
49
|
+
}) {
|
|
50
|
+
const [panelOpen, setPanelOpenState] = React.useState(
|
|
51
|
+
() => readStorage(PANEL_OPEN_KEY, String(defaultPanelOpen)) === "true"
|
|
52
|
+
);
|
|
53
|
+
const [mode, setModeState] = React.useState(
|
|
54
|
+
() => readStorage(SIDEBAR_MODE_KEY, defaultMode)
|
|
35
55
|
);
|
|
56
|
+
const [hidden, setHidden] = React.useState(false);
|
|
57
|
+
const setPanelOpen = React.useCallback((open) => {
|
|
58
|
+
setPanelOpenState(open);
|
|
59
|
+
localStorage.setItem(PANEL_OPEN_KEY, String(open));
|
|
60
|
+
}, []);
|
|
61
|
+
const togglePanel = React.useCallback(() => {
|
|
62
|
+
setPanelOpenState((prev) => {
|
|
63
|
+
const next = !prev;
|
|
64
|
+
localStorage.setItem(PANEL_OPEN_KEY, String(next));
|
|
65
|
+
return next;
|
|
66
|
+
});
|
|
67
|
+
}, []);
|
|
68
|
+
const setMode = React.useCallback((m) => {
|
|
69
|
+
setModeState(m);
|
|
70
|
+
localStorage.setItem(SIDEBAR_MODE_KEY, m);
|
|
71
|
+
}, []);
|
|
72
|
+
const switchMode = React.useCallback((m) => {
|
|
73
|
+
setPanelOpenState((prevOpen) => {
|
|
74
|
+
setModeState((prevMode) => {
|
|
75
|
+
if (prevOpen && prevMode === m) {
|
|
76
|
+
localStorage.setItem(PANEL_OPEN_KEY, "false");
|
|
77
|
+
return prevMode;
|
|
78
|
+
}
|
|
79
|
+
localStorage.setItem(PANEL_OPEN_KEY, "true");
|
|
80
|
+
localStorage.setItem(SIDEBAR_MODE_KEY, m);
|
|
81
|
+
return m;
|
|
82
|
+
});
|
|
83
|
+
return void 0;
|
|
84
|
+
});
|
|
85
|
+
}, []);
|
|
86
|
+
const switchModeStable = React.useCallback((m) => {
|
|
87
|
+
setModeState((prevMode) => {
|
|
88
|
+
setPanelOpenState((prevOpen) => {
|
|
89
|
+
if (prevOpen && prevMode === m) {
|
|
90
|
+
localStorage.setItem(PANEL_OPEN_KEY, "false");
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
localStorage.setItem(PANEL_OPEN_KEY, "true");
|
|
94
|
+
return true;
|
|
95
|
+
});
|
|
96
|
+
localStorage.setItem(SIDEBAR_MODE_KEY, m);
|
|
97
|
+
return m;
|
|
98
|
+
});
|
|
99
|
+
}, []);
|
|
100
|
+
const contentMargin = hidden ? 0 : panelOpen ? SIDEBAR_TOTAL_WIDTH : SIDEBAR_RAIL_WIDTH;
|
|
101
|
+
const value = React.useMemo(
|
|
102
|
+
() => ({
|
|
103
|
+
panelOpen,
|
|
104
|
+
setPanelOpen,
|
|
105
|
+
togglePanel,
|
|
106
|
+
mode,
|
|
107
|
+
setMode,
|
|
108
|
+
switchMode: switchModeStable,
|
|
109
|
+
hidden,
|
|
110
|
+
setHidden,
|
|
111
|
+
contentMargin
|
|
112
|
+
}),
|
|
113
|
+
[panelOpen, setPanelOpen, togglePanel, mode, setMode, switchModeStable, hidden, setHidden, contentMargin]
|
|
114
|
+
);
|
|
115
|
+
return /* @__PURE__ */ jsx(SidebarContext.Provider, { value, children });
|
|
116
|
+
}
|
|
117
|
+
function useSidebar() {
|
|
118
|
+
const ctx = React.useContext(SidebarContext);
|
|
119
|
+
if (!ctx) throw new Error("useSidebar must be used within a SidebarProvider");
|
|
120
|
+
return ctx;
|
|
36
121
|
}
|
|
122
|
+
|
|
123
|
+
// src/dashboard/app-sidebar.tsx
|
|
124
|
+
import { Fragment, jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
37
125
|
function DefaultLink({
|
|
38
126
|
href,
|
|
39
127
|
to,
|
|
@@ -41,102 +129,197 @@ function DefaultLink({
|
|
|
41
129
|
children,
|
|
42
130
|
...rest
|
|
43
131
|
}) {
|
|
44
|
-
return /* @__PURE__ */
|
|
132
|
+
return /* @__PURE__ */ jsx2("a", { href: href ?? to, className, ...rest, children });
|
|
45
133
|
}
|
|
46
|
-
function
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
})
|
|
56
|
-
|
|
57
|
-
|
|
134
|
+
function getInitials(name, email) {
|
|
135
|
+
if (name) return name.split(" ").map((w) => w[0]).filter(Boolean).slice(0, 2).join("").toUpperCase();
|
|
136
|
+
if (email) return email[0].toUpperCase();
|
|
137
|
+
return "?";
|
|
138
|
+
}
|
|
139
|
+
function SettingsIcon({ className }) {
|
|
140
|
+
return /* @__PURE__ */ jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, children: [
|
|
141
|
+
/* @__PURE__ */ jsx2("title", { children: "Settings icon" }),
|
|
142
|
+
/* @__PURE__ */ jsx2("path", { d: "M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z" }),
|
|
143
|
+
/* @__PURE__ */ jsx2("circle", { cx: "12", cy: "12", r: "3" })
|
|
144
|
+
] });
|
|
145
|
+
}
|
|
146
|
+
function LogOutIcon({ className }) {
|
|
147
|
+
return /* @__PURE__ */ jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, children: [
|
|
148
|
+
/* @__PURE__ */ jsx2("title", { children: "Log out icon" }),
|
|
149
|
+
/* @__PURE__ */ jsx2("path", { d: "M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4" }),
|
|
150
|
+
/* @__PURE__ */ jsx2("polyline", { points: "16,17 21,12 16,7" }),
|
|
151
|
+
/* @__PURE__ */ jsx2("line", { x1: "21", x2: "9", y1: "12", y2: "12" })
|
|
152
|
+
] });
|
|
153
|
+
}
|
|
154
|
+
function Sidebar({ children, className }) {
|
|
155
|
+
const { panelOpen, hidden } = useSidebar();
|
|
156
|
+
return /* @__PURE__ */ jsx2(
|
|
157
|
+
"div",
|
|
158
|
+
{
|
|
159
|
+
"data-sidebar": "true",
|
|
160
|
+
className: cn(
|
|
161
|
+
"fixed inset-y-0 left-0 z-40 flex bg-sidebar border-r border-sidebar-border transition-[transform,width] duration-200 ease-in-out",
|
|
162
|
+
hidden && "-translate-x-full",
|
|
163
|
+
className
|
|
164
|
+
),
|
|
165
|
+
style: { width: panelOpen ? SIDEBAR_TOTAL_WIDTH : SIDEBAR_RAIL_WIDTH },
|
|
166
|
+
children
|
|
167
|
+
}
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
function SidebarRail({ children, className }) {
|
|
171
|
+
return /* @__PURE__ */ jsx2("div", { className: cn("flex flex-col h-full w-16 shrink-0", className), children });
|
|
172
|
+
}
|
|
173
|
+
function SidebarRailHeader({ children, className }) {
|
|
174
|
+
return /* @__PURE__ */ jsx2("div", { className: cn("flex h-14 items-center justify-center border-b border-sidebar-border", className), children });
|
|
175
|
+
}
|
|
176
|
+
function SidebarRailNav({ children, className }) {
|
|
177
|
+
return /* @__PURE__ */ jsx2("nav", { className: cn("flex flex-col items-center gap-1 py-3 flex-1", className), children });
|
|
178
|
+
}
|
|
179
|
+
function SidebarRailFooter({ children, className }) {
|
|
180
|
+
return /* @__PURE__ */ jsx2("div", { className: cn("flex flex-col items-center gap-1 pb-3", className), children });
|
|
181
|
+
}
|
|
182
|
+
function RailSeparator({ className }) {
|
|
183
|
+
return /* @__PURE__ */ jsx2("div", { className: cn("my-2 h-px w-10 bg-sidebar-border", className) });
|
|
184
|
+
}
|
|
185
|
+
function RailButton({ icon: Icon, label, isActive, badge, onClick, className }) {
|
|
58
186
|
return /* @__PURE__ */ jsxs(
|
|
59
|
-
"
|
|
187
|
+
"button",
|
|
60
188
|
{
|
|
189
|
+
type: "button",
|
|
190
|
+
onClick,
|
|
191
|
+
title: label,
|
|
61
192
|
className: cn(
|
|
62
|
-
"
|
|
193
|
+
"relative flex items-center justify-center w-10 h-10 rounded-lg transition-all duration-150",
|
|
194
|
+
"hover:bg-sidebar-accent/80 hover:text-sidebar-accent-foreground",
|
|
195
|
+
"active:scale-95",
|
|
196
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-sidebar-ring",
|
|
197
|
+
isActive && "bg-sidebar-accent text-sidebar-accent-foreground",
|
|
198
|
+
!isActive && "text-sidebar-foreground/70",
|
|
63
199
|
className
|
|
64
200
|
),
|
|
65
201
|
children: [
|
|
66
|
-
/* @__PURE__ */
|
|
67
|
-
|
|
68
|
-
/* @__PURE__ */ jsx("div", { className: "min-w-0", children: activeSandbox ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
69
|
-
/* @__PURE__ */ jsx("div", { className: "font-mono text-xs text-white font-bold tracking-tight truncate", children: activeSandbox.name }),
|
|
70
|
-
activeSandbox.label && /* @__PURE__ */ jsx("div", { className: "font-mono text-[10px] text-slate-500 truncate", children: activeSandbox.label })
|
|
71
|
-
] }) : /* @__PURE__ */ jsx("div", { className: "font-mono text-xs text-slate-500", children: "No sandbox selected" }) })
|
|
72
|
-
] }) }),
|
|
73
|
-
/* @__PURE__ */ jsx("nav", { className: "flex-1 px-4 space-y-1", children: navItems.map((item) => {
|
|
74
|
-
const isActive = activeNavId === item.id;
|
|
75
|
-
return /* @__PURE__ */ jsxs(
|
|
76
|
-
Link,
|
|
77
|
-
{
|
|
78
|
-
href: item.href,
|
|
79
|
-
to: item.href,
|
|
80
|
-
className: cn(
|
|
81
|
-
"flex items-center gap-3 px-4 py-3 rounded-lg font-mono text-xs transition-colors",
|
|
82
|
-
isActive ? "bg-violet-500/10 text-violet-300 border-r-4 border-violet-500" : "text-slate-500 hover:bg-slate-800 hover:text-slate-300"
|
|
83
|
-
),
|
|
84
|
-
children: [
|
|
85
|
-
/* @__PURE__ */ jsx(MaterialIcon, { name: item.icon, className: "text-lg" }),
|
|
86
|
-
/* @__PURE__ */ jsx("span", { children: item.label }),
|
|
87
|
-
item.badge && /* @__PURE__ */ jsx("span", { className: "ml-auto px-2 py-0.5 rounded-full bg-primary-container text-on-primary text-[9px] font-bold", children: item.badge })
|
|
88
|
-
]
|
|
89
|
-
},
|
|
90
|
-
item.id
|
|
91
|
-
);
|
|
92
|
-
}) }),
|
|
93
|
-
/* @__PURE__ */ jsxs("div", { className: "px-4 py-4 mt-auto space-y-1 border-t border-outline-variant/10", children: [
|
|
94
|
-
onNewAgent && /* @__PURE__ */ jsxs(
|
|
95
|
-
"button",
|
|
96
|
-
{
|
|
97
|
-
type: "button",
|
|
98
|
-
onClick: onNewAgent,
|
|
99
|
-
className: "w-full flex items-center justify-center gap-2 bg-gradient-to-r from-md3-primary to-primary-container text-on-primary font-bold py-2.5 rounded-lg mb-4 text-xs active:scale-95 duration-200 transition-transform",
|
|
100
|
-
children: [
|
|
101
|
-
/* @__PURE__ */ jsx(MaterialIcon, { name: "add", className: "text-sm" }),
|
|
102
|
-
"New Agent"
|
|
103
|
-
]
|
|
104
|
-
}
|
|
105
|
-
),
|
|
106
|
-
/* @__PURE__ */ jsxs(
|
|
107
|
-
Link,
|
|
108
|
-
{
|
|
109
|
-
href: "/docs",
|
|
110
|
-
to: "/docs",
|
|
111
|
-
className: "flex items-center gap-3 px-4 py-2 rounded-lg text-slate-500 hover:bg-slate-800 hover:text-slate-300 transition-colors font-mono text-xs",
|
|
112
|
-
children: [
|
|
113
|
-
/* @__PURE__ */ jsx(MaterialIcon, { name: "menu_book", className: "text-sm" }),
|
|
114
|
-
"Documentation"
|
|
115
|
-
]
|
|
116
|
-
}
|
|
117
|
-
),
|
|
118
|
-
/* @__PURE__ */ jsxs(
|
|
119
|
-
Link,
|
|
120
|
-
{
|
|
121
|
-
href: "/support",
|
|
122
|
-
to: "/support",
|
|
123
|
-
className: "flex items-center gap-3 px-4 py-2 rounded-lg text-slate-500 hover:bg-slate-800 hover:text-slate-300 transition-colors font-mono text-xs",
|
|
124
|
-
children: [
|
|
125
|
-
/* @__PURE__ */ jsx(MaterialIcon, { name: "contact_support", className: "text-sm" }),
|
|
126
|
-
"Support"
|
|
127
|
-
]
|
|
128
|
-
}
|
|
129
|
-
)
|
|
130
|
-
] })
|
|
202
|
+
/* @__PURE__ */ jsx2(Icon, { className: "h-5 w-5" }),
|
|
203
|
+
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-sidebar-primary text-[10px] font-medium text-white px-1", children: badge > 99 ? "99+" : badge })
|
|
131
204
|
]
|
|
132
205
|
}
|
|
133
206
|
);
|
|
134
207
|
}
|
|
208
|
+
function RailModeButton({ mode, icon, label, badge, className }) {
|
|
209
|
+
const { panelOpen, mode: currentMode, switchMode } = useSidebar();
|
|
210
|
+
return /* @__PURE__ */ jsx2(
|
|
211
|
+
RailButton,
|
|
212
|
+
{
|
|
213
|
+
icon,
|
|
214
|
+
label,
|
|
215
|
+
badge,
|
|
216
|
+
isActive: panelOpen && currentMode === mode,
|
|
217
|
+
onClick: () => switchMode(mode),
|
|
218
|
+
className
|
|
219
|
+
}
|
|
220
|
+
);
|
|
221
|
+
}
|
|
222
|
+
function SidebarPanel({ children, className }) {
|
|
223
|
+
const { panelOpen } = useSidebar();
|
|
224
|
+
return /* @__PURE__ */ jsx2(
|
|
225
|
+
"div",
|
|
226
|
+
{
|
|
227
|
+
className: cn(
|
|
228
|
+
"transition-[opacity] duration-150 h-full overflow-hidden border-l border-sidebar-border",
|
|
229
|
+
panelOpen ? "w-[260px] opacity-100" : "w-0 opacity-0 pointer-events-none",
|
|
230
|
+
className
|
|
231
|
+
),
|
|
232
|
+
children: /* @__PURE__ */ jsx2("div", { className: "flex flex-col h-full w-[260px]", children })
|
|
233
|
+
}
|
|
234
|
+
);
|
|
235
|
+
}
|
|
236
|
+
function SidebarPanelHeader({ children, title, className }) {
|
|
237
|
+
return /* @__PURE__ */ jsx2("div", { className: cn("flex h-14 items-center px-4 border-b border-sidebar-border shrink-0", className), children: children ?? /* @__PURE__ */ jsx2("h2", { className: "text-sm font-semibold text-sidebar-foreground", children: title }) });
|
|
238
|
+
}
|
|
239
|
+
function SidebarPanelContent({ children, className }) {
|
|
240
|
+
return /* @__PURE__ */ jsx2("div", { className: cn("flex-1 overflow-y-auto px-2 py-2", className), children });
|
|
241
|
+
}
|
|
242
|
+
function SidebarContent({ children, className }) {
|
|
243
|
+
const { contentMargin } = useSidebar();
|
|
244
|
+
return /* @__PURE__ */ jsx2(
|
|
245
|
+
"main",
|
|
246
|
+
{
|
|
247
|
+
className: cn("min-h-screen transition-[margin-left] duration-200 ease-in-out", className),
|
|
248
|
+
style: { marginLeft: contentMargin },
|
|
249
|
+
children
|
|
250
|
+
}
|
|
251
|
+
);
|
|
252
|
+
}
|
|
253
|
+
function ProfileAvatar({
|
|
254
|
+
user,
|
|
255
|
+
isLoading = false,
|
|
256
|
+
onLogout,
|
|
257
|
+
onSettingsClick,
|
|
258
|
+
settingsHref = "/dashboard/settings",
|
|
259
|
+
children,
|
|
260
|
+
className,
|
|
261
|
+
LinkComponent
|
|
262
|
+
}) {
|
|
263
|
+
const Link = LinkComponent ?? DefaultLink;
|
|
264
|
+
return /* @__PURE__ */ jsxs(DropdownMenu, { children: [
|
|
265
|
+
/* @__PURE__ */ jsx2(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx2(
|
|
266
|
+
"button",
|
|
267
|
+
{
|
|
268
|
+
type: "button",
|
|
269
|
+
className: cn(
|
|
270
|
+
"flex items-center justify-center w-10 h-10 rounded-lg transition-colors hover:bg-sidebar-accent",
|
|
271
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-sidebar-ring",
|
|
272
|
+
className
|
|
273
|
+
),
|
|
274
|
+
"aria-label": "User menu",
|
|
275
|
+
children: isLoading ? /* @__PURE__ */ jsx2(Skeleton, { className: "h-7 w-7 rounded-full" }) : /* @__PURE__ */ jsxs(Avatar, { className: "h-7 w-7", children: [
|
|
276
|
+
user?.avatarUrl && /* @__PURE__ */ jsx2(AvatarImage, { src: user.avatarUrl, alt: "" }),
|
|
277
|
+
/* @__PURE__ */ jsx2(AvatarFallback, { className: "text-[10px] bg-violet-500/20 text-violet-300", children: getInitials(user?.name, user?.email) })
|
|
278
|
+
] })
|
|
279
|
+
}
|
|
280
|
+
) }),
|
|
281
|
+
/* @__PURE__ */ jsxs(DropdownMenuContent, { side: "right", align: "end", sideOffset: 8, className: "w-72", children: [
|
|
282
|
+
/* @__PURE__ */ jsx2(DropdownMenuLabel, { className: "p-0 font-normal", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 px-2 py-3", children: [
|
|
283
|
+
/* @__PURE__ */ jsxs(Avatar, { className: "h-12 w-12 shrink-0", children: [
|
|
284
|
+
user?.avatarUrl && /* @__PURE__ */ jsx2(AvatarImage, { src: user.avatarUrl, alt: "" }),
|
|
285
|
+
/* @__PURE__ */ jsx2(AvatarFallback, { className: "text-sm bg-violet-500/20 text-violet-300", children: getInitials(user?.name, user?.email) })
|
|
286
|
+
] }),
|
|
287
|
+
/* @__PURE__ */ jsx2("div", { className: "min-w-0 flex-1", children: isLoading ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
288
|
+
/* @__PURE__ */ jsx2(Skeleton, { className: "h-4 w-24 mb-1" }),
|
|
289
|
+
/* @__PURE__ */ jsx2(Skeleton, { className: "h-3 w-32" })
|
|
290
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
291
|
+
/* @__PURE__ */ jsx2("p", { className: "text-sm font-semibold truncate", children: user?.name ?? user?.email ?? "Not logged in" }),
|
|
292
|
+
user?.email && user?.name && /* @__PURE__ */ jsx2("p", { className: "text-xs text-muted-foreground truncate", children: user.email }),
|
|
293
|
+
user?.tier && /* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground capitalize", children: [
|
|
294
|
+
user.tier,
|
|
295
|
+
" Plan"
|
|
296
|
+
] })
|
|
297
|
+
] }) })
|
|
298
|
+
] }) }),
|
|
299
|
+
/* @__PURE__ */ jsx2(DropdownMenuSeparator, {}),
|
|
300
|
+
children,
|
|
301
|
+
onSettingsClick ? /* @__PURE__ */ jsxs(DropdownMenuItem, { onClick: onSettingsClick, children: [
|
|
302
|
+
/* @__PURE__ */ jsx2(SettingsIcon, { className: "mr-2 h-4 w-4", "aria-hidden": "true" }),
|
|
303
|
+
"Settings"
|
|
304
|
+
] }) : /* @__PURE__ */ jsx2(DropdownMenuItem, { asChild: true, children: /* @__PURE__ */ jsxs(Link, { href: settingsHref, to: settingsHref, className: "flex items-center", children: [
|
|
305
|
+
/* @__PURE__ */ jsx2(SettingsIcon, { className: "mr-2 h-4 w-4", "aria-hidden": "true" }),
|
|
306
|
+
"Settings"
|
|
307
|
+
] }) }),
|
|
308
|
+
onLogout && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
309
|
+
/* @__PURE__ */ jsx2(DropdownMenuSeparator, {}),
|
|
310
|
+
/* @__PURE__ */ jsxs(DropdownMenuItem, { className: "text-red-400", onClick: onLogout, children: [
|
|
311
|
+
/* @__PURE__ */ jsx2(LogOutIcon, { className: "mr-2 h-4 w-4", "aria-hidden": "true" }),
|
|
312
|
+
"Sign Out"
|
|
313
|
+
] })
|
|
314
|
+
] })
|
|
315
|
+
] })
|
|
316
|
+
] });
|
|
317
|
+
}
|
|
135
318
|
|
|
136
319
|
// src/dashboard/cluster-status-bar.tsx
|
|
137
|
-
import { jsx as
|
|
138
|
-
function
|
|
139
|
-
return /* @__PURE__ */
|
|
320
|
+
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
321
|
+
function MaterialIcon({ name, className }) {
|
|
322
|
+
return /* @__PURE__ */ jsx3("span", { className: cn("material-symbols-outlined", className), style: { fontVariationSettings: "'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24" }, children: name });
|
|
140
323
|
}
|
|
141
324
|
function ClusterStatusBar({ items, latency, className }) {
|
|
142
325
|
return /* @__PURE__ */ jsxs2(
|
|
@@ -147,25 +330,25 @@ function ClusterStatusBar({ items, latency, className }) {
|
|
|
147
330
|
className
|
|
148
331
|
),
|
|
149
332
|
children: [
|
|
150
|
-
/* @__PURE__ */
|
|
151
|
-
/* @__PURE__ */
|
|
333
|
+
/* @__PURE__ */ jsx3("div", { className: "flex items-center gap-6 overflow-x-auto whitespace-nowrap", children: items.map((item, i) => /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-2", children: [
|
|
334
|
+
/* @__PURE__ */ jsx3(MaterialIcon, { name: item.icon, className: "text-[14px] text-md3-primary" }),
|
|
152
335
|
/* @__PURE__ */ jsxs2("span", { className: "text-[10px] font-mono text-on-surface-variant", children: [
|
|
153
336
|
item.label,
|
|
154
337
|
": ",
|
|
155
|
-
/* @__PURE__ */
|
|
338
|
+
/* @__PURE__ */ jsx3("span", { className: cn("text-white", item.valueClass), children: item.value })
|
|
156
339
|
] })
|
|
157
340
|
] }, i)) }),
|
|
158
341
|
latency && /* @__PURE__ */ jsxs2("div", { className: "hidden sm:flex items-center gap-2", children: [
|
|
159
342
|
/* @__PURE__ */ jsxs2("span", { className: "text-[10px] font-mono text-on-surface-variant", children: [
|
|
160
343
|
"System Latency: ",
|
|
161
|
-
/* @__PURE__ */
|
|
344
|
+
/* @__PURE__ */ jsx3("span", { className: "text-white", children: latency })
|
|
162
345
|
] }),
|
|
163
346
|
/* @__PURE__ */ jsxs2("div", { className: "flex gap-0.5 h-3 items-end", children: [
|
|
164
|
-
/* @__PURE__ */
|
|
165
|
-
/* @__PURE__ */
|
|
166
|
-
/* @__PURE__ */
|
|
167
|
-
/* @__PURE__ */
|
|
168
|
-
/* @__PURE__ */
|
|
347
|
+
/* @__PURE__ */ jsx3("div", { className: "w-0.5 h-1 bg-md3-primary" }),
|
|
348
|
+
/* @__PURE__ */ jsx3("div", { className: "w-0.5 h-2 bg-md3-primary" }),
|
|
349
|
+
/* @__PURE__ */ jsx3("div", { className: "w-0.5 h-1.5 bg-md3-primary" }),
|
|
350
|
+
/* @__PURE__ */ jsx3("div", { className: "w-0.5 h-3 bg-md3-primary" }),
|
|
351
|
+
/* @__PURE__ */ jsx3("div", { className: "w-0.5 h-2.5 bg-md3-primary" })
|
|
169
352
|
] })
|
|
170
353
|
] })
|
|
171
354
|
]
|
|
@@ -174,8 +357,8 @@ function ClusterStatusBar({ items, latency, className }) {
|
|
|
174
357
|
}
|
|
175
358
|
|
|
176
359
|
// src/dashboard/credit-balance.tsx
|
|
177
|
-
import * as
|
|
178
|
-
import { jsx as
|
|
360
|
+
import * as React2 from "react";
|
|
361
|
+
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
179
362
|
function CreditBalance({
|
|
180
363
|
amount,
|
|
181
364
|
description = "Credits are automatically deducted based on hourly Sandbox usage and Agent operations.",
|
|
@@ -183,19 +366,19 @@ function CreditBalance({
|
|
|
183
366
|
quickAmounts = [10, 25, 100],
|
|
184
367
|
className
|
|
185
368
|
}) {
|
|
186
|
-
const [topUpValue, setTopUpValue] =
|
|
369
|
+
const [topUpValue, setTopUpValue] = React2.useState("50.00");
|
|
187
370
|
return /* @__PURE__ */ jsxs3("div", { className: cn("bg-gradient-to-br from-surface-container to-surface-container-high p-8 rounded-xl flex flex-col justify-between border border-md3-primary/10", className), children: [
|
|
188
371
|
/* @__PURE__ */ jsxs3("div", { children: [
|
|
189
|
-
/* @__PURE__ */
|
|
372
|
+
/* @__PURE__ */ jsx4("h3", { className: "text-lg font-bold text-white tracking-tight mb-1", children: "Available Credits" }),
|
|
190
373
|
/* @__PURE__ */ jsxs3("div", { className: "text-5xl font-extrabold text-md3-primary tracking-tighter mb-4", children: [
|
|
191
374
|
"$",
|
|
192
375
|
amount.toFixed(2)
|
|
193
376
|
] }),
|
|
194
|
-
/* @__PURE__ */
|
|
377
|
+
/* @__PURE__ */ jsx4("p", { className: "text-sm text-on-surface-variant leading-relaxed", children: description })
|
|
195
378
|
] }),
|
|
196
379
|
onTopUp && /* @__PURE__ */ jsxs3("div", { className: "space-y-4 mt-8", children: [
|
|
197
380
|
/* @__PURE__ */ jsxs3("div", { className: "bg-surface-container-lowest p-1 rounded-lg flex items-center", children: [
|
|
198
|
-
/* @__PURE__ */
|
|
381
|
+
/* @__PURE__ */ jsx4(
|
|
199
382
|
"input",
|
|
200
383
|
{
|
|
201
384
|
type: "text",
|
|
@@ -204,7 +387,7 @@ function CreditBalance({
|
|
|
204
387
|
className: "bg-transparent border-none text-white font-mono text-lg w-full focus:ring-0 px-4"
|
|
205
388
|
}
|
|
206
389
|
),
|
|
207
|
-
/* @__PURE__ */
|
|
390
|
+
/* @__PURE__ */ jsx4(
|
|
208
391
|
"button",
|
|
209
392
|
{
|
|
210
393
|
type: "button",
|
|
@@ -214,7 +397,7 @@ function CreditBalance({
|
|
|
214
397
|
}
|
|
215
398
|
)
|
|
216
399
|
] }),
|
|
217
|
-
/* @__PURE__ */
|
|
400
|
+
/* @__PURE__ */ jsx4("div", { className: "flex justify-between gap-2", children: quickAmounts.map((qa) => /* @__PURE__ */ jsxs3(
|
|
218
401
|
"button",
|
|
219
402
|
{
|
|
220
403
|
type: "button",
|
|
@@ -235,9 +418,9 @@ function CreditBalance({
|
|
|
235
418
|
}
|
|
236
419
|
|
|
237
420
|
// src/dashboard/invoice-table.tsx
|
|
238
|
-
import { jsx as
|
|
239
|
-
function
|
|
240
|
-
return /* @__PURE__ */
|
|
421
|
+
import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
422
|
+
function MaterialIcon2({ name, className }) {
|
|
423
|
+
return /* @__PURE__ */ jsx5("span", { className: cn("material-symbols-outlined", className), style: { fontVariationSettings: "'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24" }, children: name });
|
|
241
424
|
}
|
|
242
425
|
var statusStyle = {
|
|
243
426
|
paid: "bg-md3-primary/10 text-md3-primary",
|
|
@@ -247,44 +430,44 @@ var statusStyle = {
|
|
|
247
430
|
function InvoiceTable({ invoices, onExportAll, onLoadMore, onViewInvoice, hasMore, className }) {
|
|
248
431
|
return /* @__PURE__ */ jsxs4("section", { className, children: [
|
|
249
432
|
/* @__PURE__ */ jsxs4("div", { className: "flex justify-between items-center mb-6 px-2", children: [
|
|
250
|
-
/* @__PURE__ */
|
|
433
|
+
/* @__PURE__ */ jsx5("h2", { className: "text-2xl font-bold text-white tracking-tight", children: "Invoice History" }),
|
|
251
434
|
onExportAll && /* @__PURE__ */ jsxs4("button", { type: "button", onClick: onExportAll, className: "text-[10px] font-mono text-md3-primary uppercase tracking-widest flex items-center gap-2 hover:underline", children: [
|
|
252
|
-
/* @__PURE__ */
|
|
435
|
+
/* @__PURE__ */ jsx5(MaterialIcon2, { name: "download", className: "text-sm" }),
|
|
253
436
|
"Export All"
|
|
254
437
|
] })
|
|
255
438
|
] }),
|
|
256
|
-
/* @__PURE__ */
|
|
257
|
-
/* @__PURE__ */
|
|
258
|
-
/* @__PURE__ */
|
|
259
|
-
/* @__PURE__ */
|
|
260
|
-
/* @__PURE__ */
|
|
261
|
-
/* @__PURE__ */
|
|
262
|
-
/* @__PURE__ */
|
|
439
|
+
/* @__PURE__ */ jsx5("div", { className: "bg-surface-container-lowest rounded-xl overflow-hidden border border-outline-variant/10", children: /* @__PURE__ */ jsxs4("table", { className: "w-full text-left border-collapse", children: [
|
|
440
|
+
/* @__PURE__ */ jsx5("thead", { children: /* @__PURE__ */ jsxs4("tr", { className: "bg-surface-container-high", children: [
|
|
441
|
+
/* @__PURE__ */ jsx5("th", { className: "px-6 py-4 font-mono text-[10px] text-on-surface-variant uppercase tracking-widest", children: "Invoice ID" }),
|
|
442
|
+
/* @__PURE__ */ jsx5("th", { className: "px-6 py-4 font-mono text-[10px] text-on-surface-variant uppercase tracking-widest", children: "Date" }),
|
|
443
|
+
/* @__PURE__ */ jsx5("th", { className: "px-6 py-4 font-mono text-[10px] text-on-surface-variant uppercase tracking-widest", children: "Amount" }),
|
|
444
|
+
/* @__PURE__ */ jsx5("th", { className: "px-6 py-4 font-mono text-[10px] text-on-surface-variant uppercase tracking-widest", children: "Status" }),
|
|
445
|
+
/* @__PURE__ */ jsx5("th", { className: "px-6 py-4 font-mono text-[10px] text-on-surface-variant uppercase tracking-widest text-right", children: "Action" })
|
|
263
446
|
] }) }),
|
|
264
|
-
/* @__PURE__ */
|
|
265
|
-
/* @__PURE__ */
|
|
266
|
-
/* @__PURE__ */
|
|
447
|
+
/* @__PURE__ */ jsx5("tbody", { className: "divide-y divide-outline-variant/5", children: invoices.map((inv) => /* @__PURE__ */ jsxs4("tr", { className: "hover:bg-surface-container-low/50 transition-colors", children: [
|
|
448
|
+
/* @__PURE__ */ jsx5("td", { className: "px-6 py-5 font-mono text-xs text-white", children: inv.id }),
|
|
449
|
+
/* @__PURE__ */ jsx5("td", { className: "px-6 py-5 text-sm text-on-surface-variant", children: inv.date }),
|
|
267
450
|
/* @__PURE__ */ jsxs4("td", { className: "px-6 py-5 text-sm font-bold text-white", children: [
|
|
268
451
|
"$",
|
|
269
452
|
inv.amount.toFixed(2)
|
|
270
453
|
] }),
|
|
271
|
-
/* @__PURE__ */
|
|
272
|
-
/* @__PURE__ */
|
|
454
|
+
/* @__PURE__ */ jsx5("td", { className: "px-6 py-5", children: /* @__PURE__ */ jsx5("span", { className: cn("px-2 py-1 text-[10px] font-mono rounded uppercase", statusStyle[inv.status] ?? statusStyle.paid), children: inv.status }) }),
|
|
455
|
+
/* @__PURE__ */ jsx5("td", { className: "px-6 py-5 text-right", children: /* @__PURE__ */ jsx5("button", { type: "button", onClick: () => onViewInvoice?.(inv.id), className: "text-on-surface-variant hover:text-white transition-colors", children: /* @__PURE__ */ jsx5(MaterialIcon2, { name: "description" }) }) })
|
|
273
456
|
] }, inv.id)) })
|
|
274
457
|
] }) }),
|
|
275
|
-
hasMore && onLoadMore && /* @__PURE__ */
|
|
458
|
+
hasMore && onLoadMore && /* @__PURE__ */ jsx5("div", { className: "mt-6 flex justify-center", children: /* @__PURE__ */ jsx5("button", { type: "button", onClick: onLoadMore, className: "px-8 py-2 text-[10px] font-mono text-on-surface-variant border border-outline-variant/30 rounded-full hover:bg-surface-container transition-colors uppercase tracking-widest", children: "Load More History" }) })
|
|
276
459
|
] });
|
|
277
460
|
}
|
|
278
461
|
|
|
279
462
|
// src/dashboard/plan-cards.tsx
|
|
280
|
-
import { jsx as
|
|
281
|
-
function
|
|
282
|
-
return /* @__PURE__ */
|
|
463
|
+
import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
464
|
+
function MaterialIcon3({ name, className }) {
|
|
465
|
+
return /* @__PURE__ */ jsx6("span", { className: cn("material-symbols-outlined", className), style: { fontVariationSettings: "'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24" }, children: name });
|
|
283
466
|
}
|
|
284
467
|
function PlanCards({ plans, className }) {
|
|
285
468
|
return /* @__PURE__ */ jsxs5("section", { className, children: [
|
|
286
|
-
/* @__PURE__ */
|
|
287
|
-
/* @__PURE__ */
|
|
469
|
+
/* @__PURE__ */ jsx6("h2", { className: "text-2xl font-bold text-white tracking-tight mb-8 px-2", children: "Subscription Plans" }),
|
|
470
|
+
/* @__PURE__ */ jsx6("div", { className: "grid grid-cols-1 md:grid-cols-3 gap-6", children: plans.map((plan) => /* @__PURE__ */ jsxs5(
|
|
288
471
|
"div",
|
|
289
472
|
{
|
|
290
473
|
className: cn(
|
|
@@ -292,9 +475,9 @@ function PlanCards({ plans, className }) {
|
|
|
292
475
|
plan.popular ? "bg-surface-container-highest border-2 border-md3-primary/30 relative overflow-hidden" : "bg-surface-container-low group hover:bg-surface-container"
|
|
293
476
|
),
|
|
294
477
|
children: [
|
|
295
|
-
plan.popular && /* @__PURE__ */
|
|
478
|
+
plan.popular && /* @__PURE__ */ jsx6("div", { className: "absolute top-0 right-0 bg-md3-primary px-4 py-1 text-[10px] font-bold text-on-primary uppercase tracking-widest rounded-bl-lg", children: "Popular" }),
|
|
296
479
|
/* @__PURE__ */ jsxs5("div", { className: "mb-6", children: [
|
|
297
|
-
/* @__PURE__ */
|
|
480
|
+
/* @__PURE__ */ jsx6("div", { className: cn("text-xs font-mono uppercase tracking-widest mb-2", plan.popular ? "text-md3-primary" : "text-on-surface-variant"), children: plan.name }),
|
|
298
481
|
/* @__PURE__ */ jsxs5("div", { className: "text-3xl font-bold text-white", children: [
|
|
299
482
|
"$",
|
|
300
483
|
plan.price,
|
|
@@ -304,11 +487,11 @@ function PlanCards({ plans, className }) {
|
|
|
304
487
|
] })
|
|
305
488
|
] })
|
|
306
489
|
] }),
|
|
307
|
-
/* @__PURE__ */
|
|
308
|
-
/* @__PURE__ */
|
|
490
|
+
/* @__PURE__ */ jsx6("ul", { className: "space-y-3 mb-8 text-sm text-on-surface-variant", children: plan.features.map((f, i) => /* @__PURE__ */ jsxs5("li", { className: "flex items-center gap-2", children: [
|
|
491
|
+
/* @__PURE__ */ jsx6(MaterialIcon3, { name: "check", className: "text-sm text-md3-primary" }),
|
|
309
492
|
f.text
|
|
310
493
|
] }, i)) }),
|
|
311
|
-
/* @__PURE__ */
|
|
494
|
+
/* @__PURE__ */ jsx6(
|
|
312
495
|
"button",
|
|
313
496
|
{
|
|
314
497
|
type: "button",
|
|
@@ -328,47 +511,10 @@ function PlanCards({ plans, className }) {
|
|
|
328
511
|
}
|
|
329
512
|
|
|
330
513
|
// src/dashboard/dashboard-layout.tsx
|
|
331
|
-
import * as
|
|
332
|
-
import { Fragment as
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
activeNav: "bg-[var(--accent-surface-soft)] text-[var(--accent-text)]",
|
|
336
|
-
userGradient: "bg-[image:var(--accent-gradient-strong)]"
|
|
337
|
-
}
|
|
338
|
-
};
|
|
339
|
-
function DefaultLink2({
|
|
340
|
-
href,
|
|
341
|
-
to,
|
|
342
|
-
className,
|
|
343
|
-
children,
|
|
344
|
-
...rest
|
|
345
|
-
}) {
|
|
346
|
-
return /* @__PURE__ */ jsx6("a", { href: href ?? to, className, ...rest, children });
|
|
347
|
-
}
|
|
348
|
-
function UserIcon({ className }) {
|
|
349
|
-
return /* @__PURE__ */ jsxs6("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, children: [
|
|
350
|
-
/* @__PURE__ */ jsx6("title", { children: "User icon" }),
|
|
351
|
-
/* @__PURE__ */ jsx6("path", { d: "M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2" }),
|
|
352
|
-
/* @__PURE__ */ jsx6("circle", { cx: "12", cy: "7", r: "4" })
|
|
353
|
-
] });
|
|
354
|
-
}
|
|
355
|
-
function SettingsIcon({ className }) {
|
|
356
|
-
return /* @__PURE__ */ jsxs6("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, children: [
|
|
357
|
-
/* @__PURE__ */ jsx6("title", { children: "Settings icon" }),
|
|
358
|
-
/* @__PURE__ */ jsx6("path", { d: "M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z" }),
|
|
359
|
-
/* @__PURE__ */ jsx6("circle", { cx: "12", cy: "12", r: "3" })
|
|
360
|
-
] });
|
|
361
|
-
}
|
|
362
|
-
function LogOutIcon({ className }) {
|
|
363
|
-
return /* @__PURE__ */ jsxs6("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, children: [
|
|
364
|
-
/* @__PURE__ */ jsx6("title", { children: "Log out icon" }),
|
|
365
|
-
/* @__PURE__ */ jsx6("path", { d: "M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4" }),
|
|
366
|
-
/* @__PURE__ */ jsx6("polyline", { points: "16,17 21,12 16,7" }),
|
|
367
|
-
/* @__PURE__ */ jsx6("line", { x1: "21", x2: "9", y1: "12", y2: "12" })
|
|
368
|
-
] });
|
|
369
|
-
}
|
|
370
|
-
function MaterialIcon5({ name, className }) {
|
|
371
|
-
return /* @__PURE__ */ jsx6(
|
|
514
|
+
import * as React3 from "react";
|
|
515
|
+
import { Fragment as Fragment3, jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
516
|
+
function MaterialIcon4({ name, className }) {
|
|
517
|
+
return /* @__PURE__ */ jsx7(
|
|
372
518
|
"span",
|
|
373
519
|
{
|
|
374
520
|
className: cn("material-symbols-outlined", className),
|
|
@@ -377,25 +523,43 @@ function MaterialIcon5({ name, className }) {
|
|
|
377
523
|
}
|
|
378
524
|
);
|
|
379
525
|
}
|
|
526
|
+
function SettingsIconSmall({ className }) {
|
|
527
|
+
return /* @__PURE__ */ jsxs6("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, children: [
|
|
528
|
+
/* @__PURE__ */ jsx7("title", { children: "Settings" }),
|
|
529
|
+
/* @__PURE__ */ jsx7("path", { d: "M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z" }),
|
|
530
|
+
/* @__PURE__ */ jsx7("circle", { cx: "12", cy: "12", r: "3" })
|
|
531
|
+
] });
|
|
532
|
+
}
|
|
380
533
|
function MenuIcon({ className }) {
|
|
381
534
|
return /* @__PURE__ */ jsxs6("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, children: [
|
|
382
|
-
/* @__PURE__ */
|
|
383
|
-
/* @__PURE__ */
|
|
384
|
-
/* @__PURE__ */
|
|
385
|
-
/* @__PURE__ */
|
|
535
|
+
/* @__PURE__ */ jsx7("title", { children: "Menu icon" }),
|
|
536
|
+
/* @__PURE__ */ jsx7("line", { x1: "4", x2: "20", y1: "12", y2: "12" }),
|
|
537
|
+
/* @__PURE__ */ jsx7("line", { x1: "4", x2: "20", y1: "6", y2: "6" }),
|
|
538
|
+
/* @__PURE__ */ jsx7("line", { x1: "4", x2: "20", y1: "18", y2: "18" })
|
|
386
539
|
] });
|
|
387
540
|
}
|
|
388
541
|
function XIcon({ className }) {
|
|
389
542
|
return /* @__PURE__ */ jsxs6("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, children: [
|
|
390
|
-
/* @__PURE__ */
|
|
391
|
-
/* @__PURE__ */
|
|
392
|
-
/* @__PURE__ */
|
|
543
|
+
/* @__PURE__ */ jsx7("title", { children: "Close icon" }),
|
|
544
|
+
/* @__PURE__ */ jsx7("path", { d: "M18 6 6 18" }),
|
|
545
|
+
/* @__PURE__ */ jsx7("path", { d: "m6 6 12 12" })
|
|
393
546
|
] });
|
|
394
547
|
}
|
|
395
|
-
function
|
|
548
|
+
function DefaultLink2({
|
|
549
|
+
href,
|
|
550
|
+
to,
|
|
551
|
+
className,
|
|
552
|
+
children,
|
|
553
|
+
...rest
|
|
554
|
+
}) {
|
|
555
|
+
return /* @__PURE__ */ jsx7("a", { href: href ?? to, className, ...rest, children });
|
|
556
|
+
}
|
|
557
|
+
function DashboardLayoutInner({
|
|
396
558
|
children,
|
|
397
559
|
variant = "sandbox",
|
|
398
560
|
navItems,
|
|
561
|
+
modeItems = [],
|
|
562
|
+
panels = [],
|
|
399
563
|
activeNavId,
|
|
400
564
|
user,
|
|
401
565
|
isLoading = false,
|
|
@@ -408,192 +572,151 @@ function DashboardLayout({
|
|
|
408
572
|
contentClassName,
|
|
409
573
|
topNavLinks,
|
|
410
574
|
activeTopNavHref,
|
|
411
|
-
sandboxName,
|
|
412
|
-
sandboxLabel,
|
|
413
575
|
LinkComponent = DefaultLink2,
|
|
414
|
-
footer
|
|
576
|
+
footer,
|
|
577
|
+
railFooter,
|
|
578
|
+
profileMenuItems
|
|
415
579
|
}) {
|
|
416
|
-
const styles = variantStyles[variant];
|
|
417
580
|
const Link = LinkComponent;
|
|
418
|
-
const [mobileMenuOpen, setMobileMenuOpen] =
|
|
419
|
-
const
|
|
420
|
-
|
|
421
|
-
};
|
|
422
|
-
const
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
/* @__PURE__ */
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
item.id
|
|
449
|
-
)
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
onClick: onNewSandbox,
|
|
457
|
-
className: "w-full flex items-center justify-center gap-2 bg-gradient-to-r from-md3-primary to-primary-container text-on-primary font-bold py-2.5 rounded-lg mb-4 text-xs active:scale-95 duration-200 transition-transform",
|
|
458
|
-
children: [
|
|
459
|
-
/* @__PURE__ */ jsx6(MaterialIcon5, { name: "add", className: "text-sm" }),
|
|
460
|
-
"New Agent"
|
|
461
|
-
]
|
|
462
|
-
}
|
|
463
|
-
),
|
|
464
|
-
/* @__PURE__ */ jsxs6(
|
|
465
|
-
Link,
|
|
466
|
-
{
|
|
467
|
-
href: "/docs",
|
|
468
|
-
to: "/docs",
|
|
469
|
-
className: "flex items-center gap-3 px-4 py-2 rounded-lg text-slate-500 hover:bg-slate-800 hover:text-slate-300 transition-colors font-mono text-xs",
|
|
470
|
-
children: [
|
|
471
|
-
/* @__PURE__ */ jsx6(MaterialIcon5, { name: "menu_book", className: "text-sm" }),
|
|
472
|
-
"Documentation"
|
|
473
|
-
]
|
|
474
|
-
}
|
|
475
|
-
),
|
|
476
|
-
/* @__PURE__ */ jsxs6(
|
|
477
|
-
Link,
|
|
478
|
-
{
|
|
479
|
-
href: "/support",
|
|
480
|
-
to: "/support",
|
|
481
|
-
className: "flex items-center gap-3 px-4 py-2 rounded-lg text-slate-500 hover:bg-slate-800 hover:text-slate-300 transition-colors font-mono text-xs",
|
|
482
|
-
children: [
|
|
483
|
-
/* @__PURE__ */ jsx6(MaterialIcon5, { name: "contact_support", className: "text-sm" }),
|
|
484
|
-
"Support"
|
|
485
|
-
]
|
|
486
|
-
}
|
|
487
|
-
)
|
|
488
|
-
] })
|
|
489
|
-
] });
|
|
490
|
-
return /* @__PURE__ */ jsxs6("div", { className: cn("min-h-screen bg-surface text-on-surface", className), children: [
|
|
491
|
-
/* @__PURE__ */ jsxs6("nav", { className: "fixed top-0 w-full z-50 bg-slate-950/60 backdrop-blur-xl flex justify-between items-center px-8 h-16 font-sans text-sm tracking-tight", children: [
|
|
492
|
-
/* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-8", children: [
|
|
493
|
-
/* @__PURE__ */ jsx6(Logo, { variant, size: "md", className: "hidden md:block" }),
|
|
494
|
-
topNavLinks && topNavLinks.length > 0 && /* @__PURE__ */ jsx6("div", { className: "hidden md:flex gap-6", children: topNavLinks.map((link) => /* @__PURE__ */ jsx6(
|
|
495
|
-
Link,
|
|
496
|
-
{
|
|
497
|
-
href: link.href,
|
|
498
|
-
to: link.href,
|
|
499
|
-
className: cn(
|
|
500
|
-
"transition-all duration-300 px-2 py-1 rounded",
|
|
501
|
-
activeTopNavHref === link.href ? "text-white border-b-2 border-violet-500 pb-1" : "text-slate-400 hover:text-slate-200 hover:bg-white/5"
|
|
502
|
-
),
|
|
503
|
-
children: link.label
|
|
504
|
-
},
|
|
505
|
-
link.href
|
|
506
|
-
)) })
|
|
507
|
-
] }),
|
|
508
|
-
/* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-4", children: [
|
|
509
|
-
onNewSandbox && /* @__PURE__ */ jsxs6(
|
|
510
|
-
"button",
|
|
581
|
+
const [mobileMenuOpen, setMobileMenuOpen] = React3.useState(false);
|
|
582
|
+
const { contentMargin, hidden, mode } = useSidebar();
|
|
583
|
+
const modeSet = React3.useMemo(() => new Set(modeItems), [modeItems]);
|
|
584
|
+
const sidebarUser = user ? { email: user.email, name: user.name, tier: user.tier, avatarUrl: user.avatarUrl } : void 0;
|
|
585
|
+
const activePanel = panels.find((p) => p.mode === mode);
|
|
586
|
+
const sidebarContent = /* @__PURE__ */ jsxs6(Fragment3, { children: [
|
|
587
|
+
/* @__PURE__ */ jsxs6(SidebarRail, { children: [
|
|
588
|
+
/* @__PURE__ */ jsx7(SidebarRailHeader, { children: /* @__PURE__ */ jsx7(Link, { href: "/", to: "/", className: "p-1 rounded-md transition-colors hover:bg-sidebar-accent/80", children: /* @__PURE__ */ jsx7(Logo, { variant, size: "sm", iconOnly: true }) }) }),
|
|
589
|
+
/* @__PURE__ */ jsx7(SidebarRailNav, { children: navItems.map((item, i) => {
|
|
590
|
+
const isMode = modeSet.has(item.id);
|
|
591
|
+
const prevIsMode = i > 0 && modeSet.has(navItems[i - 1].id);
|
|
592
|
+
const showSep = i > 0 && isMode && !prevIsMode;
|
|
593
|
+
return /* @__PURE__ */ jsxs6(React3.Fragment, { children: [
|
|
594
|
+
showSep && /* @__PURE__ */ jsx7(RailSeparator, {}),
|
|
595
|
+
isMode ? /* @__PURE__ */ jsx7(
|
|
596
|
+
RailModeButton,
|
|
597
|
+
{
|
|
598
|
+
mode: item.id,
|
|
599
|
+
icon: item.icon,
|
|
600
|
+
label: item.label,
|
|
601
|
+
badge: item.badge
|
|
602
|
+
}
|
|
603
|
+
) : /* @__PURE__ */ jsx7(Link, { href: item.href, to: item.href, children: /* @__PURE__ */ jsx7(
|
|
604
|
+
RailButton,
|
|
605
|
+
{
|
|
606
|
+
icon: item.icon,
|
|
607
|
+
label: item.label,
|
|
608
|
+
isActive: activeNavId === item.id
|
|
609
|
+
}
|
|
610
|
+
) })
|
|
611
|
+
] }, item.id);
|
|
612
|
+
}) }),
|
|
613
|
+
/* @__PURE__ */ jsxs6(SidebarRailFooter, { children: [
|
|
614
|
+
onSettingsClick ? /* @__PURE__ */ jsx7(RailButton, { icon: SettingsIconSmall, label: "Settings", onClick: onSettingsClick }) : /* @__PURE__ */ jsx7(Link, { href: settingsHref, to: settingsHref, children: /* @__PURE__ */ jsx7(RailButton, { icon: SettingsIconSmall, label: "Settings" }) }),
|
|
615
|
+
railFooter,
|
|
616
|
+
/* @__PURE__ */ jsx7(RailSeparator, {}),
|
|
617
|
+
/* @__PURE__ */ jsx7(
|
|
618
|
+
ProfileAvatar,
|
|
511
619
|
{
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
620
|
+
user: sidebarUser,
|
|
621
|
+
isLoading,
|
|
622
|
+
onLogout,
|
|
623
|
+
onSettingsClick,
|
|
624
|
+
settingsHref,
|
|
625
|
+
LinkComponent,
|
|
626
|
+
children: profileMenuItems
|
|
519
627
|
}
|
|
520
|
-
)
|
|
521
|
-
|
|
522
|
-
onSettingsClick ? /* @__PURE__ */ jsx6("button", { type: "button", onClick: onSettingsClick, className: "text-slate-400 hover:text-violet-400 transition-colors p-2 rounded-lg hover:bg-white/5", children: /* @__PURE__ */ jsx6(MaterialIcon5, { name: "settings" }) }) : /* @__PURE__ */ jsx6(Link, { href: settingsHref, to: settingsHref, className: "text-slate-400 hover:text-violet-400 transition-colors p-2 rounded-lg hover:bg-white/5", children: /* @__PURE__ */ jsx6(MaterialIcon5, { name: "settings" }) }),
|
|
523
|
-
/* @__PURE__ */ jsxs6(DropdownMenu, { children: [
|
|
524
|
-
/* @__PURE__ */ jsx6(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx6("button", { type: "button", className: "w-8 h-8 rounded-full bg-surface-container-highest flex items-center justify-center border border-outline-variant/20 overflow-hidden", "aria-label": "User menu", children: user?.avatarUrl ? /* @__PURE__ */ jsx6("img", { src: user.avatarUrl, alt: "", className: "w-full h-full object-cover" }) : /* @__PURE__ */ jsx6(UserIcon, { className: "h-4 w-4 text-on-surface-variant" }) }) }),
|
|
525
|
-
/* @__PURE__ */ jsxs6(DropdownMenuContent, { align: "end", className: "w-56", children: [
|
|
526
|
-
/* @__PURE__ */ jsx6(DropdownMenuLabel, { children: isLoading ? /* @__PURE__ */ jsx6(Skeleton, { className: "h-4 w-24" }) : /* @__PURE__ */ jsxs6("div", { children: [
|
|
527
|
-
/* @__PURE__ */ jsx6("p", { className: "truncate text-sm", children: user?.email ?? "Not logged in" }),
|
|
528
|
-
/* @__PURE__ */ jsxs6("p", { className: "text-muted-foreground text-xs capitalize", children: [
|
|
529
|
-
user?.tier ?? "Free",
|
|
530
|
-
" Plan"
|
|
531
|
-
] })
|
|
532
|
-
] }) }),
|
|
533
|
-
/* @__PURE__ */ jsx6(DropdownMenuSeparator, {}),
|
|
534
|
-
onSettingsClick ? /* @__PURE__ */ jsxs6(DropdownMenuItem, { onClick: onSettingsClick, children: [
|
|
535
|
-
/* @__PURE__ */ jsx6(SettingsIcon, { className: "mr-2 h-4 w-4", "aria-hidden": "true" }),
|
|
536
|
-
"Settings"
|
|
537
|
-
] }) : /* @__PURE__ */ jsx6(DropdownMenuItem, { asChild: true, children: /* @__PURE__ */ jsxs6(Link, { href: settingsHref, to: settingsHref, className: "flex items-center", children: [
|
|
538
|
-
/* @__PURE__ */ jsx6(SettingsIcon, { className: "mr-2 h-4 w-4", "aria-hidden": "true" }),
|
|
539
|
-
"Settings"
|
|
540
|
-
] }) }),
|
|
541
|
-
onLogout && /* @__PURE__ */ jsxs6(DropdownMenuItem, { className: "text-red-400", onClick: onLogout, children: [
|
|
542
|
-
/* @__PURE__ */ jsx6(LogOutIcon, { className: "mr-2 h-4 w-4", "aria-hidden": "true" }),
|
|
543
|
-
"Sign Out"
|
|
544
|
-
] })
|
|
545
|
-
] })
|
|
546
|
-
] })
|
|
547
|
-
] }),
|
|
548
|
-
/* @__PURE__ */ jsx6(
|
|
549
|
-
"button",
|
|
550
|
-
{
|
|
551
|
-
type: "button",
|
|
552
|
-
onClick: () => setMobileMenuOpen(!mobileMenuOpen),
|
|
553
|
-
className: "rounded-md p-2 hover:bg-white/5 md:hidden",
|
|
554
|
-
"aria-label": mobileMenuOpen ? "Close menu" : "Open menu",
|
|
555
|
-
"aria-expanded": mobileMenuOpen,
|
|
556
|
-
children: mobileMenuOpen ? /* @__PURE__ */ jsx6(XIcon, { className: "h-6 w-6" }) : /* @__PURE__ */ jsx6(MenuIcon, { className: "h-6 w-6" })
|
|
557
|
-
}
|
|
558
|
-
)
|
|
628
|
+
)
|
|
629
|
+
] })
|
|
559
630
|
] }),
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
631
|
+
panels.length > 0 && /* @__PURE__ */ jsxs6(SidebarPanel, { children: [
|
|
632
|
+
/* @__PURE__ */ jsx7(SidebarPanelHeader, { title: activePanel?.title ?? mode }),
|
|
633
|
+
/* @__PURE__ */ jsx7(SidebarPanelContent, { children: activePanel?.content })
|
|
634
|
+
] })
|
|
635
|
+
] });
|
|
636
|
+
return /* @__PURE__ */ jsxs6("div", { className: cn("min-h-screen bg-surface text-on-surface", className), children: [
|
|
637
|
+
/* @__PURE__ */ jsxs6(
|
|
638
|
+
"nav",
|
|
563
639
|
{
|
|
564
|
-
className:
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
children:
|
|
640
|
+
className: "fixed top-0 z-50 bg-slate-950/60 backdrop-blur-xl flex justify-between items-center px-8 h-14 font-sans text-sm tracking-tight transition-[left,width] duration-200 ease-in-out",
|
|
641
|
+
style: {
|
|
642
|
+
left: hidden ? 0 : contentMargin,
|
|
643
|
+
width: hidden ? "100%" : `calc(100% - ${contentMargin}px)`
|
|
644
|
+
},
|
|
645
|
+
children: [
|
|
646
|
+
/* @__PURE__ */ jsx7("div", { className: "flex items-center gap-8", children: topNavLinks && topNavLinks.length > 0 && /* @__PURE__ */ jsx7("div", { className: "hidden md:flex gap-6", children: topNavLinks.map((link) => /* @__PURE__ */ jsx7(
|
|
647
|
+
Link,
|
|
648
|
+
{
|
|
649
|
+
href: link.href,
|
|
650
|
+
to: link.href,
|
|
651
|
+
className: cn(
|
|
652
|
+
"transition-all duration-300 px-2 py-1 rounded",
|
|
653
|
+
activeTopNavHref === link.href ? "text-white border-b-2 border-violet-500 pb-1" : "text-slate-400 hover:text-slate-200 hover:bg-white/5"
|
|
654
|
+
),
|
|
655
|
+
children: link.label
|
|
656
|
+
},
|
|
657
|
+
link.href
|
|
658
|
+
)) }) }),
|
|
659
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-4", children: [
|
|
660
|
+
onNewSandbox && /* @__PURE__ */ jsxs6(
|
|
661
|
+
"button",
|
|
662
|
+
{
|
|
663
|
+
type: "button",
|
|
664
|
+
onClick: onNewSandbox,
|
|
665
|
+
className: "hidden md:flex items-center gap-2 bg-md3-primary text-on-primary px-4 py-2 rounded-lg font-bold hover:shadow-[0_0_15px_rgba(209,188,255,0.4)] transition-all active:scale-95 text-xs",
|
|
666
|
+
children: [
|
|
667
|
+
/* @__PURE__ */ jsx7(MaterialIcon4, { name: "add", className: "text-sm" }),
|
|
668
|
+
"New Sandbox"
|
|
669
|
+
]
|
|
670
|
+
}
|
|
671
|
+
),
|
|
672
|
+
/* @__PURE__ */ jsx7("button", { type: "button", className: "text-slate-400 hover:text-violet-400 transition-colors p-2 rounded-lg hover:bg-white/5", children: /* @__PURE__ */ jsx7(MaterialIcon4, { name: "notifications" }) })
|
|
673
|
+
] }),
|
|
674
|
+
/* @__PURE__ */ jsx7(
|
|
675
|
+
"button",
|
|
676
|
+
{
|
|
677
|
+
type: "button",
|
|
678
|
+
onClick: () => setMobileMenuOpen(!mobileMenuOpen),
|
|
679
|
+
className: "rounded-md p-2 hover:bg-white/5 lg:hidden",
|
|
680
|
+
"aria-label": mobileMenuOpen ? "Close menu" : "Open menu",
|
|
681
|
+
"aria-expanded": mobileMenuOpen,
|
|
682
|
+
children: mobileMenuOpen ? /* @__PURE__ */ jsx7(XIcon, { className: "h-6 w-6" }) : /* @__PURE__ */ jsx7(MenuIcon, { className: "h-6 w-6" })
|
|
683
|
+
}
|
|
684
|
+
)
|
|
685
|
+
]
|
|
570
686
|
}
|
|
571
687
|
),
|
|
572
|
-
/* @__PURE__ */
|
|
688
|
+
mobileMenuOpen && /* @__PURE__ */ jsx7("div", { className: "fixed inset-0 z-30 bg-black/50 lg:hidden", onClick: () => setMobileMenuOpen(false), "aria-hidden": "true" }),
|
|
689
|
+
/* @__PURE__ */ jsx7(
|
|
573
690
|
"aside",
|
|
574
691
|
{
|
|
575
692
|
className: cn(
|
|
576
|
-
"
|
|
577
|
-
|
|
693
|
+
"fixed top-14 bottom-0 left-0 z-30 flex bg-sidebar backdrop-blur-xl transition-transform duration-200 lg:hidden",
|
|
694
|
+
mobileMenuOpen ? "translate-x-0" : "-translate-x-full"
|
|
578
695
|
),
|
|
579
|
-
|
|
696
|
+
style: { width: SIDEBAR_TOTAL_WIDTH },
|
|
697
|
+
children: sidebarContent
|
|
580
698
|
}
|
|
581
699
|
),
|
|
582
|
-
/* @__PURE__ */
|
|
700
|
+
/* @__PURE__ */ jsx7(Sidebar, { className: cn("hidden lg:flex", sidebarClassName), children: sidebarContent }),
|
|
701
|
+
/* @__PURE__ */ jsx7(SidebarContent, { className: cn("pt-20 px-8 pb-12 hidden lg:block", contentClassName), children }),
|
|
702
|
+
/* @__PURE__ */ jsx7("main", { className: cn("pt-20 px-8 pb-12 min-h-screen lg:hidden", contentClassName), children }),
|
|
583
703
|
footer
|
|
584
704
|
] });
|
|
585
705
|
}
|
|
706
|
+
function DashboardLayout({ defaultPanelOpen, defaultMode, ...props }) {
|
|
707
|
+
return /* @__PURE__ */ jsx7(SidebarProvider, { defaultPanelOpen, defaultMode, children: /* @__PURE__ */ jsx7(DashboardLayoutInner, { ...props }) });
|
|
708
|
+
}
|
|
586
709
|
|
|
587
710
|
// src/dashboard/resource-meter.tsx
|
|
588
|
-
import { jsx as
|
|
711
|
+
import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
589
712
|
function getColorByUsage(percent) {
|
|
590
713
|
if (percent >= 90) return "from-red-500 to-red-300";
|
|
591
714
|
if (percent >= 70) return "from-yellow-500 to-yellow-300";
|
|
592
715
|
if (percent >= 40) return "from-blue-500 to-blue-300";
|
|
593
716
|
return "from-green-500 to-green-300";
|
|
594
717
|
}
|
|
595
|
-
function
|
|
596
|
-
return /* @__PURE__ */
|
|
718
|
+
function MaterialIcon5({ name, className }) {
|
|
719
|
+
return /* @__PURE__ */ jsx8("span", { className: cn("material-symbols-outlined", className), style: { fontVariationSettings: "'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24" }, children: name });
|
|
597
720
|
}
|
|
598
721
|
function ResourceMeter({ label, value, max = 100, unit, icon, className }) {
|
|
599
722
|
const percent = max > 0 ? Math.min(value / max * 100, 100) : 0;
|
|
@@ -601,12 +724,12 @@ function ResourceMeter({ label, value, max = 100, unit, icon, className }) {
|
|
|
601
724
|
return /* @__PURE__ */ jsxs7("div", { className: cn("space-y-2", className), children: [
|
|
602
725
|
/* @__PURE__ */ jsxs7("div", { className: "flex justify-between text-[11px] font-bold font-mono text-on-surface uppercase tracking-tight", children: [
|
|
603
726
|
/* @__PURE__ */ jsxs7("span", { className: "flex items-center gap-1", children: [
|
|
604
|
-
icon && /* @__PURE__ */
|
|
727
|
+
icon && /* @__PURE__ */ jsx8(MaterialIcon5, { name: icon, className: "text-xs" }),
|
|
605
728
|
label
|
|
606
729
|
] }),
|
|
607
|
-
/* @__PURE__ */
|
|
730
|
+
/* @__PURE__ */ jsx8("span", { className: "text-primary-fixed-dim", children: unit ? `${value}${unit} / ${max}${unit}` : `${Math.round(percent)}%` })
|
|
608
731
|
] }),
|
|
609
|
-
/* @__PURE__ */
|
|
732
|
+
/* @__PURE__ */ jsx8("div", { className: "h-2 w-full bg-surface-container-highest rounded-full overflow-hidden", children: /* @__PURE__ */ jsx8(
|
|
610
733
|
"div",
|
|
611
734
|
{
|
|
612
735
|
className: cn("h-full bg-gradient-to-r rounded-full transition-all duration-500", gradient),
|
|
@@ -617,9 +740,9 @@ function ResourceMeter({ label, value, max = 100, unit, icon, className }) {
|
|
|
617
740
|
}
|
|
618
741
|
|
|
619
742
|
// src/dashboard/sandbox-card.tsx
|
|
620
|
-
import { jsx as
|
|
621
|
-
function
|
|
622
|
-
return /* @__PURE__ */
|
|
743
|
+
import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
744
|
+
function MaterialIcon6({ name, className }) {
|
|
745
|
+
return /* @__PURE__ */ jsx9("span", { className: cn("material-symbols-outlined", className), style: { fontVariationSettings: "'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24" }, children: name });
|
|
623
746
|
}
|
|
624
747
|
var statusConfig = {
|
|
625
748
|
running: { color: "text-green-400", bgColor: "bg-green-500/10", borderColor: "border-green-500/20", dotClass: "bg-green-400 animate-pulse", label: "Running" },
|
|
@@ -642,13 +765,15 @@ function getGlow(image) {
|
|
|
642
765
|
}
|
|
643
766
|
return "";
|
|
644
767
|
}
|
|
645
|
-
function SandboxCard({ sandbox, onOpenIDE, onOpenTerminal, onWake, onRestore, className }) {
|
|
768
|
+
function SandboxCard({ sandbox, onOpenIDE, onOpenTerminal, onWake, onRestore, onDelete, onSSH, className }) {
|
|
646
769
|
const status = statusConfig[sandbox.status] ?? statusConfig.stopped;
|
|
647
770
|
const glow = getGlow(sandbox.image);
|
|
648
771
|
const isActive = sandbox.status === "running";
|
|
649
772
|
const isHibernating = sandbox.status === "hibernating";
|
|
773
|
+
const isStopped = sandbox.status === "stopped";
|
|
650
774
|
const isProvisioning = sandbox.status === "provisioning";
|
|
651
775
|
const isArchived = sandbox.status === "archived";
|
|
776
|
+
const isWakeable = isHibernating || isStopped;
|
|
652
777
|
return /* @__PURE__ */ jsxs8(
|
|
653
778
|
"div",
|
|
654
779
|
{
|
|
@@ -659,20 +784,43 @@ function SandboxCard({ sandbox, onOpenIDE, onOpenTerminal, onWake, onRestore, cl
|
|
|
659
784
|
className
|
|
660
785
|
),
|
|
661
786
|
children: [
|
|
662
|
-
/* @__PURE__ */
|
|
663
|
-
/* @__PURE__ */
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
787
|
+
/* @__PURE__ */ jsxs8("div", { className: "absolute top-0 right-0 p-4 flex items-center gap-2", children: [
|
|
788
|
+
/* @__PURE__ */ jsxs8("span", { className: cn("flex items-center gap-1.5 px-3 py-1 rounded-full text-[10px] font-black tracking-widest uppercase border", status.bgColor, status.color, status.borderColor), children: [
|
|
789
|
+
/* @__PURE__ */ jsx9("span", { className: cn("w-2 h-2 rounded-full", status.dotClass) }),
|
|
790
|
+
status.label
|
|
791
|
+
] }),
|
|
792
|
+
!isProvisioning && (onSSH || onDelete) && /* @__PURE__ */ jsxs8(DropdownMenu, { children: [
|
|
793
|
+
/* @__PURE__ */ jsx9(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx9(
|
|
794
|
+
"button",
|
|
795
|
+
{
|
|
796
|
+
type: "button",
|
|
797
|
+
className: "p-1 rounded-lg hover:bg-surface-container-highest text-on-surface-variant hover:text-white transition-all opacity-0 group-hover:opacity-100",
|
|
798
|
+
children: /* @__PURE__ */ jsx9(MaterialIcon6, { name: "more_vert", className: "text-lg" })
|
|
799
|
+
}
|
|
800
|
+
) }),
|
|
801
|
+
/* @__PURE__ */ jsxs8(DropdownMenuContent, { align: "end", className: "min-w-[160px]", children: [
|
|
802
|
+
isActive && onSSH && /* @__PURE__ */ jsxs8(DropdownMenuItem, { onClick: () => onSSH(sandbox.id), children: [
|
|
803
|
+
/* @__PURE__ */ jsx9(MaterialIcon6, { name: "vpn_key", className: "text-base mr-2" }),
|
|
804
|
+
"SSH Info"
|
|
805
|
+
] }),
|
|
806
|
+
isActive && onSSH && onDelete && /* @__PURE__ */ jsx9(DropdownMenuSeparator, {}),
|
|
807
|
+
onDelete && /* @__PURE__ */ jsxs8(DropdownMenuItem, { onClick: () => onDelete(sandbox.id), className: "text-red-400 focus:text-red-400", children: [
|
|
808
|
+
/* @__PURE__ */ jsx9(MaterialIcon6, { name: "delete", className: "text-base mr-2" }),
|
|
809
|
+
"Delete"
|
|
810
|
+
] })
|
|
811
|
+
] })
|
|
812
|
+
] })
|
|
813
|
+
] }),
|
|
814
|
+
/* @__PURE__ */ jsx9("div", { className: "mb-6", children: /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-3 mb-2", children: [
|
|
815
|
+
sandbox.imageIcon && /* @__PURE__ */ jsx9("div", { className: "w-10 h-10 rounded-lg flex items-center justify-center bg-surface-container-high", children: sandbox.imageIcon }),
|
|
668
816
|
/* @__PURE__ */ jsxs8("div", { className: "min-w-0", children: [
|
|
669
|
-
/* @__PURE__ */
|
|
670
|
-
sandbox.nodeId && /* @__PURE__ */
|
|
817
|
+
/* @__PURE__ */ jsx9("h3", { className: "text-xl font-bold text-white group-hover:text-md3-primary transition-colors truncate", children: sandbox.name }),
|
|
818
|
+
sandbox.nodeId && /* @__PURE__ */ jsx9("p", { className: "text-on-surface-variant font-mono text-xs truncate", children: sandbox.nodeId })
|
|
671
819
|
] })
|
|
672
820
|
] }) }),
|
|
673
821
|
isProvisioning ? /* @__PURE__ */ jsxs8("div", { className: "mb-8 mt-10", children: [
|
|
674
|
-
/* @__PURE__ */
|
|
675
|
-
/* @__PURE__ */
|
|
822
|
+
/* @__PURE__ */ jsx9("p", { className: "text-[10px] font-bold font-mono text-orange-400 mb-3 uppercase text-center animate-pulse tracking-widest", children: sandbox.provisioningMessage ?? "Initializing..." }),
|
|
823
|
+
/* @__PURE__ */ jsx9("div", { className: "h-2 w-full bg-surface-container-highest rounded-full overflow-hidden", children: /* @__PURE__ */ jsx9(
|
|
676
824
|
"div",
|
|
677
825
|
{
|
|
678
826
|
className: "h-full bg-gradient-to-r from-orange-600 via-orange-400 to-orange-300 transition-all duration-500",
|
|
@@ -680,8 +828,8 @@ function SandboxCard({ sandbox, onOpenIDE, onOpenTerminal, onWake, onRestore, cl
|
|
|
680
828
|
}
|
|
681
829
|
) })
|
|
682
830
|
] }) : !isArchived ? /* @__PURE__ */ jsxs8("div", { className: cn("space-y-5 mb-8", !isActive && "opacity-40"), children: [
|
|
683
|
-
/* @__PURE__ */
|
|
684
|
-
/* @__PURE__ */
|
|
831
|
+
/* @__PURE__ */ jsx9(ResourceMeter, { label: "CPU Usage", icon: "memory", value: sandbox.cpuPercent ?? 0 }),
|
|
832
|
+
/* @__PURE__ */ jsx9(
|
|
685
833
|
ResourceMeter,
|
|
686
834
|
{
|
|
687
835
|
label: "RAM Usage",
|
|
@@ -691,7 +839,7 @@ function SandboxCard({ sandbox, onOpenIDE, onOpenTerminal, onWake, onRestore, cl
|
|
|
691
839
|
unit: "GB"
|
|
692
840
|
}
|
|
693
841
|
)
|
|
694
|
-
] }) : /* @__PURE__ */
|
|
842
|
+
] }) : /* @__PURE__ */ jsx9("div", { className: "mb-6", children: sandbox.archivedAt && /* @__PURE__ */ jsx9("p", { className: "text-slate-500 font-mono text-[10px]", children: sandbox.archivedAt }) }),
|
|
695
843
|
isActive && /* @__PURE__ */ jsxs8("div", { className: "grid grid-cols-2 gap-3", children: [
|
|
696
844
|
/* @__PURE__ */ jsxs8(
|
|
697
845
|
"button",
|
|
@@ -700,7 +848,7 @@ function SandboxCard({ sandbox, onOpenIDE, onOpenTerminal, onWake, onRestore, cl
|
|
|
700
848
|
onClick: () => onOpenIDE?.(sandbox.id),
|
|
701
849
|
className: "flex items-center justify-center gap-2 py-2.5 bg-surface-container-high hover:bg-md3-primary hover:text-on-primary rounded-lg transition-all duration-300 text-xs font-bold shadow-sm",
|
|
702
850
|
children: [
|
|
703
|
-
/* @__PURE__ */
|
|
851
|
+
/* @__PURE__ */ jsx9(MaterialIcon6, { name: "open_in_new", className: "text-sm" }),
|
|
704
852
|
"Open IDE"
|
|
705
853
|
]
|
|
706
854
|
}
|
|
@@ -712,25 +860,25 @@ function SandboxCard({ sandbox, onOpenIDE, onOpenTerminal, onWake, onRestore, cl
|
|
|
712
860
|
onClick: () => onOpenTerminal?.(sandbox.id),
|
|
713
861
|
className: "flex items-center justify-center gap-2 py-2.5 bg-surface-container-high hover:bg-slate-700 rounded-lg transition-all text-xs font-bold border border-outline-variant/10",
|
|
714
862
|
children: [
|
|
715
|
-
/* @__PURE__ */
|
|
863
|
+
/* @__PURE__ */ jsx9(MaterialIcon6, { name: "terminal", className: "text-sm" }),
|
|
716
864
|
"Terminal"
|
|
717
865
|
]
|
|
718
866
|
}
|
|
719
867
|
)
|
|
720
868
|
] }),
|
|
721
|
-
|
|
869
|
+
isWakeable && /* @__PURE__ */ jsxs8(
|
|
722
870
|
"button",
|
|
723
871
|
{
|
|
724
872
|
type: "button",
|
|
725
873
|
onClick: () => onWake?.(sandbox.id),
|
|
726
874
|
className: "w-full flex items-center justify-center gap-2 py-3 bg-md3-primary/10 text-md3-primary hover:bg-md3-primary hover:text-on-primary rounded-lg transition-all duration-300 text-xs font-black",
|
|
727
875
|
children: [
|
|
728
|
-
/* @__PURE__ */
|
|
876
|
+
/* @__PURE__ */ jsx9(MaterialIcon6, { name: "power_settings_new", className: "text-sm" }),
|
|
729
877
|
"Wake Sandbox"
|
|
730
878
|
]
|
|
731
879
|
}
|
|
732
880
|
),
|
|
733
|
-
isProvisioning && /* @__PURE__ */
|
|
881
|
+
isProvisioning && /* @__PURE__ */ jsx9(
|
|
734
882
|
"button",
|
|
735
883
|
{
|
|
736
884
|
type: "button",
|
|
@@ -739,7 +887,7 @@ function SandboxCard({ sandbox, onOpenIDE, onOpenTerminal, onWake, onRestore, cl
|
|
|
739
887
|
children: "Please Wait..."
|
|
740
888
|
}
|
|
741
889
|
),
|
|
742
|
-
isArchived && /* @__PURE__ */
|
|
890
|
+
isArchived && /* @__PURE__ */ jsx9(
|
|
743
891
|
"button",
|
|
744
892
|
{
|
|
745
893
|
type: "button",
|
|
@@ -763,18 +911,18 @@ function NewSandboxCard({ onClick, className }) {
|
|
|
763
911
|
className
|
|
764
912
|
),
|
|
765
913
|
children: [
|
|
766
|
-
/* @__PURE__ */
|
|
767
|
-
/* @__PURE__ */
|
|
768
|
-
/* @__PURE__ */
|
|
914
|
+
/* @__PURE__ */ jsx9("div", { className: "w-14 h-14 rounded-full bg-surface-container flex items-center justify-center mb-4 group-hover:bg-md3-primary/20 group-hover:text-md3-primary transition-all group-active:scale-90", children: /* @__PURE__ */ jsx9(MaterialIcon6, { name: "add_box", className: "text-3xl" }) }),
|
|
915
|
+
/* @__PURE__ */ jsx9("h4", { className: "font-bold text-slate-400 group-hover:text-white mb-1", children: "New Environment" }),
|
|
916
|
+
/* @__PURE__ */ jsx9("p", { className: "text-xs text-slate-600", children: "Instantiate a fresh compute node" })
|
|
769
917
|
]
|
|
770
918
|
}
|
|
771
919
|
);
|
|
772
920
|
}
|
|
773
921
|
|
|
774
922
|
// src/dashboard/sandbox-table.tsx
|
|
775
|
-
import { Fragment as
|
|
776
|
-
function
|
|
777
|
-
return /* @__PURE__ */
|
|
923
|
+
import { Fragment as Fragment4, jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
924
|
+
function MaterialIcon7({ name, className }) {
|
|
925
|
+
return /* @__PURE__ */ jsx10("span", { className: cn("material-symbols-outlined", className), style: { fontVariationSettings: "'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24" }, children: name });
|
|
778
926
|
}
|
|
779
927
|
var statusColors = {
|
|
780
928
|
running: { dot: "bg-green-400 animate-pulse", text: "text-green-400", bar: "bg-green-400" },
|
|
@@ -787,13 +935,13 @@ var statusColors = {
|
|
|
787
935
|
function MiniMeter({ label, percent, className }) {
|
|
788
936
|
return /* @__PURE__ */ jsxs9("div", { className: cn("space-y-1", className), children: [
|
|
789
937
|
/* @__PURE__ */ jsxs9("div", { className: "flex justify-between text-[10px] font-mono text-on-surface-variant", children: [
|
|
790
|
-
/* @__PURE__ */
|
|
938
|
+
/* @__PURE__ */ jsx10("span", { className: "font-bold", children: label }),
|
|
791
939
|
/* @__PURE__ */ jsxs9("span", { className: "text-primary-fixed", children: [
|
|
792
940
|
percent,
|
|
793
941
|
"%"
|
|
794
942
|
] })
|
|
795
943
|
] }),
|
|
796
|
-
/* @__PURE__ */
|
|
944
|
+
/* @__PURE__ */ jsx10("div", { className: "h-1.5 w-full bg-surface-container-highest rounded-full overflow-hidden", children: /* @__PURE__ */ jsx10("div", { className: "h-full bg-md3-primary rounded-full", style: { width: `${percent}%` } }) })
|
|
797
945
|
] });
|
|
798
946
|
}
|
|
799
947
|
function SandboxTable({
|
|
@@ -806,56 +954,72 @@ function SandboxTable({
|
|
|
806
954
|
onOpenTerminal,
|
|
807
955
|
onSSH,
|
|
808
956
|
onWake,
|
|
957
|
+
onDelete,
|
|
809
958
|
onMore,
|
|
810
959
|
className
|
|
811
960
|
}) {
|
|
961
|
+
const handleDelete = onDelete ?? onMore;
|
|
812
962
|
const totalCount = total ?? sandboxes.length;
|
|
813
963
|
const totalPages = Math.ceil(totalCount / pageSize);
|
|
814
964
|
return /* @__PURE__ */ jsxs9("div", { className: cn("w-full", className), children: [
|
|
815
|
-
/* @__PURE__ */
|
|
816
|
-
/* @__PURE__ */
|
|
817
|
-
/* @__PURE__ */
|
|
818
|
-
/* @__PURE__ */
|
|
819
|
-
/* @__PURE__ */
|
|
820
|
-
/* @__PURE__ */
|
|
821
|
-
/* @__PURE__ */
|
|
965
|
+
/* @__PURE__ */ jsx10("div", { className: "w-full bg-surface-container-low rounded-2xl overflow-hidden shadow-2xl border border-outline-variant/10", children: /* @__PURE__ */ jsx10("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsxs9("table", { className: "w-full text-left border-collapse", children: [
|
|
966
|
+
/* @__PURE__ */ jsx10("thead", { children: /* @__PURE__ */ jsxs9("tr", { className: "bg-surface-container-high/50 border-b border-outline-variant/10", children: [
|
|
967
|
+
/* @__PURE__ */ jsx10("th", { className: "px-6 py-4 text-xs font-semibold text-on-surface-variant uppercase tracking-wider", children: "Status" }),
|
|
968
|
+
/* @__PURE__ */ jsx10("th", { className: "px-6 py-4 text-xs font-semibold text-on-surface-variant uppercase tracking-wider", children: "Sandbox Name" }),
|
|
969
|
+
/* @__PURE__ */ jsx10("th", { className: "px-6 py-4 text-xs font-semibold text-on-surface-variant uppercase tracking-wider", children: "Environment" }),
|
|
970
|
+
/* @__PURE__ */ jsx10("th", { className: "px-6 py-4 text-xs font-semibold text-on-surface-variant uppercase tracking-wider", children: "Resources" }),
|
|
971
|
+
/* @__PURE__ */ jsx10("th", { className: "px-6 py-4 text-xs font-semibold text-on-surface-variant uppercase tracking-wider text-right", children: "Actions" })
|
|
822
972
|
] }) }),
|
|
823
|
-
/* @__PURE__ */
|
|
973
|
+
/* @__PURE__ */ jsx10("tbody", { className: "divide-y divide-outline-variant/5", children: sandboxes.map((sb) => {
|
|
824
974
|
const sc = statusColors[sb.status] ?? statusColors.stopped;
|
|
825
975
|
const isActive = sb.status === "running";
|
|
826
976
|
const isHibernating = sb.status === "hibernating";
|
|
977
|
+
const isStopped = sb.status === "stopped";
|
|
827
978
|
const isProvisioning = sb.status === "provisioning";
|
|
979
|
+
const isWakeable = isHibernating || isStopped;
|
|
828
980
|
return /* @__PURE__ */ jsxs9("tr", { className: "hover:bg-surface-container-highest/20 transition-colors group relative", children: [
|
|
829
|
-
/* @__PURE__ */
|
|
830
|
-
/* @__PURE__ */
|
|
831
|
-
/* @__PURE__ */
|
|
981
|
+
/* @__PURE__ */ jsx10("td", { className: "px-6 py-5 whitespace-nowrap", children: /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-2", children: [
|
|
982
|
+
/* @__PURE__ */ jsx10("span", { className: cn("flex h-2.5 w-2.5 rounded-full", sc.dot) }),
|
|
983
|
+
/* @__PURE__ */ jsx10("span", { className: cn("text-xs font-bold uppercase tracking-wide", sc.text), children: sb.status.charAt(0).toUpperCase() + sb.status.slice(1) })
|
|
832
984
|
] }) }),
|
|
833
|
-
/* @__PURE__ */
|
|
834
|
-
/* @__PURE__ */
|
|
835
|
-
sb.nodeId && /* @__PURE__ */
|
|
985
|
+
/* @__PURE__ */ jsx10("td", { className: "px-6 py-5", children: /* @__PURE__ */ jsxs9("div", { className: "flex flex-col", children: [
|
|
986
|
+
/* @__PURE__ */ jsx10("span", { className: "text-sm font-bold text-white group-hover:text-md3-primary transition-colors", children: sb.name }),
|
|
987
|
+
sb.nodeId && /* @__PURE__ */ jsx10("span", { className: "text-[10px] font-mono text-on-surface-variant", children: sb.nodeId })
|
|
836
988
|
] }) }),
|
|
837
|
-
/* @__PURE__ */
|
|
838
|
-
sb.imageIcon && /* @__PURE__ */
|
|
839
|
-
sb.image && /* @__PURE__ */
|
|
989
|
+
/* @__PURE__ */ jsx10("td", { className: "px-6 py-5", children: /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-3", children: [
|
|
990
|
+
sb.imageIcon && /* @__PURE__ */ jsx10("div", { className: "w-8 h-8 rounded-lg bg-surface-container-high flex items-center justify-center", children: sb.imageIcon }),
|
|
991
|
+
sb.image && /* @__PURE__ */ jsx10("span", { className: "text-xs font-bold text-white", children: sb.image })
|
|
840
992
|
] }) }),
|
|
841
|
-
/* @__PURE__ */
|
|
842
|
-
/* @__PURE__ */
|
|
843
|
-
/* @__PURE__ */
|
|
993
|
+
/* @__PURE__ */ jsx10("td", { className: "px-6 py-5", children: isActive ? /* @__PURE__ */ jsxs9("div", { className: "space-y-3 w-48", children: [
|
|
994
|
+
/* @__PURE__ */ jsx10(MiniMeter, { label: "CPU", percent: sb.cpuPercent ?? 0 }),
|
|
995
|
+
/* @__PURE__ */ jsx10(MiniMeter, { label: "RAM", percent: sb.ramTotal ? Math.round((sb.ramUsed ?? 0) / sb.ramTotal * 100) : 0 })
|
|
844
996
|
] }) : isProvisioning ? /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-2 text-md3-primary/80 italic text-[10px] font-bold", children: [
|
|
845
|
-
/* @__PURE__ */
|
|
997
|
+
/* @__PURE__ */ jsx10(MaterialIcon7, { name: "refresh", className: "text-[14px] animate-spin" }),
|
|
846
998
|
sb.provisioningMessage ?? "Allocating nodes..."
|
|
847
|
-
] }) : isHibernating ? /* @__PURE__ */ jsxs9("div", { className: "space-y-3 w-48 opacity-30", children: [
|
|
848
|
-
/* @__PURE__ */
|
|
849
|
-
/* @__PURE__ */
|
|
999
|
+
] }) : isHibernating || isStopped ? /* @__PURE__ */ jsxs9("div", { className: "space-y-3 w-48 opacity-30", children: [
|
|
1000
|
+
/* @__PURE__ */ jsx10(MiniMeter, { label: "CPU", percent: 0 }),
|
|
1001
|
+
/* @__PURE__ */ jsx10(MiniMeter, { label: "RAM", percent: 0 })
|
|
850
1002
|
] }) : null }),
|
|
851
|
-
/* @__PURE__ */
|
|
852
|
-
isActive && /* @__PURE__ */ jsxs9(
|
|
853
|
-
/* @__PURE__ */
|
|
854
|
-
/* @__PURE__ */
|
|
855
|
-
/* @__PURE__ */ jsx9("button", { type: "button", onClick: () => onSSH?.(sb.id), className: "p-2 rounded-lg hover:bg-surface-container-highest text-on-surface-variant hover:text-white transition-all active:scale-90", title: "SSH", children: /* @__PURE__ */ jsx9(MaterialIcon8, { name: "vpn_key", className: "text-[20px]" }) })
|
|
1003
|
+
/* @__PURE__ */ jsx10("td", { className: "px-6 py-5 text-right", children: /* @__PURE__ */ jsxs9("div", { className: "flex items-center justify-end gap-1", children: [
|
|
1004
|
+
isActive && /* @__PURE__ */ jsxs9(Fragment4, { children: [
|
|
1005
|
+
/* @__PURE__ */ jsx10("button", { type: "button", onClick: () => onOpenIDE?.(sb.id), className: "p-2 rounded-lg hover:bg-surface-container-highest text-on-surface-variant hover:text-white transition-all active:scale-90", title: "Open IDE", children: /* @__PURE__ */ jsx10(MaterialIcon7, { name: "code", className: "text-[20px]" }) }),
|
|
1006
|
+
/* @__PURE__ */ jsx10("button", { type: "button", onClick: () => onOpenTerminal?.(sb.id), className: "p-2 rounded-lg hover:bg-surface-container-highest text-on-surface-variant hover:text-white transition-all active:scale-90", title: "Terminal", children: /* @__PURE__ */ jsx10(MaterialIcon7, { name: "terminal", className: "text-[20px]" }) })
|
|
856
1007
|
] }),
|
|
857
|
-
|
|
858
|
-
|
|
1008
|
+
isWakeable && /* @__PURE__ */ jsx10("button", { type: "button", onClick: () => onWake?.(sb.id), className: "px-3 py-1.5 rounded-lg border border-md3-primary/30 text-md3-primary text-[10px] font-bold uppercase tracking-wider hover:bg-md3-primary/10 active:scale-95 transition-all", children: "Wake Up" }),
|
|
1009
|
+
(onSSH || handleDelete) && /* @__PURE__ */ jsxs9(DropdownMenu, { children: [
|
|
1010
|
+
/* @__PURE__ */ jsx10(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx10("button", { type: "button", className: "p-2 rounded-lg hover:bg-surface-container-highest text-on-surface-variant hover:text-white transition-all active:scale-90", children: /* @__PURE__ */ jsx10(MaterialIcon7, { name: "more_vert", className: "text-[20px]" }) }) }),
|
|
1011
|
+
/* @__PURE__ */ jsxs9(DropdownMenuContent, { align: "end", className: "min-w-[160px]", children: [
|
|
1012
|
+
isActive && onSSH && /* @__PURE__ */ jsxs9(DropdownMenuItem, { onClick: () => onSSH(sb.id), children: [
|
|
1013
|
+
/* @__PURE__ */ jsx10(MaterialIcon7, { name: "vpn_key", className: "text-base mr-2" }),
|
|
1014
|
+
"SSH Info"
|
|
1015
|
+
] }),
|
|
1016
|
+
isActive && onSSH && handleDelete && /* @__PURE__ */ jsx10(DropdownMenuSeparator, {}),
|
|
1017
|
+
handleDelete && /* @__PURE__ */ jsxs9(DropdownMenuItem, { onClick: () => handleDelete(sb.id), className: "text-red-400 focus:text-red-400", children: [
|
|
1018
|
+
/* @__PURE__ */ jsx10(MaterialIcon7, { name: "delete", className: "text-base mr-2" }),
|
|
1019
|
+
"Delete"
|
|
1020
|
+
] })
|
|
1021
|
+
] })
|
|
1022
|
+
] })
|
|
859
1023
|
] }) })
|
|
860
1024
|
] }, sb.id);
|
|
861
1025
|
}) })
|
|
@@ -869,8 +1033,8 @@ function SandboxTable({
|
|
|
869
1033
|
" active sandboxes"
|
|
870
1034
|
] }),
|
|
871
1035
|
/* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-2", children: [
|
|
872
|
-
/* @__PURE__ */
|
|
873
|
-
Array.from({ length: Math.min(totalPages, 5) }, (_, i) => i + 1).map((p) => /* @__PURE__ */
|
|
1036
|
+
/* @__PURE__ */ jsx10("button", { type: "button", onClick: () => onPageChange?.(page - 1), disabled: page <= 1, className: "p-2 rounded-lg border border-outline-variant/10 hover:bg-surface-container-high transition-colors disabled:opacity-30", children: /* @__PURE__ */ jsx10(MaterialIcon7, { name: "chevron_left", className: "text-[18px]" }) }),
|
|
1037
|
+
Array.from({ length: Math.min(totalPages, 5) }, (_, i) => i + 1).map((p) => /* @__PURE__ */ jsx10(
|
|
874
1038
|
"button",
|
|
875
1039
|
{
|
|
876
1040
|
type: "button",
|
|
@@ -883,14 +1047,14 @@ function SandboxTable({
|
|
|
883
1047
|
},
|
|
884
1048
|
p
|
|
885
1049
|
)),
|
|
886
|
-
/* @__PURE__ */
|
|
1050
|
+
/* @__PURE__ */ jsx10("button", { type: "button", onClick: () => onPageChange?.(page + 1), disabled: page >= totalPages, className: "p-2 rounded-lg border border-outline-variant/10 hover:bg-surface-container-high transition-colors disabled:opacity-30", children: /* @__PURE__ */ jsx10(MaterialIcon7, { name: "chevron_right", className: "text-[18px]" }) })
|
|
887
1051
|
] })
|
|
888
1052
|
] })
|
|
889
1053
|
] });
|
|
890
1054
|
}
|
|
891
1055
|
|
|
892
1056
|
// src/dashboard/backend-selector.tsx
|
|
893
|
-
import { jsx as
|
|
1057
|
+
import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
894
1058
|
function BackendSelector({
|
|
895
1059
|
backends,
|
|
896
1060
|
selected,
|
|
@@ -912,11 +1076,11 @@ function BackendSelector({
|
|
|
912
1076
|
return /* @__PURE__ */ jsxs10("div", { className, children: [
|
|
913
1077
|
/* @__PURE__ */ jsxs10("label", { className: "mb-2 block font-medium text-sm", children: [
|
|
914
1078
|
label,
|
|
915
|
-
multiSelect && /* @__PURE__ */
|
|
1079
|
+
multiSelect && /* @__PURE__ */ jsx11("span", { className: "ml-2 font-normal text-muted-foreground", children: "(select multiple to compare)" })
|
|
916
1080
|
] }),
|
|
917
|
-
/* @__PURE__ */
|
|
1081
|
+
/* @__PURE__ */ jsx11("div", { className: "flex flex-wrap gap-2", children: backends.map((backend) => {
|
|
918
1082
|
const isSelected = selected.includes(backend.type);
|
|
919
|
-
return /* @__PURE__ */
|
|
1083
|
+
return /* @__PURE__ */ jsx11(
|
|
920
1084
|
"button",
|
|
921
1085
|
{
|
|
922
1086
|
type: "button",
|
|
@@ -928,13 +1092,13 @@ function BackendSelector({
|
|
|
928
1092
|
backend.type
|
|
929
1093
|
);
|
|
930
1094
|
}) }),
|
|
931
|
-
multiSelect && selected.length > 1 && /* @__PURE__ */
|
|
1095
|
+
multiSelect && selected.length > 1 && /* @__PURE__ */ jsx11("p", { className: "mt-2 text-muted-foreground text-xs", children: hint || `Will run on ${selected.length} variants in parallel for comparison` })
|
|
932
1096
|
] });
|
|
933
1097
|
}
|
|
934
1098
|
|
|
935
1099
|
// src/dashboard/profile-selector.tsx
|
|
936
1100
|
import { Check, ChevronDown, Plus, Settings } from "lucide-react";
|
|
937
|
-
import { Fragment as
|
|
1101
|
+
import { Fragment as Fragment5, jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
938
1102
|
function ProfileSelector({
|
|
939
1103
|
profiles,
|
|
940
1104
|
selectedId,
|
|
@@ -950,11 +1114,11 @@ function ProfileSelector({
|
|
|
950
1114
|
const builtinProfiles = profiles.filter((p) => p.is_builtin);
|
|
951
1115
|
const customProfiles = profiles.filter((p) => !p.is_builtin);
|
|
952
1116
|
return /* @__PURE__ */ jsxs11("div", { className, children: [
|
|
953
|
-
label && /* @__PURE__ */
|
|
1117
|
+
label && /* @__PURE__ */ jsx12("label", { className: "mb-2 block font-medium text-sm", children: label }),
|
|
954
1118
|
/* @__PURE__ */ jsxs11(DropdownMenu, { children: [
|
|
955
|
-
/* @__PURE__ */
|
|
956
|
-
/* @__PURE__ */
|
|
957
|
-
/* @__PURE__ */
|
|
1119
|
+
/* @__PURE__ */ jsx12(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs11(Button, { variant: "outline", className: "w-full justify-between", children: [
|
|
1120
|
+
/* @__PURE__ */ jsx12("span", { className: "truncate", children: selected ? selected.name : placeholder }),
|
|
1121
|
+
/* @__PURE__ */ jsx12(ChevronDown, { className: "ml-2 h-4 w-4 shrink-0 opacity-50" })
|
|
958
1122
|
] }) }),
|
|
959
1123
|
/* @__PURE__ */ jsxs11(DropdownMenuContent, { className: "w-[300px]", align: "start", children: [
|
|
960
1124
|
/* @__PURE__ */ jsxs11(
|
|
@@ -963,14 +1127,14 @@ function ProfileSelector({
|
|
|
963
1127
|
onClick: () => onSelect(null),
|
|
964
1128
|
className: "flex items-center justify-between",
|
|
965
1129
|
children: [
|
|
966
|
-
/* @__PURE__ */
|
|
967
|
-
!selectedId && /* @__PURE__ */
|
|
1130
|
+
/* @__PURE__ */ jsx12("span", { children: placeholder }),
|
|
1131
|
+
!selectedId && /* @__PURE__ */ jsx12(Check, { className: "h-4 w-4 text-green-400" })
|
|
968
1132
|
]
|
|
969
1133
|
}
|
|
970
1134
|
),
|
|
971
|
-
builtinProfiles.length > 0 && /* @__PURE__ */ jsxs11(
|
|
972
|
-
/* @__PURE__ */
|
|
973
|
-
/* @__PURE__ */
|
|
1135
|
+
builtinProfiles.length > 0 && /* @__PURE__ */ jsxs11(Fragment5, { children: [
|
|
1136
|
+
/* @__PURE__ */ jsx12(DropdownMenuSeparator, {}),
|
|
1137
|
+
/* @__PURE__ */ jsx12(DropdownMenuLabel, { children: "Built-in Profiles" }),
|
|
974
1138
|
builtinProfiles.map((profile) => /* @__PURE__ */ jsxs11(
|
|
975
1139
|
DropdownMenuItem,
|
|
976
1140
|
{
|
|
@@ -979,23 +1143,23 @@ function ProfileSelector({
|
|
|
979
1143
|
children: [
|
|
980
1144
|
/* @__PURE__ */ jsxs11("div", { className: "flex w-full items-center justify-between", children: [
|
|
981
1145
|
/* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-2", children: [
|
|
982
|
-
/* @__PURE__ */
|
|
1146
|
+
/* @__PURE__ */ jsx12("span", { className: "font-medium", children: profile.name }),
|
|
983
1147
|
profile.extends && /* @__PURE__ */ jsxs11(Badge, { variant: "secondary", className: "border-0 text-xs", children: [
|
|
984
1148
|
"extends ",
|
|
985
1149
|
profile.extends
|
|
986
1150
|
] })
|
|
987
1151
|
] }),
|
|
988
|
-
selectedId === profile.id && /* @__PURE__ */
|
|
1152
|
+
selectedId === profile.id && /* @__PURE__ */ jsx12(Check, { className: "h-4 w-4 text-green-400" })
|
|
989
1153
|
] }),
|
|
990
|
-
profile.description && /* @__PURE__ */
|
|
1154
|
+
profile.description && /* @__PURE__ */ jsx12("span", { className: "line-clamp-1 text-muted-foreground text-xs", children: profile.description })
|
|
991
1155
|
]
|
|
992
1156
|
},
|
|
993
1157
|
profile.id
|
|
994
1158
|
))
|
|
995
1159
|
] }),
|
|
996
|
-
customProfiles.length > 0 && /* @__PURE__ */ jsxs11(
|
|
997
|
-
/* @__PURE__ */
|
|
998
|
-
/* @__PURE__ */
|
|
1160
|
+
customProfiles.length > 0 && /* @__PURE__ */ jsxs11(Fragment5, { children: [
|
|
1161
|
+
/* @__PURE__ */ jsx12(DropdownMenuSeparator, {}),
|
|
1162
|
+
/* @__PURE__ */ jsx12(DropdownMenuLabel, { children: "Custom Profiles" }),
|
|
999
1163
|
customProfiles.map((profile) => /* @__PURE__ */ jsxs11(
|
|
1000
1164
|
DropdownMenuItem,
|
|
1001
1165
|
{
|
|
@@ -1004,12 +1168,12 @@ function ProfileSelector({
|
|
|
1004
1168
|
children: [
|
|
1005
1169
|
/* @__PURE__ */ jsxs11("div", { className: "flex w-full items-center justify-between", children: [
|
|
1006
1170
|
/* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-2", children: [
|
|
1007
|
-
/* @__PURE__ */
|
|
1008
|
-
profile.model && /* @__PURE__ */
|
|
1171
|
+
/* @__PURE__ */ jsx12("span", { className: "font-medium", children: profile.name }),
|
|
1172
|
+
profile.model && /* @__PURE__ */ jsx12(Badge, { variant: "secondary", className: "border-0 text-xs", children: profile.model.split("/").pop() })
|
|
1009
1173
|
] }),
|
|
1010
|
-
selectedId === profile.id && /* @__PURE__ */
|
|
1174
|
+
selectedId === profile.id && /* @__PURE__ */ jsx12(Check, { className: "h-4 w-4 text-green-400" })
|
|
1011
1175
|
] }),
|
|
1012
|
-
profile.description && /* @__PURE__ */
|
|
1176
|
+
profile.description && /* @__PURE__ */ jsx12("span", { className: "line-clamp-1 text-muted-foreground text-xs", children: profile.description }),
|
|
1013
1177
|
showMetrics && profile.metrics && profile.metrics.total_runs > 0 && /* @__PURE__ */ jsxs11("div", { className: "flex gap-3 text-muted-foreground text-xs", children: [
|
|
1014
1178
|
/* @__PURE__ */ jsxs11("span", { children: [
|
|
1015
1179
|
profile.metrics.total_runs,
|
|
@@ -1030,15 +1194,15 @@ function ProfileSelector({
|
|
|
1030
1194
|
profile.id
|
|
1031
1195
|
))
|
|
1032
1196
|
] }),
|
|
1033
|
-
(onCreateClick || onManageClick) && /* @__PURE__ */ jsxs11(
|
|
1034
|
-
/* @__PURE__ */
|
|
1197
|
+
(onCreateClick || onManageClick) && /* @__PURE__ */ jsxs11(Fragment5, { children: [
|
|
1198
|
+
/* @__PURE__ */ jsx12(DropdownMenuSeparator, {}),
|
|
1035
1199
|
onCreateClick && /* @__PURE__ */ jsxs11(
|
|
1036
1200
|
DropdownMenuItem,
|
|
1037
1201
|
{
|
|
1038
1202
|
onClick: onCreateClick,
|
|
1039
1203
|
className: "text-blue-400",
|
|
1040
1204
|
children: [
|
|
1041
|
-
/* @__PURE__ */
|
|
1205
|
+
/* @__PURE__ */ jsx12(Plus, { className: "mr-2 h-4 w-4" }),
|
|
1042
1206
|
"Create New Profile"
|
|
1043
1207
|
]
|
|
1044
1208
|
}
|
|
@@ -1049,7 +1213,7 @@ function ProfileSelector({
|
|
|
1049
1213
|
onClick: onManageClick,
|
|
1050
1214
|
className: "text-muted-foreground",
|
|
1051
1215
|
children: [
|
|
1052
|
-
/* @__PURE__ */
|
|
1216
|
+
/* @__PURE__ */ jsx12(Settings, { className: "mr-2 h-4 w-4" }),
|
|
1053
1217
|
"Manage Profiles"
|
|
1054
1218
|
]
|
|
1055
1219
|
}
|
|
@@ -1076,8 +1240,8 @@ function ProfileComparison({
|
|
|
1076
1240
|
(best, p) => (p.metrics?.avg_duration_ms ?? Number.POSITIVE_INFINITY) < (best.metrics?.avg_duration_ms ?? Number.POSITIVE_INFINITY) ? p : best
|
|
1077
1241
|
);
|
|
1078
1242
|
return /* @__PURE__ */ jsxs11("div", { className: `rounded-lg border border-border p-4 ${className ?? ""}`, children: [
|
|
1079
|
-
/* @__PURE__ */
|
|
1080
|
-
/* @__PURE__ */
|
|
1243
|
+
/* @__PURE__ */ jsx12("h4", { className: "mb-3 font-medium text-sm", children: "Profile Performance" }),
|
|
1244
|
+
/* @__PURE__ */ jsx12("div", { className: "space-y-3", children: profilesWithMetrics.map((profile) => {
|
|
1081
1245
|
const isBestSuccess = profile.id === bestSuccess.id;
|
|
1082
1246
|
const isFastest = profile.id === fastestProfile.id;
|
|
1083
1247
|
return /* @__PURE__ */ jsxs11(
|
|
@@ -1086,13 +1250,13 @@ function ProfileComparison({
|
|
|
1086
1250
|
className: "flex items-center justify-between gap-4",
|
|
1087
1251
|
children: [
|
|
1088
1252
|
/* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-2", children: [
|
|
1089
|
-
/* @__PURE__ */
|
|
1090
|
-
isBestSuccess && /* @__PURE__ */
|
|
1091
|
-
isFastest && !isBestSuccess && /* @__PURE__ */
|
|
1253
|
+
/* @__PURE__ */ jsx12("span", { className: "font-medium", children: profile.name }),
|
|
1254
|
+
isBestSuccess && /* @__PURE__ */ jsx12(Badge, { className: "border-0 bg-green-500/10 text-green-400 text-xs", children: "Best Success" }),
|
|
1255
|
+
isFastest && !isBestSuccess && /* @__PURE__ */ jsx12(Badge, { className: "border-0 bg-blue-500/10 text-blue-400 text-xs", children: "Fastest" })
|
|
1092
1256
|
] }),
|
|
1093
1257
|
/* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-4 text-sm", children: [
|
|
1094
1258
|
/* @__PURE__ */ jsxs11("span", { children: [
|
|
1095
|
-
/* @__PURE__ */
|
|
1259
|
+
/* @__PURE__ */ jsx12("span", { className: "text-muted-foreground", children: "Success:" }),
|
|
1096
1260
|
" ",
|
|
1097
1261
|
/* @__PURE__ */ jsxs11(
|
|
1098
1262
|
"span",
|
|
@@ -1106,7 +1270,7 @@ function ProfileComparison({
|
|
|
1106
1270
|
)
|
|
1107
1271
|
] }),
|
|
1108
1272
|
/* @__PURE__ */ jsxs11("span", { children: [
|
|
1109
|
-
/* @__PURE__ */
|
|
1273
|
+
/* @__PURE__ */ jsx12("span", { className: "text-muted-foreground", children: "Avg:" }),
|
|
1110
1274
|
" ",
|
|
1111
1275
|
((profile.metrics?.avg_duration_ms ?? 0) / 1e3).toFixed(1),
|
|
1112
1276
|
"s"
|
|
@@ -1135,7 +1299,7 @@ import {
|
|
|
1135
1299
|
X,
|
|
1136
1300
|
XCircle
|
|
1137
1301
|
} from "lucide-react";
|
|
1138
|
-
import { jsx as
|
|
1302
|
+
import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
1139
1303
|
var statusConfig2 = {
|
|
1140
1304
|
pending: {
|
|
1141
1305
|
icon: Clock,
|
|
@@ -1209,7 +1373,7 @@ function VariantList({
|
|
|
1209
1373
|
isActioning,
|
|
1210
1374
|
className
|
|
1211
1375
|
}) {
|
|
1212
|
-
return /* @__PURE__ */
|
|
1376
|
+
return /* @__PURE__ */ jsx13("div", { className: `space-y-3 ${className || ""}`, children: variants.map((variant) => {
|
|
1213
1377
|
const status = statusConfig2[variant.status];
|
|
1214
1378
|
const StatusIcon = status.icon;
|
|
1215
1379
|
const isSelected = variant.id === selectedId;
|
|
@@ -1222,7 +1386,7 @@ function VariantList({
|
|
|
1222
1386
|
/* @__PURE__ */ jsxs12("div", { className: "flex items-center justify-between", children: [
|
|
1223
1387
|
/* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-3", children: [
|
|
1224
1388
|
/* @__PURE__ */ jsxs12(Badge, { className: `${status.bg} ${status.color} border-0`, children: [
|
|
1225
|
-
/* @__PURE__ */
|
|
1389
|
+
/* @__PURE__ */ jsx13(
|
|
1226
1390
|
StatusIcon,
|
|
1227
1391
|
{
|
|
1228
1392
|
className: `mr-1 h-3 w-3 ${status.animate ? "animate-spin" : ""}`
|
|
@@ -1230,20 +1394,20 @@ function VariantList({
|
|
|
1230
1394
|
),
|
|
1231
1395
|
status.label
|
|
1232
1396
|
] }),
|
|
1233
|
-
/* @__PURE__ */
|
|
1397
|
+
/* @__PURE__ */ jsx13("span", { className: "font-medium", children: variant.label }),
|
|
1234
1398
|
variant.sublabel && /* @__PURE__ */ jsxs12("span", { className: "text-muted-foreground text-sm", children: [
|
|
1235
1399
|
"(",
|
|
1236
1400
|
variant.sublabel,
|
|
1237
1401
|
")"
|
|
1238
1402
|
] }),
|
|
1239
1403
|
variant.durationMs && /* @__PURE__ */ jsxs12("span", { className: "flex items-center gap-1 text-muted-foreground text-sm", children: [
|
|
1240
|
-
/* @__PURE__ */
|
|
1404
|
+
/* @__PURE__ */ jsx13(Timer, { className: "h-3 w-3" }),
|
|
1241
1405
|
(variant.durationMs / 1e3).toFixed(2),
|
|
1242
1406
|
"s"
|
|
1243
1407
|
] })
|
|
1244
1408
|
] }),
|
|
1245
1409
|
/* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-2", children: [
|
|
1246
|
-
variant.outcome && /* @__PURE__ */
|
|
1410
|
+
variant.outcome && /* @__PURE__ */ jsx13(
|
|
1247
1411
|
Badge,
|
|
1248
1412
|
{
|
|
1249
1413
|
className: `${outcomeConfig[variant.outcome].bg} ${outcomeConfig[variant.outcome].color} border-0`,
|
|
@@ -1263,7 +1427,7 @@ function VariantList({
|
|
|
1263
1427
|
},
|
|
1264
1428
|
disabled: isActioning === variant.id,
|
|
1265
1429
|
children: [
|
|
1266
|
-
/* @__PURE__ */
|
|
1430
|
+
/* @__PURE__ */ jsx13(Check2, { className: "mr-1 h-4 w-4" }),
|
|
1267
1431
|
"Accept"
|
|
1268
1432
|
]
|
|
1269
1433
|
}
|
|
@@ -1280,13 +1444,13 @@ function VariantList({
|
|
|
1280
1444
|
},
|
|
1281
1445
|
disabled: isActioning === variant.id,
|
|
1282
1446
|
children: [
|
|
1283
|
-
/* @__PURE__ */
|
|
1447
|
+
/* @__PURE__ */ jsx13(X, { className: "mr-1 h-4 w-4" }),
|
|
1284
1448
|
"Reject"
|
|
1285
1449
|
]
|
|
1286
1450
|
}
|
|
1287
1451
|
)
|
|
1288
1452
|
] }),
|
|
1289
|
-
variant.detailsUrl && /* @__PURE__ */
|
|
1453
|
+
variant.detailsUrl && /* @__PURE__ */ jsx13(
|
|
1290
1454
|
Button,
|
|
1291
1455
|
{
|
|
1292
1456
|
variant: "ghost",
|
|
@@ -1296,13 +1460,13 @@ function VariantList({
|
|
|
1296
1460
|
e.stopPropagation();
|
|
1297
1461
|
window.open(variant.detailsUrl, "_blank");
|
|
1298
1462
|
},
|
|
1299
|
-
children: /* @__PURE__ */
|
|
1463
|
+
children: /* @__PURE__ */ jsx13(ExternalLink, { className: "h-4 w-4" })
|
|
1300
1464
|
}
|
|
1301
1465
|
)
|
|
1302
1466
|
] })
|
|
1303
1467
|
] }),
|
|
1304
|
-
variant.error && /* @__PURE__ */
|
|
1305
|
-
variant.summary && /* @__PURE__ */
|
|
1468
|
+
variant.error && /* @__PURE__ */ jsx13("p", { className: "mt-2 text-red-400 text-sm", children: variant.error }),
|
|
1469
|
+
variant.summary && /* @__PURE__ */ jsx13("p", { className: "mt-2 line-clamp-2 text-muted-foreground text-sm", children: variant.summary })
|
|
1306
1470
|
]
|
|
1307
1471
|
},
|
|
1308
1472
|
variant.id
|
|
@@ -1311,7 +1475,24 @@ function VariantList({
|
|
|
1311
1475
|
}
|
|
1312
1476
|
|
|
1313
1477
|
export {
|
|
1314
|
-
|
|
1478
|
+
SIDEBAR_RAIL_WIDTH,
|
|
1479
|
+
SIDEBAR_PANEL_WIDTH,
|
|
1480
|
+
SIDEBAR_TOTAL_WIDTH,
|
|
1481
|
+
SidebarProvider,
|
|
1482
|
+
useSidebar,
|
|
1483
|
+
Sidebar,
|
|
1484
|
+
SidebarRail,
|
|
1485
|
+
SidebarRailHeader,
|
|
1486
|
+
SidebarRailNav,
|
|
1487
|
+
SidebarRailFooter,
|
|
1488
|
+
RailSeparator,
|
|
1489
|
+
RailButton,
|
|
1490
|
+
RailModeButton,
|
|
1491
|
+
SidebarPanel,
|
|
1492
|
+
SidebarPanelHeader,
|
|
1493
|
+
SidebarPanelContent,
|
|
1494
|
+
SidebarContent,
|
|
1495
|
+
ProfileAvatar,
|
|
1315
1496
|
ClusterStatusBar,
|
|
1316
1497
|
CreditBalance,
|
|
1317
1498
|
InvoiceTable,
|