@tangle-network/sandbox-ui 0.3.5 → 0.3.6
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.
|
@@ -173,9 +173,163 @@ function ClusterStatusBar({ items, latency, className }) {
|
|
|
173
173
|
);
|
|
174
174
|
}
|
|
175
175
|
|
|
176
|
-
// src/dashboard/
|
|
176
|
+
// src/dashboard/credit-balance.tsx
|
|
177
177
|
import * as React from "react";
|
|
178
|
-
import {
|
|
178
|
+
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
179
|
+
function CreditBalance({
|
|
180
|
+
amount,
|
|
181
|
+
description = "Credits are automatically deducted based on hourly Sandbox usage and Agent operations.",
|
|
182
|
+
onTopUp,
|
|
183
|
+
quickAmounts = [10, 25, 100],
|
|
184
|
+
className
|
|
185
|
+
}) {
|
|
186
|
+
const [topUpValue, setTopUpValue] = React.useState("50.00");
|
|
187
|
+
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
|
+
/* @__PURE__ */ jsxs3("div", { children: [
|
|
189
|
+
/* @__PURE__ */ jsx3("h3", { className: "text-lg font-bold text-white tracking-tight mb-1", children: "Available Credits" }),
|
|
190
|
+
/* @__PURE__ */ jsxs3("div", { className: "text-5xl font-extrabold text-md3-primary tracking-tighter mb-4", children: [
|
|
191
|
+
"$",
|
|
192
|
+
amount.toFixed(2)
|
|
193
|
+
] }),
|
|
194
|
+
/* @__PURE__ */ jsx3("p", { className: "text-sm text-on-surface-variant leading-relaxed", children: description })
|
|
195
|
+
] }),
|
|
196
|
+
onTopUp && /* @__PURE__ */ jsxs3("div", { className: "space-y-4 mt-8", children: [
|
|
197
|
+
/* @__PURE__ */ jsxs3("div", { className: "bg-surface-container-lowest p-1 rounded-lg flex items-center", children: [
|
|
198
|
+
/* @__PURE__ */ jsx3(
|
|
199
|
+
"input",
|
|
200
|
+
{
|
|
201
|
+
type: "text",
|
|
202
|
+
value: `$${topUpValue}`,
|
|
203
|
+
onChange: (e) => setTopUpValue(e.target.value.replace(/[^0-9.]/g, "")),
|
|
204
|
+
className: "bg-transparent border-none text-white font-mono text-lg w-full focus:ring-0 px-4"
|
|
205
|
+
}
|
|
206
|
+
),
|
|
207
|
+
/* @__PURE__ */ jsx3(
|
|
208
|
+
"button",
|
|
209
|
+
{
|
|
210
|
+
type: "button",
|
|
211
|
+
onClick: () => onTopUp(Number.parseFloat(topUpValue)),
|
|
212
|
+
className: "bg-md3-primary text-on-primary px-6 py-3 rounded-md font-bold text-xs uppercase tracking-widest active:scale-95 transition-transform",
|
|
213
|
+
children: "Top Up"
|
|
214
|
+
}
|
|
215
|
+
)
|
|
216
|
+
] }),
|
|
217
|
+
/* @__PURE__ */ jsx3("div", { className: "flex justify-between gap-2", children: quickAmounts.map((qa) => /* @__PURE__ */ jsxs3(
|
|
218
|
+
"button",
|
|
219
|
+
{
|
|
220
|
+
type: "button",
|
|
221
|
+
onClick: () => {
|
|
222
|
+
setTopUpValue(String(qa));
|
|
223
|
+
onTopUp(qa);
|
|
224
|
+
},
|
|
225
|
+
className: "flex-1 py-2 text-[10px] font-mono text-on-surface-variant border border-outline-variant/30 rounded-md hover:bg-surface-variant transition-colors uppercase",
|
|
226
|
+
children: [
|
|
227
|
+
"+$",
|
|
228
|
+
qa
|
|
229
|
+
]
|
|
230
|
+
},
|
|
231
|
+
qa
|
|
232
|
+
)) })
|
|
233
|
+
] })
|
|
234
|
+
] });
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// src/dashboard/invoice-table.tsx
|
|
238
|
+
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
239
|
+
function MaterialIcon3({ name, className }) {
|
|
240
|
+
return /* @__PURE__ */ jsx4("span", { className: cn("material-symbols-outlined", className), style: { fontVariationSettings: "'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24" }, children: name });
|
|
241
|
+
}
|
|
242
|
+
var statusStyle = {
|
|
243
|
+
paid: "bg-md3-primary/10 text-md3-primary",
|
|
244
|
+
pending: "bg-yellow-500/10 text-yellow-400",
|
|
245
|
+
failed: "bg-red-500/10 text-red-400"
|
|
246
|
+
};
|
|
247
|
+
function InvoiceTable({ invoices, onExportAll, onLoadMore, onViewInvoice, hasMore, className }) {
|
|
248
|
+
return /* @__PURE__ */ jsxs4("section", { className, children: [
|
|
249
|
+
/* @__PURE__ */ jsxs4("div", { className: "flex justify-between items-center mb-6 px-2", children: [
|
|
250
|
+
/* @__PURE__ */ jsx4("h2", { className: "text-2xl font-bold text-white tracking-tight", children: "Invoice History" }),
|
|
251
|
+
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__ */ jsx4(MaterialIcon3, { name: "download", className: "text-sm" }),
|
|
253
|
+
"Export All"
|
|
254
|
+
] })
|
|
255
|
+
] }),
|
|
256
|
+
/* @__PURE__ */ jsx4("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: [
|
|
257
|
+
/* @__PURE__ */ jsx4("thead", { children: /* @__PURE__ */ jsxs4("tr", { className: "bg-surface-container-high", children: [
|
|
258
|
+
/* @__PURE__ */ jsx4("th", { className: "px-6 py-4 font-mono text-[10px] text-on-surface-variant uppercase tracking-widest", children: "Invoice ID" }),
|
|
259
|
+
/* @__PURE__ */ jsx4("th", { className: "px-6 py-4 font-mono text-[10px] text-on-surface-variant uppercase tracking-widest", children: "Date" }),
|
|
260
|
+
/* @__PURE__ */ jsx4("th", { className: "px-6 py-4 font-mono text-[10px] text-on-surface-variant uppercase tracking-widest", children: "Amount" }),
|
|
261
|
+
/* @__PURE__ */ jsx4("th", { className: "px-6 py-4 font-mono text-[10px] text-on-surface-variant uppercase tracking-widest", children: "Status" }),
|
|
262
|
+
/* @__PURE__ */ jsx4("th", { className: "px-6 py-4 font-mono text-[10px] text-on-surface-variant uppercase tracking-widest text-right", children: "Action" })
|
|
263
|
+
] }) }),
|
|
264
|
+
/* @__PURE__ */ jsx4("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: [
|
|
265
|
+
/* @__PURE__ */ jsx4("td", { className: "px-6 py-5 font-mono text-xs text-white", children: inv.id }),
|
|
266
|
+
/* @__PURE__ */ jsx4("td", { className: "px-6 py-5 text-sm text-on-surface-variant", children: inv.date }),
|
|
267
|
+
/* @__PURE__ */ jsxs4("td", { className: "px-6 py-5 text-sm font-bold text-white", children: [
|
|
268
|
+
"$",
|
|
269
|
+
inv.amount.toFixed(2)
|
|
270
|
+
] }),
|
|
271
|
+
/* @__PURE__ */ jsx4("td", { className: "px-6 py-5", children: /* @__PURE__ */ jsx4("span", { className: cn("px-2 py-1 text-[10px] font-mono rounded uppercase", statusStyle[inv.status] ?? statusStyle.paid), children: inv.status }) }),
|
|
272
|
+
/* @__PURE__ */ jsx4("td", { className: "px-6 py-5 text-right", children: /* @__PURE__ */ jsx4("button", { type: "button", onClick: () => onViewInvoice?.(inv.id), className: "text-on-surface-variant hover:text-white transition-colors", children: /* @__PURE__ */ jsx4(MaterialIcon3, { name: "description" }) }) })
|
|
273
|
+
] }, inv.id)) })
|
|
274
|
+
] }) }),
|
|
275
|
+
hasMore && onLoadMore && /* @__PURE__ */ jsx4("div", { className: "mt-6 flex justify-center", children: /* @__PURE__ */ jsx4("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
|
+
] });
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// src/dashboard/plan-cards.tsx
|
|
280
|
+
import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
281
|
+
function MaterialIcon4({ name, className }) {
|
|
282
|
+
return /* @__PURE__ */ jsx5("span", { className: cn("material-symbols-outlined", className), style: { fontVariationSettings: "'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24" }, children: name });
|
|
283
|
+
}
|
|
284
|
+
function PlanCards({ plans, className }) {
|
|
285
|
+
return /* @__PURE__ */ jsxs5("section", { className, children: [
|
|
286
|
+
/* @__PURE__ */ jsx5("h2", { className: "text-2xl font-bold text-white tracking-tight mb-8 px-2", children: "Subscription Plans" }),
|
|
287
|
+
/* @__PURE__ */ jsx5("div", { className: "grid grid-cols-1 md:grid-cols-3 gap-6", children: plans.map((plan) => /* @__PURE__ */ jsxs5(
|
|
288
|
+
"div",
|
|
289
|
+
{
|
|
290
|
+
className: cn(
|
|
291
|
+
"p-8 rounded-xl transition-all",
|
|
292
|
+
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
|
+
),
|
|
294
|
+
children: [
|
|
295
|
+
plan.popular && /* @__PURE__ */ jsx5("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
|
+
/* @__PURE__ */ jsxs5("div", { className: "mb-6", children: [
|
|
297
|
+
/* @__PURE__ */ jsx5("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
|
+
/* @__PURE__ */ jsxs5("div", { className: "text-3xl font-bold text-white", children: [
|
|
299
|
+
"$",
|
|
300
|
+
plan.price,
|
|
301
|
+
/* @__PURE__ */ jsxs5("span", { className: "text-sm font-normal text-on-surface-variant tracking-normal", children: [
|
|
302
|
+
"/",
|
|
303
|
+
plan.period ?? "mo"
|
|
304
|
+
] })
|
|
305
|
+
] })
|
|
306
|
+
] }),
|
|
307
|
+
/* @__PURE__ */ jsx5("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: [
|
|
308
|
+
/* @__PURE__ */ jsx5(MaterialIcon4, { name: "check", className: "text-sm text-md3-primary" }),
|
|
309
|
+
f.text
|
|
310
|
+
] }, i)) }),
|
|
311
|
+
/* @__PURE__ */ jsx5(
|
|
312
|
+
"button",
|
|
313
|
+
{
|
|
314
|
+
type: "button",
|
|
315
|
+
onClick: () => plan.onSelect?.(plan.id),
|
|
316
|
+
className: cn(
|
|
317
|
+
"w-full py-3 rounded-lg text-xs font-bold uppercase tracking-widest transition-all",
|
|
318
|
+
plan.current ? "border border-outline-variant/40 text-on-surface-variant hover:border-md3-primary" : plan.popular ? "bg-gradient-to-r from-md3-primary to-primary-container text-on-primary shadow-lg shadow-md3-primary/20 active:scale-95 transition-transform" : "border border-outline-variant/40 text-on-surface-variant hover:border-md3-primary"
|
|
319
|
+
),
|
|
320
|
+
children: plan.ctaLabel ?? (plan.current ? "Current Plan" : "Upgrade Now")
|
|
321
|
+
}
|
|
322
|
+
)
|
|
323
|
+
]
|
|
324
|
+
},
|
|
325
|
+
plan.id
|
|
326
|
+
)) })
|
|
327
|
+
] });
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// src/dashboard/dashboard-layout.tsx
|
|
331
|
+
import * as React2 from "react";
|
|
332
|
+
import { Fragment as Fragment2, jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
179
333
|
var variantStyles = {
|
|
180
334
|
sandbox: {
|
|
181
335
|
activeNav: "bg-[var(--accent-surface-soft)] text-[var(--accent-text)]",
|
|
@@ -189,32 +343,32 @@ function DefaultLink2({
|
|
|
189
343
|
children,
|
|
190
344
|
...rest
|
|
191
345
|
}) {
|
|
192
|
-
return /* @__PURE__ */
|
|
346
|
+
return /* @__PURE__ */ jsx6("a", { href: href ?? to, className, ...rest, children });
|
|
193
347
|
}
|
|
194
348
|
function UserIcon({ className }) {
|
|
195
|
-
return /* @__PURE__ */
|
|
196
|
-
/* @__PURE__ */
|
|
197
|
-
/* @__PURE__ */
|
|
198
|
-
/* @__PURE__ */
|
|
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" })
|
|
199
353
|
] });
|
|
200
354
|
}
|
|
201
355
|
function SettingsIcon({ className }) {
|
|
202
|
-
return /* @__PURE__ */
|
|
203
|
-
/* @__PURE__ */
|
|
204
|
-
/* @__PURE__ */
|
|
205
|
-
/* @__PURE__ */
|
|
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" })
|
|
206
360
|
] });
|
|
207
361
|
}
|
|
208
362
|
function LogOutIcon({ className }) {
|
|
209
|
-
return /* @__PURE__ */
|
|
210
|
-
/* @__PURE__ */
|
|
211
|
-
/* @__PURE__ */
|
|
212
|
-
/* @__PURE__ */
|
|
213
|
-
/* @__PURE__ */
|
|
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" })
|
|
214
368
|
] });
|
|
215
369
|
}
|
|
216
|
-
function
|
|
217
|
-
return /* @__PURE__ */
|
|
370
|
+
function MaterialIcon5({ name, className }) {
|
|
371
|
+
return /* @__PURE__ */ jsx6(
|
|
218
372
|
"span",
|
|
219
373
|
{
|
|
220
374
|
className: cn("material-symbols-outlined", className),
|
|
@@ -224,18 +378,18 @@ function MaterialIcon3({ name, className }) {
|
|
|
224
378
|
);
|
|
225
379
|
}
|
|
226
380
|
function MenuIcon({ className }) {
|
|
227
|
-
return /* @__PURE__ */
|
|
228
|
-
/* @__PURE__ */
|
|
229
|
-
/* @__PURE__ */
|
|
230
|
-
/* @__PURE__ */
|
|
231
|
-
/* @__PURE__ */
|
|
381
|
+
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__ */ jsx6("title", { children: "Menu icon" }),
|
|
383
|
+
/* @__PURE__ */ jsx6("line", { x1: "4", x2: "20", y1: "12", y2: "12" }),
|
|
384
|
+
/* @__PURE__ */ jsx6("line", { x1: "4", x2: "20", y1: "6", y2: "6" }),
|
|
385
|
+
/* @__PURE__ */ jsx6("line", { x1: "4", x2: "20", y1: "18", y2: "18" })
|
|
232
386
|
] });
|
|
233
387
|
}
|
|
234
388
|
function XIcon({ className }) {
|
|
235
|
-
return /* @__PURE__ */
|
|
236
|
-
/* @__PURE__ */
|
|
237
|
-
/* @__PURE__ */
|
|
238
|
-
/* @__PURE__ */
|
|
389
|
+
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__ */ jsx6("title", { children: "Close icon" }),
|
|
391
|
+
/* @__PURE__ */ jsx6("path", { d: "M18 6 6 18" }),
|
|
392
|
+
/* @__PURE__ */ jsx6("path", { d: "m6 6 12 12" })
|
|
239
393
|
] });
|
|
240
394
|
}
|
|
241
395
|
function DashboardLayout({
|
|
@@ -261,21 +415,21 @@ function DashboardLayout({
|
|
|
261
415
|
}) {
|
|
262
416
|
const styles = variantStyles[variant];
|
|
263
417
|
const Link = LinkComponent;
|
|
264
|
-
const [mobileMenuOpen, setMobileMenuOpen] =
|
|
418
|
+
const [mobileMenuOpen, setMobileMenuOpen] = React2.useState(false);
|
|
265
419
|
const handleNavClick = () => {
|
|
266
420
|
setMobileMenuOpen(false);
|
|
267
421
|
};
|
|
268
|
-
const SidebarContent = () => /* @__PURE__ */
|
|
269
|
-
/* @__PURE__ */
|
|
270
|
-
/* @__PURE__ */
|
|
271
|
-
/* @__PURE__ */
|
|
272
|
-
/* @__PURE__ */
|
|
273
|
-
sandboxLabel && /* @__PURE__ */
|
|
274
|
-
] }) : /* @__PURE__ */
|
|
422
|
+
const SidebarContent = () => /* @__PURE__ */ jsxs6(Fragment2, { children: [
|
|
423
|
+
/* @__PURE__ */ jsx6("div", { className: "px-6 mb-8", children: /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-3 p-3 rounded-xl bg-surface-container-low", children: [
|
|
424
|
+
/* @__PURE__ */ jsx6("div", { className: "w-10 h-10 rounded-lg bg-primary-container flex items-center justify-center", children: /* @__PURE__ */ jsx6(MaterialIcon5, { name: "terminal", className: "text-on-primary-container text-sm" }) }),
|
|
425
|
+
/* @__PURE__ */ jsx6("div", { className: "min-w-0", children: sandboxName ? /* @__PURE__ */ jsxs6(Fragment2, { children: [
|
|
426
|
+
/* @__PURE__ */ jsx6("div", { className: "font-mono text-xs text-white font-bold tracking-tight truncate", children: sandboxName }),
|
|
427
|
+
sandboxLabel && /* @__PURE__ */ jsx6("div", { className: "font-mono text-[10px] text-slate-500 truncate", children: sandboxLabel })
|
|
428
|
+
] }) : /* @__PURE__ */ jsx6("div", { className: "font-mono text-xs text-slate-500", children: "No sandbox selected" }) })
|
|
275
429
|
] }) }),
|
|
276
|
-
/* @__PURE__ */
|
|
430
|
+
/* @__PURE__ */ jsx6("nav", { className: "flex-1 px-4 space-y-1", "aria-label": "Main navigation", children: navItems.map((item) => {
|
|
277
431
|
const isActive = activeNavId === item.id;
|
|
278
|
-
return /* @__PURE__ */
|
|
432
|
+
return /* @__PURE__ */ jsxs6(
|
|
279
433
|
Link,
|
|
280
434
|
{
|
|
281
435
|
href: item.href,
|
|
@@ -287,57 +441,57 @@ function DashboardLayout({
|
|
|
287
441
|
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"
|
|
288
442
|
),
|
|
289
443
|
children: [
|
|
290
|
-
item.materialIcon ? /* @__PURE__ */
|
|
291
|
-
/* @__PURE__ */
|
|
444
|
+
item.materialIcon ? /* @__PURE__ */ jsx6(MaterialIcon5, { name: item.materialIcon, className: "text-lg" }) : /* @__PURE__ */ jsx6(item.icon, { className: "h-5 w-5", "aria-hidden": "true" }),
|
|
445
|
+
/* @__PURE__ */ jsx6("span", { children: item.label })
|
|
292
446
|
]
|
|
293
447
|
},
|
|
294
448
|
item.id
|
|
295
449
|
);
|
|
296
450
|
}) }),
|
|
297
|
-
/* @__PURE__ */
|
|
298
|
-
/* @__PURE__ */
|
|
451
|
+
/* @__PURE__ */ jsxs6("div", { className: "px-4 py-4 mt-auto space-y-1 border-t border-outline-variant/10", children: [
|
|
452
|
+
/* @__PURE__ */ jsxs6(
|
|
299
453
|
"button",
|
|
300
454
|
{
|
|
301
455
|
type: "button",
|
|
302
456
|
onClick: onNewSandbox,
|
|
303
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",
|
|
304
458
|
children: [
|
|
305
|
-
/* @__PURE__ */
|
|
459
|
+
/* @__PURE__ */ jsx6(MaterialIcon5, { name: "add", className: "text-sm" }),
|
|
306
460
|
"New Agent"
|
|
307
461
|
]
|
|
308
462
|
}
|
|
309
463
|
),
|
|
310
|
-
/* @__PURE__ */
|
|
464
|
+
/* @__PURE__ */ jsxs6(
|
|
311
465
|
Link,
|
|
312
466
|
{
|
|
313
467
|
href: "/docs",
|
|
314
468
|
to: "/docs",
|
|
315
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",
|
|
316
470
|
children: [
|
|
317
|
-
/* @__PURE__ */
|
|
471
|
+
/* @__PURE__ */ jsx6(MaterialIcon5, { name: "menu_book", className: "text-sm" }),
|
|
318
472
|
"Documentation"
|
|
319
473
|
]
|
|
320
474
|
}
|
|
321
475
|
),
|
|
322
|
-
/* @__PURE__ */
|
|
476
|
+
/* @__PURE__ */ jsxs6(
|
|
323
477
|
Link,
|
|
324
478
|
{
|
|
325
479
|
href: "/support",
|
|
326
480
|
to: "/support",
|
|
327
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",
|
|
328
482
|
children: [
|
|
329
|
-
/* @__PURE__ */
|
|
483
|
+
/* @__PURE__ */ jsx6(MaterialIcon5, { name: "contact_support", className: "text-sm" }),
|
|
330
484
|
"Support"
|
|
331
485
|
]
|
|
332
486
|
}
|
|
333
487
|
)
|
|
334
488
|
] })
|
|
335
489
|
] });
|
|
336
|
-
return /* @__PURE__ */
|
|
337
|
-
/* @__PURE__ */
|
|
338
|
-
/* @__PURE__ */
|
|
339
|
-
/* @__PURE__ */
|
|
340
|
-
topNavLinks && topNavLinks.length > 0 && /* @__PURE__ */
|
|
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(
|
|
341
495
|
Link,
|
|
342
496
|
{
|
|
343
497
|
href: link.href,
|
|
@@ -351,47 +505,47 @@ function DashboardLayout({
|
|
|
351
505
|
link.href
|
|
352
506
|
)) })
|
|
353
507
|
] }),
|
|
354
|
-
/* @__PURE__ */
|
|
355
|
-
onNewSandbox && /* @__PURE__ */
|
|
508
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-4", children: [
|
|
509
|
+
onNewSandbox && /* @__PURE__ */ jsxs6(
|
|
356
510
|
"button",
|
|
357
511
|
{
|
|
358
512
|
type: "button",
|
|
359
513
|
onClick: onNewSandbox,
|
|
360
514
|
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",
|
|
361
515
|
children: [
|
|
362
|
-
/* @__PURE__ */
|
|
516
|
+
/* @__PURE__ */ jsx6(MaterialIcon5, { name: "add", className: "text-sm" }),
|
|
363
517
|
"New Sandbox"
|
|
364
518
|
]
|
|
365
519
|
}
|
|
366
520
|
),
|
|
367
|
-
/* @__PURE__ */
|
|
368
|
-
onSettingsClick ? /* @__PURE__ */
|
|
369
|
-
/* @__PURE__ */
|
|
370
|
-
/* @__PURE__ */
|
|
371
|
-
/* @__PURE__ */
|
|
372
|
-
/* @__PURE__ */
|
|
373
|
-
/* @__PURE__ */
|
|
374
|
-
/* @__PURE__ */
|
|
521
|
+
/* @__PURE__ */ jsx6("button", { type: "button", className: "text-slate-400 hover:text-violet-400 transition-colors p-2 rounded-lg hover:bg-white/5", children: /* @__PURE__ */ jsx6(MaterialIcon5, { name: "notifications" }) }),
|
|
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: [
|
|
375
529
|
user?.tier ?? "Free",
|
|
376
530
|
" Plan"
|
|
377
531
|
] })
|
|
378
532
|
] }) }),
|
|
379
|
-
/* @__PURE__ */
|
|
380
|
-
onSettingsClick ? /* @__PURE__ */
|
|
381
|
-
/* @__PURE__ */
|
|
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" }),
|
|
382
536
|
"Settings"
|
|
383
|
-
] }) : /* @__PURE__ */
|
|
384
|
-
/* @__PURE__ */
|
|
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" }),
|
|
385
539
|
"Settings"
|
|
386
540
|
] }) }),
|
|
387
|
-
onLogout && /* @__PURE__ */
|
|
388
|
-
/* @__PURE__ */
|
|
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" }),
|
|
389
543
|
"Sign Out"
|
|
390
544
|
] })
|
|
391
545
|
] })
|
|
392
546
|
] })
|
|
393
547
|
] }),
|
|
394
|
-
/* @__PURE__ */
|
|
548
|
+
/* @__PURE__ */ jsx6(
|
|
395
549
|
"button",
|
|
396
550
|
{
|
|
397
551
|
type: "button",
|
|
@@ -399,12 +553,12 @@ function DashboardLayout({
|
|
|
399
553
|
className: "rounded-md p-2 hover:bg-white/5 md:hidden",
|
|
400
554
|
"aria-label": mobileMenuOpen ? "Close menu" : "Open menu",
|
|
401
555
|
"aria-expanded": mobileMenuOpen,
|
|
402
|
-
children: mobileMenuOpen ? /* @__PURE__ */
|
|
556
|
+
children: mobileMenuOpen ? /* @__PURE__ */ jsx6(XIcon, { className: "h-6 w-6" }) : /* @__PURE__ */ jsx6(MenuIcon, { className: "h-6 w-6" })
|
|
403
557
|
}
|
|
404
558
|
)
|
|
405
559
|
] }),
|
|
406
|
-
mobileMenuOpen && /* @__PURE__ */
|
|
407
|
-
/* @__PURE__ */
|
|
560
|
+
mobileMenuOpen && /* @__PURE__ */ jsx6("div", { className: "fixed inset-0 z-30 bg-black/50 md:hidden", onClick: () => setMobileMenuOpen(false), "aria-hidden": "true" }),
|
|
561
|
+
/* @__PURE__ */ jsx6(
|
|
408
562
|
"aside",
|
|
409
563
|
{
|
|
410
564
|
className: cn(
|
|
@@ -412,47 +566,47 @@ function DashboardLayout({
|
|
|
412
566
|
sidebarClassName,
|
|
413
567
|
mobileMenuOpen ? "translate-x-0" : "-translate-x-full"
|
|
414
568
|
),
|
|
415
|
-
children: /* @__PURE__ */
|
|
569
|
+
children: /* @__PURE__ */ jsx6(SidebarContent, {})
|
|
416
570
|
}
|
|
417
571
|
),
|
|
418
|
-
/* @__PURE__ */
|
|
572
|
+
/* @__PURE__ */ jsx6(
|
|
419
573
|
"aside",
|
|
420
574
|
{
|
|
421
575
|
className: cn(
|
|
422
576
|
"hidden lg:flex h-screen w-64 fixed left-0 top-0 flex-col py-6 bg-slate-800/40 z-40 pt-20",
|
|
423
577
|
sidebarClassName
|
|
424
578
|
),
|
|
425
|
-
children: /* @__PURE__ */
|
|
579
|
+
children: /* @__PURE__ */ jsx6(SidebarContent, {})
|
|
426
580
|
}
|
|
427
581
|
),
|
|
428
|
-
/* @__PURE__ */
|
|
582
|
+
/* @__PURE__ */ jsx6("main", { className: cn("lg:ml-64 pt-24 px-8 pb-12 min-h-screen", contentClassName), children }),
|
|
429
583
|
footer
|
|
430
584
|
] });
|
|
431
585
|
}
|
|
432
586
|
|
|
433
587
|
// src/dashboard/resource-meter.tsx
|
|
434
|
-
import { jsx as
|
|
588
|
+
import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
435
589
|
function getColorByUsage(percent) {
|
|
436
590
|
if (percent >= 90) return "from-red-500 to-red-300";
|
|
437
591
|
if (percent >= 70) return "from-yellow-500 to-yellow-300";
|
|
438
592
|
if (percent >= 40) return "from-blue-500 to-blue-300";
|
|
439
593
|
return "from-green-500 to-green-300";
|
|
440
594
|
}
|
|
441
|
-
function
|
|
442
|
-
return /* @__PURE__ */
|
|
595
|
+
function MaterialIcon6({ name, className }) {
|
|
596
|
+
return /* @__PURE__ */ jsx7("span", { className: cn("material-symbols-outlined", className), style: { fontVariationSettings: "'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24" }, children: name });
|
|
443
597
|
}
|
|
444
598
|
function ResourceMeter({ label, value, max = 100, unit, icon, className }) {
|
|
445
599
|
const percent = max > 0 ? Math.min(value / max * 100, 100) : 0;
|
|
446
600
|
const gradient = getColorByUsage(percent);
|
|
447
|
-
return /* @__PURE__ */
|
|
448
|
-
/* @__PURE__ */
|
|
449
|
-
/* @__PURE__ */
|
|
450
|
-
icon && /* @__PURE__ */
|
|
601
|
+
return /* @__PURE__ */ jsxs7("div", { className: cn("space-y-2", className), children: [
|
|
602
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex justify-between text-[11px] font-bold font-mono text-on-surface uppercase tracking-tight", children: [
|
|
603
|
+
/* @__PURE__ */ jsxs7("span", { className: "flex items-center gap-1", children: [
|
|
604
|
+
icon && /* @__PURE__ */ jsx7(MaterialIcon6, { name: icon, className: "text-xs" }),
|
|
451
605
|
label
|
|
452
606
|
] }),
|
|
453
|
-
/* @__PURE__ */
|
|
607
|
+
/* @__PURE__ */ jsx7("span", { className: "text-primary-fixed-dim", children: unit ? `${value}${unit} / ${max}${unit}` : `${Math.round(percent)}%` })
|
|
454
608
|
] }),
|
|
455
|
-
/* @__PURE__ */
|
|
609
|
+
/* @__PURE__ */ jsx7("div", { className: "h-2 w-full bg-surface-container-highest rounded-full overflow-hidden", children: /* @__PURE__ */ jsx7(
|
|
456
610
|
"div",
|
|
457
611
|
{
|
|
458
612
|
className: cn("h-full bg-gradient-to-r rounded-full transition-all duration-500", gradient),
|
|
@@ -463,9 +617,9 @@ function ResourceMeter({ label, value, max = 100, unit, icon, className }) {
|
|
|
463
617
|
}
|
|
464
618
|
|
|
465
619
|
// src/dashboard/sandbox-card.tsx
|
|
466
|
-
import { jsx as
|
|
467
|
-
function
|
|
468
|
-
return /* @__PURE__ */
|
|
620
|
+
import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
621
|
+
function MaterialIcon7({ name, className }) {
|
|
622
|
+
return /* @__PURE__ */ jsx8("span", { className: cn("material-symbols-outlined", className), style: { fontVariationSettings: "'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24" }, children: name });
|
|
469
623
|
}
|
|
470
624
|
var statusConfig = {
|
|
471
625
|
running: { color: "text-green-400", bgColor: "bg-green-500/10", borderColor: "border-green-500/20", dotClass: "bg-green-400 animate-pulse", label: "Running" },
|
|
@@ -495,7 +649,7 @@ function SandboxCard({ sandbox, onOpenIDE, onOpenTerminal, onWake, onRestore, cl
|
|
|
495
649
|
const isHibernating = sandbox.status === "hibernating";
|
|
496
650
|
const isProvisioning = sandbox.status === "provisioning";
|
|
497
651
|
const isArchived = sandbox.status === "archived";
|
|
498
|
-
return /* @__PURE__ */
|
|
652
|
+
return /* @__PURE__ */ jsxs8(
|
|
499
653
|
"div",
|
|
500
654
|
{
|
|
501
655
|
className: cn(
|
|
@@ -505,29 +659,29 @@ function SandboxCard({ sandbox, onOpenIDE, onOpenTerminal, onWake, onRestore, cl
|
|
|
505
659
|
className
|
|
506
660
|
),
|
|
507
661
|
children: [
|
|
508
|
-
/* @__PURE__ */
|
|
509
|
-
/* @__PURE__ */
|
|
662
|
+
/* @__PURE__ */ jsx8("div", { className: "absolute top-0 right-0 p-4", children: /* @__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: [
|
|
663
|
+
/* @__PURE__ */ jsx8("span", { className: cn("w-2 h-2 rounded-full", status.dotClass) }),
|
|
510
664
|
status.label
|
|
511
665
|
] }) }),
|
|
512
|
-
/* @__PURE__ */
|
|
513
|
-
sandbox.imageIcon && /* @__PURE__ */
|
|
514
|
-
/* @__PURE__ */
|
|
515
|
-
/* @__PURE__ */
|
|
516
|
-
sandbox.nodeId && /* @__PURE__ */
|
|
666
|
+
/* @__PURE__ */ jsx8("div", { className: "mb-6", children: /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-3 mb-2", children: [
|
|
667
|
+
sandbox.imageIcon && /* @__PURE__ */ jsx8("div", { className: "w-10 h-10 rounded-lg flex items-center justify-center bg-surface-container-high", children: sandbox.imageIcon }),
|
|
668
|
+
/* @__PURE__ */ jsxs8("div", { className: "min-w-0", children: [
|
|
669
|
+
/* @__PURE__ */ jsx8("h3", { className: "text-xl font-bold text-white group-hover:text-md3-primary transition-colors truncate", children: sandbox.name }),
|
|
670
|
+
sandbox.nodeId && /* @__PURE__ */ jsx8("p", { className: "text-on-surface-variant font-mono text-xs truncate", children: sandbox.nodeId })
|
|
517
671
|
] })
|
|
518
672
|
] }) }),
|
|
519
|
-
isProvisioning ? /* @__PURE__ */
|
|
520
|
-
/* @__PURE__ */
|
|
521
|
-
/* @__PURE__ */
|
|
673
|
+
isProvisioning ? /* @__PURE__ */ jsxs8("div", { className: "mb-8 mt-10", children: [
|
|
674
|
+
/* @__PURE__ */ jsx8("p", { className: "text-[10px] font-bold font-mono text-orange-400 mb-3 uppercase text-center animate-pulse tracking-widest", children: sandbox.provisioningMessage ?? "Initializing..." }),
|
|
675
|
+
/* @__PURE__ */ jsx8("div", { className: "h-2 w-full bg-surface-container-highest rounded-full overflow-hidden", children: /* @__PURE__ */ jsx8(
|
|
522
676
|
"div",
|
|
523
677
|
{
|
|
524
678
|
className: "h-full bg-gradient-to-r from-orange-600 via-orange-400 to-orange-300 transition-all duration-500",
|
|
525
679
|
style: { width: `${sandbox.provisioningPercent ?? 50}%` }
|
|
526
680
|
}
|
|
527
681
|
) })
|
|
528
|
-
] }) : !isArchived ? /* @__PURE__ */
|
|
529
|
-
/* @__PURE__ */
|
|
530
|
-
/* @__PURE__ */
|
|
682
|
+
] }) : !isArchived ? /* @__PURE__ */ jsxs8("div", { className: cn("space-y-5 mb-8", !isActive && "opacity-40"), children: [
|
|
683
|
+
/* @__PURE__ */ jsx8(ResourceMeter, { label: "CPU Usage", icon: "memory", value: sandbox.cpuPercent ?? 0 }),
|
|
684
|
+
/* @__PURE__ */ jsx8(
|
|
531
685
|
ResourceMeter,
|
|
532
686
|
{
|
|
533
687
|
label: "RAM Usage",
|
|
@@ -537,46 +691,46 @@ function SandboxCard({ sandbox, onOpenIDE, onOpenTerminal, onWake, onRestore, cl
|
|
|
537
691
|
unit: "GB"
|
|
538
692
|
}
|
|
539
693
|
)
|
|
540
|
-
] }) : /* @__PURE__ */
|
|
541
|
-
isActive && /* @__PURE__ */
|
|
542
|
-
/* @__PURE__ */
|
|
694
|
+
] }) : /* @__PURE__ */ jsx8("div", { className: "mb-6", children: sandbox.archivedAt && /* @__PURE__ */ jsx8("p", { className: "text-slate-500 font-mono text-[10px]", children: sandbox.archivedAt }) }),
|
|
695
|
+
isActive && /* @__PURE__ */ jsxs8("div", { className: "grid grid-cols-2 gap-3", children: [
|
|
696
|
+
/* @__PURE__ */ jsxs8(
|
|
543
697
|
"button",
|
|
544
698
|
{
|
|
545
699
|
type: "button",
|
|
546
700
|
onClick: () => onOpenIDE?.(sandbox.id),
|
|
547
701
|
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",
|
|
548
702
|
children: [
|
|
549
|
-
/* @__PURE__ */
|
|
703
|
+
/* @__PURE__ */ jsx8(MaterialIcon7, { name: "open_in_new", className: "text-sm" }),
|
|
550
704
|
"Open IDE"
|
|
551
705
|
]
|
|
552
706
|
}
|
|
553
707
|
),
|
|
554
|
-
/* @__PURE__ */
|
|
708
|
+
/* @__PURE__ */ jsxs8(
|
|
555
709
|
"button",
|
|
556
710
|
{
|
|
557
711
|
type: "button",
|
|
558
712
|
onClick: () => onOpenTerminal?.(sandbox.id),
|
|
559
713
|
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",
|
|
560
714
|
children: [
|
|
561
|
-
/* @__PURE__ */
|
|
715
|
+
/* @__PURE__ */ jsx8(MaterialIcon7, { name: "terminal", className: "text-sm" }),
|
|
562
716
|
"Terminal"
|
|
563
717
|
]
|
|
564
718
|
}
|
|
565
719
|
)
|
|
566
720
|
] }),
|
|
567
|
-
isHibernating && /* @__PURE__ */
|
|
721
|
+
isHibernating && /* @__PURE__ */ jsxs8(
|
|
568
722
|
"button",
|
|
569
723
|
{
|
|
570
724
|
type: "button",
|
|
571
725
|
onClick: () => onWake?.(sandbox.id),
|
|
572
726
|
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",
|
|
573
727
|
children: [
|
|
574
|
-
/* @__PURE__ */
|
|
728
|
+
/* @__PURE__ */ jsx8(MaterialIcon7, { name: "power_settings_new", className: "text-sm" }),
|
|
575
729
|
"Wake Sandbox"
|
|
576
730
|
]
|
|
577
731
|
}
|
|
578
732
|
),
|
|
579
|
-
isProvisioning && /* @__PURE__ */
|
|
733
|
+
isProvisioning && /* @__PURE__ */ jsx8(
|
|
580
734
|
"button",
|
|
581
735
|
{
|
|
582
736
|
type: "button",
|
|
@@ -585,7 +739,7 @@ function SandboxCard({ sandbox, onOpenIDE, onOpenTerminal, onWake, onRestore, cl
|
|
|
585
739
|
children: "Please Wait..."
|
|
586
740
|
}
|
|
587
741
|
),
|
|
588
|
-
isArchived && /* @__PURE__ */
|
|
742
|
+
isArchived && /* @__PURE__ */ jsx8(
|
|
589
743
|
"button",
|
|
590
744
|
{
|
|
591
745
|
type: "button",
|
|
@@ -599,7 +753,7 @@ function SandboxCard({ sandbox, onOpenIDE, onOpenTerminal, onWake, onRestore, cl
|
|
|
599
753
|
);
|
|
600
754
|
}
|
|
601
755
|
function NewSandboxCard({ onClick, className }) {
|
|
602
|
-
return /* @__PURE__ */
|
|
756
|
+
return /* @__PURE__ */ jsxs8(
|
|
603
757
|
"button",
|
|
604
758
|
{
|
|
605
759
|
type: "button",
|
|
@@ -609,18 +763,18 @@ function NewSandboxCard({ onClick, className }) {
|
|
|
609
763
|
className
|
|
610
764
|
),
|
|
611
765
|
children: [
|
|
612
|
-
/* @__PURE__ */
|
|
613
|
-
/* @__PURE__ */
|
|
614
|
-
/* @__PURE__ */
|
|
766
|
+
/* @__PURE__ */ jsx8("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__ */ jsx8(MaterialIcon7, { name: "add_box", className: "text-3xl" }) }),
|
|
767
|
+
/* @__PURE__ */ jsx8("h4", { className: "font-bold text-slate-400 group-hover:text-white mb-1", children: "New Environment" }),
|
|
768
|
+
/* @__PURE__ */ jsx8("p", { className: "text-xs text-slate-600", children: "Instantiate a fresh compute node" })
|
|
615
769
|
]
|
|
616
770
|
}
|
|
617
771
|
);
|
|
618
772
|
}
|
|
619
773
|
|
|
620
774
|
// src/dashboard/sandbox-table.tsx
|
|
621
|
-
import { Fragment as Fragment3, jsx as
|
|
622
|
-
function
|
|
623
|
-
return /* @__PURE__ */
|
|
775
|
+
import { Fragment as Fragment3, jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
776
|
+
function MaterialIcon8({ name, className }) {
|
|
777
|
+
return /* @__PURE__ */ jsx9("span", { className: cn("material-symbols-outlined", className), style: { fontVariationSettings: "'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24" }, children: name });
|
|
624
778
|
}
|
|
625
779
|
var statusColors = {
|
|
626
780
|
running: { dot: "bg-green-400 animate-pulse", text: "text-green-400", bar: "bg-green-400" },
|
|
@@ -631,15 +785,15 @@ var statusColors = {
|
|
|
631
785
|
archived: { dot: "bg-slate-600", text: "text-slate-500", bar: "bg-slate-600" }
|
|
632
786
|
};
|
|
633
787
|
function MiniMeter({ label, percent, className }) {
|
|
634
|
-
return /* @__PURE__ */
|
|
635
|
-
/* @__PURE__ */
|
|
636
|
-
/* @__PURE__ */
|
|
637
|
-
/* @__PURE__ */
|
|
788
|
+
return /* @__PURE__ */ jsxs9("div", { className: cn("space-y-1", className), children: [
|
|
789
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex justify-between text-[10px] font-mono text-on-surface-variant", children: [
|
|
790
|
+
/* @__PURE__ */ jsx9("span", { className: "font-bold", children: label }),
|
|
791
|
+
/* @__PURE__ */ jsxs9("span", { className: "text-primary-fixed", children: [
|
|
638
792
|
percent,
|
|
639
793
|
"%"
|
|
640
794
|
] })
|
|
641
795
|
] }),
|
|
642
|
-
/* @__PURE__ */
|
|
796
|
+
/* @__PURE__ */ jsx9("div", { className: "h-1.5 w-full bg-surface-container-highest rounded-full overflow-hidden", children: /* @__PURE__ */ jsx9("div", { className: "h-full bg-md3-primary rounded-full", style: { width: `${percent}%` } }) })
|
|
643
797
|
] });
|
|
644
798
|
}
|
|
645
799
|
function SandboxTable({
|
|
@@ -657,66 +811,66 @@ function SandboxTable({
|
|
|
657
811
|
}) {
|
|
658
812
|
const totalCount = total ?? sandboxes.length;
|
|
659
813
|
const totalPages = Math.ceil(totalCount / pageSize);
|
|
660
|
-
return /* @__PURE__ */
|
|
661
|
-
/* @__PURE__ */
|
|
662
|
-
/* @__PURE__ */
|
|
663
|
-
/* @__PURE__ */
|
|
664
|
-
/* @__PURE__ */
|
|
665
|
-
/* @__PURE__ */
|
|
666
|
-
/* @__PURE__ */
|
|
667
|
-
/* @__PURE__ */
|
|
814
|
+
return /* @__PURE__ */ jsxs9("div", { className: cn("w-full", className), children: [
|
|
815
|
+
/* @__PURE__ */ jsx9("div", { className: "w-full bg-surface-container-low rounded-2xl overflow-hidden shadow-2xl border border-outline-variant/10", children: /* @__PURE__ */ jsx9("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsxs9("table", { className: "w-full text-left border-collapse", children: [
|
|
816
|
+
/* @__PURE__ */ jsx9("thead", { children: /* @__PURE__ */ jsxs9("tr", { className: "bg-surface-container-high/50 border-b border-outline-variant/10", children: [
|
|
817
|
+
/* @__PURE__ */ jsx9("th", { className: "px-6 py-4 text-xs font-semibold text-on-surface-variant uppercase tracking-wider", children: "Status" }),
|
|
818
|
+
/* @__PURE__ */ jsx9("th", { className: "px-6 py-4 text-xs font-semibold text-on-surface-variant uppercase tracking-wider", children: "Sandbox Name" }),
|
|
819
|
+
/* @__PURE__ */ jsx9("th", { className: "px-6 py-4 text-xs font-semibold text-on-surface-variant uppercase tracking-wider", children: "Environment" }),
|
|
820
|
+
/* @__PURE__ */ jsx9("th", { className: "px-6 py-4 text-xs font-semibold text-on-surface-variant uppercase tracking-wider", children: "Resources" }),
|
|
821
|
+
/* @__PURE__ */ jsx9("th", { className: "px-6 py-4 text-xs font-semibold text-on-surface-variant uppercase tracking-wider text-right", children: "Actions" })
|
|
668
822
|
] }) }),
|
|
669
|
-
/* @__PURE__ */
|
|
823
|
+
/* @__PURE__ */ jsx9("tbody", { className: "divide-y divide-outline-variant/5", children: sandboxes.map((sb) => {
|
|
670
824
|
const sc = statusColors[sb.status] ?? statusColors.stopped;
|
|
671
825
|
const isActive = sb.status === "running";
|
|
672
826
|
const isHibernating = sb.status === "hibernating";
|
|
673
827
|
const isProvisioning = sb.status === "provisioning";
|
|
674
|
-
return /* @__PURE__ */
|
|
675
|
-
/* @__PURE__ */
|
|
676
|
-
/* @__PURE__ */
|
|
677
|
-
/* @__PURE__ */
|
|
828
|
+
return /* @__PURE__ */ jsxs9("tr", { className: "hover:bg-surface-container-highest/20 transition-colors group relative", children: [
|
|
829
|
+
/* @__PURE__ */ jsx9("td", { className: "px-6 py-5 whitespace-nowrap", children: /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-2", children: [
|
|
830
|
+
/* @__PURE__ */ jsx9("span", { className: cn("flex h-2.5 w-2.5 rounded-full", sc.dot) }),
|
|
831
|
+
/* @__PURE__ */ jsx9("span", { className: cn("text-xs font-bold uppercase tracking-wide", sc.text), children: sb.status.charAt(0).toUpperCase() + sb.status.slice(1) })
|
|
678
832
|
] }) }),
|
|
679
|
-
/* @__PURE__ */
|
|
680
|
-
/* @__PURE__ */
|
|
681
|
-
sb.nodeId && /* @__PURE__ */
|
|
833
|
+
/* @__PURE__ */ jsx9("td", { className: "px-6 py-5", children: /* @__PURE__ */ jsxs9("div", { className: "flex flex-col", children: [
|
|
834
|
+
/* @__PURE__ */ jsx9("span", { className: "text-sm font-bold text-white group-hover:text-md3-primary transition-colors", children: sb.name }),
|
|
835
|
+
sb.nodeId && /* @__PURE__ */ jsx9("span", { className: "text-[10px] font-mono text-on-surface-variant", children: sb.nodeId })
|
|
682
836
|
] }) }),
|
|
683
|
-
/* @__PURE__ */
|
|
684
|
-
sb.imageIcon && /* @__PURE__ */
|
|
685
|
-
sb.image && /* @__PURE__ */
|
|
837
|
+
/* @__PURE__ */ jsx9("td", { className: "px-6 py-5", children: /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-3", children: [
|
|
838
|
+
sb.imageIcon && /* @__PURE__ */ jsx9("div", { className: "w-8 h-8 rounded-lg bg-surface-container-high flex items-center justify-center", children: sb.imageIcon }),
|
|
839
|
+
sb.image && /* @__PURE__ */ jsx9("span", { className: "text-xs font-bold text-white", children: sb.image })
|
|
686
840
|
] }) }),
|
|
687
|
-
/* @__PURE__ */
|
|
688
|
-
/* @__PURE__ */
|
|
689
|
-
/* @__PURE__ */
|
|
690
|
-
] }) : isProvisioning ? /* @__PURE__ */
|
|
691
|
-
/* @__PURE__ */
|
|
841
|
+
/* @__PURE__ */ jsx9("td", { className: "px-6 py-5", children: isActive ? /* @__PURE__ */ jsxs9("div", { className: "space-y-3 w-48", children: [
|
|
842
|
+
/* @__PURE__ */ jsx9(MiniMeter, { label: "CPU", percent: sb.cpuPercent ?? 0 }),
|
|
843
|
+
/* @__PURE__ */ jsx9(MiniMeter, { label: "RAM", percent: sb.ramTotal ? Math.round((sb.ramUsed ?? 0) / sb.ramTotal * 100) : 0 })
|
|
844
|
+
] }) : isProvisioning ? /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-2 text-md3-primary/80 italic text-[10px] font-bold", children: [
|
|
845
|
+
/* @__PURE__ */ jsx9(MaterialIcon8, { name: "refresh", className: "text-[14px] animate-spin" }),
|
|
692
846
|
sb.provisioningMessage ?? "Allocating nodes..."
|
|
693
|
-
] }) : isHibernating ? /* @__PURE__ */
|
|
694
|
-
/* @__PURE__ */
|
|
695
|
-
/* @__PURE__ */
|
|
847
|
+
] }) : isHibernating ? /* @__PURE__ */ jsxs9("div", { className: "space-y-3 w-48 opacity-30", children: [
|
|
848
|
+
/* @__PURE__ */ jsx9(MiniMeter, { label: "CPU", percent: 0 }),
|
|
849
|
+
/* @__PURE__ */ jsx9(MiniMeter, { label: "RAM", percent: 0 })
|
|
696
850
|
] }) : null }),
|
|
697
|
-
/* @__PURE__ */
|
|
698
|
-
isActive && /* @__PURE__ */
|
|
699
|
-
/* @__PURE__ */
|
|
700
|
-
/* @__PURE__ */
|
|
701
|
-
/* @__PURE__ */
|
|
851
|
+
/* @__PURE__ */ jsx9("td", { className: "px-6 py-5 text-right", children: /* @__PURE__ */ jsxs9("div", { className: "flex items-center justify-end gap-1", children: [
|
|
852
|
+
isActive && /* @__PURE__ */ jsxs9(Fragment3, { children: [
|
|
853
|
+
/* @__PURE__ */ jsx9("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__ */ jsx9(MaterialIcon8, { name: "terminal", className: "text-[20px]" }) }),
|
|
854
|
+
/* @__PURE__ */ jsx9("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__ */ jsx9(MaterialIcon8, { name: "tab", className: "text-[20px]" }) }),
|
|
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]" }) })
|
|
702
856
|
] }),
|
|
703
|
-
isHibernating && /* @__PURE__ */
|
|
704
|
-
/* @__PURE__ */
|
|
857
|
+
isHibernating && /* @__PURE__ */ jsx9("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" }),
|
|
858
|
+
/* @__PURE__ */ jsx9("button", { type: "button", onClick: () => onMore?.(sb.id), className: "p-2 rounded-lg hover:bg-surface-container-highest text-on-surface-variant hover:text-white transition-all active:scale-90", children: /* @__PURE__ */ jsx9(MaterialIcon8, { name: "more_vert", className: "text-[20px]" }) })
|
|
705
859
|
] }) })
|
|
706
860
|
] }, sb.id);
|
|
707
861
|
}) })
|
|
708
862
|
] }) }) }),
|
|
709
|
-
totalPages > 1 && /* @__PURE__ */
|
|
710
|
-
/* @__PURE__ */
|
|
863
|
+
totalPages > 1 && /* @__PURE__ */ jsxs9("div", { className: "mt-6 flex flex-col md:flex-row justify-between items-center text-on-surface-variant text-xs font-medium gap-4", children: [
|
|
864
|
+
/* @__PURE__ */ jsxs9("p", { children: [
|
|
711
865
|
"Showing ",
|
|
712
866
|
sandboxes.length,
|
|
713
867
|
" of ",
|
|
714
868
|
totalCount,
|
|
715
869
|
" active sandboxes"
|
|
716
870
|
] }),
|
|
717
|
-
/* @__PURE__ */
|
|
718
|
-
/* @__PURE__ */
|
|
719
|
-
Array.from({ length: Math.min(totalPages, 5) }, (_, i) => i + 1).map((p) => /* @__PURE__ */
|
|
871
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-2", children: [
|
|
872
|
+
/* @__PURE__ */ jsx9("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__ */ jsx9(MaterialIcon8, { name: "chevron_left", className: "text-[18px]" }) }),
|
|
873
|
+
Array.from({ length: Math.min(totalPages, 5) }, (_, i) => i + 1).map((p) => /* @__PURE__ */ jsx9(
|
|
720
874
|
"button",
|
|
721
875
|
{
|
|
722
876
|
type: "button",
|
|
@@ -729,14 +883,14 @@ function SandboxTable({
|
|
|
729
883
|
},
|
|
730
884
|
p
|
|
731
885
|
)),
|
|
732
|
-
/* @__PURE__ */
|
|
886
|
+
/* @__PURE__ */ jsx9("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__ */ jsx9(MaterialIcon8, { name: "chevron_right", className: "text-[18px]" }) })
|
|
733
887
|
] })
|
|
734
888
|
] })
|
|
735
889
|
] });
|
|
736
890
|
}
|
|
737
891
|
|
|
738
892
|
// src/dashboard/backend-selector.tsx
|
|
739
|
-
import { jsx as
|
|
893
|
+
import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
740
894
|
function BackendSelector({
|
|
741
895
|
backends,
|
|
742
896
|
selected,
|
|
@@ -755,14 +909,14 @@ function BackendSelector({
|
|
|
755
909
|
onChange([type]);
|
|
756
910
|
}
|
|
757
911
|
};
|
|
758
|
-
return /* @__PURE__ */
|
|
759
|
-
/* @__PURE__ */
|
|
912
|
+
return /* @__PURE__ */ jsxs10("div", { className, children: [
|
|
913
|
+
/* @__PURE__ */ jsxs10("label", { className: "mb-2 block font-medium text-sm", children: [
|
|
760
914
|
label,
|
|
761
|
-
multiSelect && /* @__PURE__ */
|
|
915
|
+
multiSelect && /* @__PURE__ */ jsx10("span", { className: "ml-2 font-normal text-muted-foreground", children: "(select multiple to compare)" })
|
|
762
916
|
] }),
|
|
763
|
-
/* @__PURE__ */
|
|
917
|
+
/* @__PURE__ */ jsx10("div", { className: "flex flex-wrap gap-2", children: backends.map((backend) => {
|
|
764
918
|
const isSelected = selected.includes(backend.type);
|
|
765
|
-
return /* @__PURE__ */
|
|
919
|
+
return /* @__PURE__ */ jsx10(
|
|
766
920
|
"button",
|
|
767
921
|
{
|
|
768
922
|
type: "button",
|
|
@@ -774,13 +928,13 @@ function BackendSelector({
|
|
|
774
928
|
backend.type
|
|
775
929
|
);
|
|
776
930
|
}) }),
|
|
777
|
-
multiSelect && selected.length > 1 && /* @__PURE__ */
|
|
931
|
+
multiSelect && selected.length > 1 && /* @__PURE__ */ jsx10("p", { className: "mt-2 text-muted-foreground text-xs", children: hint || `Will run on ${selected.length} variants in parallel for comparison` })
|
|
778
932
|
] });
|
|
779
933
|
}
|
|
780
934
|
|
|
781
935
|
// src/dashboard/profile-selector.tsx
|
|
782
936
|
import { Check, ChevronDown, Plus, Settings } from "lucide-react";
|
|
783
|
-
import { Fragment as Fragment4, jsx as
|
|
937
|
+
import { Fragment as Fragment4, jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
784
938
|
function ProfileSelector({
|
|
785
939
|
profiles,
|
|
786
940
|
selectedId,
|
|
@@ -795,77 +949,77 @@ function ProfileSelector({
|
|
|
795
949
|
const selected = profiles.find((p) => p.id === selectedId);
|
|
796
950
|
const builtinProfiles = profiles.filter((p) => p.is_builtin);
|
|
797
951
|
const customProfiles = profiles.filter((p) => !p.is_builtin);
|
|
798
|
-
return /* @__PURE__ */
|
|
799
|
-
label && /* @__PURE__ */
|
|
800
|
-
/* @__PURE__ */
|
|
801
|
-
/* @__PURE__ */
|
|
802
|
-
/* @__PURE__ */
|
|
803
|
-
/* @__PURE__ */
|
|
952
|
+
return /* @__PURE__ */ jsxs11("div", { className, children: [
|
|
953
|
+
label && /* @__PURE__ */ jsx11("label", { className: "mb-2 block font-medium text-sm", children: label }),
|
|
954
|
+
/* @__PURE__ */ jsxs11(DropdownMenu, { children: [
|
|
955
|
+
/* @__PURE__ */ jsx11(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs11(Button, { variant: "outline", className: "w-full justify-between", children: [
|
|
956
|
+
/* @__PURE__ */ jsx11("span", { className: "truncate", children: selected ? selected.name : placeholder }),
|
|
957
|
+
/* @__PURE__ */ jsx11(ChevronDown, { className: "ml-2 h-4 w-4 shrink-0 opacity-50" })
|
|
804
958
|
] }) }),
|
|
805
|
-
/* @__PURE__ */
|
|
806
|
-
/* @__PURE__ */
|
|
959
|
+
/* @__PURE__ */ jsxs11(DropdownMenuContent, { className: "w-[300px]", align: "start", children: [
|
|
960
|
+
/* @__PURE__ */ jsxs11(
|
|
807
961
|
DropdownMenuItem,
|
|
808
962
|
{
|
|
809
963
|
onClick: () => onSelect(null),
|
|
810
964
|
className: "flex items-center justify-between",
|
|
811
965
|
children: [
|
|
812
|
-
/* @__PURE__ */
|
|
813
|
-
!selectedId && /* @__PURE__ */
|
|
966
|
+
/* @__PURE__ */ jsx11("span", { children: placeholder }),
|
|
967
|
+
!selectedId && /* @__PURE__ */ jsx11(Check, { className: "h-4 w-4 text-green-400" })
|
|
814
968
|
]
|
|
815
969
|
}
|
|
816
970
|
),
|
|
817
|
-
builtinProfiles.length > 0 && /* @__PURE__ */
|
|
818
|
-
/* @__PURE__ */
|
|
819
|
-
/* @__PURE__ */
|
|
820
|
-
builtinProfiles.map((profile) => /* @__PURE__ */
|
|
971
|
+
builtinProfiles.length > 0 && /* @__PURE__ */ jsxs11(Fragment4, { children: [
|
|
972
|
+
/* @__PURE__ */ jsx11(DropdownMenuSeparator, {}),
|
|
973
|
+
/* @__PURE__ */ jsx11(DropdownMenuLabel, { children: "Built-in Profiles" }),
|
|
974
|
+
builtinProfiles.map((profile) => /* @__PURE__ */ jsxs11(
|
|
821
975
|
DropdownMenuItem,
|
|
822
976
|
{
|
|
823
977
|
onClick: () => onSelect(profile),
|
|
824
978
|
className: "flex flex-col items-start gap-1",
|
|
825
979
|
children: [
|
|
826
|
-
/* @__PURE__ */
|
|
827
|
-
/* @__PURE__ */
|
|
828
|
-
/* @__PURE__ */
|
|
829
|
-
profile.extends && /* @__PURE__ */
|
|
980
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex w-full items-center justify-between", children: [
|
|
981
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-2", children: [
|
|
982
|
+
/* @__PURE__ */ jsx11("span", { className: "font-medium", children: profile.name }),
|
|
983
|
+
profile.extends && /* @__PURE__ */ jsxs11(Badge, { variant: "secondary", className: "border-0 text-xs", children: [
|
|
830
984
|
"extends ",
|
|
831
985
|
profile.extends
|
|
832
986
|
] })
|
|
833
987
|
] }),
|
|
834
|
-
selectedId === profile.id && /* @__PURE__ */
|
|
988
|
+
selectedId === profile.id && /* @__PURE__ */ jsx11(Check, { className: "h-4 w-4 text-green-400" })
|
|
835
989
|
] }),
|
|
836
|
-
profile.description && /* @__PURE__ */
|
|
990
|
+
profile.description && /* @__PURE__ */ jsx11("span", { className: "line-clamp-1 text-muted-foreground text-xs", children: profile.description })
|
|
837
991
|
]
|
|
838
992
|
},
|
|
839
993
|
profile.id
|
|
840
994
|
))
|
|
841
995
|
] }),
|
|
842
|
-
customProfiles.length > 0 && /* @__PURE__ */
|
|
843
|
-
/* @__PURE__ */
|
|
844
|
-
/* @__PURE__ */
|
|
845
|
-
customProfiles.map((profile) => /* @__PURE__ */
|
|
996
|
+
customProfiles.length > 0 && /* @__PURE__ */ jsxs11(Fragment4, { children: [
|
|
997
|
+
/* @__PURE__ */ jsx11(DropdownMenuSeparator, {}),
|
|
998
|
+
/* @__PURE__ */ jsx11(DropdownMenuLabel, { children: "Custom Profiles" }),
|
|
999
|
+
customProfiles.map((profile) => /* @__PURE__ */ jsxs11(
|
|
846
1000
|
DropdownMenuItem,
|
|
847
1001
|
{
|
|
848
1002
|
onClick: () => onSelect(profile),
|
|
849
1003
|
className: "flex flex-col items-start gap-1",
|
|
850
1004
|
children: [
|
|
851
|
-
/* @__PURE__ */
|
|
852
|
-
/* @__PURE__ */
|
|
853
|
-
/* @__PURE__ */
|
|
854
|
-
profile.model && /* @__PURE__ */
|
|
1005
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex w-full items-center justify-between", children: [
|
|
1006
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-2", children: [
|
|
1007
|
+
/* @__PURE__ */ jsx11("span", { className: "font-medium", children: profile.name }),
|
|
1008
|
+
profile.model && /* @__PURE__ */ jsx11(Badge, { variant: "secondary", className: "border-0 text-xs", children: profile.model.split("/").pop() })
|
|
855
1009
|
] }),
|
|
856
|
-
selectedId === profile.id && /* @__PURE__ */
|
|
1010
|
+
selectedId === profile.id && /* @__PURE__ */ jsx11(Check, { className: "h-4 w-4 text-green-400" })
|
|
857
1011
|
] }),
|
|
858
|
-
profile.description && /* @__PURE__ */
|
|
859
|
-
showMetrics && profile.metrics && profile.metrics.total_runs > 0 && /* @__PURE__ */
|
|
860
|
-
/* @__PURE__ */
|
|
1012
|
+
profile.description && /* @__PURE__ */ jsx11("span", { className: "line-clamp-1 text-muted-foreground text-xs", children: profile.description }),
|
|
1013
|
+
showMetrics && profile.metrics && profile.metrics.total_runs > 0 && /* @__PURE__ */ jsxs11("div", { className: "flex gap-3 text-muted-foreground text-xs", children: [
|
|
1014
|
+
/* @__PURE__ */ jsxs11("span", { children: [
|
|
861
1015
|
profile.metrics.total_runs,
|
|
862
1016
|
" runs"
|
|
863
1017
|
] }),
|
|
864
|
-
/* @__PURE__ */
|
|
1018
|
+
/* @__PURE__ */ jsxs11("span", { children: [
|
|
865
1019
|
profile.metrics.success_rate.toFixed(0),
|
|
866
1020
|
"% success"
|
|
867
1021
|
] }),
|
|
868
|
-
/* @__PURE__ */
|
|
1022
|
+
/* @__PURE__ */ jsxs11("span", { children: [
|
|
869
1023
|
"~",
|
|
870
1024
|
(profile.metrics.avg_duration_ms / 1e3).toFixed(1),
|
|
871
1025
|
"s avg"
|
|
@@ -876,26 +1030,26 @@ function ProfileSelector({
|
|
|
876
1030
|
profile.id
|
|
877
1031
|
))
|
|
878
1032
|
] }),
|
|
879
|
-
(onCreateClick || onManageClick) && /* @__PURE__ */
|
|
880
|
-
/* @__PURE__ */
|
|
881
|
-
onCreateClick && /* @__PURE__ */
|
|
1033
|
+
(onCreateClick || onManageClick) && /* @__PURE__ */ jsxs11(Fragment4, { children: [
|
|
1034
|
+
/* @__PURE__ */ jsx11(DropdownMenuSeparator, {}),
|
|
1035
|
+
onCreateClick && /* @__PURE__ */ jsxs11(
|
|
882
1036
|
DropdownMenuItem,
|
|
883
1037
|
{
|
|
884
1038
|
onClick: onCreateClick,
|
|
885
1039
|
className: "text-blue-400",
|
|
886
1040
|
children: [
|
|
887
|
-
/* @__PURE__ */
|
|
1041
|
+
/* @__PURE__ */ jsx11(Plus, { className: "mr-2 h-4 w-4" }),
|
|
888
1042
|
"Create New Profile"
|
|
889
1043
|
]
|
|
890
1044
|
}
|
|
891
1045
|
),
|
|
892
|
-
onManageClick && /* @__PURE__ */
|
|
1046
|
+
onManageClick && /* @__PURE__ */ jsxs11(
|
|
893
1047
|
DropdownMenuItem,
|
|
894
1048
|
{
|
|
895
1049
|
onClick: onManageClick,
|
|
896
1050
|
className: "text-muted-foreground",
|
|
897
1051
|
children: [
|
|
898
|
-
/* @__PURE__ */
|
|
1052
|
+
/* @__PURE__ */ jsx11(Settings, { className: "mr-2 h-4 w-4" }),
|
|
899
1053
|
"Manage Profiles"
|
|
900
1054
|
]
|
|
901
1055
|
}
|
|
@@ -921,26 +1075,26 @@ function ProfileComparison({
|
|
|
921
1075
|
const fastestProfile = profilesWithMetrics.reduce(
|
|
922
1076
|
(best, p) => (p.metrics?.avg_duration_ms ?? Number.POSITIVE_INFINITY) < (best.metrics?.avg_duration_ms ?? Number.POSITIVE_INFINITY) ? p : best
|
|
923
1077
|
);
|
|
924
|
-
return /* @__PURE__ */
|
|
925
|
-
/* @__PURE__ */
|
|
926
|
-
/* @__PURE__ */
|
|
1078
|
+
return /* @__PURE__ */ jsxs11("div", { className: `rounded-lg border border-border p-4 ${className ?? ""}`, children: [
|
|
1079
|
+
/* @__PURE__ */ jsx11("h4", { className: "mb-3 font-medium text-sm", children: "Profile Performance" }),
|
|
1080
|
+
/* @__PURE__ */ jsx11("div", { className: "space-y-3", children: profilesWithMetrics.map((profile) => {
|
|
927
1081
|
const isBestSuccess = profile.id === bestSuccess.id;
|
|
928
1082
|
const isFastest = profile.id === fastestProfile.id;
|
|
929
|
-
return /* @__PURE__ */
|
|
1083
|
+
return /* @__PURE__ */ jsxs11(
|
|
930
1084
|
"div",
|
|
931
1085
|
{
|
|
932
1086
|
className: "flex items-center justify-between gap-4",
|
|
933
1087
|
children: [
|
|
934
|
-
/* @__PURE__ */
|
|
935
|
-
/* @__PURE__ */
|
|
936
|
-
isBestSuccess && /* @__PURE__ */
|
|
937
|
-
isFastest && !isBestSuccess && /* @__PURE__ */
|
|
1088
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-2", children: [
|
|
1089
|
+
/* @__PURE__ */ jsx11("span", { className: "font-medium", children: profile.name }),
|
|
1090
|
+
isBestSuccess && /* @__PURE__ */ jsx11(Badge, { className: "border-0 bg-green-500/10 text-green-400 text-xs", children: "Best Success" }),
|
|
1091
|
+
isFastest && !isBestSuccess && /* @__PURE__ */ jsx11(Badge, { className: "border-0 bg-blue-500/10 text-blue-400 text-xs", children: "Fastest" })
|
|
938
1092
|
] }),
|
|
939
|
-
/* @__PURE__ */
|
|
940
|
-
/* @__PURE__ */
|
|
941
|
-
/* @__PURE__ */
|
|
1093
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-4 text-sm", children: [
|
|
1094
|
+
/* @__PURE__ */ jsxs11("span", { children: [
|
|
1095
|
+
/* @__PURE__ */ jsx11("span", { className: "text-muted-foreground", children: "Success:" }),
|
|
942
1096
|
" ",
|
|
943
|
-
/* @__PURE__ */
|
|
1097
|
+
/* @__PURE__ */ jsxs11(
|
|
944
1098
|
"span",
|
|
945
1099
|
{
|
|
946
1100
|
className: (profile.metrics?.success_rate ?? 0) >= 80 ? "text-green-400" : (profile.metrics?.success_rate ?? 0) >= 50 ? "text-yellow-400" : "text-red-400",
|
|
@@ -951,13 +1105,13 @@ function ProfileComparison({
|
|
|
951
1105
|
}
|
|
952
1106
|
)
|
|
953
1107
|
] }),
|
|
954
|
-
/* @__PURE__ */
|
|
955
|
-
/* @__PURE__ */
|
|
1108
|
+
/* @__PURE__ */ jsxs11("span", { children: [
|
|
1109
|
+
/* @__PURE__ */ jsx11("span", { className: "text-muted-foreground", children: "Avg:" }),
|
|
956
1110
|
" ",
|
|
957
1111
|
((profile.metrics?.avg_duration_ms ?? 0) / 1e3).toFixed(1),
|
|
958
1112
|
"s"
|
|
959
1113
|
] }),
|
|
960
|
-
/* @__PURE__ */
|
|
1114
|
+
/* @__PURE__ */ jsxs11("span", { className: "text-muted-foreground", children: [
|
|
961
1115
|
profile.metrics?.total_runs,
|
|
962
1116
|
" runs"
|
|
963
1117
|
] })
|
|
@@ -981,7 +1135,7 @@ import {
|
|
|
981
1135
|
X,
|
|
982
1136
|
XCircle
|
|
983
1137
|
} from "lucide-react";
|
|
984
|
-
import { jsx as
|
|
1138
|
+
import { jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
985
1139
|
var statusConfig2 = {
|
|
986
1140
|
pending: {
|
|
987
1141
|
icon: Clock,
|
|
@@ -1055,20 +1209,20 @@ function VariantList({
|
|
|
1055
1209
|
isActioning,
|
|
1056
1210
|
className
|
|
1057
1211
|
}) {
|
|
1058
|
-
return /* @__PURE__ */
|
|
1212
|
+
return /* @__PURE__ */ jsx12("div", { className: `space-y-3 ${className || ""}`, children: variants.map((variant) => {
|
|
1059
1213
|
const status = statusConfig2[variant.status];
|
|
1060
1214
|
const StatusIcon = status.icon;
|
|
1061
1215
|
const isSelected = variant.id === selectedId;
|
|
1062
|
-
return /* @__PURE__ */
|
|
1216
|
+
return /* @__PURE__ */ jsxs12(
|
|
1063
1217
|
"div",
|
|
1064
1218
|
{
|
|
1065
1219
|
className: `cursor-pointer rounded-lg border p-4 transition-colors ${isSelected ? "border-blue-500 bg-blue-500/5" : "border-border hover:border-muted-foreground/50"}`,
|
|
1066
1220
|
onClick: () => onSelect?.(variant.id),
|
|
1067
1221
|
children: [
|
|
1068
|
-
/* @__PURE__ */
|
|
1069
|
-
/* @__PURE__ */
|
|
1070
|
-
/* @__PURE__ */
|
|
1071
|
-
/* @__PURE__ */
|
|
1222
|
+
/* @__PURE__ */ jsxs12("div", { className: "flex items-center justify-between", children: [
|
|
1223
|
+
/* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-3", children: [
|
|
1224
|
+
/* @__PURE__ */ jsxs12(Badge, { className: `${status.bg} ${status.color} border-0`, children: [
|
|
1225
|
+
/* @__PURE__ */ jsx12(
|
|
1072
1226
|
StatusIcon,
|
|
1073
1227
|
{
|
|
1074
1228
|
className: `mr-1 h-3 w-3 ${status.animate ? "animate-spin" : ""}`
|
|
@@ -1076,28 +1230,28 @@ function VariantList({
|
|
|
1076
1230
|
),
|
|
1077
1231
|
status.label
|
|
1078
1232
|
] }),
|
|
1079
|
-
/* @__PURE__ */
|
|
1080
|
-
variant.sublabel && /* @__PURE__ */
|
|
1233
|
+
/* @__PURE__ */ jsx12("span", { className: "font-medium", children: variant.label }),
|
|
1234
|
+
variant.sublabel && /* @__PURE__ */ jsxs12("span", { className: "text-muted-foreground text-sm", children: [
|
|
1081
1235
|
"(",
|
|
1082
1236
|
variant.sublabel,
|
|
1083
1237
|
")"
|
|
1084
1238
|
] }),
|
|
1085
|
-
variant.durationMs && /* @__PURE__ */
|
|
1086
|
-
/* @__PURE__ */
|
|
1239
|
+
variant.durationMs && /* @__PURE__ */ jsxs12("span", { className: "flex items-center gap-1 text-muted-foreground text-sm", children: [
|
|
1240
|
+
/* @__PURE__ */ jsx12(Timer, { className: "h-3 w-3" }),
|
|
1087
1241
|
(variant.durationMs / 1e3).toFixed(2),
|
|
1088
1242
|
"s"
|
|
1089
1243
|
] })
|
|
1090
1244
|
] }),
|
|
1091
|
-
/* @__PURE__ */
|
|
1092
|
-
variant.outcome && /* @__PURE__ */
|
|
1245
|
+
/* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-2", children: [
|
|
1246
|
+
variant.outcome && /* @__PURE__ */ jsx12(
|
|
1093
1247
|
Badge,
|
|
1094
1248
|
{
|
|
1095
1249
|
className: `${outcomeConfig[variant.outcome].bg} ${outcomeConfig[variant.outcome].color} border-0`,
|
|
1096
1250
|
children: outcomeConfig[variant.outcome].label
|
|
1097
1251
|
}
|
|
1098
1252
|
),
|
|
1099
|
-
variant.status === "completed" && variant.outcome === "pending_review" && onAccept && onReject && /* @__PURE__ */
|
|
1100
|
-
/* @__PURE__ */
|
|
1253
|
+
variant.status === "completed" && variant.outcome === "pending_review" && onAccept && onReject && /* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-2", children: [
|
|
1254
|
+
/* @__PURE__ */ jsxs12(
|
|
1101
1255
|
Button,
|
|
1102
1256
|
{
|
|
1103
1257
|
variant: "outline",
|
|
@@ -1109,12 +1263,12 @@ function VariantList({
|
|
|
1109
1263
|
},
|
|
1110
1264
|
disabled: isActioning === variant.id,
|
|
1111
1265
|
children: [
|
|
1112
|
-
/* @__PURE__ */
|
|
1266
|
+
/* @__PURE__ */ jsx12(Check2, { className: "mr-1 h-4 w-4" }),
|
|
1113
1267
|
"Accept"
|
|
1114
1268
|
]
|
|
1115
1269
|
}
|
|
1116
1270
|
),
|
|
1117
|
-
/* @__PURE__ */
|
|
1271
|
+
/* @__PURE__ */ jsxs12(
|
|
1118
1272
|
Button,
|
|
1119
1273
|
{
|
|
1120
1274
|
variant: "outline",
|
|
@@ -1126,13 +1280,13 @@ function VariantList({
|
|
|
1126
1280
|
},
|
|
1127
1281
|
disabled: isActioning === variant.id,
|
|
1128
1282
|
children: [
|
|
1129
|
-
/* @__PURE__ */
|
|
1283
|
+
/* @__PURE__ */ jsx12(X, { className: "mr-1 h-4 w-4" }),
|
|
1130
1284
|
"Reject"
|
|
1131
1285
|
]
|
|
1132
1286
|
}
|
|
1133
1287
|
)
|
|
1134
1288
|
] }),
|
|
1135
|
-
variant.detailsUrl && /* @__PURE__ */
|
|
1289
|
+
variant.detailsUrl && /* @__PURE__ */ jsx12(
|
|
1136
1290
|
Button,
|
|
1137
1291
|
{
|
|
1138
1292
|
variant: "ghost",
|
|
@@ -1142,13 +1296,13 @@ function VariantList({
|
|
|
1142
1296
|
e.stopPropagation();
|
|
1143
1297
|
window.open(variant.detailsUrl, "_blank");
|
|
1144
1298
|
},
|
|
1145
|
-
children: /* @__PURE__ */
|
|
1299
|
+
children: /* @__PURE__ */ jsx12(ExternalLink, { className: "h-4 w-4" })
|
|
1146
1300
|
}
|
|
1147
1301
|
)
|
|
1148
1302
|
] })
|
|
1149
1303
|
] }),
|
|
1150
|
-
variant.error && /* @__PURE__ */
|
|
1151
|
-
variant.summary && /* @__PURE__ */
|
|
1304
|
+
variant.error && /* @__PURE__ */ jsx12("p", { className: "mt-2 text-red-400 text-sm", children: variant.error }),
|
|
1305
|
+
variant.summary && /* @__PURE__ */ jsx12("p", { className: "mt-2 line-clamp-2 text-muted-foreground text-sm", children: variant.summary })
|
|
1152
1306
|
]
|
|
1153
1307
|
},
|
|
1154
1308
|
variant.id
|
|
@@ -1159,6 +1313,9 @@ function VariantList({
|
|
|
1159
1313
|
export {
|
|
1160
1314
|
AppSidebar,
|
|
1161
1315
|
ClusterStatusBar,
|
|
1316
|
+
CreditBalance,
|
|
1317
|
+
InvoiceTable,
|
|
1318
|
+
PlanCards,
|
|
1162
1319
|
DashboardLayout,
|
|
1163
1320
|
ResourceMeter,
|
|
1164
1321
|
SandboxCard,
|