@camstack/ui-library 0.1.34 → 0.1.35
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/index.cjs +601 -407
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +29 -3
- package/dist/index.d.ts +29 -3
- package/dist/index.js +560 -369
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -32,6 +32,7 @@ var src_exports = {};
|
|
|
32
32
|
__export(src_exports, {
|
|
33
33
|
AppShell: () => AppShell,
|
|
34
34
|
Badge: () => Badge,
|
|
35
|
+
BottomSheet: () => BottomSheet,
|
|
35
36
|
Button: () => Button,
|
|
36
37
|
CLASS_COLORS: () => CLASS_COLORS,
|
|
37
38
|
Card: () => Card,
|
|
@@ -68,6 +69,7 @@ __export(src_exports, {
|
|
|
68
69
|
KeyValueList: () => KeyValueList,
|
|
69
70
|
Label: () => Label,
|
|
70
71
|
LoginForm: () => LoginForm,
|
|
72
|
+
MobileDrawer: () => MobileDrawer,
|
|
71
73
|
PageHeader: () => PageHeader,
|
|
72
74
|
PipelineBuilder: () => PipelineBuilder,
|
|
73
75
|
PipelineRuntimeSelector: () => PipelineRuntimeSelector,
|
|
@@ -107,6 +109,7 @@ __export(src_exports, {
|
|
|
107
109
|
statusIcons: () => statusIcons,
|
|
108
110
|
themeToCss: () => themeToCss,
|
|
109
111
|
useDevShell: () => useDevShell,
|
|
112
|
+
useIsMobile: () => useIsMobile,
|
|
110
113
|
useThemeMode: () => useThemeMode
|
|
111
114
|
});
|
|
112
115
|
module.exports = __toCommonJS(src_exports);
|
|
@@ -787,7 +790,7 @@ function DialogTrigger({ children, ...props }) {
|
|
|
787
790
|
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", onClick: () => setOpen(true), ...props, children });
|
|
788
791
|
}
|
|
789
792
|
var contentVariants = (0, import_class_variance_authority7.cva)(
|
|
790
|
-
"bg-background-elevated border border-border rounded-lg p-4 backdrop:bg-black/50 backdrop:backdrop-blur-sm",
|
|
793
|
+
"bg-background-elevated border border-border rounded-lg p-4 backdrop:bg-black/50 backdrop:backdrop-blur-sm max-w-[calc(100vw-2rem)] max-h-[calc(100dvh-2rem)] overflow-y-auto",
|
|
791
794
|
{
|
|
792
795
|
variants: {
|
|
793
796
|
width: {
|
|
@@ -1175,8 +1178,28 @@ var ScrollArea = (0, import_react19.forwardRef)(
|
|
|
1175
1178
|
ScrollArea.displayName = "ScrollArea";
|
|
1176
1179
|
|
|
1177
1180
|
// src/primitives/floating-panel.tsx
|
|
1178
|
-
var
|
|
1181
|
+
var import_react21 = require("react");
|
|
1179
1182
|
var import_lucide_react4 = require("lucide-react");
|
|
1183
|
+
|
|
1184
|
+
// src/hooks/use-is-mobile.ts
|
|
1185
|
+
var import_react20 = require("react");
|
|
1186
|
+
var MOBILE_QUERY = "(max-width: 767px)";
|
|
1187
|
+
function subscribe(callback) {
|
|
1188
|
+
const mql = window.matchMedia(MOBILE_QUERY);
|
|
1189
|
+
mql.addEventListener("change", callback);
|
|
1190
|
+
return () => mql.removeEventListener("change", callback);
|
|
1191
|
+
}
|
|
1192
|
+
function getSnapshot() {
|
|
1193
|
+
return window.matchMedia(MOBILE_QUERY).matches;
|
|
1194
|
+
}
|
|
1195
|
+
function getServerSnapshot() {
|
|
1196
|
+
return false;
|
|
1197
|
+
}
|
|
1198
|
+
function useIsMobile() {
|
|
1199
|
+
return (0, import_react20.useSyncExternalStore)(subscribe, getSnapshot, getServerSnapshot);
|
|
1200
|
+
}
|
|
1201
|
+
|
|
1202
|
+
// src/primitives/floating-panel.tsx
|
|
1180
1203
|
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
1181
1204
|
function FloatingPanel({
|
|
1182
1205
|
title,
|
|
@@ -1189,24 +1212,25 @@ function FloatingPanel({
|
|
|
1189
1212
|
offsetIndex = 0,
|
|
1190
1213
|
className
|
|
1191
1214
|
}) {
|
|
1192
|
-
const [pos, setPos] = (0,
|
|
1193
|
-
const [size, setSize] = (0,
|
|
1194
|
-
const [minimized, setMinimized] = (0,
|
|
1195
|
-
const dragging = (0,
|
|
1196
|
-
const resizing = (0,
|
|
1197
|
-
const offset = (0,
|
|
1198
|
-
const
|
|
1215
|
+
const [pos, setPos] = (0, import_react21.useState)({ x: 80 + offsetIndex * 30, y: 80 + offsetIndex * 30 });
|
|
1216
|
+
const [size, setSize] = (0, import_react21.useState)({ w: defaultWidth, h: defaultHeight });
|
|
1217
|
+
const [minimized, setMinimized] = (0, import_react21.useState)(false);
|
|
1218
|
+
const dragging = (0, import_react21.useRef)(false);
|
|
1219
|
+
const resizing = (0, import_react21.useRef)(false);
|
|
1220
|
+
const offset = (0, import_react21.useRef)({ x: 0, y: 0 });
|
|
1221
|
+
const isMobile = useIsMobile();
|
|
1222
|
+
const onDragStart = (0, import_react21.useCallback)((e) => {
|
|
1199
1223
|
e.preventDefault();
|
|
1200
1224
|
dragging.current = true;
|
|
1201
1225
|
offset.current = { x: e.clientX - pos.x, y: e.clientY - pos.y };
|
|
1202
1226
|
}, [pos]);
|
|
1203
|
-
const onResizeStart = (0,
|
|
1227
|
+
const onResizeStart = (0, import_react21.useCallback)((e) => {
|
|
1204
1228
|
e.preventDefault();
|
|
1205
1229
|
e.stopPropagation();
|
|
1206
1230
|
resizing.current = true;
|
|
1207
1231
|
offset.current = { x: e.clientX, y: e.clientY };
|
|
1208
1232
|
}, []);
|
|
1209
|
-
(0,
|
|
1233
|
+
(0, import_react21.useEffect)(() => {
|
|
1210
1234
|
const onMouseMove = (e) => {
|
|
1211
1235
|
if (dragging.current) setPos({ x: e.clientX - offset.current.x, y: e.clientY - offset.current.y });
|
|
1212
1236
|
if (resizing.current) {
|
|
@@ -1227,6 +1251,42 @@ function FloatingPanel({
|
|
|
1227
1251
|
window.removeEventListener("mouseup", onMouseUp);
|
|
1228
1252
|
};
|
|
1229
1253
|
}, [minWidth, minHeight]);
|
|
1254
|
+
if (isMobile) {
|
|
1255
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
1256
|
+
"div",
|
|
1257
|
+
{
|
|
1258
|
+
className: cn(
|
|
1259
|
+
"fixed inset-x-0 bottom-0 z-50 rounded-t-xl border-t border-border bg-background-elevated shadow-2xl flex flex-col overflow-hidden",
|
|
1260
|
+
className
|
|
1261
|
+
),
|
|
1262
|
+
style: { maxHeight: "60dvh" },
|
|
1263
|
+
children: [
|
|
1264
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex items-center justify-between gap-2 px-3 py-2 border-b border-border shrink-0 bg-surface", children: [
|
|
1265
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "text-[11px] font-medium truncate", children: title }),
|
|
1266
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex items-center gap-1 shrink-0", children: [
|
|
1267
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
1268
|
+
"button",
|
|
1269
|
+
{
|
|
1270
|
+
onClick: () => setMinimized(!minimized),
|
|
1271
|
+
className: "p-0.5 rounded hover:bg-surface-hover text-foreground-muted transition-colors",
|
|
1272
|
+
children: minimized ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react4.Maximize2, { size: 12 }) : /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react4.Minimize2, { size: 12 })
|
|
1273
|
+
}
|
|
1274
|
+
),
|
|
1275
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
1276
|
+
"button",
|
|
1277
|
+
{
|
|
1278
|
+
onClick: onClose,
|
|
1279
|
+
className: "p-0.5 rounded hover:bg-danger/20 text-foreground-muted hover:text-danger transition-colors",
|
|
1280
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react4.X, { size: 12 })
|
|
1281
|
+
}
|
|
1282
|
+
)
|
|
1283
|
+
] })
|
|
1284
|
+
] }),
|
|
1285
|
+
!minimized && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "flex-1 min-h-0 overflow-y-auto", children })
|
|
1286
|
+
]
|
|
1287
|
+
}
|
|
1288
|
+
);
|
|
1289
|
+
}
|
|
1230
1290
|
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
1231
1291
|
"div",
|
|
1232
1292
|
{
|
|
@@ -1285,8 +1345,115 @@ function FloatingPanel({
|
|
|
1285
1345
|
);
|
|
1286
1346
|
}
|
|
1287
1347
|
|
|
1288
|
-
// src/
|
|
1348
|
+
// src/primitives/mobile-drawer.tsx
|
|
1349
|
+
var import_react22 = require("react");
|
|
1289
1350
|
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
1351
|
+
function MobileDrawer({ open, onClose, children, className, width = "w-64" }) {
|
|
1352
|
+
const drawerRef = (0, import_react22.useRef)(null);
|
|
1353
|
+
(0, import_react22.useEffect)(() => {
|
|
1354
|
+
if (!open) return;
|
|
1355
|
+
const handleKeyDown = (e) => {
|
|
1356
|
+
if (e.key === "Escape") onClose();
|
|
1357
|
+
};
|
|
1358
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
1359
|
+
document.body.style.overflow = "hidden";
|
|
1360
|
+
return () => {
|
|
1361
|
+
document.removeEventListener("keydown", handleKeyDown);
|
|
1362
|
+
document.body.style.overflow = "";
|
|
1363
|
+
};
|
|
1364
|
+
}, [open, onClose]);
|
|
1365
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
|
|
1366
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
1367
|
+
"div",
|
|
1368
|
+
{
|
|
1369
|
+
className: cn(
|
|
1370
|
+
"fixed inset-0 z-40 bg-black/50 backdrop-blur-sm transition-opacity duration-200",
|
|
1371
|
+
open ? "opacity-100" : "pointer-events-none opacity-0"
|
|
1372
|
+
),
|
|
1373
|
+
onClick: onClose,
|
|
1374
|
+
"aria-hidden": "true"
|
|
1375
|
+
}
|
|
1376
|
+
),
|
|
1377
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
1378
|
+
"div",
|
|
1379
|
+
{
|
|
1380
|
+
ref: drawerRef,
|
|
1381
|
+
role: "dialog",
|
|
1382
|
+
"aria-modal": "true",
|
|
1383
|
+
className: cn(
|
|
1384
|
+
"fixed inset-y-0 left-0 z-50 flex flex-col bg-surface border-r border-border shadow-2xl transition-transform duration-200 ease-out",
|
|
1385
|
+
width,
|
|
1386
|
+
open ? "translate-x-0" : "-translate-x-full",
|
|
1387
|
+
className
|
|
1388
|
+
),
|
|
1389
|
+
children
|
|
1390
|
+
}
|
|
1391
|
+
)
|
|
1392
|
+
] });
|
|
1393
|
+
}
|
|
1394
|
+
|
|
1395
|
+
// src/primitives/bottom-sheet.tsx
|
|
1396
|
+
var import_react23 = require("react");
|
|
1397
|
+
var import_lucide_react5 = require("lucide-react");
|
|
1398
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
1399
|
+
function BottomSheet({ open, onClose, title, children, className }) {
|
|
1400
|
+
(0, import_react23.useEffect)(() => {
|
|
1401
|
+
if (!open) return;
|
|
1402
|
+
const handleKeyDown = (e) => {
|
|
1403
|
+
if (e.key === "Escape") onClose();
|
|
1404
|
+
};
|
|
1405
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
1406
|
+
document.body.style.overflow = "hidden";
|
|
1407
|
+
return () => {
|
|
1408
|
+
document.removeEventListener("keydown", handleKeyDown);
|
|
1409
|
+
document.body.style.overflow = "";
|
|
1410
|
+
};
|
|
1411
|
+
}, [open, onClose]);
|
|
1412
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
|
|
1413
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
1414
|
+
"div",
|
|
1415
|
+
{
|
|
1416
|
+
className: cn(
|
|
1417
|
+
"fixed inset-0 z-40 bg-black/50 transition-opacity duration-200",
|
|
1418
|
+
open ? "opacity-100" : "pointer-events-none opacity-0"
|
|
1419
|
+
),
|
|
1420
|
+
onClick: onClose,
|
|
1421
|
+
"aria-hidden": "true"
|
|
1422
|
+
}
|
|
1423
|
+
),
|
|
1424
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
1425
|
+
"div",
|
|
1426
|
+
{
|
|
1427
|
+
role: "dialog",
|
|
1428
|
+
"aria-modal": "true",
|
|
1429
|
+
className: cn(
|
|
1430
|
+
"fixed inset-x-0 bottom-0 z-50 flex flex-col bg-background-elevated border-t border-border rounded-t-xl shadow-2xl transition-transform duration-200 ease-out",
|
|
1431
|
+
"max-h-[80dvh]",
|
|
1432
|
+
open ? "translate-y-0" : "translate-y-full",
|
|
1433
|
+
className
|
|
1434
|
+
),
|
|
1435
|
+
children: [
|
|
1436
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "flex justify-center pt-2 pb-1", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "h-1 w-8 rounded-full bg-foreground-subtle/30" }) }),
|
|
1437
|
+
title && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex items-center justify-between px-4 pb-2", children: [
|
|
1438
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-sm font-medium text-foreground", children: title }),
|
|
1439
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
1440
|
+
"button",
|
|
1441
|
+
{
|
|
1442
|
+
onClick: onClose,
|
|
1443
|
+
className: "p-1 rounded-md hover:bg-surface-hover text-foreground-muted transition-colors",
|
|
1444
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react5.X, { className: "h-4 w-4" })
|
|
1445
|
+
}
|
|
1446
|
+
)
|
|
1447
|
+
] }),
|
|
1448
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "flex-1 overflow-y-auto px-4 pb-4", children })
|
|
1449
|
+
]
|
|
1450
|
+
}
|
|
1451
|
+
)
|
|
1452
|
+
] });
|
|
1453
|
+
}
|
|
1454
|
+
|
|
1455
|
+
// src/composites/status-badge.tsx
|
|
1456
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
1290
1457
|
var statusConfig = {
|
|
1291
1458
|
online: { colorClass: "bg-success", label: "Online" },
|
|
1292
1459
|
offline: { colorClass: "bg-danger", label: "Offline" },
|
|
@@ -1301,7 +1468,7 @@ function StatusBadge({
|
|
|
1301
1468
|
className
|
|
1302
1469
|
}) {
|
|
1303
1470
|
const config = statusConfig[status];
|
|
1304
|
-
return /* @__PURE__ */ (0,
|
|
1471
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
1305
1472
|
"span",
|
|
1306
1473
|
{
|
|
1307
1474
|
className: cn(
|
|
@@ -1310,21 +1477,21 @@ function StatusBadge({
|
|
|
1310
1477
|
className
|
|
1311
1478
|
),
|
|
1312
1479
|
children: [
|
|
1313
|
-
showDot && /* @__PURE__ */ (0,
|
|
1480
|
+
showDot && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
1314
1481
|
"span",
|
|
1315
1482
|
{
|
|
1316
1483
|
className: cn("h-1.5 w-1.5 shrink-0 rounded-full", config.colorClass),
|
|
1317
1484
|
"aria-hidden": "true"
|
|
1318
1485
|
}
|
|
1319
1486
|
),
|
|
1320
|
-
showLabel && /* @__PURE__ */ (0,
|
|
1487
|
+
showLabel && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "text-foreground", children: config.label })
|
|
1321
1488
|
]
|
|
1322
1489
|
}
|
|
1323
1490
|
);
|
|
1324
1491
|
}
|
|
1325
1492
|
|
|
1326
1493
|
// src/composites/provider-badge.tsx
|
|
1327
|
-
var
|
|
1494
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
1328
1495
|
var providerConfig = {
|
|
1329
1496
|
frigate: { colorClass: "bg-provider-frigate", label: "Frigate" },
|
|
1330
1497
|
scrypted: { colorClass: "bg-provider-scrypted", label: "Scrypted" },
|
|
@@ -1338,20 +1505,20 @@ function ProviderBadge({
|
|
|
1338
1505
|
className
|
|
1339
1506
|
}) {
|
|
1340
1507
|
const config = providerConfig[provider];
|
|
1341
|
-
return /* @__PURE__ */ (0,
|
|
1342
|
-
/* @__PURE__ */ (0,
|
|
1508
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("span", { className: cn("inline-flex items-center gap-1.5 text-xs", className), children: [
|
|
1509
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
1343
1510
|
"span",
|
|
1344
1511
|
{
|
|
1345
1512
|
className: cn("h-1.5 w-1.5 shrink-0 rounded-sm", config.colorClass),
|
|
1346
1513
|
"aria-hidden": "true"
|
|
1347
1514
|
}
|
|
1348
1515
|
),
|
|
1349
|
-
showLabel && /* @__PURE__ */ (0,
|
|
1516
|
+
showLabel && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-foreground", children: config.label })
|
|
1350
1517
|
] });
|
|
1351
1518
|
}
|
|
1352
1519
|
|
|
1353
1520
|
// src/composites/version-badge.tsx
|
|
1354
|
-
var
|
|
1521
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
1355
1522
|
var VARIANT_STYLES = {
|
|
1356
1523
|
success: "bg-emerald-400 text-emerald-950",
|
|
1357
1524
|
warning: "bg-amber-400 text-amber-950",
|
|
@@ -1360,7 +1527,7 @@ var VARIANT_STYLES = {
|
|
|
1360
1527
|
neutral: "bg-foreground-subtle/20 text-foreground"
|
|
1361
1528
|
};
|
|
1362
1529
|
function SemanticBadge({ children, variant = "neutral", mono, className }) {
|
|
1363
|
-
return /* @__PURE__ */ (0,
|
|
1530
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: cn(
|
|
1364
1531
|
"inline-flex items-center rounded-md px-2 py-0.5 text-[11px] font-bold leading-tight",
|
|
1365
1532
|
mono && "font-mono",
|
|
1366
1533
|
VARIANT_STYLES[variant],
|
|
@@ -1369,11 +1536,11 @@ function SemanticBadge({ children, variant = "neutral", mono, className }) {
|
|
|
1369
1536
|
}
|
|
1370
1537
|
function VersionBadge({ version, preRelease, className }) {
|
|
1371
1538
|
const isPreRelease = preRelease ?? /-(alpha|beta|rc|dev|canary|next)/i.test(version);
|
|
1372
|
-
return /* @__PURE__ */ (0,
|
|
1539
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SemanticBadge, { variant: isPreRelease ? "warning" : "success", mono: true, className, children: version });
|
|
1373
1540
|
}
|
|
1374
1541
|
|
|
1375
1542
|
// src/composites/form-field.tsx
|
|
1376
|
-
var
|
|
1543
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
1377
1544
|
function FormField({
|
|
1378
1545
|
label,
|
|
1379
1546
|
description,
|
|
@@ -1384,7 +1551,7 @@ function FormField({
|
|
|
1384
1551
|
className
|
|
1385
1552
|
}) {
|
|
1386
1553
|
const isHorizontal = orientation === "horizontal";
|
|
1387
|
-
return /* @__PURE__ */ (0,
|
|
1554
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
1388
1555
|
"div",
|
|
1389
1556
|
{
|
|
1390
1557
|
className: cn(
|
|
@@ -1393,34 +1560,34 @@ function FormField({
|
|
|
1393
1560
|
className
|
|
1394
1561
|
),
|
|
1395
1562
|
children: [
|
|
1396
|
-
/* @__PURE__ */ (0,
|
|
1397
|
-
/* @__PURE__ */ (0,
|
|
1563
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: cn(isHorizontal ? "flex-1" : ""), children: [
|
|
1564
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(Label, { children: [
|
|
1398
1565
|
label,
|
|
1399
|
-
required && /* @__PURE__ */ (0,
|
|
1566
|
+
required && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "text-danger ml-0.5", children: "*" })
|
|
1400
1567
|
] }),
|
|
1401
|
-
description && /* @__PURE__ */ (0,
|
|
1568
|
+
description && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "text-foreground-subtle text-xs mt-0.5", children: description })
|
|
1402
1569
|
] }),
|
|
1403
|
-
/* @__PURE__ */ (0,
|
|
1404
|
-
error && /* @__PURE__ */ (0,
|
|
1570
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: cn(isHorizontal ? "shrink-0" : ""), children }),
|
|
1571
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "text-danger text-xs", children: error })
|
|
1405
1572
|
]
|
|
1406
1573
|
}
|
|
1407
1574
|
);
|
|
1408
1575
|
}
|
|
1409
1576
|
|
|
1410
1577
|
// src/composites/page-header.tsx
|
|
1411
|
-
var
|
|
1578
|
+
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
1412
1579
|
function PageHeader({ title, subtitle, actions, className }) {
|
|
1413
|
-
return /* @__PURE__ */ (0,
|
|
1414
|
-
/* @__PURE__ */ (0,
|
|
1415
|
-
/* @__PURE__ */ (0,
|
|
1416
|
-
subtitle && /* @__PURE__ */ (0,
|
|
1580
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: cn("flex flex-col gap-2 mb-3 sm:flex-row sm:items-center sm:justify-between", className), children: [
|
|
1581
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { children: [
|
|
1582
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("h1", { className: "text-sm font-semibold text-foreground", children: title }),
|
|
1583
|
+
subtitle && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("p", { className: "text-foreground-subtle text-xs", children: subtitle })
|
|
1417
1584
|
] }),
|
|
1418
|
-
actions && /* @__PURE__ */ (0,
|
|
1585
|
+
actions && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "flex items-center gap-2 flex-wrap", children: actions })
|
|
1419
1586
|
] });
|
|
1420
1587
|
}
|
|
1421
1588
|
|
|
1422
1589
|
// src/composites/empty-state.tsx
|
|
1423
|
-
var
|
|
1590
|
+
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
1424
1591
|
function EmptyState({
|
|
1425
1592
|
icon: Icon,
|
|
1426
1593
|
title,
|
|
@@ -1428,18 +1595,18 @@ function EmptyState({
|
|
|
1428
1595
|
action,
|
|
1429
1596
|
className
|
|
1430
1597
|
}) {
|
|
1431
|
-
return /* @__PURE__ */ (0,
|
|
1432
|
-
Icon && /* @__PURE__ */ (0,
|
|
1433
|
-
/* @__PURE__ */ (0,
|
|
1434
|
-
/* @__PURE__ */ (0,
|
|
1435
|
-
description && /* @__PURE__ */ (0,
|
|
1598
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: cn("flex flex-col items-center justify-center gap-3 py-12", className), children: [
|
|
1599
|
+
Icon && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(Icon, { className: "h-12 w-12 text-foreground-subtle", "aria-hidden": "true" }),
|
|
1600
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex flex-col items-center gap-1 text-center", children: [
|
|
1601
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("p", { className: "text-foreground-muted text-sm font-medium", children: title }),
|
|
1602
|
+
description && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("p", { className: "text-foreground-subtle text-xs max-w-xs", children: description })
|
|
1436
1603
|
] }),
|
|
1437
|
-
action && /* @__PURE__ */ (0,
|
|
1604
|
+
action && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "mt-1", children: action })
|
|
1438
1605
|
] });
|
|
1439
1606
|
}
|
|
1440
1607
|
|
|
1441
1608
|
// src/composites/confirm-dialog.tsx
|
|
1442
|
-
var
|
|
1609
|
+
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
1443
1610
|
function ConfirmDialog({
|
|
1444
1611
|
title,
|
|
1445
1612
|
message,
|
|
@@ -1451,14 +1618,14 @@ function ConfirmDialog({
|
|
|
1451
1618
|
open,
|
|
1452
1619
|
onOpenChange
|
|
1453
1620
|
}) {
|
|
1454
|
-
return /* @__PURE__ */ (0,
|
|
1455
|
-
/* @__PURE__ */ (0,
|
|
1456
|
-
/* @__PURE__ */ (0,
|
|
1457
|
-
/* @__PURE__ */ (0,
|
|
1621
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Dialog, { open, onOpenChange, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(DialogContent, { children: [
|
|
1622
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(DialogHeader, { children: [
|
|
1623
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(DialogTitle, { children: title }),
|
|
1624
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(DialogDescription, { children: message })
|
|
1458
1625
|
] }),
|
|
1459
|
-
/* @__PURE__ */ (0,
|
|
1460
|
-
/* @__PURE__ */ (0,
|
|
1461
|
-
/* @__PURE__ */ (0,
|
|
1626
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(DialogFooter, { children: [
|
|
1627
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Button, { variant: "ghost", onClick: onCancel, children: cancelLabel }),
|
|
1628
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
1462
1629
|
Button,
|
|
1463
1630
|
{
|
|
1464
1631
|
variant: variant === "danger" ? "danger" : "primary",
|
|
@@ -1471,13 +1638,13 @@ function ConfirmDialog({
|
|
|
1471
1638
|
}
|
|
1472
1639
|
|
|
1473
1640
|
// src/composites/stat-card.tsx
|
|
1474
|
-
var
|
|
1475
|
-
var
|
|
1641
|
+
var import_lucide_react6 = require("lucide-react");
|
|
1642
|
+
var import_jsx_runtime29 = require("react/jsx-runtime");
|
|
1476
1643
|
function StatCard({ value, label, trend, className }) {
|
|
1477
|
-
return /* @__PURE__ */ (0,
|
|
1478
|
-
/* @__PURE__ */ (0,
|
|
1479
|
-
/* @__PURE__ */ (0,
|
|
1480
|
-
trend && /* @__PURE__ */ (0,
|
|
1644
|
+
return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(Card, { className: cn("flex flex-col gap-1", className), children: [
|
|
1645
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex items-baseline gap-2", children: [
|
|
1646
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "text-2xl font-semibold text-foreground", children: value }),
|
|
1647
|
+
trend && /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
|
|
1481
1648
|
"span",
|
|
1482
1649
|
{
|
|
1483
1650
|
className: cn(
|
|
@@ -1485,27 +1652,27 @@ function StatCard({ value, label, trend, className }) {
|
|
|
1485
1652
|
trend.direction === "up" ? "text-success" : "text-danger"
|
|
1486
1653
|
),
|
|
1487
1654
|
children: [
|
|
1488
|
-
trend.direction === "up" ? /* @__PURE__ */ (0,
|
|
1655
|
+
trend.direction === "up" ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_lucide_react6.TrendingUp, { className: "h-3 w-3" }) : /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_lucide_react6.TrendingDown, { className: "h-3 w-3" }),
|
|
1489
1656
|
trend.value,
|
|
1490
1657
|
"%"
|
|
1491
1658
|
]
|
|
1492
1659
|
}
|
|
1493
1660
|
)
|
|
1494
1661
|
] }),
|
|
1495
|
-
/* @__PURE__ */ (0,
|
|
1662
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "text-xs text-foreground-muted", children: label })
|
|
1496
1663
|
] });
|
|
1497
1664
|
}
|
|
1498
1665
|
|
|
1499
1666
|
// src/composites/key-value-list.tsx
|
|
1500
|
-
var
|
|
1667
|
+
var import_jsx_runtime30 = require("react/jsx-runtime");
|
|
1501
1668
|
function KeyValueList({ items, className }) {
|
|
1502
|
-
return /* @__PURE__ */ (0,
|
|
1669
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("dl", { className: cn("flex flex-col", className), children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
|
|
1503
1670
|
"div",
|
|
1504
1671
|
{
|
|
1505
1672
|
className: "flex items-center h-7",
|
|
1506
1673
|
children: [
|
|
1507
|
-
/* @__PURE__ */ (0,
|
|
1508
|
-
/* @__PURE__ */ (0,
|
|
1674
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("dt", { className: "text-foreground-subtle text-xs w-1/3 shrink-0", children: item.key }),
|
|
1675
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("dd", { className: "text-foreground text-xs", children: item.value })
|
|
1509
1676
|
]
|
|
1510
1677
|
},
|
|
1511
1678
|
item.key
|
|
@@ -1513,23 +1680,23 @@ function KeyValueList({ items, className }) {
|
|
|
1513
1680
|
}
|
|
1514
1681
|
|
|
1515
1682
|
// src/composites/code-block.tsx
|
|
1516
|
-
var
|
|
1517
|
-
var
|
|
1518
|
-
var
|
|
1683
|
+
var import_react24 = require("react");
|
|
1684
|
+
var import_lucide_react7 = require("lucide-react");
|
|
1685
|
+
var import_jsx_runtime31 = require("react/jsx-runtime");
|
|
1519
1686
|
function CodeBlock({ children, maxHeight = 300, className }) {
|
|
1520
|
-
const [copied, setCopied] = (0,
|
|
1521
|
-
const handleCopy = (0,
|
|
1687
|
+
const [copied, setCopied] = (0, import_react24.useState)(false);
|
|
1688
|
+
const handleCopy = (0, import_react24.useCallback)(() => {
|
|
1522
1689
|
navigator.clipboard.writeText(children).then(() => {
|
|
1523
1690
|
setCopied(true);
|
|
1524
1691
|
setTimeout(() => setCopied(false), 2e3);
|
|
1525
1692
|
});
|
|
1526
1693
|
}, [children]);
|
|
1527
|
-
return /* @__PURE__ */ (0,
|
|
1528
|
-
/* @__PURE__ */ (0,
|
|
1529
|
-
/* @__PURE__ */ (0,
|
|
1694
|
+
return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: cn("relative group", className), children: [
|
|
1695
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(ScrollArea, { style: { maxHeight }, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("pre", { className: "font-mono text-xs bg-surface p-3 rounded-md border border-border-subtle", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("code", { children }) }) }),
|
|
1696
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "absolute top-2 right-2 opacity-0 group-hover:opacity-100 transition-opacity", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
1530
1697
|
IconButton,
|
|
1531
1698
|
{
|
|
1532
|
-
icon: copied ?
|
|
1699
|
+
icon: copied ? import_lucide_react7.Check : import_lucide_react7.Copy,
|
|
1533
1700
|
"aria-label": "Copy code",
|
|
1534
1701
|
variant: "ghost",
|
|
1535
1702
|
size: "sm",
|
|
@@ -1540,28 +1707,28 @@ function CodeBlock({ children, maxHeight = 300, className }) {
|
|
|
1540
1707
|
}
|
|
1541
1708
|
|
|
1542
1709
|
// src/composites/filter-bar.tsx
|
|
1543
|
-
var
|
|
1544
|
-
var
|
|
1710
|
+
var import_lucide_react8 = require("lucide-react");
|
|
1711
|
+
var import_jsx_runtime32 = require("react/jsx-runtime");
|
|
1545
1712
|
function FilterBar({ filters, values, onChange, className }) {
|
|
1546
1713
|
const handleChange = (key, value) => {
|
|
1547
1714
|
onChange({ ...values, [key]: value });
|
|
1548
1715
|
};
|
|
1549
|
-
return /* @__PURE__ */ (0,
|
|
1716
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: cn("flex items-center gap-2 flex-wrap", className), children: filters.map((filter) => {
|
|
1550
1717
|
switch (filter.type) {
|
|
1551
1718
|
case "search":
|
|
1552
|
-
return /* @__PURE__ */ (0,
|
|
1719
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
1553
1720
|
Input,
|
|
1554
1721
|
{
|
|
1555
1722
|
placeholder: filter.placeholder ?? "Search...",
|
|
1556
1723
|
value: values[filter.key] ?? "",
|
|
1557
1724
|
onChange: (e) => handleChange(filter.key, e.target.value),
|
|
1558
|
-
leftSlot: /* @__PURE__ */ (0,
|
|
1725
|
+
leftSlot: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_lucide_react8.Search, { className: "h-3 w-3 text-foreground-subtle" }),
|
|
1559
1726
|
className: "w-48"
|
|
1560
1727
|
},
|
|
1561
1728
|
filter.key
|
|
1562
1729
|
);
|
|
1563
1730
|
case "select":
|
|
1564
|
-
return /* @__PURE__ */ (0,
|
|
1731
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
1565
1732
|
Select,
|
|
1566
1733
|
{
|
|
1567
1734
|
options: filter.options,
|
|
@@ -1572,10 +1739,10 @@ function FilterBar({ filters, values, onChange, className }) {
|
|
|
1572
1739
|
filter.key
|
|
1573
1740
|
);
|
|
1574
1741
|
case "badge-toggle":
|
|
1575
|
-
return /* @__PURE__ */ (0,
|
|
1742
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "flex items-center gap-1", children: filter.options.map((option) => {
|
|
1576
1743
|
const currentValue = values[filter.key];
|
|
1577
1744
|
const isActive = currentValue === option.value;
|
|
1578
|
-
return /* @__PURE__ */ (0,
|
|
1745
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
1579
1746
|
"button",
|
|
1580
1747
|
{
|
|
1581
1748
|
type: "button",
|
|
@@ -1583,7 +1750,7 @@ function FilterBar({ filters, values, onChange, className }) {
|
|
|
1583
1750
|
filter.key,
|
|
1584
1751
|
isActive ? void 0 : option.value
|
|
1585
1752
|
),
|
|
1586
|
-
children: /* @__PURE__ */ (0,
|
|
1753
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
1587
1754
|
Badge,
|
|
1588
1755
|
{
|
|
1589
1756
|
variant: isActive ? "info" : "default",
|
|
@@ -1602,7 +1769,7 @@ function FilterBar({ filters, values, onChange, className }) {
|
|
|
1602
1769
|
}
|
|
1603
1770
|
|
|
1604
1771
|
// src/composites/app-shell/sidebar-item.tsx
|
|
1605
|
-
var
|
|
1772
|
+
var import_jsx_runtime33 = require("react/jsx-runtime");
|
|
1606
1773
|
function SidebarItem({
|
|
1607
1774
|
label,
|
|
1608
1775
|
icon: Icon,
|
|
@@ -1611,7 +1778,7 @@ function SidebarItem({
|
|
|
1611
1778
|
active = false,
|
|
1612
1779
|
className
|
|
1613
1780
|
}) {
|
|
1614
|
-
return /* @__PURE__ */ (0,
|
|
1781
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
|
|
1615
1782
|
"a",
|
|
1616
1783
|
{
|
|
1617
1784
|
href,
|
|
@@ -1621,33 +1788,33 @@ function SidebarItem({
|
|
|
1621
1788
|
className
|
|
1622
1789
|
),
|
|
1623
1790
|
children: [
|
|
1624
|
-
/* @__PURE__ */ (0,
|
|
1625
|
-
/* @__PURE__ */ (0,
|
|
1626
|
-
badge !== void 0 && /* @__PURE__ */ (0,
|
|
1791
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Icon, { className: "h-3.5 w-3.5 shrink-0" }),
|
|
1792
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "truncate flex-1", children: label }),
|
|
1793
|
+
badge !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Badge, { className: "ml-auto text-[10px] px-1.5 py-0", children: badge })
|
|
1627
1794
|
]
|
|
1628
1795
|
}
|
|
1629
1796
|
);
|
|
1630
1797
|
}
|
|
1631
1798
|
|
|
1632
1799
|
// src/composites/app-shell/sidebar.tsx
|
|
1633
|
-
var
|
|
1634
|
-
function Sidebar({ logo, sections, footer, className }) {
|
|
1635
|
-
return /* @__PURE__ */ (0,
|
|
1800
|
+
var import_jsx_runtime34 = require("react/jsx-runtime");
|
|
1801
|
+
function Sidebar({ logo, sections, footer, onNavigate, className }) {
|
|
1802
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
|
|
1636
1803
|
"nav",
|
|
1637
1804
|
{
|
|
1638
1805
|
className: cn(
|
|
1639
|
-
"
|
|
1806
|
+
"bg-surface border-r border-border h-full flex flex-col",
|
|
1640
1807
|
className
|
|
1641
1808
|
),
|
|
1642
1809
|
children: [
|
|
1643
|
-
logo && /* @__PURE__ */ (0,
|
|
1644
|
-
/* @__PURE__ */ (0,
|
|
1645
|
-
section.label && /* @__PURE__ */ (0,
|
|
1646
|
-
/* @__PURE__ */ (0,
|
|
1810
|
+
logo && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "px-3 py-2 shrink-0", children: logo }),
|
|
1811
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "flex-1 overflow-auto px-1 py-1", children: sections.map((section, sectionIndex) => /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: cn(sectionIndex > 0 ? "mt-3" : ""), children: [
|
|
1812
|
+
section.label && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "text-[10px] text-foreground-disabled uppercase tracking-wider px-2 mb-1 block", children: section.label }),
|
|
1813
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "flex flex-col gap-0.5", onClick: onNavigate, children: section.items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(SidebarItem, { ...item }, item.href)) })
|
|
1647
1814
|
] }, sectionIndex)) }),
|
|
1648
|
-
footer && footer.length > 0 && /* @__PURE__ */ (0,
|
|
1649
|
-
/* @__PURE__ */ (0,
|
|
1650
|
-
/* @__PURE__ */ (0,
|
|
1815
|
+
footer && footer.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "shrink-0 px-1 pb-1", children: [
|
|
1816
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(Separator, { className: "mb-1" }),
|
|
1817
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "flex flex-col gap-0.5", onClick: onNavigate, children: footer.map((item) => /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(SidebarItem, { ...item }, item.href)) })
|
|
1651
1818
|
] })
|
|
1652
1819
|
]
|
|
1653
1820
|
}
|
|
@@ -1655,54 +1822,78 @@ function Sidebar({ logo, sections, footer, className }) {
|
|
|
1655
1822
|
}
|
|
1656
1823
|
|
|
1657
1824
|
// src/composites/app-shell/app-shell.tsx
|
|
1658
|
-
var
|
|
1659
|
-
var
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1825
|
+
var import_react25 = require("react");
|
|
1826
|
+
var import_lucide_react9 = require("lucide-react");
|
|
1827
|
+
var import_jsx_runtime35 = require("react/jsx-runtime");
|
|
1828
|
+
function AppShell({ sidebar, header, mobileLogo, mobileActions, children, className }) {
|
|
1829
|
+
const isMobile = useIsMobile();
|
|
1830
|
+
const [drawerOpen, setDrawerOpen] = (0, import_react25.useState)(false);
|
|
1831
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: cn("flex h-screen", className), children: [
|
|
1832
|
+
!isMobile && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(Sidebar, { ...sidebar, className: cn("w-44", sidebar.className) }),
|
|
1833
|
+
isMobile && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(MobileDrawer, { open: drawerOpen, onClose: () => setDrawerOpen(false), width: "w-64", children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
1834
|
+
Sidebar,
|
|
1835
|
+
{
|
|
1836
|
+
...sidebar,
|
|
1837
|
+
onNavigate: () => setDrawerOpen(false),
|
|
1838
|
+
className: "w-full border-r-0"
|
|
1839
|
+
}
|
|
1840
|
+
) }),
|
|
1841
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "flex flex-1 flex-col min-w-0", children: [
|
|
1842
|
+
isMobile && /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("header", { className: "flex items-center h-12 border-b border-border px-3 shrink-0 bg-surface/80 backdrop-blur-sm", children: [
|
|
1843
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
1844
|
+
"button",
|
|
1845
|
+
{
|
|
1846
|
+
onClick: () => setDrawerOpen(true),
|
|
1847
|
+
className: "p-1.5 -ml-1.5 rounded-md hover:bg-surface-hover text-foreground-muted transition-colors",
|
|
1848
|
+
"aria-label": "Open menu",
|
|
1849
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_lucide_react9.Menu, { className: "h-5 w-5" })
|
|
1850
|
+
}
|
|
1851
|
+
),
|
|
1852
|
+
mobileLogo && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "flex-1 flex justify-center", children: mobileLogo }),
|
|
1853
|
+
mobileActions && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "shrink-0", children: mobileActions })
|
|
1854
|
+
] }),
|
|
1855
|
+
!isMobile && header && /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("header", { className: "flex items-center h-10 border-b border-border px-4 shrink-0", children: [
|
|
1856
|
+
header.breadcrumbs && header.breadcrumbs.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("nav", { className: "flex items-center gap-1 text-xs flex-1 min-w-0", children: header.breadcrumbs.map((crumb, index) => {
|
|
1666
1857
|
const isLast = index === header.breadcrumbs.length - 1;
|
|
1667
|
-
return /* @__PURE__ */ (0,
|
|
1668
|
-
index > 0 && /* @__PURE__ */ (0,
|
|
1669
|
-
crumb.href && !isLast ? /* @__PURE__ */ (0,
|
|
1858
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("span", { className: "flex items-center gap-1", children: [
|
|
1859
|
+
index > 0 && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_lucide_react9.ChevronRight, { className: "h-3 w-3 text-foreground-subtle shrink-0" }),
|
|
1860
|
+
crumb.href && !isLast ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
1670
1861
|
"a",
|
|
1671
1862
|
{
|
|
1672
1863
|
href: crumb.href,
|
|
1673
1864
|
className: "text-foreground-subtle hover:text-foreground transition-colors truncate",
|
|
1674
1865
|
children: crumb.label
|
|
1675
1866
|
}
|
|
1676
|
-
) : /* @__PURE__ */ (0,
|
|
1867
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "text-foreground truncate", children: crumb.label })
|
|
1677
1868
|
] }, index);
|
|
1678
1869
|
}) }),
|
|
1679
|
-
header.actions && /* @__PURE__ */ (0,
|
|
1870
|
+
header.actions && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "flex items-center gap-2 ml-auto shrink-0", children: header.actions })
|
|
1680
1871
|
] }),
|
|
1681
|
-
/* @__PURE__ */ (0,
|
|
1872
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("main", { className: "flex-1 overflow-auto p-4", children })
|
|
1682
1873
|
] })
|
|
1683
1874
|
] });
|
|
1684
1875
|
}
|
|
1685
1876
|
|
|
1686
1877
|
// src/composites/data-table/data-table.tsx
|
|
1687
|
-
var
|
|
1878
|
+
var import_react26 = require("react");
|
|
1688
1879
|
var import_react_table = require("@tanstack/react-table");
|
|
1689
1880
|
|
|
1690
1881
|
// src/composites/data-table/data-table-header.tsx
|
|
1691
|
-
var
|
|
1692
|
-
var
|
|
1882
|
+
var import_lucide_react10 = require("lucide-react");
|
|
1883
|
+
var import_jsx_runtime36 = require("react/jsx-runtime");
|
|
1693
1884
|
function DataTableHeader({
|
|
1694
1885
|
headerGroups,
|
|
1695
1886
|
onSortingChange,
|
|
1696
1887
|
stickyHeader,
|
|
1697
1888
|
flexRender: render
|
|
1698
1889
|
}) {
|
|
1699
|
-
return /* @__PURE__ */ (0,
|
|
1890
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
1700
1891
|
"thead",
|
|
1701
1892
|
{
|
|
1702
1893
|
className: cn(
|
|
1703
1894
|
stickyHeader && "sticky top-0 z-10 bg-background"
|
|
1704
1895
|
),
|
|
1705
|
-
children: headerGroups.map((headerGroup) => /* @__PURE__ */ (0,
|
|
1896
|
+
children: headerGroups.map((headerGroup) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("tr", { className: "h-6", children: headerGroup.headers.map((header) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
1706
1897
|
HeaderCell,
|
|
1707
1898
|
{
|
|
1708
1899
|
header,
|
|
@@ -1716,8 +1907,8 @@ function DataTableHeader({
|
|
|
1716
1907
|
}
|
|
1717
1908
|
function HeaderCell({ header, sortable, flexRender: render }) {
|
|
1718
1909
|
const sorted = header.column.getIsSorted();
|
|
1719
|
-
const SortIcon = sorted === "asc" ?
|
|
1720
|
-
return /* @__PURE__ */ (0,
|
|
1910
|
+
const SortIcon = sorted === "asc" ? import_lucide_react10.ArrowUp : sorted === "desc" ? import_lucide_react10.ArrowDown : import_lucide_react10.ArrowUpDown;
|
|
1911
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
1721
1912
|
"th",
|
|
1722
1913
|
{
|
|
1723
1914
|
className: cn(
|
|
@@ -1725,17 +1916,17 @@ function HeaderCell({ header, sortable, flexRender: render }) {
|
|
|
1725
1916
|
sortable && "cursor-pointer select-none"
|
|
1726
1917
|
),
|
|
1727
1918
|
onClick: sortable ? header.column.getToggleSortingHandler() : void 0,
|
|
1728
|
-
children: /* @__PURE__ */ (0,
|
|
1919
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("span", { className: "inline-flex items-center gap-1", children: [
|
|
1729
1920
|
header.isPlaceholder ? null : render(header.column.columnDef.header, header.getContext()),
|
|
1730
|
-
sortable && /* @__PURE__ */ (0,
|
|
1921
|
+
sortable && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(SortIcon, { className: "h-3 w-3" })
|
|
1731
1922
|
] })
|
|
1732
1923
|
}
|
|
1733
1924
|
);
|
|
1734
1925
|
}
|
|
1735
1926
|
|
|
1736
1927
|
// src/composites/data-table/data-table-row.tsx
|
|
1737
|
-
var
|
|
1738
|
-
var
|
|
1928
|
+
var import_lucide_react11 = require("lucide-react");
|
|
1929
|
+
var import_jsx_runtime37 = require("react/jsx-runtime");
|
|
1739
1930
|
function DataTableRow({
|
|
1740
1931
|
row,
|
|
1741
1932
|
onRowClick,
|
|
@@ -1743,7 +1934,7 @@ function DataTableRow({
|
|
|
1743
1934
|
flexRender: render
|
|
1744
1935
|
}) {
|
|
1745
1936
|
const actions = rowActions ? rowActions(row.original) : [];
|
|
1746
|
-
return /* @__PURE__ */ (0,
|
|
1937
|
+
return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(
|
|
1747
1938
|
"tr",
|
|
1748
1939
|
{
|
|
1749
1940
|
className: cn(
|
|
@@ -1753,17 +1944,17 @@ function DataTableRow({
|
|
|
1753
1944
|
),
|
|
1754
1945
|
onClick: onRowClick ? () => onRowClick(row.original) : void 0,
|
|
1755
1946
|
children: [
|
|
1756
|
-
row.getVisibleCells().map((cell) => /* @__PURE__ */ (0,
|
|
1757
|
-
actions.length > 0 && /* @__PURE__ */ (0,
|
|
1758
|
-
/* @__PURE__ */ (0,
|
|
1947
|
+
row.getVisibleCells().map((cell) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(DataTableCell, { cell, flexRender: render }, cell.id)),
|
|
1948
|
+
actions.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("td", { className: "px-2 py-1.5 w-8", children: /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(Dropdown, { children: [
|
|
1949
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
1759
1950
|
DropdownTrigger,
|
|
1760
1951
|
{
|
|
1761
1952
|
className: "p-0.5 rounded hover:bg-surface-hover",
|
|
1762
1953
|
onClick: (e) => e.stopPropagation(),
|
|
1763
|
-
children: /* @__PURE__ */ (0,
|
|
1954
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_lucide_react11.MoreHorizontal, { className: "h-3.5 w-3.5 text-foreground-muted" })
|
|
1764
1955
|
}
|
|
1765
1956
|
),
|
|
1766
|
-
/* @__PURE__ */ (0,
|
|
1957
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(DropdownContent, { className: "right-0 left-auto", children: actions.map((action) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
1767
1958
|
DropdownItem,
|
|
1768
1959
|
{
|
|
1769
1960
|
icon: action.icon,
|
|
@@ -1782,12 +1973,12 @@ function DataTableRow({
|
|
|
1782
1973
|
);
|
|
1783
1974
|
}
|
|
1784
1975
|
function DataTableCell({ cell, flexRender: render }) {
|
|
1785
|
-
return /* @__PURE__ */ (0,
|
|
1976
|
+
return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("td", { className: "px-2 py-1.5 text-xs text-foreground", children: render(cell.column.columnDef.cell, cell.getContext()) });
|
|
1786
1977
|
}
|
|
1787
1978
|
|
|
1788
1979
|
// src/composites/data-table/data-table-pagination.tsx
|
|
1789
|
-
var
|
|
1790
|
-
var
|
|
1980
|
+
var import_lucide_react12 = require("lucide-react");
|
|
1981
|
+
var import_jsx_runtime38 = require("react/jsx-runtime");
|
|
1791
1982
|
var PAGE_SIZE_OPTIONS = [
|
|
1792
1983
|
{ value: "10", label: "10" },
|
|
1793
1984
|
{ value: "25", label: "25" },
|
|
@@ -1802,10 +1993,10 @@ function DataTablePagination({
|
|
|
1802
1993
|
}) {
|
|
1803
1994
|
const totalPages = Math.max(1, Math.ceil(total / pageSize));
|
|
1804
1995
|
const currentPage = page + 1;
|
|
1805
|
-
return /* @__PURE__ */ (0,
|
|
1806
|
-
/* @__PURE__ */ (0,
|
|
1807
|
-
/* @__PURE__ */ (0,
|
|
1808
|
-
/* @__PURE__ */ (0,
|
|
1996
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "flex items-center justify-between px-2 py-2 text-xs text-foreground-muted", children: [
|
|
1997
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
1998
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { children: "Rows per page" }),
|
|
1999
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "w-16", children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
1809
2000
|
Select,
|
|
1810
2001
|
{
|
|
1811
2002
|
options: PAGE_SIZE_OPTIONS,
|
|
@@ -1817,17 +2008,17 @@ function DataTablePagination({
|
|
|
1817
2008
|
}
|
|
1818
2009
|
) })
|
|
1819
2010
|
] }),
|
|
1820
|
-
/* @__PURE__ */ (0,
|
|
1821
|
-
/* @__PURE__ */ (0,
|
|
2011
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
2012
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("span", { children: [
|
|
1822
2013
|
"Page ",
|
|
1823
2014
|
currentPage,
|
|
1824
2015
|
" of ",
|
|
1825
2016
|
totalPages
|
|
1826
2017
|
] }),
|
|
1827
|
-
/* @__PURE__ */ (0,
|
|
2018
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
1828
2019
|
IconButton,
|
|
1829
2020
|
{
|
|
1830
|
-
icon:
|
|
2021
|
+
icon: import_lucide_react12.ChevronLeft,
|
|
1831
2022
|
"aria-label": "Previous page",
|
|
1832
2023
|
variant: "ghost",
|
|
1833
2024
|
size: "sm",
|
|
@@ -1835,10 +2026,10 @@ function DataTablePagination({
|
|
|
1835
2026
|
onClick: () => onPaginationChange?.({ pageIndex: page - 1, pageSize })
|
|
1836
2027
|
}
|
|
1837
2028
|
),
|
|
1838
|
-
/* @__PURE__ */ (0,
|
|
2029
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
1839
2030
|
IconButton,
|
|
1840
2031
|
{
|
|
1841
|
-
icon:
|
|
2032
|
+
icon: import_lucide_react12.ChevronRight,
|
|
1842
2033
|
"aria-label": "Next page",
|
|
1843
2034
|
variant: "ghost",
|
|
1844
2035
|
size: "sm",
|
|
@@ -1851,7 +2042,7 @@ function DataTablePagination({
|
|
|
1851
2042
|
}
|
|
1852
2043
|
|
|
1853
2044
|
// src/composites/data-table/data-table.tsx
|
|
1854
|
-
var
|
|
2045
|
+
var import_jsx_runtime39 = require("react/jsx-runtime");
|
|
1855
2046
|
function DataTable({
|
|
1856
2047
|
data,
|
|
1857
2048
|
columns: userColumns,
|
|
@@ -1870,11 +2061,11 @@ function DataTable({
|
|
|
1870
2061
|
stickyHeader = false,
|
|
1871
2062
|
className
|
|
1872
2063
|
}) {
|
|
1873
|
-
const columns = (0,
|
|
2064
|
+
const columns = (0, import_react26.useMemo)(() => {
|
|
1874
2065
|
if (!selectable) return userColumns;
|
|
1875
2066
|
const selectColumn = {
|
|
1876
2067
|
id: "__select",
|
|
1877
|
-
header: ({ table: table2 }) => /* @__PURE__ */ (0,
|
|
2068
|
+
header: ({ table: table2 }) => /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
1878
2069
|
Checkbox,
|
|
1879
2070
|
{
|
|
1880
2071
|
checked: table2.getIsAllPageRowsSelected(),
|
|
@@ -1882,7 +2073,7 @@ function DataTable({
|
|
|
1882
2073
|
"aria-label": "Select all"
|
|
1883
2074
|
}
|
|
1884
2075
|
),
|
|
1885
|
-
cell: ({ row }) => /* @__PURE__ */ (0,
|
|
2076
|
+
cell: ({ row }) => /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
1886
2077
|
Checkbox,
|
|
1887
2078
|
{
|
|
1888
2079
|
checked: row.getIsSelected(),
|
|
@@ -1920,9 +2111,9 @@ function DataTable({
|
|
|
1920
2111
|
pageCount: pagination ? Math.ceil(pagination.total / pagination.pageSize) : void 0
|
|
1921
2112
|
});
|
|
1922
2113
|
const hasActions = !!rowActions;
|
|
1923
|
-
return /* @__PURE__ */ (0,
|
|
1924
|
-
/* @__PURE__ */ (0,
|
|
1925
|
-
/* @__PURE__ */ (0,
|
|
2114
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: cn("overflow-auto", className), children: [
|
|
2115
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("table", { className: "w-full border-collapse", children: [
|
|
2116
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
1926
2117
|
DataTableHeader,
|
|
1927
2118
|
{
|
|
1928
2119
|
headerGroups: table.getHeaderGroups(),
|
|
@@ -1931,14 +2122,14 @@ function DataTable({
|
|
|
1931
2122
|
flexRender: import_react_table.flexRender
|
|
1932
2123
|
}
|
|
1933
2124
|
),
|
|
1934
|
-
/* @__PURE__ */ (0,
|
|
2125
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("tbody", { children: loading ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(LoadingRows, { colSpan: columns.length + (hasActions ? 1 : 0), compact }) : table.getRowModel().rows.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
1935
2126
|
"td",
|
|
1936
2127
|
{
|
|
1937
2128
|
colSpan: columns.length + (hasActions ? 1 : 0),
|
|
1938
2129
|
className: "text-center py-8 text-xs text-foreground-muted",
|
|
1939
2130
|
children: emptyState ?? "No data"
|
|
1940
2131
|
}
|
|
1941
|
-
) }) : table.getRowModel().rows.map((row) => /* @__PURE__ */ (0,
|
|
2132
|
+
) }) : table.getRowModel().rows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
1942
2133
|
DataTableRow,
|
|
1943
2134
|
{
|
|
1944
2135
|
row,
|
|
@@ -1949,7 +2140,7 @@ function DataTable({
|
|
|
1949
2140
|
row.id
|
|
1950
2141
|
)) })
|
|
1951
2142
|
] }),
|
|
1952
|
-
pagination && /* @__PURE__ */ (0,
|
|
2143
|
+
pagination && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
1953
2144
|
DataTablePagination,
|
|
1954
2145
|
{
|
|
1955
2146
|
page: pagination.page,
|
|
@@ -1961,11 +2152,11 @@ function DataTable({
|
|
|
1961
2152
|
] });
|
|
1962
2153
|
}
|
|
1963
2154
|
function LoadingRows({ colSpan, compact }) {
|
|
1964
|
-
return /* @__PURE__ */ (0,
|
|
2155
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_jsx_runtime39.Fragment, { children: Array.from({ length: 5 }).map((_, rowIdx) => /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("tr", { className: compact ? "h-7" : "h-9", children: Array.from({ length: colSpan }).map((_2, colIdx) => /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("td", { className: "px-2 py-1.5", children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Skeleton, { className: "h-3 w-full" }) }, colIdx)) }, rowIdx)) });
|
|
1965
2156
|
}
|
|
1966
2157
|
|
|
1967
2158
|
// src/composites/device-card.tsx
|
|
1968
|
-
var
|
|
2159
|
+
var import_jsx_runtime40 = require("react/jsx-runtime");
|
|
1969
2160
|
var STATUS_COLORS = {
|
|
1970
2161
|
online: "bg-success",
|
|
1971
2162
|
offline: "bg-danger",
|
|
@@ -1984,7 +2175,7 @@ function DeviceCard({
|
|
|
1984
2175
|
className
|
|
1985
2176
|
}) {
|
|
1986
2177
|
const isOffline = status === "offline";
|
|
1987
|
-
return /* @__PURE__ */ (0,
|
|
2178
|
+
return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
|
|
1988
2179
|
"div",
|
|
1989
2180
|
{
|
|
1990
2181
|
onClick,
|
|
@@ -1996,18 +2187,18 @@ function DeviceCard({
|
|
|
1996
2187
|
className
|
|
1997
2188
|
),
|
|
1998
2189
|
children: [
|
|
1999
|
-
/* @__PURE__ */ (0,
|
|
2000
|
-
/* @__PURE__ */ (0,
|
|
2001
|
-
status && /* @__PURE__ */ (0,
|
|
2190
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "flex items-center justify-between mb-2", children: [
|
|
2191
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "text-sm font-medium truncate", children: title }),
|
|
2192
|
+
status && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: cn("h-2 w-2 rounded-full shrink-0", STATUS_COLORS[status]) })
|
|
2002
2193
|
] }),
|
|
2003
|
-
subtitle && /* @__PURE__ */ (0,
|
|
2004
|
-
badges && badges.length > 0 && /* @__PURE__ */ (0,
|
|
2194
|
+
subtitle && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "text-[11px] text-foreground-muted", children: subtitle }),
|
|
2195
|
+
badges && badges.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "flex flex-wrap gap-1 mt-2", children: badges.map((badge, i) => {
|
|
2005
2196
|
const cls = cn(
|
|
2006
2197
|
"rounded px-1.5 py-0.5 text-[10px] flex items-center gap-0.5",
|
|
2007
2198
|
selected ? "bg-primary/20" : "bg-surface-hover",
|
|
2008
2199
|
badge.onClick && "hover:opacity-80 transition-opacity cursor-pointer"
|
|
2009
2200
|
);
|
|
2010
|
-
return badge.onClick ? /* @__PURE__ */ (0,
|
|
2201
|
+
return badge.onClick ? /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
|
|
2011
2202
|
"button",
|
|
2012
2203
|
{
|
|
2013
2204
|
onClick: (e) => {
|
|
@@ -2021,12 +2212,12 @@ function DeviceCard({
|
|
|
2021
2212
|
]
|
|
2022
2213
|
},
|
|
2023
2214
|
i
|
|
2024
|
-
) : /* @__PURE__ */ (0,
|
|
2215
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("span", { className: cls, children: [
|
|
2025
2216
|
badge.icon,
|
|
2026
2217
|
badge.label
|
|
2027
2218
|
] }, i);
|
|
2028
2219
|
}) }),
|
|
2029
|
-
!isOffline && actions && actions.length > 0 && /* @__PURE__ */ (0,
|
|
2220
|
+
!isOffline && actions && actions.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "flex items-center gap-0.5 mt-2 -mb-1", children: actions.map((action, i) => /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
2030
2221
|
"button",
|
|
2031
2222
|
{
|
|
2032
2223
|
onClick: (e) => {
|
|
@@ -2040,21 +2231,21 @@ function DeviceCard({
|
|
|
2040
2231
|
},
|
|
2041
2232
|
i
|
|
2042
2233
|
)) }),
|
|
2043
|
-
isOffline && offlineAction && /* @__PURE__ */ (0,
|
|
2234
|
+
isOffline && offlineAction && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "mt-2", onClick: (e) => e.stopPropagation(), children: offlineAction })
|
|
2044
2235
|
]
|
|
2045
2236
|
}
|
|
2046
2237
|
);
|
|
2047
2238
|
}
|
|
2048
2239
|
|
|
2049
2240
|
// src/composites/device-grid.tsx
|
|
2050
|
-
var
|
|
2241
|
+
var import_jsx_runtime41 = require("react/jsx-runtime");
|
|
2051
2242
|
function DeviceGrid({
|
|
2052
2243
|
children,
|
|
2053
2244
|
minCardWidth = 220,
|
|
2054
2245
|
gap = 3,
|
|
2055
2246
|
className
|
|
2056
2247
|
}) {
|
|
2057
|
-
return /* @__PURE__ */ (0,
|
|
2248
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
2058
2249
|
"div",
|
|
2059
2250
|
{
|
|
2060
2251
|
className: cn(
|
|
@@ -2072,9 +2263,9 @@ function DeviceGrid({
|
|
|
2072
2263
|
}
|
|
2073
2264
|
|
|
2074
2265
|
// src/composites/pipeline-step.tsx
|
|
2075
|
-
var
|
|
2076
|
-
var
|
|
2077
|
-
var
|
|
2266
|
+
var import_react27 = require("react");
|
|
2267
|
+
var import_lucide_react13 = require("lucide-react");
|
|
2268
|
+
var import_jsx_runtime42 = require("react/jsx-runtime");
|
|
2078
2269
|
var ADDON_COLORS = {
|
|
2079
2270
|
"object-detection": "border-l-blue-500",
|
|
2080
2271
|
"motion-detection": "border-l-amber-500",
|
|
@@ -2150,7 +2341,7 @@ function PipelineStep({
|
|
|
2150
2341
|
onDelete,
|
|
2151
2342
|
readOnly = false
|
|
2152
2343
|
}) {
|
|
2153
|
-
const [expanded, setExpanded] = (0,
|
|
2344
|
+
const [expanded, setExpanded] = (0, import_react27.useState)(false);
|
|
2154
2345
|
const color = borderColor(step.addonId, step.slot);
|
|
2155
2346
|
const backends = backendsForRuntime(step.runtime, capabilities, schema);
|
|
2156
2347
|
const rtOptions = runtimeOptions(capabilities);
|
|
@@ -2173,7 +2364,7 @@ function PipelineStep({
|
|
|
2173
2364
|
if (e.target.closest(".step-config")) return;
|
|
2174
2365
|
setExpanded((v) => !v);
|
|
2175
2366
|
}
|
|
2176
|
-
return /* @__PURE__ */ (0,
|
|
2367
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className: "space-y-2", children: /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
|
|
2177
2368
|
"div",
|
|
2178
2369
|
{
|
|
2179
2370
|
className: cn(
|
|
@@ -2182,18 +2373,18 @@ function PipelineStep({
|
|
|
2182
2373
|
!step.enabled && "opacity-[0.45]"
|
|
2183
2374
|
),
|
|
2184
2375
|
children: [
|
|
2185
|
-
/* @__PURE__ */ (0,
|
|
2186
|
-
/* @__PURE__ */ (0,
|
|
2187
|
-
/* @__PURE__ */ (0,
|
|
2188
|
-
/* @__PURE__ */ (0,
|
|
2189
|
-
/* @__PURE__ */ (0,
|
|
2190
|
-
/* @__PURE__ */ (0,
|
|
2191
|
-
step.inputClasses.map((c) => /* @__PURE__ */ (0,
|
|
2192
|
-
step.inputClasses.length > 0 && step.outputClasses.length > 0 && /* @__PURE__ */ (0,
|
|
2193
|
-
step.outputClasses.map((c) => /* @__PURE__ */ (0,
|
|
2376
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "flex items-center gap-2.5 px-3 py-2.5 cursor-pointer select-none", onClick: handleClick, children: [
|
|
2377
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "text-foreground-subtle", children: expanded ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_lucide_react13.ChevronDown, { className: "h-4 w-4" }) : /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_lucide_react13.ChevronRight, { className: "h-4 w-4" }) }),
|
|
2378
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "flex-1 min-w-0", children: [
|
|
2379
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "text-[10px] uppercase tracking-wider font-medium text-foreground-subtle/60 block leading-none", children: step.slot }),
|
|
2380
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "text-sm font-semibold text-foreground truncate block leading-tight", children: step.addonName }),
|
|
2381
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "flex items-center gap-1 mt-0.5 flex-wrap", children: [
|
|
2382
|
+
step.inputClasses.map((c) => /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "text-[9px] uppercase font-semibold tracking-wide px-1.5 py-0.5 rounded bg-blue-500/12 text-blue-400", children: c }, c)),
|
|
2383
|
+
step.inputClasses.length > 0 && step.outputClasses.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "text-foreground-subtle/40 text-[10px]", children: "\u2192" }),
|
|
2384
|
+
step.outputClasses.map((c) => /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "text-[9px] uppercase font-semibold tracking-wide px-1.5 py-0.5 rounded bg-green-500/12 text-green-400", children: c }, c))
|
|
2194
2385
|
] })
|
|
2195
2386
|
] }),
|
|
2196
|
-
/* @__PURE__ */ (0,
|
|
2387
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
2197
2388
|
"button",
|
|
2198
2389
|
{
|
|
2199
2390
|
onClick: (e) => {
|
|
@@ -2204,16 +2395,16 @@ function PipelineStep({
|
|
|
2204
2395
|
"relative inline-flex h-6 w-11 shrink-0 items-center rounded-full transition-colors",
|
|
2205
2396
|
step.enabled ? "bg-success" : "bg-foreground-subtle/30"
|
|
2206
2397
|
),
|
|
2207
|
-
children: /* @__PURE__ */ (0,
|
|
2398
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: cn(
|
|
2208
2399
|
"inline-block h-4 w-4 rounded-full bg-white shadow transition-transform",
|
|
2209
2400
|
step.enabled ? "translate-x-6" : "translate-x-1"
|
|
2210
2401
|
) })
|
|
2211
2402
|
}
|
|
2212
2403
|
)
|
|
2213
2404
|
] }),
|
|
2214
|
-
expanded && /* @__PURE__ */ (0,
|
|
2215
|
-
/* @__PURE__ */ (0,
|
|
2216
|
-
/* @__PURE__ */ (0,
|
|
2405
|
+
expanded && /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "step-config border-t border-border bg-background px-4 py-4 space-y-3", children: [
|
|
2406
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "grid grid-cols-2 gap-3", children: [
|
|
2407
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
2217
2408
|
ConfigSelect,
|
|
2218
2409
|
{
|
|
2219
2410
|
label: "Agent",
|
|
@@ -2223,7 +2414,7 @@ function PipelineStep({
|
|
|
2223
2414
|
onChange: (v) => onChange({ ...step, agentId: v })
|
|
2224
2415
|
}
|
|
2225
2416
|
),
|
|
2226
|
-
/* @__PURE__ */ (0,
|
|
2417
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
2227
2418
|
ConfigSelect,
|
|
2228
2419
|
{
|
|
2229
2420
|
label: "Runtime",
|
|
@@ -2233,7 +2424,7 @@ function PipelineStep({
|
|
|
2233
2424
|
onChange: (v) => onChange({ ...step, runtime: v })
|
|
2234
2425
|
}
|
|
2235
2426
|
),
|
|
2236
|
-
/* @__PURE__ */ (0,
|
|
2427
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
2237
2428
|
ConfigSelect,
|
|
2238
2429
|
{
|
|
2239
2430
|
label: "Backend",
|
|
@@ -2243,7 +2434,7 @@ function PipelineStep({
|
|
|
2243
2434
|
onChange: (v) => onChange({ ...step, backend: v })
|
|
2244
2435
|
}
|
|
2245
2436
|
),
|
|
2246
|
-
/* @__PURE__ */ (0,
|
|
2437
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
2247
2438
|
ConfigSelect,
|
|
2248
2439
|
{
|
|
2249
2440
|
label: "Model",
|
|
@@ -2254,15 +2445,15 @@ function PipelineStep({
|
|
|
2254
2445
|
}
|
|
2255
2446
|
)
|
|
2256
2447
|
] }),
|
|
2257
|
-
/* @__PURE__ */ (0,
|
|
2258
|
-
/* @__PURE__ */ (0,
|
|
2259
|
-
/* @__PURE__ */ (0,
|
|
2260
|
-
/* @__PURE__ */ (0,
|
|
2448
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { children: [
|
|
2449
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "flex items-center justify-between mb-1", children: [
|
|
2450
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "text-[10px] font-medium text-foreground-subtle uppercase tracking-wide", children: "Confidence" }),
|
|
2451
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("span", { className: "text-xs font-medium text-foreground tabular-nums", children: [
|
|
2261
2452
|
(step.confidence * 100).toFixed(0),
|
|
2262
2453
|
"%"
|
|
2263
2454
|
] })
|
|
2264
2455
|
] }),
|
|
2265
|
-
/* @__PURE__ */ (0,
|
|
2456
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
2266
2457
|
"input",
|
|
2267
2458
|
{
|
|
2268
2459
|
type: "range",
|
|
@@ -2282,9 +2473,9 @@ function PipelineStep({
|
|
|
2282
2473
|
) });
|
|
2283
2474
|
}
|
|
2284
2475
|
function ConfigSelect({ label, value, options, disabled, onChange }) {
|
|
2285
|
-
return /* @__PURE__ */ (0,
|
|
2286
|
-
/* @__PURE__ */ (0,
|
|
2287
|
-
/* @__PURE__ */ (0,
|
|
2476
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { children: [
|
|
2477
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("label", { className: "block text-[10px] font-medium text-foreground-subtle uppercase tracking-wide mb-1.5", children: label }),
|
|
2478
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
|
|
2288
2479
|
"select",
|
|
2289
2480
|
{
|
|
2290
2481
|
value,
|
|
@@ -2292,8 +2483,8 @@ function ConfigSelect({ label, value, options, disabled, onChange }) {
|
|
|
2292
2483
|
disabled,
|
|
2293
2484
|
className: "w-full rounded-lg border border-border bg-surface px-3 py-2 text-xs text-foreground focus:outline-none focus:border-primary/50",
|
|
2294
2485
|
children: [
|
|
2295
|
-
options.length === 0 && /* @__PURE__ */ (0,
|
|
2296
|
-
options.map((o) => /* @__PURE__ */ (0,
|
|
2486
|
+
options.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("option", { value, children: value || "default" }),
|
|
2487
|
+
options.map((o) => /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("option", { value: o.value, disabled: o.disabled, children: o.label }, o.value))
|
|
2297
2488
|
]
|
|
2298
2489
|
}
|
|
2299
2490
|
)
|
|
@@ -2301,30 +2492,30 @@ function ConfigSelect({ label, value, options, disabled, onChange }) {
|
|
|
2301
2492
|
}
|
|
2302
2493
|
|
|
2303
2494
|
// src/composites/pipeline-runtime-selector.tsx
|
|
2304
|
-
var
|
|
2305
|
-
var
|
|
2495
|
+
var import_lucide_react14 = require("lucide-react");
|
|
2496
|
+
var import_jsx_runtime43 = require("react/jsx-runtime");
|
|
2306
2497
|
function PipelineRuntimeSelector({ options, value, onChange }) {
|
|
2307
|
-
return /* @__PURE__ */ (0,
|
|
2498
|
+
return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: "flex flex-wrap gap-2", children: options.map((opt) => {
|
|
2308
2499
|
const active = opt.id === value;
|
|
2309
|
-
return /* @__PURE__ */ (0,
|
|
2500
|
+
return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
|
|
2310
2501
|
"button",
|
|
2311
2502
|
{
|
|
2312
2503
|
onClick: () => opt.available && onChange(opt.id),
|
|
2313
2504
|
disabled: !opt.available,
|
|
2314
2505
|
className: `flex items-center gap-2 rounded-lg border px-3 py-2 text-xs font-medium transition-all ${active ? "border-primary/40 bg-primary/10 text-primary" : opt.available ? "border-border bg-surface text-foreground-subtle hover:bg-surface-hover hover:text-foreground" : "border-border/40 bg-surface/40 text-foreground-subtle/40 cursor-not-allowed"}`,
|
|
2315
2506
|
children: [
|
|
2316
|
-
/* @__PURE__ */ (0,
|
|
2507
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_lucide_react14.Cpu, { className: "h-3.5 w-3.5 shrink-0" }),
|
|
2317
2508
|
opt.label,
|
|
2318
|
-
opt.isBest && /* @__PURE__ */ (0,
|
|
2319
|
-
/* @__PURE__ */ (0,
|
|
2509
|
+
opt.isBest && /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("span", { className: "inline-flex items-center gap-0.5 rounded-full bg-amber-500/15 px-1.5 py-0.5 text-[10px] font-semibold text-amber-400", children: [
|
|
2510
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_lucide_react14.Star, { className: "h-2.5 w-2.5" }),
|
|
2320
2511
|
"Best"
|
|
2321
2512
|
] }),
|
|
2322
|
-
opt.platformScore != null && /* @__PURE__ */ (0,
|
|
2513
|
+
opt.platformScore != null && /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("span", { className: "text-[10px] text-foreground-subtle/60", children: [
|
|
2323
2514
|
"(",
|
|
2324
2515
|
opt.platformScore,
|
|
2325
2516
|
")"
|
|
2326
2517
|
] }),
|
|
2327
|
-
/* @__PURE__ */ (0,
|
|
2518
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
2328
2519
|
"span",
|
|
2329
2520
|
{
|
|
2330
2521
|
className: `h-1.5 w-1.5 rounded-full ${opt.available ? "bg-success" : "bg-danger"}`
|
|
@@ -2338,8 +2529,8 @@ function PipelineRuntimeSelector({ options, value, onChange }) {
|
|
|
2338
2529
|
}
|
|
2339
2530
|
|
|
2340
2531
|
// src/composites/pipeline-builder.tsx
|
|
2341
|
-
var
|
|
2342
|
-
var
|
|
2532
|
+
var import_react28 = require("react");
|
|
2533
|
+
var import_lucide_react15 = require("lucide-react");
|
|
2343
2534
|
|
|
2344
2535
|
// src/lib/validate-template.ts
|
|
2345
2536
|
function validateTemplate(steps, schema) {
|
|
@@ -2371,7 +2562,7 @@ function validateTemplate(steps, schema) {
|
|
|
2371
2562
|
}
|
|
2372
2563
|
|
|
2373
2564
|
// src/composites/pipeline-builder.tsx
|
|
2374
|
-
var
|
|
2565
|
+
var import_jsx_runtime44 = require("react/jsx-runtime");
|
|
2375
2566
|
function buildSchemaMap(schema) {
|
|
2376
2567
|
const map = /* @__PURE__ */ new Map();
|
|
2377
2568
|
for (const slot of schema.slots) {
|
|
@@ -2400,20 +2591,20 @@ function createDefaultStep(addon, fallbackRuntime, fallbackBackend) {
|
|
|
2400
2591
|
};
|
|
2401
2592
|
}
|
|
2402
2593
|
function PlaceholderStep({ addon, onClick }) {
|
|
2403
|
-
return /* @__PURE__ */ (0,
|
|
2594
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
2404
2595
|
"button",
|
|
2405
2596
|
{
|
|
2406
2597
|
type: "button",
|
|
2407
2598
|
onClick,
|
|
2408
2599
|
className: "w-full rounded-xl border-2 border-dashed border-border/60 px-4 py-3 text-left transition-all hover:border-primary/30 hover:bg-surface/60 group",
|
|
2409
|
-
children: /* @__PURE__ */ (0,
|
|
2410
|
-
/* @__PURE__ */ (0,
|
|
2411
|
-
/* @__PURE__ */ (0,
|
|
2412
|
-
/* @__PURE__ */ (0,
|
|
2413
|
-
/* @__PURE__ */ (0,
|
|
2414
|
-
addon.inputClasses.map((c) => /* @__PURE__ */ (0,
|
|
2415
|
-
addon.inputClasses.length > 0 && addon.outputClasses.length > 0 && /* @__PURE__ */ (0,
|
|
2416
|
-
addon.outputClasses.map((c) => /* @__PURE__ */ (0,
|
|
2600
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "flex items-center gap-3", children: [
|
|
2601
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_lucide_react15.PlusCircle, { className: "h-[18px] w-[18px] text-foreground-subtle/30 group-hover:text-primary/60 shrink-0" }),
|
|
2602
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "flex-1 min-w-0", children: [
|
|
2603
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "text-[13px] font-medium text-foreground-subtle/50 group-hover:text-foreground-subtle block truncate", children: addon.name }),
|
|
2604
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "flex items-center gap-1 mt-0.5 flex-wrap", children: [
|
|
2605
|
+
addon.inputClasses.map((c) => /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "text-[9px] uppercase font-semibold tracking-wide px-1.5 py-0.5 rounded bg-blue-500/8 text-blue-400/50", children: c }, c)),
|
|
2606
|
+
addon.inputClasses.length > 0 && addon.outputClasses.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "text-foreground-subtle/25 text-[10px]", children: "\u2192" }),
|
|
2607
|
+
addon.outputClasses.map((c) => /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "text-[9px] uppercase font-semibold tracking-wide px-1.5 py-0.5 rounded bg-green-500/8 text-green-400/50", children: c }, c))
|
|
2417
2608
|
] })
|
|
2418
2609
|
] })
|
|
2419
2610
|
] })
|
|
@@ -2434,9 +2625,9 @@ function PipelineBuilder({
|
|
|
2434
2625
|
readOnly = false,
|
|
2435
2626
|
excludeAddons = []
|
|
2436
2627
|
}) {
|
|
2437
|
-
const excluded = (0,
|
|
2438
|
-
const schemaMap = (0,
|
|
2439
|
-
const [warnings, setWarnings] = (0,
|
|
2628
|
+
const excluded = (0, import_react28.useMemo)(() => new Set(excludeAddons), [excludeAddons]);
|
|
2629
|
+
const schemaMap = (0, import_react28.useMemo)(() => buildSchemaMap(schema), [schema]);
|
|
2630
|
+
const [warnings, setWarnings] = (0, import_react28.useState)([]);
|
|
2440
2631
|
const bestPlatformScore = capabilities.platformScores?.find((s) => s.available);
|
|
2441
2632
|
const hasPython = capabilities.runtimes.python.available && capabilities.runtimes.python.backends.some((b) => b.available);
|
|
2442
2633
|
const defaultRuntime = bestPlatformScore?.runtime ?? (hasPython ? "python" : "node");
|
|
@@ -2525,8 +2716,8 @@ function PipelineBuilder({
|
|
|
2525
2716
|
}
|
|
2526
2717
|
function renderStep(step) {
|
|
2527
2718
|
const childPlaceholders = getChildPlaceholders(step);
|
|
2528
|
-
return /* @__PURE__ */ (0,
|
|
2529
|
-
/* @__PURE__ */ (0,
|
|
2719
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "space-y-1.5", children: [
|
|
2720
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
2530
2721
|
PipelineStep,
|
|
2531
2722
|
{
|
|
2532
2723
|
step,
|
|
@@ -2538,12 +2729,12 @@ function PipelineBuilder({
|
|
|
2538
2729
|
readOnly
|
|
2539
2730
|
}
|
|
2540
2731
|
),
|
|
2541
|
-
(step.children.length > 0 || childPlaceholders.length > 0) && /* @__PURE__ */ (0,
|
|
2542
|
-
/* @__PURE__ */ (0,
|
|
2732
|
+
(step.children.length > 0 || childPlaceholders.length > 0) && /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "ml-6 pl-4 border-l-2 border-dashed border-border/40 space-y-1.5", children: [
|
|
2733
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "text-[10px] font-semibold uppercase tracking-widest text-foreground-subtle/40", children: "Slot: Cropper / Classifier" }),
|
|
2543
2734
|
step.children.map((child) => {
|
|
2544
2735
|
const childChildPlaceholders = getChildPlaceholders(child);
|
|
2545
|
-
return /* @__PURE__ */ (0,
|
|
2546
|
-
/* @__PURE__ */ (0,
|
|
2736
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "space-y-1.5", children: [
|
|
2737
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
2547
2738
|
PipelineStep,
|
|
2548
2739
|
{
|
|
2549
2740
|
step: child,
|
|
@@ -2566,9 +2757,9 @@ function PipelineBuilder({
|
|
|
2566
2757
|
readOnly
|
|
2567
2758
|
}
|
|
2568
2759
|
),
|
|
2569
|
-
(child.children.length > 0 || childChildPlaceholders.length > 0) && /* @__PURE__ */ (0,
|
|
2570
|
-
/* @__PURE__ */ (0,
|
|
2571
|
-
child.children.map((grandchild) => /* @__PURE__ */ (0,
|
|
2760
|
+
(child.children.length > 0 || childChildPlaceholders.length > 0) && /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "ml-6 pl-4 border-l-2 border-dashed border-border/30 space-y-1.5", children: [
|
|
2761
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "text-[10px] font-semibold uppercase tracking-widest text-foreground-subtle/30", children: "Slot: Recognizer" }),
|
|
2762
|
+
child.children.map((grandchild) => /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
2572
2763
|
PipelineStep,
|
|
2573
2764
|
{
|
|
2574
2765
|
step: grandchild,
|
|
@@ -2596,7 +2787,7 @@ function PipelineBuilder({
|
|
|
2596
2787
|
},
|
|
2597
2788
|
grandchild.addonId
|
|
2598
2789
|
)),
|
|
2599
|
-
!readOnly && childChildPlaceholders.map((addon) => /* @__PURE__ */ (0,
|
|
2790
|
+
!readOnly && childChildPlaceholders.map((addon) => /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
2600
2791
|
PlaceholderStep,
|
|
2601
2792
|
{
|
|
2602
2793
|
addon,
|
|
@@ -2615,7 +2806,7 @@ function PipelineBuilder({
|
|
|
2615
2806
|
] })
|
|
2616
2807
|
] }, child.addonId);
|
|
2617
2808
|
}),
|
|
2618
|
-
!readOnly && childPlaceholders.map((addon) => /* @__PURE__ */ (0,
|
|
2809
|
+
!readOnly && childPlaceholders.map((addon) => /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
2619
2810
|
PlaceholderStep,
|
|
2620
2811
|
{
|
|
2621
2812
|
addon,
|
|
@@ -2627,22 +2818,22 @@ function PipelineBuilder({
|
|
|
2627
2818
|
] }, step.addonId);
|
|
2628
2819
|
}
|
|
2629
2820
|
const rootSlots = schema.slots.filter((s) => s.parentSlot === null).sort((a, b) => a.priority - b.priority);
|
|
2630
|
-
return /* @__PURE__ */ (0,
|
|
2631
|
-
/* @__PURE__ */ (0,
|
|
2632
|
-
/* @__PURE__ */ (0,
|
|
2821
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "space-y-4", children: [
|
|
2822
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className: "rounded-xl border border-border bg-surface p-3", children: /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
2823
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className: "relative flex-1 min-w-0", children: /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
|
|
2633
2824
|
"select",
|
|
2634
2825
|
{
|
|
2635
2826
|
value: selectedTemplateId ?? "",
|
|
2636
2827
|
onChange: handleSelectTemplate,
|
|
2637
2828
|
className: "w-full rounded-lg border border-border bg-background px-3 py-2 text-sm text-foreground focus:outline-none focus:border-primary/50",
|
|
2638
2829
|
children: [
|
|
2639
|
-
/* @__PURE__ */ (0,
|
|
2640
|
-
templates.map((t) => /* @__PURE__ */ (0,
|
|
2830
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("option", { value: "", children: "No template" }),
|
|
2831
|
+
templates.map((t) => /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("option", { value: t.id, children: t.name }, t.id))
|
|
2641
2832
|
]
|
|
2642
2833
|
}
|
|
2643
2834
|
) }),
|
|
2644
|
-
dirty && /* @__PURE__ */ (0,
|
|
2645
|
-
/* @__PURE__ */ (0,
|
|
2835
|
+
dirty && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "h-1.5 w-1.5 rounded-full bg-amber-500 shrink-0" }),
|
|
2836
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
2646
2837
|
"button",
|
|
2647
2838
|
{
|
|
2648
2839
|
onClick: handleSave,
|
|
@@ -2652,10 +2843,10 @@ function PipelineBuilder({
|
|
|
2652
2843
|
"p-2 rounded-lg border border-border transition-colors",
|
|
2653
2844
|
selectedTemplateId && !readOnly ? "text-foreground-subtle hover:bg-surface-hover" : "text-foreground-subtle/30 cursor-not-allowed"
|
|
2654
2845
|
),
|
|
2655
|
-
children: /* @__PURE__ */ (0,
|
|
2846
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_lucide_react15.Save, { className: "h-4 w-4" })
|
|
2656
2847
|
}
|
|
2657
2848
|
),
|
|
2658
|
-
/* @__PURE__ */ (0,
|
|
2849
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
2659
2850
|
"button",
|
|
2660
2851
|
{
|
|
2661
2852
|
onClick: handleSaveAs,
|
|
@@ -2665,10 +2856,10 @@ function PipelineBuilder({
|
|
|
2665
2856
|
"p-2 rounded-lg border border-border transition-colors",
|
|
2666
2857
|
!readOnly ? "text-foreground-subtle hover:bg-surface-hover" : "text-foreground-subtle/30 cursor-not-allowed"
|
|
2667
2858
|
),
|
|
2668
|
-
children: /* @__PURE__ */ (0,
|
|
2859
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_lucide_react15.CopyPlus, { className: "h-4 w-4" })
|
|
2669
2860
|
}
|
|
2670
2861
|
),
|
|
2671
|
-
/* @__PURE__ */ (0,
|
|
2862
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
2672
2863
|
"button",
|
|
2673
2864
|
{
|
|
2674
2865
|
onClick: handleDelete,
|
|
@@ -2678,16 +2869,16 @@ function PipelineBuilder({
|
|
|
2678
2869
|
"p-2 rounded-lg border border-border transition-colors",
|
|
2679
2870
|
selectedTemplateId && !readOnly ? "text-foreground-subtle hover:text-danger" : "text-foreground-subtle/30 cursor-not-allowed"
|
|
2680
2871
|
),
|
|
2681
|
-
children: /* @__PURE__ */ (0,
|
|
2872
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_lucide_react15.Trash2, { className: "h-4 w-4" })
|
|
2682
2873
|
}
|
|
2683
2874
|
)
|
|
2684
2875
|
] }) }),
|
|
2685
|
-
warnings.length > 0 && /* @__PURE__ */ (0,
|
|
2686
|
-
/* @__PURE__ */ (0,
|
|
2687
|
-
/* @__PURE__ */ (0,
|
|
2688
|
-
/* @__PURE__ */ (0,
|
|
2876
|
+
warnings.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "rounded-lg border border-amber-500/30 bg-amber-500/5 p-3 text-xs text-amber-400 space-y-1", children: [
|
|
2877
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
2878
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "font-medium", children: "Template loaded with warnings:" }),
|
|
2879
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("button", { onClick: () => setWarnings([]), className: "text-amber-400/60 hover:text-amber-400", children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_lucide_react15.X, { className: "h-3.5 w-3.5" }) })
|
|
2689
2880
|
] }),
|
|
2690
|
-
warnings.map((w, i) => /* @__PURE__ */ (0,
|
|
2881
|
+
warnings.map((w, i) => /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { children: [
|
|
2691
2882
|
"\u2022 ",
|
|
2692
2883
|
w
|
|
2693
2884
|
] }, i))
|
|
@@ -2695,13 +2886,13 @@ function PipelineBuilder({
|
|
|
2695
2886
|
rootSlots.map((slot) => {
|
|
2696
2887
|
const slotSteps = steps.filter((s) => s.slot === slot.id && !excluded.has(s.addonId));
|
|
2697
2888
|
const missingRootAddons = slot.addons.filter((a) => !existingIds.has(a.id) && !excluded.has(a.id));
|
|
2698
|
-
return /* @__PURE__ */ (0,
|
|
2699
|
-
/* @__PURE__ */ (0,
|
|
2889
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "space-y-2", children: [
|
|
2890
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("span", { className: "text-[10px] font-semibold uppercase tracking-widest text-foreground-subtle/50", children: [
|
|
2700
2891
|
"Slot: ",
|
|
2701
2892
|
slot.label
|
|
2702
2893
|
] }),
|
|
2703
2894
|
slotSteps.map((step) => renderStep(step)),
|
|
2704
|
-
!readOnly && missingRootAddons.map((addon) => /* @__PURE__ */ (0,
|
|
2895
|
+
!readOnly && missingRootAddons.map((addon) => /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(PlaceholderStep, { addon, onClick: () => {
|
|
2705
2896
|
onChange([...steps, createDefaultStep(addon, defaultRuntime, defaultBackend)]);
|
|
2706
2897
|
} }, addon.id))
|
|
2707
2898
|
] }, slot.id);
|
|
@@ -2781,8 +2972,8 @@ function getClassColor(className, customColors) {
|
|
|
2781
2972
|
}
|
|
2782
2973
|
|
|
2783
2974
|
// src/composites/detection-canvas.tsx
|
|
2784
|
-
var
|
|
2785
|
-
var
|
|
2975
|
+
var import_react29 = require("react");
|
|
2976
|
+
var import_jsx_runtime45 = require("react/jsx-runtime");
|
|
2786
2977
|
var DEFAULT_CLASS_COLORS = CLASS_COLORS;
|
|
2787
2978
|
function DetectionCanvas({
|
|
2788
2979
|
src,
|
|
@@ -2802,7 +2993,7 @@ function DetectionCanvas({
|
|
|
2802
2993
|
}
|
|
2803
2994
|
const ratio = aspectRatio ?? (imageWidth && imageHeight ? `${imageWidth}/${imageHeight}` : "16/9");
|
|
2804
2995
|
const filteredDetections = detections.filter((d) => d.confidence >= minConfidence);
|
|
2805
|
-
return /* @__PURE__ */ (0,
|
|
2996
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
2806
2997
|
"div",
|
|
2807
2998
|
{
|
|
2808
2999
|
className: cn(
|
|
@@ -2810,10 +3001,10 @@ function DetectionCanvas({
|
|
|
2810
3001
|
className
|
|
2811
3002
|
),
|
|
2812
3003
|
style: { aspectRatio: ratio },
|
|
2813
|
-
children: src ? /* @__PURE__ */ (0,
|
|
2814
|
-
/* @__PURE__ */ (0,
|
|
3004
|
+
children: src ? /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(import_jsx_runtime45.Fragment, { children: [
|
|
3005
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("img", { src, className: "absolute inset-0 w-full h-full object-fill", alt: "" }),
|
|
2815
3006
|
filteredDetections.map(
|
|
2816
|
-
(d, i) => d.mask && d.maskWidth && d.maskHeight ? /* @__PURE__ */ (0,
|
|
3007
|
+
(d, i) => d.mask && d.maskWidth && d.maskHeight ? /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
2817
3008
|
MaskOverlay,
|
|
2818
3009
|
{
|
|
2819
3010
|
mask: d.mask,
|
|
@@ -2827,7 +3018,7 @@ function DetectionCanvas({
|
|
|
2827
3018
|
`mask-${i}`
|
|
2828
3019
|
) : null
|
|
2829
3020
|
),
|
|
2830
|
-
filteredDetections.map((d, i) => /* @__PURE__ */ (0,
|
|
3021
|
+
filteredDetections.map((d, i) => /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
2831
3022
|
BoundingBox,
|
|
2832
3023
|
{
|
|
2833
3024
|
detection: d,
|
|
@@ -2847,7 +3038,7 @@ function DetectionCanvas({
|
|
|
2847
3038
|
const ph = py2 - py1;
|
|
2848
3039
|
if (pw > 0 && ph > 0 && cw * ch / (pw * ph) > 0.8) return false;
|
|
2849
3040
|
return true;
|
|
2850
|
-
}).map((child, j) => /* @__PURE__ */ (0,
|
|
3041
|
+
}).map((child, j) => /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
2851
3042
|
ChildBoundingBox,
|
|
2852
3043
|
{
|
|
2853
3044
|
child,
|
|
@@ -2860,7 +3051,7 @@ function DetectionCanvas({
|
|
|
2860
3051
|
},
|
|
2861
3052
|
`det-${i}`
|
|
2862
3053
|
))
|
|
2863
|
-
] }) : /* @__PURE__ */ (0,
|
|
3054
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "w-full h-full flex items-center justify-center text-foreground-subtle text-sm", children: placeholder ?? "No image loaded" })
|
|
2864
3055
|
}
|
|
2865
3056
|
);
|
|
2866
3057
|
}
|
|
@@ -2877,15 +3068,15 @@ function BoundingBox({
|
|
|
2877
3068
|
const labelCount = 1 + (detection.labelsData?.length ?? 0);
|
|
2878
3069
|
const labelHeightPx = labelCount * 16 + 4;
|
|
2879
3070
|
const topPct = y1 / imageHeight * 100;
|
|
2880
|
-
const containerRef = (0,
|
|
3071
|
+
const containerRef = (0, import_react29.useRef)(null);
|
|
2881
3072
|
const showBelow = topPct < labelHeightPx / imageHeight * 100 * 1.5;
|
|
2882
|
-
const labelsElement = /* @__PURE__ */ (0,
|
|
3073
|
+
const labelsElement = /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(
|
|
2883
3074
|
"div",
|
|
2884
3075
|
{
|
|
2885
3076
|
className: `absolute left-0 flex flex-col items-start gap-px ${showBelow ? "" : ""}`,
|
|
2886
3077
|
style: showBelow ? { top: "100%", marginTop: "2px" } : { bottom: "100%", marginBottom: "2px" },
|
|
2887
3078
|
children: [
|
|
2888
|
-
/* @__PURE__ */ (0,
|
|
3079
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(
|
|
2889
3080
|
"span",
|
|
2890
3081
|
{
|
|
2891
3082
|
className: "text-[10px] px-1 rounded-sm whitespace-nowrap text-white",
|
|
@@ -2896,7 +3087,7 @@ function BoundingBox({
|
|
|
2896
3087
|
]
|
|
2897
3088
|
}
|
|
2898
3089
|
),
|
|
2899
|
-
detection.labelsData?.map((l, k) => /* @__PURE__ */ (0,
|
|
3090
|
+
detection.labelsData?.map((l, k) => /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(
|
|
2900
3091
|
"span",
|
|
2901
3092
|
{
|
|
2902
3093
|
className: "text-[9px] font-semibold px-1 rounded-sm whitespace-nowrap text-white",
|
|
@@ -2913,7 +3104,7 @@ function BoundingBox({
|
|
|
2913
3104
|
]
|
|
2914
3105
|
}
|
|
2915
3106
|
);
|
|
2916
|
-
return /* @__PURE__ */ (0,
|
|
3107
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(
|
|
2917
3108
|
"div",
|
|
2918
3109
|
{
|
|
2919
3110
|
ref: containerRef,
|
|
@@ -2943,8 +3134,8 @@ function MaskOverlay({
|
|
|
2943
3134
|
imageHeight,
|
|
2944
3135
|
color
|
|
2945
3136
|
}) {
|
|
2946
|
-
const canvasRef = (0,
|
|
2947
|
-
(0,
|
|
3137
|
+
const canvasRef = (0, import_react29.useRef)(null);
|
|
3138
|
+
(0, import_react29.useEffect)(() => {
|
|
2948
3139
|
const canvas = canvasRef.current;
|
|
2949
3140
|
if (!canvas) return;
|
|
2950
3141
|
const ctx = canvas.getContext("2d");
|
|
@@ -2972,7 +3163,7 @@ function MaskOverlay({
|
|
|
2972
3163
|
ctx.putImageData(imageData, 0, 0);
|
|
2973
3164
|
}, [mask, maskWidth, maskHeight, color]);
|
|
2974
3165
|
const [x1, y1, x2, y2] = bbox;
|
|
2975
|
-
return /* @__PURE__ */ (0,
|
|
3166
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
2976
3167
|
"canvas",
|
|
2977
3168
|
{
|
|
2978
3169
|
ref: canvasRef,
|
|
@@ -2998,7 +3189,7 @@ function ChildBoundingBox({
|
|
|
2998
3189
|
const pw = px2 - px1;
|
|
2999
3190
|
const ph = py2 - py1;
|
|
3000
3191
|
if (pw <= 0 || ph <= 0) return null;
|
|
3001
|
-
return /* @__PURE__ */ (0,
|
|
3192
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
3002
3193
|
"div",
|
|
3003
3194
|
{
|
|
3004
3195
|
className: "absolute rounded-sm",
|
|
@@ -3015,13 +3206,13 @@ function ChildBoundingBox({
|
|
|
3015
3206
|
const labelCount = 1 + (child.labelsData?.length ?? 0);
|
|
3016
3207
|
const relTop = (cy1 - py1) / ph * 100;
|
|
3017
3208
|
const showBelow = relTop < labelCount * 6;
|
|
3018
|
-
return /* @__PURE__ */ (0,
|
|
3209
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(
|
|
3019
3210
|
"div",
|
|
3020
3211
|
{
|
|
3021
3212
|
className: "absolute left-0 flex flex-col items-start gap-px",
|
|
3022
3213
|
style: showBelow ? { top: "100%", marginTop: "1px" } : { bottom: "100%", marginBottom: "1px" },
|
|
3023
3214
|
children: [
|
|
3024
|
-
/* @__PURE__ */ (0,
|
|
3215
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(
|
|
3025
3216
|
"span",
|
|
3026
3217
|
{
|
|
3027
3218
|
className: "text-[9px] px-0.5 rounded-sm whitespace-nowrap text-white",
|
|
@@ -3032,7 +3223,7 @@ function ChildBoundingBox({
|
|
|
3032
3223
|
]
|
|
3033
3224
|
}
|
|
3034
3225
|
),
|
|
3035
|
-
child.labelsData?.map((l, k) => /* @__PURE__ */ (0,
|
|
3226
|
+
child.labelsData?.map((l, k) => /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(
|
|
3036
3227
|
"span",
|
|
3037
3228
|
{
|
|
3038
3229
|
className: "text-[8px] font-semibold px-0.5 rounded-sm whitespace-nowrap text-white",
|
|
@@ -3055,7 +3246,7 @@ function ChildBoundingBox({
|
|
|
3055
3246
|
}
|
|
3056
3247
|
|
|
3057
3248
|
// src/composites/detection-result-tree.tsx
|
|
3058
|
-
var
|
|
3249
|
+
var import_jsx_runtime46 = require("react/jsx-runtime");
|
|
3059
3250
|
function DetectionResultTree({
|
|
3060
3251
|
detections,
|
|
3061
3252
|
classColors,
|
|
@@ -3065,15 +3256,15 @@ function DetectionResultTree({
|
|
|
3065
3256
|
}) {
|
|
3066
3257
|
const colors = classColors;
|
|
3067
3258
|
if (detections.length === 0) {
|
|
3068
|
-
return /* @__PURE__ */ (0,
|
|
3259
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: "text-sm text-foreground-subtle italic text-center py-4", children: "No detections" });
|
|
3069
3260
|
}
|
|
3070
|
-
return /* @__PURE__ */ (0,
|
|
3071
|
-
/* @__PURE__ */ (0,
|
|
3261
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className, children: [
|
|
3262
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "text-xs font-medium text-foreground-subtle uppercase tracking-wide mb-2", children: [
|
|
3072
3263
|
"Detections (",
|
|
3073
3264
|
detections.length,
|
|
3074
3265
|
")"
|
|
3075
3266
|
] }),
|
|
3076
|
-
/* @__PURE__ */ (0,
|
|
3267
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: "space-y-2", children: detections.map((d, i) => /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
3077
3268
|
DetectionNode,
|
|
3078
3269
|
{
|
|
3079
3270
|
detection: d,
|
|
@@ -3095,10 +3286,10 @@ function DetectionNode({
|
|
|
3095
3286
|
}) {
|
|
3096
3287
|
const color = getClassColor(detection.className, colors);
|
|
3097
3288
|
const isVisible = !hiddenKeys?.has(path);
|
|
3098
|
-
return /* @__PURE__ */ (0,
|
|
3099
|
-
/* @__PURE__ */ (0,
|
|
3100
|
-
/* @__PURE__ */ (0,
|
|
3101
|
-
onToggleVisibility && /* @__PURE__ */ (0,
|
|
3289
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: `rounded-md border border-border bg-surface p-3 space-y-1 ${isVisible ? "" : "opacity-40"}`, children: [
|
|
3290
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex justify-between items-center", children: [
|
|
3291
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
3292
|
+
onToggleVisibility && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
3102
3293
|
"input",
|
|
3103
3294
|
{
|
|
3104
3295
|
type: "checkbox",
|
|
@@ -3107,45 +3298,45 @@ function DetectionNode({
|
|
|
3107
3298
|
className: "h-3.5 w-3.5 rounded border-border accent-primary cursor-pointer shrink-0"
|
|
3108
3299
|
}
|
|
3109
3300
|
),
|
|
3110
|
-
/* @__PURE__ */ (0,
|
|
3301
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
3111
3302
|
"span",
|
|
3112
3303
|
{
|
|
3113
3304
|
className: "h-2.5 w-2.5 rounded-full shrink-0",
|
|
3114
3305
|
style: { backgroundColor: color }
|
|
3115
3306
|
}
|
|
3116
3307
|
),
|
|
3117
|
-
/* @__PURE__ */ (0,
|
|
3118
|
-
detection.mask && detection.maskWidth && detection.maskHeight && /* @__PURE__ */ (0,
|
|
3308
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "text-sm font-medium text-foreground", children: detection.className }),
|
|
3309
|
+
detection.mask && detection.maskWidth && detection.maskHeight && /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("span", { className: "text-[9px] font-mono px-1 py-0.5 rounded bg-primary/10 text-primary", children: [
|
|
3119
3310
|
"mask ",
|
|
3120
3311
|
detection.maskWidth,
|
|
3121
3312
|
"x",
|
|
3122
3313
|
detection.maskHeight
|
|
3123
3314
|
] })
|
|
3124
3315
|
] }),
|
|
3125
|
-
/* @__PURE__ */ (0,
|
|
3316
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(ConfidenceBadge, { confidence: detection.confidence })
|
|
3126
3317
|
] }),
|
|
3127
|
-
/* @__PURE__ */ (0,
|
|
3318
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "text-[10px] text-foreground-subtle font-mono", children: [
|
|
3128
3319
|
"bbox: [",
|
|
3129
3320
|
detection.bbox.map((v) => Math.round(v)).join(", "),
|
|
3130
3321
|
"]"
|
|
3131
3322
|
] }),
|
|
3132
|
-
detection.labelsData && detection.labelsData.length > 0 && /* @__PURE__ */ (0,
|
|
3323
|
+
detection.labelsData && detection.labelsData.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: "flex flex-wrap gap-1 mt-1", children: detection.labelsData.map((l, k) => /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
|
|
3133
3324
|
"span",
|
|
3134
3325
|
{
|
|
3135
3326
|
className: "inline-flex items-center gap-1 text-[10px] font-medium px-1.5 py-0.5 rounded-full",
|
|
3136
3327
|
style: { backgroundColor: getClassColor(l.addonId ?? l.label, colors) + "20", color: getClassColor(l.addonId ?? l.label, colors) },
|
|
3137
3328
|
children: [
|
|
3138
3329
|
l.label,
|
|
3139
|
-
/* @__PURE__ */ (0,
|
|
3330
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("span", { className: "opacity-60", children: [
|
|
3140
3331
|
(l.score * 100).toFixed(0),
|
|
3141
3332
|
"%"
|
|
3142
3333
|
] }),
|
|
3143
|
-
l.addonId && /* @__PURE__ */ (0,
|
|
3334
|
+
l.addonId && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "opacity-40 text-[8px]", children: l.addonId })
|
|
3144
3335
|
]
|
|
3145
3336
|
},
|
|
3146
3337
|
k
|
|
3147
3338
|
)) }),
|
|
3148
|
-
detection.children && detection.children.length > 0 && /* @__PURE__ */ (0,
|
|
3339
|
+
detection.children && detection.children.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
3149
3340
|
ChildrenTree,
|
|
3150
3341
|
{
|
|
3151
3342
|
children: detection.children,
|
|
@@ -3164,13 +3355,13 @@ function ChildrenTree({
|
|
|
3164
3355
|
hiddenKeys,
|
|
3165
3356
|
onToggleVisibility
|
|
3166
3357
|
}) {
|
|
3167
|
-
return /* @__PURE__ */ (0,
|
|
3358
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: "ml-4 mt-1.5 space-y-1.5 border-l-2 border-border pl-3", children: children.map((child, j) => {
|
|
3168
3359
|
const childPath = `${parentPath}.${j}`;
|
|
3169
3360
|
const childColor = getClassColor(child.className, colors);
|
|
3170
3361
|
const isVisible = !hiddenKeys?.has(childPath);
|
|
3171
|
-
return /* @__PURE__ */ (0,
|
|
3172
|
-
/* @__PURE__ */ (0,
|
|
3173
|
-
onToggleVisibility && /* @__PURE__ */ (0,
|
|
3362
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: `text-xs space-y-0.5 ${isVisible ? "" : "opacity-40"}`, children: [
|
|
3363
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex items-center gap-1.5", children: [
|
|
3364
|
+
onToggleVisibility && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
3174
3365
|
"input",
|
|
3175
3366
|
{
|
|
3176
3367
|
type: "checkbox",
|
|
@@ -3179,26 +3370,26 @@ function ChildrenTree({
|
|
|
3179
3370
|
className: "h-3 w-3 rounded border-border accent-primary cursor-pointer shrink-0"
|
|
3180
3371
|
}
|
|
3181
3372
|
),
|
|
3182
|
-
/* @__PURE__ */ (0,
|
|
3373
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
3183
3374
|
"span",
|
|
3184
3375
|
{
|
|
3185
3376
|
className: "h-1.5 w-1.5 rounded-full shrink-0",
|
|
3186
3377
|
style: { backgroundColor: childColor }
|
|
3187
3378
|
}
|
|
3188
3379
|
),
|
|
3189
|
-
/* @__PURE__ */ (0,
|
|
3190
|
-
/* @__PURE__ */ (0,
|
|
3380
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "font-medium", style: { color: childColor }, children: child.className }),
|
|
3381
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("span", { className: "text-foreground-subtle", children: [
|
|
3191
3382
|
(child.confidence * 100).toFixed(0),
|
|
3192
3383
|
"%"
|
|
3193
3384
|
] }),
|
|
3194
|
-
child.mask && child.maskWidth && child.maskHeight && /* @__PURE__ */ (0,
|
|
3385
|
+
child.mask && child.maskWidth && child.maskHeight && /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("span", { className: "text-[9px] font-mono px-1 py-0.5 rounded bg-primary/10 text-primary", children: [
|
|
3195
3386
|
"mask ",
|
|
3196
3387
|
child.maskWidth,
|
|
3197
3388
|
"x",
|
|
3198
3389
|
child.maskHeight
|
|
3199
3390
|
] })
|
|
3200
3391
|
] }),
|
|
3201
|
-
child.labelsData && child.labelsData.length > 0 && /* @__PURE__ */ (0,
|
|
3392
|
+
child.labelsData && child.labelsData.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: "flex flex-wrap gap-1 ml-5 mt-0.5", children: child.labelsData.map((l, k) => /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
|
|
3202
3393
|
"span",
|
|
3203
3394
|
{
|
|
3204
3395
|
className: "inline-flex items-center gap-0.5 text-[9px] font-medium px-1 py-0.5 rounded-full",
|
|
@@ -3206,7 +3397,7 @@ function ChildrenTree({
|
|
|
3206
3397
|
children: [
|
|
3207
3398
|
l.label,
|
|
3208
3399
|
" ",
|
|
3209
|
-
/* @__PURE__ */ (0,
|
|
3400
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("span", { className: "opacity-60", children: [
|
|
3210
3401
|
(l.score * 100).toFixed(0),
|
|
3211
3402
|
"%"
|
|
3212
3403
|
] })
|
|
@@ -3214,7 +3405,7 @@ function ChildrenTree({
|
|
|
3214
3405
|
},
|
|
3215
3406
|
k
|
|
3216
3407
|
)) }),
|
|
3217
|
-
child.children && child.children.length > 0 && /* @__PURE__ */ (0,
|
|
3408
|
+
child.children && child.children.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
3218
3409
|
ChildrenTree,
|
|
3219
3410
|
{
|
|
3220
3411
|
children: child.children,
|
|
@@ -3229,30 +3420,30 @@ function ChildrenTree({
|
|
|
3229
3420
|
}
|
|
3230
3421
|
function ConfidenceBadge({ confidence }) {
|
|
3231
3422
|
const level = confidence >= 0.8 ? "bg-success/10 text-success" : confidence >= 0.5 ? "bg-warning/10 text-warning" : "bg-danger/10 text-danger";
|
|
3232
|
-
return /* @__PURE__ */ (0,
|
|
3423
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("span", { className: `text-xs font-medium px-2 py-0.5 rounded-full ${level}`, children: [
|
|
3233
3424
|
(confidence * 100).toFixed(1),
|
|
3234
3425
|
"%"
|
|
3235
3426
|
] });
|
|
3236
3427
|
}
|
|
3237
3428
|
|
|
3238
3429
|
// src/composites/step-timings.tsx
|
|
3239
|
-
var
|
|
3430
|
+
var import_jsx_runtime47 = require("react/jsx-runtime");
|
|
3240
3431
|
function StepTimings({ timings, totalMs, className }) {
|
|
3241
3432
|
const entries = Object.entries(timings);
|
|
3242
3433
|
if (entries.length === 0 && totalMs === void 0) return null;
|
|
3243
|
-
return /* @__PURE__ */ (0,
|
|
3244
|
-
/* @__PURE__ */ (0,
|
|
3245
|
-
/* @__PURE__ */ (0,
|
|
3246
|
-
entries.map(([step, ms]) => /* @__PURE__ */ (0,
|
|
3247
|
-
/* @__PURE__ */ (0,
|
|
3248
|
-
/* @__PURE__ */ (0,
|
|
3434
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: `rounded-lg border border-border bg-surface p-3 space-y-2 ${className ?? ""}`, children: [
|
|
3435
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "text-xs font-medium text-foreground-subtle uppercase tracking-wide", children: "Timings" }),
|
|
3436
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "space-y-1 text-xs", children: [
|
|
3437
|
+
entries.map(([step, ms]) => /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex justify-between", children: [
|
|
3438
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "text-foreground-subtle", children: step }),
|
|
3439
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("span", { className: "font-mono text-foreground", children: [
|
|
3249
3440
|
ms.toFixed(1),
|
|
3250
3441
|
"ms"
|
|
3251
3442
|
] })
|
|
3252
3443
|
] }, step)),
|
|
3253
|
-
totalMs !== void 0 && /* @__PURE__ */ (0,
|
|
3254
|
-
/* @__PURE__ */ (0,
|
|
3255
|
-
/* @__PURE__ */ (0,
|
|
3444
|
+
totalMs !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex justify-between pt-1 border-t border-border font-medium text-foreground", children: [
|
|
3445
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { children: "Total" }),
|
|
3446
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("span", { className: "font-mono", children: [
|
|
3256
3447
|
totalMs.toFixed(1),
|
|
3257
3448
|
"ms"
|
|
3258
3449
|
] })
|
|
@@ -3262,7 +3453,7 @@ function StepTimings({ timings, totalMs, className }) {
|
|
|
3262
3453
|
}
|
|
3263
3454
|
|
|
3264
3455
|
// src/composites/image-selector.tsx
|
|
3265
|
-
var
|
|
3456
|
+
var import_jsx_runtime48 = require("react/jsx-runtime");
|
|
3266
3457
|
function ImageSelector({
|
|
3267
3458
|
images,
|
|
3268
3459
|
selectedFilename,
|
|
@@ -3288,8 +3479,8 @@ function ImageSelector({
|
|
|
3288
3479
|
};
|
|
3289
3480
|
input.click();
|
|
3290
3481
|
};
|
|
3291
|
-
return /* @__PURE__ */ (0,
|
|
3292
|
-
images.map((img) => /* @__PURE__ */ (0,
|
|
3482
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: `flex flex-wrap items-center gap-2 ${className ?? ""}`, children: [
|
|
3483
|
+
images.map((img) => /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
3293
3484
|
"button",
|
|
3294
3485
|
{
|
|
3295
3486
|
onClick: () => onSelect(img.filename),
|
|
@@ -3298,7 +3489,7 @@ function ImageSelector({
|
|
|
3298
3489
|
},
|
|
3299
3490
|
img.filename
|
|
3300
3491
|
)),
|
|
3301
|
-
/* @__PURE__ */ (0,
|
|
3492
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
3302
3493
|
"button",
|
|
3303
3494
|
{
|
|
3304
3495
|
onClick: handleUploadClick,
|
|
@@ -3306,12 +3497,12 @@ function ImageSelector({
|
|
|
3306
3497
|
children: "Upload..."
|
|
3307
3498
|
}
|
|
3308
3499
|
),
|
|
3309
|
-
uploadedName && /* @__PURE__ */ (0,
|
|
3500
|
+
uploadedName && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "text-xs text-foreground-subtle", children: uploadedName })
|
|
3310
3501
|
] });
|
|
3311
3502
|
}
|
|
3312
3503
|
|
|
3313
3504
|
// src/composites/inference-config-selector.tsx
|
|
3314
|
-
var
|
|
3505
|
+
var import_jsx_runtime49 = require("react/jsx-runtime");
|
|
3315
3506
|
var SELECT_CLASS = "w-full px-3 py-2 text-sm rounded-md border border-border bg-surface text-foreground focus:outline-none focus:ring-2 focus:ring-primary/50";
|
|
3316
3507
|
function InferenceConfigSelector({
|
|
3317
3508
|
runtime,
|
|
@@ -3331,16 +3522,16 @@ function InferenceConfigSelector({
|
|
|
3331
3522
|
showAgent = false
|
|
3332
3523
|
}) {
|
|
3333
3524
|
const containerClass = layout === "grid" ? "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4" : layout === "horizontal" ? "flex flex-wrap items-end gap-4" : "space-y-3";
|
|
3334
|
-
return /* @__PURE__ */ (0,
|
|
3335
|
-
showAgent && agents.length > 0 && /* @__PURE__ */ (0,
|
|
3336
|
-
/* @__PURE__ */ (0,
|
|
3337
|
-
/* @__PURE__ */ (0,
|
|
3525
|
+
return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: `${containerClass} ${className ?? ""}`, children: [
|
|
3526
|
+
showAgent && agents.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("label", { className: "space-y-1", children: [
|
|
3527
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "text-xs font-medium text-foreground-subtle", children: "Agent" }),
|
|
3528
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
3338
3529
|
"select",
|
|
3339
3530
|
{
|
|
3340
3531
|
value: agentId,
|
|
3341
3532
|
onChange: (e) => onAgentChange?.(e.target.value),
|
|
3342
3533
|
className: SELECT_CLASS,
|
|
3343
|
-
children: agents.map((a) => /* @__PURE__ */ (0,
|
|
3534
|
+
children: agents.map((a) => /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("option", { value: a.id, children: [
|
|
3344
3535
|
a.name,
|
|
3345
3536
|
" (",
|
|
3346
3537
|
a.status,
|
|
@@ -3349,45 +3540,45 @@ function InferenceConfigSelector({
|
|
|
3349
3540
|
}
|
|
3350
3541
|
)
|
|
3351
3542
|
] }),
|
|
3352
|
-
/* @__PURE__ */ (0,
|
|
3353
|
-
/* @__PURE__ */ (0,
|
|
3354
|
-
/* @__PURE__ */ (0,
|
|
3543
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("label", { className: "space-y-1", children: [
|
|
3544
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "text-xs font-medium text-foreground-subtle", children: "Runtime" }),
|
|
3545
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
3355
3546
|
"select",
|
|
3356
3547
|
{
|
|
3357
3548
|
value: runtime,
|
|
3358
3549
|
onChange: (e) => onRuntimeChange(e.target.value),
|
|
3359
3550
|
className: SELECT_CLASS,
|
|
3360
|
-
children: runtimes.map((r) => /* @__PURE__ */ (0,
|
|
3551
|
+
children: runtimes.map((r) => /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("option", { value: r.value, disabled: !r.available, children: [
|
|
3361
3552
|
r.label,
|
|
3362
3553
|
!r.available ? " (unavailable)" : ""
|
|
3363
3554
|
] }, r.value))
|
|
3364
3555
|
}
|
|
3365
3556
|
)
|
|
3366
3557
|
] }),
|
|
3367
|
-
/* @__PURE__ */ (0,
|
|
3368
|
-
/* @__PURE__ */ (0,
|
|
3369
|
-
/* @__PURE__ */ (0,
|
|
3558
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("label", { className: "space-y-1", children: [
|
|
3559
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "text-xs font-medium text-foreground-subtle", children: "Backend" }),
|
|
3560
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
3370
3561
|
"select",
|
|
3371
3562
|
{
|
|
3372
3563
|
value: backend,
|
|
3373
3564
|
onChange: (e) => onBackendChange(e.target.value),
|
|
3374
3565
|
className: SELECT_CLASS,
|
|
3375
|
-
children: backends.map((b) => /* @__PURE__ */ (0,
|
|
3566
|
+
children: backends.map((b) => /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("option", { value: b.id, disabled: !b.available, children: [
|
|
3376
3567
|
b.label,
|
|
3377
3568
|
!b.available ? " (unavailable)" : ""
|
|
3378
3569
|
] }, b.id))
|
|
3379
3570
|
}
|
|
3380
3571
|
)
|
|
3381
3572
|
] }),
|
|
3382
|
-
/* @__PURE__ */ (0,
|
|
3383
|
-
/* @__PURE__ */ (0,
|
|
3384
|
-
/* @__PURE__ */ (0,
|
|
3573
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("label", { className: "space-y-1", children: [
|
|
3574
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "text-xs font-medium text-foreground-subtle", children: "Model" }),
|
|
3575
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
3385
3576
|
"select",
|
|
3386
3577
|
{
|
|
3387
3578
|
value: modelId,
|
|
3388
3579
|
onChange: (e) => onModelChange(e.target.value),
|
|
3389
3580
|
className: SELECT_CLASS,
|
|
3390
|
-
children: models.length === 0 ? /* @__PURE__ */ (0,
|
|
3581
|
+
children: models.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("option", { value: "", children: "No compatible models" }) : models.map((m) => /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("option", { value: m.id, children: [
|
|
3391
3582
|
m.name,
|
|
3392
3583
|
m.downloaded ? " \u2713" : ""
|
|
3393
3584
|
] }, m.id))
|
|
@@ -3398,19 +3589,19 @@ function InferenceConfigSelector({
|
|
|
3398
3589
|
}
|
|
3399
3590
|
|
|
3400
3591
|
// src/composites/mount-addon-page.tsx
|
|
3401
|
-
var
|
|
3592
|
+
var import_react32 = require("react");
|
|
3402
3593
|
var import_client2 = require("react-dom/client");
|
|
3403
3594
|
|
|
3404
3595
|
// src/composites/dev-shell.tsx
|
|
3405
|
-
var
|
|
3596
|
+
var import_react31 = require("react");
|
|
3406
3597
|
var import_client = require("@trpc/client");
|
|
3407
3598
|
var import_superjson = __toESM(require("superjson"), 1);
|
|
3408
3599
|
|
|
3409
3600
|
// src/composites/login-form.tsx
|
|
3410
|
-
var
|
|
3411
|
-
var
|
|
3601
|
+
var import_react30 = require("react");
|
|
3602
|
+
var import_jsx_runtime50 = require("react/jsx-runtime");
|
|
3412
3603
|
function EyeIcon({ className }) {
|
|
3413
|
-
return /* @__PURE__ */ (0,
|
|
3604
|
+
return /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(
|
|
3414
3605
|
"svg",
|
|
3415
3606
|
{
|
|
3416
3607
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -3422,14 +3613,14 @@ function EyeIcon({ className }) {
|
|
|
3422
3613
|
strokeLinejoin: "round",
|
|
3423
3614
|
className,
|
|
3424
3615
|
children: [
|
|
3425
|
-
/* @__PURE__ */ (0,
|
|
3426
|
-
/* @__PURE__ */ (0,
|
|
3616
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)("path", { d: "M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0" }),
|
|
3617
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)("circle", { cx: "12", cy: "12", r: "3" })
|
|
3427
3618
|
]
|
|
3428
3619
|
}
|
|
3429
3620
|
);
|
|
3430
3621
|
}
|
|
3431
3622
|
function EyeOffIcon({ className }) {
|
|
3432
|
-
return /* @__PURE__ */ (0,
|
|
3623
|
+
return /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(
|
|
3433
3624
|
"svg",
|
|
3434
3625
|
{
|
|
3435
3626
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -3441,16 +3632,16 @@ function EyeOffIcon({ className }) {
|
|
|
3441
3632
|
strokeLinejoin: "round",
|
|
3442
3633
|
className,
|
|
3443
3634
|
children: [
|
|
3444
|
-
/* @__PURE__ */ (0,
|
|
3445
|
-
/* @__PURE__ */ (0,
|
|
3446
|
-
/* @__PURE__ */ (0,
|
|
3447
|
-
/* @__PURE__ */ (0,
|
|
3635
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)("path", { d: "M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49" }),
|
|
3636
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)("path", { d: "M14.084 14.158a3 3 0 0 1-4.242-4.242" }),
|
|
3637
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)("path", { d: "M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143" }),
|
|
3638
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)("path", { d: "m2 2 20 20" })
|
|
3448
3639
|
]
|
|
3449
3640
|
}
|
|
3450
3641
|
);
|
|
3451
3642
|
}
|
|
3452
3643
|
function SpinnerIcon({ className }) {
|
|
3453
|
-
return /* @__PURE__ */ (0,
|
|
3644
|
+
return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
|
|
3454
3645
|
"svg",
|
|
3455
3646
|
{
|
|
3456
3647
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -3461,7 +3652,7 @@ function SpinnerIcon({ className }) {
|
|
|
3461
3652
|
strokeLinecap: "round",
|
|
3462
3653
|
strokeLinejoin: "round",
|
|
3463
3654
|
className,
|
|
3464
|
-
children: /* @__PURE__ */ (0,
|
|
3655
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("path", { d: "M21 12a9 9 0 1 1-6.219-8.56" })
|
|
3465
3656
|
}
|
|
3466
3657
|
);
|
|
3467
3658
|
}
|
|
@@ -3472,11 +3663,11 @@ function LoginForm({
|
|
|
3472
3663
|
error: externalError,
|
|
3473
3664
|
className
|
|
3474
3665
|
}) {
|
|
3475
|
-
const [username, setUsername] = (0,
|
|
3476
|
-
const [password, setPassword] = (0,
|
|
3477
|
-
const [showPassword, setShowPassword] = (0,
|
|
3478
|
-
const [submitting, setSubmitting] = (0,
|
|
3479
|
-
const [internalError, setInternalError] = (0,
|
|
3666
|
+
const [username, setUsername] = (0, import_react30.useState)("");
|
|
3667
|
+
const [password, setPassword] = (0, import_react30.useState)("");
|
|
3668
|
+
const [showPassword, setShowPassword] = (0, import_react30.useState)(false);
|
|
3669
|
+
const [submitting, setSubmitting] = (0, import_react30.useState)(false);
|
|
3670
|
+
const [internalError, setInternalError] = (0, import_react30.useState)(null);
|
|
3480
3671
|
const error = externalError ?? internalError;
|
|
3481
3672
|
const handleSubmit = async (e) => {
|
|
3482
3673
|
e.preventDefault();
|
|
@@ -3492,26 +3683,26 @@ function LoginForm({
|
|
|
3492
3683
|
setSubmitting(false);
|
|
3493
3684
|
}
|
|
3494
3685
|
};
|
|
3495
|
-
return /* @__PURE__ */ (0,
|
|
3686
|
+
return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
|
|
3496
3687
|
"div",
|
|
3497
3688
|
{
|
|
3498
3689
|
className: cn(
|
|
3499
3690
|
"flex min-h-screen items-center justify-center bg-background p-4",
|
|
3500
3691
|
className
|
|
3501
3692
|
),
|
|
3502
|
-
children: /* @__PURE__ */ (0,
|
|
3503
|
-
logoSrc && /* @__PURE__ */ (0,
|
|
3504
|
-
serverUrl && /* @__PURE__ */ (0,
|
|
3505
|
-
/* @__PURE__ */ (0,
|
|
3693
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("div", { className: "w-full max-w-sm", children: [
|
|
3694
|
+
logoSrc && /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: "flex justify-center mb-8", children: /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("img", { src: logoSrc, alt: "Logo", className: "h-12" }) }),
|
|
3695
|
+
serverUrl && /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("p", { className: "mb-4 text-center text-xs text-foreground-subtle truncate", children: serverUrl }),
|
|
3696
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(
|
|
3506
3697
|
"form",
|
|
3507
3698
|
{
|
|
3508
3699
|
onSubmit: handleSubmit,
|
|
3509
3700
|
className: "space-y-4 rounded-xl border border-border bg-surface p-6 shadow-xl shadow-black/10",
|
|
3510
3701
|
children: [
|
|
3511
|
-
error && /* @__PURE__ */ (0,
|
|
3512
|
-
/* @__PURE__ */ (0,
|
|
3513
|
-
/* @__PURE__ */ (0,
|
|
3514
|
-
/* @__PURE__ */ (0,
|
|
3702
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: "rounded-md bg-danger/10 border border-danger/20 px-3 py-2 text-xs text-danger", children: error }),
|
|
3703
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("div", { className: "space-y-1.5", children: [
|
|
3704
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)("label", { className: "text-xs font-medium text-foreground-subtle", children: "Username" }),
|
|
3705
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
|
|
3515
3706
|
"input",
|
|
3516
3707
|
{
|
|
3517
3708
|
type: "text",
|
|
@@ -3523,10 +3714,10 @@ function LoginForm({
|
|
|
3523
3714
|
}
|
|
3524
3715
|
)
|
|
3525
3716
|
] }),
|
|
3526
|
-
/* @__PURE__ */ (0,
|
|
3527
|
-
/* @__PURE__ */ (0,
|
|
3528
|
-
/* @__PURE__ */ (0,
|
|
3529
|
-
/* @__PURE__ */ (0,
|
|
3717
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("div", { className: "space-y-1.5", children: [
|
|
3718
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)("label", { className: "text-xs font-medium text-foreground-subtle", children: "Password" }),
|
|
3719
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("div", { className: "relative", children: [
|
|
3720
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
|
|
3530
3721
|
"input",
|
|
3531
3722
|
{
|
|
3532
3723
|
type: showPassword ? "text" : "password",
|
|
@@ -3537,26 +3728,26 @@ function LoginForm({
|
|
|
3537
3728
|
className: "w-full rounded-lg border border-border bg-background px-3 py-2.5 pr-10 text-sm text-foreground placeholder:text-foreground-subtle focus:outline-none focus:ring-2 focus:ring-primary/50 focus:border-primary"
|
|
3538
3729
|
}
|
|
3539
3730
|
),
|
|
3540
|
-
/* @__PURE__ */ (0,
|
|
3731
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
|
|
3541
3732
|
"button",
|
|
3542
3733
|
{
|
|
3543
3734
|
type: "button",
|
|
3544
3735
|
onClick: () => setShowPassword((prev) => !prev),
|
|
3545
3736
|
className: "absolute right-2.5 top-1/2 -translate-y-1/2 text-foreground-subtle hover:text-foreground",
|
|
3546
3737
|
tabIndex: -1,
|
|
3547
|
-
children: showPassword ? /* @__PURE__ */ (0,
|
|
3738
|
+
children: showPassword ? /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(EyeOffIcon, { className: "h-4 w-4" }) : /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(EyeIcon, { className: "h-4 w-4" })
|
|
3548
3739
|
}
|
|
3549
3740
|
)
|
|
3550
3741
|
] })
|
|
3551
3742
|
] }),
|
|
3552
|
-
/* @__PURE__ */ (0,
|
|
3743
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(
|
|
3553
3744
|
"button",
|
|
3554
3745
|
{
|
|
3555
3746
|
type: "submit",
|
|
3556
3747
|
disabled: submitting,
|
|
3557
3748
|
className: "w-full rounded-lg bg-primary px-4 py-2.5 text-sm font-semibold text-primary-foreground hover:bg-primary/90 disabled:opacity-50 disabled:cursor-not-allowed transition-colors flex items-center justify-center gap-2",
|
|
3558
3749
|
children: [
|
|
3559
|
-
submitting && /* @__PURE__ */ (0,
|
|
3750
|
+
submitting && /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(SpinnerIcon, { className: "h-4 w-4 animate-spin" }),
|
|
3560
3751
|
submitting ? "Logging in..." : "Log in"
|
|
3561
3752
|
]
|
|
3562
3753
|
}
|
|
@@ -3570,11 +3761,11 @@ function LoginForm({
|
|
|
3570
3761
|
}
|
|
3571
3762
|
|
|
3572
3763
|
// src/composites/dev-shell.tsx
|
|
3573
|
-
var
|
|
3764
|
+
var import_jsx_runtime51 = require("react/jsx-runtime");
|
|
3574
3765
|
var STORAGE_KEY = "camstack_dev_token";
|
|
3575
|
-
var DevShellContext = (0,
|
|
3766
|
+
var DevShellContext = (0, import_react31.createContext)(null);
|
|
3576
3767
|
function useDevShell() {
|
|
3577
|
-
const ctx = (0,
|
|
3768
|
+
const ctx = (0, import_react31.useContext)(DevShellContext);
|
|
3578
3769
|
if (!ctx) {
|
|
3579
3770
|
throw new Error("useDevShell must be used within a DevShell");
|
|
3580
3771
|
}
|
|
@@ -3585,7 +3776,7 @@ function getStoredToken() {
|
|
|
3585
3776
|
return localStorage.getItem(STORAGE_KEY);
|
|
3586
3777
|
}
|
|
3587
3778
|
function SunIcon({ className }) {
|
|
3588
|
-
return /* @__PURE__ */ (0,
|
|
3779
|
+
return /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(
|
|
3589
3780
|
"svg",
|
|
3590
3781
|
{
|
|
3591
3782
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -3597,21 +3788,21 @@ function SunIcon({ className }) {
|
|
|
3597
3788
|
strokeLinejoin: "round",
|
|
3598
3789
|
className,
|
|
3599
3790
|
children: [
|
|
3600
|
-
/* @__PURE__ */ (0,
|
|
3601
|
-
/* @__PURE__ */ (0,
|
|
3602
|
-
/* @__PURE__ */ (0,
|
|
3603
|
-
/* @__PURE__ */ (0,
|
|
3604
|
-
/* @__PURE__ */ (0,
|
|
3605
|
-
/* @__PURE__ */ (0,
|
|
3606
|
-
/* @__PURE__ */ (0,
|
|
3607
|
-
/* @__PURE__ */ (0,
|
|
3608
|
-
/* @__PURE__ */ (0,
|
|
3791
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("circle", { cx: "12", cy: "12", r: "4" }),
|
|
3792
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("path", { d: "M12 2v2" }),
|
|
3793
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("path", { d: "M12 20v2" }),
|
|
3794
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("path", { d: "m4.93 4.93 1.41 1.41" }),
|
|
3795
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("path", { d: "m17.66 17.66 1.41 1.41" }),
|
|
3796
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("path", { d: "M2 12h2" }),
|
|
3797
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("path", { d: "M20 12h2" }),
|
|
3798
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("path", { d: "m6.34 17.66-1.41 1.41" }),
|
|
3799
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("path", { d: "m19.07 4.93-1.41 1.41" })
|
|
3609
3800
|
]
|
|
3610
3801
|
}
|
|
3611
3802
|
);
|
|
3612
3803
|
}
|
|
3613
3804
|
function MoonIcon({ className }) {
|
|
3614
|
-
return /* @__PURE__ */ (0,
|
|
3805
|
+
return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
3615
3806
|
"svg",
|
|
3616
3807
|
{
|
|
3617
3808
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -3622,7 +3813,7 @@ function MoonIcon({ className }) {
|
|
|
3622
3813
|
strokeLinecap: "round",
|
|
3623
3814
|
strokeLinejoin: "round",
|
|
3624
3815
|
className,
|
|
3625
|
-
children: /* @__PURE__ */ (0,
|
|
3816
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("path", { d: "M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z" })
|
|
3626
3817
|
}
|
|
3627
3818
|
);
|
|
3628
3819
|
}
|
|
@@ -3634,7 +3825,7 @@ function DevShellInner({
|
|
|
3634
3825
|
onLogout
|
|
3635
3826
|
}) {
|
|
3636
3827
|
const theme = useThemeMode();
|
|
3637
|
-
const trpc = (0,
|
|
3828
|
+
const trpc = (0, import_react31.useMemo)(
|
|
3638
3829
|
() => {
|
|
3639
3830
|
const wsUrl = serverUrl.replace(/^http/, "ws") + "/trpc";
|
|
3640
3831
|
const wsClient = (0, import_client.createWSClient)({
|
|
@@ -3657,19 +3848,19 @@ function DevShellInner({
|
|
|
3657
3848
|
},
|
|
3658
3849
|
[serverUrl, token]
|
|
3659
3850
|
);
|
|
3660
|
-
const contextValue = (0,
|
|
3851
|
+
const contextValue = (0, import_react31.useMemo)(
|
|
3661
3852
|
() => ({ trpc, token, logout: onLogout }),
|
|
3662
3853
|
[trpc, token, onLogout]
|
|
3663
3854
|
);
|
|
3664
|
-
return /* @__PURE__ */ (0,
|
|
3665
|
-
/* @__PURE__ */ (0,
|
|
3666
|
-
/* @__PURE__ */ (0,
|
|
3667
|
-
/* @__PURE__ */ (0,
|
|
3668
|
-
title && /* @__PURE__ */ (0,
|
|
3669
|
-
/* @__PURE__ */ (0,
|
|
3855
|
+
return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(DevShellContext.Provider, { value: contextValue, children: /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className: "min-h-screen bg-background text-foreground", children: [
|
|
3856
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className: "flex items-center justify-between border-b border-border bg-surface px-4 py-2", children: [
|
|
3857
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
3858
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("span", { className: "rounded bg-warning/20 px-2 py-0.5 text-xs font-bold text-warning", children: "DEV MODE" }),
|
|
3859
|
+
title && /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("span", { className: "text-sm font-medium text-foreground", children: title }),
|
|
3860
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("span", { className: "text-xs text-foreground-subtle", children: serverUrl })
|
|
3670
3861
|
] }),
|
|
3671
|
-
/* @__PURE__ */ (0,
|
|
3672
|
-
/* @__PURE__ */ (0,
|
|
3862
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
3863
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(
|
|
3673
3864
|
"button",
|
|
3674
3865
|
{
|
|
3675
3866
|
type: "button",
|
|
@@ -3677,12 +3868,12 @@ function DevShellInner({
|
|
|
3677
3868
|
className: "flex items-center gap-1.5 rounded-md px-2 py-1 text-xs font-medium text-foreground-subtle hover:text-foreground hover:bg-surface-hover transition-colors",
|
|
3678
3869
|
title: `Theme: ${theme.mode}`,
|
|
3679
3870
|
children: [
|
|
3680
|
-
theme.resolvedMode === "dark" ? /* @__PURE__ */ (0,
|
|
3871
|
+
theme.resolvedMode === "dark" ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(SunIcon, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(MoonIcon, { className: "h-3.5 w-3.5" }),
|
|
3681
3872
|
theme.mode === "dark" ? "Dark" : theme.mode === "light" ? "Light" : "System"
|
|
3682
3873
|
]
|
|
3683
3874
|
}
|
|
3684
3875
|
),
|
|
3685
|
-
/* @__PURE__ */ (0,
|
|
3876
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
3686
3877
|
"button",
|
|
3687
3878
|
{
|
|
3688
3879
|
type: "button",
|
|
@@ -3693,7 +3884,7 @@ function DevShellInner({
|
|
|
3693
3884
|
)
|
|
3694
3885
|
] })
|
|
3695
3886
|
] }),
|
|
3696
|
-
/* @__PURE__ */ (0,
|
|
3887
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { className: "p-4", children: children({ trpc, theme }) })
|
|
3697
3888
|
] }) });
|
|
3698
3889
|
}
|
|
3699
3890
|
function DevShell({
|
|
@@ -3701,8 +3892,8 @@ function DevShell({
|
|
|
3701
3892
|
serverUrl = "https://localhost:4443",
|
|
3702
3893
|
title
|
|
3703
3894
|
}) {
|
|
3704
|
-
const [token, setToken] = (0,
|
|
3705
|
-
const handleLogin = (0,
|
|
3895
|
+
const [token, setToken] = (0, import_react31.useState)(getStoredToken);
|
|
3896
|
+
const handleLogin = (0, import_react31.useCallback)(
|
|
3706
3897
|
async (username, password) => {
|
|
3707
3898
|
const anonClient = (0, import_client.createTRPCClient)({
|
|
3708
3899
|
links: [
|
|
@@ -3719,14 +3910,14 @@ function DevShell({
|
|
|
3719
3910
|
},
|
|
3720
3911
|
[serverUrl]
|
|
3721
3912
|
);
|
|
3722
|
-
const handleLogout = (0,
|
|
3913
|
+
const handleLogout = (0, import_react31.useCallback)(() => {
|
|
3723
3914
|
localStorage.removeItem(STORAGE_KEY);
|
|
3724
3915
|
setToken(null);
|
|
3725
3916
|
}, []);
|
|
3726
3917
|
if (!token) {
|
|
3727
|
-
return /* @__PURE__ */ (0,
|
|
3918
|
+
return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(ThemeProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(LoginForm, { onLogin: handleLogin, serverUrl }) });
|
|
3728
3919
|
}
|
|
3729
|
-
return /* @__PURE__ */ (0,
|
|
3920
|
+
return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(ThemeProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
3730
3921
|
DevShellInner,
|
|
3731
3922
|
{
|
|
3732
3923
|
serverUrl,
|
|
@@ -3751,10 +3942,10 @@ function mountAddonPage(PageComponent, options = {}) {
|
|
|
3751
3942
|
return;
|
|
3752
3943
|
}
|
|
3753
3944
|
(0, import_client2.createRoot)(root).render(
|
|
3754
|
-
(0,
|
|
3945
|
+
(0, import_react32.createElement)(DevShell, {
|
|
3755
3946
|
serverUrl,
|
|
3756
3947
|
title,
|
|
3757
|
-
children: ({ trpc, theme }) => (0,
|
|
3948
|
+
children: ({ trpc, theme }) => (0, import_react32.createElement)(PageComponent, {
|
|
3758
3949
|
trpc,
|
|
3759
3950
|
theme: { isDark: theme.resolvedMode === "dark" },
|
|
3760
3951
|
navigate: (path) => {
|
|
@@ -3768,6 +3959,7 @@ function mountAddonPage(PageComponent, options = {}) {
|
|
|
3768
3959
|
0 && (module.exports = {
|
|
3769
3960
|
AppShell,
|
|
3770
3961
|
Badge,
|
|
3962
|
+
BottomSheet,
|
|
3771
3963
|
Button,
|
|
3772
3964
|
CLASS_COLORS,
|
|
3773
3965
|
Card,
|
|
@@ -3804,6 +3996,7 @@ function mountAddonPage(PageComponent, options = {}) {
|
|
|
3804
3996
|
KeyValueList,
|
|
3805
3997
|
Label,
|
|
3806
3998
|
LoginForm,
|
|
3999
|
+
MobileDrawer,
|
|
3807
4000
|
PageHeader,
|
|
3808
4001
|
PipelineBuilder,
|
|
3809
4002
|
PipelineRuntimeSelector,
|
|
@@ -3843,6 +4036,7 @@ function mountAddonPage(PageComponent, options = {}) {
|
|
|
3843
4036
|
statusIcons,
|
|
3844
4037
|
themeToCss,
|
|
3845
4038
|
useDevShell,
|
|
4039
|
+
useIsMobile,
|
|
3846
4040
|
useThemeMode
|
|
3847
4041
|
});
|
|
3848
4042
|
//# sourceMappingURL=index.cjs.map
|