@tangle-network/sandbox-ui 0.9.0 → 0.10.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/{chunk-7YWFOGKQ.js → chunk-2XCOGNZP.js} +80 -2
- package/dist/dashboard.d.ts +3 -2
- package/dist/dashboard.js +27 -15
- package/dist/globals.css +18 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/pages.d.ts +9 -2
- package/dist/pages.js +76 -37
- package/dist/styles.css +18 -0
- package/dist/{variant-list-CsS6ydgm.d.ts → variant-list-BNwUOSgz.d.ts} +13 -0
- package/package.json +1 -1
|
@@ -516,6 +516,10 @@ function XIcon({ className }) {
|
|
|
516
516
|
/* @__PURE__ */ jsx7("path", { d: "m6 6 12 12" })
|
|
517
517
|
] });
|
|
518
518
|
}
|
|
519
|
+
function formatNotifDate(raw) {
|
|
520
|
+
const d = new Date(raw);
|
|
521
|
+
return Number.isNaN(d.getTime()) ? raw : d.toLocaleString(void 0, { month: "short", day: "numeric", hour: "2-digit", minute: "2-digit" });
|
|
522
|
+
}
|
|
519
523
|
function DefaultLink2({
|
|
520
524
|
href,
|
|
521
525
|
to,
|
|
@@ -546,10 +550,30 @@ function DashboardLayoutInner({
|
|
|
546
550
|
LinkComponent = DefaultLink2,
|
|
547
551
|
footer,
|
|
548
552
|
railFooter,
|
|
549
|
-
profileMenuItems
|
|
553
|
+
profileMenuItems,
|
|
554
|
+
notifications: notifData
|
|
550
555
|
}) {
|
|
551
556
|
const Link = LinkComponent;
|
|
552
557
|
const [mobileMenuOpen, setMobileMenuOpen] = React3.useState(false);
|
|
558
|
+
const [notificationsOpen, setNotificationsOpen] = React3.useState(false);
|
|
559
|
+
const notifRef = React3.useRef(null);
|
|
560
|
+
React3.useEffect(() => {
|
|
561
|
+
if (!notificationsOpen) return;
|
|
562
|
+
const handler = (e) => {
|
|
563
|
+
if (notifRef.current && !notifRef.current.contains(e.target)) {
|
|
564
|
+
setNotificationsOpen(false);
|
|
565
|
+
}
|
|
566
|
+
};
|
|
567
|
+
const keyHandler = (e) => {
|
|
568
|
+
if (e.key === "Escape") setNotificationsOpen(false);
|
|
569
|
+
};
|
|
570
|
+
document.addEventListener("mousedown", handler);
|
|
571
|
+
document.addEventListener("keydown", keyHandler);
|
|
572
|
+
return () => {
|
|
573
|
+
document.removeEventListener("mousedown", handler);
|
|
574
|
+
document.removeEventListener("keydown", keyHandler);
|
|
575
|
+
};
|
|
576
|
+
}, [notificationsOpen]);
|
|
553
577
|
const { contentMargin, hidden, mode, hasPanels, panelOpen } = useSidebar();
|
|
554
578
|
const modeSet = React3.useMemo(() => new Set(modeItems), [modeItems]);
|
|
555
579
|
const sidebarUser = user ? { email: user.email, name: user.name, tier: user.tier, avatarUrl: user.avatarUrl } : void 0;
|
|
@@ -640,7 +664,61 @@ function DashboardLayoutInner({
|
|
|
640
664
|
]
|
|
641
665
|
}
|
|
642
666
|
),
|
|
643
|
-
/* @__PURE__ */
|
|
667
|
+
/* @__PURE__ */ jsxs6("div", { className: "relative", ref: notifRef, children: [
|
|
668
|
+
/* @__PURE__ */ jsxs6(
|
|
669
|
+
"button",
|
|
670
|
+
{
|
|
671
|
+
type: "button",
|
|
672
|
+
className: "relative text-muted-foreground hover:text-foreground transition-colors p-2 rounded-lg hover:bg-muted/50",
|
|
673
|
+
onClick: () => setNotificationsOpen(!notificationsOpen),
|
|
674
|
+
"aria-label": "Notifications",
|
|
675
|
+
"aria-expanded": notificationsOpen,
|
|
676
|
+
children: [
|
|
677
|
+
/* @__PURE__ */ jsx7(Bell, { className: "h-4 w-4" }),
|
|
678
|
+
(notifData?.unreadCount ?? 0) > 0 && /* @__PURE__ */ jsx7("span", { className: "absolute top-1 right-1 h-2 w-2 rounded-full bg-destructive" })
|
|
679
|
+
]
|
|
680
|
+
}
|
|
681
|
+
),
|
|
682
|
+
notificationsOpen && /* @__PURE__ */ jsxs6("div", { className: "absolute right-0 top-full mt-2 w-80 rounded-lg border border-border bg-card shadow-lg z-50", children: [
|
|
683
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex items-center justify-between border-b border-border px-4 py-3", children: [
|
|
684
|
+
/* @__PURE__ */ jsx7("p", { className: "font-bold text-foreground text-sm", children: "Notifications" }),
|
|
685
|
+
(notifData?.unreadCount ?? 0) > 0 && notifData?.onMarkAllRead && /* @__PURE__ */ jsx7(
|
|
686
|
+
"button",
|
|
687
|
+
{
|
|
688
|
+
type: "button",
|
|
689
|
+
onClick: () => {
|
|
690
|
+
notifData.onMarkAllRead?.();
|
|
691
|
+
},
|
|
692
|
+
className: "text-primary text-xs font-medium hover:underline",
|
|
693
|
+
children: "Mark all read"
|
|
694
|
+
}
|
|
695
|
+
)
|
|
696
|
+
] }),
|
|
697
|
+
!notifData?.items || notifData.items.length === 0 ? /* @__PURE__ */ jsxs6("div", { className: "flex flex-col items-center justify-center px-4 py-8 text-center", children: [
|
|
698
|
+
/* @__PURE__ */ jsx7(Bell, { className: "h-8 w-8 text-muted-foreground/40 mb-2" }),
|
|
699
|
+
/* @__PURE__ */ jsx7("p", { className: "text-muted-foreground text-sm", children: "No notifications yet" }),
|
|
700
|
+
/* @__PURE__ */ jsx7("p", { className: "text-muted-foreground/60 text-xs mt-1", children: "We'll notify you about important updates" })
|
|
701
|
+
] }) : /* @__PURE__ */ jsx7("div", { className: "max-h-80 overflow-y-auto", children: notifData.items.map((n) => /* @__PURE__ */ jsxs6(
|
|
702
|
+
"button",
|
|
703
|
+
{
|
|
704
|
+
type: "button",
|
|
705
|
+
className: cn(
|
|
706
|
+
"w-full text-left px-4 py-3 border-b border-border last:border-0 transition-colors",
|
|
707
|
+
n.read ? "cursor-default" : "bg-primary/5 hover:bg-muted/50"
|
|
708
|
+
),
|
|
709
|
+
onClick: () => {
|
|
710
|
+
if (!n.read) notifData.onMarkRead?.(n.id);
|
|
711
|
+
},
|
|
712
|
+
children: [
|
|
713
|
+
/* @__PURE__ */ jsx7("p", { className: cn("text-sm", !n.read ? "font-semibold text-foreground" : "text-muted-foreground"), children: n.title }),
|
|
714
|
+
/* @__PURE__ */ jsx7("p", { className: "text-xs text-muted-foreground mt-0.5 line-clamp-2", children: n.message }),
|
|
715
|
+
/* @__PURE__ */ jsx7("p", { className: "text-[10px] text-muted-foreground/50 mt-1", children: formatNotifDate(n.createdAt) })
|
|
716
|
+
]
|
|
717
|
+
},
|
|
718
|
+
n.id
|
|
719
|
+
)) })
|
|
720
|
+
] })
|
|
721
|
+
] })
|
|
644
722
|
] }),
|
|
645
723
|
/* @__PURE__ */ jsx7(
|
|
646
724
|
"button",
|
package/dist/dashboard.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { B as Backend, a as BackendSelector, b as BackendSelectorProps, C as ClusterStatusBar, c as ClusterStatusBarProps, d as ClusterStatusItem, e as CreditBalance, f as CreditBalanceProps, D as DashboardLayout, g as DashboardLayoutProps, ag as DashboardProfile, h as DashboardUser, I as Invoice, i as InvoiceTable, j as InvoiceTableProps, N as NavItem, k as NewSandboxCard, l as NewSandboxCardProps, m as PlanCardData, n as PlanCards, o as PlanCardsProps, ah as PlanFeature, p as ProductVariant, q as ProfileAvatar, r as ProfileAvatarProps, s as ProfileComparison, t as ProfileComparisonProps, u as ProfileSelector, v as ProfileSelectorProps, R as RailButton, w as RailButtonProps, x as RailModeButton, y as RailModeButtonProps, z as RailSeparator, A as RailSeparatorProps, E as ResourceMeter, F as ResourceMeterProps, S as SIDEBAR_PANEL_WIDTH, G as SIDEBAR_RAIL_WIDTH, H as SIDEBAR_TOTAL_WIDTH, J as SandboxCard, K as SandboxCardData, L as SandboxCardProps, M as SandboxStatus, O as SandboxTable, Q as SandboxTableProps, T as Sidebar, U as SidebarContent, V as SidebarContentProps, W as SidebarPanel, X as SidebarPanelContent, Y as SidebarPanelContentProps, Z as SidebarPanelHeader, _ as SidebarPanelHeaderProps, $ as SidebarPanelProps, a0 as SidebarProps, a1 as SidebarProvider, a2 as SidebarProviderProps, a3 as SidebarRail, a4 as SidebarRailFooter, a5 as SidebarRailFooterProps, a6 as SidebarRailHeader, a7 as SidebarRailHeaderProps, a8 as SidebarRailNav, a9 as SidebarRailNavProps, aa as SidebarRailProps, ab as SidebarUser, ai as Variant, ad as VariantList, ae as VariantListProps, aj as VariantOutcome, ak as VariantStatus, af as useSidebar } from './variant-list-
|
|
1
|
+
export { B as Backend, a as BackendSelector, b as BackendSelectorProps, C as ClusterStatusBar, c as ClusterStatusBarProps, d as ClusterStatusItem, e as CreditBalance, f as CreditBalanceProps, D as DashboardLayout, g as DashboardLayoutProps, ag as DashboardProfile, h as DashboardUser, I as Invoice, i as InvoiceTable, j as InvoiceTableProps, N as NavItem, k as NewSandboxCard, l as NewSandboxCardProps, m as PlanCardData, n as PlanCards, o as PlanCardsProps, ah as PlanFeature, p as ProductVariant, q as ProfileAvatar, r as ProfileAvatarProps, s as ProfileComparison, t as ProfileComparisonProps, u as ProfileSelector, v as ProfileSelectorProps, R as RailButton, w as RailButtonProps, x as RailModeButton, y as RailModeButtonProps, z as RailSeparator, A as RailSeparatorProps, E as ResourceMeter, F as ResourceMeterProps, S as SIDEBAR_PANEL_WIDTH, G as SIDEBAR_RAIL_WIDTH, H as SIDEBAR_TOTAL_WIDTH, J as SandboxCard, K as SandboxCardData, L as SandboxCardProps, M as SandboxStatus, O as SandboxTable, Q as SandboxTableProps, T as Sidebar, U as SidebarContent, V as SidebarContentProps, W as SidebarPanel, X as SidebarPanelContent, Y as SidebarPanelContentProps, Z as SidebarPanelHeader, _ as SidebarPanelHeaderProps, $ as SidebarPanelProps, a0 as SidebarProps, a1 as SidebarProvider, a2 as SidebarProviderProps, a3 as SidebarRail, a4 as SidebarRailFooter, a5 as SidebarRailFooterProps, a6 as SidebarRailHeader, a7 as SidebarRailHeaderProps, a8 as SidebarRailNav, a9 as SidebarRailNavProps, aa as SidebarRailProps, ab as SidebarUser, ai as Variant, ad as VariantList, ae as VariantListProps, aj as VariantOutcome, ak as VariantStatus, af as useSidebar } from './variant-list-BNwUOSgz.js';
|
|
2
2
|
export { a as BillingBalance, c as BillingDashboard, d as BillingDashboardProps, B as BillingSubscription, b as BillingUsage, e as PricingPage, f as PricingPageProps, P as PricingTier, g as UsageChart, h as UsageChartProps, U as UsageDataPoint } from './usage-chart-SSiOgeQI.js';
|
|
3
3
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
4
4
|
export { a as TemplateCard, T as TemplateCardData, b as TemplateCardProps } from './template-card-BAtvcAkU.js';
|
|
@@ -128,10 +128,11 @@ interface SnapshotListProps {
|
|
|
128
128
|
snapshots: SnapshotInfo[];
|
|
129
129
|
onCreate: (tags?: string[]) => void;
|
|
130
130
|
onRestore: (snapshotId: string) => void;
|
|
131
|
+
onSaveAsTemplate?: (snapshotId: string) => void;
|
|
131
132
|
loading?: boolean;
|
|
132
133
|
className?: string;
|
|
133
134
|
}
|
|
134
|
-
declare function SnapshotList({ snapshots, onCreate, onRestore, loading, className }: SnapshotListProps): react_jsx_runtime.JSX.Element;
|
|
135
|
+
declare function SnapshotList({ snapshots, onCreate, onRestore, onSaveAsTemplate, loading, className }: SnapshotListProps): react_jsx_runtime.JSX.Element;
|
|
135
136
|
|
|
136
137
|
interface PromoBannerProps {
|
|
137
138
|
title: string;
|
package/dist/dashboard.js
CHANGED
|
@@ -34,7 +34,7 @@ import {
|
|
|
34
34
|
SidebarRailNav,
|
|
35
35
|
VariantList,
|
|
36
36
|
useSidebar
|
|
37
|
-
} from "./chunk-
|
|
37
|
+
} from "./chunk-2XCOGNZP.js";
|
|
38
38
|
import {
|
|
39
39
|
BillingDashboard,
|
|
40
40
|
PricingPage,
|
|
@@ -769,7 +769,7 @@ function formatDate(dateStr) {
|
|
|
769
769
|
if (Number.isNaN(d.getTime())) return dateStr;
|
|
770
770
|
return d.toLocaleDateString(void 0, { month: "short", day: "numeric", hour: "2-digit", minute: "2-digit" });
|
|
771
771
|
}
|
|
772
|
-
function SnapshotList({ snapshots, onCreate, onRestore, loading = false, className }) {
|
|
772
|
+
function SnapshotList({ snapshots, onCreate, onRestore, onSaveAsTemplate, loading = false, className }) {
|
|
773
773
|
const [showCreate, setShowCreate] = React6.useState(false);
|
|
774
774
|
const [tags, setTags] = React6.useState("");
|
|
775
775
|
const handleCreate = () => {
|
|
@@ -853,19 +853,31 @@ function SnapshotList({ snapshots, onCreate, onRestore, loading = false, classNa
|
|
|
853
853
|
formatBytes(s.sizeBytes)
|
|
854
854
|
] }) }),
|
|
855
855
|
/* @__PURE__ */ jsx8("td", { className: "px-4 py-3", children: s.tags?.length ? /* @__PURE__ */ jsx8("div", { className: "flex items-center gap-1 flex-wrap", children: s.tags.map((tag) => /* @__PURE__ */ jsx8("span", { className: "rounded-full bg-muted px-2 py-0.5 text-[10px] font-medium text-muted-foreground border border-border", children: tag }, tag)) }) : /* @__PURE__ */ jsx8("span", { className: "text-xs text-muted-foreground", children: "-" }) }),
|
|
856
|
-
/* @__PURE__ */ jsx8("td", { className: "px-4 py-3 text-right", children: /* @__PURE__ */ jsxs8(
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
856
|
+
/* @__PURE__ */ jsx8("td", { className: "px-4 py-3 text-right", children: /* @__PURE__ */ jsxs8("div", { className: "flex items-center justify-end gap-2", children: [
|
|
857
|
+
/* @__PURE__ */ jsxs8(
|
|
858
|
+
"button",
|
|
859
|
+
{
|
|
860
|
+
type: "button",
|
|
861
|
+
onClick: () => onRestore(s.id),
|
|
862
|
+
className: "inline-flex items-center gap-1.5 rounded-md bg-muted px-2.5 py-1 text-xs font-medium text-foreground hover:bg-muted/80 transition-colors border border-border",
|
|
863
|
+
title: "Restore to new sandbox",
|
|
864
|
+
children: [
|
|
865
|
+
/* @__PURE__ */ jsx8(RotateCcw, { className: "h-3 w-3" }),
|
|
866
|
+
"Restore"
|
|
867
|
+
]
|
|
868
|
+
}
|
|
869
|
+
),
|
|
870
|
+
onSaveAsTemplate && /* @__PURE__ */ jsx8(
|
|
871
|
+
"button",
|
|
872
|
+
{
|
|
873
|
+
type: "button",
|
|
874
|
+
onClick: () => onSaveAsTemplate(s.id),
|
|
875
|
+
className: "inline-flex items-center gap-1.5 rounded-md bg-primary/10 px-2.5 py-1 text-xs font-medium text-primary hover:bg-primary/20 transition-colors border border-primary/20",
|
|
876
|
+
title: "Save as reusable template",
|
|
877
|
+
children: "Save as Template"
|
|
878
|
+
}
|
|
879
|
+
)
|
|
880
|
+
] }) })
|
|
869
881
|
] }, s.id)) })
|
|
870
882
|
] }) }) : /* @__PURE__ */ jsxs8("div", { className: "rounded-lg border border-border bg-muted/20 p-6 text-center", children: [
|
|
871
883
|
/* @__PURE__ */ jsx8(Camera, { className: "mx-auto h-8 w-8 text-muted-foreground mb-2" }),
|
package/dist/globals.css
CHANGED
|
@@ -720,6 +720,9 @@
|
|
|
720
720
|
.top-0\.5 {
|
|
721
721
|
top: calc(var(--spacing) * 0.5);
|
|
722
722
|
}
|
|
723
|
+
.top-1 {
|
|
724
|
+
top: calc(var(--spacing) * 1);
|
|
725
|
+
}
|
|
723
726
|
.top-1\/2 {
|
|
724
727
|
top: calc(1 / 2 * 100%);
|
|
725
728
|
}
|
|
@@ -735,12 +738,18 @@
|
|
|
735
738
|
.top-\[50\%\] {
|
|
736
739
|
top: 50%;
|
|
737
740
|
}
|
|
741
|
+
.top-full {
|
|
742
|
+
top: 100%;
|
|
743
|
+
}
|
|
738
744
|
.-right-1 {
|
|
739
745
|
right: calc(var(--spacing) * -1);
|
|
740
746
|
}
|
|
741
747
|
.right-0 {
|
|
742
748
|
right: calc(var(--spacing) * 0);
|
|
743
749
|
}
|
|
750
|
+
.right-1 {
|
|
751
|
+
right: calc(var(--spacing) * 1);
|
|
752
|
+
}
|
|
744
753
|
.right-2 {
|
|
745
754
|
right: calc(var(--spacing) * 2);
|
|
746
755
|
}
|
|
@@ -2479,6 +2488,9 @@
|
|
|
2479
2488
|
.py-5 {
|
|
2480
2489
|
padding-block: calc(var(--spacing) * 5);
|
|
2481
2490
|
}
|
|
2491
|
+
.py-8 {
|
|
2492
|
+
padding-block: calc(var(--spacing) * 8);
|
|
2493
|
+
}
|
|
2482
2494
|
.py-12 {
|
|
2483
2495
|
padding-block: calc(var(--spacing) * 12);
|
|
2484
2496
|
}
|
|
@@ -3400,6 +3412,12 @@
|
|
|
3400
3412
|
}
|
|
3401
3413
|
}
|
|
3402
3414
|
}
|
|
3415
|
+
.last\:border-0 {
|
|
3416
|
+
&:last-child {
|
|
3417
|
+
border-style: var(--tw-border-style);
|
|
3418
|
+
border-width: 0px;
|
|
3419
|
+
}
|
|
3420
|
+
}
|
|
3403
3421
|
.focus-within\:border-\[var\(--border-accent-hover\)\] {
|
|
3404
3422
|
&:focus-within {
|
|
3405
3423
|
border-color: var(--border-accent-hover);
|
package/dist/index.d.ts
CHANGED
|
@@ -15,7 +15,7 @@ import { b as ToolPart } from './parts-CyGkM6Fp.js';
|
|
|
15
15
|
export { R as ReasoningPart, S as SessionMessage, a as SessionPart, T as TextPart, c as ToolState, d as ToolStatus, e as ToolTime } from './parts-CyGkM6Fp.js';
|
|
16
16
|
export { F as FileNode, a as FileTabData, b as FileTabs, c as FileTabsProps, d as FileTree, e as FileTreeProps, f as FileTreeVisibilityOptions, g as filterFileTree } from './file-tabs-BLfxfmAH.js';
|
|
17
17
|
export { FileArtifactPane, FileArtifactPaneProps, FilePreview, FilePreviewProps } from './files.js';
|
|
18
|
-
export { B as Backend, a as BackendSelector, b as BackendSelectorProps, C as ClusterStatusBar, c as ClusterStatusBarProps, d as ClusterStatusItem, e as CreditBalance, f as CreditBalanceProps, D as DashboardLayout, g as DashboardLayoutProps, h as DashboardUser, I as Invoice, i as InvoiceTable, j as InvoiceTableProps, N as NavItem, k as NewSandboxCard, l as NewSandboxCardProps, P as PanelConfig, m as PlanCardData, n as PlanCards, o as PlanCardsProps, p as ProductVariant, q as ProfileAvatar, r as ProfileAvatarProps, s as ProfileComparison, t as ProfileComparisonProps, u as ProfileSelector, v as ProfileSelectorProps, R as RailButton, w as RailButtonProps, x as RailModeButton, y as RailModeButtonProps, z as RailSeparator, A as RailSeparatorProps, E as ResourceMeter, F as ResourceMeterProps, S as SIDEBAR_PANEL_WIDTH, G as SIDEBAR_RAIL_WIDTH, H as SIDEBAR_TOTAL_WIDTH, J as SandboxCard, K as SandboxCardData, L as SandboxCardProps, M as SandboxStatus, O as SandboxTable, Q as SandboxTableProps, T as Sidebar, U as SidebarContent, V as SidebarContentProps, W as SidebarPanel, X as SidebarPanelContent, Y as SidebarPanelContentProps, Z as SidebarPanelHeader, _ as SidebarPanelHeaderProps, $ as SidebarPanelProps, a0 as SidebarProps, a1 as SidebarProvider, a2 as SidebarProviderProps, a3 as SidebarRail, a4 as SidebarRailFooter, a5 as SidebarRailFooterProps, a6 as SidebarRailHeader, a7 as SidebarRailHeaderProps, a8 as SidebarRailNav, a9 as SidebarRailNavProps, aa as SidebarRailProps, ab as SidebarUser, ac as TopNavLink, ad as VariantList, ae as VariantListProps, af as useSidebar } from './variant-list-
|
|
18
|
+
export { B as Backend, a as BackendSelector, b as BackendSelectorProps, C as ClusterStatusBar, c as ClusterStatusBarProps, d as ClusterStatusItem, e as CreditBalance, f as CreditBalanceProps, D as DashboardLayout, g as DashboardLayoutProps, h as DashboardUser, I as Invoice, i as InvoiceTable, j as InvoiceTableProps, N as NavItem, k as NewSandboxCard, l as NewSandboxCardProps, P as PanelConfig, m as PlanCardData, n as PlanCards, o as PlanCardsProps, p as ProductVariant, q as ProfileAvatar, r as ProfileAvatarProps, s as ProfileComparison, t as ProfileComparisonProps, u as ProfileSelector, v as ProfileSelectorProps, R as RailButton, w as RailButtonProps, x as RailModeButton, y as RailModeButtonProps, z as RailSeparator, A as RailSeparatorProps, E as ResourceMeter, F as ResourceMeterProps, S as SIDEBAR_PANEL_WIDTH, G as SIDEBAR_RAIL_WIDTH, H as SIDEBAR_TOTAL_WIDTH, J as SandboxCard, K as SandboxCardData, L as SandboxCardProps, M as SandboxStatus, O as SandboxTable, Q as SandboxTableProps, T as Sidebar, U as SidebarContent, V as SidebarContentProps, W as SidebarPanel, X as SidebarPanelContent, Y as SidebarPanelContentProps, Z as SidebarPanelHeader, _ as SidebarPanelHeaderProps, $ as SidebarPanelProps, a0 as SidebarProps, a1 as SidebarProvider, a2 as SidebarProviderProps, a3 as SidebarRail, a4 as SidebarRailFooter, a5 as SidebarRailFooterProps, a6 as SidebarRailHeader, a7 as SidebarRailHeaderProps, a8 as SidebarRailNav, a9 as SidebarRailNavProps, aa as SidebarRailProps, ab as SidebarUser, ac as TopNavLink, ad as VariantList, ae as VariantListProps, af as useSidebar } from './variant-list-BNwUOSgz.js';
|
|
19
19
|
export { c as BillingDashboard, d as BillingDashboardProps, e as PricingCards, f as PricingPageProps, g as UsageChart, h as UsageChartProps, U as UsageDataPoint } from './usage-chart-SSiOgeQI.js';
|
|
20
20
|
export { AuthHeader, GitHubLoginButton, LoginLayout, LoginLayoutProps, UserMenu } from './auth.js';
|
|
21
21
|
export { CodeBlock, CodeBlock as CodeBlockDisplay, CopyButton, Markdown, MarkdownProps } from './markdown.js';
|
package/dist/index.js
CHANGED
package/dist/pages.d.ts
CHANGED
|
@@ -34,6 +34,11 @@ interface EnvironmentEntry {
|
|
|
34
34
|
description?: string;
|
|
35
35
|
version?: string;
|
|
36
36
|
}
|
|
37
|
+
interface ResourceLimits {
|
|
38
|
+
cpuMax?: number;
|
|
39
|
+
ramMaxGB?: number;
|
|
40
|
+
storageMaxGB?: number;
|
|
41
|
+
}
|
|
37
42
|
interface ProvisioningWizardProps {
|
|
38
43
|
environments?: EnvironmentOption[];
|
|
39
44
|
onLoadEnvironments?: () => Promise<EnvironmentEntry[]>;
|
|
@@ -49,6 +54,8 @@ interface ProvisioningWizardProps {
|
|
|
49
54
|
skipToReview?: boolean;
|
|
50
55
|
/** Load user's startup scripts for the advanced options selector */
|
|
51
56
|
onLoadStartupScripts?: () => Promise<StartupScriptEntry[]>;
|
|
57
|
+
/** Plan-based resource limits — caps the slider maximums */
|
|
58
|
+
resourceLimits?: ResourceLimits;
|
|
52
59
|
}
|
|
53
60
|
interface StartupScriptEntry {
|
|
54
61
|
id: string;
|
|
@@ -75,7 +82,7 @@ interface ProvisioningConfig {
|
|
|
75
82
|
startupScriptIds?: string[];
|
|
76
83
|
}
|
|
77
84
|
declare function resolveEnvironment(env: EnvironmentEntry): EnvironmentOption;
|
|
78
|
-
declare function ProvisioningWizard({ environments: environmentsProp, onLoadEnvironments, onSubmit, onBack, className, variant, defaultEnvironment, defaultConfig, skipToReview, onLoadStartupScripts, }: ProvisioningWizardProps): react_jsx_runtime.JSX.Element;
|
|
85
|
+
declare function ProvisioningWizard({ environments: environmentsProp, onLoadEnvironments, onSubmit, onBack, className, variant, defaultEnvironment, defaultConfig, skipToReview, onLoadStartupScripts, resourceLimits, }: ProvisioningWizardProps): react_jsx_runtime.JSX.Element;
|
|
79
86
|
|
|
80
87
|
type ProductVariant = "sandbox";
|
|
81
88
|
interface StandalonePricingPageProps {
|
|
@@ -227,4 +234,4 @@ type TemplateCategory = "blockchain" | "ai-ml" | "frontend" | "infrastructure" |
|
|
|
227
234
|
type TemplatePreset = Omit<ProvisioningConfig, "name" | "gitUrl" | "envVars" | "driver" | "startupScriptIds">;
|
|
228
235
|
declare function getPresetForTemplate(id: string): TemplatePreset;
|
|
229
236
|
|
|
230
|
-
export { BillingPage, type BillingPageData, type BillingPageProps, type EnvironmentEntry, type EnvironmentOption, PricingTier, type ProductVariant$1 as ProductVariant, type Profile, type ProfileFormData, type ProfileMetrics, ProfilesPage, type ProfilesPageProps, type ProvisioningConfig, ProvisioningWizard, type ProvisioningWizardProps, type ScriptType, type Secret, type SecretsApiClient, SecretsPage, type SecretsPageProps, StandalonePricingPage, type StandalonePricingPageProps, type StartupScript, type StartupScriptEntry, type StartupScriptFormData, type StartupScriptsApiClient, StartupScriptsPage, type StartupScriptsPageProps, type TemplateCategory, type TemplatePreset, TemplatesPage, type TemplatesPageProps, getPresetForTemplate, resolveEnvironment };
|
|
237
|
+
export { BillingPage, type BillingPageData, type BillingPageProps, type EnvironmentEntry, type EnvironmentOption, PricingTier, type ProductVariant$1 as ProductVariant, type Profile, type ProfileFormData, type ProfileMetrics, ProfilesPage, type ProfilesPageProps, type ProvisioningConfig, ProvisioningWizard, type ProvisioningWizardProps, type ResourceLimits, type ScriptType, type Secret, type SecretsApiClient, SecretsPage, type SecretsPageProps, StandalonePricingPage, type StandalonePricingPageProps, type StartupScript, type StartupScriptEntry, type StartupScriptFormData, type StartupScriptsApiClient, StartupScriptsPage, type StartupScriptsPageProps, type TemplateCategory, type TemplatePreset, TemplatesPage, type TemplatesPageProps, getPresetForTemplate, resolveEnvironment };
|
package/dist/pages.js
CHANGED
|
@@ -310,6 +310,16 @@ var STACK_DISPLAY = {
|
|
|
310
310
|
rust: { name: "Rust", abbr: "Rs", color: "orange", textClass: "text-[var(--surface-orange-text)]" }
|
|
311
311
|
};
|
|
312
312
|
function resolveEnvironment(env) {
|
|
313
|
+
if (env.id.startsWith("template:")) {
|
|
314
|
+
const templateName = env.description?.replace(/^Template:\s*/, "") ?? "Custom Template";
|
|
315
|
+
return {
|
|
316
|
+
id: env.id,
|
|
317
|
+
name: templateName,
|
|
318
|
+
description: env.description ?? "User template from snapshot",
|
|
319
|
+
icon: /* @__PURE__ */ jsx2("span", { className: "text-[var(--surface-success-text)] text-2xl font-bold", children: "T" }),
|
|
320
|
+
color: "green"
|
|
321
|
+
};
|
|
322
|
+
}
|
|
313
323
|
const display = STACK_DISPLAY[env.id];
|
|
314
324
|
const name = display?.name ?? (env.id.length > 0 ? env.id.charAt(0).toUpperCase() + env.id.slice(1).replace(/-/g, " ") : "Unknown");
|
|
315
325
|
const abbr = display?.abbr ?? (env.id.length > 0 ? env.id[0].toUpperCase() : "?");
|
|
@@ -334,8 +344,8 @@ var RAM_MIN = 2;
|
|
|
334
344
|
var RAM_MAX = 32;
|
|
335
345
|
var STORAGE_MIN = 20;
|
|
336
346
|
var STORAGE_MAX = 512;
|
|
337
|
-
function calcCost(cpu, ram) {
|
|
338
|
-
const cost = cpu * 0.045 + ram * 5e-3;
|
|
347
|
+
function calcCost(cpu, ram, storage) {
|
|
348
|
+
const cost = cpu * 0.045 + ram * 5e-3 + storage * 11e-4;
|
|
339
349
|
return cost.toFixed(2);
|
|
340
350
|
}
|
|
341
351
|
function ProvisioningWizard({
|
|
@@ -348,8 +358,12 @@ function ProvisioningWizard({
|
|
|
348
358
|
defaultEnvironment,
|
|
349
359
|
defaultConfig,
|
|
350
360
|
skipToReview,
|
|
351
|
-
onLoadStartupScripts
|
|
361
|
+
onLoadStartupScripts,
|
|
362
|
+
resourceLimits
|
|
352
363
|
}) {
|
|
364
|
+
const cpuMax = Math.max(CPU_MIN, Math.min(resourceLimits?.cpuMax ?? CPU_MAX, CPU_MAX));
|
|
365
|
+
const ramMax = Math.max(RAM_MIN, Math.min(resourceLimits?.ramMaxGB ?? RAM_MAX, RAM_MAX));
|
|
366
|
+
const storageMax = Math.max(STORAGE_MIN, Math.min(resourceLimits?.storageMaxGB ?? STORAGE_MAX, STORAGE_MAX));
|
|
353
367
|
const dc = defaultConfig;
|
|
354
368
|
const [envList, setEnvList] = React2.useState(environmentsProp ?? defaultEnvironments);
|
|
355
369
|
const onLoadEnvironmentsRef = React2.useRef(onLoadEnvironments);
|
|
@@ -377,9 +391,14 @@ function ProvisioningWizard({
|
|
|
377
391
|
setSelectedEnv(effectiveDefault);
|
|
378
392
|
}
|
|
379
393
|
}, [envList, effectiveDefault]);
|
|
380
|
-
const [cpuCores, setCpuCores] = React2.useState(dc?.cpuCores ?? 4);
|
|
381
|
-
const [ramGB, setRamGB] = React2.useState(dc?.ramGB ?? 16);
|
|
382
|
-
const [storageGB, setStorageGB] = React2.useState(dc?.storageGB ?? 128);
|
|
394
|
+
const [cpuCores, setCpuCores] = React2.useState(Math.min(dc?.cpuCores ?? 4, cpuMax));
|
|
395
|
+
const [ramGB, setRamGB] = React2.useState(Math.min(dc?.ramGB ?? 16, ramMax));
|
|
396
|
+
const [storageGB, setStorageGB] = React2.useState(Math.min(dc?.storageGB ?? 128, storageMax));
|
|
397
|
+
React2.useEffect(() => {
|
|
398
|
+
setCpuCores((prev) => Math.min(prev, cpuMax));
|
|
399
|
+
setRamGB((prev) => Math.min(prev, ramMax));
|
|
400
|
+
setStorageGB((prev) => Math.min(prev, storageMax));
|
|
401
|
+
}, [cpuMax, ramMax, storageMax]);
|
|
383
402
|
const [modelTier, setModelTier] = React2.useState(dc?.modelTier ?? "claude-sonnet");
|
|
384
403
|
const [systemPrompt, setSystemPrompt] = React2.useState(dc?.systemPrompt ?? "");
|
|
385
404
|
const [name, setName] = React2.useState(dc?.name ?? "");
|
|
@@ -389,6 +408,7 @@ function ProvisioningWizard({
|
|
|
389
408
|
const [bare, setBare] = React2.useState(dc?.bare ?? false);
|
|
390
409
|
const [startupScriptIds, setStartupScriptIds] = React2.useState(dc?.startupScriptIds ?? []);
|
|
391
410
|
const [availableScripts, setAvailableScripts] = React2.useState([]);
|
|
411
|
+
const [activePreset, setActivePreset] = React2.useState(null);
|
|
392
412
|
const [showAdvanced, setShowAdvanced] = React2.useState(false);
|
|
393
413
|
const [loadError, setLoadError] = React2.useState(null);
|
|
394
414
|
const onLoadStartupScriptsRef = React2.useRef(onLoadStartupScripts);
|
|
@@ -423,12 +443,18 @@ function ProvisioningWizard({
|
|
|
423
443
|
setIsDeploying(false);
|
|
424
444
|
}
|
|
425
445
|
};
|
|
426
|
-
const applyPreset = (cpu, ram, storage) => {
|
|
427
|
-
setCpuCores(cpu);
|
|
428
|
-
setRamGB(ram);
|
|
429
|
-
setStorageGB(storage);
|
|
446
|
+
const applyPreset = (name2, cpu, ram, storage) => {
|
|
447
|
+
setCpuCores(Math.min(cpu, cpuMax));
|
|
448
|
+
setRamGB(Math.min(ram, ramMax));
|
|
449
|
+
setStorageGB(Math.min(storage, storageMax));
|
|
450
|
+
setActivePreset(name2);
|
|
430
451
|
};
|
|
431
|
-
const
|
|
452
|
+
const presets = [
|
|
453
|
+
{ name: "Lightweight", cpu: Math.min(2, cpuMax), ram: Math.min(4, ramMax), storage: Math.min(50, storageMax) },
|
|
454
|
+
{ name: "Standard", cpu: Math.min(4, cpuMax), ram: Math.min(16, ramMax), storage: Math.min(128, storageMax) },
|
|
455
|
+
{ name: "Performance", cpu: Math.min(8, cpuMax), ram: Math.min(32, ramMax), storage: Math.min(256, storageMax) }
|
|
456
|
+
];
|
|
457
|
+
const hourCost = calcCost(cpuCores, ramGB, storageGB);
|
|
432
458
|
return /* @__PURE__ */ jsxs2("div", { className: cn("max-w-6xl mx-auto flex flex-col", className), children: [
|
|
433
459
|
/* @__PURE__ */ jsxs2("div", { className: "mb-6 flex items-center gap-4 shrink-0", children: [
|
|
434
460
|
onBack && /* @__PURE__ */ jsx2("button", { type: "button", onClick: onBack, className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-xl border border-border hover:bg-muted/50 transition-colors text-foreground", children: /* @__PURE__ */ jsx2(ArrowLeft, { className: "h-5 w-5" }) }),
|
|
@@ -463,9 +489,9 @@ function ProvisioningWizard({
|
|
|
463
489
|
onClick: () => {
|
|
464
490
|
setCurrentStep(1);
|
|
465
491
|
setSelectedEnv(environments[0]?.id ?? "");
|
|
466
|
-
setCpuCores(4);
|
|
467
|
-
setRamGB(16);
|
|
468
|
-
setStorageGB(128);
|
|
492
|
+
setCpuCores(Math.min(4, cpuMax));
|
|
493
|
+
setRamGB(Math.min(16, ramMax));
|
|
494
|
+
setStorageGB(Math.min(128, storageMax));
|
|
469
495
|
setModelTier("claude-sonnet");
|
|
470
496
|
setSystemPrompt("");
|
|
471
497
|
setName("");
|
|
@@ -474,6 +500,7 @@ function ProvisioningWizard({
|
|
|
474
500
|
setDriver("docker");
|
|
475
501
|
setBare(false);
|
|
476
502
|
setStartupScriptIds([]);
|
|
503
|
+
setActivePreset(null);
|
|
477
504
|
},
|
|
478
505
|
className: "text-xs font-bold text-primary hover:text-primary/70 transition-colors",
|
|
479
506
|
children: "Start from scratch"
|
|
@@ -522,25 +549,25 @@ function ProvisioningWizard({
|
|
|
522
549
|
] }),
|
|
523
550
|
/* @__PURE__ */ jsxs2("div", { className: "mb-6", children: [
|
|
524
551
|
/* @__PURE__ */ jsx2("label", { className: "block font-label text-xs font-bold uppercase tracking-widest text-muted-foreground mb-3", children: "Compute Presets" }),
|
|
525
|
-
/* @__PURE__ */
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
/* @__PURE__ */ jsx2("div", { className: "
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
] })
|
|
538
|
-
|
|
552
|
+
/* @__PURE__ */ jsx2("div", { className: "grid grid-cols-3 gap-3", children: presets.map((p) => {
|
|
553
|
+
const active = activePreset === p.name;
|
|
554
|
+
return /* @__PURE__ */ jsxs2("button", { type: "button", onClick: () => applyPreset(p.name, p.cpu, p.ram, p.storage), className: cn("p-3 rounded-[14px] transition-all duration-200 text-center group border", active ? "bg-primary/5 border-primary ring-1 ring-primary/20 shadow-sm" : "bg-card border-border hover:border-primary/30 hover:shadow-sm active:scale-[0.97]"), children: [
|
|
555
|
+
/* @__PURE__ */ jsx2("div", { className: cn("font-bold text-sm transition-colors duration-200", active ? "text-primary" : "text-foreground"), children: p.name }),
|
|
556
|
+
/* @__PURE__ */ jsxs2("div", { className: "text-xs text-muted-foreground mt-0.5 font-mono", children: [
|
|
557
|
+
p.cpu,
|
|
558
|
+
"C / ",
|
|
559
|
+
p.ram,
|
|
560
|
+
"G / ",
|
|
561
|
+
p.storage,
|
|
562
|
+
"G"
|
|
563
|
+
] })
|
|
564
|
+
] }, p.name);
|
|
565
|
+
}) })
|
|
539
566
|
] }),
|
|
540
567
|
/* @__PURE__ */ jsx2("div", { className: "space-y-6", children: [
|
|
541
|
-
{ label: "Compute Cores (CPU)", value: cpuCores, setter: setCpuCores, min: CPU_MIN, max:
|
|
542
|
-
{ label: "Memory (RAM)", value: ramGB, setter: setRamGB, min: RAM_MIN, max:
|
|
543
|
-
{ label: "Ephemeral Storage", value: storageGB, setter: setStorageGB, min: STORAGE_MIN, max:
|
|
568
|
+
{ label: "Compute Cores (CPU)", value: cpuCores, setter: setCpuCores, min: CPU_MIN, max: cpuMax, step: 0.5, unit: "vCPUs" },
|
|
569
|
+
{ label: "Memory (RAM)", value: ramGB, setter: setRamGB, min: RAM_MIN, max: ramMax, step: 1, unit: "GB" },
|
|
570
|
+
{ label: "Ephemeral Storage", value: storageGB, setter: setStorageGB, min: STORAGE_MIN, max: storageMax, step: 8, unit: "GB" }
|
|
544
571
|
].map(({ label, value, setter, min, max, step: s, unit }) => /* @__PURE__ */ jsxs2("div", { children: [
|
|
545
572
|
/* @__PURE__ */ jsxs2("div", { className: "flex justify-between items-end border-b border-border pb-1.5 mb-2", children: [
|
|
546
573
|
/* @__PURE__ */ jsx2("label", { className: "font-label text-xs font-bold uppercase tracking-widest text-muted-foreground", children: label }),
|
|
@@ -558,7 +585,10 @@ function ProvisioningWizard({
|
|
|
558
585
|
max,
|
|
559
586
|
step: s,
|
|
560
587
|
value,
|
|
561
|
-
onChange: (e) =>
|
|
588
|
+
onChange: (e) => {
|
|
589
|
+
setter(+e.target.value);
|
|
590
|
+
setActivePreset(null);
|
|
591
|
+
},
|
|
562
592
|
className: "w-full h-2 rounded-full appearance-none cursor-pointer accent-primary [&::-webkit-slider-runnable-track]:bg-border [&::-webkit-slider-runnable-track]:rounded-full [&::-webkit-slider-runnable-track]:h-2 [&::-moz-range-track]:bg-border [&::-moz-range-track]:rounded-full [&::-moz-range-track]:h-2 [&::-webkit-slider-thumb]:bg-primary [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:h-5 [&::-webkit-slider-thumb]:w-5 [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:-mt-[6px] [&::-webkit-slider-thumb]:shadow-md [&::-webkit-slider-thumb]:border-2 [&::-webkit-slider-thumb]:border-primary-foreground [&::-webkit-slider-thumb]:transition-transform [&::-webkit-slider-thumb]:hover:scale-110"
|
|
563
593
|
}
|
|
564
594
|
),
|
|
@@ -829,7 +859,16 @@ function ProvisioningWizard({
|
|
|
829
859
|
/* @__PURE__ */ jsx2("span", { children: "MEMORY" }),
|
|
830
860
|
/* @__PURE__ */ jsxs2("span", { className: "text-foreground/80", children: [
|
|
831
861
|
"$",
|
|
832
|
-
(ramGB * 5e-3).toFixed(2)
|
|
862
|
+
(ramGB * 5e-3).toFixed(2),
|
|
863
|
+
"/h"
|
|
864
|
+
] })
|
|
865
|
+
] }),
|
|
866
|
+
/* @__PURE__ */ jsxs2("div", { className: "flex justify-between text-xs font-mono tracking-widest text-muted-foreground", children: [
|
|
867
|
+
/* @__PURE__ */ jsx2("span", { children: "STORAGE" }),
|
|
868
|
+
/* @__PURE__ */ jsxs2("span", { className: "text-foreground/80", children: [
|
|
869
|
+
"$",
|
|
870
|
+
(storageGB * 11e-4).toFixed(2),
|
|
871
|
+
"/h"
|
|
833
872
|
] })
|
|
834
873
|
] })
|
|
835
874
|
] })
|
|
@@ -902,16 +941,16 @@ async function fetchTiersFromApi(apiBasePath) {
|
|
|
902
941
|
}
|
|
903
942
|
var FAQ = [
|
|
904
943
|
{
|
|
905
|
-
q: "What
|
|
906
|
-
a: "
|
|
944
|
+
q: "What is included usage?",
|
|
945
|
+
a: "Each plan includes a monthly USD usage balance. Compute and AI model usage are billed per second from this balance. If you exceed your included amount, overage is billed at the same rates with no penalty."
|
|
907
946
|
},
|
|
908
947
|
{
|
|
909
948
|
q: "Can I change plans later?",
|
|
910
949
|
a: "Yes. You can upgrade or downgrade your plan at any time. When you upgrade, you are charged the prorated difference. When you downgrade, the change takes effect at the end of your billing cycle."
|
|
911
950
|
},
|
|
912
951
|
{
|
|
913
|
-
q: "
|
|
914
|
-
a: "Monthly
|
|
952
|
+
q: "Does unused balance roll over?",
|
|
953
|
+
a: "Monthly included usage does not roll over to the next month. Your balance resets at the start of each billing cycle."
|
|
915
954
|
}
|
|
916
955
|
];
|
|
917
956
|
function StandalonePricingPage({
|
package/dist/styles.css
CHANGED
|
@@ -720,6 +720,9 @@
|
|
|
720
720
|
.top-0\.5 {
|
|
721
721
|
top: calc(var(--spacing) * 0.5);
|
|
722
722
|
}
|
|
723
|
+
.top-1 {
|
|
724
|
+
top: calc(var(--spacing) * 1);
|
|
725
|
+
}
|
|
723
726
|
.top-1\/2 {
|
|
724
727
|
top: calc(1 / 2 * 100%);
|
|
725
728
|
}
|
|
@@ -735,12 +738,18 @@
|
|
|
735
738
|
.top-\[50\%\] {
|
|
736
739
|
top: 50%;
|
|
737
740
|
}
|
|
741
|
+
.top-full {
|
|
742
|
+
top: 100%;
|
|
743
|
+
}
|
|
738
744
|
.-right-1 {
|
|
739
745
|
right: calc(var(--spacing) * -1);
|
|
740
746
|
}
|
|
741
747
|
.right-0 {
|
|
742
748
|
right: calc(var(--spacing) * 0);
|
|
743
749
|
}
|
|
750
|
+
.right-1 {
|
|
751
|
+
right: calc(var(--spacing) * 1);
|
|
752
|
+
}
|
|
744
753
|
.right-2 {
|
|
745
754
|
right: calc(var(--spacing) * 2);
|
|
746
755
|
}
|
|
@@ -2479,6 +2488,9 @@
|
|
|
2479
2488
|
.py-5 {
|
|
2480
2489
|
padding-block: calc(var(--spacing) * 5);
|
|
2481
2490
|
}
|
|
2491
|
+
.py-8 {
|
|
2492
|
+
padding-block: calc(var(--spacing) * 8);
|
|
2493
|
+
}
|
|
2482
2494
|
.py-12 {
|
|
2483
2495
|
padding-block: calc(var(--spacing) * 12);
|
|
2484
2496
|
}
|
|
@@ -3400,6 +3412,12 @@
|
|
|
3400
3412
|
}
|
|
3401
3413
|
}
|
|
3402
3414
|
}
|
|
3415
|
+
.last\:border-0 {
|
|
3416
|
+
&:last-child {
|
|
3417
|
+
border-style: var(--tw-border-style);
|
|
3418
|
+
border-width: 0px;
|
|
3419
|
+
}
|
|
3420
|
+
}
|
|
3403
3421
|
.focus-within\:border-\[var\(--border-accent-hover\)\] {
|
|
3404
3422
|
&:focus-within {
|
|
3405
3423
|
border-color: var(--border-accent-hover);
|
|
@@ -235,6 +235,19 @@ interface DashboardLayoutProps {
|
|
|
235
235
|
railFooter?: React.ReactNode;
|
|
236
236
|
/** Extra dropdown items in the profile menu */
|
|
237
237
|
profileMenuItems?: React.ReactNode;
|
|
238
|
+
/** Notification data for the bell dropdown */
|
|
239
|
+
notifications?: {
|
|
240
|
+
items: {
|
|
241
|
+
id: string;
|
|
242
|
+
title: string;
|
|
243
|
+
message: string;
|
|
244
|
+
read: boolean;
|
|
245
|
+
createdAt: string;
|
|
246
|
+
}[];
|
|
247
|
+
unreadCount: number;
|
|
248
|
+
onMarkRead?: (id: string) => void;
|
|
249
|
+
onMarkAllRead?: () => void;
|
|
250
|
+
};
|
|
238
251
|
}
|
|
239
252
|
declare function DashboardLayout({ defaultPanelOpen, defaultMode, ...props }: DashboardLayoutProps): react_jsx_runtime.JSX.Element;
|
|
240
253
|
|
package/package.json
CHANGED