@tangle-network/sandbox-ui 0.19.0 → 0.20.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-5I363RL7.js → chunk-R6QNJQRH.js} +636 -571
- package/dist/dashboard.d.ts +49 -1
- package/dist/dashboard.js +7 -1
- package/dist/globals.css +4 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +7 -1
- package/dist/integrations.js +81 -0
- package/dist/styles.css +4 -0
- package/package.json +1 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
+
Button,
|
|
2
3
|
Logo
|
|
3
4
|
} from "./chunk-7ZA5SEK3.js";
|
|
4
5
|
import {
|
|
@@ -402,33 +403,94 @@ function CreditBalance({
|
|
|
402
403
|
);
|
|
403
404
|
}
|
|
404
405
|
|
|
406
|
+
// src/dashboard/out-of-credits.tsx
|
|
407
|
+
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
408
|
+
var INSUFFICIENT_BALANCE_CODE = "insufficient_balance";
|
|
409
|
+
function parseInsufficientBalance(payload, opts = {}) {
|
|
410
|
+
if (!payload || typeof payload !== "object") return null;
|
|
411
|
+
const body = payload;
|
|
412
|
+
const code = typeof body.code === "string" ? body.code : void 0;
|
|
413
|
+
if (code !== INSUFFICIENT_BALANCE_CODE) return null;
|
|
414
|
+
const manageUrl = typeof body.manageUrl === "string" && body.manageUrl.length > 0 ? body.manageUrl : opts.defaultManageUrl;
|
|
415
|
+
if (!manageUrl) return null;
|
|
416
|
+
return {
|
|
417
|
+
manageUrl,
|
|
418
|
+
plan: typeof body.plan === "string" ? body.plan : void 0,
|
|
419
|
+
remainingBalanceUsd: typeof body.remainingBalanceUsd === "number" ? body.remainingBalanceUsd : void 0,
|
|
420
|
+
message: typeof body.message === "string" ? body.message : typeof body.error === "string" ? body.error : void 0
|
|
421
|
+
};
|
|
422
|
+
}
|
|
423
|
+
function OutOfCreditsModal({
|
|
424
|
+
balance,
|
|
425
|
+
onClose,
|
|
426
|
+
ctaLabel = "Add credits",
|
|
427
|
+
className
|
|
428
|
+
}) {
|
|
429
|
+
if (!balance) return null;
|
|
430
|
+
return /* @__PURE__ */ jsx4(
|
|
431
|
+
"div",
|
|
432
|
+
{
|
|
433
|
+
role: "dialog",
|
|
434
|
+
"aria-modal": "true",
|
|
435
|
+
"aria-label": "Out of credits",
|
|
436
|
+
className: "fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4",
|
|
437
|
+
onClick: onClose,
|
|
438
|
+
children: /* @__PURE__ */ jsxs3(
|
|
439
|
+
"div",
|
|
440
|
+
{
|
|
441
|
+
className: cn(
|
|
442
|
+
"bg-card border border-border rounded-xl p-6 max-w-md w-full shadow-xl",
|
|
443
|
+
className
|
|
444
|
+
),
|
|
445
|
+
onClick: (e) => e.stopPropagation(),
|
|
446
|
+
children: [
|
|
447
|
+
/* @__PURE__ */ jsx4("h3", { className: "text-lg font-bold text-foreground mb-1", children: "You're out of credits" }),
|
|
448
|
+
/* @__PURE__ */ jsxs3("p", { className: "text-sm text-muted-foreground leading-relaxed mb-4", children: [
|
|
449
|
+
balance.message ?? "Add credits or start a subscription to keep going. Usage is billed to your Tangle account.",
|
|
450
|
+
typeof balance.remainingBalanceUsd === "number" && /* @__PURE__ */ jsxs3("span", { className: "block mt-1", children: [
|
|
451
|
+
"Balance: $",
|
|
452
|
+
balance.remainingBalanceUsd.toFixed(2),
|
|
453
|
+
balance.plan ? ` \xB7 ${balance.plan} plan` : ""
|
|
454
|
+
] })
|
|
455
|
+
] }),
|
|
456
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex gap-2 justify-end", children: [
|
|
457
|
+
onClose && /* @__PURE__ */ jsx4(Button, { variant: "outline", onClick: onClose, children: "Not now" }),
|
|
458
|
+
/* @__PURE__ */ jsx4(Button, { asChild: true, children: /* @__PURE__ */ jsx4("a", { href: balance.manageUrl, target: "_blank", rel: "noopener noreferrer", children: ctaLabel }) })
|
|
459
|
+
] })
|
|
460
|
+
]
|
|
461
|
+
}
|
|
462
|
+
)
|
|
463
|
+
}
|
|
464
|
+
);
|
|
465
|
+
}
|
|
466
|
+
|
|
405
467
|
// src/dashboard/cluster-status-bar.tsx
|
|
406
|
-
import { Fragment as Fragment2, jsx as
|
|
468
|
+
import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
407
469
|
function ClusterStatusBar({ items, latency, className }) {
|
|
408
470
|
if (!items?.length) return null;
|
|
409
|
-
return /* @__PURE__ */
|
|
410
|
-
/* @__PURE__ */
|
|
411
|
-
/* @__PURE__ */
|
|
412
|
-
/* @__PURE__ */
|
|
413
|
-
/* @__PURE__ */
|
|
414
|
-
/* @__PURE__ */
|
|
471
|
+
return /* @__PURE__ */ jsx5("div", { className: cn("fixed bottom-6 left-1/2 -translate-x-1/2 z-40 w-max max-w-[90vw] animate-in slide-in-from-bottom flex justify-center", className), children: /* @__PURE__ */ jsxs4("div", { className: "overflow-hidden rounded-full border border-border bg-card px-6 py-3 flex flex-wrap sm:flex-nowrap items-center justify-between gap-8 shadow-sm", children: [
|
|
472
|
+
/* @__PURE__ */ jsx5("div", { className: "flex items-center gap-6", children: items.map((item, i) => /* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-2", children: [
|
|
473
|
+
/* @__PURE__ */ jsx5("span", { className: "text-[var(--md3-primary)] [&_svg]:h-[18px] [&_svg]:w-[18px]", children: item.icon }),
|
|
474
|
+
/* @__PURE__ */ jsxs4("div", { className: "flex flex-col", children: [
|
|
475
|
+
/* @__PURE__ */ jsx5("span", { className: "text-[10px] text-[var(--md3-on-surface-variant)] uppercase tracking-wider font-bold", children: item.label }),
|
|
476
|
+
/* @__PURE__ */ jsx5("span", { className: cn("text-xs font-bold text-foreground", item.valueClass), children: item.value })
|
|
415
477
|
] })
|
|
416
478
|
] }, i)) }),
|
|
417
|
-
latency && /* @__PURE__ */
|
|
418
|
-
/* @__PURE__ */
|
|
419
|
-
/* @__PURE__ */
|
|
420
|
-
/* @__PURE__ */
|
|
421
|
-
/* @__PURE__ */
|
|
422
|
-
/* @__PURE__ */
|
|
479
|
+
latency && /* @__PURE__ */ jsxs4(Fragment2, { children: [
|
|
480
|
+
/* @__PURE__ */ jsx5("div", { className: "h-6 w-px bg-border" }),
|
|
481
|
+
/* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-3", children: [
|
|
482
|
+
/* @__PURE__ */ jsxs4("div", { className: "relative flex h-2.5 w-2.5 items-center justify-center", children: [
|
|
483
|
+
/* @__PURE__ */ jsx5("span", { className: "absolute inline-flex h-full w-full animate-ping rounded-full bg-green-400 opacity-75" }),
|
|
484
|
+
/* @__PURE__ */ jsx5("span", { className: "relative inline-flex h-2 w-2 rounded-full bg-green-500" })
|
|
423
485
|
] }),
|
|
424
|
-
/* @__PURE__ */
|
|
486
|
+
/* @__PURE__ */ jsx5("span", { className: "text-xs font-mono text-green-400 font-bold", children: latency })
|
|
425
487
|
] })
|
|
426
488
|
] })
|
|
427
489
|
] }) });
|
|
428
490
|
}
|
|
429
491
|
|
|
430
492
|
// src/dashboard/resource-meter.tsx
|
|
431
|
-
import { jsx as
|
|
493
|
+
import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
432
494
|
function getBarColor(percent) {
|
|
433
495
|
if (percent >= 90) return "bg-[var(--code-error)]";
|
|
434
496
|
if (percent >= 70) return "bg-[var(--surface-warning-text)]";
|
|
@@ -437,19 +499,19 @@ function getBarColor(percent) {
|
|
|
437
499
|
function ResourceMeter({ label, value, max = 100, unit, icon, className }) {
|
|
438
500
|
const percent = max > 0 ? Math.min(value / max * 100, 100) : 0;
|
|
439
501
|
const barColor = getBarColor(percent);
|
|
440
|
-
return /* @__PURE__ */
|
|
441
|
-
/* @__PURE__ */
|
|
502
|
+
return /* @__PURE__ */ jsxs5("div", { className: cn("flex items-center gap-3", className), children: [
|
|
503
|
+
/* @__PURE__ */ jsxs5("span", { className: "flex shrink-0 items-center gap-1 text-[10px] font-mono text-muted-foreground uppercase tracking-wide", children: [
|
|
442
504
|
icon,
|
|
443
505
|
label
|
|
444
506
|
] }),
|
|
445
|
-
/* @__PURE__ */
|
|
507
|
+
/* @__PURE__ */ jsx6("div", { className: "h-1.5 min-w-0 flex-1 bg-card rounded-full overflow-hidden", children: /* @__PURE__ */ jsx6(
|
|
446
508
|
"div",
|
|
447
509
|
{
|
|
448
510
|
className: cn("h-full rounded-full transition-all duration-500", barColor),
|
|
449
511
|
style: { width: `${percent}%` }
|
|
450
512
|
}
|
|
451
513
|
) }),
|
|
452
|
-
/* @__PURE__ */
|
|
514
|
+
/* @__PURE__ */ jsx6("span", { className: "shrink-0 text-[10px] font-mono tabular-nums text-muted-foreground", children: unit ? `${value}${unit}/${max}${unit}` : `${Math.round(percent)}%` })
|
|
453
515
|
] });
|
|
454
516
|
}
|
|
455
517
|
|
|
@@ -477,7 +539,7 @@ import {
|
|
|
477
539
|
Plus,
|
|
478
540
|
Users
|
|
479
541
|
} from "lucide-react";
|
|
480
|
-
import { Fragment as Fragment3, jsx as
|
|
542
|
+
import { Fragment as Fragment3, jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
481
543
|
function canAdminSandbox(sandbox) {
|
|
482
544
|
if (!sandbox.team) return true;
|
|
483
545
|
return sandbox.team.role === "owner" || sandbox.team.role === "admin";
|
|
@@ -500,115 +562,115 @@ function SandboxCard({
|
|
|
500
562
|
const isRunning = sandbox.status === "running";
|
|
501
563
|
const isTransitioning = sandbox.status === "provisioning" || sandbox.status === "creating";
|
|
502
564
|
const isStopped = !isRunning && !isTransitioning;
|
|
503
|
-
return /* @__PURE__ */
|
|
565
|
+
return /* @__PURE__ */ jsxs6("div", { className: cn(
|
|
504
566
|
"group relative flex flex-col justify-between overflow-hidden rounded-lg border bg-card p-5 transition-colors",
|
|
505
567
|
isRunning ? "border-[var(--status-running)]/30" : "border-border",
|
|
506
568
|
"hover:border-foreground/15",
|
|
507
569
|
className
|
|
508
570
|
), children: [
|
|
509
|
-
/* @__PURE__ */
|
|
510
|
-
/* @__PURE__ */
|
|
511
|
-
/* @__PURE__ */
|
|
512
|
-
/* @__PURE__ */
|
|
571
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex items-start justify-between", children: [
|
|
572
|
+
/* @__PURE__ */ jsxs6("div", { children: [
|
|
573
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2", children: [
|
|
574
|
+
/* @__PURE__ */ jsxs6("h3", { className: "flex items-center gap-2 text-sm font-bold text-foreground", children: [
|
|
513
575
|
sandbox.name,
|
|
514
|
-
isRunning && /* @__PURE__ */
|
|
515
|
-
/* @__PURE__ */
|
|
516
|
-
/* @__PURE__ */
|
|
576
|
+
isRunning && /* @__PURE__ */ jsxs6("span", { className: "relative flex h-2 w-2", children: [
|
|
577
|
+
/* @__PURE__ */ jsx7("span", { className: "absolute inline-flex h-full w-full animate-pulse rounded-full bg-[var(--status-running)] opacity-75" }),
|
|
578
|
+
/* @__PURE__ */ jsx7("span", { className: "relative inline-flex h-1.5 w-1.5 rounded-full bg-[var(--status-running)]" })
|
|
517
579
|
] })
|
|
518
580
|
] }),
|
|
519
|
-
sandbox.team && /* @__PURE__ */
|
|
581
|
+
sandbox.team && /* @__PURE__ */ jsxs6(
|
|
520
582
|
"span",
|
|
521
583
|
{
|
|
522
584
|
className: "inline-flex items-center gap-1 rounded-full bg-[var(--accent-surface-soft)] px-2 py-0.5 text-[10px] font-semibold text-[var(--accent-text)]",
|
|
523
585
|
title: `Shared with ${sandbox.team.name ?? "Team"} \xB7 ${sandbox.team.role}`,
|
|
524
586
|
children: [
|
|
525
|
-
/* @__PURE__ */
|
|
587
|
+
/* @__PURE__ */ jsx7(Users, { className: "h-3 w-3", "aria-hidden": "true" }),
|
|
526
588
|
sandbox.team.name ?? "Team"
|
|
527
589
|
]
|
|
528
590
|
}
|
|
529
591
|
)
|
|
530
592
|
] }),
|
|
531
|
-
/* @__PURE__ */
|
|
593
|
+
/* @__PURE__ */ jsxs6("p", { className: "mt-0.5 font-mono text-[10px] tracking-wider text-muted-foreground uppercase", children: [
|
|
532
594
|
sandbox.nodeId || "Unknown Node",
|
|
533
|
-
sandbox.team && /* @__PURE__ */
|
|
595
|
+
sandbox.team && /* @__PURE__ */ jsxs6("span", { className: "ml-2 normal-case tracking-normal", children: [
|
|
534
596
|
"\xB7 your role: ",
|
|
535
597
|
sandbox.team.role
|
|
536
598
|
] })
|
|
537
599
|
] })
|
|
538
600
|
] }),
|
|
539
|
-
/* @__PURE__ */
|
|
540
|
-
/* @__PURE__ */
|
|
601
|
+
/* @__PURE__ */ jsxs6(DropdownMenu2, { children: [
|
|
602
|
+
/* @__PURE__ */ jsx7(DropdownMenuTrigger2, { asChild: true, children: /* @__PURE__ */ jsx7(
|
|
541
603
|
"button",
|
|
542
604
|
{
|
|
543
605
|
type: "button",
|
|
544
606
|
className: "rounded-md p-1.5 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground outline-none",
|
|
545
607
|
"aria-label": "Sandbox options",
|
|
546
|
-
children: /* @__PURE__ */
|
|
608
|
+
children: /* @__PURE__ */ jsx7(MoreVertical, { className: "h-4 w-4" })
|
|
547
609
|
}
|
|
548
610
|
) }),
|
|
549
|
-
/* @__PURE__ */
|
|
550
|
-
isRunning && /* @__PURE__ */
|
|
551
|
-
onStop && /* @__PURE__ */
|
|
552
|
-
/* @__PURE__ */
|
|
611
|
+
/* @__PURE__ */ jsxs6(DropdownMenuContent2, { align: "end", className: "min-w-[180px]", children: [
|
|
612
|
+
isRunning && /* @__PURE__ */ jsxs6(Fragment3, { children: [
|
|
613
|
+
onStop && /* @__PURE__ */ jsxs6(DropdownMenuItem2, { onClick: () => onStop(sandbox.id), children: [
|
|
614
|
+
/* @__PURE__ */ jsx7(PowerOff, { className: "mr-2 h-4 w-4" }),
|
|
553
615
|
" Stop Sandbox"
|
|
554
616
|
] }),
|
|
555
|
-
onKeepAlive && /* @__PURE__ */
|
|
556
|
-
/* @__PURE__ */
|
|
617
|
+
onKeepAlive && /* @__PURE__ */ jsxs6(DropdownMenuItem2, { onClick: () => onKeepAlive(sandbox.id), children: [
|
|
618
|
+
/* @__PURE__ */ jsx7(Clock, { className: "mr-2 h-4 w-4" }),
|
|
557
619
|
" Keep Alive"
|
|
558
620
|
] }),
|
|
559
|
-
(onStop || onKeepAlive) && /* @__PURE__ */
|
|
560
|
-
onUsage && /* @__PURE__ */
|
|
561
|
-
/* @__PURE__ */
|
|
621
|
+
(onStop || onKeepAlive) && /* @__PURE__ */ jsx7(DropdownMenuSeparator2, {}),
|
|
622
|
+
onUsage && /* @__PURE__ */ jsxs6(DropdownMenuItem2, { onClick: () => onUsage(sandbox.id), children: [
|
|
623
|
+
/* @__PURE__ */ jsx7(BarChart2, { className: "mr-2 h-4 w-4" }),
|
|
562
624
|
" View Usage"
|
|
563
625
|
] }),
|
|
564
|
-
onHealth && /* @__PURE__ */
|
|
565
|
-
/* @__PURE__ */
|
|
626
|
+
onHealth && /* @__PURE__ */ jsxs6(DropdownMenuItem2, { onClick: () => onHealth(sandbox.id), children: [
|
|
627
|
+
/* @__PURE__ */ jsx7(Activity, { className: "mr-2 h-4 w-4" }),
|
|
566
628
|
" Health Check"
|
|
567
629
|
] }),
|
|
568
|
-
(onUsage || onHealth) && /* @__PURE__ */
|
|
569
|
-
onFork && /* @__PURE__ */
|
|
570
|
-
/* @__PURE__ */
|
|
571
|
-
/* @__PURE__ */
|
|
630
|
+
(onUsage || onHealth) && /* @__PURE__ */ jsx7(DropdownMenuSeparator2, {}),
|
|
631
|
+
onFork && /* @__PURE__ */ jsxs6(Fragment3, { children: [
|
|
632
|
+
/* @__PURE__ */ jsxs6(DropdownMenuItem2, { onClick: () => onFork(sandbox.id), children: [
|
|
633
|
+
/* @__PURE__ */ jsx7(Copy, { className: "mr-2 h-4 w-4" }),
|
|
572
634
|
" Fork Sandbox"
|
|
573
635
|
] }),
|
|
574
|
-
/* @__PURE__ */
|
|
636
|
+
/* @__PURE__ */ jsx7(DropdownMenuSeparator2, {})
|
|
575
637
|
] })
|
|
576
638
|
] }),
|
|
577
|
-
isStopped && /* @__PURE__ */
|
|
578
|
-
onResume && /* @__PURE__ */
|
|
579
|
-
/* @__PURE__ */
|
|
639
|
+
isStopped && /* @__PURE__ */ jsxs6(Fragment3, { children: [
|
|
640
|
+
onResume && /* @__PURE__ */ jsxs6(DropdownMenuItem2, { onClick: () => onResume(sandbox.id), children: [
|
|
641
|
+
/* @__PURE__ */ jsx7(Power, { className: "mr-2 h-4 w-4" }),
|
|
580
642
|
" Resume Sandbox"
|
|
581
643
|
] }),
|
|
582
|
-
onFork && /* @__PURE__ */
|
|
583
|
-
/* @__PURE__ */
|
|
644
|
+
onFork && /* @__PURE__ */ jsxs6(DropdownMenuItem2, { onClick: () => onFork(sandbox.id), children: [
|
|
645
|
+
/* @__PURE__ */ jsx7(Copy, { className: "mr-2 h-4 w-4" }),
|
|
584
646
|
" Fork Sandbox"
|
|
585
647
|
] }),
|
|
586
|
-
(onResume || onFork) && /* @__PURE__ */
|
|
648
|
+
(onResume || onFork) && /* @__PURE__ */ jsx7(DropdownMenuSeparator2, {})
|
|
587
649
|
] }),
|
|
588
|
-
onDelete && canAdminSandbox(sandbox) && /* @__PURE__ */
|
|
589
|
-
/* @__PURE__ */
|
|
650
|
+
onDelete && canAdminSandbox(sandbox) && /* @__PURE__ */ jsxs6(DropdownMenuItem2, { className: "text-destructive focus:bg-destructive/10 focus:text-destructive", onClick: () => onDelete(sandbox.id), children: [
|
|
651
|
+
/* @__PURE__ */ jsx7(Trash2, { className: "mr-2 h-4 w-4" }),
|
|
590
652
|
" Delete Sandbox"
|
|
591
653
|
] })
|
|
592
654
|
] })
|
|
593
655
|
] })
|
|
594
656
|
] }),
|
|
595
|
-
/* @__PURE__ */
|
|
596
|
-
/* @__PURE__ */
|
|
597
|
-
/* @__PURE__ */
|
|
598
|
-
/* @__PURE__ */
|
|
599
|
-
/* @__PURE__ */
|
|
600
|
-
/* @__PURE__ */
|
|
657
|
+
/* @__PURE__ */ jsxs6("div", { className: "my-4", children: [
|
|
658
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-3 rounded-md border border-border bg-muted/30 p-3", children: [
|
|
659
|
+
/* @__PURE__ */ jsx7("div", { className: cn("flex h-10 w-10 items-center justify-center rounded-md", isRunning ? "bg-[var(--surface-success-bg)]" : "bg-muted"), children: sandbox.imageIcon ? sandbox.imageIcon : sandbox.image?.includes("node") ? /* @__PURE__ */ jsx7(Code2, { className: cn("h-5 w-5", isRunning ? "text-[var(--surface-success-text)]" : "text-muted-foreground") }) : /* @__PURE__ */ jsx7(Terminal, { className: cn("h-5 w-5", isRunning ? "text-[var(--surface-success-text)]" : "text-muted-foreground") }) }),
|
|
660
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex flex-col", children: [
|
|
661
|
+
/* @__PURE__ */ jsx7("span", { className: "text-[10px] text-muted-foreground uppercase tracking-widest font-bold", children: "Environment" }),
|
|
662
|
+
/* @__PURE__ */ jsx7("span", { className: "text-xs font-medium text-foreground font-mono mt-0.5", children: sandbox.image || "Universal" })
|
|
601
663
|
] })
|
|
602
664
|
] }),
|
|
603
|
-
isTransitioning && /* @__PURE__ */
|
|
604
|
-
/* @__PURE__ */
|
|
605
|
-
/* @__PURE__ */
|
|
606
|
-
/* @__PURE__ */
|
|
665
|
+
isTransitioning && /* @__PURE__ */ jsxs6("div", { className: "mt-3", children: [
|
|
666
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex justify-between text-xs text-muted-foreground font-medium mb-1", children: [
|
|
667
|
+
/* @__PURE__ */ jsx7("span", { children: sandbox.provisioningMessage || "Starting..." }),
|
|
668
|
+
/* @__PURE__ */ jsxs6("span", { children: [
|
|
607
669
|
sandbox.provisioningPercent || 0,
|
|
608
670
|
"%"
|
|
609
671
|
] })
|
|
610
672
|
] }),
|
|
611
|
-
/* @__PURE__ */
|
|
673
|
+
/* @__PURE__ */ jsx7("div", { className: "h-1 w-full overflow-hidden rounded-full bg-muted", children: /* @__PURE__ */ jsx7(
|
|
612
674
|
"div",
|
|
613
675
|
{
|
|
614
676
|
className: "h-full bg-primary transition-all duration-500 rounded-full",
|
|
@@ -617,18 +679,18 @@ function SandboxCard({
|
|
|
617
679
|
) })
|
|
618
680
|
] })
|
|
619
681
|
] }),
|
|
620
|
-
/* @__PURE__ */
|
|
682
|
+
/* @__PURE__ */ jsx7("div", { className: "border-t border-border pt-3", children: isRunning ? /* @__PURE__ */ jsxs6(
|
|
621
683
|
"button",
|
|
622
684
|
{
|
|
623
685
|
type: "button",
|
|
624
686
|
onClick: () => onOpenIDE?.(sandbox.id),
|
|
625
687
|
className: "flex w-full items-center justify-center gap-2 rounded-md bg-[var(--btn-primary-bg)] px-4 py-2 text-sm font-semibold text-[var(--btn-primary-text)] transition-colors hover:bg-[var(--btn-primary-hover)] active:scale-[0.97]",
|
|
626
688
|
children: [
|
|
627
|
-
/* @__PURE__ */
|
|
689
|
+
/* @__PURE__ */ jsx7(Network, { className: "h-4 w-4" }),
|
|
628
690
|
"Connect Session"
|
|
629
691
|
]
|
|
630
692
|
}
|
|
631
|
-
) : /* @__PURE__ */
|
|
693
|
+
) : /* @__PURE__ */ jsxs6(
|
|
632
694
|
"button",
|
|
633
695
|
{
|
|
634
696
|
type: "button",
|
|
@@ -639,7 +701,7 @@ function SandboxCard({
|
|
|
639
701
|
isTransitioning ? "bg-muted text-muted-foreground cursor-not-allowed border-border" : "bg-card text-foreground hover:bg-muted border-border active:scale-[0.97]"
|
|
640
702
|
),
|
|
641
703
|
children: [
|
|
642
|
-
/* @__PURE__ */
|
|
704
|
+
/* @__PURE__ */ jsx7(Play, { className: "h-4 w-4" }),
|
|
643
705
|
isTransitioning ? "Starting..." : "Wake Sandbox"
|
|
644
706
|
]
|
|
645
707
|
}
|
|
@@ -647,7 +709,7 @@ function SandboxCard({
|
|
|
647
709
|
] });
|
|
648
710
|
}
|
|
649
711
|
function NewSandboxCard({ onClick, className }) {
|
|
650
|
-
return /* @__PURE__ */
|
|
712
|
+
return /* @__PURE__ */ jsxs6(
|
|
651
713
|
"button",
|
|
652
714
|
{
|
|
653
715
|
type: "button",
|
|
@@ -657,9 +719,9 @@ function NewSandboxCard({ onClick, className }) {
|
|
|
657
719
|
className
|
|
658
720
|
),
|
|
659
721
|
children: [
|
|
660
|
-
/* @__PURE__ */
|
|
661
|
-
/* @__PURE__ */
|
|
662
|
-
/* @__PURE__ */
|
|
722
|
+
/* @__PURE__ */ jsx7("div", { className: "flex h-12 w-12 items-center justify-center rounded-lg bg-muted text-muted-foreground", children: /* @__PURE__ */ jsx7(Plus, { className: "h-6 w-6" }) }),
|
|
723
|
+
/* @__PURE__ */ jsx7("span", { className: "mt-4 text-sm font-semibold text-foreground", children: "New Sandbox" }),
|
|
724
|
+
/* @__PURE__ */ jsx7("span", { className: "mt-1 text-xs text-muted-foreground", children: "Deploy a new isolated environment" })
|
|
663
725
|
]
|
|
664
726
|
}
|
|
665
727
|
);
|
|
@@ -693,7 +755,7 @@ import {
|
|
|
693
755
|
DropdownMenuSeparator as DropdownMenuSeparator3,
|
|
694
756
|
DropdownMenuTrigger as DropdownMenuTrigger3
|
|
695
757
|
} from "@tangle-network/ui/primitives";
|
|
696
|
-
import { Fragment as Fragment5, jsx as
|
|
758
|
+
import { Fragment as Fragment5, jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
697
759
|
var statusColors = {
|
|
698
760
|
running: { dot: "bg-[var(--code-success)] animate-pulse", text: "text-[var(--code-success)]", bar: "bg-[var(--code-success)]" },
|
|
699
761
|
hibernating: { dot: "bg-muted-foreground", text: "text-muted-foreground", bar: "bg-muted-foreground" },
|
|
@@ -707,15 +769,15 @@ function isResumable(status) {
|
|
|
707
769
|
return status !== "running" && status !== "provisioning" && status !== "creating";
|
|
708
770
|
}
|
|
709
771
|
function MiniMeter({ label, percent, className }) {
|
|
710
|
-
return /* @__PURE__ */
|
|
711
|
-
/* @__PURE__ */
|
|
712
|
-
/* @__PURE__ */
|
|
713
|
-
/* @__PURE__ */
|
|
772
|
+
return /* @__PURE__ */ jsxs7("div", { className: cn("space-y-1", className), children: [
|
|
773
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex justify-between text-[10px] font-mono text-muted-foreground", children: [
|
|
774
|
+
/* @__PURE__ */ jsx8("span", { className: "font-bold", children: label }),
|
|
775
|
+
/* @__PURE__ */ jsxs7("span", { className: "text-primary", children: [
|
|
714
776
|
percent,
|
|
715
777
|
"%"
|
|
716
778
|
] })
|
|
717
779
|
] }),
|
|
718
|
-
/* @__PURE__ */
|
|
780
|
+
/* @__PURE__ */ jsx8("div", { className: "h-1.5 w-full bg-background rounded-full overflow-hidden", children: /* @__PURE__ */ jsx8("div", { className: "h-full bg-primary rounded-full", style: { width: `${percent}%` } }) })
|
|
719
781
|
] });
|
|
720
782
|
}
|
|
721
783
|
function SandboxTable({
|
|
@@ -754,17 +816,17 @@ function SandboxTable({
|
|
|
754
816
|
const handler = resolveResumeHandler(sb.status);
|
|
755
817
|
return handler ? () => handler(sb.id) : void 0;
|
|
756
818
|
};
|
|
757
|
-
return /* @__PURE__ */
|
|
758
|
-
/* @__PURE__ */
|
|
759
|
-
/* @__PURE__ */
|
|
760
|
-
/* @__PURE__ */
|
|
761
|
-
/* @__PURE__ */
|
|
762
|
-
hasTeamSandboxes && /* @__PURE__ */
|
|
763
|
-
/* @__PURE__ */
|
|
764
|
-
/* @__PURE__ */
|
|
765
|
-
/* @__PURE__ */
|
|
819
|
+
return /* @__PURE__ */ jsxs7("div", { className: cn("w-full", className), children: [
|
|
820
|
+
/* @__PURE__ */ jsx8("div", { className: "w-full bg-card rounded-2xl overflow-hidden border border-border", children: /* @__PURE__ */ jsx8("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsxs7("table", { className: "w-full text-left border-collapse", children: [
|
|
821
|
+
/* @__PURE__ */ jsx8("thead", { children: /* @__PURE__ */ jsxs7("tr", { className: "bg-background border-b border-border", children: [
|
|
822
|
+
/* @__PURE__ */ jsx8("th", { className: "px-6 py-4 text-xs font-semibold text-muted-foreground uppercase tracking-wider", children: "Status" }),
|
|
823
|
+
/* @__PURE__ */ jsx8("th", { className: "px-6 py-4 text-xs font-semibold text-muted-foreground uppercase tracking-wider", children: "Sandbox Name" }),
|
|
824
|
+
hasTeamSandboxes && /* @__PURE__ */ jsx8("th", { className: "px-6 py-4 text-xs font-semibold text-muted-foreground uppercase tracking-wider", children: "Scope" }),
|
|
825
|
+
/* @__PURE__ */ jsx8("th", { className: "px-6 py-4 text-xs font-semibold text-muted-foreground uppercase tracking-wider", children: "Environment" }),
|
|
826
|
+
/* @__PURE__ */ jsx8("th", { className: "px-6 py-4 text-xs font-semibold text-muted-foreground uppercase tracking-wider", children: "Resources" }),
|
|
827
|
+
/* @__PURE__ */ jsx8("th", { className: "px-6 py-4 text-xs font-semibold text-muted-foreground uppercase tracking-wider text-right", children: "Actions" })
|
|
766
828
|
] }) }),
|
|
767
|
-
/* @__PURE__ */
|
|
829
|
+
/* @__PURE__ */ jsx8("tbody", { className: "divide-y divide-border", children: sandboxes.map((sb) => {
|
|
768
830
|
const sc = statusColors[sb.status] ?? statusColors.stopped;
|
|
769
831
|
const isActive = sb.status === "running";
|
|
770
832
|
const isHibernating = sb.status === "hibernating";
|
|
@@ -786,7 +848,7 @@ function SandboxTable({
|
|
|
786
848
|
// IDE, Delete, …), which keep their native
|
|
787
849
|
// semantics. Mouse users get the click-anywhere
|
|
788
850
|
// affordance; nobody loses access.
|
|
789
|
-
/* @__PURE__ */
|
|
851
|
+
/* @__PURE__ */ jsxs7(
|
|
790
852
|
"tr",
|
|
791
853
|
{
|
|
792
854
|
className: cn(
|
|
@@ -795,69 +857,69 @@ function SandboxTable({
|
|
|
795
857
|
),
|
|
796
858
|
onClick: onRowClick,
|
|
797
859
|
children: [
|
|
798
|
-
/* @__PURE__ */
|
|
799
|
-
/* @__PURE__ */
|
|
800
|
-
/* @__PURE__ */
|
|
860
|
+
/* @__PURE__ */ jsx8("td", { className: "px-6 py-5 whitespace-nowrap", children: /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-2", children: [
|
|
861
|
+
/* @__PURE__ */ jsx8("span", { className: cn("flex h-2.5 w-2.5 rounded-full", sc.dot) }),
|
|
862
|
+
/* @__PURE__ */ jsx8("span", { className: cn("text-xs font-bold uppercase tracking-wide", sc.text), children: sb.status.charAt(0).toUpperCase() + sb.status.slice(1) })
|
|
801
863
|
] }) }),
|
|
802
|
-
/* @__PURE__ */
|
|
803
|
-
/* @__PURE__ */
|
|
804
|
-
sb.nodeId && /* @__PURE__ */
|
|
864
|
+
/* @__PURE__ */ jsx8("td", { className: "px-6 py-5", children: /* @__PURE__ */ jsxs7("div", { className: "flex flex-col", children: [
|
|
865
|
+
/* @__PURE__ */ jsx8("span", { className: "text-sm font-bold text-foreground group-hover:text-primary transition-colors", children: sb.name }),
|
|
866
|
+
sb.nodeId && /* @__PURE__ */ jsx8("span", { className: "text-[10px] font-mono text-muted-foreground", children: sb.nodeId })
|
|
805
867
|
] }) }),
|
|
806
|
-
hasTeamSandboxes && /* @__PURE__ */
|
|
868
|
+
hasTeamSandboxes && /* @__PURE__ */ jsx8("td", { className: "px-6 py-5", children: sb.team ? /* @__PURE__ */ jsxs7(
|
|
807
869
|
"div",
|
|
808
870
|
{
|
|
809
871
|
className: "inline-flex items-center gap-1.5 rounded-full bg-[var(--accent-surface-soft)] px-2.5 py-1 text-[11px] font-semibold text-[var(--accent-text)]",
|
|
810
872
|
title: `Shared with ${sb.team.name ?? "Team"} \xB7 ${sb.team.role}`,
|
|
811
873
|
children: [
|
|
812
|
-
/* @__PURE__ */
|
|
813
|
-
/* @__PURE__ */
|
|
814
|
-
/* @__PURE__ */
|
|
874
|
+
/* @__PURE__ */ jsx8(Users2, { className: "h-3 w-3", "aria-hidden": "true" }),
|
|
875
|
+
/* @__PURE__ */ jsx8("span", { children: sb.team.name ?? "Team" }),
|
|
876
|
+
/* @__PURE__ */ jsxs7("span", { className: "font-normal text-muted-foreground", children: [
|
|
815
877
|
"\xB7 ",
|
|
816
878
|
sb.team.role
|
|
817
879
|
] })
|
|
818
880
|
]
|
|
819
881
|
}
|
|
820
|
-
) : /* @__PURE__ */
|
|
882
|
+
) : /* @__PURE__ */ jsxs7(
|
|
821
883
|
"div",
|
|
822
884
|
{
|
|
823
885
|
className: "inline-flex items-center gap-1.5 rounded-full bg-muted px-2.5 py-1 text-[11px] font-medium text-muted-foreground",
|
|
824
886
|
title: "Personal sandbox",
|
|
825
887
|
children: [
|
|
826
|
-
/* @__PURE__ */
|
|
888
|
+
/* @__PURE__ */ jsx8(User, { className: "h-3 w-3", "aria-hidden": "true" }),
|
|
827
889
|
"Personal"
|
|
828
890
|
]
|
|
829
891
|
}
|
|
830
892
|
) }),
|
|
831
|
-
/* @__PURE__ */
|
|
832
|
-
sb.imageIcon && /* @__PURE__ */
|
|
833
|
-
sb.image && /* @__PURE__ */
|
|
893
|
+
/* @__PURE__ */ jsx8("td", { className: "px-6 py-5", children: /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-3", children: [
|
|
894
|
+
sb.imageIcon && /* @__PURE__ */ jsx8("div", { className: "w-8 h-8 rounded-lg bg-muted/50 flex items-center justify-center", children: sb.imageIcon }),
|
|
895
|
+
sb.image && /* @__PURE__ */ jsx8("span", { className: "text-xs font-bold text-foreground", children: sb.image })
|
|
834
896
|
] }) }),
|
|
835
|
-
/* @__PURE__ */
|
|
836
|
-
/* @__PURE__ */
|
|
837
|
-
/* @__PURE__ */
|
|
838
|
-
] }) : isProvisioning ? /* @__PURE__ */
|
|
839
|
-
/* @__PURE__ */
|
|
897
|
+
/* @__PURE__ */ jsx8("td", { className: "px-6 py-5", children: isActive ? /* @__PURE__ */ jsxs7("div", { className: "space-y-3 w-48", children: [
|
|
898
|
+
/* @__PURE__ */ jsx8(MiniMeter, { label: "CPU", percent: sb.cpuPercent ?? 0 }),
|
|
899
|
+
/* @__PURE__ */ jsx8(MiniMeter, { label: "RAM", percent: sb.ramTotal ? Math.round((sb.ramUsed ?? 0) / sb.ramTotal * 100) : 0 })
|
|
900
|
+
] }) : isProvisioning ? /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-2 text-primary italic text-[10px] font-bold", children: [
|
|
901
|
+
/* @__PURE__ */ jsx8(RefreshCw, { className: "h-3.5 w-3.5 animate-spin" }),
|
|
840
902
|
sb.provisioningMessage ?? "Allocating nodes..."
|
|
841
|
-
] }) : isHibernating ? /* @__PURE__ */
|
|
842
|
-
/* @__PURE__ */
|
|
843
|
-
/* @__PURE__ */
|
|
903
|
+
] }) : isHibernating ? /* @__PURE__ */ jsxs7("div", { className: "space-y-3 w-48 opacity-30", children: [
|
|
904
|
+
/* @__PURE__ */ jsx8(MiniMeter, { label: "CPU", percent: 0 }),
|
|
905
|
+
/* @__PURE__ */ jsx8(MiniMeter, { label: "RAM", percent: 0 })
|
|
844
906
|
] }) : null }),
|
|
845
|
-
/* @__PURE__ */
|
|
846
|
-
isActive && /* @__PURE__ */
|
|
847
|
-
/* @__PURE__ */
|
|
907
|
+
/* @__PURE__ */ jsx8("td", { className: "px-6 py-5 text-right", children: /* @__PURE__ */ jsxs7("div", { className: "flex items-center justify-end gap-1", children: [
|
|
908
|
+
isActive && /* @__PURE__ */ jsxs7(Fragment5, { children: [
|
|
909
|
+
/* @__PURE__ */ jsx8("button", { type: "button", onClick: (e) => {
|
|
848
910
|
stopRowClick(e);
|
|
849
911
|
onOpenIDE?.(sb.id);
|
|
850
|
-
}, className: "p-2 rounded-lg hover:bg-muted text-muted-foreground hover:text-foreground transition-all active:scale-90", title: "Open IDE", children: /* @__PURE__ */
|
|
851
|
-
/* @__PURE__ */
|
|
912
|
+
}, className: "p-2 rounded-lg hover:bg-muted text-muted-foreground hover:text-foreground transition-all active:scale-90", title: "Open IDE", children: /* @__PURE__ */ jsx8(Code22, { className: "h-4 w-4" }) }),
|
|
913
|
+
/* @__PURE__ */ jsx8("button", { type: "button", onClick: (e) => {
|
|
852
914
|
stopRowClick(e);
|
|
853
915
|
onOpenTerminal?.(sb.id);
|
|
854
|
-
}, className: "p-2 rounded-lg hover:bg-muted text-muted-foreground hover:text-foreground transition-all active:scale-90", title: "Terminal", children: /* @__PURE__ */
|
|
855
|
-
/* @__PURE__ */
|
|
916
|
+
}, className: "p-2 rounded-lg hover:bg-muted text-muted-foreground hover:text-foreground transition-all active:scale-90", title: "Terminal", children: /* @__PURE__ */ jsx8(Terminal2, { className: "h-4 w-4" }) }),
|
|
917
|
+
/* @__PURE__ */ jsx8("button", { type: "button", onClick: (e) => {
|
|
856
918
|
stopRowClick(e);
|
|
857
919
|
onSSH?.(sb.id);
|
|
858
|
-
}, className: "p-2 rounded-lg hover:bg-muted text-muted-foreground hover:text-foreground transition-all active:scale-90", title: "SSH", children: /* @__PURE__ */
|
|
920
|
+
}, className: "p-2 rounded-lg hover:bg-muted text-muted-foreground hover:text-foreground transition-all active:scale-90", title: "SSH", children: /* @__PURE__ */ jsx8(Key, { className: "h-4 w-4" }) })
|
|
859
921
|
] }),
|
|
860
|
-
resumeHandler && /* @__PURE__ */
|
|
922
|
+
resumeHandler && /* @__PURE__ */ jsxs7(
|
|
861
923
|
"button",
|
|
862
924
|
{
|
|
863
925
|
type: "button",
|
|
@@ -868,7 +930,7 @@ function SandboxTable({
|
|
|
868
930
|
className: "inline-flex items-center gap-1.5 px-3 py-1.5 rounded-lg border border-border text-primary text-[10px] font-bold uppercase tracking-wider hover:bg-[var(--accent-surface-soft)] active:scale-95 transition-all",
|
|
869
931
|
title: resumeLabel,
|
|
870
932
|
children: [
|
|
871
|
-
/* @__PURE__ */
|
|
933
|
+
/* @__PURE__ */ jsx8(Play2, { className: "h-3 w-3" }),
|
|
872
934
|
resumeLabel
|
|
873
935
|
]
|
|
874
936
|
}
|
|
@@ -882,55 +944,55 @@ function SandboxTable({
|
|
|
882
944
|
if (isActive) {
|
|
883
945
|
const lifecycle = [];
|
|
884
946
|
if (onStop) lifecycle.push(
|
|
885
|
-
/* @__PURE__ */
|
|
886
|
-
/* @__PURE__ */
|
|
947
|
+
/* @__PURE__ */ jsxs7(DropdownMenuItem3, { onClick: runItem(onStop), children: [
|
|
948
|
+
/* @__PURE__ */ jsx8(PowerOff2, { className: "mr-2 h-4 w-4" }),
|
|
887
949
|
" Stop Sandbox"
|
|
888
950
|
] }, "stop")
|
|
889
951
|
);
|
|
890
952
|
if (onKeepAlive) lifecycle.push(
|
|
891
|
-
/* @__PURE__ */
|
|
892
|
-
/* @__PURE__ */
|
|
953
|
+
/* @__PURE__ */ jsxs7(DropdownMenuItem3, { onClick: runItem(onKeepAlive), children: [
|
|
954
|
+
/* @__PURE__ */ jsx8(Clock2, { className: "mr-2 h-4 w-4" }),
|
|
893
955
|
" Keep Alive"
|
|
894
956
|
] }, "keep-alive")
|
|
895
957
|
);
|
|
896
958
|
if (lifecycle.length) overflowSections.push(lifecycle);
|
|
897
959
|
const observability = [];
|
|
898
960
|
if (onUsage) observability.push(
|
|
899
|
-
/* @__PURE__ */
|
|
900
|
-
/* @__PURE__ */
|
|
961
|
+
/* @__PURE__ */ jsxs7(DropdownMenuItem3, { onClick: runItem(onUsage), children: [
|
|
962
|
+
/* @__PURE__ */ jsx8(BarChart22, { className: "mr-2 h-4 w-4" }),
|
|
901
963
|
" View Usage"
|
|
902
964
|
] }, "usage")
|
|
903
965
|
);
|
|
904
966
|
if (onHealth) observability.push(
|
|
905
|
-
/* @__PURE__ */
|
|
906
|
-
/* @__PURE__ */
|
|
967
|
+
/* @__PURE__ */ jsxs7(DropdownMenuItem3, { onClick: runItem(onHealth), children: [
|
|
968
|
+
/* @__PURE__ */ jsx8(Activity2, { className: "mr-2 h-4 w-4" }),
|
|
907
969
|
" Health Check"
|
|
908
970
|
] }, "health")
|
|
909
971
|
);
|
|
910
972
|
if (observability.length) overflowSections.push(observability);
|
|
911
973
|
if (onFork) overflowSections.push([
|
|
912
|
-
/* @__PURE__ */
|
|
913
|
-
/* @__PURE__ */
|
|
974
|
+
/* @__PURE__ */ jsxs7(DropdownMenuItem3, { onClick: runItem(onFork), children: [
|
|
975
|
+
/* @__PURE__ */ jsx8(Copy2, { className: "mr-2 h-4 w-4" }),
|
|
914
976
|
" Fork Sandbox"
|
|
915
977
|
] }, "fork")
|
|
916
978
|
]);
|
|
917
979
|
} else if (isResumable(sb.status)) {
|
|
918
980
|
if (onFork) overflowSections.push([
|
|
919
|
-
/* @__PURE__ */
|
|
920
|
-
/* @__PURE__ */
|
|
981
|
+
/* @__PURE__ */ jsxs7(DropdownMenuItem3, { onClick: runItem(onFork), children: [
|
|
982
|
+
/* @__PURE__ */ jsx8(Copy2, { className: "mr-2 h-4 w-4" }),
|
|
921
983
|
" Fork Sandbox"
|
|
922
984
|
] }, "fork")
|
|
923
985
|
]);
|
|
924
986
|
}
|
|
925
987
|
if (onMore) overflowSections.push([
|
|
926
|
-
/* @__PURE__ */
|
|
927
|
-
/* @__PURE__ */
|
|
988
|
+
/* @__PURE__ */ jsxs7(DropdownMenuItem3, { onClick: runItem(onMore), children: [
|
|
989
|
+
/* @__PURE__ */ jsx8(ExternalLink, { className: "mr-2 h-4 w-4" }),
|
|
928
990
|
" View Details"
|
|
929
991
|
] }, "view-details")
|
|
930
992
|
]);
|
|
931
993
|
if (overflowSections.length === 0) return null;
|
|
932
|
-
return /* @__PURE__ */
|
|
933
|
-
/* @__PURE__ */
|
|
994
|
+
return /* @__PURE__ */ jsxs7(DropdownMenu3, { children: [
|
|
995
|
+
/* @__PURE__ */ jsx8(DropdownMenuTrigger3, { asChild: true, children: /* @__PURE__ */ jsx8(
|
|
934
996
|
"button",
|
|
935
997
|
{
|
|
936
998
|
type: "button",
|
|
@@ -938,19 +1000,19 @@ function SandboxTable({
|
|
|
938
1000
|
className: "p-2 rounded-lg hover:bg-muted text-muted-foreground hover:text-foreground transition-all active:scale-90 outline-none",
|
|
939
1001
|
"aria-label": "More actions",
|
|
940
1002
|
title: "More actions",
|
|
941
|
-
children: /* @__PURE__ */
|
|
1003
|
+
children: /* @__PURE__ */ jsx8(MoreVertical2, { className: "h-4 w-4" })
|
|
942
1004
|
}
|
|
943
1005
|
) }),
|
|
944
|
-
/* @__PURE__ */
|
|
945
|
-
sectionIdx > 0 && /* @__PURE__ */
|
|
1006
|
+
/* @__PURE__ */ jsx8(DropdownMenuContent3, { align: "end", className: "min-w-[180px]", children: overflowSections.map((section, sectionIdx) => /* @__PURE__ */ jsxs7(React3.Fragment, { children: [
|
|
1007
|
+
sectionIdx > 0 && /* @__PURE__ */ jsx8(DropdownMenuSeparator3, {}),
|
|
946
1008
|
section
|
|
947
1009
|
] }, sectionIdx)) })
|
|
948
1010
|
] });
|
|
949
1011
|
})(),
|
|
950
|
-
onDelete && canAdminSandbox(sb) && /* @__PURE__ */
|
|
1012
|
+
onDelete && canAdminSandbox(sb) && /* @__PURE__ */ jsx8("button", { type: "button", onClick: (e) => {
|
|
951
1013
|
stopRowClick(e);
|
|
952
1014
|
onDelete(sb.id);
|
|
953
|
-
}, className: "p-2 rounded-lg hover:bg-[var(--surface-danger-bg)] text-muted-foreground hover:text-[var(--surface-danger-text)] transition-all active:scale-90", title: "Delete", children: /* @__PURE__ */
|
|
1015
|
+
}, className: "p-2 rounded-lg hover:bg-[var(--surface-danger-bg)] text-muted-foreground hover:text-[var(--surface-danger-text)] transition-all active:scale-90", title: "Delete", children: /* @__PURE__ */ jsx8(Trash22, { className: "h-4 w-4" }) })
|
|
954
1016
|
] }) })
|
|
955
1017
|
]
|
|
956
1018
|
},
|
|
@@ -959,17 +1021,17 @@ function SandboxTable({
|
|
|
959
1021
|
);
|
|
960
1022
|
}) })
|
|
961
1023
|
] }) }) }),
|
|
962
|
-
totalPages > 1 && /* @__PURE__ */
|
|
963
|
-
/* @__PURE__ */
|
|
1024
|
+
totalPages > 1 && /* @__PURE__ */ jsxs7("div", { className: "mt-6 flex flex-col md:flex-row justify-between items-center text-muted-foreground text-xs font-medium gap-4", children: [
|
|
1025
|
+
/* @__PURE__ */ jsxs7("p", { children: [
|
|
964
1026
|
"Showing ",
|
|
965
1027
|
sandboxes.length,
|
|
966
1028
|
" of ",
|
|
967
1029
|
totalCount,
|
|
968
1030
|
" active sandboxes"
|
|
969
1031
|
] }),
|
|
970
|
-
/* @__PURE__ */
|
|
971
|
-
/* @__PURE__ */
|
|
972
|
-
Array.from({ length: Math.min(totalPages, 5) }, (_, i) => i + 1).map((p) => /* @__PURE__ */
|
|
1032
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-2", children: [
|
|
1033
|
+
/* @__PURE__ */ jsx8("button", { type: "button", onClick: () => onPageChange?.(page - 1), disabled: page <= 1, className: "p-2 rounded-lg border border-border hover:bg-muted/50 transition-colors disabled:opacity-30", children: /* @__PURE__ */ jsx8(ChevronLeft, { className: "h-4 w-4" }) }),
|
|
1034
|
+
Array.from({ length: Math.min(totalPages, 5) }, (_, i) => i + 1).map((p) => /* @__PURE__ */ jsx8(
|
|
973
1035
|
"button",
|
|
974
1036
|
{
|
|
975
1037
|
type: "button",
|
|
@@ -982,7 +1044,7 @@ function SandboxTable({
|
|
|
982
1044
|
},
|
|
983
1045
|
p
|
|
984
1046
|
)),
|
|
985
|
-
/* @__PURE__ */
|
|
1047
|
+
/* @__PURE__ */ jsx8("button", { type: "button", onClick: () => onPageChange?.(page + 1), disabled: page >= totalPages, className: "p-2 rounded-lg border border-border hover:bg-muted/50 transition-colors disabled:opacity-30", children: /* @__PURE__ */ jsx8(ChevronRight, { className: "h-4 w-4" }) })
|
|
986
1048
|
] })
|
|
987
1049
|
] })
|
|
988
1050
|
] });
|
|
@@ -990,51 +1052,51 @@ function SandboxTable({
|
|
|
990
1052
|
|
|
991
1053
|
// src/dashboard/invoice-table.tsx
|
|
992
1054
|
import { Download, FileText } from "lucide-react";
|
|
993
|
-
import { jsx as
|
|
1055
|
+
import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
994
1056
|
var statusStyle = {
|
|
995
1057
|
paid: "bg-[var(--accent-surface-soft)] text-primary border border-border",
|
|
996
1058
|
pending: "bg-[var(--surface-warning-bg)] text-[var(--surface-warning-text)] border border-[var(--surface-warning-border)]",
|
|
997
1059
|
failed: "bg-[var(--surface-danger-bg)] text-[var(--surface-danger-text)] border border-[var(--surface-danger-border)]"
|
|
998
1060
|
};
|
|
999
1061
|
function InvoiceTable({ invoices, onExportAll, onLoadMore, onViewInvoice, hasMore, className }) {
|
|
1000
|
-
return /* @__PURE__ */
|
|
1001
|
-
/* @__PURE__ */
|
|
1002
|
-
/* @__PURE__ */
|
|
1003
|
-
onExportAll && /* @__PURE__ */
|
|
1004
|
-
/* @__PURE__ */
|
|
1062
|
+
return /* @__PURE__ */ jsxs8("section", { className, children: [
|
|
1063
|
+
/* @__PURE__ */ jsxs8("div", { className: "flex justify-between items-center mb-6 px-2", children: [
|
|
1064
|
+
/* @__PURE__ */ jsx9("h2", { className: "text-2xl font-bold text-foreground tracking-tight", children: "Invoice History" }),
|
|
1065
|
+
onExportAll && /* @__PURE__ */ jsxs8("button", { type: "button", onClick: onExportAll, className: "text-[10px] font-mono text-primary uppercase tracking-widest flex items-center gap-2 hover:underline", children: [
|
|
1066
|
+
/* @__PURE__ */ jsx9(Download, { className: "h-3.5 w-3.5" }),
|
|
1005
1067
|
"Export All"
|
|
1006
1068
|
] })
|
|
1007
1069
|
] }),
|
|
1008
|
-
/* @__PURE__ */
|
|
1009
|
-
/* @__PURE__ */
|
|
1010
|
-
/* @__PURE__ */
|
|
1011
|
-
/* @__PURE__ */
|
|
1012
|
-
/* @__PURE__ */
|
|
1013
|
-
/* @__PURE__ */
|
|
1014
|
-
/* @__PURE__ */
|
|
1070
|
+
/* @__PURE__ */ jsx9("div", { className: "bg-card rounded-xl overflow-hidden border border-border", children: /* @__PURE__ */ jsxs8("table", { className: "w-full text-left border-collapse", children: [
|
|
1071
|
+
/* @__PURE__ */ jsx9("thead", { children: /* @__PURE__ */ jsxs8("tr", { className: "bg-background border-b border-border", children: [
|
|
1072
|
+
/* @__PURE__ */ jsx9("th", { className: "px-6 py-4 font-mono text-[10px] text-muted-foreground uppercase tracking-widest", children: "Invoice ID" }),
|
|
1073
|
+
/* @__PURE__ */ jsx9("th", { className: "px-6 py-4 font-mono text-[10px] text-muted-foreground uppercase tracking-widest", children: "Date" }),
|
|
1074
|
+
/* @__PURE__ */ jsx9("th", { className: "px-6 py-4 font-mono text-[10px] text-muted-foreground uppercase tracking-widest", children: "Amount" }),
|
|
1075
|
+
/* @__PURE__ */ jsx9("th", { className: "px-6 py-4 font-mono text-[10px] text-muted-foreground uppercase tracking-widest", children: "Status" }),
|
|
1076
|
+
/* @__PURE__ */ jsx9("th", { className: "px-6 py-4 font-mono text-[10px] text-muted-foreground uppercase tracking-widest text-right", children: "Action" })
|
|
1015
1077
|
] }) }),
|
|
1016
|
-
/* @__PURE__ */
|
|
1017
|
-
/* @__PURE__ */
|
|
1018
|
-
/* @__PURE__ */
|
|
1019
|
-
/* @__PURE__ */
|
|
1078
|
+
/* @__PURE__ */ jsx9("tbody", { className: "divide-y divide-border", children: invoices.map((inv) => /* @__PURE__ */ jsxs8("tr", { className: "hover:bg-muted/50 transition-colors", children: [
|
|
1079
|
+
/* @__PURE__ */ jsx9("td", { className: "px-6 py-5 font-mono text-xs text-foreground", children: inv.id }),
|
|
1080
|
+
/* @__PURE__ */ jsx9("td", { className: "px-6 py-5 text-sm text-foreground", children: inv.date }),
|
|
1081
|
+
/* @__PURE__ */ jsxs8("td", { className: "px-6 py-5 text-sm font-bold text-foreground", children: [
|
|
1020
1082
|
"$",
|
|
1021
1083
|
inv.amount.toFixed(2)
|
|
1022
1084
|
] }),
|
|
1023
|
-
/* @__PURE__ */
|
|
1024
|
-
/* @__PURE__ */
|
|
1085
|
+
/* @__PURE__ */ jsx9("td", { className: "px-6 py-5", children: /* @__PURE__ */ jsx9("span", { className: cn("px-2 py-1 text-[10px] font-mono rounded uppercase", statusStyle[inv.status] ?? statusStyle.paid), children: inv.status }) }),
|
|
1086
|
+
/* @__PURE__ */ jsx9("td", { className: "px-6 py-5 text-right", children: /* @__PURE__ */ jsx9("button", { type: "button", onClick: () => onViewInvoice?.(inv.id), className: "text-muted-foreground hover:text-foreground transition-colors", children: /* @__PURE__ */ jsx9(FileText, { className: "h-4 w-4" }) }) })
|
|
1025
1087
|
] }, inv.id)) })
|
|
1026
1088
|
] }) }),
|
|
1027
|
-
hasMore && onLoadMore && /* @__PURE__ */
|
|
1089
|
+
hasMore && onLoadMore && /* @__PURE__ */ jsx9("div", { className: "mt-6 flex justify-center", children: /* @__PURE__ */ jsx9("button", { type: "button", onClick: onLoadMore, className: "px-8 py-2 text-[10px] font-mono text-muted-foreground border border-border rounded-full hover:bg-muted/50 transition-colors uppercase tracking-widest", children: "Load More History" }) })
|
|
1028
1090
|
] });
|
|
1029
1091
|
}
|
|
1030
1092
|
|
|
1031
1093
|
// src/dashboard/plan-cards.tsx
|
|
1032
1094
|
import { Check } from "lucide-react";
|
|
1033
|
-
import { jsx as
|
|
1095
|
+
import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1034
1096
|
function PlanCards({ plans, className }) {
|
|
1035
|
-
return /* @__PURE__ */
|
|
1036
|
-
/* @__PURE__ */
|
|
1037
|
-
/* @__PURE__ */
|
|
1097
|
+
return /* @__PURE__ */ jsxs9("section", { className, children: [
|
|
1098
|
+
/* @__PURE__ */ jsx10("h2", { className: "text-2xl font-bold text-foreground tracking-tight mb-5 px-2", children: "Subscription Plans" }),
|
|
1099
|
+
/* @__PURE__ */ jsx10("div", { className: "grid grid-cols-1 md:grid-cols-3 gap-6", children: plans.map((plan) => /* @__PURE__ */ jsxs9(
|
|
1038
1100
|
"div",
|
|
1039
1101
|
{
|
|
1040
1102
|
className: cn(
|
|
@@ -1042,23 +1104,23 @@ function PlanCards({ plans, className }) {
|
|
|
1042
1104
|
plan.popular ? "bg-muted/50 border-border" : "bg-card border-border hover:bg-muted/50 hover:border-primary/20"
|
|
1043
1105
|
),
|
|
1044
1106
|
children: [
|
|
1045
|
-
plan.popular && /* @__PURE__ */
|
|
1046
|
-
/* @__PURE__ */
|
|
1047
|
-
/* @__PURE__ */
|
|
1048
|
-
/* @__PURE__ */
|
|
1107
|
+
plan.popular && /* @__PURE__ */ jsx10("div", { className: "absolute top-0 right-0 bg-[var(--accent-surface-soft)] border-l border-b border-border px-4 py-1 text-[10px] font-bold text-[var(--accent-text)] uppercase tracking-widest rounded-bl-lg", children: "Popular" }),
|
|
1108
|
+
/* @__PURE__ */ jsxs9("div", { className: "mb-4", children: [
|
|
1109
|
+
/* @__PURE__ */ jsx10("div", { className: cn("text-xs font-mono uppercase tracking-widest mb-2", plan.popular ? "text-primary" : "text-muted-foreground"), children: plan.name }),
|
|
1110
|
+
/* @__PURE__ */ jsxs9("div", { className: "text-3xl font-bold text-foreground", children: [
|
|
1049
1111
|
"$",
|
|
1050
1112
|
plan.price,
|
|
1051
|
-
/* @__PURE__ */
|
|
1113
|
+
/* @__PURE__ */ jsxs9("span", { className: "text-sm font-normal text-muted-foreground tracking-normal", children: [
|
|
1052
1114
|
"/",
|
|
1053
1115
|
plan.period ?? "mo"
|
|
1054
1116
|
] })
|
|
1055
1117
|
] })
|
|
1056
1118
|
] }),
|
|
1057
|
-
/* @__PURE__ */
|
|
1058
|
-
/* @__PURE__ */
|
|
1119
|
+
/* @__PURE__ */ jsx10("ul", { className: "space-y-2 mb-5 text-sm text-muted-foreground", children: plan.features.map((f, i) => /* @__PURE__ */ jsxs9("li", { className: "flex items-center gap-2", children: [
|
|
1120
|
+
/* @__PURE__ */ jsx10(Check, { className: "h-3.5 w-3.5 text-primary shrink-0" }),
|
|
1059
1121
|
f.text
|
|
1060
1122
|
] }, i)) }),
|
|
1061
|
-
/* @__PURE__ */
|
|
1123
|
+
/* @__PURE__ */ jsx10(
|
|
1062
1124
|
"button",
|
|
1063
1125
|
{
|
|
1064
1126
|
type: "button",
|
|
@@ -1080,7 +1142,7 @@ function PlanCards({ plans, className }) {
|
|
|
1080
1142
|
// src/dashboard/backend-selector.tsx
|
|
1081
1143
|
import { ChevronDown } from "lucide-react";
|
|
1082
1144
|
import * as Select from "@radix-ui/react-select";
|
|
1083
|
-
import { jsx as
|
|
1145
|
+
import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1084
1146
|
function BackendSelector({
|
|
1085
1147
|
backends,
|
|
1086
1148
|
selected,
|
|
@@ -1090,10 +1152,10 @@ function BackendSelector({
|
|
|
1090
1152
|
className
|
|
1091
1153
|
}) {
|
|
1092
1154
|
const current = backends.find((b) => b.type === selected);
|
|
1093
|
-
return /* @__PURE__ */
|
|
1094
|
-
label && /* @__PURE__ */
|
|
1095
|
-
/* @__PURE__ */
|
|
1096
|
-
/* @__PURE__ */
|
|
1155
|
+
return /* @__PURE__ */ jsxs10("div", { className: cn("space-y-1.5", className), children: [
|
|
1156
|
+
label && /* @__PURE__ */ jsx11("label", { className: "block text-xs font-medium text-muted-foreground uppercase tracking-[0.06em]", children: label }),
|
|
1157
|
+
/* @__PURE__ */ jsxs10(Select.Root, { value: selected, onValueChange: onChange, children: [
|
|
1158
|
+
/* @__PURE__ */ jsxs10(
|
|
1097
1159
|
Select.Trigger,
|
|
1098
1160
|
{
|
|
1099
1161
|
className: cn(
|
|
@@ -1106,15 +1168,15 @@ function BackendSelector({
|
|
|
1106
1168
|
"data-[state=open]:border-primary/30 data-[state=open]:bg-accent/30"
|
|
1107
1169
|
),
|
|
1108
1170
|
children: [
|
|
1109
|
-
/* @__PURE__ */
|
|
1110
|
-
/* @__PURE__ */
|
|
1111
|
-
current.description && /* @__PURE__ */
|
|
1112
|
-
] }) : /* @__PURE__ */
|
|
1113
|
-
/* @__PURE__ */
|
|
1171
|
+
/* @__PURE__ */ jsx11("div", { className: "min-w-0 flex-1", children: current ? /* @__PURE__ */ jsxs10("div", { children: [
|
|
1172
|
+
/* @__PURE__ */ jsx11("span", { className: "font-medium text-foreground", children: current.label }),
|
|
1173
|
+
current.description && /* @__PURE__ */ jsx11("span", { className: "ml-2 text-xs text-muted-foreground", children: current.description })
|
|
1174
|
+
] }) : /* @__PURE__ */ jsx11("span", { className: "text-muted-foreground", children: placeholder }) }),
|
|
1175
|
+
/* @__PURE__ */ jsx11(Select.Icon, { asChild: true, children: /* @__PURE__ */ jsx11(ChevronDown, { className: "h-4 w-4 shrink-0 text-muted-foreground transition-transform duration-[var(--transition-fast)] data-[state=open]:rotate-180" }) })
|
|
1114
1176
|
]
|
|
1115
1177
|
}
|
|
1116
1178
|
),
|
|
1117
|
-
/* @__PURE__ */
|
|
1179
|
+
/* @__PURE__ */ jsx11(Select.Portal, { children: /* @__PURE__ */ jsx11(
|
|
1118
1180
|
Select.Content,
|
|
1119
1181
|
{
|
|
1120
1182
|
position: "popper",
|
|
@@ -1128,7 +1190,7 @@ function BackendSelector({
|
|
|
1128
1190
|
"data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
|
|
1129
1191
|
"data-[side=bottom]:slide-in-from-top-1"
|
|
1130
1192
|
),
|
|
1131
|
-
children: /* @__PURE__ */
|
|
1193
|
+
children: /* @__PURE__ */ jsx11(Select.Viewport, { className: "p-1", children: backends.map((backend) => /* @__PURE__ */ jsxs10(
|
|
1132
1194
|
Select.Item,
|
|
1133
1195
|
{
|
|
1134
1196
|
value: backend.type,
|
|
@@ -1140,8 +1202,8 @@ function BackendSelector({
|
|
|
1140
1202
|
"data-[state=checked]:bg-[var(--accent-surface-soft)] data-[state=checked]:text-[var(--brand-primary)]"
|
|
1141
1203
|
),
|
|
1142
1204
|
children: [
|
|
1143
|
-
/* @__PURE__ */
|
|
1144
|
-
backend.description && /* @__PURE__ */
|
|
1205
|
+
/* @__PURE__ */ jsx11(Select.ItemText, { children: /* @__PURE__ */ jsx11("span", { className: "font-medium", children: backend.label }) }),
|
|
1206
|
+
backend.description && /* @__PURE__ */ jsx11("span", { className: "mt-0.5 text-xs text-muted-foreground data-[state=checked]:text-[var(--accent-text)]", children: backend.description })
|
|
1145
1207
|
]
|
|
1146
1208
|
},
|
|
1147
1209
|
backend.type
|
|
@@ -1153,7 +1215,7 @@ function BackendSelector({
|
|
|
1153
1215
|
}
|
|
1154
1216
|
|
|
1155
1217
|
// src/dashboard/harness-picker.tsx
|
|
1156
|
-
import { jsx as
|
|
1218
|
+
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
1157
1219
|
var HARNESS_OPTIONS = [
|
|
1158
1220
|
{
|
|
1159
1221
|
type: "opencode",
|
|
@@ -1203,7 +1265,7 @@ function HarnessPicker({
|
|
|
1203
1265
|
description: override?.description ?? h.description
|
|
1204
1266
|
};
|
|
1205
1267
|
});
|
|
1206
|
-
return /* @__PURE__ */
|
|
1268
|
+
return /* @__PURE__ */ jsx12(
|
|
1207
1269
|
BackendSelector,
|
|
1208
1270
|
{
|
|
1209
1271
|
backends,
|
|
@@ -1218,27 +1280,27 @@ function HarnessPicker({
|
|
|
1218
1280
|
// src/dashboard/dashboard-layout.tsx
|
|
1219
1281
|
import * as React4 from "react";
|
|
1220
1282
|
import { Plus as Plus2, Bell } from "lucide-react";
|
|
1221
|
-
import { Fragment as Fragment7, jsx as
|
|
1283
|
+
import { Fragment as Fragment7, jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
1222
1284
|
function SettingsIconSmall({ className }) {
|
|
1223
|
-
return /* @__PURE__ */
|
|
1224
|
-
/* @__PURE__ */
|
|
1225
|
-
/* @__PURE__ */
|
|
1226
|
-
/* @__PURE__ */
|
|
1285
|
+
return /* @__PURE__ */ jsxs11("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: [
|
|
1286
|
+
/* @__PURE__ */ jsx13("title", { children: "Settings" }),
|
|
1287
|
+
/* @__PURE__ */ jsx13("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" }),
|
|
1288
|
+
/* @__PURE__ */ jsx13("circle", { cx: "12", cy: "12", r: "3" })
|
|
1227
1289
|
] });
|
|
1228
1290
|
}
|
|
1229
1291
|
function MenuIcon({ className }) {
|
|
1230
|
-
return /* @__PURE__ */
|
|
1231
|
-
/* @__PURE__ */
|
|
1232
|
-
/* @__PURE__ */
|
|
1233
|
-
/* @__PURE__ */
|
|
1234
|
-
/* @__PURE__ */
|
|
1292
|
+
return /* @__PURE__ */ jsxs11("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: [
|
|
1293
|
+
/* @__PURE__ */ jsx13("title", { children: "Menu icon" }),
|
|
1294
|
+
/* @__PURE__ */ jsx13("line", { x1: "4", x2: "20", y1: "12", y2: "12" }),
|
|
1295
|
+
/* @__PURE__ */ jsx13("line", { x1: "4", x2: "20", y1: "6", y2: "6" }),
|
|
1296
|
+
/* @__PURE__ */ jsx13("line", { x1: "4", x2: "20", y1: "18", y2: "18" })
|
|
1235
1297
|
] });
|
|
1236
1298
|
}
|
|
1237
1299
|
function XIcon({ className }) {
|
|
1238
|
-
return /* @__PURE__ */
|
|
1239
|
-
/* @__PURE__ */
|
|
1240
|
-
/* @__PURE__ */
|
|
1241
|
-
/* @__PURE__ */
|
|
1300
|
+
return /* @__PURE__ */ jsxs11("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: [
|
|
1301
|
+
/* @__PURE__ */ jsx13("title", { children: "Close icon" }),
|
|
1302
|
+
/* @__PURE__ */ jsx13("path", { d: "M18 6 6 18" }),
|
|
1303
|
+
/* @__PURE__ */ jsx13("path", { d: "m6 6 12 12" })
|
|
1242
1304
|
] });
|
|
1243
1305
|
}
|
|
1244
1306
|
function formatNotifDate(raw) {
|
|
@@ -1252,7 +1314,7 @@ function DefaultLink2({
|
|
|
1252
1314
|
children,
|
|
1253
1315
|
...rest
|
|
1254
1316
|
}) {
|
|
1255
|
-
return /* @__PURE__ */
|
|
1317
|
+
return /* @__PURE__ */ jsx13("a", { href: href ?? to, className, ...rest, children });
|
|
1256
1318
|
}
|
|
1257
1319
|
function DashboardLayoutInner({
|
|
1258
1320
|
children,
|
|
@@ -1307,16 +1369,16 @@ function DashboardLayoutInner({
|
|
|
1307
1369
|
);
|
|
1308
1370
|
const activePanel = panels.find((p) => p.mode === mode);
|
|
1309
1371
|
const buildSidebarContent = React4.useCallback(
|
|
1310
|
-
(showLabels) => /* @__PURE__ */
|
|
1311
|
-
/* @__PURE__ */
|
|
1312
|
-
/* @__PURE__ */
|
|
1313
|
-
/* @__PURE__ */
|
|
1372
|
+
(showLabels) => /* @__PURE__ */ jsxs11(Fragment7, { children: [
|
|
1373
|
+
/* @__PURE__ */ jsxs11(SidebarRail, { wide: showLabels, children: [
|
|
1374
|
+
/* @__PURE__ */ jsx13(SidebarRailHeader, { children: /* @__PURE__ */ jsx13(Link, { href: "/", to: "/", className: "p-1 rounded-md transition-colors hover:bg-muted/50", children: /* @__PURE__ */ jsx13(Logo, { variant, size: "sm", iconOnly: true }) }) }),
|
|
1375
|
+
/* @__PURE__ */ jsx13(SidebarRailNav, { children: navItems.map((item, i) => {
|
|
1314
1376
|
const isMode = modeSet.has(item.id);
|
|
1315
1377
|
const prevIsMode = i > 0 && modeSet.has(navItems[i - 1].id);
|
|
1316
1378
|
const showSep = i > 0 && isMode && !prevIsMode;
|
|
1317
|
-
return /* @__PURE__ */
|
|
1318
|
-
showSep && /* @__PURE__ */
|
|
1319
|
-
isMode ? /* @__PURE__ */
|
|
1379
|
+
return /* @__PURE__ */ jsxs11(React4.Fragment, { children: [
|
|
1380
|
+
showSep && /* @__PURE__ */ jsx13(RailSeparator, {}),
|
|
1381
|
+
isMode ? /* @__PURE__ */ jsx13(
|
|
1320
1382
|
RailModeButton,
|
|
1321
1383
|
{
|
|
1322
1384
|
mode: item.id,
|
|
@@ -1325,7 +1387,7 @@ function DashboardLayoutInner({
|
|
|
1325
1387
|
badge: item.badge,
|
|
1326
1388
|
showLabel: showLabels
|
|
1327
1389
|
}
|
|
1328
|
-
) : /* @__PURE__ */
|
|
1390
|
+
) : /* @__PURE__ */ jsx13(Link, { href: item.href, to: item.href, children: /* @__PURE__ */ jsx13(
|
|
1329
1391
|
RailButton,
|
|
1330
1392
|
{
|
|
1331
1393
|
icon: item.icon,
|
|
@@ -1336,11 +1398,11 @@ function DashboardLayoutInner({
|
|
|
1336
1398
|
) })
|
|
1337
1399
|
] }, item.id);
|
|
1338
1400
|
}) }),
|
|
1339
|
-
/* @__PURE__ */
|
|
1340
|
-
onSettingsClick ? /* @__PURE__ */
|
|
1401
|
+
/* @__PURE__ */ jsxs11(SidebarRailFooter, { children: [
|
|
1402
|
+
onSettingsClick ? /* @__PURE__ */ jsx13(RailButton, { icon: SettingsIconSmall, label: "Settings", onClick: onSettingsClick, showLabel: showLabels }) : /* @__PURE__ */ jsx13(Link, { href: settingsHref, to: settingsHref, children: /* @__PURE__ */ jsx13(RailButton, { icon: SettingsIconSmall, label: "Settings", showLabel: showLabels }) }),
|
|
1341
1403
|
railFooter,
|
|
1342
|
-
/* @__PURE__ */
|
|
1343
|
-
/* @__PURE__ */
|
|
1404
|
+
/* @__PURE__ */ jsx13(RailSeparator, {}),
|
|
1405
|
+
/* @__PURE__ */ jsx13(
|
|
1344
1406
|
ProfileAvatar,
|
|
1345
1407
|
{
|
|
1346
1408
|
user: sidebarUser,
|
|
@@ -1354,9 +1416,9 @@ function DashboardLayoutInner({
|
|
|
1354
1416
|
)
|
|
1355
1417
|
] })
|
|
1356
1418
|
] }),
|
|
1357
|
-
panels.length > 0 && /* @__PURE__ */
|
|
1358
|
-
/* @__PURE__ */
|
|
1359
|
-
/* @__PURE__ */
|
|
1419
|
+
panels.length > 0 && /* @__PURE__ */ jsxs11(SidebarPanel, { children: [
|
|
1420
|
+
/* @__PURE__ */ jsx13(SidebarPanelHeader, { title: activePanel?.title ?? mode }),
|
|
1421
|
+
/* @__PURE__ */ jsx13(SidebarPanelContent, { children: activePanel?.content })
|
|
1360
1422
|
] })
|
|
1361
1423
|
] }),
|
|
1362
1424
|
// biome-ignore lint/correctness/useExhaustiveDependencies: intentional — only the inputs that actually affect the sidebar tree
|
|
@@ -1381,8 +1443,8 @@ function DashboardLayoutInner({
|
|
|
1381
1443
|
);
|
|
1382
1444
|
const sidebarContent = React4.useMemo(() => buildSidebarContent(false), [buildSidebarContent]);
|
|
1383
1445
|
const mobileSidebarContent = React4.useMemo(() => buildSidebarContent(true), [buildSidebarContent]);
|
|
1384
|
-
return /* @__PURE__ */
|
|
1385
|
-
/* @__PURE__ */
|
|
1446
|
+
return /* @__PURE__ */ jsxs11("div", { className: cn("min-h-screen bg-background text-foreground", className), children: [
|
|
1447
|
+
/* @__PURE__ */ jsxs11(
|
|
1386
1448
|
"nav",
|
|
1387
1449
|
{
|
|
1388
1450
|
className: "fixed top-0 z-50 bg-card border-b border-border flex justify-between items-center px-8 h-14 font-sans text-[13px] tracking-tight transition-[left,width] duration-200 ease-in-out",
|
|
@@ -1391,9 +1453,9 @@ function DashboardLayoutInner({
|
|
|
1391
1453
|
width: hidden ? "100%" : `calc(100% - ${contentMargin}px)`
|
|
1392
1454
|
},
|
|
1393
1455
|
children: [
|
|
1394
|
-
/* @__PURE__ */
|
|
1395
|
-
/* @__PURE__ */
|
|
1396
|
-
topNavLinks && topNavLinks.length > 0 && /* @__PURE__ */
|
|
1456
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-8", children: [
|
|
1457
|
+
/* @__PURE__ */ jsx13(Link, { href: "/", to: "/", className: "lg:hidden flex items-center p-1 rounded-md hover:bg-muted/50 transition-colors", children: /* @__PURE__ */ jsx13(Logo, { variant, size: "sm", iconOnly: true }) }),
|
|
1458
|
+
topNavLinks && topNavLinks.length > 0 && /* @__PURE__ */ jsx13("div", { className: "hidden md:flex gap-6", children: topNavLinks.map((link) => /* @__PURE__ */ jsx13(
|
|
1397
1459
|
Link,
|
|
1398
1460
|
{
|
|
1399
1461
|
href: link.href,
|
|
@@ -1407,21 +1469,21 @@ function DashboardLayoutInner({
|
|
|
1407
1469
|
link.href
|
|
1408
1470
|
)) })
|
|
1409
1471
|
] }),
|
|
1410
|
-
/* @__PURE__ */
|
|
1411
|
-
onNewSandbox && /* @__PURE__ */
|
|
1472
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-4", children: [
|
|
1473
|
+
onNewSandbox && /* @__PURE__ */ jsxs11(
|
|
1412
1474
|
"button",
|
|
1413
1475
|
{
|
|
1414
1476
|
type: "button",
|
|
1415
1477
|
onClick: onNewSandbox,
|
|
1416
1478
|
className: "hidden md:flex items-center gap-2 bg-[var(--btn-primary-bg)] border border-[var(--border-accent)] text-[var(--btn-primary-text)] px-4 py-2 rounded-lg font-bold hover:bg-[var(--btn-primary-hover)] transition-all active:scale-95 text-xs",
|
|
1417
1479
|
children: [
|
|
1418
|
-
/* @__PURE__ */
|
|
1480
|
+
/* @__PURE__ */ jsx13(Plus2, { className: "h-3.5 w-3.5" }),
|
|
1419
1481
|
"New Sandbox"
|
|
1420
1482
|
]
|
|
1421
1483
|
}
|
|
1422
1484
|
),
|
|
1423
|
-
/* @__PURE__ */
|
|
1424
|
-
/* @__PURE__ */
|
|
1485
|
+
/* @__PURE__ */ jsxs11("div", { className: "relative", ref: notifRef, children: [
|
|
1486
|
+
/* @__PURE__ */ jsxs11(
|
|
1425
1487
|
"button",
|
|
1426
1488
|
{
|
|
1427
1489
|
type: "button",
|
|
@@ -1430,15 +1492,15 @@ function DashboardLayoutInner({
|
|
|
1430
1492
|
"aria-label": "Notifications",
|
|
1431
1493
|
"aria-expanded": notificationsOpen,
|
|
1432
1494
|
children: [
|
|
1433
|
-
/* @__PURE__ */
|
|
1434
|
-
(notifData?.unreadCount ?? 0) > 0 && /* @__PURE__ */
|
|
1495
|
+
/* @__PURE__ */ jsx13(Bell, { className: "h-4 w-4" }),
|
|
1496
|
+
(notifData?.unreadCount ?? 0) > 0 && /* @__PURE__ */ jsx13("span", { className: "absolute top-1 right-1 h-2 w-2 rounded-full bg-destructive" })
|
|
1435
1497
|
]
|
|
1436
1498
|
}
|
|
1437
1499
|
),
|
|
1438
|
-
notificationsOpen && /* @__PURE__ */
|
|
1439
|
-
/* @__PURE__ */
|
|
1440
|
-
/* @__PURE__ */
|
|
1441
|
-
(notifData?.unreadCount ?? 0) > 0 && notifData?.onMarkAllRead && /* @__PURE__ */
|
|
1500
|
+
notificationsOpen && /* @__PURE__ */ jsxs11("div", { className: "absolute right-0 top-full mt-2 w-80 rounded-lg border border-border bg-card shadow-lg z-50", children: [
|
|
1501
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex items-center justify-between border-b border-border px-4 py-3", children: [
|
|
1502
|
+
/* @__PURE__ */ jsx13("p", { className: "font-bold text-foreground text-sm", children: "Notifications" }),
|
|
1503
|
+
(notifData?.unreadCount ?? 0) > 0 && notifData?.onMarkAllRead && /* @__PURE__ */ jsx13(
|
|
1442
1504
|
"button",
|
|
1443
1505
|
{
|
|
1444
1506
|
type: "button",
|
|
@@ -1450,11 +1512,11 @@ function DashboardLayoutInner({
|
|
|
1450
1512
|
}
|
|
1451
1513
|
)
|
|
1452
1514
|
] }),
|
|
1453
|
-
!notifData?.items || notifData.items.length === 0 ? /* @__PURE__ */
|
|
1454
|
-
/* @__PURE__ */
|
|
1455
|
-
/* @__PURE__ */
|
|
1456
|
-
/* @__PURE__ */
|
|
1457
|
-
] }) : /* @__PURE__ */
|
|
1515
|
+
!notifData?.items || notifData.items.length === 0 ? /* @__PURE__ */ jsxs11("div", { className: "flex flex-col items-center justify-center px-4 py-8 text-center", children: [
|
|
1516
|
+
/* @__PURE__ */ jsx13(Bell, { className: "h-8 w-8 text-muted-foreground/40 mb-2" }),
|
|
1517
|
+
/* @__PURE__ */ jsx13("p", { className: "text-muted-foreground text-sm", children: "No notifications yet" }),
|
|
1518
|
+
/* @__PURE__ */ jsx13("p", { className: "text-muted-foreground/60 text-xs mt-1", children: "We'll notify you about important updates" })
|
|
1519
|
+
] }) : /* @__PURE__ */ jsx13("div", { className: "max-h-80 overflow-y-auto", children: notifData.items.map((n) => /* @__PURE__ */ jsxs11(
|
|
1458
1520
|
"button",
|
|
1459
1521
|
{
|
|
1460
1522
|
type: "button",
|
|
@@ -1466,9 +1528,9 @@ function DashboardLayoutInner({
|
|
|
1466
1528
|
if (!n.read) notifData.onMarkRead?.(n.id);
|
|
1467
1529
|
},
|
|
1468
1530
|
children: [
|
|
1469
|
-
/* @__PURE__ */
|
|
1470
|
-
/* @__PURE__ */
|
|
1471
|
-
/* @__PURE__ */
|
|
1531
|
+
/* @__PURE__ */ jsx13("p", { className: cn("text-sm", !n.read ? "font-semibold text-foreground" : "text-muted-foreground"), children: n.title }),
|
|
1532
|
+
/* @__PURE__ */ jsx13("p", { className: "text-xs text-muted-foreground mt-0.5 line-clamp-2", children: n.message }),
|
|
1533
|
+
/* @__PURE__ */ jsx13("p", { className: "text-[10px] text-muted-foreground/50 mt-1", children: formatNotifDate(n.createdAt) })
|
|
1472
1534
|
]
|
|
1473
1535
|
},
|
|
1474
1536
|
n.id
|
|
@@ -1476,7 +1538,7 @@ function DashboardLayoutInner({
|
|
|
1476
1538
|
] })
|
|
1477
1539
|
] })
|
|
1478
1540
|
] }),
|
|
1479
|
-
/* @__PURE__ */
|
|
1541
|
+
/* @__PURE__ */ jsx13(
|
|
1480
1542
|
"button",
|
|
1481
1543
|
{
|
|
1482
1544
|
type: "button",
|
|
@@ -1484,14 +1546,14 @@ function DashboardLayoutInner({
|
|
|
1484
1546
|
className: "rounded-md p-2 hover:bg-muted/50 lg:hidden",
|
|
1485
1547
|
"aria-label": mobileMenuOpen ? "Close menu" : "Open menu",
|
|
1486
1548
|
"aria-expanded": mobileMenuOpen,
|
|
1487
|
-
children: mobileMenuOpen ? /* @__PURE__ */
|
|
1549
|
+
children: mobileMenuOpen ? /* @__PURE__ */ jsx13(XIcon, { className: "h-6 w-6" }) : /* @__PURE__ */ jsx13(MenuIcon, { className: "h-6 w-6" })
|
|
1488
1550
|
}
|
|
1489
1551
|
)
|
|
1490
1552
|
]
|
|
1491
1553
|
}
|
|
1492
1554
|
),
|
|
1493
|
-
mobileMenuOpen && /* @__PURE__ */
|
|
1494
|
-
/* @__PURE__ */
|
|
1555
|
+
mobileMenuOpen && /* @__PURE__ */ jsx13("div", { className: "fixed inset-0 z-30 bg-black/50 lg:hidden", onClick: () => setMobileMenuOpen(false), "aria-hidden": "true" }),
|
|
1556
|
+
/* @__PURE__ */ jsx13(
|
|
1495
1557
|
"aside",
|
|
1496
1558
|
{
|
|
1497
1559
|
className: cn(
|
|
@@ -1504,18 +1566,18 @@ function DashboardLayoutInner({
|
|
|
1504
1566
|
children: mobileSidebarContent
|
|
1505
1567
|
}
|
|
1506
1568
|
),
|
|
1507
|
-
/* @__PURE__ */
|
|
1508
|
-
/* @__PURE__ */
|
|
1569
|
+
/* @__PURE__ */ jsx13(Sidebar, { className: cn("hidden lg:flex", sidebarClassName), children: sidebarContent }),
|
|
1570
|
+
/* @__PURE__ */ jsx13(SidebarContent, { className: cn("pt-16 px-6 pb-8 lg:px-8 bg-background", contentClassName), children }),
|
|
1509
1571
|
footer
|
|
1510
1572
|
] });
|
|
1511
1573
|
}
|
|
1512
1574
|
function DashboardLayout({ defaultPanelOpen, defaultMode, ...props }) {
|
|
1513
|
-
return /* @__PURE__ */
|
|
1575
|
+
return /* @__PURE__ */ jsx13(SidebarProvider, { defaultPanelOpen, defaultMode, hasPanels: (props.panels?.length ?? 0) > 0, children: /* @__PURE__ */ jsx13(DashboardLayoutInner, { defaultPanelOpen, defaultMode, ...props }) });
|
|
1514
1576
|
}
|
|
1515
1577
|
|
|
1516
1578
|
// src/dashboard/profile-selector.tsx
|
|
1517
1579
|
import { Check as Check2, ChevronDown as ChevronDown2, Plus as Plus3, Settings } from "lucide-react";
|
|
1518
|
-
import { Button } from "@tangle-network/ui/primitives";
|
|
1580
|
+
import { Button as Button2 } from "@tangle-network/ui/primitives";
|
|
1519
1581
|
import { Badge } from "@tangle-network/ui/primitives";
|
|
1520
1582
|
import {
|
|
1521
1583
|
DropdownMenu as DropdownMenu4,
|
|
@@ -1525,7 +1587,7 @@ import {
|
|
|
1525
1587
|
DropdownMenuSeparator as DropdownMenuSeparator4,
|
|
1526
1588
|
DropdownMenuTrigger as DropdownMenuTrigger4
|
|
1527
1589
|
} from "@tangle-network/ui/primitives";
|
|
1528
|
-
import { Fragment as Fragment8, jsx as
|
|
1590
|
+
import { Fragment as Fragment8, jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
1529
1591
|
function ProfileSelector({
|
|
1530
1592
|
profiles,
|
|
1531
1593
|
selectedId,
|
|
@@ -1540,77 +1602,77 @@ function ProfileSelector({
|
|
|
1540
1602
|
const selected = profiles.find((p) => p.id === selectedId);
|
|
1541
1603
|
const builtinProfiles = profiles.filter((p) => p.is_builtin);
|
|
1542
1604
|
const customProfiles = profiles.filter((p) => !p.is_builtin);
|
|
1543
|
-
return /* @__PURE__ */
|
|
1544
|
-
label && /* @__PURE__ */
|
|
1545
|
-
/* @__PURE__ */
|
|
1546
|
-
/* @__PURE__ */
|
|
1547
|
-
/* @__PURE__ */
|
|
1548
|
-
/* @__PURE__ */
|
|
1605
|
+
return /* @__PURE__ */ jsxs12("div", { className, children: [
|
|
1606
|
+
label && /* @__PURE__ */ jsx14("label", { className: "mb-2 block font-medium text-sm", children: label }),
|
|
1607
|
+
/* @__PURE__ */ jsxs12(DropdownMenu4, { children: [
|
|
1608
|
+
/* @__PURE__ */ jsx14(DropdownMenuTrigger4, { asChild: true, children: /* @__PURE__ */ jsxs12(Button2, { variant: "outline", className: "w-full justify-between", children: [
|
|
1609
|
+
/* @__PURE__ */ jsx14("span", { className: "truncate", children: selected ? selected.name : placeholder }),
|
|
1610
|
+
/* @__PURE__ */ jsx14(ChevronDown2, { className: "ml-2 h-4 w-4 shrink-0 opacity-50" })
|
|
1549
1611
|
] }) }),
|
|
1550
|
-
/* @__PURE__ */
|
|
1551
|
-
/* @__PURE__ */
|
|
1612
|
+
/* @__PURE__ */ jsxs12(DropdownMenuContent4, { className: "w-[300px]", align: "start", children: [
|
|
1613
|
+
/* @__PURE__ */ jsxs12(
|
|
1552
1614
|
DropdownMenuItem4,
|
|
1553
1615
|
{
|
|
1554
1616
|
onClick: () => onSelect(null),
|
|
1555
1617
|
className: "flex items-center justify-between",
|
|
1556
1618
|
children: [
|
|
1557
|
-
/* @__PURE__ */
|
|
1558
|
-
!selectedId && /* @__PURE__ */
|
|
1619
|
+
/* @__PURE__ */ jsx14("span", { children: placeholder }),
|
|
1620
|
+
!selectedId && /* @__PURE__ */ jsx14(Check2, { className: "h-4 w-4 text-[var(--surface-success-text)]" })
|
|
1559
1621
|
]
|
|
1560
1622
|
}
|
|
1561
1623
|
),
|
|
1562
|
-
builtinProfiles.length > 0 && /* @__PURE__ */
|
|
1563
|
-
/* @__PURE__ */
|
|
1564
|
-
/* @__PURE__ */
|
|
1565
|
-
builtinProfiles.map((profile) => /* @__PURE__ */
|
|
1624
|
+
builtinProfiles.length > 0 && /* @__PURE__ */ jsxs12(Fragment8, { children: [
|
|
1625
|
+
/* @__PURE__ */ jsx14(DropdownMenuSeparator4, {}),
|
|
1626
|
+
/* @__PURE__ */ jsx14(DropdownMenuLabel2, { children: "Built-in Profiles" }),
|
|
1627
|
+
builtinProfiles.map((profile) => /* @__PURE__ */ jsxs12(
|
|
1566
1628
|
DropdownMenuItem4,
|
|
1567
1629
|
{
|
|
1568
1630
|
onClick: () => onSelect(profile),
|
|
1569
1631
|
className: "flex flex-col items-start gap-1",
|
|
1570
1632
|
children: [
|
|
1571
|
-
/* @__PURE__ */
|
|
1572
|
-
/* @__PURE__ */
|
|
1573
|
-
/* @__PURE__ */
|
|
1574
|
-
profile.extends && /* @__PURE__ */
|
|
1633
|
+
/* @__PURE__ */ jsxs12("div", { className: "flex w-full items-center justify-between", children: [
|
|
1634
|
+
/* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-2", children: [
|
|
1635
|
+
/* @__PURE__ */ jsx14("span", { className: "font-medium", children: profile.name }),
|
|
1636
|
+
profile.extends && /* @__PURE__ */ jsxs12(Badge, { variant: "secondary", className: "border-0 text-xs", children: [
|
|
1575
1637
|
"extends ",
|
|
1576
1638
|
profile.extends
|
|
1577
1639
|
] })
|
|
1578
1640
|
] }),
|
|
1579
|
-
selectedId === profile.id && /* @__PURE__ */
|
|
1641
|
+
selectedId === profile.id && /* @__PURE__ */ jsx14(Check2, { className: "h-4 w-4 text-[var(--surface-success-text)]" })
|
|
1580
1642
|
] }),
|
|
1581
|
-
profile.description && /* @__PURE__ */
|
|
1643
|
+
profile.description && /* @__PURE__ */ jsx14("span", { className: "line-clamp-1 text-muted-foreground text-xs", children: profile.description })
|
|
1582
1644
|
]
|
|
1583
1645
|
},
|
|
1584
1646
|
profile.id
|
|
1585
1647
|
))
|
|
1586
1648
|
] }),
|
|
1587
|
-
customProfiles.length > 0 && /* @__PURE__ */
|
|
1588
|
-
/* @__PURE__ */
|
|
1589
|
-
/* @__PURE__ */
|
|
1590
|
-
customProfiles.map((profile) => /* @__PURE__ */
|
|
1649
|
+
customProfiles.length > 0 && /* @__PURE__ */ jsxs12(Fragment8, { children: [
|
|
1650
|
+
/* @__PURE__ */ jsx14(DropdownMenuSeparator4, {}),
|
|
1651
|
+
/* @__PURE__ */ jsx14(DropdownMenuLabel2, { children: "Custom Profiles" }),
|
|
1652
|
+
customProfiles.map((profile) => /* @__PURE__ */ jsxs12(
|
|
1591
1653
|
DropdownMenuItem4,
|
|
1592
1654
|
{
|
|
1593
1655
|
onClick: () => onSelect(profile),
|
|
1594
1656
|
className: "flex flex-col items-start gap-1",
|
|
1595
1657
|
children: [
|
|
1596
|
-
/* @__PURE__ */
|
|
1597
|
-
/* @__PURE__ */
|
|
1598
|
-
/* @__PURE__ */
|
|
1599
|
-
profile.model && /* @__PURE__ */
|
|
1658
|
+
/* @__PURE__ */ jsxs12("div", { className: "flex w-full items-center justify-between", children: [
|
|
1659
|
+
/* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-2", children: [
|
|
1660
|
+
/* @__PURE__ */ jsx14("span", { className: "font-medium", children: profile.name }),
|
|
1661
|
+
profile.model && /* @__PURE__ */ jsx14(Badge, { variant: "secondary", className: "border-0 text-xs", children: profile.model.split("/").pop() })
|
|
1600
1662
|
] }),
|
|
1601
|
-
selectedId === profile.id && /* @__PURE__ */
|
|
1663
|
+
selectedId === profile.id && /* @__PURE__ */ jsx14(Check2, { className: "h-4 w-4 text-[var(--surface-success-text)]" })
|
|
1602
1664
|
] }),
|
|
1603
|
-
profile.description && /* @__PURE__ */
|
|
1604
|
-
showMetrics && profile.metrics && profile.metrics.total_runs > 0 && /* @__PURE__ */
|
|
1605
|
-
/* @__PURE__ */
|
|
1665
|
+
profile.description && /* @__PURE__ */ jsx14("span", { className: "line-clamp-1 text-muted-foreground text-xs", children: profile.description }),
|
|
1666
|
+
showMetrics && profile.metrics && profile.metrics.total_runs > 0 && /* @__PURE__ */ jsxs12("div", { className: "flex gap-3 text-muted-foreground text-xs", children: [
|
|
1667
|
+
/* @__PURE__ */ jsxs12("span", { children: [
|
|
1606
1668
|
profile.metrics.total_runs,
|
|
1607
1669
|
" runs"
|
|
1608
1670
|
] }),
|
|
1609
|
-
/* @__PURE__ */
|
|
1671
|
+
/* @__PURE__ */ jsxs12("span", { children: [
|
|
1610
1672
|
profile.metrics.success_rate.toFixed(0),
|
|
1611
1673
|
"% success"
|
|
1612
1674
|
] }),
|
|
1613
|
-
/* @__PURE__ */
|
|
1675
|
+
/* @__PURE__ */ jsxs12("span", { children: [
|
|
1614
1676
|
"~",
|
|
1615
1677
|
(profile.metrics.avg_duration_ms / 1e3).toFixed(1),
|
|
1616
1678
|
"s avg"
|
|
@@ -1621,26 +1683,26 @@ function ProfileSelector({
|
|
|
1621
1683
|
profile.id
|
|
1622
1684
|
))
|
|
1623
1685
|
] }),
|
|
1624
|
-
(onCreateClick || onManageClick) && /* @__PURE__ */
|
|
1625
|
-
/* @__PURE__ */
|
|
1626
|
-
onCreateClick && /* @__PURE__ */
|
|
1686
|
+
(onCreateClick || onManageClick) && /* @__PURE__ */ jsxs12(Fragment8, { children: [
|
|
1687
|
+
/* @__PURE__ */ jsx14(DropdownMenuSeparator4, {}),
|
|
1688
|
+
onCreateClick && /* @__PURE__ */ jsxs12(
|
|
1627
1689
|
DropdownMenuItem4,
|
|
1628
1690
|
{
|
|
1629
1691
|
onClick: onCreateClick,
|
|
1630
1692
|
className: "text-[var(--surface-info-text)]",
|
|
1631
1693
|
children: [
|
|
1632
|
-
/* @__PURE__ */
|
|
1694
|
+
/* @__PURE__ */ jsx14(Plus3, { className: "mr-2 h-4 w-4" }),
|
|
1633
1695
|
"Create New Profile"
|
|
1634
1696
|
]
|
|
1635
1697
|
}
|
|
1636
1698
|
),
|
|
1637
|
-
onManageClick && /* @__PURE__ */
|
|
1699
|
+
onManageClick && /* @__PURE__ */ jsxs12(
|
|
1638
1700
|
DropdownMenuItem4,
|
|
1639
1701
|
{
|
|
1640
1702
|
onClick: onManageClick,
|
|
1641
1703
|
className: "text-muted-foreground",
|
|
1642
1704
|
children: [
|
|
1643
|
-
/* @__PURE__ */
|
|
1705
|
+
/* @__PURE__ */ jsx14(Settings, { className: "mr-2 h-4 w-4" }),
|
|
1644
1706
|
"Manage Profiles"
|
|
1645
1707
|
]
|
|
1646
1708
|
}
|
|
@@ -1666,26 +1728,26 @@ function ProfileComparison({
|
|
|
1666
1728
|
const fastestProfile = profilesWithMetrics.reduce(
|
|
1667
1729
|
(best, p) => (p.metrics?.avg_duration_ms ?? Number.POSITIVE_INFINITY) < (best.metrics?.avg_duration_ms ?? Number.POSITIVE_INFINITY) ? p : best
|
|
1668
1730
|
);
|
|
1669
|
-
return /* @__PURE__ */
|
|
1670
|
-
/* @__PURE__ */
|
|
1671
|
-
/* @__PURE__ */
|
|
1731
|
+
return /* @__PURE__ */ jsxs12("div", { className: `rounded-lg border border-border p-4 ${className ?? ""}`, children: [
|
|
1732
|
+
/* @__PURE__ */ jsx14("h4", { className: "mb-3 font-medium text-sm", children: "Profile Performance" }),
|
|
1733
|
+
/* @__PURE__ */ jsx14("div", { className: "space-y-3", children: profilesWithMetrics.map((profile) => {
|
|
1672
1734
|
const isBestSuccess = profile.id === bestSuccess.id;
|
|
1673
1735
|
const isFastest = profile.id === fastestProfile.id;
|
|
1674
|
-
return /* @__PURE__ */
|
|
1736
|
+
return /* @__PURE__ */ jsxs12(
|
|
1675
1737
|
"div",
|
|
1676
1738
|
{
|
|
1677
1739
|
className: "flex items-center justify-between gap-4",
|
|
1678
1740
|
children: [
|
|
1679
|
-
/* @__PURE__ */
|
|
1680
|
-
/* @__PURE__ */
|
|
1681
|
-
isBestSuccess && /* @__PURE__ */
|
|
1682
|
-
isFastest && !isBestSuccess && /* @__PURE__ */
|
|
1741
|
+
/* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-2", children: [
|
|
1742
|
+
/* @__PURE__ */ jsx14("span", { className: "font-medium", children: profile.name }),
|
|
1743
|
+
isBestSuccess && /* @__PURE__ */ jsx14(Badge, { className: "border border-[var(--surface-success-border)] bg-[var(--surface-success-bg)] text-[var(--surface-success-text)] text-xs", children: "Best Success" }),
|
|
1744
|
+
isFastest && !isBestSuccess && /* @__PURE__ */ jsx14(Badge, { className: "border border-[var(--surface-info-border)] bg-[var(--surface-info-bg)] text-[var(--surface-info-text)] text-xs", children: "Fastest" })
|
|
1683
1745
|
] }),
|
|
1684
|
-
/* @__PURE__ */
|
|
1685
|
-
/* @__PURE__ */
|
|
1686
|
-
/* @__PURE__ */
|
|
1746
|
+
/* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-4 text-sm", children: [
|
|
1747
|
+
/* @__PURE__ */ jsxs12("span", { children: [
|
|
1748
|
+
/* @__PURE__ */ jsx14("span", { className: "text-muted-foreground", children: "Success:" }),
|
|
1687
1749
|
" ",
|
|
1688
|
-
/* @__PURE__ */
|
|
1750
|
+
/* @__PURE__ */ jsxs12(
|
|
1689
1751
|
"span",
|
|
1690
1752
|
{
|
|
1691
1753
|
className: (profile.metrics?.success_rate ?? 0) >= 80 ? "text-[var(--surface-success-text)]" : (profile.metrics?.success_rate ?? 0) >= 50 ? "text-[var(--surface-warning-text)]" : "text-[var(--surface-danger-text)]",
|
|
@@ -1696,13 +1758,13 @@ function ProfileComparison({
|
|
|
1696
1758
|
}
|
|
1697
1759
|
)
|
|
1698
1760
|
] }),
|
|
1699
|
-
/* @__PURE__ */
|
|
1700
|
-
/* @__PURE__ */
|
|
1761
|
+
/* @__PURE__ */ jsxs12("span", { children: [
|
|
1762
|
+
/* @__PURE__ */ jsx14("span", { className: "text-muted-foreground", children: "Avg:" }),
|
|
1701
1763
|
" ",
|
|
1702
1764
|
((profile.metrics?.avg_duration_ms ?? 0) / 1e3).toFixed(1),
|
|
1703
1765
|
"s"
|
|
1704
1766
|
] }),
|
|
1705
|
-
/* @__PURE__ */
|
|
1767
|
+
/* @__PURE__ */ jsxs12("span", { className: "text-muted-foreground", children: [
|
|
1706
1768
|
profile.metrics?.total_runs,
|
|
1707
1769
|
" runs"
|
|
1708
1770
|
] })
|
|
@@ -1726,9 +1788,9 @@ import {
|
|
|
1726
1788
|
X,
|
|
1727
1789
|
XCircle
|
|
1728
1790
|
} from "lucide-react";
|
|
1729
|
-
import { Button as
|
|
1791
|
+
import { Button as Button3 } from "@tangle-network/ui/primitives";
|
|
1730
1792
|
import { Badge as Badge2 } from "@tangle-network/ui/primitives";
|
|
1731
|
-
import { Fragment as Fragment9, jsx as
|
|
1793
|
+
import { Fragment as Fragment9, jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
1732
1794
|
var statusConfig = {
|
|
1733
1795
|
pending: {
|
|
1734
1796
|
icon: Clock3,
|
|
@@ -1812,19 +1874,19 @@ function VariantList({
|
|
|
1812
1874
|
isActioning,
|
|
1813
1875
|
className
|
|
1814
1876
|
}) {
|
|
1815
|
-
return /* @__PURE__ */
|
|
1877
|
+
return /* @__PURE__ */ jsx15("div", { className: `space-y-2 ${className || ""}`, children: variants.map((variant) => {
|
|
1816
1878
|
const status = statusConfig[variant.status];
|
|
1817
1879
|
const StatusIcon = status.icon;
|
|
1818
1880
|
const isSelected = variant.id === selectedId;
|
|
1819
|
-
return /* @__PURE__ */
|
|
1881
|
+
return /* @__PURE__ */ jsxs13(
|
|
1820
1882
|
"div",
|
|
1821
1883
|
{
|
|
1822
1884
|
className: `cursor-pointer rounded-lg border px-3 py-2.5 transition-colors ${isSelected ? "border-primary/30 bg-[var(--accent-surface-soft)]" : "border-border bg-card hover:border-primary/20 hover:bg-muted/50"}`,
|
|
1823
1885
|
onClick: () => onSelect?.(variant.id),
|
|
1824
1886
|
children: [
|
|
1825
|
-
/* @__PURE__ */
|
|
1826
|
-
/* @__PURE__ */
|
|
1827
|
-
/* @__PURE__ */
|
|
1887
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-2", children: [
|
|
1888
|
+
/* @__PURE__ */ jsxs13(Badge2, { className: `shrink-0 ${status.bg} ${status.border} ${status.color}`, children: [
|
|
1889
|
+
/* @__PURE__ */ jsx15(
|
|
1828
1890
|
StatusIcon,
|
|
1829
1891
|
{
|
|
1830
1892
|
className: `mr-1 h-3 w-3 ${status.animate ? "animate-spin" : ""}`
|
|
@@ -1832,28 +1894,28 @@ function VariantList({
|
|
|
1832
1894
|
),
|
|
1833
1895
|
status.label
|
|
1834
1896
|
] }),
|
|
1835
|
-
/* @__PURE__ */
|
|
1836
|
-
variant.sublabel && /* @__PURE__ */
|
|
1897
|
+
/* @__PURE__ */ jsx15("span", { className: "truncate text-sm font-medium text-foreground", children: variant.label }),
|
|
1898
|
+
variant.sublabel && /* @__PURE__ */ jsxs13("span", { className: "shrink-0 text-xs text-muted-foreground", children: [
|
|
1837
1899
|
"(",
|
|
1838
1900
|
variant.sublabel,
|
|
1839
1901
|
")"
|
|
1840
1902
|
] }),
|
|
1841
|
-
variant.durationMs && /* @__PURE__ */
|
|
1842
|
-
/* @__PURE__ */
|
|
1903
|
+
variant.durationMs && /* @__PURE__ */ jsxs13("span", { className: "flex shrink-0 items-center gap-1 text-xs text-muted-foreground", children: [
|
|
1904
|
+
/* @__PURE__ */ jsx15(Timer, { className: "h-3 w-3" }),
|
|
1843
1905
|
(variant.durationMs / 1e3).toFixed(1),
|
|
1844
1906
|
"s"
|
|
1845
1907
|
] }),
|
|
1846
|
-
/* @__PURE__ */
|
|
1847
|
-
variant.outcome && /* @__PURE__ */
|
|
1908
|
+
/* @__PURE__ */ jsxs13("div", { className: "ml-auto flex shrink-0 items-center gap-1.5", children: [
|
|
1909
|
+
variant.outcome && /* @__PURE__ */ jsx15(
|
|
1848
1910
|
Badge2,
|
|
1849
1911
|
{
|
|
1850
1912
|
className: `${outcomeConfig[variant.outcome].bg} ${outcomeConfig[variant.outcome].border} ${outcomeConfig[variant.outcome].color}`,
|
|
1851
1913
|
children: outcomeConfig[variant.outcome].label
|
|
1852
1914
|
}
|
|
1853
1915
|
),
|
|
1854
|
-
variant.status === "completed" && variant.outcome === "pending_review" && onAccept && onReject && /* @__PURE__ */
|
|
1855
|
-
/* @__PURE__ */
|
|
1856
|
-
|
|
1916
|
+
variant.status === "completed" && variant.outcome === "pending_review" && onAccept && onReject && /* @__PURE__ */ jsxs13(Fragment9, { children: [
|
|
1917
|
+
/* @__PURE__ */ jsxs13(
|
|
1918
|
+
Button3,
|
|
1857
1919
|
{
|
|
1858
1920
|
variant: "outline",
|
|
1859
1921
|
size: "sm",
|
|
@@ -1864,13 +1926,13 @@ function VariantList({
|
|
|
1864
1926
|
},
|
|
1865
1927
|
disabled: isActioning === variant.id,
|
|
1866
1928
|
children: [
|
|
1867
|
-
/* @__PURE__ */
|
|
1929
|
+
/* @__PURE__ */ jsx15(Check3, { className: "mr-1 h-3 w-3" }),
|
|
1868
1930
|
"Accept"
|
|
1869
1931
|
]
|
|
1870
1932
|
}
|
|
1871
1933
|
),
|
|
1872
|
-
/* @__PURE__ */
|
|
1873
|
-
|
|
1934
|
+
/* @__PURE__ */ jsxs13(
|
|
1935
|
+
Button3,
|
|
1874
1936
|
{
|
|
1875
1937
|
variant: "outline",
|
|
1876
1938
|
size: "sm",
|
|
@@ -1881,14 +1943,14 @@ function VariantList({
|
|
|
1881
1943
|
},
|
|
1882
1944
|
disabled: isActioning === variant.id,
|
|
1883
1945
|
children: [
|
|
1884
|
-
/* @__PURE__ */
|
|
1946
|
+
/* @__PURE__ */ jsx15(X, { className: "mr-1 h-3 w-3" }),
|
|
1885
1947
|
"Reject"
|
|
1886
1948
|
]
|
|
1887
1949
|
}
|
|
1888
1950
|
)
|
|
1889
1951
|
] }),
|
|
1890
|
-
variant.detailsUrl && /* @__PURE__ */
|
|
1891
|
-
|
|
1952
|
+
variant.detailsUrl && /* @__PURE__ */ jsx15(
|
|
1953
|
+
Button3,
|
|
1892
1954
|
{
|
|
1893
1955
|
variant: "ghost",
|
|
1894
1956
|
size: "sm",
|
|
@@ -1897,13 +1959,13 @@ function VariantList({
|
|
|
1897
1959
|
e.stopPropagation();
|
|
1898
1960
|
window.open(variant.detailsUrl, "_blank");
|
|
1899
1961
|
},
|
|
1900
|
-
children: /* @__PURE__ */
|
|
1962
|
+
children: /* @__PURE__ */ jsx15(ExternalLink2, { className: "h-3.5 w-3.5" })
|
|
1901
1963
|
}
|
|
1902
1964
|
)
|
|
1903
1965
|
] })
|
|
1904
1966
|
] }),
|
|
1905
|
-
variant.error && /* @__PURE__ */
|
|
1906
|
-
variant.summary && /* @__PURE__ */
|
|
1967
|
+
variant.error && /* @__PURE__ */ jsx15("p", { className: "mt-1.5 text-xs text-[var(--surface-danger-text)]", children: variant.error }),
|
|
1968
|
+
variant.summary && /* @__PURE__ */ jsx15("p", { className: "mt-1.5 line-clamp-2 text-xs text-muted-foreground", children: variant.summary })
|
|
1907
1969
|
]
|
|
1908
1970
|
},
|
|
1909
1971
|
variant.id
|
|
@@ -1914,7 +1976,7 @@ function VariantList({
|
|
|
1914
1976
|
// src/dashboard/system-logs.tsx
|
|
1915
1977
|
import { Terminal as Terminal3 } from "lucide-react";
|
|
1916
1978
|
import { useEffect as useEffect2, useRef as useRef2, useState as useState4 } from "react";
|
|
1917
|
-
import { jsx as
|
|
1979
|
+
import { jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1918
1980
|
function SystemLogsViewer({ apiUrl, token, className }) {
|
|
1919
1981
|
const [logs, setLogs] = useState4([]);
|
|
1920
1982
|
const [error, setError] = useState4(null);
|
|
@@ -1967,18 +2029,18 @@ function SystemLogsViewer({ apiUrl, token, className }) {
|
|
|
1967
2029
|
const isAtBottom = scrollHeight - scrollTop - clientHeight < 20;
|
|
1968
2030
|
setIsFollowing((prev) => prev === isAtBottom ? prev : isAtBottom);
|
|
1969
2031
|
};
|
|
1970
|
-
return /* @__PURE__ */
|
|
1971
|
-
/* @__PURE__ */
|
|
1972
|
-
/* @__PURE__ */
|
|
1973
|
-
/* @__PURE__ */
|
|
1974
|
-
/* @__PURE__ */
|
|
2032
|
+
return /* @__PURE__ */ jsxs14("div", { className: cn("flex flex-col h-full bg-background text-foreground font-mono text-sm leading-relaxed overflow-hidden rounded-lg border border-border", className), children: [
|
|
2033
|
+
/* @__PURE__ */ jsxs14("div", { className: "flex-none flex items-center justify-between border-b border-border bg-muted/50 backdrop-blur-md px-4 py-2", children: [
|
|
2034
|
+
/* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-2", children: [
|
|
2035
|
+
/* @__PURE__ */ jsx16(Terminal3, { className: "h-4 w-4 text-primary animate-pulse" }),
|
|
2036
|
+
/* @__PURE__ */ jsx16("span", { className: "font-bold text-xs uppercase tracking-widest text-muted-foreground", children: "System Traces" })
|
|
1975
2037
|
] }),
|
|
1976
|
-
/* @__PURE__ */
|
|
1977
|
-
error && /* @__PURE__ */
|
|
1978
|
-
/* @__PURE__ */
|
|
2038
|
+
/* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-3", children: [
|
|
2039
|
+
error && /* @__PURE__ */ jsxs14("span", { className: "text-destructive text-xs flex items-center gap-1", children: [
|
|
2040
|
+
/* @__PURE__ */ jsx16("span", { className: "w-2 h-2 rounded-full bg-destructive animate-ping" }),
|
|
1979
2041
|
" Error fetching logs"
|
|
1980
2042
|
] }),
|
|
1981
|
-
/* @__PURE__ */
|
|
2043
|
+
/* @__PURE__ */ jsx16(
|
|
1982
2044
|
"button",
|
|
1983
2045
|
{
|
|
1984
2046
|
onClick: () => {
|
|
@@ -1993,29 +2055,29 @@ function SystemLogsViewer({ apiUrl, token, className }) {
|
|
|
1993
2055
|
)
|
|
1994
2056
|
] })
|
|
1995
2057
|
] }),
|
|
1996
|
-
/* @__PURE__ */
|
|
2058
|
+
/* @__PURE__ */ jsx16(
|
|
1997
2059
|
"div",
|
|
1998
2060
|
{
|
|
1999
2061
|
ref: scrollRef,
|
|
2000
2062
|
onScroll: handleScroll,
|
|
2001
2063
|
className: "flex-1 overflow-y-auto p-4 space-y-1",
|
|
2002
|
-
children: logs.length === 0 && !error ? /* @__PURE__ */
|
|
2003
|
-
/* @__PURE__ */
|
|
2064
|
+
children: logs.length === 0 && !error ? /* @__PURE__ */ jsx16("div", { className: "flex h-full items-center justify-center text-muted-foreground italic", children: "Waiting for orchestrator logs..." }) : logs.map((log, i) => /* @__PURE__ */ jsxs14("div", { className: "break-words", children: [
|
|
2065
|
+
/* @__PURE__ */ jsxs14("span", { className: "text-muted-foreground mr-3 select-none", children: [
|
|
2004
2066
|
"[",
|
|
2005
2067
|
log.timestamp || i.toString().padStart(4, "0"),
|
|
2006
2068
|
"]"
|
|
2007
2069
|
] }),
|
|
2008
|
-
/* @__PURE__ */
|
|
2070
|
+
/* @__PURE__ */ jsxs14("span", { className: "text-primary/70 mr-2", children: [
|
|
2009
2071
|
"[",
|
|
2010
2072
|
log.level,
|
|
2011
2073
|
"]"
|
|
2012
2074
|
] }),
|
|
2013
|
-
/* @__PURE__ */
|
|
2075
|
+
/* @__PURE__ */ jsxs14("span", { className: "text-muted-foreground mr-2", children: [
|
|
2014
2076
|
"[",
|
|
2015
2077
|
log.scope,
|
|
2016
2078
|
"]"
|
|
2017
2079
|
] }),
|
|
2018
|
-
/* @__PURE__ */
|
|
2080
|
+
/* @__PURE__ */ jsx16("span", { className: log.level.toUpperCase() === "ERROR" || log.message.toLowerCase().includes("failed") ? "text-destructive" : log.level.toUpperCase() === "WARN" ? "text-warning" : "text-foreground", children: log.message })
|
|
2019
2081
|
] }, `${log.timestamp}-${log.scope}-${i}`))
|
|
2020
2082
|
}
|
|
2021
2083
|
)
|
|
@@ -2026,50 +2088,50 @@ function SystemLogsViewer({ apiUrl, token, className }) {
|
|
|
2026
2088
|
import { Clock as Clock4, Layers, MessageSquare, DollarSign } from "lucide-react";
|
|
2027
2089
|
import { StatCard } from "@tangle-network/ui/primitives";
|
|
2028
2090
|
import { Skeleton as Skeleton2 } from "@tangle-network/ui/primitives";
|
|
2029
|
-
import { jsx as
|
|
2091
|
+
import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
2030
2092
|
function UsageSummary({ data, loading = false, className }) {
|
|
2031
2093
|
if (loading || !data) {
|
|
2032
|
-
return /* @__PURE__ */
|
|
2094
|
+
return /* @__PURE__ */ jsx17("div", { className: cn("grid grid-cols-2 gap-4 lg:grid-cols-4", className), children: Array.from({ length: 4 }).map((_, i) => /* @__PURE__ */ jsx17(Skeleton2, { className: "h-28 rounded-xl" }, i)) });
|
|
2033
2095
|
}
|
|
2034
|
-
return /* @__PURE__ */
|
|
2035
|
-
/* @__PURE__ */
|
|
2096
|
+
return /* @__PURE__ */ jsxs15("div", { className: cn("grid grid-cols-2 gap-4 lg:grid-cols-4", className), children: [
|
|
2097
|
+
/* @__PURE__ */ jsx17(
|
|
2036
2098
|
StatCard,
|
|
2037
2099
|
{
|
|
2038
2100
|
variant: "sandbox",
|
|
2039
2101
|
title: "Compute Hours",
|
|
2040
2102
|
value: data.computeHours.toFixed(1),
|
|
2041
2103
|
subtitle: "This billing period",
|
|
2042
|
-
icon: /* @__PURE__ */
|
|
2104
|
+
icon: /* @__PURE__ */ jsx17(Clock4, { className: "h-5 w-5" })
|
|
2043
2105
|
}
|
|
2044
2106
|
),
|
|
2045
|
-
/* @__PURE__ */
|
|
2107
|
+
/* @__PURE__ */ jsx17(
|
|
2046
2108
|
StatCard,
|
|
2047
2109
|
{
|
|
2048
2110
|
variant: "sandbox",
|
|
2049
2111
|
title: "Active Sessions",
|
|
2050
2112
|
value: data.activeSessions,
|
|
2051
2113
|
subtitle: "Currently running",
|
|
2052
|
-
icon: /* @__PURE__ */
|
|
2114
|
+
icon: /* @__PURE__ */ jsx17(Layers, { className: "h-5 w-5" })
|
|
2053
2115
|
}
|
|
2054
2116
|
),
|
|
2055
|
-
/* @__PURE__ */
|
|
2117
|
+
/* @__PURE__ */ jsx17(
|
|
2056
2118
|
StatCard,
|
|
2057
2119
|
{
|
|
2058
2120
|
variant: "sandbox",
|
|
2059
2121
|
title: "Messages Sent",
|
|
2060
2122
|
value: data.messagesSent.toLocaleString(),
|
|
2061
2123
|
subtitle: "Agent interactions",
|
|
2062
|
-
icon: /* @__PURE__ */
|
|
2124
|
+
icon: /* @__PURE__ */ jsx17(MessageSquare, { className: "h-5 w-5" })
|
|
2063
2125
|
}
|
|
2064
2126
|
),
|
|
2065
|
-
/* @__PURE__ */
|
|
2127
|
+
/* @__PURE__ */ jsx17(
|
|
2066
2128
|
StatCard,
|
|
2067
2129
|
{
|
|
2068
2130
|
variant: "sandbox",
|
|
2069
2131
|
title: "Estimated Cost",
|
|
2070
2132
|
value: `$${data.estimatedCost.toFixed(2)}`,
|
|
2071
2133
|
subtitle: "This billing period",
|
|
2072
|
-
icon: /* @__PURE__ */
|
|
2134
|
+
icon: /* @__PURE__ */ jsx17(DollarSign, { className: "h-5 w-5" })
|
|
2073
2135
|
}
|
|
2074
2136
|
)
|
|
2075
2137
|
] });
|
|
@@ -2077,66 +2139,66 @@ function UsageSummary({ data, loading = false, className }) {
|
|
|
2077
2139
|
|
|
2078
2140
|
// src/dashboard/git-panel.tsx
|
|
2079
2141
|
import { GitBranch, GitCommit, FileEdit, FilePlus, File } from "lucide-react";
|
|
2080
|
-
import { jsx as
|
|
2142
|
+
import { jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
2081
2143
|
function GitPanel({ status, log, loading = false, onRefresh, className }) {
|
|
2082
2144
|
if (loading) {
|
|
2083
|
-
return /* @__PURE__ */
|
|
2084
|
-
/* @__PURE__ */
|
|
2145
|
+
return /* @__PURE__ */ jsx18("div", { className: cn("rounded-lg border border-border bg-card p-5", className), children: /* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [
|
|
2146
|
+
/* @__PURE__ */ jsx18("div", { className: "h-4 w-4 animate-spin rounded-full border-2 border-primary border-t-transparent" }),
|
|
2085
2147
|
"Loading git info..."
|
|
2086
2148
|
] }) });
|
|
2087
2149
|
}
|
|
2088
2150
|
if (!status) {
|
|
2089
|
-
return /* @__PURE__ */
|
|
2090
|
-
/* @__PURE__ */
|
|
2151
|
+
return /* @__PURE__ */ jsx18("div", { className: cn("rounded-lg border border-border bg-card p-5", className), children: /* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [
|
|
2152
|
+
/* @__PURE__ */ jsx18(GitBranch, { className: "h-4 w-4" }),
|
|
2091
2153
|
"No git repository detected"
|
|
2092
2154
|
] }) });
|
|
2093
2155
|
}
|
|
2094
2156
|
const changedCount = status.staged.length + status.modified.length + status.untracked.length;
|
|
2095
|
-
return /* @__PURE__ */
|
|
2096
|
-
/* @__PURE__ */
|
|
2097
|
-
/* @__PURE__ */
|
|
2098
|
-
/* @__PURE__ */
|
|
2099
|
-
/* @__PURE__ */
|
|
2100
|
-
status.isDirty && /* @__PURE__ */
|
|
2157
|
+
return /* @__PURE__ */ jsxs16("div", { className: cn("rounded-lg border border-border bg-card overflow-hidden", className), children: [
|
|
2158
|
+
/* @__PURE__ */ jsxs16("div", { className: "flex items-center justify-between border-b border-border bg-muted/30 px-4 py-3", children: [
|
|
2159
|
+
/* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-2", children: [
|
|
2160
|
+
/* @__PURE__ */ jsx18(GitBranch, { className: "h-4 w-4 text-primary" }),
|
|
2161
|
+
/* @__PURE__ */ jsx18("span", { className: "text-sm font-bold text-foreground", children: status.branch }),
|
|
2162
|
+
status.isDirty && /* @__PURE__ */ jsxs16("span", { className: "rounded-full bg-[var(--surface-warning-bg)] px-1.5 py-0.5 text-[10px] font-bold text-[var(--surface-warning-text)]", children: [
|
|
2101
2163
|
changedCount,
|
|
2102
2164
|
" change",
|
|
2103
2165
|
changedCount !== 1 ? "s" : ""
|
|
2104
2166
|
] })
|
|
2105
2167
|
] }),
|
|
2106
|
-
onRefresh && /* @__PURE__ */
|
|
2168
|
+
onRefresh && /* @__PURE__ */ jsx18("button", { type: "button", onClick: onRefresh, className: "text-xs text-muted-foreground hover:text-foreground transition-colors", children: "Refresh" })
|
|
2107
2169
|
] }),
|
|
2108
|
-
changedCount > 0 && /* @__PURE__ */
|
|
2109
|
-
status.staged.map((f) => /* @__PURE__ */
|
|
2110
|
-
/* @__PURE__ */
|
|
2111
|
-
/* @__PURE__ */
|
|
2112
|
-
/* @__PURE__ */
|
|
2170
|
+
changedCount > 0 && /* @__PURE__ */ jsx18("div", { className: "border-b border-border px-4 py-3", children: /* @__PURE__ */ jsxs16("div", { className: "space-y-1.5", children: [
|
|
2171
|
+
status.staged.map((f) => /* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-2 text-xs", children: [
|
|
2172
|
+
/* @__PURE__ */ jsx18(FilePlus, { className: "h-3 w-3 text-[var(--surface-success-text)]" }),
|
|
2173
|
+
/* @__PURE__ */ jsx18("span", { className: "font-mono text-foreground truncate", children: f }),
|
|
2174
|
+
/* @__PURE__ */ jsx18("span", { className: "text-[var(--surface-success-text)] text-[10px] font-bold ml-auto", children: "STAGED" })
|
|
2113
2175
|
] }, `s-${f}`)),
|
|
2114
|
-
status.modified.map((f) => /* @__PURE__ */
|
|
2115
|
-
/* @__PURE__ */
|
|
2116
|
-
/* @__PURE__ */
|
|
2176
|
+
status.modified.map((f) => /* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-2 text-xs", children: [
|
|
2177
|
+
/* @__PURE__ */ jsx18(FileEdit, { className: "h-3 w-3 text-[var(--surface-warning-text)]" }),
|
|
2178
|
+
/* @__PURE__ */ jsx18("span", { className: "font-mono text-foreground truncate", children: f })
|
|
2117
2179
|
] }, `m-${f}`)),
|
|
2118
|
-
status.untracked.map((f) => /* @__PURE__ */
|
|
2119
|
-
/* @__PURE__ */
|
|
2120
|
-
/* @__PURE__ */
|
|
2180
|
+
status.untracked.map((f) => /* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-2 text-xs", children: [
|
|
2181
|
+
/* @__PURE__ */ jsx18(File, { className: "h-3 w-3 text-muted-foreground" }),
|
|
2182
|
+
/* @__PURE__ */ jsx18("span", { className: "font-mono text-muted-foreground truncate", children: f })
|
|
2121
2183
|
] }, `u-${f}`))
|
|
2122
2184
|
] }) }),
|
|
2123
|
-
log.length > 0 && /* @__PURE__ */
|
|
2124
|
-
/* @__PURE__ */
|
|
2125
|
-
/* @__PURE__ */
|
|
2126
|
-
/* @__PURE__ */
|
|
2127
|
-
/* @__PURE__ */
|
|
2128
|
-
/* @__PURE__ */
|
|
2129
|
-
/* @__PURE__ */
|
|
2185
|
+
log.length > 0 && /* @__PURE__ */ jsxs16("div", { className: "px-4 py-3", children: [
|
|
2186
|
+
/* @__PURE__ */ jsx18("div", { className: "mb-2 text-[10px] font-bold uppercase tracking-widest text-muted-foreground", children: "Recent Commits" }),
|
|
2187
|
+
/* @__PURE__ */ jsx18("div", { className: "space-y-2", children: log.slice(0, 5).map((commit) => /* @__PURE__ */ jsxs16("div", { className: "flex items-start gap-2 text-xs", children: [
|
|
2188
|
+
/* @__PURE__ */ jsx18(GitCommit, { className: "h-3 w-3 text-muted-foreground mt-0.5 shrink-0" }),
|
|
2189
|
+
/* @__PURE__ */ jsxs16("div", { className: "min-w-0", children: [
|
|
2190
|
+
/* @__PURE__ */ jsx18("span", { className: "font-mono text-primary mr-1.5", children: commit.shortSha }),
|
|
2191
|
+
/* @__PURE__ */ jsx18("span", { className: "text-foreground", children: commit.message })
|
|
2130
2192
|
] })
|
|
2131
2193
|
] }, commit.shortSha)) })
|
|
2132
2194
|
] }),
|
|
2133
|
-
(status.ahead > 0 || status.behind > 0) && /* @__PURE__ */
|
|
2134
|
-
status.ahead > 0 && /* @__PURE__ */
|
|
2195
|
+
(status.ahead > 0 || status.behind > 0) && /* @__PURE__ */ jsxs16("div", { className: "border-t border-border px-4 py-2 flex items-center gap-3 text-xs text-muted-foreground", children: [
|
|
2196
|
+
status.ahead > 0 && /* @__PURE__ */ jsxs16("span", { children: [
|
|
2135
2197
|
"\u2191 ",
|
|
2136
2198
|
status.ahead,
|
|
2137
2199
|
" ahead"
|
|
2138
2200
|
] }),
|
|
2139
|
-
status.behind > 0 && /* @__PURE__ */
|
|
2201
|
+
status.behind > 0 && /* @__PURE__ */ jsxs16("span", { children: [
|
|
2140
2202
|
"\u2193 ",
|
|
2141
2203
|
status.behind,
|
|
2142
2204
|
" behind"
|
|
@@ -2148,7 +2210,7 @@ function GitPanel({ status, log, loading = false, onRefresh, className }) {
|
|
|
2148
2210
|
// src/dashboard/ports-list.tsx
|
|
2149
2211
|
import * as React6 from "react";
|
|
2150
2212
|
import { Copy as Copy3, Check as Check4, Globe, Plus as Plus4, Trash2 as Trash23 } from "lucide-react";
|
|
2151
|
-
import { jsx as
|
|
2213
|
+
import { jsx as jsx19, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
2152
2214
|
function PortsList({ ports, onExposePort, onRemovePort, isExposing = false, className }) {
|
|
2153
2215
|
const [newPort, setNewPort] = React6.useState("");
|
|
2154
2216
|
const [copiedPort, setCopiedPort] = React6.useState(null);
|
|
@@ -2175,48 +2237,48 @@ function PortsList({ ports, onExposePort, onRemovePort, isExposing = false, clas
|
|
|
2175
2237
|
setNewPort("");
|
|
2176
2238
|
}
|
|
2177
2239
|
};
|
|
2178
|
-
return /* @__PURE__ */
|
|
2179
|
-
ports.length > 0 ? /* @__PURE__ */
|
|
2180
|
-
/* @__PURE__ */
|
|
2181
|
-
/* @__PURE__ */
|
|
2182
|
-
/* @__PURE__ */
|
|
2183
|
-
/* @__PURE__ */
|
|
2184
|
-
/* @__PURE__ */
|
|
2240
|
+
return /* @__PURE__ */ jsxs17("div", { className: cn("space-y-4", className), children: [
|
|
2241
|
+
ports.length > 0 ? /* @__PURE__ */ jsx19("div", { className: "rounded-lg border border-border overflow-hidden", children: /* @__PURE__ */ jsxs17("table", { className: "w-full text-sm", children: [
|
|
2242
|
+
/* @__PURE__ */ jsx19("thead", { className: "bg-muted/30 border-b border-border", children: /* @__PURE__ */ jsxs17("tr", { children: [
|
|
2243
|
+
/* @__PURE__ */ jsx19("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "Port" }),
|
|
2244
|
+
/* @__PURE__ */ jsx19("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "Public URL" }),
|
|
2245
|
+
/* @__PURE__ */ jsx19("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "Status" }),
|
|
2246
|
+
/* @__PURE__ */ jsx19("th", { className: "px-4 py-2.5 text-right text-xs font-medium text-muted-foreground w-20" })
|
|
2185
2247
|
] }) }),
|
|
2186
|
-
/* @__PURE__ */
|
|
2187
|
-
/* @__PURE__ */
|
|
2188
|
-
/* @__PURE__ */
|
|
2248
|
+
/* @__PURE__ */ jsx19("tbody", { className: "divide-y divide-border", children: ports.map((p) => /* @__PURE__ */ jsxs17("tr", { children: [
|
|
2249
|
+
/* @__PURE__ */ jsx19("td", { className: "px-4 py-3 font-mono text-xs text-foreground", children: p.port }),
|
|
2250
|
+
/* @__PURE__ */ jsx19("td", { className: "px-4 py-3", children: /* @__PURE__ */ jsxs17(
|
|
2189
2251
|
"button",
|
|
2190
2252
|
{
|
|
2191
2253
|
type: "button",
|
|
2192
2254
|
onClick: () => handleCopy(p.url, p.port),
|
|
2193
2255
|
className: "flex items-center gap-2 font-mono text-xs text-primary hover:underline cursor-pointer group",
|
|
2194
2256
|
children: [
|
|
2195
|
-
/* @__PURE__ */
|
|
2196
|
-
copiedPort === p.port ? /* @__PURE__ */
|
|
2257
|
+
/* @__PURE__ */ jsx19("span", { className: "truncate max-w-[300px]", children: p.url }),
|
|
2258
|
+
copiedPort === p.port ? /* @__PURE__ */ jsx19(Check4, { className: "h-3 w-3 text-[var(--surface-success-text)] shrink-0" }) : /* @__PURE__ */ jsx19(Copy3, { className: "h-3 w-3 opacity-0 group-hover:opacity-100 transition-opacity shrink-0" })
|
|
2197
2259
|
]
|
|
2198
2260
|
}
|
|
2199
2261
|
) }),
|
|
2200
|
-
/* @__PURE__ */
|
|
2262
|
+
/* @__PURE__ */ jsx19("td", { className: "px-4 py-3", children: /* @__PURE__ */ jsx19("span", { className: cn(
|
|
2201
2263
|
"inline-flex items-center gap-1.5 rounded-full px-2 py-0.5 text-[10px] font-bold uppercase tracking-wider",
|
|
2202
2264
|
p.status === "active" ? "bg-[var(--surface-success-bg)] text-[var(--surface-success-text)]" : "bg-[var(--surface-warning-bg)] text-[var(--surface-warning-text)]"
|
|
2203
2265
|
), children: p.status }) }),
|
|
2204
|
-
/* @__PURE__ */
|
|
2266
|
+
/* @__PURE__ */ jsx19("td", { className: "px-4 py-3 text-right", children: onRemovePort && /* @__PURE__ */ jsx19(
|
|
2205
2267
|
"button",
|
|
2206
2268
|
{
|
|
2207
2269
|
type: "button",
|
|
2208
2270
|
onClick: () => onRemovePort(p.port),
|
|
2209
2271
|
className: "p-1 text-muted-foreground hover:text-destructive transition-colors rounded",
|
|
2210
|
-
children: /* @__PURE__ */
|
|
2272
|
+
children: /* @__PURE__ */ jsx19(Trash23, { className: "h-3.5 w-3.5" })
|
|
2211
2273
|
}
|
|
2212
2274
|
) })
|
|
2213
2275
|
] }, p.port)) })
|
|
2214
|
-
] }) }) : /* @__PURE__ */
|
|
2215
|
-
/* @__PURE__ */
|
|
2216
|
-
/* @__PURE__ */
|
|
2276
|
+
] }) }) : /* @__PURE__ */ jsxs17("div", { className: "rounded-lg border border-border bg-muted/20 p-6 text-center", children: [
|
|
2277
|
+
/* @__PURE__ */ jsx19(Globe, { className: "mx-auto h-8 w-8 text-muted-foreground mb-2" }),
|
|
2278
|
+
/* @__PURE__ */ jsx19("p", { className: "text-sm text-muted-foreground", children: "No ports exposed yet" })
|
|
2217
2279
|
] }),
|
|
2218
|
-
/* @__PURE__ */
|
|
2219
|
-
/* @__PURE__ */
|
|
2280
|
+
/* @__PURE__ */ jsxs17("div", { className: "flex items-center gap-3", children: [
|
|
2281
|
+
/* @__PURE__ */ jsx19(
|
|
2220
2282
|
"input",
|
|
2221
2283
|
{
|
|
2222
2284
|
type: "number",
|
|
@@ -2229,7 +2291,7 @@ function PortsList({ ports, onExposePort, onRemovePort, isExposing = false, clas
|
|
|
2229
2291
|
className: "flex-1 rounded-lg border border-border bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring"
|
|
2230
2292
|
}
|
|
2231
2293
|
),
|
|
2232
|
-
/* @__PURE__ */
|
|
2294
|
+
/* @__PURE__ */ jsxs17(
|
|
2233
2295
|
"button",
|
|
2234
2296
|
{
|
|
2235
2297
|
type: "button",
|
|
@@ -2237,7 +2299,7 @@ function PortsList({ ports, onExposePort, onRemovePort, isExposing = false, clas
|
|
|
2237
2299
|
disabled: !newPort || isExposing,
|
|
2238
2300
|
className: "inline-flex items-center gap-2 rounded-lg bg-primary/20 border border-primary/30 px-4 py-2 text-sm font-medium text-primary hover:bg-primary hover:text-primary-foreground transition-colors disabled:opacity-50",
|
|
2239
2301
|
children: [
|
|
2240
|
-
/* @__PURE__ */
|
|
2302
|
+
/* @__PURE__ */ jsx19(Plus4, { className: "h-4 w-4" }),
|
|
2241
2303
|
"Expose"
|
|
2242
2304
|
]
|
|
2243
2305
|
}
|
|
@@ -2249,7 +2311,7 @@ function PortsList({ ports, onExposePort, onRemovePort, isExposing = false, clas
|
|
|
2249
2311
|
// src/dashboard/process-list.tsx
|
|
2250
2312
|
import * as React7 from "react";
|
|
2251
2313
|
import { Activity as Activity3, Plus as Plus5, Skull, Terminal as Terminal4 } from "lucide-react";
|
|
2252
|
-
import { jsx as
|
|
2314
|
+
import { jsx as jsx20, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
2253
2315
|
function formatUptime(startedAt) {
|
|
2254
2316
|
if (!startedAt) return "-";
|
|
2255
2317
|
const ms = Date.now() - new Date(startedAt).getTime();
|
|
@@ -2267,43 +2329,43 @@ function ProcessList({ processes, onSpawn, onKill, loading = false, className })
|
|
|
2267
2329
|
setNewCommand("");
|
|
2268
2330
|
}
|
|
2269
2331
|
};
|
|
2270
|
-
return /* @__PURE__ */
|
|
2271
|
-
loading ? /* @__PURE__ */
|
|
2272
|
-
/* @__PURE__ */
|
|
2273
|
-
/* @__PURE__ */
|
|
2274
|
-
] }) : processes.length > 0 ? /* @__PURE__ */
|
|
2275
|
-
/* @__PURE__ */
|
|
2276
|
-
/* @__PURE__ */
|
|
2277
|
-
/* @__PURE__ */
|
|
2278
|
-
/* @__PURE__ */
|
|
2279
|
-
/* @__PURE__ */
|
|
2280
|
-
/* @__PURE__ */
|
|
2332
|
+
return /* @__PURE__ */ jsxs18("div", { className: cn("space-y-4", className), children: [
|
|
2333
|
+
loading ? /* @__PURE__ */ jsxs18("div", { className: "rounded-lg border border-border bg-muted/20 p-6 text-center", children: [
|
|
2334
|
+
/* @__PURE__ */ jsx20(Activity3, { className: "mx-auto h-6 w-6 text-muted-foreground animate-spin mb-2" }),
|
|
2335
|
+
/* @__PURE__ */ jsx20("p", { className: "text-sm text-muted-foreground", children: "Loading processes..." })
|
|
2336
|
+
] }) : processes.length > 0 ? /* @__PURE__ */ jsx20("div", { className: "rounded-lg border border-border overflow-hidden", children: /* @__PURE__ */ jsxs18("table", { className: "w-full text-sm", children: [
|
|
2337
|
+
/* @__PURE__ */ jsx20("thead", { className: "bg-muted/30 border-b border-border", children: /* @__PURE__ */ jsxs18("tr", { children: [
|
|
2338
|
+
/* @__PURE__ */ jsx20("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "PID" }),
|
|
2339
|
+
/* @__PURE__ */ jsx20("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "Command" }),
|
|
2340
|
+
/* @__PURE__ */ jsx20("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "Status" }),
|
|
2341
|
+
/* @__PURE__ */ jsx20("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "Uptime" }),
|
|
2342
|
+
/* @__PURE__ */ jsx20("th", { className: "px-4 py-2.5 text-right text-xs font-medium text-muted-foreground w-20" })
|
|
2281
2343
|
] }) }),
|
|
2282
|
-
/* @__PURE__ */
|
|
2283
|
-
/* @__PURE__ */
|
|
2284
|
-
/* @__PURE__ */
|
|
2285
|
-
/* @__PURE__ */
|
|
2344
|
+
/* @__PURE__ */ jsx20("tbody", { className: "divide-y divide-border", children: processes.map((p) => /* @__PURE__ */ jsxs18("tr", { children: [
|
|
2345
|
+
/* @__PURE__ */ jsx20("td", { className: "px-4 py-3 font-mono text-xs text-foreground", children: p.pid }),
|
|
2346
|
+
/* @__PURE__ */ jsx20("td", { className: "px-4 py-3 font-mono text-xs text-foreground truncate max-w-[250px]", children: p.command }),
|
|
2347
|
+
/* @__PURE__ */ jsx20("td", { className: "px-4 py-3", children: /* @__PURE__ */ jsx20("span", { className: cn(
|
|
2286
2348
|
"inline-flex items-center gap-1.5 rounded-full px-2 py-0.5 text-[10px] font-bold uppercase tracking-wider",
|
|
2287
2349
|
p.running ? "bg-[var(--surface-success-bg)] text-[var(--surface-success-text)]" : "bg-muted text-muted-foreground"
|
|
2288
2350
|
), children: p.running ? "running" : `exited (${p.exitCode ?? "?"})` }) }),
|
|
2289
|
-
/* @__PURE__ */
|
|
2290
|
-
/* @__PURE__ */
|
|
2351
|
+
/* @__PURE__ */ jsx20("td", { className: "px-4 py-3 font-mono text-xs text-muted-foreground", children: formatUptime(p.startedAt) }),
|
|
2352
|
+
/* @__PURE__ */ jsx20("td", { className: "px-4 py-3 text-right", children: p.running && /* @__PURE__ */ jsx20(
|
|
2291
2353
|
"button",
|
|
2292
2354
|
{
|
|
2293
2355
|
type: "button",
|
|
2294
2356
|
onClick: () => onKill(p.pid),
|
|
2295
2357
|
className: "p-1 text-muted-foreground hover:text-destructive transition-colors rounded",
|
|
2296
2358
|
title: "Kill process",
|
|
2297
|
-
children: /* @__PURE__ */
|
|
2359
|
+
children: /* @__PURE__ */ jsx20(Skull, { className: "h-3.5 w-3.5" })
|
|
2298
2360
|
}
|
|
2299
2361
|
) })
|
|
2300
2362
|
] }, `${p.pid}-${p.startedAt ?? p.command}`)) })
|
|
2301
|
-
] }) }) : /* @__PURE__ */
|
|
2302
|
-
/* @__PURE__ */
|
|
2303
|
-
/* @__PURE__ */
|
|
2363
|
+
] }) }) : /* @__PURE__ */ jsxs18("div", { className: "rounded-lg border border-border bg-muted/20 p-6 text-center", children: [
|
|
2364
|
+
/* @__PURE__ */ jsx20(Terminal4, { className: "mx-auto h-8 w-8 text-muted-foreground mb-2" }),
|
|
2365
|
+
/* @__PURE__ */ jsx20("p", { className: "text-sm text-muted-foreground", children: "No processes running" })
|
|
2304
2366
|
] }),
|
|
2305
|
-
/* @__PURE__ */
|
|
2306
|
-
/* @__PURE__ */
|
|
2367
|
+
/* @__PURE__ */ jsxs18("div", { className: "flex items-center gap-3", children: [
|
|
2368
|
+
/* @__PURE__ */ jsx20(
|
|
2307
2369
|
"input",
|
|
2308
2370
|
{
|
|
2309
2371
|
type: "text",
|
|
@@ -2314,7 +2376,7 @@ function ProcessList({ processes, onSpawn, onKill, loading = false, className })
|
|
|
2314
2376
|
className: "flex-1 rounded-lg border border-border bg-background px-3 py-2 text-sm font-mono text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring"
|
|
2315
2377
|
}
|
|
2316
2378
|
),
|
|
2317
|
-
/* @__PURE__ */
|
|
2379
|
+
/* @__PURE__ */ jsxs18(
|
|
2318
2380
|
"button",
|
|
2319
2381
|
{
|
|
2320
2382
|
type: "button",
|
|
@@ -2322,7 +2384,7 @@ function ProcessList({ processes, onSpawn, onKill, loading = false, className })
|
|
|
2322
2384
|
disabled: !newCommand.trim(),
|
|
2323
2385
|
className: "inline-flex items-center gap-2 rounded-lg bg-primary/20 border border-primary/30 px-4 py-2 text-sm font-medium text-primary hover:bg-primary hover:text-primary-foreground transition-colors disabled:opacity-50",
|
|
2324
2386
|
children: [
|
|
2325
|
-
/* @__PURE__ */
|
|
2387
|
+
/* @__PURE__ */ jsx20(Plus5, { className: "h-4 w-4" }),
|
|
2326
2388
|
"Spawn"
|
|
2327
2389
|
]
|
|
2328
2390
|
}
|
|
@@ -2334,7 +2396,7 @@ function ProcessList({ processes, onSpawn, onKill, loading = false, className })
|
|
|
2334
2396
|
// src/dashboard/network-config.tsx
|
|
2335
2397
|
import * as React8 from "react";
|
|
2336
2398
|
import { Network as Network2, Plus as Plus6, Trash2 as Trash24, ShieldAlert } from "lucide-react";
|
|
2337
|
-
import { jsx as
|
|
2399
|
+
import { jsx as jsx21, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
2338
2400
|
function NetworkConfig({ config, onUpdate, loading = false, className }) {
|
|
2339
2401
|
const [newCidr, setNewCidr] = React8.useState("");
|
|
2340
2402
|
const isValidCidr = (value) => {
|
|
@@ -2357,21 +2419,21 @@ function NetworkConfig({ config, onUpdate, loading = false, className }) {
|
|
|
2357
2419
|
}
|
|
2358
2420
|
};
|
|
2359
2421
|
if (loading || !config) {
|
|
2360
|
-
return /* @__PURE__ */
|
|
2361
|
-
/* @__PURE__ */
|
|
2362
|
-
/* @__PURE__ */
|
|
2422
|
+
return /* @__PURE__ */ jsxs19("div", { className: cn("rounded-lg border border-border bg-muted/20 p-6 text-center", className), children: [
|
|
2423
|
+
/* @__PURE__ */ jsx21(Network2, { className: "mx-auto h-6 w-6 text-muted-foreground animate-pulse mb-2" }),
|
|
2424
|
+
/* @__PURE__ */ jsx21("p", { className: "text-sm text-muted-foreground", children: "Loading network configuration..." })
|
|
2363
2425
|
] });
|
|
2364
2426
|
}
|
|
2365
|
-
return /* @__PURE__ */
|
|
2366
|
-
/* @__PURE__ */
|
|
2367
|
-
/* @__PURE__ */
|
|
2368
|
-
/* @__PURE__ */
|
|
2369
|
-
/* @__PURE__ */
|
|
2370
|
-
/* @__PURE__ */
|
|
2371
|
-
/* @__PURE__ */
|
|
2427
|
+
return /* @__PURE__ */ jsxs19("div", { className: cn("space-y-4", className), children: [
|
|
2428
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex items-center justify-between rounded-lg border border-border bg-card px-4 py-3", children: [
|
|
2429
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex items-center gap-3", children: [
|
|
2430
|
+
/* @__PURE__ */ jsx21(ShieldAlert, { className: "h-4 w-4 text-muted-foreground" }),
|
|
2431
|
+
/* @__PURE__ */ jsxs19("div", { children: [
|
|
2432
|
+
/* @__PURE__ */ jsx21("p", { className: "text-sm font-medium text-foreground", children: "Block Outbound Traffic" }),
|
|
2433
|
+
/* @__PURE__ */ jsx21("p", { className: "text-xs text-muted-foreground", children: "Prevent the sandbox from making external network requests" })
|
|
2372
2434
|
] })
|
|
2373
2435
|
] }),
|
|
2374
|
-
/* @__PURE__ */
|
|
2436
|
+
/* @__PURE__ */ jsx21(
|
|
2375
2437
|
"button",
|
|
2376
2438
|
{
|
|
2377
2439
|
type: "button",
|
|
@@ -2383,7 +2445,7 @@ function NetworkConfig({ config, onUpdate, loading = false, className }) {
|
|
|
2383
2445
|
"relative inline-flex h-6 w-11 items-center rounded-full transition-colors",
|
|
2384
2446
|
config.blockOutbound ? "bg-destructive" : "bg-muted"
|
|
2385
2447
|
),
|
|
2386
|
-
children: /* @__PURE__ */
|
|
2448
|
+
children: /* @__PURE__ */ jsx21(
|
|
2387
2449
|
"span",
|
|
2388
2450
|
{
|
|
2389
2451
|
className: cn(
|
|
@@ -2395,22 +2457,22 @@ function NetworkConfig({ config, onUpdate, loading = false, className }) {
|
|
|
2395
2457
|
}
|
|
2396
2458
|
)
|
|
2397
2459
|
] }),
|
|
2398
|
-
/* @__PURE__ */
|
|
2399
|
-
/* @__PURE__ */
|
|
2400
|
-
config.allowList.length > 0 ? /* @__PURE__ */
|
|
2401
|
-
/* @__PURE__ */
|
|
2402
|
-
/* @__PURE__ */
|
|
2460
|
+
/* @__PURE__ */ jsxs19("div", { children: [
|
|
2461
|
+
/* @__PURE__ */ jsx21("h4", { className: "text-xs font-medium text-muted-foreground mb-2 uppercase tracking-wider", children: "Allowlist (CIDR)" }),
|
|
2462
|
+
config.allowList.length > 0 ? /* @__PURE__ */ jsx21("div", { className: "space-y-1.5 mb-3", children: config.allowList.map((cidr) => /* @__PURE__ */ jsxs19("div", { className: "flex items-center justify-between rounded border border-border bg-muted/20 px-3 py-2", children: [
|
|
2463
|
+
/* @__PURE__ */ jsx21("span", { className: "font-mono text-xs text-foreground", children: cidr }),
|
|
2464
|
+
/* @__PURE__ */ jsx21(
|
|
2403
2465
|
"button",
|
|
2404
2466
|
{
|
|
2405
2467
|
type: "button",
|
|
2406
2468
|
onClick: () => handleRemoveCidr(cidr),
|
|
2407
2469
|
className: "p-1 text-muted-foreground hover:text-destructive transition-colors rounded",
|
|
2408
|
-
children: /* @__PURE__ */
|
|
2470
|
+
children: /* @__PURE__ */ jsx21(Trash24, { className: "h-3 w-3" })
|
|
2409
2471
|
}
|
|
2410
2472
|
)
|
|
2411
|
-
] }, cidr)) }) : /* @__PURE__ */
|
|
2412
|
-
/* @__PURE__ */
|
|
2413
|
-
/* @__PURE__ */
|
|
2473
|
+
] }, cidr)) }) : /* @__PURE__ */ jsx21("p", { className: "text-xs text-muted-foreground mb-3", children: "No CIDR rules configured. All traffic is allowed." }),
|
|
2474
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex items-center gap-3", children: [
|
|
2475
|
+
/* @__PURE__ */ jsx21(
|
|
2414
2476
|
"input",
|
|
2415
2477
|
{
|
|
2416
2478
|
type: "text",
|
|
@@ -2421,7 +2483,7 @@ function NetworkConfig({ config, onUpdate, loading = false, className }) {
|
|
|
2421
2483
|
className: "flex-1 rounded-lg border border-border bg-background px-3 py-2 text-sm font-mono text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring"
|
|
2422
2484
|
}
|
|
2423
2485
|
),
|
|
2424
|
-
/* @__PURE__ */
|
|
2486
|
+
/* @__PURE__ */ jsxs19(
|
|
2425
2487
|
"button",
|
|
2426
2488
|
{
|
|
2427
2489
|
type: "button",
|
|
@@ -2429,7 +2491,7 @@ function NetworkConfig({ config, onUpdate, loading = false, className }) {
|
|
|
2429
2491
|
disabled: !newCidr.trim(),
|
|
2430
2492
|
className: "inline-flex items-center gap-2 rounded-lg bg-primary/20 border border-primary/30 px-4 py-2 text-sm font-medium text-primary hover:bg-primary hover:text-primary-foreground transition-colors disabled:opacity-50",
|
|
2431
2493
|
children: [
|
|
2432
|
-
/* @__PURE__ */
|
|
2494
|
+
/* @__PURE__ */ jsx21(Plus6, { className: "h-4 w-4" }),
|
|
2433
2495
|
"Add"
|
|
2434
2496
|
]
|
|
2435
2497
|
}
|
|
@@ -2442,7 +2504,7 @@ function NetworkConfig({ config, onUpdate, loading = false, className }) {
|
|
|
2442
2504
|
// src/dashboard/backend-config.tsx
|
|
2443
2505
|
import * as React9 from "react";
|
|
2444
2506
|
import { Bot, Plus as Plus7, RefreshCw as RefreshCw2, Trash2 as Trash25, Server, Wrench } from "lucide-react";
|
|
2445
|
-
import { Fragment as Fragment10, jsx as
|
|
2507
|
+
import { Fragment as Fragment10, jsx as jsx22, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
2446
2508
|
function BackendConfig({
|
|
2447
2509
|
status,
|
|
2448
2510
|
mcpServers,
|
|
@@ -2472,91 +2534,91 @@ function BackendConfig({
|
|
|
2472
2534
|
}
|
|
2473
2535
|
};
|
|
2474
2536
|
if (loading || !status) {
|
|
2475
|
-
return /* @__PURE__ */
|
|
2476
|
-
/* @__PURE__ */
|
|
2477
|
-
/* @__PURE__ */
|
|
2537
|
+
return /* @__PURE__ */ jsxs20("div", { className: cn("rounded-lg border border-border bg-muted/20 p-6 text-center", className), children: [
|
|
2538
|
+
/* @__PURE__ */ jsx22(Bot, { className: "mx-auto h-6 w-6 text-muted-foreground animate-pulse mb-2" }),
|
|
2539
|
+
/* @__PURE__ */ jsx22("p", { className: "text-sm text-muted-foreground", children: "Loading backend status..." })
|
|
2478
2540
|
] });
|
|
2479
2541
|
}
|
|
2480
|
-
return /* @__PURE__ */
|
|
2481
|
-
/* @__PURE__ */
|
|
2482
|
-
/* @__PURE__ */
|
|
2483
|
-
/* @__PURE__ */
|
|
2484
|
-
/* @__PURE__ */
|
|
2542
|
+
return /* @__PURE__ */ jsxs20("div", { className: cn("space-y-4", className), children: [
|
|
2543
|
+
/* @__PURE__ */ jsxs20("div", { className: "rounded-lg border border-border bg-card overflow-hidden", children: [
|
|
2544
|
+
/* @__PURE__ */ jsxs20("div", { className: "px-4 py-3 border-b border-border bg-muted/30 flex items-center justify-between", children: [
|
|
2545
|
+
/* @__PURE__ */ jsx22("h4", { className: "text-xs font-medium text-muted-foreground uppercase tracking-wider", children: "Agent Status" }),
|
|
2546
|
+
/* @__PURE__ */ jsxs20(
|
|
2485
2547
|
"button",
|
|
2486
2548
|
{
|
|
2487
2549
|
type: "button",
|
|
2488
2550
|
onClick: onRestart,
|
|
2489
2551
|
className: "inline-flex items-center gap-1.5 rounded-md bg-muted px-2.5 py-1 text-xs font-medium text-foreground hover:bg-muted/80 transition-colors border border-border",
|
|
2490
2552
|
children: [
|
|
2491
|
-
/* @__PURE__ */
|
|
2553
|
+
/* @__PURE__ */ jsx22(RefreshCw2, { className: "h-3 w-3" }),
|
|
2492
2554
|
"Restart"
|
|
2493
2555
|
]
|
|
2494
2556
|
}
|
|
2495
2557
|
)
|
|
2496
2558
|
] }),
|
|
2497
|
-
/* @__PURE__ */
|
|
2498
|
-
/* @__PURE__ */
|
|
2499
|
-
/* @__PURE__ */
|
|
2559
|
+
/* @__PURE__ */ jsx22("div", { className: "p-4", children: /* @__PURE__ */ jsxs20("dl", { className: "grid grid-cols-[100px_1fr] gap-y-3 text-sm", children: [
|
|
2560
|
+
/* @__PURE__ */ jsx22("dt", { className: "text-muted-foreground", children: "Status" }),
|
|
2561
|
+
/* @__PURE__ */ jsx22("dd", { children: /* @__PURE__ */ jsx22("span", { className: cn(
|
|
2500
2562
|
"inline-flex items-center gap-1.5 rounded-full px-2 py-0.5 text-[10px] font-bold uppercase tracking-wider",
|
|
2501
2563
|
status.running ? "bg-[var(--surface-success-bg)] text-[var(--surface-success-text)]" : "bg-destructive/10 text-destructive"
|
|
2502
2564
|
), children: status.running ? "Running" : "Stopped" }) }),
|
|
2503
|
-
/* @__PURE__ */
|
|
2504
|
-
/* @__PURE__ */
|
|
2505
|
-
status.provider && /* @__PURE__ */
|
|
2506
|
-
/* @__PURE__ */
|
|
2507
|
-
/* @__PURE__ */
|
|
2565
|
+
/* @__PURE__ */ jsx22("dt", { className: "text-muted-foreground", children: "Model" }),
|
|
2566
|
+
/* @__PURE__ */ jsx22("dd", { className: "font-mono text-xs", children: status.model ?? "Default" }),
|
|
2567
|
+
status.provider && /* @__PURE__ */ jsxs20(Fragment10, { children: [
|
|
2568
|
+
/* @__PURE__ */ jsx22("dt", { className: "text-muted-foreground", children: "Provider" }),
|
|
2569
|
+
/* @__PURE__ */ jsx22("dd", { className: "font-mono text-xs", children: status.provider })
|
|
2508
2570
|
] })
|
|
2509
2571
|
] }) })
|
|
2510
2572
|
] }),
|
|
2511
|
-
/* @__PURE__ */
|
|
2512
|
-
/* @__PURE__ */
|
|
2513
|
-
/* @__PURE__ */
|
|
2514
|
-
/* @__PURE__ */
|
|
2573
|
+
/* @__PURE__ */ jsxs20("div", { className: "rounded-lg border border-border bg-card overflow-hidden", children: [
|
|
2574
|
+
/* @__PURE__ */ jsxs20("div", { className: "px-4 py-3 border-b border-border bg-muted/30 flex items-center justify-between", children: [
|
|
2575
|
+
/* @__PURE__ */ jsxs20("h4", { className: "text-xs font-medium text-muted-foreground uppercase tracking-wider flex items-center gap-2", children: [
|
|
2576
|
+
/* @__PURE__ */ jsx22(Wrench, { className: "h-3.5 w-3.5" }),
|
|
2515
2577
|
"MCP Servers"
|
|
2516
2578
|
] }),
|
|
2517
|
-
/* @__PURE__ */
|
|
2579
|
+
/* @__PURE__ */ jsxs20(
|
|
2518
2580
|
"button",
|
|
2519
2581
|
{
|
|
2520
2582
|
type: "button",
|
|
2521
2583
|
onClick: () => setShowAddMcp(!showAddMcp),
|
|
2522
2584
|
className: "inline-flex items-center gap-1.5 rounded-md bg-primary/20 border border-primary/30 px-2.5 py-1 text-xs font-medium text-primary hover:bg-primary hover:text-primary-foreground transition-colors",
|
|
2523
2585
|
children: [
|
|
2524
|
-
/* @__PURE__ */
|
|
2586
|
+
/* @__PURE__ */ jsx22(Plus7, { className: "h-3 w-3" }),
|
|
2525
2587
|
"Add"
|
|
2526
2588
|
]
|
|
2527
2589
|
}
|
|
2528
2590
|
)
|
|
2529
2591
|
] }),
|
|
2530
|
-
mcpServers.length > 0 ? /* @__PURE__ */
|
|
2531
|
-
/* @__PURE__ */
|
|
2532
|
-
/* @__PURE__ */
|
|
2533
|
-
/* @__PURE__ */
|
|
2534
|
-
/* @__PURE__ */
|
|
2535
|
-
/* @__PURE__ */
|
|
2592
|
+
mcpServers.length > 0 ? /* @__PURE__ */ jsx22("div", { className: "divide-y divide-border", children: mcpServers.map((s) => /* @__PURE__ */ jsxs20("div", { className: "flex items-center justify-between px-4 py-3", children: [
|
|
2593
|
+
/* @__PURE__ */ jsxs20("div", { className: "flex items-center gap-3 min-w-0", children: [
|
|
2594
|
+
/* @__PURE__ */ jsx22(Server, { className: "h-3.5 w-3.5 text-muted-foreground shrink-0" }),
|
|
2595
|
+
/* @__PURE__ */ jsxs20("div", { className: "min-w-0", children: [
|
|
2596
|
+
/* @__PURE__ */ jsx22("p", { className: "text-sm font-medium text-foreground truncate", children: s.name }),
|
|
2597
|
+
/* @__PURE__ */ jsxs20("p", { className: "text-xs font-mono text-muted-foreground truncate", children: [
|
|
2536
2598
|
s.command,
|
|
2537
2599
|
" ",
|
|
2538
2600
|
s.args?.join(" ") ?? ""
|
|
2539
2601
|
] })
|
|
2540
2602
|
] })
|
|
2541
2603
|
] }),
|
|
2542
|
-
/* @__PURE__ */
|
|
2543
|
-
s.status && /* @__PURE__ */
|
|
2604
|
+
/* @__PURE__ */ jsxs20("div", { className: "flex items-center gap-2 shrink-0", children: [
|
|
2605
|
+
s.status && /* @__PURE__ */ jsx22("span", { className: cn(
|
|
2544
2606
|
"inline-flex items-center rounded-full px-1.5 py-0.5 text-[9px] font-bold uppercase",
|
|
2545
2607
|
s.status === "running" ? "bg-[var(--surface-success-bg)] text-[var(--surface-success-text)]" : s.status === "error" ? "bg-destructive/10 text-destructive" : "bg-muted text-muted-foreground"
|
|
2546
2608
|
), children: s.status }),
|
|
2547
|
-
/* @__PURE__ */
|
|
2609
|
+
/* @__PURE__ */ jsx22(
|
|
2548
2610
|
"button",
|
|
2549
2611
|
{
|
|
2550
2612
|
type: "button",
|
|
2551
2613
|
onClick: () => onRemoveMcp(s.name),
|
|
2552
2614
|
className: "p-1 text-muted-foreground hover:text-destructive transition-colors rounded",
|
|
2553
|
-
children: /* @__PURE__ */
|
|
2615
|
+
children: /* @__PURE__ */ jsx22(Trash25, { className: "h-3.5 w-3.5" })
|
|
2554
2616
|
}
|
|
2555
2617
|
)
|
|
2556
2618
|
] })
|
|
2557
|
-
] }, s.name)) }) : /* @__PURE__ */
|
|
2558
|
-
showAddMcp && /* @__PURE__ */
|
|
2559
|
-
/* @__PURE__ */
|
|
2619
|
+
] }, s.name)) }) : /* @__PURE__ */ jsx22("div", { className: "p-4 text-center", children: /* @__PURE__ */ jsx22("p", { className: "text-xs text-muted-foreground", children: "No MCP servers configured" }) }),
|
|
2620
|
+
showAddMcp && /* @__PURE__ */ jsxs20("div", { className: "p-4 border-t border-border bg-muted/10 space-y-2", children: [
|
|
2621
|
+
/* @__PURE__ */ jsx22(
|
|
2560
2622
|
"input",
|
|
2561
2623
|
{
|
|
2562
2624
|
type: "text",
|
|
@@ -2566,7 +2628,7 @@ function BackendConfig({
|
|
|
2566
2628
|
className: "w-full rounded-lg border border-border bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring"
|
|
2567
2629
|
}
|
|
2568
2630
|
),
|
|
2569
|
-
/* @__PURE__ */
|
|
2631
|
+
/* @__PURE__ */ jsx22(
|
|
2570
2632
|
"input",
|
|
2571
2633
|
{
|
|
2572
2634
|
type: "text",
|
|
@@ -2576,7 +2638,7 @@ function BackendConfig({
|
|
|
2576
2638
|
className: "w-full rounded-lg border border-border bg-background px-3 py-2 text-sm font-mono text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring"
|
|
2577
2639
|
}
|
|
2578
2640
|
),
|
|
2579
|
-
/* @__PURE__ */
|
|
2641
|
+
/* @__PURE__ */ jsx22(
|
|
2580
2642
|
"input",
|
|
2581
2643
|
{
|
|
2582
2644
|
type: "text",
|
|
@@ -2586,8 +2648,8 @@ function BackendConfig({
|
|
|
2586
2648
|
className: "w-full rounded-lg border border-border bg-background px-3 py-2 text-sm font-mono text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring"
|
|
2587
2649
|
}
|
|
2588
2650
|
),
|
|
2589
|
-
/* @__PURE__ */
|
|
2590
|
-
/* @__PURE__ */
|
|
2651
|
+
/* @__PURE__ */ jsxs20("div", { className: "flex justify-end gap-2 pt-1", children: [
|
|
2652
|
+
/* @__PURE__ */ jsx22(
|
|
2591
2653
|
"button",
|
|
2592
2654
|
{
|
|
2593
2655
|
type: "button",
|
|
@@ -2596,7 +2658,7 @@ function BackendConfig({
|
|
|
2596
2658
|
children: "Cancel"
|
|
2597
2659
|
}
|
|
2598
2660
|
),
|
|
2599
|
-
/* @__PURE__ */
|
|
2661
|
+
/* @__PURE__ */ jsx22(
|
|
2600
2662
|
"button",
|
|
2601
2663
|
{
|
|
2602
2664
|
type: "button",
|
|
@@ -2615,7 +2677,7 @@ function BackendConfig({
|
|
|
2615
2677
|
// src/dashboard/snapshot-list.tsx
|
|
2616
2678
|
import * as React10 from "react";
|
|
2617
2679
|
import { Camera, Clock as Clock5, HardDrive, Plus as Plus8, RotateCcw } from "lucide-react";
|
|
2618
|
-
import { jsx as
|
|
2680
|
+
import { jsx as jsx23, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
2619
2681
|
function formatBytes(bytes) {
|
|
2620
2682
|
if (bytes == null || bytes < 0) return "-";
|
|
2621
2683
|
if (bytes === 0) return "0 B";
|
|
@@ -2638,25 +2700,25 @@ function SnapshotList({ snapshots, onCreate, onRestore, onSaveAsTemplate, loadin
|
|
|
2638
2700
|
setTags("");
|
|
2639
2701
|
setShowCreate(false);
|
|
2640
2702
|
};
|
|
2641
|
-
return /* @__PURE__ */
|
|
2642
|
-
/* @__PURE__ */
|
|
2643
|
-
/* @__PURE__ */
|
|
2644
|
-
/* @__PURE__ */
|
|
2703
|
+
return /* @__PURE__ */ jsxs21("div", { className: cn("space-y-4", className), children: [
|
|
2704
|
+
/* @__PURE__ */ jsxs21("div", { className: "flex items-center justify-between", children: [
|
|
2705
|
+
/* @__PURE__ */ jsx23("h3", { className: "text-sm font-bold text-foreground", children: "Snapshots" }),
|
|
2706
|
+
/* @__PURE__ */ jsxs21(
|
|
2645
2707
|
"button",
|
|
2646
2708
|
{
|
|
2647
2709
|
type: "button",
|
|
2648
2710
|
onClick: () => setShowCreate(!showCreate),
|
|
2649
2711
|
className: "inline-flex items-center gap-1.5 rounded-lg bg-primary/20 border border-primary/30 px-3 py-1.5 text-xs font-medium text-primary hover:bg-primary hover:text-primary-foreground transition-colors",
|
|
2650
2712
|
children: [
|
|
2651
|
-
/* @__PURE__ */
|
|
2713
|
+
/* @__PURE__ */ jsx23(Plus8, { className: "h-3.5 w-3.5" }),
|
|
2652
2714
|
"Create Snapshot"
|
|
2653
2715
|
]
|
|
2654
2716
|
}
|
|
2655
2717
|
)
|
|
2656
2718
|
] }),
|
|
2657
|
-
showCreate && /* @__PURE__ */
|
|
2658
|
-
/* @__PURE__ */
|
|
2659
|
-
/* @__PURE__ */
|
|
2719
|
+
showCreate && /* @__PURE__ */ jsxs21("div", { className: "rounded-lg border border-primary/20 bg-primary/5 p-4 space-y-3", children: [
|
|
2720
|
+
/* @__PURE__ */ jsx23("p", { className: "text-sm text-foreground font-medium", children: "Create a new snapshot of the current sandbox state." }),
|
|
2721
|
+
/* @__PURE__ */ jsx23(
|
|
2660
2722
|
"input",
|
|
2661
2723
|
{
|
|
2662
2724
|
type: "text",
|
|
@@ -2667,8 +2729,8 @@ function SnapshotList({ snapshots, onCreate, onRestore, onSaveAsTemplate, loadin
|
|
|
2667
2729
|
className: "w-full rounded-lg border border-border bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring"
|
|
2668
2730
|
}
|
|
2669
2731
|
),
|
|
2670
|
-
/* @__PURE__ */
|
|
2671
|
-
/* @__PURE__ */
|
|
2732
|
+
/* @__PURE__ */ jsxs21("div", { className: "flex justify-end gap-2", children: [
|
|
2733
|
+
/* @__PURE__ */ jsx23(
|
|
2672
2734
|
"button",
|
|
2673
2735
|
{
|
|
2674
2736
|
type: "button",
|
|
@@ -2677,44 +2739,44 @@ function SnapshotList({ snapshots, onCreate, onRestore, onSaveAsTemplate, loadin
|
|
|
2677
2739
|
children: "Cancel"
|
|
2678
2740
|
}
|
|
2679
2741
|
),
|
|
2680
|
-
/* @__PURE__ */
|
|
2742
|
+
/* @__PURE__ */ jsxs21(
|
|
2681
2743
|
"button",
|
|
2682
2744
|
{
|
|
2683
2745
|
type: "button",
|
|
2684
2746
|
onClick: handleCreate,
|
|
2685
2747
|
className: "rounded-md bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90 transition-colors",
|
|
2686
2748
|
children: [
|
|
2687
|
-
/* @__PURE__ */
|
|
2749
|
+
/* @__PURE__ */ jsx23(Camera, { className: "h-3 w-3 mr-1.5 inline" }),
|
|
2688
2750
|
"Create"
|
|
2689
2751
|
]
|
|
2690
2752
|
}
|
|
2691
2753
|
)
|
|
2692
2754
|
] })
|
|
2693
2755
|
] }),
|
|
2694
|
-
loading ? /* @__PURE__ */
|
|
2695
|
-
/* @__PURE__ */
|
|
2696
|
-
/* @__PURE__ */
|
|
2697
|
-
] }) : snapshots.length > 0 ? /* @__PURE__ */
|
|
2698
|
-
/* @__PURE__ */
|
|
2699
|
-
/* @__PURE__ */
|
|
2700
|
-
/* @__PURE__ */
|
|
2701
|
-
/* @__PURE__ */
|
|
2702
|
-
/* @__PURE__ */
|
|
2703
|
-
/* @__PURE__ */
|
|
2756
|
+
loading ? /* @__PURE__ */ jsxs21("div", { className: "rounded-lg border border-border bg-muted/20 p-6 text-center", children: [
|
|
2757
|
+
/* @__PURE__ */ jsx23(Camera, { className: "mx-auto h-6 w-6 text-muted-foreground animate-pulse mb-2" }),
|
|
2758
|
+
/* @__PURE__ */ jsx23("p", { className: "text-sm text-muted-foreground", children: "Loading snapshots..." })
|
|
2759
|
+
] }) : snapshots.length > 0 ? /* @__PURE__ */ jsx23("div", { className: "rounded-lg border border-border overflow-hidden", children: /* @__PURE__ */ jsxs21("table", { className: "w-full text-sm", children: [
|
|
2760
|
+
/* @__PURE__ */ jsx23("thead", { className: "bg-muted/30 border-b border-border", children: /* @__PURE__ */ jsxs21("tr", { children: [
|
|
2761
|
+
/* @__PURE__ */ jsx23("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "ID" }),
|
|
2762
|
+
/* @__PURE__ */ jsx23("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "Created" }),
|
|
2763
|
+
/* @__PURE__ */ jsx23("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "Size" }),
|
|
2764
|
+
/* @__PURE__ */ jsx23("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "Tags" }),
|
|
2765
|
+
/* @__PURE__ */ jsx23("th", { className: "px-4 py-2.5 text-right text-xs font-medium text-muted-foreground w-24" })
|
|
2704
2766
|
] }) }),
|
|
2705
|
-
/* @__PURE__ */
|
|
2706
|
-
/* @__PURE__ */
|
|
2707
|
-
/* @__PURE__ */
|
|
2708
|
-
/* @__PURE__ */
|
|
2767
|
+
/* @__PURE__ */ jsx23("tbody", { className: "divide-y divide-border", children: snapshots.map((s) => /* @__PURE__ */ jsxs21("tr", { children: [
|
|
2768
|
+
/* @__PURE__ */ jsx23("td", { className: "px-4 py-3 font-mono text-xs text-foreground", children: s.id.slice(0, 12) }),
|
|
2769
|
+
/* @__PURE__ */ jsx23("td", { className: "px-4 py-3 text-xs text-muted-foreground", children: /* @__PURE__ */ jsxs21("span", { className: "inline-flex items-center gap-1.5", children: [
|
|
2770
|
+
/* @__PURE__ */ jsx23(Clock5, { className: "h-3 w-3" }),
|
|
2709
2771
|
formatDate(s.createdAt)
|
|
2710
2772
|
] }) }),
|
|
2711
|
-
/* @__PURE__ */
|
|
2712
|
-
/* @__PURE__ */
|
|
2773
|
+
/* @__PURE__ */ jsx23("td", { className: "px-4 py-3 text-xs text-muted-foreground", children: /* @__PURE__ */ jsxs21("span", { className: "inline-flex items-center gap-1.5", children: [
|
|
2774
|
+
/* @__PURE__ */ jsx23(HardDrive, { className: "h-3 w-3" }),
|
|
2713
2775
|
formatBytes(s.sizeBytes)
|
|
2714
2776
|
] }) }),
|
|
2715
|
-
/* @__PURE__ */
|
|
2716
|
-
/* @__PURE__ */
|
|
2717
|
-
/* @__PURE__ */
|
|
2777
|
+
/* @__PURE__ */ jsx23("td", { className: "px-4 py-3", children: s.tags?.length ? /* @__PURE__ */ jsx23("div", { className: "flex items-center gap-1 flex-wrap", children: s.tags.map((tag) => /* @__PURE__ */ jsx23("span", { className: "rounded-full bg-muted px-2 py-0.5 text-[10px] font-medium text-muted-foreground border border-border", children: tag }, tag)) }) : /* @__PURE__ */ jsx23("span", { className: "text-xs text-muted-foreground", children: "-" }) }),
|
|
2778
|
+
/* @__PURE__ */ jsx23("td", { className: "px-4 py-3 text-right", children: /* @__PURE__ */ jsxs21("div", { className: "flex items-center justify-end gap-2", children: [
|
|
2779
|
+
/* @__PURE__ */ jsxs21(
|
|
2718
2780
|
"button",
|
|
2719
2781
|
{
|
|
2720
2782
|
type: "button",
|
|
@@ -2722,12 +2784,12 @@ function SnapshotList({ snapshots, onCreate, onRestore, onSaveAsTemplate, loadin
|
|
|
2722
2784
|
className: "inline-flex items-center gap-1.5 rounded-md bg-muted px-2.5 py-1 text-xs font-medium text-foreground hover:bg-muted/80 transition-colors border border-border",
|
|
2723
2785
|
title: "Restore to new sandbox",
|
|
2724
2786
|
children: [
|
|
2725
|
-
/* @__PURE__ */
|
|
2787
|
+
/* @__PURE__ */ jsx23(RotateCcw, { className: "h-3 w-3" }),
|
|
2726
2788
|
"Restore"
|
|
2727
2789
|
]
|
|
2728
2790
|
}
|
|
2729
2791
|
),
|
|
2730
|
-
onSaveAsTemplate && /* @__PURE__ */
|
|
2792
|
+
onSaveAsTemplate && /* @__PURE__ */ jsx23(
|
|
2731
2793
|
"button",
|
|
2732
2794
|
{
|
|
2733
2795
|
type: "button",
|
|
@@ -2739,16 +2801,16 @@ function SnapshotList({ snapshots, onCreate, onRestore, onSaveAsTemplate, loadin
|
|
|
2739
2801
|
)
|
|
2740
2802
|
] }) })
|
|
2741
2803
|
] }, s.id)) })
|
|
2742
|
-
] }) }) : /* @__PURE__ */
|
|
2743
|
-
/* @__PURE__ */
|
|
2744
|
-
/* @__PURE__ */
|
|
2745
|
-
/* @__PURE__ */
|
|
2804
|
+
] }) }) : /* @__PURE__ */ jsxs21("div", { className: "rounded-lg border border-border bg-muted/20 p-6 text-center", children: [
|
|
2805
|
+
/* @__PURE__ */ jsx23(Camera, { className: "mx-auto h-8 w-8 text-muted-foreground mb-2" }),
|
|
2806
|
+
/* @__PURE__ */ jsx23("p", { className: "text-sm text-muted-foreground", children: "No snapshots yet" }),
|
|
2807
|
+
/* @__PURE__ */ jsx23("p", { className: "text-xs text-muted-foreground mt-1", children: "Create a snapshot to save the current state of your sandbox." })
|
|
2746
2808
|
] })
|
|
2747
2809
|
] });
|
|
2748
2810
|
}
|
|
2749
2811
|
|
|
2750
2812
|
// src/dashboard/promo-banner.tsx
|
|
2751
|
-
import { Fragment as Fragment11, jsx as
|
|
2813
|
+
import { Fragment as Fragment11, jsx as jsx24, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
2752
2814
|
function PromoBanner({
|
|
2753
2815
|
title,
|
|
2754
2816
|
description,
|
|
@@ -2763,21 +2825,21 @@ function PromoBanner({
|
|
|
2763
2825
|
"mt-6 inline-flex items-center gap-2 rounded-md border border-white/20 bg-[var(--btn-primary-bg)] px-4 py-2 text-sm font-medium text-[var(--btn-primary-text)] transition-colors",
|
|
2764
2826
|
disabled ? "opacity-50 cursor-not-allowed" : "hover:bg-[var(--btn-primary-hover)]"
|
|
2765
2827
|
);
|
|
2766
|
-
const buttonContent = /* @__PURE__ */
|
|
2828
|
+
const buttonContent = /* @__PURE__ */ jsxs22(Fragment11, { children: [
|
|
2767
2829
|
buttonLabel,
|
|
2768
|
-
/* @__PURE__ */
|
|
2769
|
-
/* @__PURE__ */
|
|
2770
|
-
/* @__PURE__ */
|
|
2830
|
+
/* @__PURE__ */ jsxs22("svg", { "aria-hidden": "true", xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className: "h-4 w-4", children: [
|
|
2831
|
+
/* @__PURE__ */ jsx24("path", { d: "M5 12h14" }),
|
|
2832
|
+
/* @__PURE__ */ jsx24("path", { d: "m12 5 7 7-7 7" })
|
|
2771
2833
|
] })
|
|
2772
2834
|
] });
|
|
2773
|
-
return /* @__PURE__ */
|
|
2774
|
-
/* @__PURE__ */
|
|
2775
|
-
/* @__PURE__ */
|
|
2776
|
-
/* @__PURE__ */
|
|
2777
|
-
href && !disabled ? /* @__PURE__ */
|
|
2835
|
+
return /* @__PURE__ */ jsxs22("div", { className: cn("relative overflow-hidden rounded-xl bg-[var(--brand-strong)] p-8 md:flex md:items-center md:justify-between", className), children: [
|
|
2836
|
+
/* @__PURE__ */ jsxs22("div", { className: "relative z-10", children: [
|
|
2837
|
+
/* @__PURE__ */ jsx24("h3", { className: "text-xl font-bold text-[var(--brand-strong-text)]", children: title }),
|
|
2838
|
+
/* @__PURE__ */ jsx24("p", { className: "mt-2 max-w-md text-sm text-[var(--brand-strong-text-muted)]", children: description }),
|
|
2839
|
+
href && !disabled ? /* @__PURE__ */ jsx24("a", { href, target: "_blank", rel: "noopener noreferrer", onClick, className: buttonClasses, children: buttonContent }) : /* @__PURE__ */ jsx24("button", { type: "button", onClick, disabled, className: buttonClasses, children: buttonContent })
|
|
2778
2840
|
] }),
|
|
2779
|
-
icon && /* @__PURE__ */
|
|
2780
|
-
/* @__PURE__ */
|
|
2841
|
+
icon && /* @__PURE__ */ jsx24("div", { className: "relative z-10 mt-6 flex items-center md:mt-0", children: /* @__PURE__ */ jsx24("div", { className: "flex h-16 w-16 items-center justify-center rounded-2xl border border-white/10 bg-white/10", children: icon }) }),
|
|
2842
|
+
/* @__PURE__ */ jsx24("div", { className: "pointer-events-none absolute inset-y-0 right-0 w-1/3 bg-gradient-to-l from-white/5 to-transparent" })
|
|
2781
2843
|
] });
|
|
2782
2844
|
}
|
|
2783
2845
|
|
|
@@ -2802,6 +2864,9 @@ export {
|
|
|
2802
2864
|
SidebarContent,
|
|
2803
2865
|
ProfileAvatar,
|
|
2804
2866
|
CreditBalance,
|
|
2867
|
+
INSUFFICIENT_BALANCE_CODE,
|
|
2868
|
+
parseInsufficientBalance,
|
|
2869
|
+
OutOfCreditsModal,
|
|
2805
2870
|
ClusterStatusBar,
|
|
2806
2871
|
ResourceMeter,
|
|
2807
2872
|
canAdminSandbox,
|