@tangle-network/sandbox-ui 0.10.2 → 0.10.3
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-2XCOGNZP.js → chunk-7LBHRASD.js} +124 -74
- package/dist/dashboard.d.ts +1 -1
- package/dist/dashboard.js +3 -1
- package/dist/globals.css +16 -20
- package/dist/index.d.ts +1 -1
- package/dist/index.js +3 -1
- package/dist/pages.d.ts +38 -2
- package/dist/pages.js +259 -183
- package/dist/styles.css +16 -20
- package/dist/{variant-list-BNwUOSgz.d.ts → variant-list-DHP2OXFE.d.ts} +21 -5
- package/package.json +1 -1
|
@@ -33,6 +33,7 @@ var SIDEBAR_MODE_KEY = "sandbox-sidebar-mode";
|
|
|
33
33
|
var SIDEBAR_RAIL_WIDTH = 64;
|
|
34
34
|
var SIDEBAR_PANEL_WIDTH = 260;
|
|
35
35
|
var SIDEBAR_TOTAL_WIDTH = SIDEBAR_RAIL_WIDTH + SIDEBAR_PANEL_WIDTH;
|
|
36
|
+
var SIDEBAR_MOBILE_WIDTH = 256;
|
|
36
37
|
var SidebarContext = React.createContext(null);
|
|
37
38
|
function readStorage(key, fallback) {
|
|
38
39
|
if (typeof window === "undefined") return fallback;
|
|
@@ -166,8 +167,18 @@ function Sidebar({ children, className, style }) {
|
|
|
166
167
|
}
|
|
167
168
|
);
|
|
168
169
|
}
|
|
169
|
-
function SidebarRail({ children, className }) {
|
|
170
|
-
return /* @__PURE__ */ jsx2(
|
|
170
|
+
function SidebarRail({ children, className, wide = false }) {
|
|
171
|
+
return /* @__PURE__ */ jsx2(
|
|
172
|
+
"div",
|
|
173
|
+
{
|
|
174
|
+
className: cn(
|
|
175
|
+
"flex flex-col h-full shrink-0 bg-transparent",
|
|
176
|
+
wide ? "w-full" : "w-16",
|
|
177
|
+
className
|
|
178
|
+
),
|
|
179
|
+
children
|
|
180
|
+
}
|
|
181
|
+
);
|
|
171
182
|
}
|
|
172
183
|
function SidebarRailHeader({ children, className }) {
|
|
173
184
|
return /* @__PURE__ */ jsx2("div", { className: cn("flex h-14 items-center justify-center border-b border-border", className), children });
|
|
@@ -181,7 +192,7 @@ function SidebarRailFooter({ children, className }) {
|
|
|
181
192
|
function RailSeparator({ className }) {
|
|
182
193
|
return /* @__PURE__ */ jsx2("div", { className: cn("my-2 h-px w-10 bg-[var(--md3-outline-variant)]", className) });
|
|
183
194
|
}
|
|
184
|
-
function RailButton({ icon: Icon2, label, isActive, badge, onClick, className }) {
|
|
195
|
+
function RailButton({ icon: Icon2, label, isActive, badge, onClick, className, showLabel }) {
|
|
185
196
|
return /* @__PURE__ */ jsxs(
|
|
186
197
|
"button",
|
|
187
198
|
{
|
|
@@ -189,7 +200,8 @@ function RailButton({ icon: Icon2, label, isActive, badge, onClick, className })
|
|
|
189
200
|
onClick,
|
|
190
201
|
title: label,
|
|
191
202
|
className: cn(
|
|
192
|
-
"group relative flex items-center justify-center
|
|
203
|
+
"group relative flex items-center justify-center rounded-xl transition-all duration-200",
|
|
204
|
+
showLabel ? "w-full justify-start px-3 h-11 gap-3" : "w-11 h-11 justify-center",
|
|
193
205
|
"hover:bg-[var(--accent-surface-soft)] hover:text-[var(--accent-text)]",
|
|
194
206
|
"active:scale-95",
|
|
195
207
|
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary",
|
|
@@ -198,23 +210,25 @@ function RailButton({ icon: Icon2, label, isActive, badge, onClick, className })
|
|
|
198
210
|
className
|
|
199
211
|
),
|
|
200
212
|
children: [
|
|
201
|
-
/* @__PURE__ */ jsx2(Icon2, { className: "h-5 w-5" }),
|
|
213
|
+
/* @__PURE__ */ jsx2(Icon2, { className: "h-5 w-5 shrink-0" }),
|
|
214
|
+
showLabel && /* @__PURE__ */ jsx2("span", { className: "text-sm font-medium", children: label }),
|
|
202
215
|
badge !== void 0 && badge > 0 && /* @__PURE__ */ jsx2("span", { className: "absolute -top-1 -right-1 flex h-4 min-w-4 items-center justify-center rounded-full bg-primary text-[9px] font-bold text-[var(--md3-on-primary)] px-1 shadow-sm", children: badge > 99 ? "99+" : badge })
|
|
203
216
|
]
|
|
204
217
|
}
|
|
205
218
|
);
|
|
206
219
|
}
|
|
207
|
-
function RailModeButton({ mode, icon, label, badge, className }) {
|
|
220
|
+
function RailModeButton({ mode, icon, label, badge, className, showLabel }) {
|
|
208
221
|
const { panelOpen, mode: currentMode, switchMode } = useSidebar();
|
|
209
222
|
return /* @__PURE__ */ jsx2(
|
|
210
223
|
RailButton,
|
|
211
224
|
{
|
|
212
225
|
icon,
|
|
213
226
|
label,
|
|
227
|
+
isActive: mode === currentMode && panelOpen,
|
|
214
228
|
badge,
|
|
215
|
-
isActive: panelOpen && currentMode === mode,
|
|
216
229
|
onClick: () => switchMode(mode),
|
|
217
|
-
className
|
|
230
|
+
className,
|
|
231
|
+
showLabel
|
|
218
232
|
}
|
|
219
233
|
);
|
|
220
234
|
}
|
|
@@ -243,8 +257,11 @@ function SidebarContent({ children, className }) {
|
|
|
243
257
|
return /* @__PURE__ */ jsx2(
|
|
244
258
|
"main",
|
|
245
259
|
{
|
|
246
|
-
className: cn(
|
|
247
|
-
|
|
260
|
+
className: cn(
|
|
261
|
+
"min-h-screen transition-[margin-left] duration-200 ease-in-out lg:ml-[var(--sb-content-margin,0px)]",
|
|
262
|
+
className
|
|
263
|
+
),
|
|
264
|
+
style: { "--sb-content-margin": `${contentMargin}px` },
|
|
248
265
|
children
|
|
249
266
|
}
|
|
250
267
|
);
|
|
@@ -576,58 +593,86 @@ function DashboardLayoutInner({
|
|
|
576
593
|
}, [notificationsOpen]);
|
|
577
594
|
const { contentMargin, hidden, mode, hasPanels, panelOpen } = useSidebar();
|
|
578
595
|
const modeSet = React3.useMemo(() => new Set(modeItems), [modeItems]);
|
|
579
|
-
const sidebarUser =
|
|
596
|
+
const sidebarUser = React3.useMemo(
|
|
597
|
+
() => user ? { email: user.email, name: user.name, tier: user.tier, avatarUrl: user.avatarUrl } : void 0,
|
|
598
|
+
[user?.email, user?.name, user?.tier, user?.avatarUrl]
|
|
599
|
+
);
|
|
580
600
|
const activePanel = panels.find((p) => p.mode === mode);
|
|
581
|
-
const
|
|
582
|
-
/* @__PURE__ */ jsxs6(
|
|
583
|
-
/* @__PURE__ */
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
601
|
+
const buildSidebarContent = React3.useCallback(
|
|
602
|
+
(showLabels) => /* @__PURE__ */ jsxs6(Fragment4, { children: [
|
|
603
|
+
/* @__PURE__ */ jsxs6(SidebarRail, { wide: showLabels, children: [
|
|
604
|
+
/* @__PURE__ */ jsx7(SidebarRailHeader, { children: /* @__PURE__ */ jsx7(Link, { href: "/", to: "/", className: "p-1 rounded-md transition-colors hover:bg-muted/50", children: /* @__PURE__ */ jsx7(Logo, { variant, size: "sm", iconOnly: true }) }) }),
|
|
605
|
+
/* @__PURE__ */ jsx7(SidebarRailNav, { children: navItems.map((item, i) => {
|
|
606
|
+
const isMode = modeSet.has(item.id);
|
|
607
|
+
const prevIsMode = i > 0 && modeSet.has(navItems[i - 1].id);
|
|
608
|
+
const showSep = i > 0 && isMode && !prevIsMode;
|
|
609
|
+
return /* @__PURE__ */ jsxs6(React3.Fragment, { children: [
|
|
610
|
+
showSep && /* @__PURE__ */ jsx7(RailSeparator, {}),
|
|
611
|
+
isMode ? /* @__PURE__ */ jsx7(
|
|
612
|
+
RailModeButton,
|
|
613
|
+
{
|
|
614
|
+
mode: item.id,
|
|
615
|
+
icon: item.icon,
|
|
616
|
+
label: item.label,
|
|
617
|
+
badge: item.badge,
|
|
618
|
+
showLabel: showLabels
|
|
619
|
+
}
|
|
620
|
+
) : /* @__PURE__ */ jsx7(Link, { href: item.href, to: item.href, children: /* @__PURE__ */ jsx7(
|
|
621
|
+
RailButton,
|
|
622
|
+
{
|
|
623
|
+
icon: item.icon,
|
|
624
|
+
label: item.label,
|
|
625
|
+
isActive: activeNavId === item.id,
|
|
626
|
+
showLabel: showLabels
|
|
627
|
+
}
|
|
628
|
+
) })
|
|
629
|
+
] }, item.id);
|
|
630
|
+
}) }),
|
|
631
|
+
/* @__PURE__ */ jsxs6(SidebarRailFooter, { children: [
|
|
632
|
+
onSettingsClick ? /* @__PURE__ */ jsx7(RailButton, { icon: SettingsIconSmall, label: "Settings", onClick: onSettingsClick, showLabel: showLabels }) : /* @__PURE__ */ jsx7(Link, { href: settingsHref, to: settingsHref, children: /* @__PURE__ */ jsx7(RailButton, { icon: SettingsIconSmall, label: "Settings", showLabel: showLabels }) }),
|
|
633
|
+
railFooter,
|
|
634
|
+
/* @__PURE__ */ jsx7(RailSeparator, {}),
|
|
635
|
+
/* @__PURE__ */ jsx7(
|
|
636
|
+
ProfileAvatar,
|
|
600
637
|
{
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
638
|
+
user: sidebarUser,
|
|
639
|
+
isLoading,
|
|
640
|
+
onLogout,
|
|
641
|
+
onSettingsClick,
|
|
642
|
+
settingsHref,
|
|
643
|
+
LinkComponent,
|
|
644
|
+
children: profileMenuItems
|
|
604
645
|
}
|
|
605
|
-
)
|
|
606
|
-
] }
|
|
607
|
-
|
|
608
|
-
/* @__PURE__ */ jsxs6(
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
/* @__PURE__ */ jsx7(RailSeparator, {}),
|
|
612
|
-
/* @__PURE__ */ jsx7(
|
|
613
|
-
ProfileAvatar,
|
|
614
|
-
{
|
|
615
|
-
user: sidebarUser,
|
|
616
|
-
isLoading,
|
|
617
|
-
onLogout,
|
|
618
|
-
onSettingsClick,
|
|
619
|
-
settingsHref,
|
|
620
|
-
LinkComponent,
|
|
621
|
-
children: profileMenuItems
|
|
622
|
-
}
|
|
623
|
-
)
|
|
646
|
+
)
|
|
647
|
+
] })
|
|
648
|
+
] }),
|
|
649
|
+
panels.length > 0 && /* @__PURE__ */ jsxs6(SidebarPanel, { children: [
|
|
650
|
+
/* @__PURE__ */ jsx7(SidebarPanelHeader, { title: activePanel?.title ?? mode }),
|
|
651
|
+
/* @__PURE__ */ jsx7(SidebarPanelContent, { children: activePanel?.content })
|
|
624
652
|
] })
|
|
625
653
|
] }),
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
654
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies: intentional — only the inputs that actually affect the sidebar tree
|
|
655
|
+
[
|
|
656
|
+
Link,
|
|
657
|
+
variant,
|
|
658
|
+
navItems,
|
|
659
|
+
modeSet,
|
|
660
|
+
activeNavId,
|
|
661
|
+
onSettingsClick,
|
|
662
|
+
settingsHref,
|
|
663
|
+
railFooter,
|
|
664
|
+
sidebarUser,
|
|
665
|
+
isLoading,
|
|
666
|
+
onLogout,
|
|
667
|
+
LinkComponent,
|
|
668
|
+
profileMenuItems,
|
|
669
|
+
panels,
|
|
670
|
+
activePanel,
|
|
671
|
+
mode
|
|
672
|
+
]
|
|
673
|
+
);
|
|
674
|
+
const sidebarContent = React3.useMemo(() => buildSidebarContent(false), [buildSidebarContent]);
|
|
675
|
+
const mobileSidebarContent = React3.useMemo(() => buildSidebarContent(true), [buildSidebarContent]);
|
|
631
676
|
return /* @__PURE__ */ jsxs6("div", { className: cn("min-h-screen bg-background text-foreground", className), children: [
|
|
632
677
|
/* @__PURE__ */ jsxs6(
|
|
633
678
|
"nav",
|
|
@@ -638,19 +683,22 @@ function DashboardLayoutInner({
|
|
|
638
683
|
width: hidden ? "100%" : `calc(100% - ${contentMargin}px)`
|
|
639
684
|
},
|
|
640
685
|
children: [
|
|
641
|
-
/* @__PURE__ */
|
|
642
|
-
Link,
|
|
643
|
-
{
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
686
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-8", children: [
|
|
687
|
+
/* @__PURE__ */ jsx7(Link, { href: "/", to: "/", className: "lg:hidden flex items-center p-1 rounded-md hover:bg-muted/50 transition-colors", children: /* @__PURE__ */ jsx7(Logo, { variant, size: "sm", iconOnly: true }) }),
|
|
688
|
+
topNavLinks && topNavLinks.length > 0 && /* @__PURE__ */ jsx7("div", { className: "hidden md:flex gap-6", children: topNavLinks.map((link) => /* @__PURE__ */ jsx7(
|
|
689
|
+
Link,
|
|
690
|
+
{
|
|
691
|
+
href: link.href,
|
|
692
|
+
to: link.href,
|
|
693
|
+
className: cn(
|
|
694
|
+
"transition-all duration-300 px-2 py-1 rounded",
|
|
695
|
+
activeTopNavHref === link.href ? "text-foreground border-b-2 border-primary pb-1" : "text-muted-foreground hover:text-foreground hover:bg-muted/50"
|
|
696
|
+
),
|
|
697
|
+
children: link.label
|
|
698
|
+
},
|
|
699
|
+
link.href
|
|
700
|
+
)) })
|
|
701
|
+
] }),
|
|
654
702
|
/* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-4", children: [
|
|
655
703
|
onNewSandbox && /* @__PURE__ */ jsxs6(
|
|
656
704
|
"button",
|
|
@@ -742,13 +790,14 @@ function DashboardLayoutInner({
|
|
|
742
790
|
"fixed top-14 bottom-0 left-0 z-30 flex bg-background transition-transform duration-200 lg:hidden",
|
|
743
791
|
mobileMenuOpen ? "translate-x-0" : "-translate-x-full"
|
|
744
792
|
),
|
|
745
|
-
style: {
|
|
746
|
-
|
|
793
|
+
style: {
|
|
794
|
+
width: panelOpen && hasPanels ? SIDEBAR_MOBILE_WIDTH + SIDEBAR_PANEL_WIDTH : SIDEBAR_MOBILE_WIDTH
|
|
795
|
+
},
|
|
796
|
+
children: mobileSidebarContent
|
|
747
797
|
}
|
|
748
798
|
),
|
|
749
799
|
/* @__PURE__ */ jsx7(Sidebar, { className: cn("hidden lg:flex", sidebarClassName), children: sidebarContent }),
|
|
750
|
-
/* @__PURE__ */ jsx7(SidebarContent, { className: cn("pt-16 px-
|
|
751
|
-
/* @__PURE__ */ jsx7("main", { className: cn("pt-16 px-6 pb-8 min-h-screen lg:hidden bg-background", contentClassName), children }),
|
|
800
|
+
/* @__PURE__ */ jsx7(SidebarContent, { className: cn("pt-16 px-6 pb-8 lg:px-8 bg-background", contentClassName), children }),
|
|
752
801
|
footer
|
|
753
802
|
] });
|
|
754
803
|
}
|
|
@@ -1547,6 +1596,7 @@ export {
|
|
|
1547
1596
|
SIDEBAR_RAIL_WIDTH,
|
|
1548
1597
|
SIDEBAR_PANEL_WIDTH,
|
|
1549
1598
|
SIDEBAR_TOTAL_WIDTH,
|
|
1599
|
+
SIDEBAR_MOBILE_WIDTH,
|
|
1550
1600
|
SidebarProvider,
|
|
1551
1601
|
useSidebar,
|
|
1552
1602
|
Sidebar,
|
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,
|
|
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, ah 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, ai 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_MOBILE_WIDTH, G as SIDEBAR_PANEL_WIDTH, H as SIDEBAR_RAIL_WIDTH, J as SIDEBAR_TOTAL_WIDTH, K as SandboxCard, L as SandboxCardData, M as SandboxCardProps, O as SandboxStatus, Q as SandboxTable, T as SandboxTableProps, U as Sidebar, V as SidebarContent, W as SidebarContentProps, X as SidebarPanel, Y as SidebarPanelContent, Z as SidebarPanelContentProps, _ as SidebarPanelHeader, $ as SidebarPanelHeaderProps, a0 as SidebarPanelProps, a1 as SidebarProps, a2 as SidebarProvider, a3 as SidebarProviderProps, a4 as SidebarRail, a5 as SidebarRailFooter, a6 as SidebarRailFooterProps, a7 as SidebarRailHeader, a8 as SidebarRailHeaderProps, a9 as SidebarRailNav, aa as SidebarRailNavProps, ab as SidebarRailProps, ac as SidebarUser, aj as Variant, ae as VariantList, af as VariantListProps, ak as VariantOutcome, al as VariantStatus, ag as useSidebar } from './variant-list-DHP2OXFE.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';
|
package/dist/dashboard.js
CHANGED
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
RailModeButton,
|
|
18
18
|
RailSeparator,
|
|
19
19
|
ResourceMeter,
|
|
20
|
+
SIDEBAR_MOBILE_WIDTH,
|
|
20
21
|
SIDEBAR_PANEL_WIDTH,
|
|
21
22
|
SIDEBAR_RAIL_WIDTH,
|
|
22
23
|
SIDEBAR_TOTAL_WIDTH,
|
|
@@ -34,7 +35,7 @@ import {
|
|
|
34
35
|
SidebarRailNav,
|
|
35
36
|
VariantList,
|
|
36
37
|
useSidebar
|
|
37
|
-
} from "./chunk-
|
|
38
|
+
} from "./chunk-7LBHRASD.js";
|
|
38
39
|
import {
|
|
39
40
|
BillingDashboard,
|
|
40
41
|
PricingPage,
|
|
@@ -944,6 +945,7 @@ export {
|
|
|
944
945
|
RailModeButton,
|
|
945
946
|
RailSeparator,
|
|
946
947
|
ResourceMeter,
|
|
948
|
+
SIDEBAR_MOBILE_WIDTH,
|
|
947
949
|
SIDEBAR_PANEL_WIDTH,
|
|
948
950
|
SIDEBAR_RAIL_WIDTH,
|
|
949
951
|
SIDEBAR_TOTAL_WIDTH,
|
package/dist/globals.css
CHANGED
|
@@ -705,6 +705,9 @@
|
|
|
705
705
|
.-top-1 {
|
|
706
706
|
top: calc(var(--spacing) * -1);
|
|
707
707
|
}
|
|
708
|
+
.-top-1\.5 {
|
|
709
|
+
top: calc(var(--spacing) * -1.5);
|
|
710
|
+
}
|
|
708
711
|
.-top-4 {
|
|
709
712
|
top: calc(var(--spacing) * -4);
|
|
710
713
|
}
|
|
@@ -744,6 +747,9 @@
|
|
|
744
747
|
.-right-1 {
|
|
745
748
|
right: calc(var(--spacing) * -1);
|
|
746
749
|
}
|
|
750
|
+
.-right-1\.5 {
|
|
751
|
+
right: calc(var(--spacing) * -1.5);
|
|
752
|
+
}
|
|
747
753
|
.right-0 {
|
|
748
754
|
right: calc(var(--spacing) * 0);
|
|
749
755
|
}
|
|
@@ -1164,9 +1170,6 @@
|
|
|
1164
1170
|
.min-h-\[200px\] {
|
|
1165
1171
|
min-height: 200px;
|
|
1166
1172
|
}
|
|
1167
|
-
.min-h-\[240px\] {
|
|
1168
|
-
min-height: 240px;
|
|
1169
|
-
}
|
|
1170
1173
|
.min-h-full {
|
|
1171
1174
|
min-height: 100%;
|
|
1172
1175
|
}
|
|
@@ -1631,6 +1634,9 @@
|
|
|
1631
1634
|
.justify-end {
|
|
1632
1635
|
justify-content: flex-end;
|
|
1633
1636
|
}
|
|
1637
|
+
.justify-start {
|
|
1638
|
+
justify-content: flex-start;
|
|
1639
|
+
}
|
|
1634
1640
|
.gap-0\.5 {
|
|
1635
1641
|
gap: calc(var(--spacing) * 0.5);
|
|
1636
1642
|
}
|
|
@@ -2122,21 +2128,12 @@
|
|
|
2122
2128
|
.bg-\[\#8E59FF\] {
|
|
2123
2129
|
background-color: #8E59FF;
|
|
2124
2130
|
}
|
|
2125
|
-
.bg-\[\#27c93f\]\/80 {
|
|
2126
|
-
background-color: color-mix(in oklab, #27c93f 80%, transparent);
|
|
2127
|
-
}
|
|
2128
2131
|
.bg-\[\#FEBC2E\] {
|
|
2129
2132
|
background-color: #FEBC2E;
|
|
2130
2133
|
}
|
|
2131
2134
|
.bg-\[\#FF5F57\] {
|
|
2132
2135
|
background-color: #FF5F57;
|
|
2133
2136
|
}
|
|
2134
|
-
.bg-\[\#ff5f56\]\/80 {
|
|
2135
|
-
background-color: color-mix(in oklab, #ff5f56 80%, transparent);
|
|
2136
|
-
}
|
|
2137
|
-
.bg-\[\#ffbd2e\]\/80 {
|
|
2138
|
-
background-color: color-mix(in oklab, #ffbd2e 80%, transparent);
|
|
2139
|
-
}
|
|
2140
2137
|
.bg-\[color\:color-mix\(in_srgb\,var\(--bg-card\)_94\%\,transparent\)\] {
|
|
2141
2138
|
background-color: var(--bg-card);
|
|
2142
2139
|
@supports (color: color-mix(in lab, red, red)) {
|
|
@@ -2406,9 +2403,6 @@
|
|
|
2406
2403
|
.bg-\[linear-gradient\(180deg\,rgba\(255\,255\,255\,0\.04\)\,transparent\)\] {
|
|
2407
2404
|
background-image: linear-gradient(180deg,rgba(255,255,255,0.04),transparent);
|
|
2408
2405
|
}
|
|
2409
|
-
.bg-\[radial-gradient\(circle_at_top\,rgba\(173\,163\,255\,0\.05\)_0\,transparent_100\%\)\] {
|
|
2410
|
-
background-image: radial-gradient(circle at top,rgba(173,163,255,0.05) 0,transparent 100%);
|
|
2411
|
-
}
|
|
2412
2406
|
.from-white\/5 {
|
|
2413
2407
|
--tw-gradient-from: color-mix(in srgb, #fff 5%, transparent);
|
|
2414
2408
|
@supports (color: color-mix(in lab, red, red)) {
|
|
@@ -2648,9 +2642,6 @@
|
|
|
2648
2642
|
.pl-2 {
|
|
2649
2643
|
padding-left: calc(var(--spacing) * 2);
|
|
2650
2644
|
}
|
|
2651
|
-
.pl-3 {
|
|
2652
|
-
padding-left: calc(var(--spacing) * 3);
|
|
2653
|
-
}
|
|
2654
2645
|
.pl-4 {
|
|
2655
2646
|
padding-left: calc(var(--spacing) * 4);
|
|
2656
2647
|
}
|
|
@@ -4183,9 +4174,9 @@
|
|
|
4183
4174
|
grid-column: span 1 / span 1;
|
|
4184
4175
|
}
|
|
4185
4176
|
}
|
|
4186
|
-
.lg\:
|
|
4177
|
+
.lg\:ml-\[var\(--sb-content-margin\,0px\)\] {
|
|
4187
4178
|
@media (width >= 64rem) {
|
|
4188
|
-
|
|
4179
|
+
margin-left: var(--sb-content-margin,0px);
|
|
4189
4180
|
}
|
|
4190
4181
|
}
|
|
4191
4182
|
.lg\:flex {
|
|
@@ -4223,6 +4214,11 @@
|
|
|
4223
4214
|
padding: calc(var(--spacing) * 4);
|
|
4224
4215
|
}
|
|
4225
4216
|
}
|
|
4217
|
+
.lg\:px-8 {
|
|
4218
|
+
@media (width >= 64rem) {
|
|
4219
|
+
padding-inline: calc(var(--spacing) * 8);
|
|
4220
|
+
}
|
|
4221
|
+
}
|
|
4226
4222
|
.xl\:col-span-4 {
|
|
4227
4223
|
@media (width >= 80rem) {
|
|
4228
4224
|
grid-column: span 4 / span 4;
|
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
|
|
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_MOBILE_WIDTH, G as SIDEBAR_PANEL_WIDTH, H as SIDEBAR_RAIL_WIDTH, J as SIDEBAR_TOTAL_WIDTH, K as SandboxCard, L as SandboxCardData, M as SandboxCardProps, O as SandboxStatus, Q as SandboxTable, T as SandboxTableProps, U as Sidebar, V as SidebarContent, W as SidebarContentProps, X as SidebarPanel, Y as SidebarPanelContent, Z as SidebarPanelContentProps, _ as SidebarPanelHeader, $ as SidebarPanelHeaderProps, a0 as SidebarPanelProps, a1 as SidebarProps, a2 as SidebarProvider, a3 as SidebarProviderProps, a4 as SidebarRail, a5 as SidebarRailFooter, a6 as SidebarRailFooterProps, a7 as SidebarRailHeader, a8 as SidebarRailHeaderProps, a9 as SidebarRailNav, aa as SidebarRailNavProps, ab as SidebarRailProps, ac as SidebarUser, ad as TopNavLink, ae as VariantList, af as VariantListProps, ag as useSidebar } from './variant-list-DHP2OXFE.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
|
@@ -195,6 +195,7 @@ import {
|
|
|
195
195
|
RailModeButton,
|
|
196
196
|
RailSeparator,
|
|
197
197
|
ResourceMeter,
|
|
198
|
+
SIDEBAR_MOBILE_WIDTH,
|
|
198
199
|
SIDEBAR_PANEL_WIDTH,
|
|
199
200
|
SIDEBAR_RAIL_WIDTH,
|
|
200
201
|
SIDEBAR_TOTAL_WIDTH,
|
|
@@ -212,7 +213,7 @@ import {
|
|
|
212
213
|
SidebarRailNav,
|
|
213
214
|
VariantList,
|
|
214
215
|
useSidebar
|
|
215
|
-
} from "./chunk-
|
|
216
|
+
} from "./chunk-7LBHRASD.js";
|
|
216
217
|
import {
|
|
217
218
|
BillingDashboard,
|
|
218
219
|
PricingPage,
|
|
@@ -449,6 +450,7 @@ export {
|
|
|
449
450
|
ResourceMeter,
|
|
450
451
|
RunGroup,
|
|
451
452
|
RuntimePane,
|
|
453
|
+
SIDEBAR_MOBILE_WIDTH,
|
|
452
454
|
SIDEBAR_PANEL_WIDTH,
|
|
453
455
|
SIDEBAR_RAIL_WIDTH,
|
|
454
456
|
SIDEBAR_TOTAL_WIDTH,
|
package/dist/pages.d.ts
CHANGED
|
@@ -39,6 +39,32 @@ interface ResourceLimits {
|
|
|
39
39
|
ramMaxGB?: number;
|
|
40
40
|
storageMaxGB?: number;
|
|
41
41
|
}
|
|
42
|
+
interface ModelOption {
|
|
43
|
+
value: string;
|
|
44
|
+
label: string;
|
|
45
|
+
disabled?: boolean;
|
|
46
|
+
}
|
|
47
|
+
interface PricingRates {
|
|
48
|
+
cpuPerHr: number;
|
|
49
|
+
ramPerGbHr: number;
|
|
50
|
+
diskPerGbHr: number;
|
|
51
|
+
minChargePerHr?: number;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Describes one selectable plan tier for the purpose of badging locked
|
|
55
|
+
* presets with the *correct* upgrade target. Without this, every locked
|
|
56
|
+
* preset shows "Pro" — wrong for a user who is already on Pro and whose
|
|
57
|
+
* next step up is Enterprise.
|
|
58
|
+
*/
|
|
59
|
+
interface PlanTierInfo {
|
|
60
|
+
/** Stable id (e.g. "free" | "pro" | "enterprise") */
|
|
61
|
+
id: string;
|
|
62
|
+
/** Short badge label shown on locked presets (e.g. "Pro", "Enterprise") */
|
|
63
|
+
label: string;
|
|
64
|
+
cpuMax: number;
|
|
65
|
+
ramMaxGB: number;
|
|
66
|
+
storageMaxGB: number;
|
|
67
|
+
}
|
|
42
68
|
interface ProvisioningWizardProps {
|
|
43
69
|
environments?: EnvironmentOption[];
|
|
44
70
|
onLoadEnvironments?: () => Promise<EnvironmentEntry[]>;
|
|
@@ -56,6 +82,16 @@ interface ProvisioningWizardProps {
|
|
|
56
82
|
onLoadStartupScripts?: () => Promise<StartupScriptEntry[]>;
|
|
57
83
|
/** Plan-based resource limits — caps the slider maximums */
|
|
58
84
|
resourceLimits?: ResourceLimits;
|
|
85
|
+
/** Override the list of model engines shown in step 3 */
|
|
86
|
+
modelOptions?: ModelOption[];
|
|
87
|
+
/** Real pricing rates from the API for accurate cost calculation */
|
|
88
|
+
pricingRates?: PricingRates;
|
|
89
|
+
/**
|
|
90
|
+
* Ordered list of plan tiers (smallest to largest). When provided,
|
|
91
|
+
* locked presets are badged with the label of the smallest tier that
|
|
92
|
+
* would unlock them. Falls back to a generic "Pro" badge when omitted.
|
|
93
|
+
*/
|
|
94
|
+
planTiers?: PlanTierInfo[];
|
|
59
95
|
}
|
|
60
96
|
interface StartupScriptEntry {
|
|
61
97
|
id: string;
|
|
@@ -82,7 +118,7 @@ interface ProvisioningConfig {
|
|
|
82
118
|
startupScriptIds?: string[];
|
|
83
119
|
}
|
|
84
120
|
declare function resolveEnvironment(env: EnvironmentEntry): EnvironmentOption;
|
|
85
|
-
declare function ProvisioningWizard({ environments: environmentsProp, onLoadEnvironments, onSubmit, onBack, className, variant, defaultEnvironment, defaultConfig, skipToReview, onLoadStartupScripts, resourceLimits, }: ProvisioningWizardProps): react_jsx_runtime.JSX.Element;
|
|
121
|
+
declare function ProvisioningWizard({ environments: environmentsProp, onLoadEnvironments, onSubmit, onBack, className, variant, defaultEnvironment, defaultConfig, skipToReview, onLoadStartupScripts, resourceLimits, modelOptions, pricingRates, planTiers, }: ProvisioningWizardProps): react_jsx_runtime.JSX.Element;
|
|
86
122
|
|
|
87
123
|
type ProductVariant = "sandbox";
|
|
88
124
|
interface StandalonePricingPageProps {
|
|
@@ -234,4 +270,4 @@ type TemplateCategory = "blockchain" | "ai-ml" | "frontend" | "infrastructure" |
|
|
|
234
270
|
type TemplatePreset = Omit<ProvisioningConfig, "name" | "gitUrl" | "envVars" | "driver" | "startupScriptIds">;
|
|
235
271
|
declare function getPresetForTemplate(id: string): TemplatePreset;
|
|
236
272
|
|
|
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 };
|
|
273
|
+
export { BillingPage, type BillingPageData, type BillingPageProps, type EnvironmentEntry, type EnvironmentOption, type ModelOption, type PlanTierInfo, type PricingRates, 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
|
@@ -301,6 +301,10 @@ import * as React2 from "react";
|
|
|
301
301
|
import { ArrowLeft, Layers, Cpu, Bot, Info, Loader2, Settings, Plus, Trash2, Check } from "lucide-react";
|
|
302
302
|
import { Fragment as Fragment2, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
303
303
|
var VALID_DRIVERS = /* @__PURE__ */ new Set(["docker", "firecracker", "tangle"]);
|
|
304
|
+
var DEFAULT_MODEL_OPTIONS = [
|
|
305
|
+
{ value: "claude-sonnet", label: "Claude Sonnet 4.6 (Highly Capable)" }
|
|
306
|
+
];
|
|
307
|
+
var DEFAULT_MODEL_TIER = DEFAULT_MODEL_OPTIONS[0]?.value ?? "claude-sonnet";
|
|
304
308
|
var STACK_DISPLAY = {
|
|
305
309
|
universal: { name: "Default", abbr: "D", color: "violet", textClass: "text-[var(--surface-violet-text)]" },
|
|
306
310
|
ethereum: { name: "Ethereum", abbr: "\u039E", color: "blue", textClass: "text-[var(--surface-info-text)]" },
|
|
@@ -344,8 +348,22 @@ var RAM_MIN = 2;
|
|
|
344
348
|
var RAM_MAX = 32;
|
|
345
349
|
var STORAGE_MIN = 20;
|
|
346
350
|
var STORAGE_MAX = 512;
|
|
347
|
-
|
|
348
|
-
|
|
351
|
+
var DEFAULT_PRICING_RATES = {
|
|
352
|
+
cpuPerHr: 0.045,
|
|
353
|
+
ramPerGbHr: 5e-3,
|
|
354
|
+
diskPerGbHr: 11e-4,
|
|
355
|
+
minChargePerHr: void 0
|
|
356
|
+
};
|
|
357
|
+
var RAW_PRESETS = [
|
|
358
|
+
{ name: "Lightweight", cpu: 2, ram: 4, storage: 50 },
|
|
359
|
+
{ name: "Standard", cpu: 4, ram: 16, storage: 128 },
|
|
360
|
+
{ name: "Performance", cpu: 8, ram: 32, storage: 256 }
|
|
361
|
+
];
|
|
362
|
+
function calcCost(cpu, ram, storage, rates) {
|
|
363
|
+
const cost = Math.max(
|
|
364
|
+
rates.minChargePerHr ?? 0,
|
|
365
|
+
cpu * rates.cpuPerHr + ram * rates.ramPerGbHr + storage * rates.diskPerGbHr
|
|
366
|
+
);
|
|
349
367
|
return cost.toFixed(2);
|
|
350
368
|
}
|
|
351
369
|
function ProvisioningWizard({
|
|
@@ -359,7 +377,10 @@ function ProvisioningWizard({
|
|
|
359
377
|
defaultConfig,
|
|
360
378
|
skipToReview,
|
|
361
379
|
onLoadStartupScripts,
|
|
362
|
-
resourceLimits
|
|
380
|
+
resourceLimits,
|
|
381
|
+
modelOptions,
|
|
382
|
+
pricingRates,
|
|
383
|
+
planTiers
|
|
363
384
|
}) {
|
|
364
385
|
const cpuMax = Math.max(CPU_MIN, Math.min(resourceLimits?.cpuMax ?? CPU_MAX, CPU_MAX));
|
|
365
386
|
const ramMax = Math.max(RAM_MIN, Math.min(resourceLimits?.ramMaxGB ?? RAM_MAX, RAM_MAX));
|
|
@@ -399,8 +420,19 @@ function ProvisioningWizard({
|
|
|
399
420
|
setRamGB((prev) => Math.min(prev, ramMax));
|
|
400
421
|
setStorageGB((prev) => Math.min(prev, storageMax));
|
|
401
422
|
}, [cpuMax, ramMax, storageMax]);
|
|
402
|
-
const [modelTier, setModelTier] = React2.useState(dc?.modelTier ??
|
|
423
|
+
const [modelTier, setModelTier] = React2.useState(dc?.modelTier ?? DEFAULT_MODEL_TIER);
|
|
403
424
|
const [systemPrompt, setSystemPrompt] = React2.useState(dc?.systemPrompt ?? "");
|
|
425
|
+
React2.useEffect(() => {
|
|
426
|
+
const options = modelOptions ?? DEFAULT_MODEL_OPTIONS;
|
|
427
|
+
if (options.length === 0) return;
|
|
428
|
+
const currentOption = options.find((o) => o.value === modelTier);
|
|
429
|
+
if (!currentOption || currentOption.disabled) {
|
|
430
|
+
const firstAvailable = options.find((o) => !o.disabled);
|
|
431
|
+
if (firstAvailable && firstAvailable.value !== modelTier) {
|
|
432
|
+
setModelTier(firstAvailable.value);
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
}, [modelOptions, modelTier]);
|
|
404
436
|
const [name, setName] = React2.useState(dc?.name ?? "");
|
|
405
437
|
const [gitUrl, setGitUrl] = React2.useState(dc?.gitUrl ?? "");
|
|
406
438
|
const [envVars, setEnvVars] = React2.useState(dc?.envVars ?? [{ key: "", value: "" }]);
|
|
@@ -449,12 +481,45 @@ function ProvisioningWizard({
|
|
|
449
481
|
setStorageGB(Math.min(storage, storageMax));
|
|
450
482
|
setActivePreset(name2);
|
|
451
483
|
};
|
|
452
|
-
const presets =
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
484
|
+
const presets = RAW_PRESETS.map((p) => {
|
|
485
|
+
const locked = p.cpu > cpuMax || p.ram > ramMax || p.storage > storageMax;
|
|
486
|
+
let unlockLabel;
|
|
487
|
+
if (locked && planTiers && planTiers.length > 0) {
|
|
488
|
+
const unlocking = planTiers.find(
|
|
489
|
+
(t) => p.cpu <= t.cpuMax && p.ram <= t.ramMaxGB && p.storage <= t.storageMaxGB
|
|
490
|
+
);
|
|
491
|
+
unlockLabel = unlocking?.label;
|
|
492
|
+
}
|
|
493
|
+
return {
|
|
494
|
+
...p,
|
|
495
|
+
fits: !locked,
|
|
496
|
+
locked,
|
|
497
|
+
unlockLabel: unlockLabel ?? "Pro"
|
|
498
|
+
};
|
|
499
|
+
});
|
|
500
|
+
const didInitPresetFromDcRef = React2.useRef(false);
|
|
501
|
+
const lastLimitsRef = React2.useRef(null);
|
|
502
|
+
React2.useEffect(() => {
|
|
503
|
+
const limitsUnchanged = lastLimitsRef.current !== null && lastLimitsRef.current.cpu === cpuMax && lastLimitsRef.current.ram === ramMax && lastLimitsRef.current.storage === storageMax;
|
|
504
|
+
if (limitsUnchanged) return;
|
|
505
|
+
lastLimitsRef.current = { cpu: cpuMax, ram: ramMax, storage: storageMax };
|
|
506
|
+
if (dc && !didInitPresetFromDcRef.current) {
|
|
507
|
+
didInitPresetFromDcRef.current = true;
|
|
508
|
+
const matching = RAW_PRESETS.find(
|
|
509
|
+
(p) => p.cpu === dc.cpuCores && p.ram === dc.ramGB && p.storage === dc.storageGB
|
|
510
|
+
);
|
|
511
|
+
if (matching) setActivePreset(matching.name);
|
|
512
|
+
return;
|
|
513
|
+
}
|
|
514
|
+
const largestFitting = [...RAW_PRESETS].reverse().find((p) => p.cpu <= cpuMax && p.ram <= ramMax && p.storage <= storageMax);
|
|
515
|
+
if (largestFitting) {
|
|
516
|
+
applyPreset(largestFitting.name, largestFitting.cpu, largestFitting.ram, largestFitting.storage);
|
|
517
|
+
} else {
|
|
518
|
+
setActivePreset(null);
|
|
519
|
+
}
|
|
520
|
+
}, [cpuMax, ramMax, storageMax, dc]);
|
|
521
|
+
const effectivePricingRates = pricingRates ?? DEFAULT_PRICING_RATES;
|
|
522
|
+
const hourCost = calcCost(cpuCores, ramGB, storageGB, effectivePricingRates);
|
|
458
523
|
return /* @__PURE__ */ jsxs2("div", { className: cn("max-w-6xl mx-auto flex flex-col", className), children: [
|
|
459
524
|
/* @__PURE__ */ jsxs2("div", { className: "mb-6 flex items-center gap-4 shrink-0", children: [
|
|
460
525
|
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" }) }),
|
|
@@ -492,7 +557,11 @@ function ProvisioningWizard({
|
|
|
492
557
|
setCpuCores(Math.min(4, cpuMax));
|
|
493
558
|
setRamGB(Math.min(16, ramMax));
|
|
494
559
|
setStorageGB(Math.min(128, storageMax));
|
|
495
|
-
|
|
560
|
+
{
|
|
561
|
+
const resetOptions = modelOptions ?? DEFAULT_MODEL_OPTIONS;
|
|
562
|
+
const firstAvailable = resetOptions.find((o) => !o.disabled);
|
|
563
|
+
setModelTier(firstAvailable?.value ?? DEFAULT_MODEL_TIER);
|
|
564
|
+
}
|
|
496
565
|
setSystemPrompt("");
|
|
497
566
|
setName("");
|
|
498
567
|
setGitUrl("");
|
|
@@ -550,59 +619,74 @@ function ProvisioningWizard({
|
|
|
550
619
|
/* @__PURE__ */ jsxs2("div", { className: "mb-6", children: [
|
|
551
620
|
/* @__PURE__ */ jsx2("label", { className: "block font-label text-xs font-bold uppercase tracking-widest text-muted-foreground mb-3", children: "Compute Presets" }),
|
|
552
621
|
/* @__PURE__ */ jsx2("div", { className: "grid grid-cols-3 gap-3", children: presets.map((p) => {
|
|
553
|
-
const active = activePreset === p.name;
|
|
554
|
-
return /* @__PURE__ */ jsxs2(
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
p.
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
622
|
+
const active = activePreset === p.name && !p.locked;
|
|
623
|
+
return /* @__PURE__ */ jsxs2(
|
|
624
|
+
"button",
|
|
625
|
+
{
|
|
626
|
+
type: "button",
|
|
627
|
+
onClick: () => !p.locked && applyPreset(p.name, p.cpu, p.ram, p.storage),
|
|
628
|
+
disabled: p.locked,
|
|
629
|
+
className: cn(
|
|
630
|
+
"p-3 rounded-[14px] transition-all duration-200 text-center group border relative",
|
|
631
|
+
active ? "bg-primary/5 border-primary ring-1 ring-primary/20 shadow-sm" : p.locked ? "bg-muted/30 border-border opacity-60 cursor-not-allowed" : "bg-card border-border hover:border-primary/30 hover:shadow-sm active:scale-[0.97]"
|
|
632
|
+
),
|
|
633
|
+
children: [
|
|
634
|
+
p.locked && /* @__PURE__ */ jsx2("div", { className: "absolute -top-1.5 -right-1.5 bg-primary text-primary-foreground text-[9px] font-bold px-1.5 py-0.5 rounded-full uppercase tracking-wider", children: p.unlockLabel }),
|
|
635
|
+
/* @__PURE__ */ jsx2("div", { className: cn("font-bold text-sm transition-colors duration-200", active ? "text-primary" : p.locked ? "text-muted-foreground" : "text-foreground"), children: p.name }),
|
|
636
|
+
/* @__PURE__ */ jsxs2("div", { className: "text-xs text-muted-foreground mt-0.5 font-mono", children: [
|
|
637
|
+
p.cpu,
|
|
638
|
+
" vCPU",
|
|
639
|
+
p.cpu === 1 ? "" : "s",
|
|
640
|
+
" / ",
|
|
641
|
+
p.ram,
|
|
642
|
+
"GB / ",
|
|
643
|
+
p.storage,
|
|
644
|
+
"GB"
|
|
645
|
+
] })
|
|
646
|
+
]
|
|
647
|
+
},
|
|
648
|
+
p.name
|
|
649
|
+
);
|
|
565
650
|
}) })
|
|
566
651
|
] }),
|
|
567
652
|
/* @__PURE__ */ jsx2("div", { className: "space-y-6", children: [
|
|
568
|
-
{ label: "Compute Cores (CPU)", value: cpuCores, setter: setCpuCores, min: CPU_MIN, max: cpuMax, step: 0.5, unit: "
|
|
653
|
+
{ label: "Compute Cores (CPU)", value: cpuCores, setter: setCpuCores, min: CPU_MIN, max: cpuMax, step: 0.5, unit: "vCPU" },
|
|
569
654
|
{ label: "Memory (RAM)", value: ramGB, setter: setRamGB, min: RAM_MIN, max: ramMax, step: 1, unit: "GB" },
|
|
570
655
|
{ label: "Ephemeral Storage", value: storageGB, setter: setStorageGB, min: STORAGE_MIN, max: storageMax, step: 8, unit: "GB" }
|
|
571
|
-
].map(({ label, value, setter, min, max, step: s, unit }) =>
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
/* @__PURE__ */ jsxs2("
|
|
575
|
-
|
|
576
|
-
" ",
|
|
577
|
-
/* @__PURE__ */ jsx2("span", { className: "text-xs text-primary ml-1", children: unit })
|
|
578
|
-
] })
|
|
579
|
-
] }),
|
|
580
|
-
/* @__PURE__ */ jsx2(
|
|
581
|
-
"input",
|
|
582
|
-
{
|
|
583
|
-
type: "range",
|
|
584
|
-
min,
|
|
585
|
-
max,
|
|
586
|
-
step: s,
|
|
587
|
-
value,
|
|
588
|
-
onChange: (e) => {
|
|
589
|
-
setter(+e.target.value);
|
|
590
|
-
setActivePreset(null);
|
|
591
|
-
},
|
|
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"
|
|
593
|
-
}
|
|
594
|
-
),
|
|
595
|
-
/* @__PURE__ */ jsxs2("div", { className: "flex justify-between text-[10px] font-mono text-muted-foreground/60 mt-1", children: [
|
|
596
|
-
/* @__PURE__ */ jsxs2("span", { children: [
|
|
597
|
-
min,
|
|
598
|
-
unit
|
|
656
|
+
].map(({ label, value, setter, min, max, step: s, unit }) => {
|
|
657
|
+
const displayUnit = unit === "vCPU" ? `${value} vCPU${value === 1 ? "" : "s"}` : `${value}${unit}`;
|
|
658
|
+
return /* @__PURE__ */ jsxs2("div", { children: [
|
|
659
|
+
/* @__PURE__ */ jsxs2("div", { className: "flex justify-between items-end border-b border-border pb-1.5 mb-2", children: [
|
|
660
|
+
/* @__PURE__ */ jsx2("label", { className: "font-label text-xs font-bold uppercase tracking-widest text-muted-foreground", children: label }),
|
|
661
|
+
/* @__PURE__ */ jsx2("span", { className: "text-xl font-bold text-foreground tracking-tight", children: displayUnit })
|
|
599
662
|
] }),
|
|
600
|
-
/* @__PURE__ */
|
|
601
|
-
|
|
602
|
-
|
|
663
|
+
/* @__PURE__ */ jsx2(
|
|
664
|
+
"input",
|
|
665
|
+
{
|
|
666
|
+
type: "range",
|
|
667
|
+
min,
|
|
668
|
+
max,
|
|
669
|
+
step: s,
|
|
670
|
+
value,
|
|
671
|
+
onChange: (e) => {
|
|
672
|
+
setter(+e.target.value);
|
|
673
|
+
setActivePreset(null);
|
|
674
|
+
},
|
|
675
|
+
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"
|
|
676
|
+
}
|
|
677
|
+
),
|
|
678
|
+
/* @__PURE__ */ jsxs2("div", { className: "flex justify-between text-[10px] font-mono text-muted-foreground/60 mt-1", children: [
|
|
679
|
+
/* @__PURE__ */ jsxs2("span", { children: [
|
|
680
|
+
min,
|
|
681
|
+
unit === "vCPU" ? min === 1 ? " vCPU" : " vCPUs" : unit
|
|
682
|
+
] }),
|
|
683
|
+
/* @__PURE__ */ jsxs2("span", { children: [
|
|
684
|
+
max,
|
|
685
|
+
unit === "vCPU" ? max === 1 ? " vCPU" : " vCPUs" : unit
|
|
686
|
+
] })
|
|
603
687
|
] })
|
|
604
|
-
] })
|
|
605
|
-
|
|
688
|
+
] }, label);
|
|
689
|
+
}) })
|
|
606
690
|
] }) }),
|
|
607
691
|
(!isMultistep || currentStep === 3) && /* @__PURE__ */ jsx2(React2.Fragment, { children: /* @__PURE__ */ jsxs2("section", { className: "bg-card border border-border rounded-[24px] p-6 shadow-2xl relative overflow-hidden animate-in fade-in slide-in-from-bottom-4 duration-300", children: [
|
|
608
692
|
/* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-3 mb-5", children: [
|
|
@@ -612,19 +696,26 @@ function ProvisioningWizard({
|
|
|
612
696
|
/* @__PURE__ */ jsxs2("div", { className: "space-y-5", children: [
|
|
613
697
|
/* @__PURE__ */ jsxs2("div", { children: [
|
|
614
698
|
/* @__PURE__ */ jsx2("label", { className: "block font-label text-xs font-bold uppercase tracking-widest text-muted-foreground mb-2", children: "Model Engine" }),
|
|
615
|
-
/* @__PURE__ */
|
|
699
|
+
/* @__PURE__ */ jsx2(
|
|
616
700
|
"select",
|
|
617
701
|
{
|
|
618
702
|
value: modelTier,
|
|
619
703
|
onChange: (e) => setModelTier(e.target.value),
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
704
|
+
disabled: modelOptions && modelOptions.filter((o) => !o.disabled).length === 0,
|
|
705
|
+
className: "w-full bg-card border border-border rounded-xl h-12 px-4 font-bold text-sm text-foreground focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent appearance-none disabled:opacity-50 disabled:cursor-not-allowed",
|
|
706
|
+
children: (modelOptions ?? DEFAULT_MODEL_OPTIONS).map((option) => /* @__PURE__ */ jsx2(
|
|
707
|
+
"option",
|
|
708
|
+
{
|
|
709
|
+
value: option.value,
|
|
710
|
+
disabled: option.disabled,
|
|
711
|
+
className: "bg-gray-900",
|
|
712
|
+
children: option.label
|
|
713
|
+
},
|
|
714
|
+
option.value
|
|
715
|
+
))
|
|
626
716
|
}
|
|
627
|
-
)
|
|
717
|
+
),
|
|
718
|
+
modelOptions && modelOptions.length > 0 && modelOptions.every((o) => o.disabled) && /* @__PURE__ */ jsx2("p", { className: "text-xs text-muted-foreground mt-2", children: "All model options are currently disabled. Please upgrade your plan or contact support." })
|
|
628
719
|
] }),
|
|
629
720
|
/* @__PURE__ */ jsxs2("div", { children: [
|
|
630
721
|
/* @__PURE__ */ jsx2("label", { className: "block font-label text-xs font-bold uppercase tracking-widest text-muted-foreground mb-2", children: "Core Directives (System Prompt)" }),
|
|
@@ -782,57 +873,6 @@ function ProvisioningWizard({
|
|
|
782
873
|
] })
|
|
783
874
|
] }),
|
|
784
875
|
/* @__PURE__ */ jsxs2("div", { className: "col-span-12 xl:col-span-4 sticky top-4 space-y-4", children: [
|
|
785
|
-
/* @__PURE__ */ jsxs2("div", { className: "bg-card border border-primary/15 rounded-[24px] overflow-hidden shadow-2xl relative", children: [
|
|
786
|
-
/* @__PURE__ */ jsx2("div", { className: "absolute inset-0 bg-[radial-gradient(circle_at_top,rgba(173,163,255,0.05)_0,transparent_100%)] pointer-events-none" }),
|
|
787
|
-
/* @__PURE__ */ jsxs2("div", { className: "bg-muted/50 border-b border-border px-4 py-3 flex items-center gap-3", children: [
|
|
788
|
-
/* @__PURE__ */ jsxs2("div", { className: "flex gap-2", children: [
|
|
789
|
-
/* @__PURE__ */ jsx2("div", { className: "h-3 w-3 rounded-full bg-[#ff5f56]/80" }),
|
|
790
|
-
/* @__PURE__ */ jsx2("div", { className: "h-3 w-3 rounded-full bg-[#ffbd2e]/80" }),
|
|
791
|
-
/* @__PURE__ */ jsx2("div", { className: "h-3 w-3 rounded-full bg-[#27c93f]/80" })
|
|
792
|
-
] }),
|
|
793
|
-
/* @__PURE__ */ jsx2("div", { className: "font-mono text-[10px] text-muted-foreground uppercase tracking-widest ml-2 border-l border-border pl-3", children: "deploy_sequence.sh" })
|
|
794
|
-
] }),
|
|
795
|
-
/* @__PURE__ */ jsxs2("div", { className: "p-5 font-mono text-xs space-y-3 min-h-[240px] relative z-10 text-[13px]", children: [
|
|
796
|
-
/* @__PURE__ */ jsxs2("div", { className: "text-green-400", children: [
|
|
797
|
-
"root@tangle:~# ",
|
|
798
|
-
/* @__PURE__ */ jsx2("span", { className: "text-foreground/80", children: "tangle-cli provision --new" })
|
|
799
|
-
] }),
|
|
800
|
-
/* @__PURE__ */ jsx2("div", { className: "text-muted-foreground/70", children: "Initializing deployment handshake..." }),
|
|
801
|
-
/* @__PURE__ */ jsxs2("div", { className: "text-foreground/70", children: [
|
|
802
|
-
/* @__PURE__ */ jsx2("span", { className: "text-primary mr-2", children: "\u2713" }),
|
|
803
|
-
" Bound Platform: ",
|
|
804
|
-
/* @__PURE__ */ jsx2("span", { className: "text-foreground font-bold animate-in fade-in duration-300", children: environments.find((e) => e.id === selectedEnv)?.name ?? "Node.js" }, `env-${selectedEnv}`)
|
|
805
|
-
] }),
|
|
806
|
-
/* @__PURE__ */ jsxs2("div", { className: "text-foreground/70", children: [
|
|
807
|
-
/* @__PURE__ */ jsx2("span", { className: "text-primary mr-2", children: "\u2713" }),
|
|
808
|
-
" Allocation CPU: ",
|
|
809
|
-
/* @__PURE__ */ jsxs2("span", { className: "text-foreground font-bold animate-in fade-in duration-300", children: [
|
|
810
|
-
cpuCores,
|
|
811
|
-
" Cores"
|
|
812
|
-
] }, `cpu-${cpuCores}`)
|
|
813
|
-
] }),
|
|
814
|
-
/* @__PURE__ */ jsxs2("div", { className: "text-foreground/70", children: [
|
|
815
|
-
/* @__PURE__ */ jsx2("span", { className: "text-primary mr-2", children: "\u2713" }),
|
|
816
|
-
" Allocation RAM: ",
|
|
817
|
-
/* @__PURE__ */ jsxs2("span", { className: "text-foreground font-bold animate-in fade-in duration-300", children: [
|
|
818
|
-
ramGB,
|
|
819
|
-
"GB"
|
|
820
|
-
] }, `ram-${ramGB}`)
|
|
821
|
-
] }),
|
|
822
|
-
/* @__PURE__ */ jsxs2("div", { className: "text-foreground/70", children: [
|
|
823
|
-
/* @__PURE__ */ jsx2("span", { className: "text-primary mr-2", children: "\u2713" }),
|
|
824
|
-
" Mounted Storage: ",
|
|
825
|
-
/* @__PURE__ */ jsxs2("span", { className: "text-foreground font-bold animate-in fade-in duration-300", children: [
|
|
826
|
-
storageGB,
|
|
827
|
-
"GB NVMe"
|
|
828
|
-
] }, `disk-${storageGB}`)
|
|
829
|
-
] }),
|
|
830
|
-
/* @__PURE__ */ jsxs2("div", { className: "pt-3 flex items-center gap-3", children: [
|
|
831
|
-
/* @__PURE__ */ jsx2("div", { className: "w-2 h-4 bg-primary animate-pulse" }),
|
|
832
|
-
/* @__PURE__ */ jsx2("span", { className: "text-muted-foreground", children: "Awaiting user confirmation..." })
|
|
833
|
-
] })
|
|
834
|
-
] })
|
|
835
|
-
] }),
|
|
836
876
|
/* @__PURE__ */ jsxs2("div", { className: "p-6 rounded-[24px] bg-card border border-primary/15 relative overflow-hidden", children: [
|
|
837
877
|
/* @__PURE__ */ jsx2("div", { className: "hidden" }),
|
|
838
878
|
/* @__PURE__ */ jsxs2("div", { className: "flex justify-between items-center mb-4 relative z-10", children: [
|
|
@@ -846,32 +886,48 @@ function ProvisioningWizard({
|
|
|
846
886
|
] }, hourCost),
|
|
847
887
|
/* @__PURE__ */ jsx2("span", { className: "text-muted-foreground text-sm font-bold", children: "/ hour" })
|
|
848
888
|
] }),
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
] })
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
889
|
+
(() => {
|
|
890
|
+
const computeCost = cpuCores * effectivePricingRates.cpuPerHr;
|
|
891
|
+
const memoryCost = ramGB * effectivePricingRates.ramPerGbHr;
|
|
892
|
+
const storageCost = storageGB * effectivePricingRates.diskPerGbHr;
|
|
893
|
+
const lineSum = computeCost + memoryCost + storageCost;
|
|
894
|
+
const floor = effectivePricingRates.minChargePerHr ?? 0;
|
|
895
|
+
const floorApplies = floor > lineSum;
|
|
896
|
+
return /* @__PURE__ */ jsxs2("div", { className: "space-y-2 relative z-10 bg-card border border-border rounded-xl p-3", children: [
|
|
897
|
+
/* @__PURE__ */ jsxs2("div", { className: "flex justify-between text-xs font-mono tracking-widest text-muted-foreground", children: [
|
|
898
|
+
/* @__PURE__ */ jsx2("span", { children: "COMPUTE" }),
|
|
899
|
+
/* @__PURE__ */ jsxs2("span", { className: "text-foreground", children: [
|
|
900
|
+
"$",
|
|
901
|
+
computeCost.toFixed(2),
|
|
902
|
+
"/h"
|
|
903
|
+
] })
|
|
904
|
+
] }),
|
|
905
|
+
/* @__PURE__ */ jsxs2("div", { className: "flex justify-between text-xs font-mono tracking-widest text-muted-foreground", children: [
|
|
906
|
+
/* @__PURE__ */ jsx2("span", { children: "MEMORY" }),
|
|
907
|
+
/* @__PURE__ */ jsxs2("span", { className: "text-foreground/80", children: [
|
|
908
|
+
"$",
|
|
909
|
+
memoryCost.toFixed(2),
|
|
910
|
+
"/h"
|
|
911
|
+
] })
|
|
912
|
+
] }),
|
|
913
|
+
/* @__PURE__ */ jsxs2("div", { className: "flex justify-between text-xs font-mono tracking-widest text-muted-foreground", children: [
|
|
914
|
+
/* @__PURE__ */ jsx2("span", { children: "STORAGE" }),
|
|
915
|
+
/* @__PURE__ */ jsxs2("span", { className: "text-foreground/80", children: [
|
|
916
|
+
"$",
|
|
917
|
+
storageCost.toFixed(2),
|
|
918
|
+
"/h"
|
|
919
|
+
] })
|
|
920
|
+
] }),
|
|
921
|
+
floorApplies && /* @__PURE__ */ jsxs2("div", { className: "flex justify-between text-xs font-mono tracking-widest text-primary border-t border-border pt-2", children: [
|
|
922
|
+
/* @__PURE__ */ jsx2("span", { children: "MIN CHARGE" }),
|
|
923
|
+
/* @__PURE__ */ jsxs2("span", { children: [
|
|
924
|
+
"$",
|
|
925
|
+
(floor - lineSum).toFixed(2),
|
|
926
|
+
"/h"
|
|
927
|
+
] })
|
|
872
928
|
] })
|
|
873
|
-
] })
|
|
874
|
-
|
|
929
|
+
] });
|
|
930
|
+
})()
|
|
875
931
|
] }),
|
|
876
932
|
deployError && /* @__PURE__ */ jsxs2("div", { className: "rounded-xl border border-destructive/30 bg-destructive/10 p-3 flex items-center gap-2", children: [
|
|
877
933
|
/* @__PURE__ */ jsx2(Info, { className: "h-4 w-4 text-destructive shrink-0" }),
|
|
@@ -1839,46 +1895,64 @@ function SecretsPage({ apiClient, className }) {
|
|
|
1839
1895
|
/* @__PURE__ */ jsx5(DialogTitle, { children: "Create Secret" }),
|
|
1840
1896
|
/* @__PURE__ */ jsx5(DialogDescription, { children: "Secrets are automatically exposed as environment variables across all your new sandboxes." })
|
|
1841
1897
|
] }),
|
|
1842
|
-
/* @__PURE__ */ jsxs5(
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1898
|
+
/* @__PURE__ */ jsxs5(
|
|
1899
|
+
"form",
|
|
1900
|
+
{
|
|
1901
|
+
onSubmit: (e) => {
|
|
1902
|
+
e.preventDefault();
|
|
1903
|
+
if (newName.trim() && newValue.trim() && !isCreating) handleCreate();
|
|
1904
|
+
},
|
|
1905
|
+
className: "space-y-4",
|
|
1906
|
+
children: [
|
|
1907
|
+
/* @__PURE__ */ jsxs5("div", { children: [
|
|
1908
|
+
/* @__PURE__ */ jsx5("label", { htmlFor: "secret-name", className: "block text-xs font-bold uppercase tracking-widest text-muted-foreground mb-2", children: "Name" }),
|
|
1909
|
+
/* @__PURE__ */ jsx5(
|
|
1910
|
+
"input",
|
|
1911
|
+
{
|
|
1912
|
+
id: "secret-name",
|
|
1913
|
+
name: "secret-name",
|
|
1914
|
+
type: "text",
|
|
1915
|
+
value: newName,
|
|
1916
|
+
onChange: (e) => setNewName(e.target.value.toUpperCase().replace(/[^A-Z0-9_]/g, "_")),
|
|
1917
|
+
placeholder: "MY_SECRET_KEY",
|
|
1918
|
+
autoComplete: "off",
|
|
1919
|
+
className: "w-full rounded-md border border-border bg-card px-3 py-2.5 text-sm font-mono text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring"
|
|
1920
|
+
}
|
|
1921
|
+
)
|
|
1922
|
+
] }),
|
|
1923
|
+
/* @__PURE__ */ jsxs5("div", { children: [
|
|
1924
|
+
/* @__PURE__ */ jsx5("label", { htmlFor: "secret-value", className: "block text-xs font-bold uppercase tracking-widest text-muted-foreground mb-2", children: "Value" }),
|
|
1925
|
+
/* @__PURE__ */ jsxs5("div", { className: "relative", children: [
|
|
1926
|
+
/* @__PURE__ */ jsx5(
|
|
1927
|
+
"input",
|
|
1928
|
+
{
|
|
1929
|
+
id: "secret-value",
|
|
1930
|
+
name: "secret-value",
|
|
1931
|
+
type: showValue ? "text" : "password",
|
|
1932
|
+
value: newValue,
|
|
1933
|
+
onChange: (e) => setNewValue(e.target.value),
|
|
1934
|
+
placeholder: "Enter secret value...",
|
|
1935
|
+
autoComplete: "new-password",
|
|
1936
|
+
className: "w-full rounded-md border border-border bg-card px-3 py-2.5 pr-10 text-sm font-mono text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring"
|
|
1937
|
+
}
|
|
1938
|
+
),
|
|
1939
|
+
/* @__PURE__ */ jsx5(
|
|
1940
|
+
"button",
|
|
1941
|
+
{
|
|
1942
|
+
type: "button",
|
|
1943
|
+
onClick: () => setShowValue(!showValue),
|
|
1944
|
+
className: "absolute right-2 top-1/2 -translate-y-1/2 p-1 text-muted-foreground hover:text-foreground",
|
|
1945
|
+
"aria-label": showValue ? "Hide value" : "Show value",
|
|
1946
|
+
children: showValue ? /* @__PURE__ */ jsx5(EyeOff, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx5(Eye, { className: "h-4 w-4" })
|
|
1947
|
+
}
|
|
1948
|
+
)
|
|
1949
|
+
] }),
|
|
1950
|
+
/* @__PURE__ */ jsx5("p", { className: "mt-1.5 text-xs text-muted-foreground", children: "This value cannot be retrieved after creation." })
|
|
1951
|
+
] }),
|
|
1952
|
+
/* @__PURE__ */ jsx5("button", { type: "submit", className: "hidden", tabIndex: -1, "aria-hidden": "true", children: "Submit" })
|
|
1953
|
+
]
|
|
1954
|
+
}
|
|
1955
|
+
),
|
|
1882
1956
|
createError && /* @__PURE__ */ jsx5("p", { className: "mt-3 text-sm text-destructive", children: createError }),
|
|
1883
1957
|
/* @__PURE__ */ jsxs5(DialogFooter, { children: [
|
|
1884
1958
|
/* @__PURE__ */ jsx5(
|
|
@@ -1958,10 +2032,11 @@ function SecretsPage({ apiClient, className }) {
|
|
|
1958
2032
|
{
|
|
1959
2033
|
type: "button",
|
|
1960
2034
|
onClick: () => setIsCreateOpen(true),
|
|
2035
|
+
"aria-label": "Create your first secret",
|
|
1961
2036
|
className: "mt-6 inline-flex items-center gap-2 rounded-md bg-[var(--btn-primary-bg)] px-4 py-2 text-sm font-semibold text-[var(--btn-primary-text)] hover:bg-[var(--btn-primary-hover)] transition-colors active:scale-[0.97]",
|
|
1962
2037
|
children: [
|
|
1963
2038
|
/* @__PURE__ */ jsx5(Plus3, { className: "h-4 w-4" }),
|
|
1964
|
-
"
|
|
2039
|
+
"New Secret"
|
|
1965
2040
|
]
|
|
1966
2041
|
}
|
|
1967
2042
|
)
|
|
@@ -2858,10 +2933,11 @@ function StartupScriptsPage({ apiClient, className }) {
|
|
|
2858
2933
|
{
|
|
2859
2934
|
type: "button",
|
|
2860
2935
|
onClick: openCreate,
|
|
2936
|
+
"aria-label": "Create your first startup script",
|
|
2861
2937
|
className: "mt-4 inline-flex items-center gap-2 rounded-lg bg-[var(--btn-primary-bg)] px-4 py-2.5 text-sm font-bold text-[var(--btn-primary-text)] shadow-sm transition-colors hover:bg-[var(--btn-primary-hover)]",
|
|
2862
2938
|
children: [
|
|
2863
2939
|
/* @__PURE__ */ jsx7(Plus4, { className: "h-4 w-4" }),
|
|
2864
|
-
"
|
|
2940
|
+
"New Script"
|
|
2865
2941
|
]
|
|
2866
2942
|
}
|
|
2867
2943
|
)
|
package/dist/styles.css
CHANGED
|
@@ -705,6 +705,9 @@
|
|
|
705
705
|
.-top-1 {
|
|
706
706
|
top: calc(var(--spacing) * -1);
|
|
707
707
|
}
|
|
708
|
+
.-top-1\.5 {
|
|
709
|
+
top: calc(var(--spacing) * -1.5);
|
|
710
|
+
}
|
|
708
711
|
.-top-4 {
|
|
709
712
|
top: calc(var(--spacing) * -4);
|
|
710
713
|
}
|
|
@@ -744,6 +747,9 @@
|
|
|
744
747
|
.-right-1 {
|
|
745
748
|
right: calc(var(--spacing) * -1);
|
|
746
749
|
}
|
|
750
|
+
.-right-1\.5 {
|
|
751
|
+
right: calc(var(--spacing) * -1.5);
|
|
752
|
+
}
|
|
747
753
|
.right-0 {
|
|
748
754
|
right: calc(var(--spacing) * 0);
|
|
749
755
|
}
|
|
@@ -1164,9 +1170,6 @@
|
|
|
1164
1170
|
.min-h-\[200px\] {
|
|
1165
1171
|
min-height: 200px;
|
|
1166
1172
|
}
|
|
1167
|
-
.min-h-\[240px\] {
|
|
1168
|
-
min-height: 240px;
|
|
1169
|
-
}
|
|
1170
1173
|
.min-h-full {
|
|
1171
1174
|
min-height: 100%;
|
|
1172
1175
|
}
|
|
@@ -1631,6 +1634,9 @@
|
|
|
1631
1634
|
.justify-end {
|
|
1632
1635
|
justify-content: flex-end;
|
|
1633
1636
|
}
|
|
1637
|
+
.justify-start {
|
|
1638
|
+
justify-content: flex-start;
|
|
1639
|
+
}
|
|
1634
1640
|
.gap-0\.5 {
|
|
1635
1641
|
gap: calc(var(--spacing) * 0.5);
|
|
1636
1642
|
}
|
|
@@ -2122,21 +2128,12 @@
|
|
|
2122
2128
|
.bg-\[\#8E59FF\] {
|
|
2123
2129
|
background-color: #8E59FF;
|
|
2124
2130
|
}
|
|
2125
|
-
.bg-\[\#27c93f\]\/80 {
|
|
2126
|
-
background-color: color-mix(in oklab, #27c93f 80%, transparent);
|
|
2127
|
-
}
|
|
2128
2131
|
.bg-\[\#FEBC2E\] {
|
|
2129
2132
|
background-color: #FEBC2E;
|
|
2130
2133
|
}
|
|
2131
2134
|
.bg-\[\#FF5F57\] {
|
|
2132
2135
|
background-color: #FF5F57;
|
|
2133
2136
|
}
|
|
2134
|
-
.bg-\[\#ff5f56\]\/80 {
|
|
2135
|
-
background-color: color-mix(in oklab, #ff5f56 80%, transparent);
|
|
2136
|
-
}
|
|
2137
|
-
.bg-\[\#ffbd2e\]\/80 {
|
|
2138
|
-
background-color: color-mix(in oklab, #ffbd2e 80%, transparent);
|
|
2139
|
-
}
|
|
2140
2137
|
.bg-\[color\:color-mix\(in_srgb\,var\(--bg-card\)_94\%\,transparent\)\] {
|
|
2141
2138
|
background-color: var(--bg-card);
|
|
2142
2139
|
@supports (color: color-mix(in lab, red, red)) {
|
|
@@ -2406,9 +2403,6 @@
|
|
|
2406
2403
|
.bg-\[linear-gradient\(180deg\,rgba\(255\,255\,255\,0\.04\)\,transparent\)\] {
|
|
2407
2404
|
background-image: linear-gradient(180deg,rgba(255,255,255,0.04),transparent);
|
|
2408
2405
|
}
|
|
2409
|
-
.bg-\[radial-gradient\(circle_at_top\,rgba\(173\,163\,255\,0\.05\)_0\,transparent_100\%\)\] {
|
|
2410
|
-
background-image: radial-gradient(circle at top,rgba(173,163,255,0.05) 0,transparent 100%);
|
|
2411
|
-
}
|
|
2412
2406
|
.from-white\/5 {
|
|
2413
2407
|
--tw-gradient-from: color-mix(in srgb, #fff 5%, transparent);
|
|
2414
2408
|
@supports (color: color-mix(in lab, red, red)) {
|
|
@@ -2648,9 +2642,6 @@
|
|
|
2648
2642
|
.pl-2 {
|
|
2649
2643
|
padding-left: calc(var(--spacing) * 2);
|
|
2650
2644
|
}
|
|
2651
|
-
.pl-3 {
|
|
2652
|
-
padding-left: calc(var(--spacing) * 3);
|
|
2653
|
-
}
|
|
2654
2645
|
.pl-4 {
|
|
2655
2646
|
padding-left: calc(var(--spacing) * 4);
|
|
2656
2647
|
}
|
|
@@ -4183,9 +4174,9 @@
|
|
|
4183
4174
|
grid-column: span 1 / span 1;
|
|
4184
4175
|
}
|
|
4185
4176
|
}
|
|
4186
|
-
.lg\:
|
|
4177
|
+
.lg\:ml-\[var\(--sb-content-margin\,0px\)\] {
|
|
4187
4178
|
@media (width >= 64rem) {
|
|
4188
|
-
|
|
4179
|
+
margin-left: var(--sb-content-margin,0px);
|
|
4189
4180
|
}
|
|
4190
4181
|
}
|
|
4191
4182
|
.lg\:flex {
|
|
@@ -4223,6 +4214,11 @@
|
|
|
4223
4214
|
padding: calc(var(--spacing) * 4);
|
|
4224
4215
|
}
|
|
4225
4216
|
}
|
|
4217
|
+
.lg\:px-8 {
|
|
4218
|
+
@media (width >= 64rem) {
|
|
4219
|
+
padding-inline: calc(var(--spacing) * 8);
|
|
4220
|
+
}
|
|
4221
|
+
}
|
|
4226
4222
|
.xl\:col-span-4 {
|
|
4227
4223
|
@media (width >= 80rem) {
|
|
4228
4224
|
grid-column: span 4 / span 4;
|
|
@@ -16,8 +16,14 @@ declare function Sidebar({ children, className, style }: SidebarProps): react_js
|
|
|
16
16
|
interface SidebarRailProps {
|
|
17
17
|
children: React.ReactNode;
|
|
18
18
|
className?: string;
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
/**
|
|
20
|
+
* Render the rail at the wider mobile-drawer width so labels fit
|
|
21
|
+
* beside the icons. Defaults to the 64px icon-only rail used on
|
|
22
|
+
* desktop.
|
|
23
|
+
*/
|
|
24
|
+
wide?: boolean;
|
|
25
|
+
}
|
|
26
|
+
declare function SidebarRail({ children, className, wide }: SidebarRailProps): react_jsx_runtime.JSX.Element;
|
|
21
27
|
interface SidebarRailHeaderProps {
|
|
22
28
|
children: React.ReactNode;
|
|
23
29
|
className?: string;
|
|
@@ -46,8 +52,10 @@ interface RailButtonProps {
|
|
|
46
52
|
badge?: number;
|
|
47
53
|
onClick?: () => void;
|
|
48
54
|
className?: string;
|
|
55
|
+
/** Show label text next to icon (for mobile drawer) */
|
|
56
|
+
showLabel?: boolean;
|
|
49
57
|
}
|
|
50
|
-
declare function RailButton({ icon: Icon, label, isActive, badge, onClick, className }: RailButtonProps): react_jsx_runtime.JSX.Element;
|
|
58
|
+
declare function RailButton({ icon: Icon, label, isActive, badge, onClick, className, showLabel }: RailButtonProps): react_jsx_runtime.JSX.Element;
|
|
51
59
|
interface RailModeButtonProps {
|
|
52
60
|
mode: string;
|
|
53
61
|
icon: React.ComponentType<{
|
|
@@ -56,8 +64,10 @@ interface RailModeButtonProps {
|
|
|
56
64
|
label: string;
|
|
57
65
|
badge?: number;
|
|
58
66
|
className?: string;
|
|
67
|
+
/** Show label text next to icon (for mobile drawer) */
|
|
68
|
+
showLabel?: boolean;
|
|
59
69
|
}
|
|
60
|
-
declare function RailModeButton({ mode, icon, label, badge, className }: RailModeButtonProps): react_jsx_runtime.JSX.Element;
|
|
70
|
+
declare function RailModeButton({ mode, icon, label, badge, className, showLabel }: RailModeButtonProps): react_jsx_runtime.JSX.Element;
|
|
61
71
|
interface SidebarPanelProps {
|
|
62
72
|
children: React.ReactNode;
|
|
63
73
|
className?: string;
|
|
@@ -96,6 +106,12 @@ declare function ProfileAvatar({ user, isLoading, onLogout, onSettingsClick, set
|
|
|
96
106
|
declare const SIDEBAR_RAIL_WIDTH = 64;
|
|
97
107
|
declare const SIDEBAR_PANEL_WIDTH = 260;
|
|
98
108
|
declare const SIDEBAR_TOTAL_WIDTH: number;
|
|
109
|
+
/**
|
|
110
|
+
* Width of the mobile drawer when the rail is rendered with labels
|
|
111
|
+
* (`showLabel` on {@link RailButton}). The standard 64px rail is only
|
|
112
|
+
* wide enough for icons; labels need a wider container to avoid truncation.
|
|
113
|
+
*/
|
|
114
|
+
declare const SIDEBAR_MOBILE_WIDTH = 256;
|
|
99
115
|
interface SidebarContextValue {
|
|
100
116
|
/** Whether the content panel beside the rail is open */
|
|
101
117
|
panelOpen: boolean;
|
|
@@ -389,4 +405,4 @@ interface VariantListProps {
|
|
|
389
405
|
}
|
|
390
406
|
declare function VariantList({ variants, selectedId, onSelect, onAccept, onReject, isActioning, className, }: VariantListProps): react_jsx_runtime.JSX.Element;
|
|
391
407
|
|
|
392
|
-
export { type
|
|
408
|
+
export { type SidebarPanelHeaderProps as $, type RailSeparatorProps as A, type Backend as B, ClusterStatusBar as C, DashboardLayout as D, ResourceMeter as E, type ResourceMeterProps as F, SIDEBAR_PANEL_WIDTH as G, SIDEBAR_RAIL_WIDTH as H, type Invoice as I, SIDEBAR_TOTAL_WIDTH as J, SandboxCard as K, type SandboxCardData as L, type SandboxCardProps as M, type NavItem as N, type SandboxStatus as O, type PanelConfig as P, SandboxTable as Q, RailButton as R, SIDEBAR_MOBILE_WIDTH as S, type SandboxTableProps as T, Sidebar as U, SidebarContent as V, type SidebarContentProps as W, SidebarPanel as X, SidebarPanelContent as Y, type SidebarPanelContentProps as Z, SidebarPanelHeader as _, BackendSelector as a, type SidebarPanelProps as a0, type SidebarProps as a1, SidebarProvider as a2, type SidebarProviderProps as a3, SidebarRail as a4, SidebarRailFooter as a5, type SidebarRailFooterProps as a6, SidebarRailHeader as a7, type SidebarRailHeaderProps as a8, SidebarRailNav as a9, type SidebarRailNavProps as aa, type SidebarRailProps as ab, type SidebarUser as ac, type TopNavLink as ad, VariantList as ae, type VariantListProps as af, useSidebar as ag, type Profile as ah, type PlanFeature as ai, type Variant as aj, type VariantOutcome as ak, type VariantStatus as al, type BackendSelectorProps as b, type ClusterStatusBarProps as c, type ClusterStatusItem as d, CreditBalance as e, type CreditBalanceProps as f, type DashboardLayoutProps as g, type DashboardUser as h, InvoiceTable as i, type InvoiceTableProps as j, NewSandboxCard as k, type NewSandboxCardProps as l, type PlanCardData as m, PlanCards as n, type PlanCardsProps as o, type ProductVariant as p, ProfileAvatar as q, type ProfileAvatarProps as r, ProfileComparison as s, type ProfileComparisonProps as t, ProfileSelector as u, type ProfileSelectorProps as v, type RailButtonProps as w, RailModeButton as x, type RailModeButtonProps as y, RailSeparator as z };
|
package/package.json
CHANGED