@tangle-network/sandbox-ui 0.44.0 → 0.46.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{WorkflowGraph-7YYGIBNV.js → WorkflowGraph-6IKZYPST.js} +2 -1
- package/dist/assets.js +1 -0
- package/dist/assistant.js +2 -1
- package/dist/auth.js +1 -0
- package/dist/chat.js +4 -3
- package/dist/{chunk-6NDOA4SB.js → chunk-2ISY4R72.js} +112 -104
- package/dist/{chunk-KIRJZUX2.js → chunk-BR2LMUAE.js} +61 -34
- package/dist/{chunk-H7GMPMPB.js → chunk-CXV6X33U.js} +19 -1
- package/dist/{chunk-CUUUFJF5.js → chunk-KOUYJ6QP.js} +23 -23
- package/dist/{chunk-3RNYDTQ3.js → chunk-LQHTCM56.js} +21 -27
- package/dist/chunk-NXUSLH7H.js +7528 -0
- package/dist/{chunk-2XNT74ZX.js → chunk-OMUIPJQZ.js} +28 -20
- package/dist/{chunk-KCWIC3SJ.js → chunk-PZ62T5PM.js} +281 -214
- package/dist/chunk-U67V476Y.js +35 -0
- package/dist/chunk-VIREDUBF.js +215 -0
- package/dist/dashboard.d.ts +82 -66
- package/dist/dashboard.js +5 -4
- package/dist/editor.js +2 -0
- package/dist/files.d.ts +5 -0
- package/dist/files.js +1 -0
- package/dist/globals.css +1155 -50
- package/dist/hooks.js +1 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.js +95 -65
- package/dist/integrations.js +2 -1
- package/dist/markdown.js +2 -0
- package/dist/openui.d.ts +0 -5
- package/dist/openui.js +1 -0
- package/dist/pages.d.ts +1 -1
- package/dist/pages.js +89 -88
- package/dist/ports-list-DfG0VfPt.d.ts +17 -0
- package/dist/primitives.js +1 -0
- package/dist/run.js +1 -0
- package/dist/sdk-hooks.js +1 -0
- package/dist/stores.js +1 -0
- package/dist/styles.css +1155 -50
- package/dist/terminal.js +5 -209
- package/dist/tokens.css +13 -2
- package/dist/utils.js +1 -0
- package/dist/workbench.d.ts +227 -0
- package/dist/workbench.js +40 -0
- package/dist/workflows.js +2 -1
- package/dist/workspace.d.ts +6 -2
- package/dist/workspace.js +2 -1
- package/package.json +15 -9
|
@@ -147,8 +147,8 @@ function RailTooltip({ label, children, disabled, className }) {
|
|
|
147
147
|
"aria-hidden": "true",
|
|
148
148
|
className: cn(
|
|
149
149
|
"pointer-events-none absolute left-full top-1/2 z-50 ml-2 -translate-y-1/2 translate-x-1 whitespace-nowrap",
|
|
150
|
-
"rounded-md border border-
|
|
151
|
-
"opacity-0 shadow-[
|
|
150
|
+
"rounded-md border border-[var(--md3-outline-variant)] bg-surface-container-highest px-2 py-1 text-xs font-medium text-popover-foreground",
|
|
151
|
+
"opacity-0 shadow-[0_8px_30px_rgba(0,0,0,0.45)] ring-1 ring-[#ffffff14] transition-[opacity,transform] duration-150 ease-out",
|
|
152
152
|
"group-hover/tip:translate-x-0 group-hover/tip:opacity-100 group-hover/tip:delay-300",
|
|
153
153
|
"group-focus-within/tip:translate-x-0 group-focus-within/tip:opacity-100"
|
|
154
154
|
),
|
|
@@ -267,7 +267,7 @@ function Sidebar({ children, className, style }) {
|
|
|
267
267
|
{
|
|
268
268
|
"data-sidebar": "true",
|
|
269
269
|
className: cn(
|
|
270
|
-
"fixed inset-y-0 left-0 z-40 flex bg-
|
|
270
|
+
"fixed inset-y-0 left-0 z-40 flex bg-surface-container-low border-r border-[var(--md3-outline-variant)] transition-[transform,width] duration-200 ease-in-out",
|
|
271
271
|
hidden && "-translate-x-full",
|
|
272
272
|
className
|
|
273
273
|
),
|
|
@@ -292,7 +292,7 @@ function SidebarRail({ children, className, wide = false }) {
|
|
|
292
292
|
);
|
|
293
293
|
}
|
|
294
294
|
function SidebarRailHeader({ children, className }) {
|
|
295
|
-
return /* @__PURE__ */ jsx3("div", { className: cn("flex h-14 shrink-0 items-center justify-center border-b border-
|
|
295
|
+
return /* @__PURE__ */ jsx3("div", { className: cn("flex h-14 shrink-0 items-center justify-center border-b border-[var(--md3-outline-variant)]", className), children });
|
|
296
296
|
}
|
|
297
297
|
function SidebarRailNav({ children, className }) {
|
|
298
298
|
return /* @__PURE__ */ jsx3("nav", { className: cn("flex flex-col items-center gap-1 py-3 flex-1 min-h-0 overflow-y-auto", className), children });
|
|
@@ -402,7 +402,7 @@ function RailFlyout({
|
|
|
402
402
|
if (el.closest("a,button")) setOpen(false);
|
|
403
403
|
},
|
|
404
404
|
className: cn(
|
|
405
|
-
"absolute top-0 z-50 min-w-[12rem] rounded-md border border-
|
|
405
|
+
"absolute top-0 z-50 min-w-[12rem] rounded-md border border-[var(--md3-outline-variant)] bg-surface-container-highest p-1.5 shadow-[0_8px_30px_rgba(0,0,0,0.45)] ring-1 ring-[#ffffff14]",
|
|
406
406
|
showLabel ? "left-full ml-2" : "left-full ml-2"
|
|
407
407
|
),
|
|
408
408
|
children: [
|
|
@@ -440,7 +440,7 @@ function SidebarPanel({ children, className }) {
|
|
|
440
440
|
"div",
|
|
441
441
|
{
|
|
442
442
|
className: cn(
|
|
443
|
-
"transition-[opacity] duration-150 h-full overflow-hidden border-l border-
|
|
443
|
+
"transition-[opacity] duration-150 h-full overflow-hidden border-l border-[var(--md3-outline-variant)] bg-surface-container-low",
|
|
444
444
|
panelOpen ? "w-[268px] opacity-100" : "w-0 opacity-0 pointer-events-none",
|
|
445
445
|
className
|
|
446
446
|
),
|
|
@@ -449,7 +449,7 @@ function SidebarPanel({ children, className }) {
|
|
|
449
449
|
);
|
|
450
450
|
}
|
|
451
451
|
function SidebarPanelHeader({ children, title, className }) {
|
|
452
|
-
return /* @__PURE__ */ jsx3("div", { className: cn("flex h-14 items-center px-4 border-b border-
|
|
452
|
+
return /* @__PURE__ */ jsx3("div", { className: cn("flex h-14 items-center px-4 border-b border-[var(--md3-outline-variant)] shrink-0", className), children: children ?? /* @__PURE__ */ jsx3("h2", { className: "text-sm font-semibold text-foreground", children: title }) });
|
|
453
453
|
}
|
|
454
454
|
function SidebarPanelContent({ children, className }) {
|
|
455
455
|
return /* @__PURE__ */ jsx3("div", { className: cn("flex-1 overflow-y-auto px-2 py-2", className), children });
|
|
@@ -554,7 +554,7 @@ function CreditBalance({
|
|
|
554
554
|
"div",
|
|
555
555
|
{
|
|
556
556
|
className: cn(
|
|
557
|
-
"bg-
|
|
557
|
+
"bg-surface-container p-5 rounded-xl flex flex-col justify-between border border-[var(--md3-outline-variant)]",
|
|
558
558
|
className
|
|
559
559
|
),
|
|
560
560
|
children: [
|
|
@@ -567,7 +567,7 @@ function CreditBalance({
|
|
|
567
567
|
/* @__PURE__ */ jsx4("p", { className: "text-sm text-muted-foreground leading-relaxed", children: description })
|
|
568
568
|
] }),
|
|
569
569
|
onTopUp && /* @__PURE__ */ jsxs3("div", { className: "space-y-2.5 mt-5", children: [
|
|
570
|
-
/* @__PURE__ */ jsxs3("div", { className: "bg-
|
|
570
|
+
/* @__PURE__ */ jsxs3("div", { className: "bg-surface-container-low border border-[var(--md3-outline-variant)] p-1 rounded-lg flex items-center", children: [
|
|
571
571
|
/* @__PURE__ */ jsx4(
|
|
572
572
|
"input",
|
|
573
573
|
{
|
|
@@ -577,7 +577,7 @@ function CreditBalance({
|
|
|
577
577
|
const raw = e.target.value.replace(/[^0-9.]/g, "");
|
|
578
578
|
setTopUpValue(raw.match(/^(\d*\.?\d{0,2})/)?.[1] ?? "");
|
|
579
579
|
},
|
|
580
|
-
className: "bg-transparent border-none text-foreground font-mono text-lg w-
|
|
580
|
+
className: "bg-transparent border-none text-foreground font-mono text-lg min-w-0 flex-1 focus:ring-0 px-4 outline-none"
|
|
581
581
|
}
|
|
582
582
|
),
|
|
583
583
|
/* @__PURE__ */ jsx4(
|
|
@@ -589,7 +589,7 @@ function CreditBalance({
|
|
|
589
589
|
if (!Number.isFinite(parsed) || parsed <= 0) return;
|
|
590
590
|
onTopUp(parsed);
|
|
591
591
|
},
|
|
592
|
-
className: "bg-[var(--accent-surface-soft)] border border-
|
|
592
|
+
className: "shrink-0 whitespace-nowrap bg-[var(--accent-surface-soft)] border border-[var(--md3-outline-variant)] text-[var(--accent-text)] px-5 py-3 rounded-md font-bold text-xs uppercase tracking-widest active:scale-95 transition-transform hover:bg-[var(--accent-surface-strong)]",
|
|
593
593
|
children: "Top Up"
|
|
594
594
|
}
|
|
595
595
|
)
|
|
@@ -603,10 +603,10 @@ function CreditBalance({
|
|
|
603
603
|
setTopUpValue(qa.toFixed(2));
|
|
604
604
|
onTopUp(rounded);
|
|
605
605
|
},
|
|
606
|
-
className: "flex-1 py-2 text-
|
|
606
|
+
className: "flex-1 py-2 text-center text-xs font-mono tabular-nums text-muted-foreground border border-[var(--md3-outline-variant)] rounded-md hover:bg-surface-container-high hover:text-foreground transition-colors uppercase",
|
|
607
607
|
children: [
|
|
608
608
|
"+$",
|
|
609
|
-
qa
|
|
609
|
+
qa.toLocaleString("en-US")
|
|
610
610
|
]
|
|
611
611
|
},
|
|
612
612
|
qa
|
|
@@ -653,7 +653,7 @@ function OutOfCreditsModal({
|
|
|
653
653
|
"div",
|
|
654
654
|
{
|
|
655
655
|
className: cn(
|
|
656
|
-
"bg-
|
|
656
|
+
"bg-surface-container-highest border border-[var(--md3-outline-variant)] rounded-xl p-6 max-w-md w-full shadow-[0_8px_30px_rgba(0,0,0,0.45)] ring-1 ring-[#ffffff14]",
|
|
657
657
|
className
|
|
658
658
|
),
|
|
659
659
|
onClick: (e) => e.stopPropagation(),
|
|
@@ -679,25 +679,29 @@ function OutOfCreditsModal({
|
|
|
679
679
|
}
|
|
680
680
|
|
|
681
681
|
// src/dashboard/cluster-status-bar.tsx
|
|
682
|
-
import
|
|
682
|
+
import * as React4 from "react";
|
|
683
|
+
import { Fragment as Fragment4, jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
683
684
|
function ClusterStatusBar({ items, latency, className }) {
|
|
684
685
|
if (!items?.length) return null;
|
|
685
|
-
return /* @__PURE__ */ jsx6("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__ */ jsxs5("div", { className: "overflow-
|
|
686
|
-
|
|
687
|
-
/* @__PURE__ */ jsx6("span", { className: "
|
|
688
|
-
/* @__PURE__ */ jsxs5("div", { className: "flex
|
|
689
|
-
/* @__PURE__ */ jsx6("span", { className: "
|
|
690
|
-
/* @__PURE__ */
|
|
686
|
+
return /* @__PURE__ */ jsx6("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__ */ jsxs5("div", { className: "flex items-center gap-4 overflow-x-auto rounded-full border border-[var(--md3-outline-variant)] bg-surface-container px-5 py-2.5 shadow-sm", children: [
|
|
687
|
+
items.map((item, i) => /* @__PURE__ */ jsxs5(React4.Fragment, { children: [
|
|
688
|
+
i > 0 && /* @__PURE__ */ jsx6("span", { "aria-hidden": true, className: "h-5 w-px shrink-0 bg-border" }),
|
|
689
|
+
/* @__PURE__ */ jsxs5("div", { className: "flex shrink-0 items-center gap-2", children: [
|
|
690
|
+
item.icon ? /* @__PURE__ */ jsx6("span", { className: "flex shrink-0 items-center text-[var(--md3-primary)] [&_svg]:h-[18px] [&_svg]:w-[18px]", children: item.icon }) : null,
|
|
691
|
+
/* @__PURE__ */ jsxs5("div", { className: "flex flex-col leading-tight", children: [
|
|
692
|
+
/* @__PURE__ */ jsx6("span", { className: "text-[10px] font-bold uppercase tracking-wider text-[var(--md3-on-surface-variant)]", children: item.label }),
|
|
693
|
+
/* @__PURE__ */ jsx6("span", { className: cn("text-sm font-bold tabular-nums text-foreground", item.valueClass), children: item.value })
|
|
694
|
+
] })
|
|
691
695
|
] })
|
|
692
|
-
] }, i))
|
|
693
|
-
latency && /* @__PURE__ */ jsxs5(
|
|
694
|
-
/* @__PURE__ */ jsx6("
|
|
695
|
-
/* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-
|
|
696
|
-
/* @__PURE__ */ jsxs5("
|
|
696
|
+
] }, i)),
|
|
697
|
+
latency && /* @__PURE__ */ jsxs5(Fragment4, { children: [
|
|
698
|
+
/* @__PURE__ */ jsx6("span", { "aria-hidden": true, className: "h-5 w-px shrink-0 bg-border" }),
|
|
699
|
+
/* @__PURE__ */ jsxs5("div", { className: "flex shrink-0 items-center gap-2", children: [
|
|
700
|
+
/* @__PURE__ */ jsxs5("span", { className: "relative flex h-2.5 w-2.5 items-center justify-center", children: [
|
|
697
701
|
/* @__PURE__ */ jsx6("span", { className: "absolute inline-flex h-full w-full animate-ping rounded-full bg-green-400 opacity-75" }),
|
|
698
702
|
/* @__PURE__ */ jsx6("span", { className: "relative inline-flex h-2 w-2 rounded-full bg-green-500" })
|
|
699
703
|
] }),
|
|
700
|
-
/* @__PURE__ */ jsx6("span", { className: "text-xs font-
|
|
704
|
+
/* @__PURE__ */ jsx6("span", { className: "font-mono text-xs font-bold text-green-400", children: latency })
|
|
701
705
|
] })
|
|
702
706
|
] })
|
|
703
707
|
] }) });
|
|
@@ -715,18 +719,18 @@ function ResourceMeter({ label, value, max = 100, unit, valueLabel, icon, classN
|
|
|
715
719
|
const barColor = getBarColor(percent);
|
|
716
720
|
const readout = valueLabel ?? (unit ? `${value}${unit}/${max}${unit}` : `${Math.round(percent)}%`);
|
|
717
721
|
return /* @__PURE__ */ jsxs6("div", { className: cn("flex items-center gap-3", className), children: [
|
|
718
|
-
/* @__PURE__ */ jsxs6("span", { className: "flex shrink-0 items-center gap-1 text-
|
|
719
|
-
icon,
|
|
720
|
-
label
|
|
722
|
+
/* @__PURE__ */ jsxs6("span", { className: "flex shrink-0 items-center gap-1.5 text-xs font-mono text-muted-foreground uppercase tracking-wide", children: [
|
|
723
|
+
icon ? /* @__PURE__ */ jsx7("span", { className: "flex shrink-0 items-center [&_svg]:h-3.5 [&_svg]:w-3.5", children: icon }) : null,
|
|
724
|
+
/* @__PURE__ */ jsx7("span", { children: label })
|
|
721
725
|
] }),
|
|
722
|
-
/* @__PURE__ */ jsx7("div", { className: "h-1.5 min-w-0 flex-1 bg-
|
|
726
|
+
/* @__PURE__ */ jsx7("div", { className: "h-1.5 min-w-0 flex-1 bg-muted rounded-full overflow-hidden", children: /* @__PURE__ */ jsx7(
|
|
723
727
|
"div",
|
|
724
728
|
{
|
|
725
729
|
className: cn("h-full rounded-full transition-all duration-500", barColor),
|
|
726
730
|
style: { width: `${percent}%` }
|
|
727
731
|
}
|
|
728
732
|
) }),
|
|
729
|
-
/* @__PURE__ */ jsx7("span", { className: "shrink-0 text-
|
|
733
|
+
/* @__PURE__ */ jsx7("span", { className: "shrink-0 text-xs font-mono tabular-nums text-muted-foreground", children: readout })
|
|
730
734
|
] });
|
|
731
735
|
}
|
|
732
736
|
|
|
@@ -746,7 +750,7 @@ function ResourceSnapshot({
|
|
|
746
750
|
"div",
|
|
747
751
|
{
|
|
748
752
|
className: cn(
|
|
749
|
-
"flex flex-col rounded-lg border border-
|
|
753
|
+
"flex flex-col rounded-lg border border-[var(--md3-outline-variant)] bg-surface-container p-6",
|
|
750
754
|
className
|
|
751
755
|
),
|
|
752
756
|
children: [
|
|
@@ -772,7 +776,7 @@ function ResourceSnapshot({
|
|
|
772
776
|
}
|
|
773
777
|
|
|
774
778
|
// src/dashboard/activity-feed.tsx
|
|
775
|
-
import * as
|
|
779
|
+
import * as React5 from "react";
|
|
776
780
|
import { Skeleton as Skeleton3 } from "@tangle-network/ui/primitives";
|
|
777
781
|
import { timeAgo } from "@tangle-network/ui/utils";
|
|
778
782
|
import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
@@ -785,7 +789,7 @@ function ActivityFeed({
|
|
|
785
789
|
emptyLabel = "No recent activity",
|
|
786
790
|
className
|
|
787
791
|
}) {
|
|
788
|
-
const sorted =
|
|
792
|
+
const sorted = React5.useMemo(
|
|
789
793
|
() => [...items].sort((a, b) => (b.timestamp ?? 0) - (a.timestamp ?? 0)).slice(0, maxItems),
|
|
790
794
|
[items, maxItems]
|
|
791
795
|
);
|
|
@@ -793,7 +797,7 @@ function ActivityFeed({
|
|
|
793
797
|
"div",
|
|
794
798
|
{
|
|
795
799
|
className: cn(
|
|
796
|
-
"flex flex-col rounded-lg border border-
|
|
800
|
+
"flex flex-col rounded-lg border border-[var(--md3-outline-variant)] bg-surface-container p-6",
|
|
797
801
|
className
|
|
798
802
|
),
|
|
799
803
|
children: [
|
|
@@ -831,18 +835,36 @@ import {
|
|
|
831
835
|
Activity,
|
|
832
836
|
BarChart2,
|
|
833
837
|
Trash2,
|
|
834
|
-
Terminal,
|
|
835
|
-
Code2,
|
|
836
838
|
Network,
|
|
837
839
|
Play,
|
|
838
840
|
Plus,
|
|
839
|
-
Users
|
|
841
|
+
Users,
|
|
842
|
+
Cpu,
|
|
843
|
+
MemoryStick,
|
|
844
|
+
HardDrive,
|
|
845
|
+
Box
|
|
840
846
|
} from "lucide-react";
|
|
841
|
-
import { Fragment as
|
|
847
|
+
import { Fragment as Fragment5, jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
842
848
|
function canAdminSandbox(sandbox) {
|
|
843
849
|
if (!sandbox.team) return true;
|
|
844
850
|
return sandbox.team.role === "owner" || sandbox.team.role === "admin";
|
|
845
851
|
}
|
|
852
|
+
var STATUS_META = {
|
|
853
|
+
running: { label: "Running", color: "var(--status-running)" },
|
|
854
|
+
hibernating: { label: "Hibernating", color: "var(--status-warm)" },
|
|
855
|
+
provisioning: { label: "Provisioning", color: "var(--status-creating)" },
|
|
856
|
+
creating: { label: "Creating", color: "var(--status-creating)" },
|
|
857
|
+
stopped: { label: "Stopped", color: "var(--status-stopped)" },
|
|
858
|
+
failed: { label: "Failed", color: "var(--status-error)" },
|
|
859
|
+
archived: { label: "Archived", color: "var(--status-deleted)" }
|
|
860
|
+
};
|
|
861
|
+
function Spec({ icon, value, unit }) {
|
|
862
|
+
return /* @__PURE__ */ jsxs9("span", { className: "flex items-center gap-1.5", children: [
|
|
863
|
+
/* @__PURE__ */ jsx10("span", { className: "text-muted-foreground", "aria-hidden": "true", children: icon }),
|
|
864
|
+
/* @__PURE__ */ jsx10("span", { className: "font-mono text-xs tabular-nums text-foreground", children: value }),
|
|
865
|
+
/* @__PURE__ */ jsx10("span", { className: "text-[10px] text-muted-foreground", children: unit })
|
|
866
|
+
] });
|
|
867
|
+
}
|
|
846
868
|
function SandboxCard({
|
|
847
869
|
sandbox,
|
|
848
870
|
onOpenIDE,
|
|
@@ -862,29 +884,35 @@ function SandboxCard({
|
|
|
862
884
|
const isTransitioning = sandbox.status === "provisioning" || sandbox.status === "creating";
|
|
863
885
|
const isStopped = !isRunning && !isTransitioning;
|
|
864
886
|
const isHibernating = sandbox.status === "hibernating";
|
|
865
|
-
const resolveResumeHandler = (
|
|
887
|
+
const resolveResumeHandler = (status2) => {
|
|
866
888
|
if (onResume) return onResume;
|
|
867
|
-
if (
|
|
889
|
+
if (status2 === "hibernating") return onWake;
|
|
868
890
|
return void 0;
|
|
869
891
|
};
|
|
870
892
|
const resumeLabel = isHibernating ? "Wake Sandbox" : "Resume Sandbox";
|
|
871
893
|
const resumeHandler = isStopped ? resolveResumeHandler(sandbox.status) : void 0;
|
|
894
|
+
const status = STATUS_META[sandbox.status];
|
|
895
|
+
const isArchived = sandbox.status === "archived";
|
|
896
|
+
const cpuPercent = sandbox.cpuPercent ?? 0;
|
|
897
|
+
const ramUsed = sandbox.ramUsed ?? 0;
|
|
898
|
+
const ramTotal = sandbox.ramTotal ?? 0;
|
|
899
|
+
const diskUsed = sandbox.diskUsed;
|
|
900
|
+
const diskTotal = sandbox.diskTotal;
|
|
901
|
+
const specs = [
|
|
902
|
+
sandbox.vcpu != null && { key: "vcpu", icon: /* @__PURE__ */ jsx10(Cpu, { className: "h-3.5 w-3.5" }), value: sandbox.vcpu, unit: "vCPU" },
|
|
903
|
+
ramTotal > 0 && { key: "ram", icon: /* @__PURE__ */ jsx10(MemoryStick, { className: "h-3.5 w-3.5" }), value: ramTotal, unit: "GB RAM" },
|
|
904
|
+
diskTotal != null && { key: "disk", icon: /* @__PURE__ */ jsx10(HardDrive, { className: "h-3.5 w-3.5" }), value: diskTotal, unit: "GB SSD" }
|
|
905
|
+
].filter(Boolean);
|
|
872
906
|
return /* @__PURE__ */ jsxs9("div", { className: cn(
|
|
873
|
-
"group relative flex flex-col justify-between overflow-hidden rounded-lg border bg-
|
|
874
|
-
isRunning ? "border-[var(--status-running)]/30" : "border-
|
|
907
|
+
"group relative flex flex-col justify-between overflow-hidden rounded-lg border bg-surface-container p-5 transition-colors",
|
|
908
|
+
isRunning ? "border-[var(--status-running)]/30" : "border-[var(--md3-outline-variant)]",
|
|
875
909
|
"hover:border-foreground/15",
|
|
876
910
|
className
|
|
877
911
|
), children: [
|
|
878
912
|
/* @__PURE__ */ jsxs9("div", { className: "flex items-start justify-between", children: [
|
|
879
913
|
/* @__PURE__ */ jsxs9("div", { children: [
|
|
880
914
|
/* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-2", children: [
|
|
881
|
-
/* @__PURE__ */
|
|
882
|
-
sandbox.name,
|
|
883
|
-
isRunning && /* @__PURE__ */ jsxs9("span", { className: "relative flex h-2 w-2", children: [
|
|
884
|
-
/* @__PURE__ */ jsx10("span", { className: "absolute inline-flex h-full w-full animate-pulse rounded-full bg-[var(--status-running)] opacity-75" }),
|
|
885
|
-
/* @__PURE__ */ jsx10("span", { className: "relative inline-flex h-1.5 w-1.5 rounded-full bg-[var(--status-running)]" })
|
|
886
|
-
] })
|
|
887
|
-
] }),
|
|
915
|
+
/* @__PURE__ */ jsx10("h3", { className: "truncate text-sm font-bold text-foreground", children: sandbox.name }),
|
|
888
916
|
sandbox.team && /* @__PURE__ */ jsxs9(
|
|
889
917
|
"span",
|
|
890
918
|
{
|
|
@@ -910,13 +938,13 @@ function SandboxCard({
|
|
|
910
938
|
"button",
|
|
911
939
|
{
|
|
912
940
|
type: "button",
|
|
913
|
-
className: "rounded-md p-1.5 text-muted-foreground transition-colors hover:bg-
|
|
941
|
+
className: "rounded-md p-1.5 text-muted-foreground transition-colors hover:bg-surface-container-high hover:text-foreground outline-none",
|
|
914
942
|
"aria-label": "Sandbox options",
|
|
915
943
|
children: /* @__PURE__ */ jsx10(MoreVertical, { className: "h-4 w-4" })
|
|
916
944
|
}
|
|
917
945
|
) }),
|
|
918
946
|
/* @__PURE__ */ jsxs9(DropdownMenuContent2, { align: "end", className: "min-w-[180px]", children: [
|
|
919
|
-
isRunning && /* @__PURE__ */ jsxs9(
|
|
947
|
+
isRunning && /* @__PURE__ */ jsxs9(Fragment5, { children: [
|
|
920
948
|
onStop && /* @__PURE__ */ jsxs9(DropdownMenuItem2, { onClick: () => onStop(sandbox.id), children: [
|
|
921
949
|
/* @__PURE__ */ jsx10(PowerOff, { className: "mr-2 h-4 w-4" }),
|
|
922
950
|
" Stop Sandbox"
|
|
@@ -935,7 +963,7 @@ function SandboxCard({
|
|
|
935
963
|
" Health Check"
|
|
936
964
|
] }),
|
|
937
965
|
(onUsage || onHealth) && /* @__PURE__ */ jsx10(DropdownMenuSeparator2, {}),
|
|
938
|
-
onFork && /* @__PURE__ */ jsxs9(
|
|
966
|
+
onFork && /* @__PURE__ */ jsxs9(Fragment5, { children: [
|
|
939
967
|
/* @__PURE__ */ jsxs9(DropdownMenuItem2, { onClick: () => onFork(sandbox.id), children: [
|
|
940
968
|
/* @__PURE__ */ jsx10(Copy, { className: "mr-2 h-4 w-4" }),
|
|
941
969
|
" Fork Sandbox"
|
|
@@ -943,7 +971,7 @@ function SandboxCard({
|
|
|
943
971
|
/* @__PURE__ */ jsx10(DropdownMenuSeparator2, {})
|
|
944
972
|
] })
|
|
945
973
|
] }),
|
|
946
|
-
isStopped && /* @__PURE__ */ jsxs9(
|
|
974
|
+
isStopped && /* @__PURE__ */ jsxs9(Fragment5, { children: [
|
|
947
975
|
resumeHandler && /* @__PURE__ */ jsxs9(DropdownMenuItem2, { onClick: () => resumeHandler(sandbox.id), children: [
|
|
948
976
|
/* @__PURE__ */ jsx10(Power, { className: "mr-2 h-4 w-4" }),
|
|
949
977
|
" ",
|
|
@@ -962,32 +990,71 @@ function SandboxCard({
|
|
|
962
990
|
] })
|
|
963
991
|
] })
|
|
964
992
|
] }),
|
|
965
|
-
/* @__PURE__ */ jsxs9("div", { className: "my-4", children: [
|
|
966
|
-
/* @__PURE__ */ jsxs9("div", { className: "flex items-center
|
|
967
|
-
/* @__PURE__ */
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
993
|
+
/* @__PURE__ */ jsxs9("div", { className: "my-4 space-y-3", children: [
|
|
994
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex items-center justify-between", children: [
|
|
995
|
+
/* @__PURE__ */ jsxs9("span", { className: "inline-flex items-center gap-1.5 rounded-full border border-[var(--md3-outline-variant)] bg-surface-container-high px-2 py-0.5 text-[11px] font-medium text-foreground", children: [
|
|
996
|
+
/* @__PURE__ */ jsxs9("span", { className: "relative flex h-1.5 w-1.5", children: [
|
|
997
|
+
isRunning && /* @__PURE__ */ jsx10(
|
|
998
|
+
"span",
|
|
999
|
+
{
|
|
1000
|
+
className: "absolute inline-flex h-full w-full animate-ping rounded-full opacity-75",
|
|
1001
|
+
style: { backgroundColor: status.color }
|
|
1002
|
+
}
|
|
1003
|
+
),
|
|
1004
|
+
/* @__PURE__ */ jsx10("span", { className: "relative inline-flex h-1.5 w-1.5 rounded-full", style: { backgroundColor: status.color } })
|
|
1005
|
+
] }),
|
|
1006
|
+
status.label
|
|
1007
|
+
] }),
|
|
1008
|
+
isRunning && sandbox.uptime && /* @__PURE__ */ jsxs9("span", { className: "font-mono text-[10px] tabular-nums text-muted-foreground", children: [
|
|
1009
|
+
"up ",
|
|
1010
|
+
sandbox.uptime
|
|
971
1011
|
] })
|
|
972
1012
|
] }),
|
|
973
|
-
|
|
974
|
-
/* @__PURE__ */
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
1013
|
+
isRunning ? /* @__PURE__ */ jsxs9("div", { className: "space-y-2 rounded-md border border-[var(--md3-outline-variant)] bg-surface-container-high p-3", children: [
|
|
1014
|
+
/* @__PURE__ */ jsx10(ResourceMeter, { label: "CPU", value: cpuPercent, max: 100, icon: /* @__PURE__ */ jsx10(Cpu, { className: "h-3 w-3" }) }),
|
|
1015
|
+
ramTotal > 0 && /* @__PURE__ */ jsx10(
|
|
1016
|
+
ResourceMeter,
|
|
1017
|
+
{
|
|
1018
|
+
label: "MEM",
|
|
1019
|
+
value: ramUsed,
|
|
1020
|
+
max: ramTotal,
|
|
1021
|
+
valueLabel: `${ramUsed} / ${ramTotal} GB`,
|
|
1022
|
+
icon: /* @__PURE__ */ jsx10(MemoryStick, { className: "h-3 w-3" })
|
|
1023
|
+
}
|
|
1024
|
+
),
|
|
1025
|
+
diskUsed != null && diskTotal != null && diskTotal > 0 && /* @__PURE__ */ jsx10(
|
|
1026
|
+
ResourceMeter,
|
|
1027
|
+
{
|
|
1028
|
+
label: "DISK",
|
|
1029
|
+
value: diskUsed,
|
|
1030
|
+
max: diskTotal,
|
|
1031
|
+
valueLabel: `${diskUsed} / ${diskTotal} GB`,
|
|
1032
|
+
icon: /* @__PURE__ */ jsx10(HardDrive, { className: "h-3 w-3" })
|
|
1033
|
+
}
|
|
1034
|
+
)
|
|
1035
|
+
] }) : isTransitioning ? /* @__PURE__ */ jsxs9("div", { className: "rounded-md border border-[var(--md3-outline-variant)] bg-surface-container-high p-3", children: [
|
|
1036
|
+
/* @__PURE__ */ jsxs9("div", { className: "mb-1.5 flex justify-between text-[11px] font-medium text-muted-foreground", children: [
|
|
1037
|
+
/* @__PURE__ */ jsx10("span", { children: sandbox.provisioningMessage || "Starting\u2026" }),
|
|
1038
|
+
/* @__PURE__ */ jsxs9("span", { className: "font-mono tabular-nums", children: [
|
|
1039
|
+
sandbox.provisioningPercent ?? 0,
|
|
978
1040
|
"%"
|
|
979
1041
|
] })
|
|
980
1042
|
] }),
|
|
981
1043
|
/* @__PURE__ */ jsx10("div", { className: "h-1 w-full overflow-hidden rounded-full bg-muted", children: /* @__PURE__ */ jsx10(
|
|
982
1044
|
"div",
|
|
983
1045
|
{
|
|
984
|
-
className: "h-full bg-primary transition-all duration-500
|
|
1046
|
+
className: "h-full rounded-full bg-primary transition-all duration-500",
|
|
985
1047
|
style: { width: `${sandbox.provisioningPercent || 5}%` }
|
|
986
1048
|
}
|
|
987
1049
|
) })
|
|
1050
|
+
] }) : isArchived && sandbox.archivedAt ? /* @__PURE__ */ jsx10("p", { className: "font-mono text-[11px] text-muted-foreground", children: sandbox.archivedAt }) : null,
|
|
1051
|
+
specs.length > 0 && /* @__PURE__ */ jsx10("div", { className: "flex items-center gap-4 rounded-md border border-[var(--md3-outline-variant)] bg-surface-container-high px-3 py-2", children: specs.map((s) => /* @__PURE__ */ jsx10(Spec, { icon: s.icon, value: s.value, unit: s.unit }, s.key)) }),
|
|
1052
|
+
sandbox.customImage && /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-1.5 truncate font-mono text-[10px] text-muted-foreground", children: [
|
|
1053
|
+
/* @__PURE__ */ jsx10(Box, { className: "h-3 w-3 shrink-0", "aria-hidden": "true" }),
|
|
1054
|
+
/* @__PURE__ */ jsx10("span", { className: "truncate", title: sandbox.customImage, children: sandbox.customImage })
|
|
988
1055
|
] })
|
|
989
1056
|
] }),
|
|
990
|
-
/* @__PURE__ */ jsx10("div", { className: "border-t border-
|
|
1057
|
+
/* @__PURE__ */ jsx10("div", { className: "border-t border-[var(--md3-outline-variant)] pt-3", children: isRunning ? /* @__PURE__ */ jsxs9(
|
|
991
1058
|
"button",
|
|
992
1059
|
{
|
|
993
1060
|
type: "button",
|
|
@@ -1006,7 +1073,7 @@ function SandboxCard({
|
|
|
1006
1073
|
disabled: isTransitioning || !resumeHandler,
|
|
1007
1074
|
className: cn(
|
|
1008
1075
|
"flex w-full items-center justify-center gap-2 rounded-md px-4 py-2 text-sm font-semibold transition-colors border",
|
|
1009
|
-
isTransitioning || !resumeHandler ? "bg-muted text-muted-foreground cursor-not-allowed border-
|
|
1076
|
+
isTransitioning || !resumeHandler ? "bg-muted text-muted-foreground cursor-not-allowed border-[var(--md3-outline-variant)]" : "bg-surface-container-high text-foreground hover:bg-surface-container-highest border-[var(--md3-outline-variant)] active:scale-[0.97]"
|
|
1010
1077
|
),
|
|
1011
1078
|
children: [
|
|
1012
1079
|
/* @__PURE__ */ jsx10(Play, { className: "h-4 w-4" }),
|
|
@@ -1023,27 +1090,27 @@ function NewSandboxCard({ onClick, className }) {
|
|
|
1023
1090
|
type: "button",
|
|
1024
1091
|
onClick,
|
|
1025
1092
|
className: cn(
|
|
1026
|
-
"border-2 border-dashed border-
|
|
1093
|
+
"border-2 border-dashed border-[var(--md3-outline-variant)] rounded-lg p-5 flex flex-col items-center justify-center text-center cursor-pointer hover:border-foreground/20 hover:bg-surface-container-high transition-colors w-full min-h-[160px]",
|
|
1027
1094
|
className
|
|
1028
1095
|
),
|
|
1029
1096
|
children: [
|
|
1030
|
-
/* @__PURE__ */ jsx10("div", { className: "flex h-12 w-12 items-center justify-center rounded-lg bg-
|
|
1097
|
+
/* @__PURE__ */ jsx10("div", { className: "flex h-12 w-12 items-center justify-center rounded-lg bg-surface-container-high text-muted-foreground", children: /* @__PURE__ */ jsx10(Plus, { className: "h-6 w-6" }) }),
|
|
1031
1098
|
/* @__PURE__ */ jsx10("span", { className: "mt-4 text-sm font-semibold text-foreground", children: "New Sandbox" }),
|
|
1032
|
-
/* @__PURE__ */ jsx10("span", { className: "mt-1 text-xs text-muted-foreground", children: "
|
|
1099
|
+
/* @__PURE__ */ jsx10("span", { className: "mt-1 text-xs text-muted-foreground", children: "Spin up an isolated sandbox" })
|
|
1033
1100
|
]
|
|
1034
1101
|
}
|
|
1035
1102
|
);
|
|
1036
1103
|
}
|
|
1037
1104
|
|
|
1038
1105
|
// src/dashboard/sandbox-table.tsx
|
|
1039
|
-
import * as
|
|
1106
|
+
import * as React6 from "react";
|
|
1040
1107
|
import {
|
|
1041
1108
|
Activity as Activity2,
|
|
1042
1109
|
BarChart2 as BarChart22,
|
|
1043
1110
|
ChevronLeft,
|
|
1044
1111
|
ChevronRight,
|
|
1045
1112
|
Clock as Clock2,
|
|
1046
|
-
Code2
|
|
1113
|
+
Code2,
|
|
1047
1114
|
Copy as Copy2,
|
|
1048
1115
|
ExternalLink,
|
|
1049
1116
|
Key,
|
|
@@ -1051,7 +1118,7 @@ import {
|
|
|
1051
1118
|
Play as Play2,
|
|
1052
1119
|
PowerOff as PowerOff2,
|
|
1053
1120
|
RefreshCw,
|
|
1054
|
-
Terminal
|
|
1121
|
+
Terminal,
|
|
1055
1122
|
Trash2 as Trash22,
|
|
1056
1123
|
User,
|
|
1057
1124
|
Users as Users2
|
|
@@ -1063,7 +1130,7 @@ import {
|
|
|
1063
1130
|
DropdownMenuSeparator as DropdownMenuSeparator3,
|
|
1064
1131
|
DropdownMenuTrigger as DropdownMenuTrigger3
|
|
1065
1132
|
} from "@tangle-network/ui/primitives";
|
|
1066
|
-
import { Fragment as
|
|
1133
|
+
import { Fragment as Fragment7, jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1067
1134
|
var statusColors = {
|
|
1068
1135
|
running: { dot: "bg-[var(--code-success)] animate-pulse", text: "text-[var(--code-success)]", bar: "bg-[var(--code-success)]" },
|
|
1069
1136
|
hibernating: { dot: "bg-muted-foreground", text: "text-muted-foreground", bar: "bg-muted-foreground" },
|
|
@@ -1085,7 +1152,7 @@ function MiniMeter({ label, percent, className }) {
|
|
|
1085
1152
|
"%"
|
|
1086
1153
|
] })
|
|
1087
1154
|
] }),
|
|
1088
|
-
/* @__PURE__ */ jsx11("div", { className: "h-1.5 w-full bg-
|
|
1155
|
+
/* @__PURE__ */ jsx11("div", { className: "h-1.5 w-full bg-muted rounded-full overflow-hidden", children: /* @__PURE__ */ jsx11("div", { className: "h-full bg-primary rounded-full", style: { width: `${percent}%` } }) })
|
|
1089
1156
|
] });
|
|
1090
1157
|
}
|
|
1091
1158
|
function SandboxTable({
|
|
@@ -1125,8 +1192,8 @@ function SandboxTable({
|
|
|
1125
1192
|
return handler ? () => handler(sb.id) : void 0;
|
|
1126
1193
|
};
|
|
1127
1194
|
return /* @__PURE__ */ jsxs10("div", { className: cn("w-full", className), children: [
|
|
1128
|
-
/* @__PURE__ */ jsx11("div", { className: "w-full bg-
|
|
1129
|
-
/* @__PURE__ */ jsx11("thead", { children: /* @__PURE__ */ jsxs10("tr", { className: "bg-
|
|
1195
|
+
/* @__PURE__ */ jsx11("div", { className: "w-full bg-surface-container rounded-2xl overflow-hidden border border-[var(--md3-outline-variant)]", children: /* @__PURE__ */ jsx11("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsxs10("table", { className: "w-full text-left border-collapse", children: [
|
|
1196
|
+
/* @__PURE__ */ jsx11("thead", { children: /* @__PURE__ */ jsxs10("tr", { className: "bg-surface-container-high border-b border-[var(--md3-outline-variant)]", children: [
|
|
1130
1197
|
/* @__PURE__ */ jsx11("th", { className: "px-6 py-4 text-xs font-semibold text-muted-foreground uppercase tracking-wider", children: "Status" }),
|
|
1131
1198
|
/* @__PURE__ */ jsx11("th", { className: "px-6 py-4 text-xs font-semibold text-muted-foreground uppercase tracking-wider", children: "Sandbox Name" }),
|
|
1132
1199
|
hasTeamSandboxes && /* @__PURE__ */ jsx11("th", { className: "px-6 py-4 text-xs font-semibold text-muted-foreground uppercase tracking-wider", children: "Scope" }),
|
|
@@ -1161,7 +1228,7 @@ function SandboxTable({
|
|
|
1161
1228
|
{
|
|
1162
1229
|
className: cn(
|
|
1163
1230
|
"group relative transition-colors",
|
|
1164
|
-
onRowClick ? "cursor-pointer hover:bg-
|
|
1231
|
+
onRowClick ? "cursor-pointer hover:bg-surface-container-high" : "hover:bg-surface-container-high"
|
|
1165
1232
|
),
|
|
1166
1233
|
onClick: onRowClick,
|
|
1167
1234
|
children: [
|
|
@@ -1190,7 +1257,7 @@ function SandboxTable({
|
|
|
1190
1257
|
) : /* @__PURE__ */ jsxs10(
|
|
1191
1258
|
"div",
|
|
1192
1259
|
{
|
|
1193
|
-
className: "inline-flex items-center gap-1.5 rounded-full bg-
|
|
1260
|
+
className: "inline-flex items-center gap-1.5 rounded-full bg-surface-container-high px-2.5 py-1 text-[11px] font-medium text-muted-foreground",
|
|
1194
1261
|
title: "Personal sandbox",
|
|
1195
1262
|
children: [
|
|
1196
1263
|
/* @__PURE__ */ jsx11(User, { className: "h-3 w-3", "aria-hidden": "true" }),
|
|
@@ -1199,7 +1266,7 @@ function SandboxTable({
|
|
|
1199
1266
|
}
|
|
1200
1267
|
) }),
|
|
1201
1268
|
/* @__PURE__ */ jsx11("td", { className: "px-6 py-5", children: /* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-3", children: [
|
|
1202
|
-
sb.imageIcon && /* @__PURE__ */ jsx11("div", { className: "w-8 h-8 rounded-lg bg-
|
|
1269
|
+
sb.imageIcon && /* @__PURE__ */ jsx11("div", { className: "w-8 h-8 rounded-lg bg-surface-container-high flex items-center justify-center", children: sb.imageIcon }),
|
|
1203
1270
|
sb.image && /* @__PURE__ */ jsx11("span", { className: "text-xs font-bold text-foreground", children: sb.image })
|
|
1204
1271
|
] }) }),
|
|
1205
1272
|
/* @__PURE__ */ jsx11("td", { className: "px-6 py-5", children: isActive ? /* @__PURE__ */ jsxs10("div", { className: "space-y-3 w-48", children: [
|
|
@@ -1213,19 +1280,19 @@ function SandboxTable({
|
|
|
1213
1280
|
/* @__PURE__ */ jsx11(MiniMeter, { label: "RAM", percent: 0 })
|
|
1214
1281
|
] }) : null }),
|
|
1215
1282
|
/* @__PURE__ */ jsx11("td", { className: "px-6 py-5 text-right", children: /* @__PURE__ */ jsxs10("div", { className: "flex items-center justify-end gap-1", children: [
|
|
1216
|
-
isActive && /* @__PURE__ */ jsxs10(
|
|
1283
|
+
isActive && /* @__PURE__ */ jsxs10(Fragment7, { children: [
|
|
1217
1284
|
/* @__PURE__ */ jsx11("button", { type: "button", onClick: (e) => {
|
|
1218
1285
|
stopRowClick(e);
|
|
1219
1286
|
onOpenIDE?.(sb.id);
|
|
1220
|
-
}, className: "p-2 rounded-lg hover:bg-
|
|
1287
|
+
}, className: "p-2 rounded-lg hover:bg-surface-container-high text-muted-foreground hover:text-foreground transition-all active:scale-90", title: "Open IDE", children: /* @__PURE__ */ jsx11(Code2, { className: "h-4 w-4" }) }),
|
|
1221
1288
|
/* @__PURE__ */ jsx11("button", { type: "button", onClick: (e) => {
|
|
1222
1289
|
stopRowClick(e);
|
|
1223
1290
|
onOpenTerminal?.(sb.id);
|
|
1224
|
-
}, className: "p-2 rounded-lg hover:bg-
|
|
1291
|
+
}, className: "p-2 rounded-lg hover:bg-surface-container-high text-muted-foreground hover:text-foreground transition-all active:scale-90", title: "Terminal", children: /* @__PURE__ */ jsx11(Terminal, { className: "h-4 w-4" }) }),
|
|
1225
1292
|
/* @__PURE__ */ jsx11("button", { type: "button", onClick: (e) => {
|
|
1226
1293
|
stopRowClick(e);
|
|
1227
1294
|
onSSH?.(sb.id);
|
|
1228
|
-
}, className: "p-2 rounded-lg hover:bg-
|
|
1295
|
+
}, className: "p-2 rounded-lg hover:bg-surface-container-high text-muted-foreground hover:text-foreground transition-all active:scale-90", title: "SSH", children: /* @__PURE__ */ jsx11(Key, { className: "h-4 w-4" }) })
|
|
1229
1296
|
] }),
|
|
1230
1297
|
resumeHandler && /* @__PURE__ */ jsxs10(
|
|
1231
1298
|
"button",
|
|
@@ -1235,7 +1302,7 @@ function SandboxTable({
|
|
|
1235
1302
|
stopRowClick(e);
|
|
1236
1303
|
resumeHandler(sb.id);
|
|
1237
1304
|
},
|
|
1238
|
-
className: "inline-flex items-center gap-1.5 px-3 py-1.5 rounded-lg border border-
|
|
1305
|
+
className: "inline-flex items-center gap-1.5 px-3 py-1.5 rounded-lg border border-[var(--md3-outline-variant)] text-primary text-[10px] font-bold uppercase tracking-wider hover:bg-[var(--accent-surface-soft)] active:scale-95 transition-all",
|
|
1239
1306
|
title: resumeLabel,
|
|
1240
1307
|
children: [
|
|
1241
1308
|
/* @__PURE__ */ jsx11(Play2, { className: "h-3 w-3" }),
|
|
@@ -1305,13 +1372,13 @@ function SandboxTable({
|
|
|
1305
1372
|
{
|
|
1306
1373
|
type: "button",
|
|
1307
1374
|
onClick: stopRowClick,
|
|
1308
|
-
className: "p-2 rounded-lg hover:bg-
|
|
1375
|
+
className: "p-2 rounded-lg hover:bg-surface-container-high text-muted-foreground hover:text-foreground transition-all active:scale-90 outline-none",
|
|
1309
1376
|
"aria-label": "More actions",
|
|
1310
1377
|
title: "More actions",
|
|
1311
1378
|
children: /* @__PURE__ */ jsx11(MoreVertical2, { className: "h-4 w-4" })
|
|
1312
1379
|
}
|
|
1313
1380
|
) }),
|
|
1314
|
-
/* @__PURE__ */ jsx11(DropdownMenuContent3, { align: "end", className: "min-w-[180px]", children: overflowSections.map((section, sectionIdx) => /* @__PURE__ */ jsxs10(
|
|
1381
|
+
/* @__PURE__ */ jsx11(DropdownMenuContent3, { align: "end", className: "min-w-[180px]", children: overflowSections.map((section, sectionIdx) => /* @__PURE__ */ jsxs10(React6.Fragment, { children: [
|
|
1315
1382
|
sectionIdx > 0 && /* @__PURE__ */ jsx11(DropdownMenuSeparator3, {}),
|
|
1316
1383
|
section
|
|
1317
1384
|
] }, sectionIdx)) })
|
|
@@ -1338,7 +1405,7 @@ function SandboxTable({
|
|
|
1338
1405
|
" active sandboxes"
|
|
1339
1406
|
] }),
|
|
1340
1407
|
/* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-2", children: [
|
|
1341
|
-
/* @__PURE__ */ jsx11("button", { type: "button", onClick: () => onPageChange?.(page - 1), disabled: page <= 1, className: "p-2 rounded-lg border border-
|
|
1408
|
+
/* @__PURE__ */ jsx11("button", { type: "button", onClick: () => onPageChange?.(page - 1), disabled: page <= 1, className: "p-2 rounded-lg border border-[var(--md3-outline-variant)] hover:bg-surface-container-high transition-colors disabled:opacity-30", children: /* @__PURE__ */ jsx11(ChevronLeft, { className: "h-4 w-4" }) }),
|
|
1342
1409
|
Array.from({ length: Math.min(totalPages, 5) }, (_, i) => i + 1).map((p) => /* @__PURE__ */ jsx11(
|
|
1343
1410
|
"button",
|
|
1344
1411
|
{
|
|
@@ -1346,13 +1413,13 @@ function SandboxTable({
|
|
|
1346
1413
|
onClick: () => onPageChange?.(p),
|
|
1347
1414
|
className: cn(
|
|
1348
1415
|
"px-3 py-1 rounded-lg transition-colors",
|
|
1349
|
-
p === page ? "bg-[var(--accent-surface-soft)] text-primary border border-
|
|
1416
|
+
p === page ? "bg-[var(--accent-surface-soft)] text-primary border border-[var(--md3-outline)]" : "hover:bg-surface-container-high"
|
|
1350
1417
|
),
|
|
1351
1418
|
children: p
|
|
1352
1419
|
},
|
|
1353
1420
|
p
|
|
1354
1421
|
)),
|
|
1355
|
-
/* @__PURE__ */ jsx11("button", { type: "button", onClick: () => onPageChange?.(page + 1), disabled: page >= totalPages, className: "p-2 rounded-lg border border-
|
|
1422
|
+
/* @__PURE__ */ jsx11("button", { type: "button", onClick: () => onPageChange?.(page + 1), disabled: page >= totalPages, className: "p-2 rounded-lg border border-[var(--md3-outline-variant)] hover:bg-surface-container-high transition-colors disabled:opacity-30", children: /* @__PURE__ */ jsx11(ChevronRight, { className: "h-4 w-4" }) })
|
|
1356
1423
|
] })
|
|
1357
1424
|
] })
|
|
1358
1425
|
] });
|
|
@@ -1362,7 +1429,7 @@ function SandboxTable({
|
|
|
1362
1429
|
import { Download, FileText } from "lucide-react";
|
|
1363
1430
|
import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
1364
1431
|
var statusStyle = {
|
|
1365
|
-
paid: "bg-[var(--accent-surface-soft)] text-primary border border-
|
|
1432
|
+
paid: "bg-[var(--accent-surface-soft)] text-primary border border-[var(--md3-outline-variant)]",
|
|
1366
1433
|
pending: "bg-[var(--surface-warning-bg)] text-[var(--surface-warning-text)] border border-[var(--surface-warning-border)]",
|
|
1367
1434
|
failed: "bg-[var(--surface-danger-bg)] text-[var(--surface-danger-text)] border border-[var(--surface-danger-border)]"
|
|
1368
1435
|
};
|
|
@@ -1375,15 +1442,15 @@ function InvoiceTable({ invoices, onExportAll, onLoadMore, onViewInvoice, hasMor
|
|
|
1375
1442
|
"Export All"
|
|
1376
1443
|
] })
|
|
1377
1444
|
] }),
|
|
1378
|
-
/* @__PURE__ */ jsx12("div", { className: "bg-
|
|
1379
|
-
/* @__PURE__ */ jsx12("thead", { children: /* @__PURE__ */ jsxs11("tr", { className: "bg-
|
|
1445
|
+
/* @__PURE__ */ jsx12("div", { className: "bg-surface-container rounded-xl overflow-hidden border border-[var(--md3-outline-variant)]", children: /* @__PURE__ */ jsxs11("table", { className: "w-full text-left border-collapse", children: [
|
|
1446
|
+
/* @__PURE__ */ jsx12("thead", { children: /* @__PURE__ */ jsxs11("tr", { className: "bg-surface-container-high border-b border-[var(--md3-outline-variant)]", children: [
|
|
1380
1447
|
/* @__PURE__ */ jsx12("th", { className: "px-6 py-4 font-mono text-[10px] text-muted-foreground uppercase tracking-widest", children: "Invoice ID" }),
|
|
1381
1448
|
/* @__PURE__ */ jsx12("th", { className: "px-6 py-4 font-mono text-[10px] text-muted-foreground uppercase tracking-widest", children: "Date" }),
|
|
1382
1449
|
/* @__PURE__ */ jsx12("th", { className: "px-6 py-4 font-mono text-[10px] text-muted-foreground uppercase tracking-widest", children: "Amount" }),
|
|
1383
1450
|
/* @__PURE__ */ jsx12("th", { className: "px-6 py-4 font-mono text-[10px] text-muted-foreground uppercase tracking-widest", children: "Status" }),
|
|
1384
1451
|
/* @__PURE__ */ jsx12("th", { className: "px-6 py-4 font-mono text-[10px] text-muted-foreground uppercase tracking-widest text-right", children: "Action" })
|
|
1385
1452
|
] }) }),
|
|
1386
|
-
/* @__PURE__ */ jsx12("tbody", { className: "divide-y divide-border", children: invoices.map((inv) => /* @__PURE__ */ jsxs11("tr", { className: "hover:bg-
|
|
1453
|
+
/* @__PURE__ */ jsx12("tbody", { className: "divide-y divide-border", children: invoices.map((inv) => /* @__PURE__ */ jsxs11("tr", { className: "hover:bg-surface-container-high transition-colors", children: [
|
|
1387
1454
|
/* @__PURE__ */ jsx12("td", { className: "px-6 py-5 font-mono text-xs text-foreground", children: inv.id }),
|
|
1388
1455
|
/* @__PURE__ */ jsx12("td", { className: "px-6 py-5 text-sm text-foreground", children: inv.date }),
|
|
1389
1456
|
/* @__PURE__ */ jsxs11("td", { className: "px-6 py-5 text-sm font-bold text-foreground", children: [
|
|
@@ -1394,7 +1461,7 @@ function InvoiceTable({ invoices, onExportAll, onLoadMore, onViewInvoice, hasMor
|
|
|
1394
1461
|
/* @__PURE__ */ jsx12("td", { className: "px-6 py-5 text-right", children: /* @__PURE__ */ jsx12("button", { type: "button", onClick: () => onViewInvoice?.(inv.id), className: "text-muted-foreground hover:text-foreground transition-colors", children: /* @__PURE__ */ jsx12(FileText, { className: "h-4 w-4" }) }) })
|
|
1395
1462
|
] }, inv.id)) })
|
|
1396
1463
|
] }) }),
|
|
1397
|
-
hasMore && onLoadMore && /* @__PURE__ */ jsx12("div", { className: "mt-6 flex justify-center", children: /* @__PURE__ */ jsx12("button", { type: "button", onClick: onLoadMore, className: "px-8 py-2 text-[10px] font-mono text-muted-foreground border border-
|
|
1464
|
+
hasMore && onLoadMore && /* @__PURE__ */ jsx12("div", { className: "mt-6 flex justify-center", children: /* @__PURE__ */ jsx12("button", { type: "button", onClick: onLoadMore, className: "px-8 py-2 text-[10px] font-mono text-muted-foreground border border-[var(--md3-outline-variant)] rounded-full hover:bg-surface-container-high transition-colors uppercase tracking-widest", children: "Load More History" }) })
|
|
1398
1465
|
] });
|
|
1399
1466
|
}
|
|
1400
1467
|
|
|
@@ -1409,10 +1476,10 @@ function PlanCards({ plans, className }) {
|
|
|
1409
1476
|
{
|
|
1410
1477
|
className: cn(
|
|
1411
1478
|
"p-5 rounded-xl transition-all relative overflow-hidden border",
|
|
1412
|
-
plan.popular ? "bg-
|
|
1479
|
+
plan.popular ? "bg-surface-container-high border-[var(--md3-outline-variant)]" : "bg-surface-container border-[var(--md3-outline-variant)] hover:bg-surface-container-high hover:border-primary/20"
|
|
1413
1480
|
),
|
|
1414
1481
|
children: [
|
|
1415
|
-
plan.popular && /* @__PURE__ */ jsx13("div", { className: "absolute top-0 right-0 bg-[var(--accent-surface-soft)] border-l border-b border-
|
|
1482
|
+
plan.popular && /* @__PURE__ */ jsx13("div", { className: "absolute top-0 right-0 bg-[var(--accent-surface-soft)] border-l border-b border-[var(--md3-outline-variant)] px-4 py-1 text-[10px] font-bold text-[var(--accent-text)] uppercase tracking-widest rounded-bl-lg", children: "Popular" }),
|
|
1416
1483
|
/* @__PURE__ */ jsxs12("div", { className: "mb-4", children: [
|
|
1417
1484
|
/* @__PURE__ */ jsx13("div", { className: cn("text-xs font-mono uppercase tracking-widest mb-2", plan.popular ? "text-primary" : "text-muted-foreground"), children: plan.name }),
|
|
1418
1485
|
/* @__PURE__ */ jsxs12("div", { className: "text-3xl font-bold text-foreground", children: [
|
|
@@ -1435,7 +1502,7 @@ function PlanCards({ plans, className }) {
|
|
|
1435
1502
|
onClick: () => plan.onSelect?.(plan.id),
|
|
1436
1503
|
className: cn(
|
|
1437
1504
|
"w-full py-3 rounded-lg text-xs font-bold uppercase tracking-widest transition-all border",
|
|
1438
|
-
plan.current ? "border-
|
|
1505
|
+
plan.current ? "border-[var(--md3-outline-variant)] text-muted-foreground hover:border-primary/20 hover:text-foreground" : plan.popular ? "bg-[var(--accent-surface-soft)] border-[var(--md3-outline-variant)] text-[var(--accent-text)] hover:bg-[var(--accent-surface-strong)] active:scale-95 transition-transform" : "border-[var(--md3-outline-variant)] text-foreground hover:border-primary/20 hover:text-primary"
|
|
1439
1506
|
),
|
|
1440
1507
|
children: plan.ctaLabel ?? (plan.current ? "Current Plan" : "Upgrade Now")
|
|
1441
1508
|
}
|
|
@@ -1448,9 +1515,9 @@ function PlanCards({ plans, className }) {
|
|
|
1448
1515
|
}
|
|
1449
1516
|
|
|
1450
1517
|
// src/dashboard/dashboard-layout.tsx
|
|
1451
|
-
import * as
|
|
1518
|
+
import * as React7 from "react";
|
|
1452
1519
|
import { Plus as Plus2, Bell } from "lucide-react";
|
|
1453
|
-
import { Fragment as
|
|
1520
|
+
import { Fragment as Fragment9, jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
1454
1521
|
function SettingsIconSmall({ className }) {
|
|
1455
1522
|
return /* @__PURE__ */ jsxs13("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: [
|
|
1456
1523
|
/* @__PURE__ */ jsx14("title", { children: "Settings" }),
|
|
@@ -1515,10 +1582,10 @@ function DashboardLayoutInner({
|
|
|
1515
1582
|
notifications: notifData
|
|
1516
1583
|
}) {
|
|
1517
1584
|
const Link = LinkComponent;
|
|
1518
|
-
const [mobileMenuOpen, setMobileMenuOpen] =
|
|
1519
|
-
const [notificationsOpen, setNotificationsOpen] =
|
|
1520
|
-
const notifRef =
|
|
1521
|
-
|
|
1585
|
+
const [mobileMenuOpen, setMobileMenuOpen] = React7.useState(false);
|
|
1586
|
+
const [notificationsOpen, setNotificationsOpen] = React7.useState(false);
|
|
1587
|
+
const notifRef = React7.useRef(null);
|
|
1588
|
+
React7.useEffect(() => {
|
|
1522
1589
|
if (!notificationsOpen) return;
|
|
1523
1590
|
const handler = (e) => {
|
|
1524
1591
|
if (notifRef.current && !notifRef.current.contains(e.target)) {
|
|
@@ -1536,14 +1603,14 @@ function DashboardLayoutInner({
|
|
|
1536
1603
|
};
|
|
1537
1604
|
}, [notificationsOpen]);
|
|
1538
1605
|
const { contentMargin, hidden, mode, hasPanels, panelOpen, toggleRail, railCollapsed } = useSidebar();
|
|
1539
|
-
const modeSet =
|
|
1540
|
-
const sidebarUser =
|
|
1606
|
+
const modeSet = React7.useMemo(() => new Set(modeItems), [modeItems]);
|
|
1607
|
+
const sidebarUser = React7.useMemo(
|
|
1541
1608
|
() => user ? { email: user.email, name: user.name, tier: user.tier, avatarUrl: user.avatarUrl } : void 0,
|
|
1542
1609
|
[user?.email, user?.name, user?.tier, user?.avatarUrl]
|
|
1543
1610
|
);
|
|
1544
1611
|
const activePanel = panels.find((p) => p.mode === mode);
|
|
1545
|
-
const buildSidebarContent =
|
|
1546
|
-
(showLabels, allowCollapse) => /* @__PURE__ */ jsxs13(
|
|
1612
|
+
const buildSidebarContent = React7.useCallback(
|
|
1613
|
+
(showLabels, allowCollapse) => /* @__PURE__ */ jsxs13(Fragment9, { children: [
|
|
1547
1614
|
/* @__PURE__ */ jsxs13(SidebarRail, { wide: showLabels, children: [
|
|
1548
1615
|
/* @__PURE__ */ jsx14(SidebarRailHeader, { className: cn(showLabels && "justify-start px-3"), children: onLogoClick ? /* @__PURE__ */ jsx14(
|
|
1549
1616
|
"button",
|
|
@@ -1551,7 +1618,7 @@ function DashboardLayoutInner({
|
|
|
1551
1618
|
type: "button",
|
|
1552
1619
|
onClick: onLogoClick,
|
|
1553
1620
|
"aria-label": logoAriaLabel,
|
|
1554
|
-
className: "p-1 rounded-md transition-colors hover:bg-
|
|
1621
|
+
className: "p-1 rounded-md transition-colors hover:bg-surface-container-high",
|
|
1555
1622
|
children: /* @__PURE__ */ jsx14(Logo, { variant, size: "sm", iconOnly: true })
|
|
1556
1623
|
}
|
|
1557
1624
|
) : labeledRail ? /* @__PURE__ */ jsx14(
|
|
@@ -1561,7 +1628,7 @@ function DashboardLayoutInner({
|
|
|
1561
1628
|
onClick: toggleRail,
|
|
1562
1629
|
"aria-label": railCollapsed ? "Expand navigation" : "Collapse navigation",
|
|
1563
1630
|
"aria-expanded": !railCollapsed,
|
|
1564
|
-
className: "p-1 rounded-md transition-colors hover:bg-
|
|
1631
|
+
className: "p-1 rounded-md transition-colors hover:bg-surface-container-high",
|
|
1565
1632
|
children: /* @__PURE__ */ jsx14(Logo, { variant, size: "sm", iconOnly: true })
|
|
1566
1633
|
}
|
|
1567
1634
|
) : /* @__PURE__ */ jsx14(
|
|
@@ -1569,7 +1636,7 @@ function DashboardLayoutInner({
|
|
|
1569
1636
|
{
|
|
1570
1637
|
href: logoHref,
|
|
1571
1638
|
to: logoHref,
|
|
1572
|
-
className: "p-1 rounded-md transition-colors hover:bg-
|
|
1639
|
+
className: "p-1 rounded-md transition-colors hover:bg-surface-container-high",
|
|
1573
1640
|
children: /* @__PURE__ */ jsx14(Logo, { variant, size: "sm", iconOnly: true })
|
|
1574
1641
|
}
|
|
1575
1642
|
) }),
|
|
@@ -1577,7 +1644,7 @@ function DashboardLayoutInner({
|
|
|
1577
1644
|
const isMode = modeSet.has(item.id);
|
|
1578
1645
|
const prevIsMode = i > 0 && modeSet.has(navItems[i - 1].id);
|
|
1579
1646
|
const showSep = i > 0 && isMode && !prevIsMode;
|
|
1580
|
-
return /* @__PURE__ */ jsxs13(
|
|
1647
|
+
return /* @__PURE__ */ jsxs13(React7.Fragment, { children: [
|
|
1581
1648
|
showSep && /* @__PURE__ */ jsx14(
|
|
1582
1649
|
RailSeparator,
|
|
1583
1650
|
{
|
|
@@ -1664,23 +1731,23 @@ function DashboardLayoutInner({
|
|
|
1664
1731
|
mode
|
|
1665
1732
|
]
|
|
1666
1733
|
);
|
|
1667
|
-
const sidebarContent =
|
|
1734
|
+
const sidebarContent = React7.useMemo(
|
|
1668
1735
|
() => buildSidebarContent(labeledRail && !railCollapsed, labeledRail),
|
|
1669
1736
|
[buildSidebarContent, labeledRail, railCollapsed]
|
|
1670
1737
|
);
|
|
1671
|
-
const mobileSidebarContent =
|
|
1672
|
-
return /* @__PURE__ */ jsxs13("div", { className: cn("min-h-screen bg-
|
|
1738
|
+
const mobileSidebarContent = React7.useMemo(() => buildSidebarContent(true, false), [buildSidebarContent]);
|
|
1739
|
+
return /* @__PURE__ */ jsxs13("div", { className: cn("min-h-screen bg-surface text-foreground", className), children: [
|
|
1673
1740
|
/* @__PURE__ */ jsxs13(
|
|
1674
1741
|
"nav",
|
|
1675
1742
|
{
|
|
1676
|
-
className: "fixed top-0 z-50 bg-
|
|
1743
|
+
className: "fixed top-0 z-50 bg-surface-container-low border-b border-[var(--md3-outline-variant)] flex justify-between items-center px-8 h-14 font-sans text-[13px] tracking-tight transition-[left,width] duration-200 ease-in-out",
|
|
1677
1744
|
style: {
|
|
1678
1745
|
left: hidden ? 0 : contentMargin,
|
|
1679
1746
|
width: hidden ? "100%" : `calc(100% - ${contentMargin}px)`
|
|
1680
1747
|
},
|
|
1681
1748
|
children: [
|
|
1682
1749
|
/* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-8", children: [
|
|
1683
|
-
/* @__PURE__ */ jsx14(Link, { href: logoHref, to: logoHref, className: "lg:hidden flex items-center p-1 rounded-md hover:bg-
|
|
1750
|
+
/* @__PURE__ */ jsx14(Link, { href: logoHref, to: logoHref, className: "lg:hidden flex items-center p-1 rounded-md hover:bg-surface-container-high transition-colors", children: /* @__PURE__ */ jsx14(Logo, { variant, size: "sm", iconOnly: true }) }),
|
|
1684
1751
|
topNavLinks && topNavLinks.length > 0 && /* @__PURE__ */ jsx14("div", { className: "hidden md:flex gap-6", children: topNavLinks.map((link) => /* @__PURE__ */ jsx14(
|
|
1685
1752
|
Link,
|
|
1686
1753
|
{
|
|
@@ -1688,7 +1755,7 @@ function DashboardLayoutInner({
|
|
|
1688
1755
|
to: link.href,
|
|
1689
1756
|
className: cn(
|
|
1690
1757
|
"transition-all duration-300 px-2 py-1 rounded",
|
|
1691
|
-
activeTopNavHref === link.href ? "text-foreground border-b-2 border-primary pb-1" : "text-muted-foreground hover:text-foreground hover:bg-
|
|
1758
|
+
activeTopNavHref === link.href ? "text-foreground border-b-2 border-primary pb-1" : "text-muted-foreground hover:text-foreground hover:bg-surface-container-high"
|
|
1692
1759
|
),
|
|
1693
1760
|
children: link.label
|
|
1694
1761
|
},
|
|
@@ -1713,7 +1780,7 @@ function DashboardLayoutInner({
|
|
|
1713
1780
|
"button",
|
|
1714
1781
|
{
|
|
1715
1782
|
type: "button",
|
|
1716
|
-
className: "relative text-muted-foreground hover:text-foreground transition-colors p-2 rounded-lg hover:bg-
|
|
1783
|
+
className: "relative text-muted-foreground hover:text-foreground transition-colors p-2 rounded-lg hover:bg-surface-container-high",
|
|
1717
1784
|
onClick: () => setNotificationsOpen(!notificationsOpen),
|
|
1718
1785
|
"aria-label": "Notifications",
|
|
1719
1786
|
"aria-expanded": notificationsOpen,
|
|
@@ -1723,8 +1790,8 @@ function DashboardLayoutInner({
|
|
|
1723
1790
|
]
|
|
1724
1791
|
}
|
|
1725
1792
|
),
|
|
1726
|
-
notificationsOpen && /* @__PURE__ */ jsxs13("div", { className: "absolute right-0 top-full mt-2 w-80 rounded-lg border border-
|
|
1727
|
-
/* @__PURE__ */ jsxs13("div", { className: "flex items-center justify-between border-b border-
|
|
1793
|
+
notificationsOpen && /* @__PURE__ */ jsxs13("div", { className: "absolute right-0 top-full mt-2 w-80 rounded-lg border border-[var(--md3-outline-variant)] bg-surface-container-highest shadow-[0_8px_30px_rgba(0,0,0,0.45)] ring-1 ring-[#ffffff14] z-50", children: [
|
|
1794
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex items-center justify-between border-b border-[var(--md3-outline-variant)] px-4 py-3", children: [
|
|
1728
1795
|
/* @__PURE__ */ jsx14("p", { className: "font-bold text-foreground text-sm", children: "Notifications" }),
|
|
1729
1796
|
(notifData?.unreadCount ?? 0) > 0 && notifData?.onMarkAllRead && /* @__PURE__ */ jsx14(
|
|
1730
1797
|
"button",
|
|
@@ -1747,8 +1814,8 @@ function DashboardLayoutInner({
|
|
|
1747
1814
|
{
|
|
1748
1815
|
type: "button",
|
|
1749
1816
|
className: cn(
|
|
1750
|
-
"w-full text-left px-4 py-3 border-b border-
|
|
1751
|
-
n.read ? "cursor-default" : "bg-primary/5 hover:bg-
|
|
1817
|
+
"w-full text-left px-4 py-3 border-b border-[var(--md3-outline-variant)] last:border-0 transition-colors",
|
|
1818
|
+
n.read ? "cursor-default" : "bg-primary/5 hover:bg-white/5"
|
|
1752
1819
|
),
|
|
1753
1820
|
onClick: () => {
|
|
1754
1821
|
if (!n.read) notifData.onMarkRead?.(n.id);
|
|
@@ -1769,7 +1836,7 @@ function DashboardLayoutInner({
|
|
|
1769
1836
|
{
|
|
1770
1837
|
type: "button",
|
|
1771
1838
|
onClick: () => setMobileMenuOpen(!mobileMenuOpen),
|
|
1772
|
-
className: "rounded-md p-2 hover:bg-
|
|
1839
|
+
className: "rounded-md p-2 hover:bg-surface-container-high lg:hidden",
|
|
1773
1840
|
"aria-label": mobileMenuOpen ? "Close menu" : "Open menu",
|
|
1774
1841
|
"aria-expanded": mobileMenuOpen,
|
|
1775
1842
|
children: mobileMenuOpen ? /* @__PURE__ */ jsx14(XIcon, { className: "h-6 w-6" }) : /* @__PURE__ */ jsx14(MenuIcon, { className: "h-6 w-6" })
|
|
@@ -1783,7 +1850,7 @@ function DashboardLayoutInner({
|
|
|
1783
1850
|
"aside",
|
|
1784
1851
|
{
|
|
1785
1852
|
className: cn(
|
|
1786
|
-
"fixed top-14 bottom-0 left-0 z-30 flex bg-
|
|
1853
|
+
"fixed top-14 bottom-0 left-0 z-30 flex bg-surface-container-low transition-transform duration-200 lg:hidden",
|
|
1787
1854
|
mobileMenuOpen ? "translate-x-0" : "-translate-x-full"
|
|
1788
1855
|
),
|
|
1789
1856
|
style: {
|
|
@@ -1793,7 +1860,7 @@ function DashboardLayoutInner({
|
|
|
1793
1860
|
}
|
|
1794
1861
|
),
|
|
1795
1862
|
/* @__PURE__ */ jsx14(Sidebar, { className: cn("hidden lg:flex", sidebarClassName), children: sidebarContent }),
|
|
1796
|
-
/* @__PURE__ */ jsx14(SidebarContent, { className: cn("pt-16 px-6 pb-8 lg:px-8 bg-
|
|
1863
|
+
/* @__PURE__ */ jsx14(SidebarContent, { className: cn("pt-16 px-6 pb-8 lg:px-8 bg-surface", contentClassName), children }),
|
|
1797
1864
|
footer
|
|
1798
1865
|
] });
|
|
1799
1866
|
}
|
|
@@ -1845,7 +1912,7 @@ function SidebarLayoutInner({
|
|
|
1845
1912
|
const handleNavClick = closePanelOnNavigate && panelOpen ? () => setPanelOpen(false) : void 0;
|
|
1846
1913
|
const hasProfile = user !== void 0 || onLogout !== void 0 || onSettingsClick !== void 0;
|
|
1847
1914
|
const showLabels = railLabels && !railCollapsed;
|
|
1848
|
-
return /* @__PURE__ */ jsxs14("div", { className: cn("min-h-screen bg-
|
|
1915
|
+
return /* @__PURE__ */ jsxs14("div", { className: cn("min-h-screen bg-surface text-foreground", className), children: [
|
|
1849
1916
|
/* @__PURE__ */ jsx15("div", { className: cn(hideBelow && HIDE_BELOW_CLASS[hideBelow]), children: /* @__PURE__ */ jsxs14(Sidebar, { className: sidebarClassName, children: [
|
|
1850
1917
|
/* @__PURE__ */ jsxs14(SidebarRail, { children: [
|
|
1851
1918
|
(railHeaderContent !== void 0 || logo !== void 0) && /* @__PURE__ */ jsx15(SidebarRailHeader, { className: cn(showLabels && (railHeaderContent !== void 0 ? "px-2" : "justify-start px-4")), children: railHeaderContent !== void 0 ? railHeaderContent : /* @__PURE__ */ jsx15(
|
|
@@ -1853,7 +1920,7 @@ function SidebarLayoutInner({
|
|
|
1853
1920
|
{
|
|
1854
1921
|
href: logoHref,
|
|
1855
1922
|
to: logoHref,
|
|
1856
|
-
className: "flex items-center justify-center rounded-lg p-1 transition-colors hover:bg-
|
|
1923
|
+
className: "flex items-center justify-center rounded-lg p-1 transition-colors hover:bg-surface-container-high",
|
|
1857
1924
|
children: logo
|
|
1858
1925
|
}
|
|
1859
1926
|
) }),
|
|
@@ -1915,7 +1982,7 @@ function SidebarLayoutInner({
|
|
|
1915
1982
|
}
|
|
1916
1983
|
) }, item.id);
|
|
1917
1984
|
}) }),
|
|
1918
|
-
(railLabels || railFooter !== void 0 || hasProfile) && /* @__PURE__ */ jsxs14(SidebarRailFooter, { className: cn("border-t border-
|
|
1985
|
+
(railLabels || railFooter !== void 0 || hasProfile) && /* @__PURE__ */ jsxs14(SidebarRailFooter, { className: cn("border-t border-[var(--md3-outline-variant)] pt-2", showLabels && "items-stretch px-2"), children: [
|
|
1919
1986
|
railLabels && /* @__PURE__ */ jsx15(RailCollapseToggle, { collapsed: railCollapsed, showLabel: showLabels, onToggle: toggleRail }),
|
|
1920
1987
|
railFooter,
|
|
1921
1988
|
hasProfile && (() => {
|
|
@@ -1985,7 +2052,7 @@ import {
|
|
|
1985
2052
|
DropdownMenuSeparator as DropdownMenuSeparator4,
|
|
1986
2053
|
DropdownMenuTrigger as DropdownMenuTrigger4
|
|
1987
2054
|
} from "@tangle-network/ui/primitives";
|
|
1988
|
-
import { Fragment as
|
|
2055
|
+
import { Fragment as Fragment10, jsx as jsx16, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
1989
2056
|
function ProfileSelector({
|
|
1990
2057
|
profiles,
|
|
1991
2058
|
selectedId,
|
|
@@ -2019,7 +2086,7 @@ function ProfileSelector({
|
|
|
2019
2086
|
]
|
|
2020
2087
|
}
|
|
2021
2088
|
),
|
|
2022
|
-
builtinProfiles.length > 0 && /* @__PURE__ */ jsxs15(
|
|
2089
|
+
builtinProfiles.length > 0 && /* @__PURE__ */ jsxs15(Fragment10, { children: [
|
|
2023
2090
|
/* @__PURE__ */ jsx16(DropdownMenuSeparator4, {}),
|
|
2024
2091
|
/* @__PURE__ */ jsx16(DropdownMenuLabel2, { children: "Built-in Profiles" }),
|
|
2025
2092
|
builtinProfiles.map((profile) => /* @__PURE__ */ jsxs15(
|
|
@@ -2044,7 +2111,7 @@ function ProfileSelector({
|
|
|
2044
2111
|
profile.id
|
|
2045
2112
|
))
|
|
2046
2113
|
] }),
|
|
2047
|
-
customProfiles.length > 0 && /* @__PURE__ */ jsxs15(
|
|
2114
|
+
customProfiles.length > 0 && /* @__PURE__ */ jsxs15(Fragment10, { children: [
|
|
2048
2115
|
/* @__PURE__ */ jsx16(DropdownMenuSeparator4, {}),
|
|
2049
2116
|
/* @__PURE__ */ jsx16(DropdownMenuLabel2, { children: "Custom Profiles" }),
|
|
2050
2117
|
customProfiles.map((profile) => /* @__PURE__ */ jsxs15(
|
|
@@ -2081,7 +2148,7 @@ function ProfileSelector({
|
|
|
2081
2148
|
profile.id
|
|
2082
2149
|
))
|
|
2083
2150
|
] }),
|
|
2084
|
-
(onCreateClick || onManageClick) && /* @__PURE__ */ jsxs15(
|
|
2151
|
+
(onCreateClick || onManageClick) && /* @__PURE__ */ jsxs15(Fragment10, { children: [
|
|
2085
2152
|
/* @__PURE__ */ jsx16(DropdownMenuSeparator4, {}),
|
|
2086
2153
|
onCreateClick && /* @__PURE__ */ jsxs15(
|
|
2087
2154
|
DropdownMenuItem4,
|
|
@@ -2126,7 +2193,7 @@ function ProfileComparison({
|
|
|
2126
2193
|
const fastestProfile = profilesWithMetrics.reduce(
|
|
2127
2194
|
(best, p) => (p.metrics?.avg_duration_ms ?? Number.POSITIVE_INFINITY) < (best.metrics?.avg_duration_ms ?? Number.POSITIVE_INFINITY) ? p : best
|
|
2128
2195
|
);
|
|
2129
|
-
return /* @__PURE__ */ jsxs15("div", { className: `rounded-lg border border-
|
|
2196
|
+
return /* @__PURE__ */ jsxs15("div", { className: `rounded-lg border border-[var(--md3-outline-variant)] bg-surface-container p-4 ${className ?? ""}`, children: [
|
|
2130
2197
|
/* @__PURE__ */ jsx16("h4", { className: "mb-3 font-medium text-sm", children: "Profile Performance" }),
|
|
2131
2198
|
/* @__PURE__ */ jsx16("div", { className: "space-y-3", children: profilesWithMetrics.map((profile) => {
|
|
2132
2199
|
const isBestSuccess = profile.id === bestSuccess.id;
|
|
@@ -2176,7 +2243,7 @@ function ProfileComparison({
|
|
|
2176
2243
|
}
|
|
2177
2244
|
|
|
2178
2245
|
// src/dashboard/metric-area-chart.tsx
|
|
2179
|
-
import * as
|
|
2246
|
+
import * as React8 from "react";
|
|
2180
2247
|
import { jsx as jsx17, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
2181
2248
|
var TONE_VARS = {
|
|
2182
2249
|
primary: "var(--brand-primary, hsl(var(--primary)))",
|
|
@@ -2223,7 +2290,7 @@ function MetricAreaChart({
|
|
|
2223
2290
|
emptyState,
|
|
2224
2291
|
className
|
|
2225
2292
|
}) {
|
|
2226
|
-
const gradientId =
|
|
2293
|
+
const gradientId = React8.useId();
|
|
2227
2294
|
const width = 400;
|
|
2228
2295
|
const values = points.map((p) => p.value).filter((v) => v !== null);
|
|
2229
2296
|
const latest = values.length > 0 ? values[values.length - 1] : null;
|
|
@@ -2235,7 +2302,7 @@ function MetricAreaChart({
|
|
|
2235
2302
|
"div",
|
|
2236
2303
|
{
|
|
2237
2304
|
className: cn(
|
|
2238
|
-
"rounded-lg border border-
|
|
2305
|
+
"rounded-lg border border-[var(--md3-outline-variant)] bg-surface-container p-4 shadow-sm",
|
|
2239
2306
|
className
|
|
2240
2307
|
),
|
|
2241
2308
|
"data-testid": `metric-chart-${label.toLowerCase().replace(/\s+/g, "-")}`,
|
|
@@ -2283,7 +2350,7 @@ function MetricAreaChart({
|
|
|
2283
2350
|
/* @__PURE__ */ jsx17("stop", { offset: "0%", stopColor: color, stopOpacity: 0.28 }),
|
|
2284
2351
|
/* @__PURE__ */ jsx17("stop", { offset: "100%", stopColor: color, stopOpacity: 0.02 })
|
|
2285
2352
|
] }) }),
|
|
2286
|
-
segments.map((segment) => /* @__PURE__ */ jsxs16(
|
|
2353
|
+
segments.map((segment) => /* @__PURE__ */ jsxs16(React8.Fragment, { children: [
|
|
2287
2354
|
/* @__PURE__ */ jsx17("path", { d: segment.area, fill: `url(#${gradientId})` }),
|
|
2288
2355
|
/* @__PURE__ */ jsx17(
|
|
2289
2356
|
"path",
|
|
@@ -2323,7 +2390,7 @@ import {
|
|
|
2323
2390
|
} from "lucide-react";
|
|
2324
2391
|
import { Button as Button3 } from "@tangle-network/ui/primitives";
|
|
2325
2392
|
import { Badge as Badge2 } from "@tangle-network/ui/primitives";
|
|
2326
|
-
import { Fragment as
|
|
2393
|
+
import { Fragment as Fragment12, jsx as jsx18, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
2327
2394
|
var statusConfig = {
|
|
2328
2395
|
pending: {
|
|
2329
2396
|
icon: Clock3,
|
|
@@ -2337,7 +2404,7 @@ var statusConfig = {
|
|
|
2337
2404
|
icon: Loader2,
|
|
2338
2405
|
color: "text-primary",
|
|
2339
2406
|
bg: "bg-[var(--accent-surface-soft)]",
|
|
2340
|
-
border: "border-
|
|
2407
|
+
border: "border-[var(--md3-outline-variant)]",
|
|
2341
2408
|
label: "Running",
|
|
2342
2409
|
animate: true
|
|
2343
2410
|
},
|
|
@@ -2414,7 +2481,7 @@ function VariantList({
|
|
|
2414
2481
|
return /* @__PURE__ */ jsxs17(
|
|
2415
2482
|
"div",
|
|
2416
2483
|
{
|
|
2417
|
-
className: `cursor-pointer rounded-lg border px-3 py-2.5 transition-colors ${isSelected ? "border-primary/30 bg-[var(--accent-surface-soft)]" : "border-
|
|
2484
|
+
className: `cursor-pointer rounded-lg border px-3 py-2.5 transition-colors ${isSelected ? "border-primary/30 bg-[var(--accent-surface-soft)]" : "border-[var(--md3-outline-variant)] bg-surface-container hover:border-primary/20 hover:bg-surface-container-high"}`,
|
|
2418
2485
|
onClick: () => onSelect?.(variant.id),
|
|
2419
2486
|
children: [
|
|
2420
2487
|
/* @__PURE__ */ jsxs17("div", { className: "flex items-center gap-2", children: [
|
|
@@ -2446,7 +2513,7 @@ function VariantList({
|
|
|
2446
2513
|
children: outcomeConfig[variant.outcome].label
|
|
2447
2514
|
}
|
|
2448
2515
|
),
|
|
2449
|
-
variant.status === "completed" && variant.outcome === "pending_review" && onAccept && onReject && /* @__PURE__ */ jsxs17(
|
|
2516
|
+
variant.status === "completed" && variant.outcome === "pending_review" && onAccept && onReject && /* @__PURE__ */ jsxs17(Fragment12, { children: [
|
|
2450
2517
|
/* @__PURE__ */ jsxs17(
|
|
2451
2518
|
Button3,
|
|
2452
2519
|
{
|
|
@@ -2507,7 +2574,7 @@ function VariantList({
|
|
|
2507
2574
|
}
|
|
2508
2575
|
|
|
2509
2576
|
// src/dashboard/system-logs.tsx
|
|
2510
|
-
import { Terminal as
|
|
2577
|
+
import { Terminal as Terminal2 } from "lucide-react";
|
|
2511
2578
|
import { useEffect as useEffect3, useRef as useRef3, useState as useState5 } from "react";
|
|
2512
2579
|
import { jsx as jsx19, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
2513
2580
|
function SystemLogsViewer({ apiUrl, token, className }) {
|
|
@@ -2562,10 +2629,10 @@ function SystemLogsViewer({ apiUrl, token, className }) {
|
|
|
2562
2629
|
const isAtBottom = scrollHeight - scrollTop - clientHeight < 20;
|
|
2563
2630
|
setIsFollowing((prev) => prev === isAtBottom ? prev : isAtBottom);
|
|
2564
2631
|
};
|
|
2565
|
-
return /* @__PURE__ */ jsxs18("div", { className: cn("flex flex-col h-full bg-
|
|
2566
|
-
/* @__PURE__ */ jsxs18("div", { className: "flex-none flex items-center justify-between border-b border-
|
|
2632
|
+
return /* @__PURE__ */ jsxs18("div", { className: cn("flex flex-col h-full bg-surface-dim text-foreground font-mono text-sm leading-relaxed overflow-hidden rounded-lg border border-[var(--md3-outline-variant)]", className), children: [
|
|
2633
|
+
/* @__PURE__ */ jsxs18("div", { className: "flex-none flex items-center justify-between border-b border-[var(--md3-outline-variant)] bg-surface-container-high backdrop-blur-md px-4 py-2", children: [
|
|
2567
2634
|
/* @__PURE__ */ jsxs18("div", { className: "flex items-center gap-2", children: [
|
|
2568
|
-
/* @__PURE__ */ jsx19(
|
|
2635
|
+
/* @__PURE__ */ jsx19(Terminal2, { className: "h-4 w-4 text-primary animate-pulse" }),
|
|
2569
2636
|
/* @__PURE__ */ jsx19("span", { className: "font-bold text-xs uppercase tracking-widest text-muted-foreground", children: "System Traces" })
|
|
2570
2637
|
] }),
|
|
2571
2638
|
/* @__PURE__ */ jsxs18("div", { className: "flex items-center gap-3", children: [
|
|
@@ -2582,7 +2649,7 @@ function SystemLogsViewer({ apiUrl, token, className }) {
|
|
|
2582
2649
|
scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
|
|
2583
2650
|
}
|
|
2584
2651
|
},
|
|
2585
|
-
className: cn("px-3 py-1 text-[10px] font-bold uppercase rounded-md transition-colors", isFollowing ? "bg-primary/20 text-primary border border-primary/20" : "bg-
|
|
2652
|
+
className: cn("px-3 py-1 text-[10px] font-bold uppercase rounded-md transition-colors", isFollowing ? "bg-primary/20 text-primary border border-primary/20" : "bg-surface-container-high text-muted-foreground border border-[var(--md3-outline-variant)] hover:bg-accent hover:text-foreground"),
|
|
2586
2653
|
children: isFollowing ? "Auto-Scroll ON" : "Auto-Scroll OFF"
|
|
2587
2654
|
}
|
|
2588
2655
|
)
|
|
@@ -2678,11 +2745,11 @@ function GitPanel({ status, log, loading = false, onRefresh, className }) {
|
|
|
2678
2745
|
return /* @__PURE__ */ jsxs20(
|
|
2679
2746
|
"div",
|
|
2680
2747
|
{
|
|
2681
|
-
className: cn("rounded-lg border border-
|
|
2748
|
+
className: cn("rounded-lg border border-[var(--md3-outline-variant)] bg-surface-container overflow-hidden", className),
|
|
2682
2749
|
"aria-busy": "true",
|
|
2683
2750
|
children: [
|
|
2684
2751
|
/* @__PURE__ */ jsx21("span", { className: "sr-only", children: "Loading git info\u2026" }),
|
|
2685
|
-
/* @__PURE__ */ jsx21("div", { className: "flex items-center justify-between border-b border-
|
|
2752
|
+
/* @__PURE__ */ jsx21("div", { className: "flex items-center justify-between border-b border-[var(--md3-outline-variant)] bg-surface-container-high px-4 py-3", children: /* @__PURE__ */ jsxs20("div", { className: "flex items-center gap-2", children: [
|
|
2686
2753
|
/* @__PURE__ */ jsx21(GitBranch, { className: "h-4 w-4 text-muted-foreground" }),
|
|
2687
2754
|
/* @__PURE__ */ jsx21("div", { className: "h-3.5 w-24 animate-pulse rounded bg-muted" })
|
|
2688
2755
|
] }) }),
|
|
@@ -2698,14 +2765,14 @@ function GitPanel({ status, log, loading = false, onRefresh, className }) {
|
|
|
2698
2765
|
);
|
|
2699
2766
|
}
|
|
2700
2767
|
if (!status) {
|
|
2701
|
-
return /* @__PURE__ */ jsx21("div", { className: cn("rounded-lg border border-
|
|
2768
|
+
return /* @__PURE__ */ jsx21("div", { className: cn("rounded-lg border border-[var(--md3-outline-variant)] bg-surface-container p-5", className), children: /* @__PURE__ */ jsxs20("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [
|
|
2702
2769
|
/* @__PURE__ */ jsx21(GitBranch, { className: "h-4 w-4" }),
|
|
2703
2770
|
"No git repository detected"
|
|
2704
2771
|
] }) });
|
|
2705
2772
|
}
|
|
2706
2773
|
const changedCount = status.staged.length + status.modified.length + status.untracked.length;
|
|
2707
|
-
return /* @__PURE__ */ jsxs20("div", { className: cn("rounded-lg border border-
|
|
2708
|
-
/* @__PURE__ */ jsxs20("div", { className: "flex items-center justify-between border-b border-
|
|
2774
|
+
return /* @__PURE__ */ jsxs20("div", { className: cn("rounded-lg border border-[var(--md3-outline-variant)] bg-surface-container overflow-hidden", className), children: [
|
|
2775
|
+
/* @__PURE__ */ jsxs20("div", { className: "flex items-center justify-between border-b border-[var(--md3-outline-variant)] bg-surface-container-high px-4 py-3", children: [
|
|
2709
2776
|
/* @__PURE__ */ jsxs20("div", { className: "flex items-center gap-2", children: [
|
|
2710
2777
|
/* @__PURE__ */ jsx21(GitBranch, { className: "h-4 w-4 text-primary" }),
|
|
2711
2778
|
/* @__PURE__ */ jsx21("span", { className: "text-sm font-bold text-foreground", children: status.branch }),
|
|
@@ -2717,7 +2784,7 @@ function GitPanel({ status, log, loading = false, onRefresh, className }) {
|
|
|
2717
2784
|
] }),
|
|
2718
2785
|
onRefresh && /* @__PURE__ */ jsx21("button", { type: "button", onClick: onRefresh, className: "text-xs text-muted-foreground hover:text-foreground transition-colors", children: "Refresh" })
|
|
2719
2786
|
] }),
|
|
2720
|
-
changedCount > 0 && /* @__PURE__ */ jsx21("div", { className: "border-b border-
|
|
2787
|
+
changedCount > 0 && /* @__PURE__ */ jsx21("div", { className: "border-b border-[var(--md3-outline-variant)] px-4 py-3", children: /* @__PURE__ */ jsxs20("div", { className: "space-y-1.5", children: [
|
|
2721
2788
|
status.staged.map((f) => /* @__PURE__ */ jsxs20("div", { className: "flex items-center gap-2 text-xs", children: [
|
|
2722
2789
|
/* @__PURE__ */ jsx21(FilePlus, { className: "h-3 w-3 text-[var(--surface-success-text)]" }),
|
|
2723
2790
|
/* @__PURE__ */ jsx21("span", { className: "font-mono text-foreground truncate", children: f }),
|
|
@@ -2742,7 +2809,7 @@ function GitPanel({ status, log, loading = false, onRefresh, className }) {
|
|
|
2742
2809
|
] })
|
|
2743
2810
|
] }, commit.shortSha)) })
|
|
2744
2811
|
] }),
|
|
2745
|
-
(status.ahead > 0 || status.behind > 0) && /* @__PURE__ */ jsxs20("div", { className: "border-t border-
|
|
2812
|
+
(status.ahead > 0 || status.behind > 0) && /* @__PURE__ */ jsxs20("div", { className: "border-t border-[var(--md3-outline-variant)] px-4 py-2 flex items-center gap-3 text-xs text-muted-foreground", children: [
|
|
2746
2813
|
status.ahead > 0 && /* @__PURE__ */ jsxs20("span", { children: [
|
|
2747
2814
|
"\u2191 ",
|
|
2748
2815
|
status.ahead,
|
|
@@ -2758,14 +2825,14 @@ function GitPanel({ status, log, loading = false, onRefresh, className }) {
|
|
|
2758
2825
|
}
|
|
2759
2826
|
|
|
2760
2827
|
// src/dashboard/ports-list.tsx
|
|
2761
|
-
import * as
|
|
2828
|
+
import * as React10 from "react";
|
|
2762
2829
|
import { Copy as Copy3, Check as Check4, Globe, Plus as Plus4, Trash2 as Trash23 } from "lucide-react";
|
|
2763
2830
|
import { jsx as jsx22, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
2764
2831
|
function PortsList({ ports, onExposePort, onRemovePort, isExposing = false, className }) {
|
|
2765
|
-
const [newPort, setNewPort] =
|
|
2766
|
-
const [copiedPort, setCopiedPort] =
|
|
2767
|
-
const copyTimerRef =
|
|
2768
|
-
|
|
2832
|
+
const [newPort, setNewPort] = React10.useState("");
|
|
2833
|
+
const [copiedPort, setCopiedPort] = React10.useState(null);
|
|
2834
|
+
const copyTimerRef = React10.useRef(null);
|
|
2835
|
+
React10.useEffect(() => {
|
|
2769
2836
|
return () => {
|
|
2770
2837
|
if (copyTimerRef.current) clearTimeout(copyTimerRef.current);
|
|
2771
2838
|
};
|
|
@@ -2788,8 +2855,8 @@ function PortsList({ ports, onExposePort, onRemovePort, isExposing = false, clas
|
|
|
2788
2855
|
}
|
|
2789
2856
|
};
|
|
2790
2857
|
return /* @__PURE__ */ jsxs21("div", { className: cn("space-y-4", className), children: [
|
|
2791
|
-
ports.length > 0 ? /* @__PURE__ */ jsx22("div", { className: "rounded-lg border border-
|
|
2792
|
-
/* @__PURE__ */ jsx22("thead", { className: "bg-
|
|
2858
|
+
ports.length > 0 ? /* @__PURE__ */ jsx22("div", { className: "rounded-lg border border-[var(--md3-outline-variant)] bg-surface-container overflow-hidden", children: /* @__PURE__ */ jsxs21("table", { className: "w-full text-sm", children: [
|
|
2859
|
+
/* @__PURE__ */ jsx22("thead", { className: "bg-surface-container-high border-b border-[var(--md3-outline-variant)]", children: /* @__PURE__ */ jsxs21("tr", { children: [
|
|
2793
2860
|
/* @__PURE__ */ jsx22("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "Port" }),
|
|
2794
2861
|
/* @__PURE__ */ jsx22("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "Public URL" }),
|
|
2795
2862
|
/* @__PURE__ */ jsx22("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "Status" }),
|
|
@@ -2823,7 +2890,7 @@ function PortsList({ ports, onExposePort, onRemovePort, isExposing = false, clas
|
|
|
2823
2890
|
}
|
|
2824
2891
|
) })
|
|
2825
2892
|
] }, p.port)) })
|
|
2826
|
-
] }) }) : /* @__PURE__ */ jsxs21("div", { className: "rounded-lg border border-
|
|
2893
|
+
] }) }) : /* @__PURE__ */ jsxs21("div", { className: "rounded-lg border border-[var(--md3-outline-variant)] bg-surface-container p-6 text-center", children: [
|
|
2827
2894
|
/* @__PURE__ */ jsx22(Globe, { className: "mx-auto h-8 w-8 text-muted-foreground mb-2" }),
|
|
2828
2895
|
/* @__PURE__ */ jsx22("p", { className: "text-sm text-muted-foreground", children: "No ports exposed yet" })
|
|
2829
2896
|
] }),
|
|
@@ -2838,7 +2905,7 @@ function PortsList({ ports, onExposePort, onRemovePort, isExposing = false, clas
|
|
|
2838
2905
|
value: newPort,
|
|
2839
2906
|
onChange: (e) => setNewPort(e.target.value),
|
|
2840
2907
|
onKeyDown: (e) => e.key === "Enter" && handleExpose(),
|
|
2841
|
-
className: "flex-1 rounded-lg border border-
|
|
2908
|
+
className: "flex-1 rounded-lg border border-[var(--md3-outline-variant)] bg-surface-container-low px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus-visible:ring-1 focus-visible:ring-ring"
|
|
2842
2909
|
}
|
|
2843
2910
|
),
|
|
2844
2911
|
/* @__PURE__ */ jsxs21(
|
|
@@ -2859,8 +2926,8 @@ function PortsList({ ports, onExposePort, onRemovePort, isExposing = false, clas
|
|
|
2859
2926
|
}
|
|
2860
2927
|
|
|
2861
2928
|
// src/dashboard/process-list.tsx
|
|
2862
|
-
import * as
|
|
2863
|
-
import { Activity as Activity3, Plus as Plus5, Skull, Terminal as
|
|
2929
|
+
import * as React11 from "react";
|
|
2930
|
+
import { Activity as Activity3, Plus as Plus5, Skull, Terminal as Terminal3 } from "lucide-react";
|
|
2864
2931
|
import { jsx as jsx23, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
2865
2932
|
function formatUptime(startedAt) {
|
|
2866
2933
|
if (!startedAt) return "-";
|
|
@@ -2871,7 +2938,7 @@ function formatUptime(startedAt) {
|
|
|
2871
2938
|
return `${Math.floor(ms / 36e5)}h ${Math.floor(ms % 36e5 / 6e4)}m`;
|
|
2872
2939
|
}
|
|
2873
2940
|
function ProcessList({ processes, onSpawn, onKill, loading = false, className }) {
|
|
2874
|
-
const [newCommand, setNewCommand] =
|
|
2941
|
+
const [newCommand, setNewCommand] = React11.useState("");
|
|
2875
2942
|
const handleSpawn = () => {
|
|
2876
2943
|
const cmd = newCommand.trim();
|
|
2877
2944
|
if (cmd) {
|
|
@@ -2880,11 +2947,11 @@ function ProcessList({ processes, onSpawn, onKill, loading = false, className })
|
|
|
2880
2947
|
}
|
|
2881
2948
|
};
|
|
2882
2949
|
return /* @__PURE__ */ jsxs22("div", { className: cn("space-y-4", className), children: [
|
|
2883
|
-
loading ? /* @__PURE__ */ jsxs22("div", { className: "rounded-lg border border-
|
|
2950
|
+
loading ? /* @__PURE__ */ jsxs22("div", { className: "rounded-lg border border-[var(--md3-outline-variant)] bg-surface-container p-6 text-center", children: [
|
|
2884
2951
|
/* @__PURE__ */ jsx23(Activity3, { className: "mx-auto h-6 w-6 text-muted-foreground animate-spin mb-2" }),
|
|
2885
2952
|
/* @__PURE__ */ jsx23("p", { className: "text-sm text-muted-foreground", children: "Loading processes..." })
|
|
2886
|
-
] }) : processes.length > 0 ? /* @__PURE__ */ jsx23("div", { className: "rounded-lg border border-
|
|
2887
|
-
/* @__PURE__ */ jsx23("thead", { className: "bg-
|
|
2953
|
+
] }) : processes.length > 0 ? /* @__PURE__ */ jsx23("div", { className: "rounded-lg border border-[var(--md3-outline-variant)] bg-surface-container overflow-hidden", children: /* @__PURE__ */ jsxs22("table", { className: "w-full text-sm", children: [
|
|
2954
|
+
/* @__PURE__ */ jsx23("thead", { className: "bg-surface-container-high border-b border-[var(--md3-outline-variant)]", children: /* @__PURE__ */ jsxs22("tr", { children: [
|
|
2888
2955
|
/* @__PURE__ */ jsx23("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "PID" }),
|
|
2889
2956
|
/* @__PURE__ */ jsx23("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "Command" }),
|
|
2890
2957
|
/* @__PURE__ */ jsx23("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "Status" }),
|
|
@@ -2896,7 +2963,7 @@ function ProcessList({ processes, onSpawn, onKill, loading = false, className })
|
|
|
2896
2963
|
/* @__PURE__ */ jsx23("td", { className: "px-4 py-3 font-mono text-xs text-foreground truncate max-w-[250px]", children: p.command }),
|
|
2897
2964
|
/* @__PURE__ */ jsx23("td", { className: "px-4 py-3", children: /* @__PURE__ */ jsx23("span", { className: cn(
|
|
2898
2965
|
"inline-flex items-center gap-1.5 rounded-full px-2 py-0.5 text-[10px] font-bold uppercase tracking-wider",
|
|
2899
|
-
p.running ? "bg-[var(--surface-success-bg)] text-[var(--surface-success-text)]" : "bg-
|
|
2966
|
+
p.running ? "bg-[var(--surface-success-bg)] text-[var(--surface-success-text)]" : "bg-surface-container-high text-muted-foreground"
|
|
2900
2967
|
), children: p.running ? "running" : `exited (${p.exitCode ?? "?"})` }) }),
|
|
2901
2968
|
/* @__PURE__ */ jsx23("td", { className: "px-4 py-3 font-mono text-xs text-muted-foreground", children: formatUptime(p.startedAt) }),
|
|
2902
2969
|
/* @__PURE__ */ jsx23("td", { className: "px-4 py-3 text-right", children: p.running && /* @__PURE__ */ jsx23(
|
|
@@ -2910,8 +2977,8 @@ function ProcessList({ processes, onSpawn, onKill, loading = false, className })
|
|
|
2910
2977
|
}
|
|
2911
2978
|
) })
|
|
2912
2979
|
] }, `${p.pid}-${p.startedAt ?? p.command}`)) })
|
|
2913
|
-
] }) }) : /* @__PURE__ */ jsxs22("div", { className: "rounded-lg border border-
|
|
2914
|
-
/* @__PURE__ */ jsx23(
|
|
2980
|
+
] }) }) : /* @__PURE__ */ jsxs22("div", { className: "rounded-lg border border-[var(--md3-outline-variant)] bg-surface-container p-6 text-center", children: [
|
|
2981
|
+
/* @__PURE__ */ jsx23(Terminal3, { className: "mx-auto h-8 w-8 text-muted-foreground mb-2" }),
|
|
2915
2982
|
/* @__PURE__ */ jsx23("p", { className: "text-sm text-muted-foreground", children: "No processes running" })
|
|
2916
2983
|
] }),
|
|
2917
2984
|
/* @__PURE__ */ jsxs22("div", { className: "flex items-center gap-3", children: [
|
|
@@ -2923,7 +2990,7 @@ function ProcessList({ processes, onSpawn, onKill, loading = false, className })
|
|
|
2923
2990
|
value: newCommand,
|
|
2924
2991
|
onChange: (e) => setNewCommand(e.target.value),
|
|
2925
2992
|
onKeyDown: (e) => e.key === "Enter" && handleSpawn(),
|
|
2926
|
-
className: "flex-1 rounded-lg border border-
|
|
2993
|
+
className: "flex-1 rounded-lg border border-[var(--md3-outline-variant)] bg-surface-container-low px-3 py-2 text-sm font-mono text-foreground placeholder:text-muted-foreground focus:outline-none focus-visible:ring-1 focus-visible:ring-ring"
|
|
2927
2994
|
}
|
|
2928
2995
|
),
|
|
2929
2996
|
/* @__PURE__ */ jsxs22(
|
|
@@ -2944,11 +3011,11 @@ function ProcessList({ processes, onSpawn, onKill, loading = false, className })
|
|
|
2944
3011
|
}
|
|
2945
3012
|
|
|
2946
3013
|
// src/dashboard/network-config.tsx
|
|
2947
|
-
import * as
|
|
3014
|
+
import * as React12 from "react";
|
|
2948
3015
|
import { Network as Network2, Plus as Plus6, Trash2 as Trash24, ShieldAlert } from "lucide-react";
|
|
2949
3016
|
import { jsx as jsx24, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
2950
3017
|
function NetworkConfig({ config, onUpdate, loading = false, className }) {
|
|
2951
|
-
const [newCidr, setNewCidr] =
|
|
3018
|
+
const [newCidr, setNewCidr] = React12.useState("");
|
|
2952
3019
|
const isValidCidr = (value) => {
|
|
2953
3020
|
const match = value.match(/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\/(\d{1,2})$/);
|
|
2954
3021
|
if (!match) return false;
|
|
@@ -2969,13 +3036,13 @@ function NetworkConfig({ config, onUpdate, loading = false, className }) {
|
|
|
2969
3036
|
}
|
|
2970
3037
|
};
|
|
2971
3038
|
if (loading || !config) {
|
|
2972
|
-
return /* @__PURE__ */ jsxs23("div", { className: cn("rounded-lg border border-
|
|
3039
|
+
return /* @__PURE__ */ jsxs23("div", { className: cn("rounded-lg border border-[var(--md3-outline-variant)] bg-surface-container p-6 text-center", className), children: [
|
|
2973
3040
|
/* @__PURE__ */ jsx24(Network2, { className: "mx-auto h-6 w-6 text-muted-foreground animate-pulse mb-2" }),
|
|
2974
3041
|
/* @__PURE__ */ jsx24("p", { className: "text-sm text-muted-foreground", children: "Loading network configuration..." })
|
|
2975
3042
|
] });
|
|
2976
3043
|
}
|
|
2977
3044
|
return /* @__PURE__ */ jsxs23("div", { className: cn("space-y-4", className), children: [
|
|
2978
|
-
/* @__PURE__ */ jsxs23("div", { className: "flex items-center justify-between rounded-lg border border-
|
|
3045
|
+
/* @__PURE__ */ jsxs23("div", { className: "flex items-center justify-between rounded-lg border border-[var(--md3-outline-variant)] bg-surface-container px-4 py-3", children: [
|
|
2979
3046
|
/* @__PURE__ */ jsxs23("div", { className: "flex items-center gap-3", children: [
|
|
2980
3047
|
/* @__PURE__ */ jsx24(ShieldAlert, { className: "h-4 w-4 text-muted-foreground" }),
|
|
2981
3048
|
/* @__PURE__ */ jsxs23("div", { children: [
|
|
@@ -2993,7 +3060,7 @@ function NetworkConfig({ config, onUpdate, loading = false, className }) {
|
|
|
2993
3060
|
onClick: () => onUpdate({ blockOutbound: !config.blockOutbound }),
|
|
2994
3061
|
className: cn(
|
|
2995
3062
|
"relative inline-flex h-6 w-11 items-center rounded-full transition-colors",
|
|
2996
|
-
config.blockOutbound ? "bg-destructive" : "bg-
|
|
3063
|
+
config.blockOutbound ? "bg-destructive" : "bg-surface-container-high"
|
|
2997
3064
|
),
|
|
2998
3065
|
children: /* @__PURE__ */ jsx24(
|
|
2999
3066
|
"span",
|
|
@@ -3009,7 +3076,7 @@ function NetworkConfig({ config, onUpdate, loading = false, className }) {
|
|
|
3009
3076
|
] }),
|
|
3010
3077
|
/* @__PURE__ */ jsxs23("div", { children: [
|
|
3011
3078
|
/* @__PURE__ */ jsx24("h4", { className: "text-xs font-medium text-muted-foreground mb-2 uppercase tracking-wider", children: "Allowlist (CIDR)" }),
|
|
3012
|
-
config.allowList.length > 0 ? /* @__PURE__ */ jsx24("div", { className: "space-y-1.5 mb-3", children: config.allowList.map((cidr) => /* @__PURE__ */ jsxs23("div", { className: "flex items-center justify-between rounded border border-
|
|
3079
|
+
config.allowList.length > 0 ? /* @__PURE__ */ jsx24("div", { className: "space-y-1.5 mb-3", children: config.allowList.map((cidr) => /* @__PURE__ */ jsxs23("div", { className: "flex items-center justify-between rounded border border-[var(--md3-outline-variant)] bg-surface-container-high px-3 py-2", children: [
|
|
3013
3080
|
/* @__PURE__ */ jsx24("span", { className: "font-mono text-xs text-foreground", children: cidr }),
|
|
3014
3081
|
/* @__PURE__ */ jsx24(
|
|
3015
3082
|
"button",
|
|
@@ -3030,7 +3097,7 @@ function NetworkConfig({ config, onUpdate, loading = false, className }) {
|
|
|
3030
3097
|
value: newCidr,
|
|
3031
3098
|
onChange: (e) => setNewCidr(e.target.value),
|
|
3032
3099
|
onKeyDown: (e) => e.key === "Enter" && handleAddCidr(),
|
|
3033
|
-
className: "flex-1 rounded-lg border border-
|
|
3100
|
+
className: "flex-1 rounded-lg border border-[var(--md3-outline-variant)] bg-surface-container-low px-3 py-2 text-sm font-mono text-foreground placeholder:text-muted-foreground focus:outline-none focus-visible:ring-1 focus-visible:ring-ring"
|
|
3034
3101
|
}
|
|
3035
3102
|
),
|
|
3036
3103
|
/* @__PURE__ */ jsxs23(
|
|
@@ -3052,9 +3119,9 @@ function NetworkConfig({ config, onUpdate, loading = false, className }) {
|
|
|
3052
3119
|
}
|
|
3053
3120
|
|
|
3054
3121
|
// src/dashboard/backend-config.tsx
|
|
3055
|
-
import * as
|
|
3122
|
+
import * as React13 from "react";
|
|
3056
3123
|
import { Bot, Plus as Plus7, RefreshCw as RefreshCw2, Trash2 as Trash25, Server, Wrench } from "lucide-react";
|
|
3057
|
-
import { Fragment as
|
|
3124
|
+
import { Fragment as Fragment13, jsx as jsx25, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
3058
3125
|
function BackendConfig({
|
|
3059
3126
|
status,
|
|
3060
3127
|
mcpServers,
|
|
@@ -3064,10 +3131,10 @@ function BackendConfig({
|
|
|
3064
3131
|
loading = false,
|
|
3065
3132
|
className
|
|
3066
3133
|
}) {
|
|
3067
|
-
const [showAddMcp, setShowAddMcp] =
|
|
3068
|
-
const [mcpName, setMcpName] =
|
|
3069
|
-
const [mcpCommand, setMcpCommand] =
|
|
3070
|
-
const [mcpArgs, setMcpArgs] =
|
|
3134
|
+
const [showAddMcp, setShowAddMcp] = React13.useState(false);
|
|
3135
|
+
const [mcpName, setMcpName] = React13.useState("");
|
|
3136
|
+
const [mcpCommand, setMcpCommand] = React13.useState("");
|
|
3137
|
+
const [mcpArgs, setMcpArgs] = React13.useState("");
|
|
3071
3138
|
const handleAddMcp = () => {
|
|
3072
3139
|
const name = mcpName.trim();
|
|
3073
3140
|
const command = mcpCommand.trim();
|
|
@@ -3084,21 +3151,21 @@ function BackendConfig({
|
|
|
3084
3151
|
}
|
|
3085
3152
|
};
|
|
3086
3153
|
if (loading || !status) {
|
|
3087
|
-
return /* @__PURE__ */ jsxs24("div", { className: cn("rounded-lg border border-
|
|
3154
|
+
return /* @__PURE__ */ jsxs24("div", { className: cn("rounded-lg border border-[var(--md3-outline-variant)] bg-surface-container p-6 text-center", className), children: [
|
|
3088
3155
|
/* @__PURE__ */ jsx25(Bot, { className: "mx-auto h-6 w-6 text-muted-foreground animate-pulse mb-2" }),
|
|
3089
3156
|
/* @__PURE__ */ jsx25("p", { className: "text-sm text-muted-foreground", children: "Loading backend status..." })
|
|
3090
3157
|
] });
|
|
3091
3158
|
}
|
|
3092
3159
|
return /* @__PURE__ */ jsxs24("div", { className: cn("space-y-4", className), children: [
|
|
3093
|
-
/* @__PURE__ */ jsxs24("div", { className: "rounded-lg border border-
|
|
3094
|
-
/* @__PURE__ */ jsxs24("div", { className: "px-4 py-3 border-b border-
|
|
3160
|
+
/* @__PURE__ */ jsxs24("div", { className: "rounded-lg border border-[var(--md3-outline-variant)] bg-surface-container overflow-hidden", children: [
|
|
3161
|
+
/* @__PURE__ */ jsxs24("div", { className: "px-4 py-3 border-b border-[var(--md3-outline-variant)] bg-surface-container-high flex items-center justify-between", children: [
|
|
3095
3162
|
/* @__PURE__ */ jsx25("h4", { className: "text-xs font-medium text-muted-foreground uppercase tracking-wider", children: "Agent Status" }),
|
|
3096
3163
|
/* @__PURE__ */ jsxs24(
|
|
3097
3164
|
"button",
|
|
3098
3165
|
{
|
|
3099
3166
|
type: "button",
|
|
3100
3167
|
onClick: onRestart,
|
|
3101
|
-
className: "inline-flex items-center gap-1.5 rounded-md bg-
|
|
3168
|
+
className: "inline-flex items-center gap-1.5 rounded-md bg-surface-container-high px-2.5 py-1 text-xs font-medium text-foreground hover:bg-surface-container-highest transition-colors border border-[var(--md3-outline-variant)]",
|
|
3102
3169
|
children: [
|
|
3103
3170
|
/* @__PURE__ */ jsx25(RefreshCw2, { className: "h-3 w-3" }),
|
|
3104
3171
|
"Restart"
|
|
@@ -3114,14 +3181,14 @@ function BackendConfig({
|
|
|
3114
3181
|
), children: status.running ? "Running" : "Stopped" }) }),
|
|
3115
3182
|
/* @__PURE__ */ jsx25("dt", { className: "text-muted-foreground", children: "Model" }),
|
|
3116
3183
|
/* @__PURE__ */ jsx25("dd", { className: "font-mono text-xs", children: status.model ?? "Default" }),
|
|
3117
|
-
status.provider && /* @__PURE__ */ jsxs24(
|
|
3184
|
+
status.provider && /* @__PURE__ */ jsxs24(Fragment13, { children: [
|
|
3118
3185
|
/* @__PURE__ */ jsx25("dt", { className: "text-muted-foreground", children: "Provider" }),
|
|
3119
3186
|
/* @__PURE__ */ jsx25("dd", { className: "font-mono text-xs", children: status.provider })
|
|
3120
3187
|
] })
|
|
3121
3188
|
] }) })
|
|
3122
3189
|
] }),
|
|
3123
|
-
/* @__PURE__ */ jsxs24("div", { className: "rounded-lg border border-
|
|
3124
|
-
/* @__PURE__ */ jsxs24("div", { className: "px-4 py-3 border-b border-
|
|
3190
|
+
/* @__PURE__ */ jsxs24("div", { className: "rounded-lg border border-[var(--md3-outline-variant)] bg-surface-container overflow-hidden", children: [
|
|
3191
|
+
/* @__PURE__ */ jsxs24("div", { className: "px-4 py-3 border-b border-[var(--md3-outline-variant)] bg-surface-container-high flex items-center justify-between", children: [
|
|
3125
3192
|
/* @__PURE__ */ jsxs24("h4", { className: "text-xs font-medium text-muted-foreground uppercase tracking-wider flex items-center gap-2", children: [
|
|
3126
3193
|
/* @__PURE__ */ jsx25(Wrench, { className: "h-3.5 w-3.5" }),
|
|
3127
3194
|
"MCP Servers"
|
|
@@ -3154,7 +3221,7 @@ function BackendConfig({
|
|
|
3154
3221
|
/* @__PURE__ */ jsxs24("div", { className: "flex items-center gap-2 shrink-0", children: [
|
|
3155
3222
|
s.status && /* @__PURE__ */ jsx25("span", { className: cn(
|
|
3156
3223
|
"inline-flex items-center rounded-full px-1.5 py-0.5 text-[9px] font-bold uppercase",
|
|
3157
|
-
s.status === "running" ? "bg-[var(--surface-success-bg)] text-[var(--surface-success-text)]" : s.status === "error" ? "bg-destructive/10 text-destructive" : "bg-
|
|
3224
|
+
s.status === "running" ? "bg-[var(--surface-success-bg)] text-[var(--surface-success-text)]" : s.status === "error" ? "bg-destructive/10 text-destructive" : "bg-surface-container-high text-muted-foreground"
|
|
3158
3225
|
), children: s.status }),
|
|
3159
3226
|
/* @__PURE__ */ jsx25(
|
|
3160
3227
|
"button",
|
|
@@ -3167,7 +3234,7 @@ function BackendConfig({
|
|
|
3167
3234
|
)
|
|
3168
3235
|
] })
|
|
3169
3236
|
] }, s.name)) }) : /* @__PURE__ */ jsx25("div", { className: "p-4 text-center", children: /* @__PURE__ */ jsx25("p", { className: "text-xs text-muted-foreground", children: "No MCP servers configured" }) }),
|
|
3170
|
-
showAddMcp && /* @__PURE__ */ jsxs24("div", { className: "p-4 border-t border-
|
|
3237
|
+
showAddMcp && /* @__PURE__ */ jsxs24("div", { className: "p-4 border-t border-[var(--md3-outline-variant)] bg-surface-container-high space-y-2", children: [
|
|
3171
3238
|
/* @__PURE__ */ jsx25(
|
|
3172
3239
|
"input",
|
|
3173
3240
|
{
|
|
@@ -3175,7 +3242,7 @@ function BackendConfig({
|
|
|
3175
3242
|
placeholder: "Server name",
|
|
3176
3243
|
value: mcpName,
|
|
3177
3244
|
onChange: (e) => setMcpName(e.target.value),
|
|
3178
|
-
className: "w-full rounded-lg border border-
|
|
3245
|
+
className: "w-full rounded-lg border border-[var(--md3-outline-variant)] bg-surface-container-low px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus-visible:ring-1 focus-visible:ring-ring"
|
|
3179
3246
|
}
|
|
3180
3247
|
),
|
|
3181
3248
|
/* @__PURE__ */ jsx25(
|
|
@@ -3185,7 +3252,7 @@ function BackendConfig({
|
|
|
3185
3252
|
placeholder: "Command (e.g. npx @server/mcp)",
|
|
3186
3253
|
value: mcpCommand,
|
|
3187
3254
|
onChange: (e) => setMcpCommand(e.target.value),
|
|
3188
|
-
className: "w-full rounded-lg border border-
|
|
3255
|
+
className: "w-full rounded-lg border border-[var(--md3-outline-variant)] bg-surface-container-low px-3 py-2 text-sm font-mono text-foreground placeholder:text-muted-foreground focus:outline-none focus-visible:ring-1 focus-visible:ring-ring"
|
|
3189
3256
|
}
|
|
3190
3257
|
),
|
|
3191
3258
|
/* @__PURE__ */ jsx25(
|
|
@@ -3195,7 +3262,7 @@ function BackendConfig({
|
|
|
3195
3262
|
placeholder: "Arguments (space-separated, optional)",
|
|
3196
3263
|
value: mcpArgs,
|
|
3197
3264
|
onChange: (e) => setMcpArgs(e.target.value),
|
|
3198
|
-
className: "w-full rounded-lg border border-
|
|
3265
|
+
className: "w-full rounded-lg border border-[var(--md3-outline-variant)] bg-surface-container-low px-3 py-2 text-sm font-mono text-foreground placeholder:text-muted-foreground focus:outline-none focus-visible:ring-1 focus-visible:ring-ring"
|
|
3199
3266
|
}
|
|
3200
3267
|
),
|
|
3201
3268
|
/* @__PURE__ */ jsxs24("div", { className: "flex justify-end gap-2 pt-1", children: [
|
|
@@ -3225,8 +3292,8 @@ function BackendConfig({
|
|
|
3225
3292
|
}
|
|
3226
3293
|
|
|
3227
3294
|
// src/dashboard/snapshot-list.tsx
|
|
3228
|
-
import * as
|
|
3229
|
-
import { Camera, Clock as Clock5, HardDrive, Plus as Plus8, RotateCcw } from "lucide-react";
|
|
3295
|
+
import * as React14 from "react";
|
|
3296
|
+
import { Camera, Clock as Clock5, HardDrive as HardDrive2, Plus as Plus8, RotateCcw } from "lucide-react";
|
|
3230
3297
|
import { jsx as jsx26, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
3231
3298
|
function formatBytes(bytes) {
|
|
3232
3299
|
if (bytes == null || bytes < 0) return "-";
|
|
@@ -3242,8 +3309,8 @@ function formatDate(dateStr) {
|
|
|
3242
3309
|
return d.toLocaleDateString(void 0, { month: "short", day: "numeric", hour: "2-digit", minute: "2-digit" });
|
|
3243
3310
|
}
|
|
3244
3311
|
function SnapshotList({ snapshots, onCreate, onRestore, onSaveAsTemplate, loading = false, className }) {
|
|
3245
|
-
const [showCreate, setShowCreate] =
|
|
3246
|
-
const [tags, setTags] =
|
|
3312
|
+
const [showCreate, setShowCreate] = React14.useState(false);
|
|
3313
|
+
const [tags, setTags] = React14.useState("");
|
|
3247
3314
|
const handleCreate = () => {
|
|
3248
3315
|
const tagList = tags.trim() ? tags.trim().split(",").map((t) => t.trim()).filter(Boolean) : void 0;
|
|
3249
3316
|
onCreate(tagList);
|
|
@@ -3276,7 +3343,7 @@ function SnapshotList({ snapshots, onCreate, onRestore, onSaveAsTemplate, loadin
|
|
|
3276
3343
|
value: tags,
|
|
3277
3344
|
onChange: (e) => setTags(e.target.value),
|
|
3278
3345
|
onKeyDown: (e) => e.key === "Enter" && handleCreate(),
|
|
3279
|
-
className: "w-full rounded-lg border border-
|
|
3346
|
+
className: "w-full rounded-lg border border-[var(--md3-outline-variant)] bg-surface-container-low px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus-visible:ring-1 focus-visible:ring-ring"
|
|
3280
3347
|
}
|
|
3281
3348
|
),
|
|
3282
3349
|
/* @__PURE__ */ jsxs25("div", { className: "flex justify-end gap-2", children: [
|
|
@@ -3303,11 +3370,11 @@ function SnapshotList({ snapshots, onCreate, onRestore, onSaveAsTemplate, loadin
|
|
|
3303
3370
|
)
|
|
3304
3371
|
] })
|
|
3305
3372
|
] }),
|
|
3306
|
-
loading ? /* @__PURE__ */ jsxs25("div", { className: "rounded-lg border border-
|
|
3373
|
+
loading ? /* @__PURE__ */ jsxs25("div", { className: "rounded-lg border border-[var(--md3-outline-variant)] bg-surface-container p-6 text-center", children: [
|
|
3307
3374
|
/* @__PURE__ */ jsx26(Camera, { className: "mx-auto h-6 w-6 text-muted-foreground animate-pulse mb-2" }),
|
|
3308
3375
|
/* @__PURE__ */ jsx26("p", { className: "text-sm text-muted-foreground", children: "Loading snapshots..." })
|
|
3309
|
-
] }) : snapshots.length > 0 ? /* @__PURE__ */ jsx26("div", { className: "rounded-lg border border-
|
|
3310
|
-
/* @__PURE__ */ jsx26("thead", { className: "bg-
|
|
3376
|
+
] }) : snapshots.length > 0 ? /* @__PURE__ */ jsx26("div", { className: "rounded-lg border border-[var(--md3-outline-variant)] bg-surface-container overflow-hidden", children: /* @__PURE__ */ jsxs25("table", { className: "w-full text-sm", children: [
|
|
3377
|
+
/* @__PURE__ */ jsx26("thead", { className: "bg-surface-container-high border-b border-[var(--md3-outline-variant)]", children: /* @__PURE__ */ jsxs25("tr", { children: [
|
|
3311
3378
|
/* @__PURE__ */ jsx26("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "ID" }),
|
|
3312
3379
|
/* @__PURE__ */ jsx26("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "Created" }),
|
|
3313
3380
|
/* @__PURE__ */ jsx26("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "Size" }),
|
|
@@ -3321,17 +3388,17 @@ function SnapshotList({ snapshots, onCreate, onRestore, onSaveAsTemplate, loadin
|
|
|
3321
3388
|
formatDate(s.createdAt)
|
|
3322
3389
|
] }) }),
|
|
3323
3390
|
/* @__PURE__ */ jsx26("td", { className: "px-4 py-3 text-xs text-muted-foreground", children: /* @__PURE__ */ jsxs25("span", { className: "inline-flex items-center gap-1.5", children: [
|
|
3324
|
-
/* @__PURE__ */ jsx26(
|
|
3391
|
+
/* @__PURE__ */ jsx26(HardDrive2, { className: "h-3 w-3" }),
|
|
3325
3392
|
formatBytes(s.sizeBytes)
|
|
3326
3393
|
] }) }),
|
|
3327
|
-
/* @__PURE__ */ jsx26("td", { className: "px-4 py-3", children: s.tags?.length ? /* @__PURE__ */ jsx26("div", { className: "flex items-center gap-1 flex-wrap", children: s.tags.map((tag) => /* @__PURE__ */ jsx26("span", { className: "rounded-full bg-
|
|
3394
|
+
/* @__PURE__ */ jsx26("td", { className: "px-4 py-3", children: s.tags?.length ? /* @__PURE__ */ jsx26("div", { className: "flex items-center gap-1 flex-wrap", children: s.tags.map((tag) => /* @__PURE__ */ jsx26("span", { className: "rounded-full bg-surface-container-high px-2 py-0.5 text-[10px] font-medium text-muted-foreground border border-[var(--md3-outline-variant)]", children: tag }, tag)) }) : /* @__PURE__ */ jsx26("span", { className: "text-xs text-muted-foreground", children: "-" }) }),
|
|
3328
3395
|
/* @__PURE__ */ jsx26("td", { className: "px-4 py-3 text-right", children: /* @__PURE__ */ jsxs25("div", { className: "flex items-center justify-end gap-2", children: [
|
|
3329
3396
|
/* @__PURE__ */ jsxs25(
|
|
3330
3397
|
"button",
|
|
3331
3398
|
{
|
|
3332
3399
|
type: "button",
|
|
3333
3400
|
onClick: () => onRestore(s.id),
|
|
3334
|
-
className: "inline-flex items-center gap-1.5 rounded-md bg-
|
|
3401
|
+
className: "inline-flex items-center gap-1.5 rounded-md bg-surface-container-high px-2.5 py-1 text-xs font-medium text-foreground hover:bg-surface-container-highest transition-colors border border-[var(--md3-outline-variant)]",
|
|
3335
3402
|
title: "Restore to new sandbox",
|
|
3336
3403
|
children: [
|
|
3337
3404
|
/* @__PURE__ */ jsx26(RotateCcw, { className: "h-3 w-3" }),
|
|
@@ -3351,7 +3418,7 @@ function SnapshotList({ snapshots, onCreate, onRestore, onSaveAsTemplate, loadin
|
|
|
3351
3418
|
)
|
|
3352
3419
|
] }) })
|
|
3353
3420
|
] }, s.id)) })
|
|
3354
|
-
] }) }) : /* @__PURE__ */ jsxs25("div", { className: "rounded-lg border border-
|
|
3421
|
+
] }) }) : /* @__PURE__ */ jsxs25("div", { className: "rounded-lg border border-[var(--md3-outline-variant)] bg-surface-container p-6 text-center", children: [
|
|
3355
3422
|
/* @__PURE__ */ jsx26(Camera, { className: "mx-auto h-8 w-8 text-muted-foreground mb-2" }),
|
|
3356
3423
|
/* @__PURE__ */ jsx26("p", { className: "text-sm text-muted-foreground", children: "No snapshots yet" }),
|
|
3357
3424
|
/* @__PURE__ */ jsx26("p", { className: "text-xs text-muted-foreground mt-1", children: "Create a snapshot to save the current state of your sandbox." })
|
|
@@ -3360,7 +3427,7 @@ function SnapshotList({ snapshots, onCreate, onRestore, onSaveAsTemplate, loadin
|
|
|
3360
3427
|
}
|
|
3361
3428
|
|
|
3362
3429
|
// src/dashboard/promo-banner.tsx
|
|
3363
|
-
import { Fragment as
|
|
3430
|
+
import { Fragment as Fragment14, jsx as jsx27, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
3364
3431
|
function PromoBanner({
|
|
3365
3432
|
title,
|
|
3366
3433
|
description,
|
|
@@ -3375,7 +3442,7 @@ function PromoBanner({
|
|
|
3375
3442
|
"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",
|
|
3376
3443
|
disabled ? "opacity-50 cursor-not-allowed" : "hover:bg-[var(--btn-primary-hover)]"
|
|
3377
3444
|
);
|
|
3378
|
-
const buttonContent = /* @__PURE__ */ jsxs26(
|
|
3445
|
+
const buttonContent = /* @__PURE__ */ jsxs26(Fragment14, { children: [
|
|
3379
3446
|
buttonLabel,
|
|
3380
3447
|
/* @__PURE__ */ jsxs26("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: [
|
|
3381
3448
|
/* @__PURE__ */ jsx27("path", { d: "M5 12h14" }),
|