@camstack/ui-library 0.1.34 → 0.1.36
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 +778 -460
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +32 -4
- package/dist/index.d.ts +32 -4
- package/dist/index.js +728 -413
- 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: {
|
|
@@ -1003,31 +1006,111 @@ function TooltipContent({ className, children, ...props }) {
|
|
|
1003
1006
|
}
|
|
1004
1007
|
|
|
1005
1008
|
// src/primitives/popover.tsx
|
|
1009
|
+
var import_react19 = require("react");
|
|
1010
|
+
|
|
1011
|
+
// src/hooks/use-is-mobile.ts
|
|
1006
1012
|
var import_react17 = require("react");
|
|
1013
|
+
var MOBILE_QUERY = "(max-width: 767px)";
|
|
1014
|
+
function subscribe(callback) {
|
|
1015
|
+
const mql = window.matchMedia(MOBILE_QUERY);
|
|
1016
|
+
mql.addEventListener("change", callback);
|
|
1017
|
+
return () => mql.removeEventListener("change", callback);
|
|
1018
|
+
}
|
|
1019
|
+
function getSnapshot() {
|
|
1020
|
+
return window.matchMedia(MOBILE_QUERY).matches;
|
|
1021
|
+
}
|
|
1022
|
+
function getServerSnapshot() {
|
|
1023
|
+
return false;
|
|
1024
|
+
}
|
|
1025
|
+
function useIsMobile() {
|
|
1026
|
+
return (0, import_react17.useSyncExternalStore)(subscribe, getSnapshot, getServerSnapshot);
|
|
1027
|
+
}
|
|
1028
|
+
|
|
1029
|
+
// src/primitives/bottom-sheet.tsx
|
|
1030
|
+
var import_react18 = require("react");
|
|
1031
|
+
var import_lucide_react4 = require("lucide-react");
|
|
1007
1032
|
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
1008
|
-
|
|
1033
|
+
function BottomSheet({ open, onClose, title, children, className }) {
|
|
1034
|
+
(0, import_react18.useEffect)(() => {
|
|
1035
|
+
if (!open) return;
|
|
1036
|
+
const handleKeyDown = (e) => {
|
|
1037
|
+
if (e.key === "Escape") onClose();
|
|
1038
|
+
};
|
|
1039
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
1040
|
+
document.body.style.overflow = "hidden";
|
|
1041
|
+
return () => {
|
|
1042
|
+
document.removeEventListener("keydown", handleKeyDown);
|
|
1043
|
+
document.body.style.overflow = "";
|
|
1044
|
+
};
|
|
1045
|
+
}, [open, onClose]);
|
|
1046
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
|
|
1047
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1048
|
+
"div",
|
|
1049
|
+
{
|
|
1050
|
+
className: cn(
|
|
1051
|
+
"fixed inset-0 z-40 bg-black/50 transition-opacity duration-200",
|
|
1052
|
+
open ? "opacity-100" : "pointer-events-none opacity-0"
|
|
1053
|
+
),
|
|
1054
|
+
onClick: onClose,
|
|
1055
|
+
"aria-hidden": "true"
|
|
1056
|
+
}
|
|
1057
|
+
),
|
|
1058
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
1059
|
+
"div",
|
|
1060
|
+
{
|
|
1061
|
+
role: "dialog",
|
|
1062
|
+
"aria-modal": "true",
|
|
1063
|
+
className: cn(
|
|
1064
|
+
"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",
|
|
1065
|
+
"max-h-[80dvh]",
|
|
1066
|
+
open ? "translate-y-0" : "translate-y-full",
|
|
1067
|
+
className
|
|
1068
|
+
),
|
|
1069
|
+
children: [
|
|
1070
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "flex justify-center pt-2 pb-1", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "h-1 w-8 rounded-full bg-foreground-subtle/30" }) }),
|
|
1071
|
+
title && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex items-center justify-between px-4 pb-2", children: [
|
|
1072
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "text-sm font-medium text-foreground", children: title }),
|
|
1073
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1074
|
+
"button",
|
|
1075
|
+
{
|
|
1076
|
+
onClick: onClose,
|
|
1077
|
+
className: "p-1 rounded-md hover:bg-surface-hover text-foreground-muted transition-colors",
|
|
1078
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_lucide_react4.X, { className: "h-4 w-4" })
|
|
1079
|
+
}
|
|
1080
|
+
)
|
|
1081
|
+
] }),
|
|
1082
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "flex-1 overflow-y-auto px-4 pb-4", children })
|
|
1083
|
+
]
|
|
1084
|
+
}
|
|
1085
|
+
)
|
|
1086
|
+
] });
|
|
1087
|
+
}
|
|
1088
|
+
|
|
1089
|
+
// src/primitives/popover.tsx
|
|
1090
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
1091
|
+
var PopoverContext = (0, import_react19.createContext)(null);
|
|
1009
1092
|
function usePopoverContext() {
|
|
1010
|
-
const ctx = (0,
|
|
1093
|
+
const ctx = (0, import_react19.useContext)(PopoverContext);
|
|
1011
1094
|
if (!ctx) throw new Error("Popover compound components must be used within <Popover>");
|
|
1012
1095
|
return ctx;
|
|
1013
1096
|
}
|
|
1014
1097
|
function Popover({ children, open: controlledOpen, onOpenChange }) {
|
|
1015
|
-
const [uncontrolledOpen, setUncontrolledOpen] = (0,
|
|
1098
|
+
const [uncontrolledOpen, setUncontrolledOpen] = (0, import_react19.useState)(false);
|
|
1016
1099
|
const open = controlledOpen ?? uncontrolledOpen;
|
|
1017
|
-
const triggerId = (0,
|
|
1018
|
-
const contentId = (0,
|
|
1019
|
-
const setOpen = (0,
|
|
1100
|
+
const triggerId = (0, import_react19.useId)();
|
|
1101
|
+
const contentId = (0, import_react19.useId)();
|
|
1102
|
+
const setOpen = (0, import_react19.useCallback)(
|
|
1020
1103
|
(next) => {
|
|
1021
1104
|
onOpenChange?.(next);
|
|
1022
1105
|
if (controlledOpen === void 0) setUncontrolledOpen(next);
|
|
1023
1106
|
},
|
|
1024
1107
|
[controlledOpen, onOpenChange]
|
|
1025
1108
|
);
|
|
1026
|
-
return /* @__PURE__ */ (0,
|
|
1109
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(PopoverContext.Provider, { value: { open, setOpen, triggerId, contentId }, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "relative inline-block", children }) });
|
|
1027
1110
|
}
|
|
1028
1111
|
function PopoverTrigger({ children, ...props }) {
|
|
1029
1112
|
const { open, setOpen, triggerId, contentId } = usePopoverContext();
|
|
1030
|
-
return /* @__PURE__ */ (0,
|
|
1113
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
1031
1114
|
"button",
|
|
1032
1115
|
{
|
|
1033
1116
|
type: "button",
|
|
@@ -1043,9 +1126,10 @@ function PopoverTrigger({ children, ...props }) {
|
|
|
1043
1126
|
}
|
|
1044
1127
|
function PopoverContent({ className, children, ...props }) {
|
|
1045
1128
|
const { open, setOpen, contentId, triggerId } = usePopoverContext();
|
|
1046
|
-
const
|
|
1047
|
-
(0,
|
|
1048
|
-
|
|
1129
|
+
const isMobile = useIsMobile();
|
|
1130
|
+
const ref = (0, import_react19.useRef)(null);
|
|
1131
|
+
(0, import_react19.useEffect)(() => {
|
|
1132
|
+
if (!open || isMobile) return;
|
|
1049
1133
|
const handler = (e) => {
|
|
1050
1134
|
const el = ref.current;
|
|
1051
1135
|
const trigger = document.getElementById(triggerId);
|
|
@@ -1062,9 +1146,12 @@ function PopoverContent({ className, children, ...props }) {
|
|
|
1062
1146
|
document.removeEventListener("mousedown", handler);
|
|
1063
1147
|
document.removeEventListener("keydown", escHandler);
|
|
1064
1148
|
};
|
|
1065
|
-
}, [open, setOpen, triggerId]);
|
|
1149
|
+
}, [open, setOpen, triggerId, isMobile]);
|
|
1066
1150
|
if (!open) return null;
|
|
1067
|
-
|
|
1151
|
+
if (isMobile) {
|
|
1152
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(BottomSheet, { open, onClose: () => setOpen(false), children });
|
|
1153
|
+
}
|
|
1154
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
1068
1155
|
"div",
|
|
1069
1156
|
{
|
|
1070
1157
|
ref,
|
|
@@ -1082,11 +1169,11 @@ function PopoverContent({ className, children, ...props }) {
|
|
|
1082
1169
|
}
|
|
1083
1170
|
|
|
1084
1171
|
// src/primitives/tabs.tsx
|
|
1085
|
-
var
|
|
1086
|
-
var
|
|
1087
|
-
var TabsContext = (0,
|
|
1172
|
+
var import_react20 = require("react");
|
|
1173
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
1174
|
+
var TabsContext = (0, import_react20.createContext)(null);
|
|
1088
1175
|
function useTabsContext() {
|
|
1089
|
-
const ctx = (0,
|
|
1176
|
+
const ctx = (0, import_react20.useContext)(TabsContext);
|
|
1090
1177
|
if (!ctx) throw new Error("Tabs compound components must be used within <Tabs>");
|
|
1091
1178
|
return ctx;
|
|
1092
1179
|
}
|
|
@@ -1097,19 +1184,19 @@ function Tabs({
|
|
|
1097
1184
|
className,
|
|
1098
1185
|
...props
|
|
1099
1186
|
}) {
|
|
1100
|
-
const [uncontrolledValue, setUncontrolledValue] = (0,
|
|
1187
|
+
const [uncontrolledValue, setUncontrolledValue] = (0, import_react20.useState)(defaultValue);
|
|
1101
1188
|
const value = controlledValue ?? uncontrolledValue;
|
|
1102
|
-
const setValue = (0,
|
|
1189
|
+
const setValue = (0, import_react20.useCallback)(
|
|
1103
1190
|
(next) => {
|
|
1104
1191
|
onValueChange?.(next);
|
|
1105
1192
|
if (controlledValue === void 0) setUncontrolledValue(next);
|
|
1106
1193
|
},
|
|
1107
1194
|
[controlledValue, onValueChange]
|
|
1108
1195
|
);
|
|
1109
|
-
return /* @__PURE__ */ (0,
|
|
1196
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(TabsContext.Provider, { value: { value, setValue }, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className, ...props }) });
|
|
1110
1197
|
}
|
|
1111
1198
|
function TabsList({ className, ...props }) {
|
|
1112
|
-
return /* @__PURE__ */ (0,
|
|
1199
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
1113
1200
|
"div",
|
|
1114
1201
|
{
|
|
1115
1202
|
role: "tablist",
|
|
@@ -1122,7 +1209,7 @@ function TabsTrigger({ value, className, ...props }) {
|
|
|
1122
1209
|
const { value: activeValue, setValue } = useTabsContext();
|
|
1123
1210
|
const isActive = value === activeValue;
|
|
1124
1211
|
const panelId = `tabpanel-${value}`;
|
|
1125
|
-
return /* @__PURE__ */ (0,
|
|
1212
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
1126
1213
|
"button",
|
|
1127
1214
|
{
|
|
1128
1215
|
type: "button",
|
|
@@ -1143,7 +1230,7 @@ function TabsTrigger({ value, className, ...props }) {
|
|
|
1143
1230
|
function TabsContent({ value, className, ...props }) {
|
|
1144
1231
|
const { value: activeValue } = useTabsContext();
|
|
1145
1232
|
if (value !== activeValue) return null;
|
|
1146
|
-
return /* @__PURE__ */ (0,
|
|
1233
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
1147
1234
|
"div",
|
|
1148
1235
|
{
|
|
1149
1236
|
role: "tabpanel",
|
|
@@ -1155,11 +1242,11 @@ function TabsContent({ value, className, ...props }) {
|
|
|
1155
1242
|
}
|
|
1156
1243
|
|
|
1157
1244
|
// src/primitives/scroll-area.tsx
|
|
1158
|
-
var
|
|
1159
|
-
var
|
|
1160
|
-
var ScrollArea = (0,
|
|
1245
|
+
var import_react21 = require("react");
|
|
1246
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
1247
|
+
var ScrollArea = (0, import_react21.forwardRef)(
|
|
1161
1248
|
({ className, ...props }, ref) => {
|
|
1162
|
-
return /* @__PURE__ */ (0,
|
|
1249
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
1163
1250
|
"div",
|
|
1164
1251
|
{
|
|
1165
1252
|
ref,
|
|
@@ -1175,9 +1262,9 @@ var ScrollArea = (0, import_react19.forwardRef)(
|
|
|
1175
1262
|
ScrollArea.displayName = "ScrollArea";
|
|
1176
1263
|
|
|
1177
1264
|
// src/primitives/floating-panel.tsx
|
|
1178
|
-
var
|
|
1179
|
-
var
|
|
1180
|
-
var
|
|
1265
|
+
var import_react22 = require("react");
|
|
1266
|
+
var import_lucide_react5 = require("lucide-react");
|
|
1267
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
1181
1268
|
function FloatingPanel({
|
|
1182
1269
|
title,
|
|
1183
1270
|
onClose,
|
|
@@ -1189,24 +1276,25 @@ function FloatingPanel({
|
|
|
1189
1276
|
offsetIndex = 0,
|
|
1190
1277
|
className
|
|
1191
1278
|
}) {
|
|
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
|
|
1279
|
+
const [pos, setPos] = (0, import_react22.useState)({ x: 80 + offsetIndex * 30, y: 80 + offsetIndex * 30 });
|
|
1280
|
+
const [size, setSize] = (0, import_react22.useState)({ w: defaultWidth, h: defaultHeight });
|
|
1281
|
+
const [minimized, setMinimized] = (0, import_react22.useState)(false);
|
|
1282
|
+
const dragging = (0, import_react22.useRef)(false);
|
|
1283
|
+
const resizing = (0, import_react22.useRef)(false);
|
|
1284
|
+
const offset = (0, import_react22.useRef)({ x: 0, y: 0 });
|
|
1285
|
+
const isMobile = useIsMobile();
|
|
1286
|
+
const onDragStart = (0, import_react22.useCallback)((e) => {
|
|
1199
1287
|
e.preventDefault();
|
|
1200
1288
|
dragging.current = true;
|
|
1201
1289
|
offset.current = { x: e.clientX - pos.x, y: e.clientY - pos.y };
|
|
1202
1290
|
}, [pos]);
|
|
1203
|
-
const onResizeStart = (0,
|
|
1291
|
+
const onResizeStart = (0, import_react22.useCallback)((e) => {
|
|
1204
1292
|
e.preventDefault();
|
|
1205
1293
|
e.stopPropagation();
|
|
1206
1294
|
resizing.current = true;
|
|
1207
1295
|
offset.current = { x: e.clientX, y: e.clientY };
|
|
1208
1296
|
}, []);
|
|
1209
|
-
(0,
|
|
1297
|
+
(0, import_react22.useEffect)(() => {
|
|
1210
1298
|
const onMouseMove = (e) => {
|
|
1211
1299
|
if (dragging.current) setPos({ x: e.clientX - offset.current.x, y: e.clientY - offset.current.y });
|
|
1212
1300
|
if (resizing.current) {
|
|
@@ -1227,7 +1315,43 @@ function FloatingPanel({
|
|
|
1227
1315
|
window.removeEventListener("mouseup", onMouseUp);
|
|
1228
1316
|
};
|
|
1229
1317
|
}, [minWidth, minHeight]);
|
|
1230
|
-
|
|
1318
|
+
if (isMobile) {
|
|
1319
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
1320
|
+
"div",
|
|
1321
|
+
{
|
|
1322
|
+
className: cn(
|
|
1323
|
+
"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",
|
|
1324
|
+
className
|
|
1325
|
+
),
|
|
1326
|
+
style: { maxHeight: "60dvh" },
|
|
1327
|
+
children: [
|
|
1328
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex items-center justify-between gap-2 px-3 py-2 border-b border-border shrink-0 bg-surface", children: [
|
|
1329
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "text-[11px] font-medium truncate", children: title }),
|
|
1330
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex items-center gap-1 shrink-0", children: [
|
|
1331
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
1332
|
+
"button",
|
|
1333
|
+
{
|
|
1334
|
+
onClick: () => setMinimized(!minimized),
|
|
1335
|
+
className: "p-0.5 rounded hover:bg-surface-hover text-foreground-muted transition-colors",
|
|
1336
|
+
children: minimized ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react5.Maximize2, { size: 12 }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react5.Minimize2, { size: 12 })
|
|
1337
|
+
}
|
|
1338
|
+
),
|
|
1339
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
1340
|
+
"button",
|
|
1341
|
+
{
|
|
1342
|
+
onClick: onClose,
|
|
1343
|
+
className: "p-0.5 rounded hover:bg-danger/20 text-foreground-muted hover:text-danger transition-colors",
|
|
1344
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react5.X, { size: 12 })
|
|
1345
|
+
}
|
|
1346
|
+
)
|
|
1347
|
+
] })
|
|
1348
|
+
] }),
|
|
1349
|
+
!minimized && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "flex-1 min-h-0 overflow-y-auto", children })
|
|
1350
|
+
]
|
|
1351
|
+
}
|
|
1352
|
+
);
|
|
1353
|
+
}
|
|
1354
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
1231
1355
|
"div",
|
|
1232
1356
|
{
|
|
1233
1357
|
className: cn(
|
|
@@ -1236,42 +1360,42 @@ function FloatingPanel({
|
|
|
1236
1360
|
),
|
|
1237
1361
|
style: { left: pos.x, top: pos.y, width: minimized ? 280 : size.w, height: minimized ? "auto" : size.h },
|
|
1238
1362
|
children: [
|
|
1239
|
-
/* @__PURE__ */ (0,
|
|
1363
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
1240
1364
|
"div",
|
|
1241
1365
|
{
|
|
1242
1366
|
onMouseDown: onDragStart,
|
|
1243
1367
|
className: "flex items-center justify-between gap-2 px-3 py-2 border-b border-border cursor-move select-none shrink-0 bg-surface",
|
|
1244
1368
|
children: [
|
|
1245
|
-
/* @__PURE__ */ (0,
|
|
1246
|
-
/* @__PURE__ */ (0,
|
|
1247
|
-
/* @__PURE__ */ (0,
|
|
1369
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex items-center gap-2 min-w-0", children: [
|
|
1370
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react5.GripHorizontal, { size: 12, className: "text-foreground-subtle shrink-0" }),
|
|
1371
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "text-[11px] font-medium truncate", children: title })
|
|
1248
1372
|
] }),
|
|
1249
|
-
/* @__PURE__ */ (0,
|
|
1250
|
-
/* @__PURE__ */ (0,
|
|
1373
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex items-center gap-1 shrink-0", children: [
|
|
1374
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
1251
1375
|
"button",
|
|
1252
1376
|
{
|
|
1253
1377
|
onClick: () => setMinimized(!minimized),
|
|
1254
1378
|
className: "p-0.5 rounded hover:bg-surface-hover text-foreground-muted transition-colors",
|
|
1255
1379
|
title: minimized ? "Restore" : "Minimize",
|
|
1256
|
-
children: minimized ? /* @__PURE__ */ (0,
|
|
1380
|
+
children: minimized ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react5.Maximize2, { size: 12 }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react5.Minimize2, { size: 12 })
|
|
1257
1381
|
}
|
|
1258
1382
|
),
|
|
1259
|
-
/* @__PURE__ */ (0,
|
|
1383
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
1260
1384
|
"button",
|
|
1261
1385
|
{
|
|
1262
1386
|
onClick: onClose,
|
|
1263
1387
|
className: "p-0.5 rounded hover:bg-danger/20 text-foreground-muted hover:text-danger transition-colors",
|
|
1264
1388
|
title: "Close",
|
|
1265
|
-
children: /* @__PURE__ */ (0,
|
|
1389
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react5.X, { size: 12 })
|
|
1266
1390
|
}
|
|
1267
1391
|
)
|
|
1268
1392
|
] })
|
|
1269
1393
|
]
|
|
1270
1394
|
}
|
|
1271
1395
|
),
|
|
1272
|
-
!minimized && /* @__PURE__ */ (0,
|
|
1396
|
+
!minimized && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex-1 min-h-0 overflow-y-auto relative", children: [
|
|
1273
1397
|
children,
|
|
1274
|
-
/* @__PURE__ */ (0,
|
|
1398
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
1275
1399
|
"div",
|
|
1276
1400
|
{
|
|
1277
1401
|
onMouseDown: onResizeStart,
|
|
@@ -1285,8 +1409,55 @@ function FloatingPanel({
|
|
|
1285
1409
|
);
|
|
1286
1410
|
}
|
|
1287
1411
|
|
|
1412
|
+
// src/primitives/mobile-drawer.tsx
|
|
1413
|
+
var import_react23 = require("react");
|
|
1414
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
1415
|
+
function MobileDrawer({ open, onClose, children, className, width = "w-64" }) {
|
|
1416
|
+
const drawerRef = (0, import_react23.useRef)(null);
|
|
1417
|
+
(0, import_react23.useEffect)(() => {
|
|
1418
|
+
if (!open) return;
|
|
1419
|
+
const handleKeyDown = (e) => {
|
|
1420
|
+
if (e.key === "Escape") onClose();
|
|
1421
|
+
};
|
|
1422
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
1423
|
+
document.body.style.overflow = "hidden";
|
|
1424
|
+
return () => {
|
|
1425
|
+
document.removeEventListener("keydown", handleKeyDown);
|
|
1426
|
+
document.body.style.overflow = "";
|
|
1427
|
+
};
|
|
1428
|
+
}, [open, onClose]);
|
|
1429
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
|
|
1430
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
1431
|
+
"div",
|
|
1432
|
+
{
|
|
1433
|
+
className: cn(
|
|
1434
|
+
"fixed inset-0 z-40 bg-black/50 backdrop-blur-sm transition-opacity duration-200",
|
|
1435
|
+
open ? "opacity-100" : "pointer-events-none opacity-0"
|
|
1436
|
+
),
|
|
1437
|
+
onClick: onClose,
|
|
1438
|
+
"aria-hidden": "true"
|
|
1439
|
+
}
|
|
1440
|
+
),
|
|
1441
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
1442
|
+
"div",
|
|
1443
|
+
{
|
|
1444
|
+
ref: drawerRef,
|
|
1445
|
+
role: "dialog",
|
|
1446
|
+
"aria-modal": "true",
|
|
1447
|
+
className: cn(
|
|
1448
|
+
"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",
|
|
1449
|
+
width,
|
|
1450
|
+
open ? "translate-x-0" : "-translate-x-full",
|
|
1451
|
+
className
|
|
1452
|
+
),
|
|
1453
|
+
children
|
|
1454
|
+
}
|
|
1455
|
+
)
|
|
1456
|
+
] });
|
|
1457
|
+
}
|
|
1458
|
+
|
|
1288
1459
|
// src/composites/status-badge.tsx
|
|
1289
|
-
var
|
|
1460
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
1290
1461
|
var statusConfig = {
|
|
1291
1462
|
online: { colorClass: "bg-success", label: "Online" },
|
|
1292
1463
|
offline: { colorClass: "bg-danger", label: "Offline" },
|
|
@@ -1301,7 +1472,7 @@ function StatusBadge({
|
|
|
1301
1472
|
className
|
|
1302
1473
|
}) {
|
|
1303
1474
|
const config = statusConfig[status];
|
|
1304
|
-
return /* @__PURE__ */ (0,
|
|
1475
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
1305
1476
|
"span",
|
|
1306
1477
|
{
|
|
1307
1478
|
className: cn(
|
|
@@ -1310,21 +1481,21 @@ function StatusBadge({
|
|
|
1310
1481
|
className
|
|
1311
1482
|
),
|
|
1312
1483
|
children: [
|
|
1313
|
-
showDot && /* @__PURE__ */ (0,
|
|
1484
|
+
showDot && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
1314
1485
|
"span",
|
|
1315
1486
|
{
|
|
1316
1487
|
className: cn("h-1.5 w-1.5 shrink-0 rounded-full", config.colorClass),
|
|
1317
1488
|
"aria-hidden": "true"
|
|
1318
1489
|
}
|
|
1319
1490
|
),
|
|
1320
|
-
showLabel && /* @__PURE__ */ (0,
|
|
1491
|
+
showLabel && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "text-foreground", children: config.label })
|
|
1321
1492
|
]
|
|
1322
1493
|
}
|
|
1323
1494
|
);
|
|
1324
1495
|
}
|
|
1325
1496
|
|
|
1326
1497
|
// src/composites/provider-badge.tsx
|
|
1327
|
-
var
|
|
1498
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
1328
1499
|
var providerConfig = {
|
|
1329
1500
|
frigate: { colorClass: "bg-provider-frigate", label: "Frigate" },
|
|
1330
1501
|
scrypted: { colorClass: "bg-provider-scrypted", label: "Scrypted" },
|
|
@@ -1338,20 +1509,20 @@ function ProviderBadge({
|
|
|
1338
1509
|
className
|
|
1339
1510
|
}) {
|
|
1340
1511
|
const config = providerConfig[provider];
|
|
1341
|
-
return /* @__PURE__ */ (0,
|
|
1342
|
-
/* @__PURE__ */ (0,
|
|
1512
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("span", { className: cn("inline-flex items-center gap-1.5 text-xs", className), children: [
|
|
1513
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
1343
1514
|
"span",
|
|
1344
1515
|
{
|
|
1345
1516
|
className: cn("h-1.5 w-1.5 shrink-0 rounded-sm", config.colorClass),
|
|
1346
1517
|
"aria-hidden": "true"
|
|
1347
1518
|
}
|
|
1348
1519
|
),
|
|
1349
|
-
showLabel && /* @__PURE__ */ (0,
|
|
1520
|
+
showLabel && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-foreground", children: config.label })
|
|
1350
1521
|
] });
|
|
1351
1522
|
}
|
|
1352
1523
|
|
|
1353
1524
|
// src/composites/version-badge.tsx
|
|
1354
|
-
var
|
|
1525
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
1355
1526
|
var VARIANT_STYLES = {
|
|
1356
1527
|
success: "bg-emerald-400 text-emerald-950",
|
|
1357
1528
|
warning: "bg-amber-400 text-amber-950",
|
|
@@ -1360,7 +1531,7 @@ var VARIANT_STYLES = {
|
|
|
1360
1531
|
neutral: "bg-foreground-subtle/20 text-foreground"
|
|
1361
1532
|
};
|
|
1362
1533
|
function SemanticBadge({ children, variant = "neutral", mono, className }) {
|
|
1363
|
-
return /* @__PURE__ */ (0,
|
|
1534
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: cn(
|
|
1364
1535
|
"inline-flex items-center rounded-md px-2 py-0.5 text-[11px] font-bold leading-tight",
|
|
1365
1536
|
mono && "font-mono",
|
|
1366
1537
|
VARIANT_STYLES[variant],
|
|
@@ -1369,11 +1540,11 @@ function SemanticBadge({ children, variant = "neutral", mono, className }) {
|
|
|
1369
1540
|
}
|
|
1370
1541
|
function VersionBadge({ version, preRelease, className }) {
|
|
1371
1542
|
const isPreRelease = preRelease ?? /-(alpha|beta|rc|dev|canary|next)/i.test(version);
|
|
1372
|
-
return /* @__PURE__ */ (0,
|
|
1543
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SemanticBadge, { variant: isPreRelease ? "warning" : "success", mono: true, className, children: version });
|
|
1373
1544
|
}
|
|
1374
1545
|
|
|
1375
1546
|
// src/composites/form-field.tsx
|
|
1376
|
-
var
|
|
1547
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
1377
1548
|
function FormField({
|
|
1378
1549
|
label,
|
|
1379
1550
|
description,
|
|
@@ -1384,7 +1555,7 @@ function FormField({
|
|
|
1384
1555
|
className
|
|
1385
1556
|
}) {
|
|
1386
1557
|
const isHorizontal = orientation === "horizontal";
|
|
1387
|
-
return /* @__PURE__ */ (0,
|
|
1558
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
1388
1559
|
"div",
|
|
1389
1560
|
{
|
|
1390
1561
|
className: cn(
|
|
@@ -1393,34 +1564,34 @@ function FormField({
|
|
|
1393
1564
|
className
|
|
1394
1565
|
),
|
|
1395
1566
|
children: [
|
|
1396
|
-
/* @__PURE__ */ (0,
|
|
1397
|
-
/* @__PURE__ */ (0,
|
|
1567
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: cn(isHorizontal ? "flex-1" : ""), children: [
|
|
1568
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(Label, { children: [
|
|
1398
1569
|
label,
|
|
1399
|
-
required && /* @__PURE__ */ (0,
|
|
1570
|
+
required && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "text-danger ml-0.5", children: "*" })
|
|
1400
1571
|
] }),
|
|
1401
|
-
description && /* @__PURE__ */ (0,
|
|
1572
|
+
description && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "text-foreground-subtle text-xs mt-0.5", children: description })
|
|
1402
1573
|
] }),
|
|
1403
|
-
/* @__PURE__ */ (0,
|
|
1404
|
-
error && /* @__PURE__ */ (0,
|
|
1574
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: cn(isHorizontal ? "shrink-0" : ""), children }),
|
|
1575
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "text-danger text-xs", children: error })
|
|
1405
1576
|
]
|
|
1406
1577
|
}
|
|
1407
1578
|
);
|
|
1408
1579
|
}
|
|
1409
1580
|
|
|
1410
1581
|
// src/composites/page-header.tsx
|
|
1411
|
-
var
|
|
1582
|
+
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
1412
1583
|
function PageHeader({ title, subtitle, actions, className }) {
|
|
1413
|
-
return /* @__PURE__ */ (0,
|
|
1414
|
-
/* @__PURE__ */ (0,
|
|
1415
|
-
/* @__PURE__ */ (0,
|
|
1416
|
-
subtitle && /* @__PURE__ */ (0,
|
|
1584
|
+
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: [
|
|
1585
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { children: [
|
|
1586
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("h1", { className: "text-sm font-semibold text-foreground", children: title }),
|
|
1587
|
+
subtitle && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("p", { className: "text-foreground-subtle text-xs", children: subtitle })
|
|
1417
1588
|
] }),
|
|
1418
|
-
actions && /* @__PURE__ */ (0,
|
|
1589
|
+
actions && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "flex items-center gap-2 flex-wrap", children: actions })
|
|
1419
1590
|
] });
|
|
1420
1591
|
}
|
|
1421
1592
|
|
|
1422
1593
|
// src/composites/empty-state.tsx
|
|
1423
|
-
var
|
|
1594
|
+
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
1424
1595
|
function EmptyState({
|
|
1425
1596
|
icon: Icon,
|
|
1426
1597
|
title,
|
|
@@ -1428,18 +1599,18 @@ function EmptyState({
|
|
|
1428
1599
|
action,
|
|
1429
1600
|
className
|
|
1430
1601
|
}) {
|
|
1431
|
-
return /* @__PURE__ */ (0,
|
|
1432
|
-
Icon && /* @__PURE__ */ (0,
|
|
1433
|
-
/* @__PURE__ */ (0,
|
|
1434
|
-
/* @__PURE__ */ (0,
|
|
1435
|
-
description && /* @__PURE__ */ (0,
|
|
1602
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: cn("flex flex-col items-center justify-center gap-3 py-12", className), children: [
|
|
1603
|
+
Icon && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(Icon, { className: "h-12 w-12 text-foreground-subtle", "aria-hidden": "true" }),
|
|
1604
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex flex-col items-center gap-1 text-center", children: [
|
|
1605
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("p", { className: "text-foreground-muted text-sm font-medium", children: title }),
|
|
1606
|
+
description && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("p", { className: "text-foreground-subtle text-xs max-w-xs", children: description })
|
|
1436
1607
|
] }),
|
|
1437
|
-
action && /* @__PURE__ */ (0,
|
|
1608
|
+
action && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "mt-1", children: action })
|
|
1438
1609
|
] });
|
|
1439
1610
|
}
|
|
1440
1611
|
|
|
1441
1612
|
// src/composites/confirm-dialog.tsx
|
|
1442
|
-
var
|
|
1613
|
+
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
1443
1614
|
function ConfirmDialog({
|
|
1444
1615
|
title,
|
|
1445
1616
|
message,
|
|
@@ -1451,14 +1622,14 @@ function ConfirmDialog({
|
|
|
1451
1622
|
open,
|
|
1452
1623
|
onOpenChange
|
|
1453
1624
|
}) {
|
|
1454
|
-
return /* @__PURE__ */ (0,
|
|
1455
|
-
/* @__PURE__ */ (0,
|
|
1456
|
-
/* @__PURE__ */ (0,
|
|
1457
|
-
/* @__PURE__ */ (0,
|
|
1625
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Dialog, { open, onOpenChange, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(DialogContent, { children: [
|
|
1626
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(DialogHeader, { children: [
|
|
1627
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(DialogTitle, { children: title }),
|
|
1628
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(DialogDescription, { children: message })
|
|
1458
1629
|
] }),
|
|
1459
|
-
/* @__PURE__ */ (0,
|
|
1460
|
-
/* @__PURE__ */ (0,
|
|
1461
|
-
/* @__PURE__ */ (0,
|
|
1630
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(DialogFooter, { children: [
|
|
1631
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Button, { variant: "ghost", onClick: onCancel, children: cancelLabel }),
|
|
1632
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
1462
1633
|
Button,
|
|
1463
1634
|
{
|
|
1464
1635
|
variant: variant === "danger" ? "danger" : "primary",
|
|
@@ -1471,13 +1642,13 @@ function ConfirmDialog({
|
|
|
1471
1642
|
}
|
|
1472
1643
|
|
|
1473
1644
|
// src/composites/stat-card.tsx
|
|
1474
|
-
var
|
|
1475
|
-
var
|
|
1645
|
+
var import_lucide_react6 = require("lucide-react");
|
|
1646
|
+
var import_jsx_runtime29 = require("react/jsx-runtime");
|
|
1476
1647
|
function StatCard({ value, label, trend, className }) {
|
|
1477
|
-
return /* @__PURE__ */ (0,
|
|
1478
|
-
/* @__PURE__ */ (0,
|
|
1479
|
-
/* @__PURE__ */ (0,
|
|
1480
|
-
trend && /* @__PURE__ */ (0,
|
|
1648
|
+
return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(Card, { className: cn("flex flex-col gap-1", className), children: [
|
|
1649
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex items-baseline gap-2", children: [
|
|
1650
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "text-2xl font-semibold text-foreground", children: value }),
|
|
1651
|
+
trend && /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
|
|
1481
1652
|
"span",
|
|
1482
1653
|
{
|
|
1483
1654
|
className: cn(
|
|
@@ -1485,27 +1656,27 @@ function StatCard({ value, label, trend, className }) {
|
|
|
1485
1656
|
trend.direction === "up" ? "text-success" : "text-danger"
|
|
1486
1657
|
),
|
|
1487
1658
|
children: [
|
|
1488
|
-
trend.direction === "up" ? /* @__PURE__ */ (0,
|
|
1659
|
+
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
1660
|
trend.value,
|
|
1490
1661
|
"%"
|
|
1491
1662
|
]
|
|
1492
1663
|
}
|
|
1493
1664
|
)
|
|
1494
1665
|
] }),
|
|
1495
|
-
/* @__PURE__ */ (0,
|
|
1666
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "text-xs text-foreground-muted", children: label })
|
|
1496
1667
|
] });
|
|
1497
1668
|
}
|
|
1498
1669
|
|
|
1499
1670
|
// src/composites/key-value-list.tsx
|
|
1500
|
-
var
|
|
1671
|
+
var import_jsx_runtime30 = require("react/jsx-runtime");
|
|
1501
1672
|
function KeyValueList({ items, className }) {
|
|
1502
|
-
return /* @__PURE__ */ (0,
|
|
1673
|
+
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
1674
|
"div",
|
|
1504
1675
|
{
|
|
1505
1676
|
className: "flex items-center h-7",
|
|
1506
1677
|
children: [
|
|
1507
|
-
/* @__PURE__ */ (0,
|
|
1508
|
-
/* @__PURE__ */ (0,
|
|
1678
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("dt", { className: "text-foreground-subtle text-xs w-1/3 shrink-0", children: item.key }),
|
|
1679
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("dd", { className: "text-foreground text-xs", children: item.value })
|
|
1509
1680
|
]
|
|
1510
1681
|
},
|
|
1511
1682
|
item.key
|
|
@@ -1513,23 +1684,23 @@ function KeyValueList({ items, className }) {
|
|
|
1513
1684
|
}
|
|
1514
1685
|
|
|
1515
1686
|
// src/composites/code-block.tsx
|
|
1516
|
-
var
|
|
1517
|
-
var
|
|
1518
|
-
var
|
|
1687
|
+
var import_react24 = require("react");
|
|
1688
|
+
var import_lucide_react7 = require("lucide-react");
|
|
1689
|
+
var import_jsx_runtime31 = require("react/jsx-runtime");
|
|
1519
1690
|
function CodeBlock({ children, maxHeight = 300, className }) {
|
|
1520
|
-
const [copied, setCopied] = (0,
|
|
1521
|
-
const handleCopy = (0,
|
|
1691
|
+
const [copied, setCopied] = (0, import_react24.useState)(false);
|
|
1692
|
+
const handleCopy = (0, import_react24.useCallback)(() => {
|
|
1522
1693
|
navigator.clipboard.writeText(children).then(() => {
|
|
1523
1694
|
setCopied(true);
|
|
1524
1695
|
setTimeout(() => setCopied(false), 2e3);
|
|
1525
1696
|
});
|
|
1526
1697
|
}, [children]);
|
|
1527
|
-
return /* @__PURE__ */ (0,
|
|
1528
|
-
/* @__PURE__ */ (0,
|
|
1529
|
-
/* @__PURE__ */ (0,
|
|
1698
|
+
return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: cn("relative group", className), children: [
|
|
1699
|
+
/* @__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 }) }) }),
|
|
1700
|
+
/* @__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
1701
|
IconButton,
|
|
1531
1702
|
{
|
|
1532
|
-
icon: copied ?
|
|
1703
|
+
icon: copied ? import_lucide_react7.Check : import_lucide_react7.Copy,
|
|
1533
1704
|
"aria-label": "Copy code",
|
|
1534
1705
|
variant: "ghost",
|
|
1535
1706
|
size: "sm",
|
|
@@ -1540,28 +1711,95 @@ function CodeBlock({ children, maxHeight = 300, className }) {
|
|
|
1540
1711
|
}
|
|
1541
1712
|
|
|
1542
1713
|
// src/composites/filter-bar.tsx
|
|
1543
|
-
var
|
|
1544
|
-
var
|
|
1714
|
+
var import_react25 = require("react");
|
|
1715
|
+
var import_lucide_react8 = require("lucide-react");
|
|
1716
|
+
var import_jsx_runtime32 = require("react/jsx-runtime");
|
|
1545
1717
|
function FilterBar({ filters, values, onChange, className }) {
|
|
1718
|
+
const isMobile = useIsMobile();
|
|
1719
|
+
const [sheetOpen, setSheetOpen] = (0, import_react25.useState)(false);
|
|
1546
1720
|
const handleChange = (key, value) => {
|
|
1547
1721
|
onChange({ ...values, [key]: value });
|
|
1548
1722
|
};
|
|
1549
|
-
|
|
1723
|
+
const activeCount = Object.values(values).filter((v) => v !== void 0 && v !== "").length;
|
|
1724
|
+
if (isMobile) {
|
|
1725
|
+
const searchFilter = filters.find((f) => f.type === "search");
|
|
1726
|
+
const hasNonSearchFilters = filters.some((f) => f.type !== "search");
|
|
1727
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: cn("flex items-center gap-2", className), children: [
|
|
1728
|
+
searchFilter && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
1729
|
+
Input,
|
|
1730
|
+
{
|
|
1731
|
+
placeholder: searchFilter.placeholder ?? "Search...",
|
|
1732
|
+
value: values[searchFilter.key] ?? "",
|
|
1733
|
+
onChange: (e) => handleChange(searchFilter.key, e.target.value),
|
|
1734
|
+
leftSlot: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_lucide_react8.Search, { className: "h-3 w-3 text-foreground-subtle" }),
|
|
1735
|
+
className: "flex-1"
|
|
1736
|
+
}
|
|
1737
|
+
),
|
|
1738
|
+
hasNonSearchFilters && /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_jsx_runtime32.Fragment, { children: [
|
|
1739
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
|
|
1740
|
+
"button",
|
|
1741
|
+
{
|
|
1742
|
+
onClick: () => setSheetOpen(true),
|
|
1743
|
+
className: "flex items-center gap-1.5 rounded-md border border-border px-2.5 py-1.5 text-xs text-foreground-muted hover:bg-surface-hover transition-colors shrink-0",
|
|
1744
|
+
children: [
|
|
1745
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_lucide_react8.SlidersHorizontal, { className: "h-3.5 w-3.5" }),
|
|
1746
|
+
"Filters",
|
|
1747
|
+
activeCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Badge, { variant: "info", className: "ml-1 text-[10px] px-1 py-0", children: activeCount })
|
|
1748
|
+
]
|
|
1749
|
+
}
|
|
1750
|
+
),
|
|
1751
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(BottomSheet, { open: sheetOpen, onClose: () => setSheetOpen(false), title: "Filters", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "flex flex-col gap-3", children: filters.filter((f) => f.type !== "search").map((filter) => {
|
|
1752
|
+
switch (filter.type) {
|
|
1753
|
+
case "select":
|
|
1754
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { children: [
|
|
1755
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("label", { className: "text-xs text-foreground-muted mb-1 block", children: filter.label }),
|
|
1756
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
1757
|
+
Select,
|
|
1758
|
+
{
|
|
1759
|
+
options: filter.options,
|
|
1760
|
+
value: values[filter.key] ?? "",
|
|
1761
|
+
onChange: (e) => handleChange(filter.key, e.target.value),
|
|
1762
|
+
className: "w-full"
|
|
1763
|
+
}
|
|
1764
|
+
)
|
|
1765
|
+
] }, filter.key);
|
|
1766
|
+
case "badge-toggle":
|
|
1767
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "flex items-center gap-1 flex-wrap", children: filter.options.map((option) => {
|
|
1768
|
+
const currentValue = values[filter.key];
|
|
1769
|
+
const isActive = currentValue === option.value;
|
|
1770
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
1771
|
+
"button",
|
|
1772
|
+
{
|
|
1773
|
+
type: "button",
|
|
1774
|
+
onClick: () => handleChange(filter.key, isActive ? void 0 : option.value),
|
|
1775
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Badge, { variant: isActive ? "info" : "default", className: "cursor-pointer", children: option.label })
|
|
1776
|
+
},
|
|
1777
|
+
option.value
|
|
1778
|
+
);
|
|
1779
|
+
}) }, filter.key);
|
|
1780
|
+
default:
|
|
1781
|
+
return null;
|
|
1782
|
+
}
|
|
1783
|
+
}) }) })
|
|
1784
|
+
] })
|
|
1785
|
+
] });
|
|
1786
|
+
}
|
|
1787
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: cn("flex items-center gap-2 flex-wrap", className), children: filters.map((filter) => {
|
|
1550
1788
|
switch (filter.type) {
|
|
1551
1789
|
case "search":
|
|
1552
|
-
return /* @__PURE__ */ (0,
|
|
1790
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
1553
1791
|
Input,
|
|
1554
1792
|
{
|
|
1555
1793
|
placeholder: filter.placeholder ?? "Search...",
|
|
1556
1794
|
value: values[filter.key] ?? "",
|
|
1557
1795
|
onChange: (e) => handleChange(filter.key, e.target.value),
|
|
1558
|
-
leftSlot: /* @__PURE__ */ (0,
|
|
1796
|
+
leftSlot: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_lucide_react8.Search, { className: "h-3 w-3 text-foreground-subtle" }),
|
|
1559
1797
|
className: "w-48"
|
|
1560
1798
|
},
|
|
1561
1799
|
filter.key
|
|
1562
1800
|
);
|
|
1563
1801
|
case "select":
|
|
1564
|
-
return /* @__PURE__ */ (0,
|
|
1802
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
1565
1803
|
Select,
|
|
1566
1804
|
{
|
|
1567
1805
|
options: filter.options,
|
|
@@ -1572,25 +1810,15 @@ function FilterBar({ filters, values, onChange, className }) {
|
|
|
1572
1810
|
filter.key
|
|
1573
1811
|
);
|
|
1574
1812
|
case "badge-toggle":
|
|
1575
|
-
return /* @__PURE__ */ (0,
|
|
1813
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "flex items-center gap-1", children: filter.options.map((option) => {
|
|
1576
1814
|
const currentValue = values[filter.key];
|
|
1577
1815
|
const isActive = currentValue === option.value;
|
|
1578
|
-
return /* @__PURE__ */ (0,
|
|
1816
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
1579
1817
|
"button",
|
|
1580
1818
|
{
|
|
1581
1819
|
type: "button",
|
|
1582
|
-
onClick: () => handleChange(
|
|
1583
|
-
|
|
1584
|
-
isActive ? void 0 : option.value
|
|
1585
|
-
),
|
|
1586
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
1587
|
-
Badge,
|
|
1588
|
-
{
|
|
1589
|
-
variant: isActive ? "info" : "default",
|
|
1590
|
-
className: "cursor-pointer",
|
|
1591
|
-
children: option.label
|
|
1592
|
-
}
|
|
1593
|
-
)
|
|
1820
|
+
onClick: () => handleChange(filter.key, isActive ? void 0 : option.value),
|
|
1821
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Badge, { variant: isActive ? "info" : "default", className: "cursor-pointer", children: option.label })
|
|
1594
1822
|
},
|
|
1595
1823
|
option.value
|
|
1596
1824
|
);
|
|
@@ -1602,7 +1830,7 @@ function FilterBar({ filters, values, onChange, className }) {
|
|
|
1602
1830
|
}
|
|
1603
1831
|
|
|
1604
1832
|
// src/composites/app-shell/sidebar-item.tsx
|
|
1605
|
-
var
|
|
1833
|
+
var import_jsx_runtime33 = require("react/jsx-runtime");
|
|
1606
1834
|
function SidebarItem({
|
|
1607
1835
|
label,
|
|
1608
1836
|
icon: Icon,
|
|
@@ -1611,7 +1839,7 @@ function SidebarItem({
|
|
|
1611
1839
|
active = false,
|
|
1612
1840
|
className
|
|
1613
1841
|
}) {
|
|
1614
|
-
return /* @__PURE__ */ (0,
|
|
1842
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
|
|
1615
1843
|
"a",
|
|
1616
1844
|
{
|
|
1617
1845
|
href,
|
|
@@ -1621,33 +1849,33 @@ function SidebarItem({
|
|
|
1621
1849
|
className
|
|
1622
1850
|
),
|
|
1623
1851
|
children: [
|
|
1624
|
-
/* @__PURE__ */ (0,
|
|
1625
|
-
/* @__PURE__ */ (0,
|
|
1626
|
-
badge !== void 0 && /* @__PURE__ */ (0,
|
|
1852
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Icon, { className: "h-3.5 w-3.5 shrink-0" }),
|
|
1853
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "truncate flex-1", children: label }),
|
|
1854
|
+
badge !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Badge, { className: "ml-auto text-[10px] px-1.5 py-0", children: badge })
|
|
1627
1855
|
]
|
|
1628
1856
|
}
|
|
1629
1857
|
);
|
|
1630
1858
|
}
|
|
1631
1859
|
|
|
1632
1860
|
// src/composites/app-shell/sidebar.tsx
|
|
1633
|
-
var
|
|
1634
|
-
function Sidebar({ logo, sections, footer, className }) {
|
|
1635
|
-
return /* @__PURE__ */ (0,
|
|
1861
|
+
var import_jsx_runtime34 = require("react/jsx-runtime");
|
|
1862
|
+
function Sidebar({ logo, sections, footer, onNavigate, className }) {
|
|
1863
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
|
|
1636
1864
|
"nav",
|
|
1637
1865
|
{
|
|
1638
1866
|
className: cn(
|
|
1639
|
-
"
|
|
1867
|
+
"bg-surface border-r border-border h-full flex flex-col",
|
|
1640
1868
|
className
|
|
1641
1869
|
),
|
|
1642
1870
|
children: [
|
|
1643
|
-
logo && /* @__PURE__ */ (0,
|
|
1644
|
-
/* @__PURE__ */ (0,
|
|
1645
|
-
section.label && /* @__PURE__ */ (0,
|
|
1646
|
-
/* @__PURE__ */ (0,
|
|
1871
|
+
logo && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "px-3 py-2 shrink-0", children: logo }),
|
|
1872
|
+
/* @__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: [
|
|
1873
|
+
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 }),
|
|
1874
|
+
/* @__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
1875
|
] }, sectionIndex)) }),
|
|
1648
|
-
footer && footer.length > 0 && /* @__PURE__ */ (0,
|
|
1649
|
-
/* @__PURE__ */ (0,
|
|
1650
|
-
/* @__PURE__ */ (0,
|
|
1876
|
+
footer && footer.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "shrink-0 px-1 pb-1", children: [
|
|
1877
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(Separator, { className: "mb-1" }),
|
|
1878
|
+
/* @__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
1879
|
] })
|
|
1652
1880
|
]
|
|
1653
1881
|
}
|
|
@@ -1655,54 +1883,78 @@ function Sidebar({ logo, sections, footer, className }) {
|
|
|
1655
1883
|
}
|
|
1656
1884
|
|
|
1657
1885
|
// src/composites/app-shell/app-shell.tsx
|
|
1658
|
-
var
|
|
1659
|
-
var
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1886
|
+
var import_react26 = require("react");
|
|
1887
|
+
var import_lucide_react9 = require("lucide-react");
|
|
1888
|
+
var import_jsx_runtime35 = require("react/jsx-runtime");
|
|
1889
|
+
function AppShell({ sidebar, header, mobileLogo, mobileActions, children, className }) {
|
|
1890
|
+
const isMobile = useIsMobile();
|
|
1891
|
+
const [drawerOpen, setDrawerOpen] = (0, import_react26.useState)(false);
|
|
1892
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: cn("flex h-screen", className), children: [
|
|
1893
|
+
!isMobile && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(Sidebar, { ...sidebar, className: cn("w-44", sidebar.className) }),
|
|
1894
|
+
isMobile && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(MobileDrawer, { open: drawerOpen, onClose: () => setDrawerOpen(false), width: "w-64", children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
1895
|
+
Sidebar,
|
|
1896
|
+
{
|
|
1897
|
+
...sidebar,
|
|
1898
|
+
onNavigate: () => setDrawerOpen(false),
|
|
1899
|
+
className: "w-full border-r-0"
|
|
1900
|
+
}
|
|
1901
|
+
) }),
|
|
1902
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "flex flex-1 flex-col min-w-0", children: [
|
|
1903
|
+
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: [
|
|
1904
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
1905
|
+
"button",
|
|
1906
|
+
{
|
|
1907
|
+
onClick: () => setDrawerOpen(true),
|
|
1908
|
+
className: "p-1.5 -ml-1.5 rounded-md hover:bg-surface-hover text-foreground-muted transition-colors",
|
|
1909
|
+
"aria-label": "Open menu",
|
|
1910
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_lucide_react9.Menu, { className: "h-5 w-5" })
|
|
1911
|
+
}
|
|
1912
|
+
),
|
|
1913
|
+
mobileLogo && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "flex-1 flex justify-center", children: mobileLogo }),
|
|
1914
|
+
mobileActions && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "shrink-0", children: mobileActions })
|
|
1915
|
+
] }),
|
|
1916
|
+
!isMobile && header && /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("header", { className: "flex items-center h-10 border-b border-border px-4 shrink-0", children: [
|
|
1917
|
+
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
1918
|
const isLast = index === header.breadcrumbs.length - 1;
|
|
1667
|
-
return /* @__PURE__ */ (0,
|
|
1668
|
-
index > 0 && /* @__PURE__ */ (0,
|
|
1669
|
-
crumb.href && !isLast ? /* @__PURE__ */ (0,
|
|
1919
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("span", { className: "flex items-center gap-1", children: [
|
|
1920
|
+
index > 0 && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_lucide_react9.ChevronRight, { className: "h-3 w-3 text-foreground-subtle shrink-0" }),
|
|
1921
|
+
crumb.href && !isLast ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
1670
1922
|
"a",
|
|
1671
1923
|
{
|
|
1672
1924
|
href: crumb.href,
|
|
1673
1925
|
className: "text-foreground-subtle hover:text-foreground transition-colors truncate",
|
|
1674
1926
|
children: crumb.label
|
|
1675
1927
|
}
|
|
1676
|
-
) : /* @__PURE__ */ (0,
|
|
1928
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "text-foreground truncate", children: crumb.label })
|
|
1677
1929
|
] }, index);
|
|
1678
1930
|
}) }),
|
|
1679
|
-
header.actions && /* @__PURE__ */ (0,
|
|
1931
|
+
header.actions && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "flex items-center gap-2 ml-auto shrink-0", children: header.actions })
|
|
1680
1932
|
] }),
|
|
1681
|
-
/* @__PURE__ */ (0,
|
|
1933
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("main", { className: "flex-1 overflow-auto p-4", children })
|
|
1682
1934
|
] })
|
|
1683
1935
|
] });
|
|
1684
1936
|
}
|
|
1685
1937
|
|
|
1686
1938
|
// src/composites/data-table/data-table.tsx
|
|
1687
|
-
var
|
|
1939
|
+
var import_react27 = require("react");
|
|
1688
1940
|
var import_react_table = require("@tanstack/react-table");
|
|
1689
1941
|
|
|
1690
1942
|
// src/composites/data-table/data-table-header.tsx
|
|
1691
|
-
var
|
|
1692
|
-
var
|
|
1943
|
+
var import_lucide_react10 = require("lucide-react");
|
|
1944
|
+
var import_jsx_runtime36 = require("react/jsx-runtime");
|
|
1693
1945
|
function DataTableHeader({
|
|
1694
1946
|
headerGroups,
|
|
1695
1947
|
onSortingChange,
|
|
1696
1948
|
stickyHeader,
|
|
1697
1949
|
flexRender: render
|
|
1698
1950
|
}) {
|
|
1699
|
-
return /* @__PURE__ */ (0,
|
|
1951
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
1700
1952
|
"thead",
|
|
1701
1953
|
{
|
|
1702
1954
|
className: cn(
|
|
1703
1955
|
stickyHeader && "sticky top-0 z-10 bg-background"
|
|
1704
1956
|
),
|
|
1705
|
-
children: headerGroups.map((headerGroup) => /* @__PURE__ */ (0,
|
|
1957
|
+
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
1958
|
HeaderCell,
|
|
1707
1959
|
{
|
|
1708
1960
|
header,
|
|
@@ -1716,8 +1968,8 @@ function DataTableHeader({
|
|
|
1716
1968
|
}
|
|
1717
1969
|
function HeaderCell({ header, sortable, flexRender: render }) {
|
|
1718
1970
|
const sorted = header.column.getIsSorted();
|
|
1719
|
-
const SortIcon = sorted === "asc" ?
|
|
1720
|
-
return /* @__PURE__ */ (0,
|
|
1971
|
+
const SortIcon = sorted === "asc" ? import_lucide_react10.ArrowUp : sorted === "desc" ? import_lucide_react10.ArrowDown : import_lucide_react10.ArrowUpDown;
|
|
1972
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
1721
1973
|
"th",
|
|
1722
1974
|
{
|
|
1723
1975
|
className: cn(
|
|
@@ -1725,17 +1977,17 @@ function HeaderCell({ header, sortable, flexRender: render }) {
|
|
|
1725
1977
|
sortable && "cursor-pointer select-none"
|
|
1726
1978
|
),
|
|
1727
1979
|
onClick: sortable ? header.column.getToggleSortingHandler() : void 0,
|
|
1728
|
-
children: /* @__PURE__ */ (0,
|
|
1980
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("span", { className: "inline-flex items-center gap-1", children: [
|
|
1729
1981
|
header.isPlaceholder ? null : render(header.column.columnDef.header, header.getContext()),
|
|
1730
|
-
sortable && /* @__PURE__ */ (0,
|
|
1982
|
+
sortable && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(SortIcon, { className: "h-3 w-3" })
|
|
1731
1983
|
] })
|
|
1732
1984
|
}
|
|
1733
1985
|
);
|
|
1734
1986
|
}
|
|
1735
1987
|
|
|
1736
1988
|
// src/composites/data-table/data-table-row.tsx
|
|
1737
|
-
var
|
|
1738
|
-
var
|
|
1989
|
+
var import_lucide_react11 = require("lucide-react");
|
|
1990
|
+
var import_jsx_runtime37 = require("react/jsx-runtime");
|
|
1739
1991
|
function DataTableRow({
|
|
1740
1992
|
row,
|
|
1741
1993
|
onRowClick,
|
|
@@ -1743,7 +1995,7 @@ function DataTableRow({
|
|
|
1743
1995
|
flexRender: render
|
|
1744
1996
|
}) {
|
|
1745
1997
|
const actions = rowActions ? rowActions(row.original) : [];
|
|
1746
|
-
return /* @__PURE__ */ (0,
|
|
1998
|
+
return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(
|
|
1747
1999
|
"tr",
|
|
1748
2000
|
{
|
|
1749
2001
|
className: cn(
|
|
@@ -1753,17 +2005,17 @@ function DataTableRow({
|
|
|
1753
2005
|
),
|
|
1754
2006
|
onClick: onRowClick ? () => onRowClick(row.original) : void 0,
|
|
1755
2007
|
children: [
|
|
1756
|
-
row.getVisibleCells().map((cell) => /* @__PURE__ */ (0,
|
|
1757
|
-
actions.length > 0 && /* @__PURE__ */ (0,
|
|
1758
|
-
/* @__PURE__ */ (0,
|
|
2008
|
+
row.getVisibleCells().map((cell) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(DataTableCell, { cell, flexRender: render }, cell.id)),
|
|
2009
|
+
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: [
|
|
2010
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
1759
2011
|
DropdownTrigger,
|
|
1760
2012
|
{
|
|
1761
2013
|
className: "p-0.5 rounded hover:bg-surface-hover",
|
|
1762
2014
|
onClick: (e) => e.stopPropagation(),
|
|
1763
|
-
children: /* @__PURE__ */ (0,
|
|
2015
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_lucide_react11.MoreHorizontal, { className: "h-3.5 w-3.5 text-foreground-muted" })
|
|
1764
2016
|
}
|
|
1765
2017
|
),
|
|
1766
|
-
/* @__PURE__ */ (0,
|
|
2018
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(DropdownContent, { className: "right-0 left-auto", children: actions.map((action) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
1767
2019
|
DropdownItem,
|
|
1768
2020
|
{
|
|
1769
2021
|
icon: action.icon,
|
|
@@ -1782,12 +2034,12 @@ function DataTableRow({
|
|
|
1782
2034
|
);
|
|
1783
2035
|
}
|
|
1784
2036
|
function DataTableCell({ cell, flexRender: render }) {
|
|
1785
|
-
return /* @__PURE__ */ (0,
|
|
2037
|
+
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
2038
|
}
|
|
1787
2039
|
|
|
1788
2040
|
// src/composites/data-table/data-table-pagination.tsx
|
|
1789
|
-
var
|
|
1790
|
-
var
|
|
2041
|
+
var import_lucide_react12 = require("lucide-react");
|
|
2042
|
+
var import_jsx_runtime38 = require("react/jsx-runtime");
|
|
1791
2043
|
var PAGE_SIZE_OPTIONS = [
|
|
1792
2044
|
{ value: "10", label: "10" },
|
|
1793
2045
|
{ value: "25", label: "25" },
|
|
@@ -1802,10 +2054,10 @@ function DataTablePagination({
|
|
|
1802
2054
|
}) {
|
|
1803
2055
|
const totalPages = Math.max(1, Math.ceil(total / pageSize));
|
|
1804
2056
|
const currentPage = page + 1;
|
|
1805
|
-
return /* @__PURE__ */ (0,
|
|
1806
|
-
/* @__PURE__ */ (0,
|
|
1807
|
-
/* @__PURE__ */ (0,
|
|
1808
|
-
/* @__PURE__ */ (0,
|
|
2057
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "flex items-center justify-between px-2 py-2 text-xs text-foreground-muted", children: [
|
|
2058
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
2059
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { children: "Rows per page" }),
|
|
2060
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "w-16", children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
1809
2061
|
Select,
|
|
1810
2062
|
{
|
|
1811
2063
|
options: PAGE_SIZE_OPTIONS,
|
|
@@ -1817,17 +2069,17 @@ function DataTablePagination({
|
|
|
1817
2069
|
}
|
|
1818
2070
|
) })
|
|
1819
2071
|
] }),
|
|
1820
|
-
/* @__PURE__ */ (0,
|
|
1821
|
-
/* @__PURE__ */ (0,
|
|
2072
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
2073
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("span", { children: [
|
|
1822
2074
|
"Page ",
|
|
1823
2075
|
currentPage,
|
|
1824
2076
|
" of ",
|
|
1825
2077
|
totalPages
|
|
1826
2078
|
] }),
|
|
1827
|
-
/* @__PURE__ */ (0,
|
|
2079
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
1828
2080
|
IconButton,
|
|
1829
2081
|
{
|
|
1830
|
-
icon:
|
|
2082
|
+
icon: import_lucide_react12.ChevronLeft,
|
|
1831
2083
|
"aria-label": "Previous page",
|
|
1832
2084
|
variant: "ghost",
|
|
1833
2085
|
size: "sm",
|
|
@@ -1835,10 +2087,10 @@ function DataTablePagination({
|
|
|
1835
2087
|
onClick: () => onPaginationChange?.({ pageIndex: page - 1, pageSize })
|
|
1836
2088
|
}
|
|
1837
2089
|
),
|
|
1838
|
-
/* @__PURE__ */ (0,
|
|
2090
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
1839
2091
|
IconButton,
|
|
1840
2092
|
{
|
|
1841
|
-
icon:
|
|
2093
|
+
icon: import_lucide_react12.ChevronRight,
|
|
1842
2094
|
"aria-label": "Next page",
|
|
1843
2095
|
variant: "ghost",
|
|
1844
2096
|
size: "sm",
|
|
@@ -1851,7 +2103,7 @@ function DataTablePagination({
|
|
|
1851
2103
|
}
|
|
1852
2104
|
|
|
1853
2105
|
// src/composites/data-table/data-table.tsx
|
|
1854
|
-
var
|
|
2106
|
+
var import_jsx_runtime39 = require("react/jsx-runtime");
|
|
1855
2107
|
function DataTable({
|
|
1856
2108
|
data,
|
|
1857
2109
|
columns: userColumns,
|
|
@@ -1868,13 +2120,14 @@ function DataTable({
|
|
|
1868
2120
|
selectable = false,
|
|
1869
2121
|
compact = true,
|
|
1870
2122
|
stickyHeader = false,
|
|
1871
|
-
className
|
|
2123
|
+
className,
|
|
2124
|
+
mobileMode = "scroll"
|
|
1872
2125
|
}) {
|
|
1873
|
-
const columns = (0,
|
|
2126
|
+
const columns = (0, import_react27.useMemo)(() => {
|
|
1874
2127
|
if (!selectable) return userColumns;
|
|
1875
2128
|
const selectColumn = {
|
|
1876
2129
|
id: "__select",
|
|
1877
|
-
header: ({ table: table2 }) => /* @__PURE__ */ (0,
|
|
2130
|
+
header: ({ table: table2 }) => /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
1878
2131
|
Checkbox,
|
|
1879
2132
|
{
|
|
1880
2133
|
checked: table2.getIsAllPageRowsSelected(),
|
|
@@ -1882,7 +2135,7 @@ function DataTable({
|
|
|
1882
2135
|
"aria-label": "Select all"
|
|
1883
2136
|
}
|
|
1884
2137
|
),
|
|
1885
|
-
cell: ({ row }) => /* @__PURE__ */ (0,
|
|
2138
|
+
cell: ({ row }) => /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
1886
2139
|
Checkbox,
|
|
1887
2140
|
{
|
|
1888
2141
|
checked: row.getIsSelected(),
|
|
@@ -1920,9 +2173,71 @@ function DataTable({
|
|
|
1920
2173
|
pageCount: pagination ? Math.ceil(pagination.total / pagination.pageSize) : void 0
|
|
1921
2174
|
});
|
|
1922
2175
|
const hasActions = !!rowActions;
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
2176
|
+
const isMobile = useIsMobile();
|
|
2177
|
+
const showCards = isMobile && mobileMode === "cards";
|
|
2178
|
+
if (showCards) {
|
|
2179
|
+
const rows = table.getRowModel().rows;
|
|
2180
|
+
if (loading) {
|
|
2181
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: cn("space-y-2", className), children: Array.from({ length: 3 }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "rounded-lg border border-border bg-surface p-3 space-y-2", children: [
|
|
2182
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Skeleton, { className: "h-3 w-3/4" }),
|
|
2183
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Skeleton, { className: "h-3 w-1/2" }),
|
|
2184
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Skeleton, { className: "h-3 w-2/3" })
|
|
2185
|
+
] }, i)) });
|
|
2186
|
+
}
|
|
2187
|
+
if (rows.length === 0) {
|
|
2188
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: cn("text-center py-8 text-xs text-foreground-muted", className), children: emptyState ?? "No data" });
|
|
2189
|
+
}
|
|
2190
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: cn("space-y-2", className), children: [
|
|
2191
|
+
rows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
|
|
2192
|
+
"div",
|
|
2193
|
+
{
|
|
2194
|
+
className: cn(
|
|
2195
|
+
"rounded-lg border border-border bg-surface p-3 space-y-1.5",
|
|
2196
|
+
onRowClick && "cursor-pointer hover:bg-surface-hover transition-colors"
|
|
2197
|
+
),
|
|
2198
|
+
onClick: onRowClick ? () => onRowClick(row.original) : void 0,
|
|
2199
|
+
children: [
|
|
2200
|
+
row.getVisibleCells().filter((cell) => cell.column.id !== "__select").map((cell) => {
|
|
2201
|
+
const header = cell.column.columnDef.header;
|
|
2202
|
+
const label = typeof header === "string" ? header : cell.column.id;
|
|
2203
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "flex items-baseline justify-between gap-2 text-xs", children: [
|
|
2204
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: "text-foreground-muted shrink-0", children: label }),
|
|
2205
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: "text-foreground text-right truncate", children: (0, import_react_table.flexRender)(cell.column.columnDef.cell, cell.getContext()) })
|
|
2206
|
+
] }, cell.id);
|
|
2207
|
+
}),
|
|
2208
|
+
rowActions && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "flex items-center gap-1 pt-1 border-t border-border mt-1.5", children: rowActions(row.original).map((action, i) => /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
2209
|
+
"button",
|
|
2210
|
+
{
|
|
2211
|
+
onClick: (e) => {
|
|
2212
|
+
e.stopPropagation();
|
|
2213
|
+
action.onClick();
|
|
2214
|
+
},
|
|
2215
|
+
className: cn(
|
|
2216
|
+
"text-[11px] px-2 py-1 rounded-md transition-colors",
|
|
2217
|
+
action.variant === "danger" ? "text-danger hover:bg-danger/10" : "text-foreground-muted hover:bg-surface-hover"
|
|
2218
|
+
),
|
|
2219
|
+
children: action.label
|
|
2220
|
+
},
|
|
2221
|
+
i
|
|
2222
|
+
)) })
|
|
2223
|
+
]
|
|
2224
|
+
},
|
|
2225
|
+
row.id
|
|
2226
|
+
)),
|
|
2227
|
+
pagination && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
2228
|
+
DataTablePagination,
|
|
2229
|
+
{
|
|
2230
|
+
page: pagination.page,
|
|
2231
|
+
pageSize: pagination.pageSize,
|
|
2232
|
+
total: pagination.total,
|
|
2233
|
+
onPaginationChange
|
|
2234
|
+
}
|
|
2235
|
+
)
|
|
2236
|
+
] });
|
|
2237
|
+
}
|
|
2238
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: cn("overflow-x-auto", className), children: [
|
|
2239
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("table", { className: "w-full border-collapse", children: [
|
|
2240
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
1926
2241
|
DataTableHeader,
|
|
1927
2242
|
{
|
|
1928
2243
|
headerGroups: table.getHeaderGroups(),
|
|
@@ -1931,14 +2246,14 @@ function DataTable({
|
|
|
1931
2246
|
flexRender: import_react_table.flexRender
|
|
1932
2247
|
}
|
|
1933
2248
|
),
|
|
1934
|
-
/* @__PURE__ */ (0,
|
|
2249
|
+
/* @__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
2250
|
"td",
|
|
1936
2251
|
{
|
|
1937
2252
|
colSpan: columns.length + (hasActions ? 1 : 0),
|
|
1938
2253
|
className: "text-center py-8 text-xs text-foreground-muted",
|
|
1939
2254
|
children: emptyState ?? "No data"
|
|
1940
2255
|
}
|
|
1941
|
-
) }) : table.getRowModel().rows.map((row) => /* @__PURE__ */ (0,
|
|
2256
|
+
) }) : table.getRowModel().rows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
1942
2257
|
DataTableRow,
|
|
1943
2258
|
{
|
|
1944
2259
|
row,
|
|
@@ -1949,7 +2264,7 @@ function DataTable({
|
|
|
1949
2264
|
row.id
|
|
1950
2265
|
)) })
|
|
1951
2266
|
] }),
|
|
1952
|
-
pagination && /* @__PURE__ */ (0,
|
|
2267
|
+
pagination && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
1953
2268
|
DataTablePagination,
|
|
1954
2269
|
{
|
|
1955
2270
|
page: pagination.page,
|
|
@@ -1961,11 +2276,11 @@ function DataTable({
|
|
|
1961
2276
|
] });
|
|
1962
2277
|
}
|
|
1963
2278
|
function LoadingRows({ colSpan, compact }) {
|
|
1964
|
-
return /* @__PURE__ */ (0,
|
|
2279
|
+
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
2280
|
}
|
|
1966
2281
|
|
|
1967
2282
|
// src/composites/device-card.tsx
|
|
1968
|
-
var
|
|
2283
|
+
var import_jsx_runtime40 = require("react/jsx-runtime");
|
|
1969
2284
|
var STATUS_COLORS = {
|
|
1970
2285
|
online: "bg-success",
|
|
1971
2286
|
offline: "bg-danger",
|
|
@@ -1984,7 +2299,7 @@ function DeviceCard({
|
|
|
1984
2299
|
className
|
|
1985
2300
|
}) {
|
|
1986
2301
|
const isOffline = status === "offline";
|
|
1987
|
-
return /* @__PURE__ */ (0,
|
|
2302
|
+
return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
|
|
1988
2303
|
"div",
|
|
1989
2304
|
{
|
|
1990
2305
|
onClick,
|
|
@@ -1996,18 +2311,18 @@ function DeviceCard({
|
|
|
1996
2311
|
className
|
|
1997
2312
|
),
|
|
1998
2313
|
children: [
|
|
1999
|
-
/* @__PURE__ */ (0,
|
|
2000
|
-
/* @__PURE__ */ (0,
|
|
2001
|
-
status && /* @__PURE__ */ (0,
|
|
2314
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "flex items-center justify-between mb-2", children: [
|
|
2315
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "text-sm font-medium truncate", children: title }),
|
|
2316
|
+
status && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: cn("h-2 w-2 rounded-full shrink-0", STATUS_COLORS[status]) })
|
|
2002
2317
|
] }),
|
|
2003
|
-
subtitle && /* @__PURE__ */ (0,
|
|
2004
|
-
badges && badges.length > 0 && /* @__PURE__ */ (0,
|
|
2318
|
+
subtitle && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "text-[11px] text-foreground-muted", children: subtitle }),
|
|
2319
|
+
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
2320
|
const cls = cn(
|
|
2006
2321
|
"rounded px-1.5 py-0.5 text-[10px] flex items-center gap-0.5",
|
|
2007
2322
|
selected ? "bg-primary/20" : "bg-surface-hover",
|
|
2008
2323
|
badge.onClick && "hover:opacity-80 transition-opacity cursor-pointer"
|
|
2009
2324
|
);
|
|
2010
|
-
return badge.onClick ? /* @__PURE__ */ (0,
|
|
2325
|
+
return badge.onClick ? /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
|
|
2011
2326
|
"button",
|
|
2012
2327
|
{
|
|
2013
2328
|
onClick: (e) => {
|
|
@@ -2021,12 +2336,12 @@ function DeviceCard({
|
|
|
2021
2336
|
]
|
|
2022
2337
|
},
|
|
2023
2338
|
i
|
|
2024
|
-
) : /* @__PURE__ */ (0,
|
|
2339
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("span", { className: cls, children: [
|
|
2025
2340
|
badge.icon,
|
|
2026
2341
|
badge.label
|
|
2027
2342
|
] }, i);
|
|
2028
2343
|
}) }),
|
|
2029
|
-
!isOffline && actions && actions.length > 0 && /* @__PURE__ */ (0,
|
|
2344
|
+
!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
2345
|
"button",
|
|
2031
2346
|
{
|
|
2032
2347
|
onClick: (e) => {
|
|
@@ -2040,21 +2355,21 @@ function DeviceCard({
|
|
|
2040
2355
|
},
|
|
2041
2356
|
i
|
|
2042
2357
|
)) }),
|
|
2043
|
-
isOffline && offlineAction && /* @__PURE__ */ (0,
|
|
2358
|
+
isOffline && offlineAction && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "mt-2", onClick: (e) => e.stopPropagation(), children: offlineAction })
|
|
2044
2359
|
]
|
|
2045
2360
|
}
|
|
2046
2361
|
);
|
|
2047
2362
|
}
|
|
2048
2363
|
|
|
2049
2364
|
// src/composites/device-grid.tsx
|
|
2050
|
-
var
|
|
2365
|
+
var import_jsx_runtime41 = require("react/jsx-runtime");
|
|
2051
2366
|
function DeviceGrid({
|
|
2052
2367
|
children,
|
|
2053
2368
|
minCardWidth = 220,
|
|
2054
2369
|
gap = 3,
|
|
2055
2370
|
className
|
|
2056
2371
|
}) {
|
|
2057
|
-
return /* @__PURE__ */ (0,
|
|
2372
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
2058
2373
|
"div",
|
|
2059
2374
|
{
|
|
2060
2375
|
className: cn(
|
|
@@ -2072,9 +2387,9 @@ function DeviceGrid({
|
|
|
2072
2387
|
}
|
|
2073
2388
|
|
|
2074
2389
|
// src/composites/pipeline-step.tsx
|
|
2075
|
-
var
|
|
2076
|
-
var
|
|
2077
|
-
var
|
|
2390
|
+
var import_react28 = require("react");
|
|
2391
|
+
var import_lucide_react13 = require("lucide-react");
|
|
2392
|
+
var import_jsx_runtime42 = require("react/jsx-runtime");
|
|
2078
2393
|
var ADDON_COLORS = {
|
|
2079
2394
|
"object-detection": "border-l-blue-500",
|
|
2080
2395
|
"motion-detection": "border-l-amber-500",
|
|
@@ -2150,7 +2465,7 @@ function PipelineStep({
|
|
|
2150
2465
|
onDelete,
|
|
2151
2466
|
readOnly = false
|
|
2152
2467
|
}) {
|
|
2153
|
-
const [expanded, setExpanded] = (0,
|
|
2468
|
+
const [expanded, setExpanded] = (0, import_react28.useState)(false);
|
|
2154
2469
|
const color = borderColor(step.addonId, step.slot);
|
|
2155
2470
|
const backends = backendsForRuntime(step.runtime, capabilities, schema);
|
|
2156
2471
|
const rtOptions = runtimeOptions(capabilities);
|
|
@@ -2173,7 +2488,7 @@ function PipelineStep({
|
|
|
2173
2488
|
if (e.target.closest(".step-config")) return;
|
|
2174
2489
|
setExpanded((v) => !v);
|
|
2175
2490
|
}
|
|
2176
|
-
return /* @__PURE__ */ (0,
|
|
2491
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className: "space-y-2", children: /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
|
|
2177
2492
|
"div",
|
|
2178
2493
|
{
|
|
2179
2494
|
className: cn(
|
|
@@ -2182,18 +2497,18 @@ function PipelineStep({
|
|
|
2182
2497
|
!step.enabled && "opacity-[0.45]"
|
|
2183
2498
|
),
|
|
2184
2499
|
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,
|
|
2500
|
+
/* @__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: [
|
|
2501
|
+
/* @__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" }) }),
|
|
2502
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "flex-1 min-w-0", children: [
|
|
2503
|
+
/* @__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 }),
|
|
2504
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "text-sm font-semibold text-foreground truncate block leading-tight", children: step.addonName }),
|
|
2505
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "flex items-center gap-1 mt-0.5 flex-wrap", children: [
|
|
2506
|
+
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)),
|
|
2507
|
+
step.inputClasses.length > 0 && step.outputClasses.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "text-foreground-subtle/40 text-[10px]", children: "\u2192" }),
|
|
2508
|
+
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
2509
|
] })
|
|
2195
2510
|
] }),
|
|
2196
|
-
/* @__PURE__ */ (0,
|
|
2511
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
2197
2512
|
"button",
|
|
2198
2513
|
{
|
|
2199
2514
|
onClick: (e) => {
|
|
@@ -2204,16 +2519,16 @@ function PipelineStep({
|
|
|
2204
2519
|
"relative inline-flex h-6 w-11 shrink-0 items-center rounded-full transition-colors",
|
|
2205
2520
|
step.enabled ? "bg-success" : "bg-foreground-subtle/30"
|
|
2206
2521
|
),
|
|
2207
|
-
children: /* @__PURE__ */ (0,
|
|
2522
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: cn(
|
|
2208
2523
|
"inline-block h-4 w-4 rounded-full bg-white shadow transition-transform",
|
|
2209
2524
|
step.enabled ? "translate-x-6" : "translate-x-1"
|
|
2210
2525
|
) })
|
|
2211
2526
|
}
|
|
2212
2527
|
)
|
|
2213
2528
|
] }),
|
|
2214
|
-
expanded && /* @__PURE__ */ (0,
|
|
2215
|
-
/* @__PURE__ */ (0,
|
|
2216
|
-
/* @__PURE__ */ (0,
|
|
2529
|
+
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: [
|
|
2530
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "grid grid-cols-2 gap-3", children: [
|
|
2531
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
2217
2532
|
ConfigSelect,
|
|
2218
2533
|
{
|
|
2219
2534
|
label: "Agent",
|
|
@@ -2223,7 +2538,7 @@ function PipelineStep({
|
|
|
2223
2538
|
onChange: (v) => onChange({ ...step, agentId: v })
|
|
2224
2539
|
}
|
|
2225
2540
|
),
|
|
2226
|
-
/* @__PURE__ */ (0,
|
|
2541
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
2227
2542
|
ConfigSelect,
|
|
2228
2543
|
{
|
|
2229
2544
|
label: "Runtime",
|
|
@@ -2233,7 +2548,7 @@ function PipelineStep({
|
|
|
2233
2548
|
onChange: (v) => onChange({ ...step, runtime: v })
|
|
2234
2549
|
}
|
|
2235
2550
|
),
|
|
2236
|
-
/* @__PURE__ */ (0,
|
|
2551
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
2237
2552
|
ConfigSelect,
|
|
2238
2553
|
{
|
|
2239
2554
|
label: "Backend",
|
|
@@ -2243,7 +2558,7 @@ function PipelineStep({
|
|
|
2243
2558
|
onChange: (v) => onChange({ ...step, backend: v })
|
|
2244
2559
|
}
|
|
2245
2560
|
),
|
|
2246
|
-
/* @__PURE__ */ (0,
|
|
2561
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
2247
2562
|
ConfigSelect,
|
|
2248
2563
|
{
|
|
2249
2564
|
label: "Model",
|
|
@@ -2254,15 +2569,15 @@ function PipelineStep({
|
|
|
2254
2569
|
}
|
|
2255
2570
|
)
|
|
2256
2571
|
] }),
|
|
2257
|
-
/* @__PURE__ */ (0,
|
|
2258
|
-
/* @__PURE__ */ (0,
|
|
2259
|
-
/* @__PURE__ */ (0,
|
|
2260
|
-
/* @__PURE__ */ (0,
|
|
2572
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { children: [
|
|
2573
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "flex items-center justify-between mb-1", children: [
|
|
2574
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "text-[10px] font-medium text-foreground-subtle uppercase tracking-wide", children: "Confidence" }),
|
|
2575
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("span", { className: "text-xs font-medium text-foreground tabular-nums", children: [
|
|
2261
2576
|
(step.confidence * 100).toFixed(0),
|
|
2262
2577
|
"%"
|
|
2263
2578
|
] })
|
|
2264
2579
|
] }),
|
|
2265
|
-
/* @__PURE__ */ (0,
|
|
2580
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
2266
2581
|
"input",
|
|
2267
2582
|
{
|
|
2268
2583
|
type: "range",
|
|
@@ -2282,9 +2597,9 @@ function PipelineStep({
|
|
|
2282
2597
|
) });
|
|
2283
2598
|
}
|
|
2284
2599
|
function ConfigSelect({ label, value, options, disabled, onChange }) {
|
|
2285
|
-
return /* @__PURE__ */ (0,
|
|
2286
|
-
/* @__PURE__ */ (0,
|
|
2287
|
-
/* @__PURE__ */ (0,
|
|
2600
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { children: [
|
|
2601
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("label", { className: "block text-[10px] font-medium text-foreground-subtle uppercase tracking-wide mb-1.5", children: label }),
|
|
2602
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
|
|
2288
2603
|
"select",
|
|
2289
2604
|
{
|
|
2290
2605
|
value,
|
|
@@ -2292,8 +2607,8 @@ function ConfigSelect({ label, value, options, disabled, onChange }) {
|
|
|
2292
2607
|
disabled,
|
|
2293
2608
|
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
2609
|
children: [
|
|
2295
|
-
options.length === 0 && /* @__PURE__ */ (0,
|
|
2296
|
-
options.map((o) => /* @__PURE__ */ (0,
|
|
2610
|
+
options.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("option", { value, children: value || "default" }),
|
|
2611
|
+
options.map((o) => /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("option", { value: o.value, disabled: o.disabled, children: o.label }, o.value))
|
|
2297
2612
|
]
|
|
2298
2613
|
}
|
|
2299
2614
|
)
|
|
@@ -2301,30 +2616,30 @@ function ConfigSelect({ label, value, options, disabled, onChange }) {
|
|
|
2301
2616
|
}
|
|
2302
2617
|
|
|
2303
2618
|
// src/composites/pipeline-runtime-selector.tsx
|
|
2304
|
-
var
|
|
2305
|
-
var
|
|
2619
|
+
var import_lucide_react14 = require("lucide-react");
|
|
2620
|
+
var import_jsx_runtime43 = require("react/jsx-runtime");
|
|
2306
2621
|
function PipelineRuntimeSelector({ options, value, onChange }) {
|
|
2307
|
-
return /* @__PURE__ */ (0,
|
|
2622
|
+
return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: "flex flex-wrap gap-2", children: options.map((opt) => {
|
|
2308
2623
|
const active = opt.id === value;
|
|
2309
|
-
return /* @__PURE__ */ (0,
|
|
2624
|
+
return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
|
|
2310
2625
|
"button",
|
|
2311
2626
|
{
|
|
2312
2627
|
onClick: () => opt.available && onChange(opt.id),
|
|
2313
2628
|
disabled: !opt.available,
|
|
2314
2629
|
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
2630
|
children: [
|
|
2316
|
-
/* @__PURE__ */ (0,
|
|
2631
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_lucide_react14.Cpu, { className: "h-3.5 w-3.5 shrink-0" }),
|
|
2317
2632
|
opt.label,
|
|
2318
|
-
opt.isBest && /* @__PURE__ */ (0,
|
|
2319
|
-
/* @__PURE__ */ (0,
|
|
2633
|
+
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: [
|
|
2634
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_lucide_react14.Star, { className: "h-2.5 w-2.5" }),
|
|
2320
2635
|
"Best"
|
|
2321
2636
|
] }),
|
|
2322
|
-
opt.platformScore != null && /* @__PURE__ */ (0,
|
|
2637
|
+
opt.platformScore != null && /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("span", { className: "text-[10px] text-foreground-subtle/60", children: [
|
|
2323
2638
|
"(",
|
|
2324
2639
|
opt.platformScore,
|
|
2325
2640
|
")"
|
|
2326
2641
|
] }),
|
|
2327
|
-
/* @__PURE__ */ (0,
|
|
2642
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
2328
2643
|
"span",
|
|
2329
2644
|
{
|
|
2330
2645
|
className: `h-1.5 w-1.5 rounded-full ${opt.available ? "bg-success" : "bg-danger"}`
|
|
@@ -2338,8 +2653,8 @@ function PipelineRuntimeSelector({ options, value, onChange }) {
|
|
|
2338
2653
|
}
|
|
2339
2654
|
|
|
2340
2655
|
// src/composites/pipeline-builder.tsx
|
|
2341
|
-
var
|
|
2342
|
-
var
|
|
2656
|
+
var import_react29 = require("react");
|
|
2657
|
+
var import_lucide_react15 = require("lucide-react");
|
|
2343
2658
|
|
|
2344
2659
|
// src/lib/validate-template.ts
|
|
2345
2660
|
function validateTemplate(steps, schema) {
|
|
@@ -2371,7 +2686,7 @@ function validateTemplate(steps, schema) {
|
|
|
2371
2686
|
}
|
|
2372
2687
|
|
|
2373
2688
|
// src/composites/pipeline-builder.tsx
|
|
2374
|
-
var
|
|
2689
|
+
var import_jsx_runtime44 = require("react/jsx-runtime");
|
|
2375
2690
|
function buildSchemaMap(schema) {
|
|
2376
2691
|
const map = /* @__PURE__ */ new Map();
|
|
2377
2692
|
for (const slot of schema.slots) {
|
|
@@ -2400,20 +2715,20 @@ function createDefaultStep(addon, fallbackRuntime, fallbackBackend) {
|
|
|
2400
2715
|
};
|
|
2401
2716
|
}
|
|
2402
2717
|
function PlaceholderStep({ addon, onClick }) {
|
|
2403
|
-
return /* @__PURE__ */ (0,
|
|
2718
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
2404
2719
|
"button",
|
|
2405
2720
|
{
|
|
2406
2721
|
type: "button",
|
|
2407
2722
|
onClick,
|
|
2408
2723
|
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,
|
|
2724
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "flex items-center gap-3", children: [
|
|
2725
|
+
/* @__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" }),
|
|
2726
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "flex-1 min-w-0", children: [
|
|
2727
|
+
/* @__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 }),
|
|
2728
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "flex items-center gap-1 mt-0.5 flex-wrap", children: [
|
|
2729
|
+
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)),
|
|
2730
|
+
addon.inputClasses.length > 0 && addon.outputClasses.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "text-foreground-subtle/25 text-[10px]", children: "\u2192" }),
|
|
2731
|
+
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
2732
|
] })
|
|
2418
2733
|
] })
|
|
2419
2734
|
] })
|
|
@@ -2434,9 +2749,9 @@ function PipelineBuilder({
|
|
|
2434
2749
|
readOnly = false,
|
|
2435
2750
|
excludeAddons = []
|
|
2436
2751
|
}) {
|
|
2437
|
-
const excluded = (0,
|
|
2438
|
-
const schemaMap = (0,
|
|
2439
|
-
const [warnings, setWarnings] = (0,
|
|
2752
|
+
const excluded = (0, import_react29.useMemo)(() => new Set(excludeAddons), [excludeAddons]);
|
|
2753
|
+
const schemaMap = (0, import_react29.useMemo)(() => buildSchemaMap(schema), [schema]);
|
|
2754
|
+
const [warnings, setWarnings] = (0, import_react29.useState)([]);
|
|
2440
2755
|
const bestPlatformScore = capabilities.platformScores?.find((s) => s.available);
|
|
2441
2756
|
const hasPython = capabilities.runtimes.python.available && capabilities.runtimes.python.backends.some((b) => b.available);
|
|
2442
2757
|
const defaultRuntime = bestPlatformScore?.runtime ?? (hasPython ? "python" : "node");
|
|
@@ -2525,8 +2840,8 @@ function PipelineBuilder({
|
|
|
2525
2840
|
}
|
|
2526
2841
|
function renderStep(step) {
|
|
2527
2842
|
const childPlaceholders = getChildPlaceholders(step);
|
|
2528
|
-
return /* @__PURE__ */ (0,
|
|
2529
|
-
/* @__PURE__ */ (0,
|
|
2843
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "space-y-1.5", children: [
|
|
2844
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
2530
2845
|
PipelineStep,
|
|
2531
2846
|
{
|
|
2532
2847
|
step,
|
|
@@ -2538,12 +2853,12 @@ function PipelineBuilder({
|
|
|
2538
2853
|
readOnly
|
|
2539
2854
|
}
|
|
2540
2855
|
),
|
|
2541
|
-
(step.children.length > 0 || childPlaceholders.length > 0) && /* @__PURE__ */ (0,
|
|
2542
|
-
/* @__PURE__ */ (0,
|
|
2856
|
+
(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: [
|
|
2857
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "text-[10px] font-semibold uppercase tracking-widest text-foreground-subtle/40", children: "Slot: Cropper / Classifier" }),
|
|
2543
2858
|
step.children.map((child) => {
|
|
2544
2859
|
const childChildPlaceholders = getChildPlaceholders(child);
|
|
2545
|
-
return /* @__PURE__ */ (0,
|
|
2546
|
-
/* @__PURE__ */ (0,
|
|
2860
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "space-y-1.5", children: [
|
|
2861
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
2547
2862
|
PipelineStep,
|
|
2548
2863
|
{
|
|
2549
2864
|
step: child,
|
|
@@ -2566,9 +2881,9 @@ function PipelineBuilder({
|
|
|
2566
2881
|
readOnly
|
|
2567
2882
|
}
|
|
2568
2883
|
),
|
|
2569
|
-
(child.children.length > 0 || childChildPlaceholders.length > 0) && /* @__PURE__ */ (0,
|
|
2570
|
-
/* @__PURE__ */ (0,
|
|
2571
|
-
child.children.map((grandchild) => /* @__PURE__ */ (0,
|
|
2884
|
+
(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: [
|
|
2885
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "text-[10px] font-semibold uppercase tracking-widest text-foreground-subtle/30", children: "Slot: Recognizer" }),
|
|
2886
|
+
child.children.map((grandchild) => /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
2572
2887
|
PipelineStep,
|
|
2573
2888
|
{
|
|
2574
2889
|
step: grandchild,
|
|
@@ -2596,7 +2911,7 @@ function PipelineBuilder({
|
|
|
2596
2911
|
},
|
|
2597
2912
|
grandchild.addonId
|
|
2598
2913
|
)),
|
|
2599
|
-
!readOnly && childChildPlaceholders.map((addon) => /* @__PURE__ */ (0,
|
|
2914
|
+
!readOnly && childChildPlaceholders.map((addon) => /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
2600
2915
|
PlaceholderStep,
|
|
2601
2916
|
{
|
|
2602
2917
|
addon,
|
|
@@ -2615,7 +2930,7 @@ function PipelineBuilder({
|
|
|
2615
2930
|
] })
|
|
2616
2931
|
] }, child.addonId);
|
|
2617
2932
|
}),
|
|
2618
|
-
!readOnly && childPlaceholders.map((addon) => /* @__PURE__ */ (0,
|
|
2933
|
+
!readOnly && childPlaceholders.map((addon) => /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
2619
2934
|
PlaceholderStep,
|
|
2620
2935
|
{
|
|
2621
2936
|
addon,
|
|
@@ -2627,22 +2942,22 @@ function PipelineBuilder({
|
|
|
2627
2942
|
] }, step.addonId);
|
|
2628
2943
|
}
|
|
2629
2944
|
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,
|
|
2945
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "space-y-4", children: [
|
|
2946
|
+
/* @__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: [
|
|
2947
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className: "relative flex-1 min-w-0", children: /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
|
|
2633
2948
|
"select",
|
|
2634
2949
|
{
|
|
2635
2950
|
value: selectedTemplateId ?? "",
|
|
2636
2951
|
onChange: handleSelectTemplate,
|
|
2637
2952
|
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
2953
|
children: [
|
|
2639
|
-
/* @__PURE__ */ (0,
|
|
2640
|
-
templates.map((t) => /* @__PURE__ */ (0,
|
|
2954
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("option", { value: "", children: "No template" }),
|
|
2955
|
+
templates.map((t) => /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("option", { value: t.id, children: t.name }, t.id))
|
|
2641
2956
|
]
|
|
2642
2957
|
}
|
|
2643
2958
|
) }),
|
|
2644
|
-
dirty && /* @__PURE__ */ (0,
|
|
2645
|
-
/* @__PURE__ */ (0,
|
|
2959
|
+
dirty && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "h-1.5 w-1.5 rounded-full bg-amber-500 shrink-0" }),
|
|
2960
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
2646
2961
|
"button",
|
|
2647
2962
|
{
|
|
2648
2963
|
onClick: handleSave,
|
|
@@ -2652,10 +2967,10 @@ function PipelineBuilder({
|
|
|
2652
2967
|
"p-2 rounded-lg border border-border transition-colors",
|
|
2653
2968
|
selectedTemplateId && !readOnly ? "text-foreground-subtle hover:bg-surface-hover" : "text-foreground-subtle/30 cursor-not-allowed"
|
|
2654
2969
|
),
|
|
2655
|
-
children: /* @__PURE__ */ (0,
|
|
2970
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_lucide_react15.Save, { className: "h-4 w-4" })
|
|
2656
2971
|
}
|
|
2657
2972
|
),
|
|
2658
|
-
/* @__PURE__ */ (0,
|
|
2973
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
2659
2974
|
"button",
|
|
2660
2975
|
{
|
|
2661
2976
|
onClick: handleSaveAs,
|
|
@@ -2665,10 +2980,10 @@ function PipelineBuilder({
|
|
|
2665
2980
|
"p-2 rounded-lg border border-border transition-colors",
|
|
2666
2981
|
!readOnly ? "text-foreground-subtle hover:bg-surface-hover" : "text-foreground-subtle/30 cursor-not-allowed"
|
|
2667
2982
|
),
|
|
2668
|
-
children: /* @__PURE__ */ (0,
|
|
2983
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_lucide_react15.CopyPlus, { className: "h-4 w-4" })
|
|
2669
2984
|
}
|
|
2670
2985
|
),
|
|
2671
|
-
/* @__PURE__ */ (0,
|
|
2986
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
2672
2987
|
"button",
|
|
2673
2988
|
{
|
|
2674
2989
|
onClick: handleDelete,
|
|
@@ -2678,16 +2993,16 @@ function PipelineBuilder({
|
|
|
2678
2993
|
"p-2 rounded-lg border border-border transition-colors",
|
|
2679
2994
|
selectedTemplateId && !readOnly ? "text-foreground-subtle hover:text-danger" : "text-foreground-subtle/30 cursor-not-allowed"
|
|
2680
2995
|
),
|
|
2681
|
-
children: /* @__PURE__ */ (0,
|
|
2996
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_lucide_react15.Trash2, { className: "h-4 w-4" })
|
|
2682
2997
|
}
|
|
2683
2998
|
)
|
|
2684
2999
|
] }) }),
|
|
2685
|
-
warnings.length > 0 && /* @__PURE__ */ (0,
|
|
2686
|
-
/* @__PURE__ */ (0,
|
|
2687
|
-
/* @__PURE__ */ (0,
|
|
2688
|
-
/* @__PURE__ */ (0,
|
|
3000
|
+
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: [
|
|
3001
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
3002
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "font-medium", children: "Template loaded with warnings:" }),
|
|
3003
|
+
/* @__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
3004
|
] }),
|
|
2690
|
-
warnings.map((w, i) => /* @__PURE__ */ (0,
|
|
3005
|
+
warnings.map((w, i) => /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { children: [
|
|
2691
3006
|
"\u2022 ",
|
|
2692
3007
|
w
|
|
2693
3008
|
] }, i))
|
|
@@ -2695,13 +3010,13 @@ function PipelineBuilder({
|
|
|
2695
3010
|
rootSlots.map((slot) => {
|
|
2696
3011
|
const slotSteps = steps.filter((s) => s.slot === slot.id && !excluded.has(s.addonId));
|
|
2697
3012
|
const missingRootAddons = slot.addons.filter((a) => !existingIds.has(a.id) && !excluded.has(a.id));
|
|
2698
|
-
return /* @__PURE__ */ (0,
|
|
2699
|
-
/* @__PURE__ */ (0,
|
|
3013
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "space-y-2", children: [
|
|
3014
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("span", { className: "text-[10px] font-semibold uppercase tracking-widest text-foreground-subtle/50", children: [
|
|
2700
3015
|
"Slot: ",
|
|
2701
3016
|
slot.label
|
|
2702
3017
|
] }),
|
|
2703
3018
|
slotSteps.map((step) => renderStep(step)),
|
|
2704
|
-
!readOnly && missingRootAddons.map((addon) => /* @__PURE__ */ (0,
|
|
3019
|
+
!readOnly && missingRootAddons.map((addon) => /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(PlaceholderStep, { addon, onClick: () => {
|
|
2705
3020
|
onChange([...steps, createDefaultStep(addon, defaultRuntime, defaultBackend)]);
|
|
2706
3021
|
} }, addon.id))
|
|
2707
3022
|
] }, slot.id);
|
|
@@ -2781,8 +3096,8 @@ function getClassColor(className, customColors) {
|
|
|
2781
3096
|
}
|
|
2782
3097
|
|
|
2783
3098
|
// src/composites/detection-canvas.tsx
|
|
2784
|
-
var
|
|
2785
|
-
var
|
|
3099
|
+
var import_react30 = require("react");
|
|
3100
|
+
var import_jsx_runtime45 = require("react/jsx-runtime");
|
|
2786
3101
|
var DEFAULT_CLASS_COLORS = CLASS_COLORS;
|
|
2787
3102
|
function DetectionCanvas({
|
|
2788
3103
|
src,
|
|
@@ -2802,7 +3117,7 @@ function DetectionCanvas({
|
|
|
2802
3117
|
}
|
|
2803
3118
|
const ratio = aspectRatio ?? (imageWidth && imageHeight ? `${imageWidth}/${imageHeight}` : "16/9");
|
|
2804
3119
|
const filteredDetections = detections.filter((d) => d.confidence >= minConfidence);
|
|
2805
|
-
return /* @__PURE__ */ (0,
|
|
3120
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
2806
3121
|
"div",
|
|
2807
3122
|
{
|
|
2808
3123
|
className: cn(
|
|
@@ -2810,10 +3125,10 @@ function DetectionCanvas({
|
|
|
2810
3125
|
className
|
|
2811
3126
|
),
|
|
2812
3127
|
style: { aspectRatio: ratio },
|
|
2813
|
-
children: src ? /* @__PURE__ */ (0,
|
|
2814
|
-
/* @__PURE__ */ (0,
|
|
3128
|
+
children: src ? /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(import_jsx_runtime45.Fragment, { children: [
|
|
3129
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("img", { src, className: "absolute inset-0 w-full h-full object-fill", alt: "" }),
|
|
2815
3130
|
filteredDetections.map(
|
|
2816
|
-
(d, i) => d.mask && d.maskWidth && d.maskHeight ? /* @__PURE__ */ (0,
|
|
3131
|
+
(d, i) => d.mask && d.maskWidth && d.maskHeight ? /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
2817
3132
|
MaskOverlay,
|
|
2818
3133
|
{
|
|
2819
3134
|
mask: d.mask,
|
|
@@ -2827,7 +3142,7 @@ function DetectionCanvas({
|
|
|
2827
3142
|
`mask-${i}`
|
|
2828
3143
|
) : null
|
|
2829
3144
|
),
|
|
2830
|
-
filteredDetections.map((d, i) => /* @__PURE__ */ (0,
|
|
3145
|
+
filteredDetections.map((d, i) => /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
2831
3146
|
BoundingBox,
|
|
2832
3147
|
{
|
|
2833
3148
|
detection: d,
|
|
@@ -2847,7 +3162,7 @@ function DetectionCanvas({
|
|
|
2847
3162
|
const ph = py2 - py1;
|
|
2848
3163
|
if (pw > 0 && ph > 0 && cw * ch / (pw * ph) > 0.8) return false;
|
|
2849
3164
|
return true;
|
|
2850
|
-
}).map((child, j) => /* @__PURE__ */ (0,
|
|
3165
|
+
}).map((child, j) => /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
2851
3166
|
ChildBoundingBox,
|
|
2852
3167
|
{
|
|
2853
3168
|
child,
|
|
@@ -2860,7 +3175,7 @@ function DetectionCanvas({
|
|
|
2860
3175
|
},
|
|
2861
3176
|
`det-${i}`
|
|
2862
3177
|
))
|
|
2863
|
-
] }) : /* @__PURE__ */ (0,
|
|
3178
|
+
] }) : /* @__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
3179
|
}
|
|
2865
3180
|
);
|
|
2866
3181
|
}
|
|
@@ -2877,15 +3192,15 @@ function BoundingBox({
|
|
|
2877
3192
|
const labelCount = 1 + (detection.labelsData?.length ?? 0);
|
|
2878
3193
|
const labelHeightPx = labelCount * 16 + 4;
|
|
2879
3194
|
const topPct = y1 / imageHeight * 100;
|
|
2880
|
-
const containerRef = (0,
|
|
3195
|
+
const containerRef = (0, import_react30.useRef)(null);
|
|
2881
3196
|
const showBelow = topPct < labelHeightPx / imageHeight * 100 * 1.5;
|
|
2882
|
-
const labelsElement = /* @__PURE__ */ (0,
|
|
3197
|
+
const labelsElement = /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(
|
|
2883
3198
|
"div",
|
|
2884
3199
|
{
|
|
2885
3200
|
className: `absolute left-0 flex flex-col items-start gap-px ${showBelow ? "" : ""}`,
|
|
2886
3201
|
style: showBelow ? { top: "100%", marginTop: "2px" } : { bottom: "100%", marginBottom: "2px" },
|
|
2887
3202
|
children: [
|
|
2888
|
-
/* @__PURE__ */ (0,
|
|
3203
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(
|
|
2889
3204
|
"span",
|
|
2890
3205
|
{
|
|
2891
3206
|
className: "text-[10px] px-1 rounded-sm whitespace-nowrap text-white",
|
|
@@ -2896,7 +3211,7 @@ function BoundingBox({
|
|
|
2896
3211
|
]
|
|
2897
3212
|
}
|
|
2898
3213
|
),
|
|
2899
|
-
detection.labelsData?.map((l, k) => /* @__PURE__ */ (0,
|
|
3214
|
+
detection.labelsData?.map((l, k) => /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(
|
|
2900
3215
|
"span",
|
|
2901
3216
|
{
|
|
2902
3217
|
className: "text-[9px] font-semibold px-1 rounded-sm whitespace-nowrap text-white",
|
|
@@ -2913,7 +3228,7 @@ function BoundingBox({
|
|
|
2913
3228
|
]
|
|
2914
3229
|
}
|
|
2915
3230
|
);
|
|
2916
|
-
return /* @__PURE__ */ (0,
|
|
3231
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(
|
|
2917
3232
|
"div",
|
|
2918
3233
|
{
|
|
2919
3234
|
ref: containerRef,
|
|
@@ -2943,8 +3258,8 @@ function MaskOverlay({
|
|
|
2943
3258
|
imageHeight,
|
|
2944
3259
|
color
|
|
2945
3260
|
}) {
|
|
2946
|
-
const canvasRef = (0,
|
|
2947
|
-
(0,
|
|
3261
|
+
const canvasRef = (0, import_react30.useRef)(null);
|
|
3262
|
+
(0, import_react30.useEffect)(() => {
|
|
2948
3263
|
const canvas = canvasRef.current;
|
|
2949
3264
|
if (!canvas) return;
|
|
2950
3265
|
const ctx = canvas.getContext("2d");
|
|
@@ -2972,7 +3287,7 @@ function MaskOverlay({
|
|
|
2972
3287
|
ctx.putImageData(imageData, 0, 0);
|
|
2973
3288
|
}, [mask, maskWidth, maskHeight, color]);
|
|
2974
3289
|
const [x1, y1, x2, y2] = bbox;
|
|
2975
|
-
return /* @__PURE__ */ (0,
|
|
3290
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
2976
3291
|
"canvas",
|
|
2977
3292
|
{
|
|
2978
3293
|
ref: canvasRef,
|
|
@@ -2998,7 +3313,7 @@ function ChildBoundingBox({
|
|
|
2998
3313
|
const pw = px2 - px1;
|
|
2999
3314
|
const ph = py2 - py1;
|
|
3000
3315
|
if (pw <= 0 || ph <= 0) return null;
|
|
3001
|
-
return /* @__PURE__ */ (0,
|
|
3316
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
3002
3317
|
"div",
|
|
3003
3318
|
{
|
|
3004
3319
|
className: "absolute rounded-sm",
|
|
@@ -3015,13 +3330,13 @@ function ChildBoundingBox({
|
|
|
3015
3330
|
const labelCount = 1 + (child.labelsData?.length ?? 0);
|
|
3016
3331
|
const relTop = (cy1 - py1) / ph * 100;
|
|
3017
3332
|
const showBelow = relTop < labelCount * 6;
|
|
3018
|
-
return /* @__PURE__ */ (0,
|
|
3333
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(
|
|
3019
3334
|
"div",
|
|
3020
3335
|
{
|
|
3021
3336
|
className: "absolute left-0 flex flex-col items-start gap-px",
|
|
3022
3337
|
style: showBelow ? { top: "100%", marginTop: "1px" } : { bottom: "100%", marginBottom: "1px" },
|
|
3023
3338
|
children: [
|
|
3024
|
-
/* @__PURE__ */ (0,
|
|
3339
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(
|
|
3025
3340
|
"span",
|
|
3026
3341
|
{
|
|
3027
3342
|
className: "text-[9px] px-0.5 rounded-sm whitespace-nowrap text-white",
|
|
@@ -3032,7 +3347,7 @@ function ChildBoundingBox({
|
|
|
3032
3347
|
]
|
|
3033
3348
|
}
|
|
3034
3349
|
),
|
|
3035
|
-
child.labelsData?.map((l, k) => /* @__PURE__ */ (0,
|
|
3350
|
+
child.labelsData?.map((l, k) => /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(
|
|
3036
3351
|
"span",
|
|
3037
3352
|
{
|
|
3038
3353
|
className: "text-[8px] font-semibold px-0.5 rounded-sm whitespace-nowrap text-white",
|
|
@@ -3055,7 +3370,7 @@ function ChildBoundingBox({
|
|
|
3055
3370
|
}
|
|
3056
3371
|
|
|
3057
3372
|
// src/composites/detection-result-tree.tsx
|
|
3058
|
-
var
|
|
3373
|
+
var import_jsx_runtime46 = require("react/jsx-runtime");
|
|
3059
3374
|
function DetectionResultTree({
|
|
3060
3375
|
detections,
|
|
3061
3376
|
classColors,
|
|
@@ -3065,15 +3380,15 @@ function DetectionResultTree({
|
|
|
3065
3380
|
}) {
|
|
3066
3381
|
const colors = classColors;
|
|
3067
3382
|
if (detections.length === 0) {
|
|
3068
|
-
return /* @__PURE__ */ (0,
|
|
3383
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: "text-sm text-foreground-subtle italic text-center py-4", children: "No detections" });
|
|
3069
3384
|
}
|
|
3070
|
-
return /* @__PURE__ */ (0,
|
|
3071
|
-
/* @__PURE__ */ (0,
|
|
3385
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className, children: [
|
|
3386
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "text-xs font-medium text-foreground-subtle uppercase tracking-wide mb-2", children: [
|
|
3072
3387
|
"Detections (",
|
|
3073
3388
|
detections.length,
|
|
3074
3389
|
")"
|
|
3075
3390
|
] }),
|
|
3076
|
-
/* @__PURE__ */ (0,
|
|
3391
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: "space-y-2", children: detections.map((d, i) => /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
3077
3392
|
DetectionNode,
|
|
3078
3393
|
{
|
|
3079
3394
|
detection: d,
|
|
@@ -3095,10 +3410,10 @@ function DetectionNode({
|
|
|
3095
3410
|
}) {
|
|
3096
3411
|
const color = getClassColor(detection.className, colors);
|
|
3097
3412
|
const isVisible = !hiddenKeys?.has(path);
|
|
3098
|
-
return /* @__PURE__ */ (0,
|
|
3099
|
-
/* @__PURE__ */ (0,
|
|
3100
|
-
/* @__PURE__ */ (0,
|
|
3101
|
-
onToggleVisibility && /* @__PURE__ */ (0,
|
|
3413
|
+
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: [
|
|
3414
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex justify-between items-center", children: [
|
|
3415
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
3416
|
+
onToggleVisibility && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
3102
3417
|
"input",
|
|
3103
3418
|
{
|
|
3104
3419
|
type: "checkbox",
|
|
@@ -3107,45 +3422,45 @@ function DetectionNode({
|
|
|
3107
3422
|
className: "h-3.5 w-3.5 rounded border-border accent-primary cursor-pointer shrink-0"
|
|
3108
3423
|
}
|
|
3109
3424
|
),
|
|
3110
|
-
/* @__PURE__ */ (0,
|
|
3425
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
3111
3426
|
"span",
|
|
3112
3427
|
{
|
|
3113
3428
|
className: "h-2.5 w-2.5 rounded-full shrink-0",
|
|
3114
3429
|
style: { backgroundColor: color }
|
|
3115
3430
|
}
|
|
3116
3431
|
),
|
|
3117
|
-
/* @__PURE__ */ (0,
|
|
3118
|
-
detection.mask && detection.maskWidth && detection.maskHeight && /* @__PURE__ */ (0,
|
|
3432
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "text-sm font-medium text-foreground", children: detection.className }),
|
|
3433
|
+
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
3434
|
"mask ",
|
|
3120
3435
|
detection.maskWidth,
|
|
3121
3436
|
"x",
|
|
3122
3437
|
detection.maskHeight
|
|
3123
3438
|
] })
|
|
3124
3439
|
] }),
|
|
3125
|
-
/* @__PURE__ */ (0,
|
|
3440
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(ConfidenceBadge, { confidence: detection.confidence })
|
|
3126
3441
|
] }),
|
|
3127
|
-
/* @__PURE__ */ (0,
|
|
3442
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "text-[10px] text-foreground-subtle font-mono", children: [
|
|
3128
3443
|
"bbox: [",
|
|
3129
3444
|
detection.bbox.map((v) => Math.round(v)).join(", "),
|
|
3130
3445
|
"]"
|
|
3131
3446
|
] }),
|
|
3132
|
-
detection.labelsData && detection.labelsData.length > 0 && /* @__PURE__ */ (0,
|
|
3447
|
+
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
3448
|
"span",
|
|
3134
3449
|
{
|
|
3135
3450
|
className: "inline-flex items-center gap-1 text-[10px] font-medium px-1.5 py-0.5 rounded-full",
|
|
3136
3451
|
style: { backgroundColor: getClassColor(l.addonId ?? l.label, colors) + "20", color: getClassColor(l.addonId ?? l.label, colors) },
|
|
3137
3452
|
children: [
|
|
3138
3453
|
l.label,
|
|
3139
|
-
/* @__PURE__ */ (0,
|
|
3454
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("span", { className: "opacity-60", children: [
|
|
3140
3455
|
(l.score * 100).toFixed(0),
|
|
3141
3456
|
"%"
|
|
3142
3457
|
] }),
|
|
3143
|
-
l.addonId && /* @__PURE__ */ (0,
|
|
3458
|
+
l.addonId && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "opacity-40 text-[8px]", children: l.addonId })
|
|
3144
3459
|
]
|
|
3145
3460
|
},
|
|
3146
3461
|
k
|
|
3147
3462
|
)) }),
|
|
3148
|
-
detection.children && detection.children.length > 0 && /* @__PURE__ */ (0,
|
|
3463
|
+
detection.children && detection.children.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
3149
3464
|
ChildrenTree,
|
|
3150
3465
|
{
|
|
3151
3466
|
children: detection.children,
|
|
@@ -3164,13 +3479,13 @@ function ChildrenTree({
|
|
|
3164
3479
|
hiddenKeys,
|
|
3165
3480
|
onToggleVisibility
|
|
3166
3481
|
}) {
|
|
3167
|
-
return /* @__PURE__ */ (0,
|
|
3482
|
+
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
3483
|
const childPath = `${parentPath}.${j}`;
|
|
3169
3484
|
const childColor = getClassColor(child.className, colors);
|
|
3170
3485
|
const isVisible = !hiddenKeys?.has(childPath);
|
|
3171
|
-
return /* @__PURE__ */ (0,
|
|
3172
|
-
/* @__PURE__ */ (0,
|
|
3173
|
-
onToggleVisibility && /* @__PURE__ */ (0,
|
|
3486
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: `text-xs space-y-0.5 ${isVisible ? "" : "opacity-40"}`, children: [
|
|
3487
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex items-center gap-1.5", children: [
|
|
3488
|
+
onToggleVisibility && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
3174
3489
|
"input",
|
|
3175
3490
|
{
|
|
3176
3491
|
type: "checkbox",
|
|
@@ -3179,26 +3494,26 @@ function ChildrenTree({
|
|
|
3179
3494
|
className: "h-3 w-3 rounded border-border accent-primary cursor-pointer shrink-0"
|
|
3180
3495
|
}
|
|
3181
3496
|
),
|
|
3182
|
-
/* @__PURE__ */ (0,
|
|
3497
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
3183
3498
|
"span",
|
|
3184
3499
|
{
|
|
3185
3500
|
className: "h-1.5 w-1.5 rounded-full shrink-0",
|
|
3186
3501
|
style: { backgroundColor: childColor }
|
|
3187
3502
|
}
|
|
3188
3503
|
),
|
|
3189
|
-
/* @__PURE__ */ (0,
|
|
3190
|
-
/* @__PURE__ */ (0,
|
|
3504
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "font-medium", style: { color: childColor }, children: child.className }),
|
|
3505
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("span", { className: "text-foreground-subtle", children: [
|
|
3191
3506
|
(child.confidence * 100).toFixed(0),
|
|
3192
3507
|
"%"
|
|
3193
3508
|
] }),
|
|
3194
|
-
child.mask && child.maskWidth && child.maskHeight && /* @__PURE__ */ (0,
|
|
3509
|
+
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
3510
|
"mask ",
|
|
3196
3511
|
child.maskWidth,
|
|
3197
3512
|
"x",
|
|
3198
3513
|
child.maskHeight
|
|
3199
3514
|
] })
|
|
3200
3515
|
] }),
|
|
3201
|
-
child.labelsData && child.labelsData.length > 0 && /* @__PURE__ */ (0,
|
|
3516
|
+
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
3517
|
"span",
|
|
3203
3518
|
{
|
|
3204
3519
|
className: "inline-flex items-center gap-0.5 text-[9px] font-medium px-1 py-0.5 rounded-full",
|
|
@@ -3206,7 +3521,7 @@ function ChildrenTree({
|
|
|
3206
3521
|
children: [
|
|
3207
3522
|
l.label,
|
|
3208
3523
|
" ",
|
|
3209
|
-
/* @__PURE__ */ (0,
|
|
3524
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("span", { className: "opacity-60", children: [
|
|
3210
3525
|
(l.score * 100).toFixed(0),
|
|
3211
3526
|
"%"
|
|
3212
3527
|
] })
|
|
@@ -3214,7 +3529,7 @@ function ChildrenTree({
|
|
|
3214
3529
|
},
|
|
3215
3530
|
k
|
|
3216
3531
|
)) }),
|
|
3217
|
-
child.children && child.children.length > 0 && /* @__PURE__ */ (0,
|
|
3532
|
+
child.children && child.children.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
3218
3533
|
ChildrenTree,
|
|
3219
3534
|
{
|
|
3220
3535
|
children: child.children,
|
|
@@ -3229,30 +3544,30 @@ function ChildrenTree({
|
|
|
3229
3544
|
}
|
|
3230
3545
|
function ConfidenceBadge({ confidence }) {
|
|
3231
3546
|
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,
|
|
3547
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("span", { className: `text-xs font-medium px-2 py-0.5 rounded-full ${level}`, children: [
|
|
3233
3548
|
(confidence * 100).toFixed(1),
|
|
3234
3549
|
"%"
|
|
3235
3550
|
] });
|
|
3236
3551
|
}
|
|
3237
3552
|
|
|
3238
3553
|
// src/composites/step-timings.tsx
|
|
3239
|
-
var
|
|
3554
|
+
var import_jsx_runtime47 = require("react/jsx-runtime");
|
|
3240
3555
|
function StepTimings({ timings, totalMs, className }) {
|
|
3241
3556
|
const entries = Object.entries(timings);
|
|
3242
3557
|
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,
|
|
3558
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: `rounded-lg border border-border bg-surface p-3 space-y-2 ${className ?? ""}`, children: [
|
|
3559
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "text-xs font-medium text-foreground-subtle uppercase tracking-wide", children: "Timings" }),
|
|
3560
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "space-y-1 text-xs", children: [
|
|
3561
|
+
entries.map(([step, ms]) => /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex justify-between", children: [
|
|
3562
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "text-foreground-subtle", children: step }),
|
|
3563
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("span", { className: "font-mono text-foreground", children: [
|
|
3249
3564
|
ms.toFixed(1),
|
|
3250
3565
|
"ms"
|
|
3251
3566
|
] })
|
|
3252
3567
|
] }, step)),
|
|
3253
|
-
totalMs !== void 0 && /* @__PURE__ */ (0,
|
|
3254
|
-
/* @__PURE__ */ (0,
|
|
3255
|
-
/* @__PURE__ */ (0,
|
|
3568
|
+
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: [
|
|
3569
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { children: "Total" }),
|
|
3570
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("span", { className: "font-mono", children: [
|
|
3256
3571
|
totalMs.toFixed(1),
|
|
3257
3572
|
"ms"
|
|
3258
3573
|
] })
|
|
@@ -3262,7 +3577,7 @@ function StepTimings({ timings, totalMs, className }) {
|
|
|
3262
3577
|
}
|
|
3263
3578
|
|
|
3264
3579
|
// src/composites/image-selector.tsx
|
|
3265
|
-
var
|
|
3580
|
+
var import_jsx_runtime48 = require("react/jsx-runtime");
|
|
3266
3581
|
function ImageSelector({
|
|
3267
3582
|
images,
|
|
3268
3583
|
selectedFilename,
|
|
@@ -3288,8 +3603,8 @@ function ImageSelector({
|
|
|
3288
3603
|
};
|
|
3289
3604
|
input.click();
|
|
3290
3605
|
};
|
|
3291
|
-
return /* @__PURE__ */ (0,
|
|
3292
|
-
images.map((img) => /* @__PURE__ */ (0,
|
|
3606
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: `flex flex-wrap items-center gap-2 ${className ?? ""}`, children: [
|
|
3607
|
+
images.map((img) => /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
3293
3608
|
"button",
|
|
3294
3609
|
{
|
|
3295
3610
|
onClick: () => onSelect(img.filename),
|
|
@@ -3298,7 +3613,7 @@ function ImageSelector({
|
|
|
3298
3613
|
},
|
|
3299
3614
|
img.filename
|
|
3300
3615
|
)),
|
|
3301
|
-
/* @__PURE__ */ (0,
|
|
3616
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
3302
3617
|
"button",
|
|
3303
3618
|
{
|
|
3304
3619
|
onClick: handleUploadClick,
|
|
@@ -3306,12 +3621,12 @@ function ImageSelector({
|
|
|
3306
3621
|
children: "Upload..."
|
|
3307
3622
|
}
|
|
3308
3623
|
),
|
|
3309
|
-
uploadedName && /* @__PURE__ */ (0,
|
|
3624
|
+
uploadedName && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "text-xs text-foreground-subtle", children: uploadedName })
|
|
3310
3625
|
] });
|
|
3311
3626
|
}
|
|
3312
3627
|
|
|
3313
3628
|
// src/composites/inference-config-selector.tsx
|
|
3314
|
-
var
|
|
3629
|
+
var import_jsx_runtime49 = require("react/jsx-runtime");
|
|
3315
3630
|
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
3631
|
function InferenceConfigSelector({
|
|
3317
3632
|
runtime,
|
|
@@ -3331,16 +3646,16 @@ function InferenceConfigSelector({
|
|
|
3331
3646
|
showAgent = false
|
|
3332
3647
|
}) {
|
|
3333
3648
|
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,
|
|
3649
|
+
return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: `${containerClass} ${className ?? ""}`, children: [
|
|
3650
|
+
showAgent && agents.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("label", { className: "space-y-1", children: [
|
|
3651
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "text-xs font-medium text-foreground-subtle", children: "Agent" }),
|
|
3652
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
3338
3653
|
"select",
|
|
3339
3654
|
{
|
|
3340
3655
|
value: agentId,
|
|
3341
3656
|
onChange: (e) => onAgentChange?.(e.target.value),
|
|
3342
3657
|
className: SELECT_CLASS,
|
|
3343
|
-
children: agents.map((a) => /* @__PURE__ */ (0,
|
|
3658
|
+
children: agents.map((a) => /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("option", { value: a.id, children: [
|
|
3344
3659
|
a.name,
|
|
3345
3660
|
" (",
|
|
3346
3661
|
a.status,
|
|
@@ -3349,45 +3664,45 @@ function InferenceConfigSelector({
|
|
|
3349
3664
|
}
|
|
3350
3665
|
)
|
|
3351
3666
|
] }),
|
|
3352
|
-
/* @__PURE__ */ (0,
|
|
3353
|
-
/* @__PURE__ */ (0,
|
|
3354
|
-
/* @__PURE__ */ (0,
|
|
3667
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("label", { className: "space-y-1", children: [
|
|
3668
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "text-xs font-medium text-foreground-subtle", children: "Runtime" }),
|
|
3669
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
3355
3670
|
"select",
|
|
3356
3671
|
{
|
|
3357
3672
|
value: runtime,
|
|
3358
3673
|
onChange: (e) => onRuntimeChange(e.target.value),
|
|
3359
3674
|
className: SELECT_CLASS,
|
|
3360
|
-
children: runtimes.map((r) => /* @__PURE__ */ (0,
|
|
3675
|
+
children: runtimes.map((r) => /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("option", { value: r.value, disabled: !r.available, children: [
|
|
3361
3676
|
r.label,
|
|
3362
3677
|
!r.available ? " (unavailable)" : ""
|
|
3363
3678
|
] }, r.value))
|
|
3364
3679
|
}
|
|
3365
3680
|
)
|
|
3366
3681
|
] }),
|
|
3367
|
-
/* @__PURE__ */ (0,
|
|
3368
|
-
/* @__PURE__ */ (0,
|
|
3369
|
-
/* @__PURE__ */ (0,
|
|
3682
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("label", { className: "space-y-1", children: [
|
|
3683
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "text-xs font-medium text-foreground-subtle", children: "Backend" }),
|
|
3684
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
3370
3685
|
"select",
|
|
3371
3686
|
{
|
|
3372
3687
|
value: backend,
|
|
3373
3688
|
onChange: (e) => onBackendChange(e.target.value),
|
|
3374
3689
|
className: SELECT_CLASS,
|
|
3375
|
-
children: backends.map((b) => /* @__PURE__ */ (0,
|
|
3690
|
+
children: backends.map((b) => /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("option", { value: b.id, disabled: !b.available, children: [
|
|
3376
3691
|
b.label,
|
|
3377
3692
|
!b.available ? " (unavailable)" : ""
|
|
3378
3693
|
] }, b.id))
|
|
3379
3694
|
}
|
|
3380
3695
|
)
|
|
3381
3696
|
] }),
|
|
3382
|
-
/* @__PURE__ */ (0,
|
|
3383
|
-
/* @__PURE__ */ (0,
|
|
3384
|
-
/* @__PURE__ */ (0,
|
|
3697
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("label", { className: "space-y-1", children: [
|
|
3698
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "text-xs font-medium text-foreground-subtle", children: "Model" }),
|
|
3699
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
3385
3700
|
"select",
|
|
3386
3701
|
{
|
|
3387
3702
|
value: modelId,
|
|
3388
3703
|
onChange: (e) => onModelChange(e.target.value),
|
|
3389
3704
|
className: SELECT_CLASS,
|
|
3390
|
-
children: models.length === 0 ? /* @__PURE__ */ (0,
|
|
3705
|
+
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
3706
|
m.name,
|
|
3392
3707
|
m.downloaded ? " \u2713" : ""
|
|
3393
3708
|
] }, m.id))
|
|
@@ -3398,19 +3713,19 @@ function InferenceConfigSelector({
|
|
|
3398
3713
|
}
|
|
3399
3714
|
|
|
3400
3715
|
// src/composites/mount-addon-page.tsx
|
|
3401
|
-
var
|
|
3716
|
+
var import_react33 = require("react");
|
|
3402
3717
|
var import_client2 = require("react-dom/client");
|
|
3403
3718
|
|
|
3404
3719
|
// src/composites/dev-shell.tsx
|
|
3405
|
-
var
|
|
3720
|
+
var import_react32 = require("react");
|
|
3406
3721
|
var import_client = require("@trpc/client");
|
|
3407
3722
|
var import_superjson = __toESM(require("superjson"), 1);
|
|
3408
3723
|
|
|
3409
3724
|
// src/composites/login-form.tsx
|
|
3410
|
-
var
|
|
3411
|
-
var
|
|
3725
|
+
var import_react31 = require("react");
|
|
3726
|
+
var import_jsx_runtime50 = require("react/jsx-runtime");
|
|
3412
3727
|
function EyeIcon({ className }) {
|
|
3413
|
-
return /* @__PURE__ */ (0,
|
|
3728
|
+
return /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(
|
|
3414
3729
|
"svg",
|
|
3415
3730
|
{
|
|
3416
3731
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -3422,14 +3737,14 @@ function EyeIcon({ className }) {
|
|
|
3422
3737
|
strokeLinejoin: "round",
|
|
3423
3738
|
className,
|
|
3424
3739
|
children: [
|
|
3425
|
-
/* @__PURE__ */ (0,
|
|
3426
|
-
/* @__PURE__ */ (0,
|
|
3740
|
+
/* @__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" }),
|
|
3741
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)("circle", { cx: "12", cy: "12", r: "3" })
|
|
3427
3742
|
]
|
|
3428
3743
|
}
|
|
3429
3744
|
);
|
|
3430
3745
|
}
|
|
3431
3746
|
function EyeOffIcon({ className }) {
|
|
3432
|
-
return /* @__PURE__ */ (0,
|
|
3747
|
+
return /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(
|
|
3433
3748
|
"svg",
|
|
3434
3749
|
{
|
|
3435
3750
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -3441,16 +3756,16 @@ function EyeOffIcon({ className }) {
|
|
|
3441
3756
|
strokeLinejoin: "round",
|
|
3442
3757
|
className,
|
|
3443
3758
|
children: [
|
|
3444
|
-
/* @__PURE__ */ (0,
|
|
3445
|
-
/* @__PURE__ */ (0,
|
|
3446
|
-
/* @__PURE__ */ (0,
|
|
3447
|
-
/* @__PURE__ */ (0,
|
|
3759
|
+
/* @__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" }),
|
|
3760
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)("path", { d: "M14.084 14.158a3 3 0 0 1-4.242-4.242" }),
|
|
3761
|
+
/* @__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" }),
|
|
3762
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)("path", { d: "m2 2 20 20" })
|
|
3448
3763
|
]
|
|
3449
3764
|
}
|
|
3450
3765
|
);
|
|
3451
3766
|
}
|
|
3452
3767
|
function SpinnerIcon({ className }) {
|
|
3453
|
-
return /* @__PURE__ */ (0,
|
|
3768
|
+
return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
|
|
3454
3769
|
"svg",
|
|
3455
3770
|
{
|
|
3456
3771
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -3461,7 +3776,7 @@ function SpinnerIcon({ className }) {
|
|
|
3461
3776
|
strokeLinecap: "round",
|
|
3462
3777
|
strokeLinejoin: "round",
|
|
3463
3778
|
className,
|
|
3464
|
-
children: /* @__PURE__ */ (0,
|
|
3779
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("path", { d: "M21 12a9 9 0 1 1-6.219-8.56" })
|
|
3465
3780
|
}
|
|
3466
3781
|
);
|
|
3467
3782
|
}
|
|
@@ -3472,11 +3787,11 @@ function LoginForm({
|
|
|
3472
3787
|
error: externalError,
|
|
3473
3788
|
className
|
|
3474
3789
|
}) {
|
|
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,
|
|
3790
|
+
const [username, setUsername] = (0, import_react31.useState)("");
|
|
3791
|
+
const [password, setPassword] = (0, import_react31.useState)("");
|
|
3792
|
+
const [showPassword, setShowPassword] = (0, import_react31.useState)(false);
|
|
3793
|
+
const [submitting, setSubmitting] = (0, import_react31.useState)(false);
|
|
3794
|
+
const [internalError, setInternalError] = (0, import_react31.useState)(null);
|
|
3480
3795
|
const error = externalError ?? internalError;
|
|
3481
3796
|
const handleSubmit = async (e) => {
|
|
3482
3797
|
e.preventDefault();
|
|
@@ -3492,26 +3807,26 @@ function LoginForm({
|
|
|
3492
3807
|
setSubmitting(false);
|
|
3493
3808
|
}
|
|
3494
3809
|
};
|
|
3495
|
-
return /* @__PURE__ */ (0,
|
|
3810
|
+
return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
|
|
3496
3811
|
"div",
|
|
3497
3812
|
{
|
|
3498
3813
|
className: cn(
|
|
3499
3814
|
"flex min-h-screen items-center justify-center bg-background p-4",
|
|
3500
3815
|
className
|
|
3501
3816
|
),
|
|
3502
|
-
children: /* @__PURE__ */ (0,
|
|
3503
|
-
logoSrc && /* @__PURE__ */ (0,
|
|
3504
|
-
serverUrl && /* @__PURE__ */ (0,
|
|
3505
|
-
/* @__PURE__ */ (0,
|
|
3817
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("div", { className: "w-full max-w-sm", children: [
|
|
3818
|
+
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" }) }),
|
|
3819
|
+
serverUrl && /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("p", { className: "mb-4 text-center text-xs text-foreground-subtle truncate", children: serverUrl }),
|
|
3820
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(
|
|
3506
3821
|
"form",
|
|
3507
3822
|
{
|
|
3508
3823
|
onSubmit: handleSubmit,
|
|
3509
3824
|
className: "space-y-4 rounded-xl border border-border bg-surface p-6 shadow-xl shadow-black/10",
|
|
3510
3825
|
children: [
|
|
3511
|
-
error && /* @__PURE__ */ (0,
|
|
3512
|
-
/* @__PURE__ */ (0,
|
|
3513
|
-
/* @__PURE__ */ (0,
|
|
3514
|
-
/* @__PURE__ */ (0,
|
|
3826
|
+
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 }),
|
|
3827
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("div", { className: "space-y-1.5", children: [
|
|
3828
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)("label", { className: "text-xs font-medium text-foreground-subtle", children: "Username" }),
|
|
3829
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
|
|
3515
3830
|
"input",
|
|
3516
3831
|
{
|
|
3517
3832
|
type: "text",
|
|
@@ -3523,10 +3838,10 @@ function LoginForm({
|
|
|
3523
3838
|
}
|
|
3524
3839
|
)
|
|
3525
3840
|
] }),
|
|
3526
|
-
/* @__PURE__ */ (0,
|
|
3527
|
-
/* @__PURE__ */ (0,
|
|
3528
|
-
/* @__PURE__ */ (0,
|
|
3529
|
-
/* @__PURE__ */ (0,
|
|
3841
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("div", { className: "space-y-1.5", children: [
|
|
3842
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)("label", { className: "text-xs font-medium text-foreground-subtle", children: "Password" }),
|
|
3843
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("div", { className: "relative", children: [
|
|
3844
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
|
|
3530
3845
|
"input",
|
|
3531
3846
|
{
|
|
3532
3847
|
type: showPassword ? "text" : "password",
|
|
@@ -3537,26 +3852,26 @@ function LoginForm({
|
|
|
3537
3852
|
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
3853
|
}
|
|
3539
3854
|
),
|
|
3540
|
-
/* @__PURE__ */ (0,
|
|
3855
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
|
|
3541
3856
|
"button",
|
|
3542
3857
|
{
|
|
3543
3858
|
type: "button",
|
|
3544
3859
|
onClick: () => setShowPassword((prev) => !prev),
|
|
3545
3860
|
className: "absolute right-2.5 top-1/2 -translate-y-1/2 text-foreground-subtle hover:text-foreground",
|
|
3546
3861
|
tabIndex: -1,
|
|
3547
|
-
children: showPassword ? /* @__PURE__ */ (0,
|
|
3862
|
+
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
3863
|
}
|
|
3549
3864
|
)
|
|
3550
3865
|
] })
|
|
3551
3866
|
] }),
|
|
3552
|
-
/* @__PURE__ */ (0,
|
|
3867
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(
|
|
3553
3868
|
"button",
|
|
3554
3869
|
{
|
|
3555
3870
|
type: "submit",
|
|
3556
3871
|
disabled: submitting,
|
|
3557
3872
|
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
3873
|
children: [
|
|
3559
|
-
submitting && /* @__PURE__ */ (0,
|
|
3874
|
+
submitting && /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(SpinnerIcon, { className: "h-4 w-4 animate-spin" }),
|
|
3560
3875
|
submitting ? "Logging in..." : "Log in"
|
|
3561
3876
|
]
|
|
3562
3877
|
}
|
|
@@ -3570,11 +3885,11 @@ function LoginForm({
|
|
|
3570
3885
|
}
|
|
3571
3886
|
|
|
3572
3887
|
// src/composites/dev-shell.tsx
|
|
3573
|
-
var
|
|
3888
|
+
var import_jsx_runtime51 = require("react/jsx-runtime");
|
|
3574
3889
|
var STORAGE_KEY = "camstack_dev_token";
|
|
3575
|
-
var DevShellContext = (0,
|
|
3890
|
+
var DevShellContext = (0, import_react32.createContext)(null);
|
|
3576
3891
|
function useDevShell() {
|
|
3577
|
-
const ctx = (0,
|
|
3892
|
+
const ctx = (0, import_react32.useContext)(DevShellContext);
|
|
3578
3893
|
if (!ctx) {
|
|
3579
3894
|
throw new Error("useDevShell must be used within a DevShell");
|
|
3580
3895
|
}
|
|
@@ -3585,7 +3900,7 @@ function getStoredToken() {
|
|
|
3585
3900
|
return localStorage.getItem(STORAGE_KEY);
|
|
3586
3901
|
}
|
|
3587
3902
|
function SunIcon({ className }) {
|
|
3588
|
-
return /* @__PURE__ */ (0,
|
|
3903
|
+
return /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(
|
|
3589
3904
|
"svg",
|
|
3590
3905
|
{
|
|
3591
3906
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -3597,21 +3912,21 @@ function SunIcon({ className }) {
|
|
|
3597
3912
|
strokeLinejoin: "round",
|
|
3598
3913
|
className,
|
|
3599
3914
|
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,
|
|
3915
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("circle", { cx: "12", cy: "12", r: "4" }),
|
|
3916
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("path", { d: "M12 2v2" }),
|
|
3917
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("path", { d: "M12 20v2" }),
|
|
3918
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("path", { d: "m4.93 4.93 1.41 1.41" }),
|
|
3919
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("path", { d: "m17.66 17.66 1.41 1.41" }),
|
|
3920
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("path", { d: "M2 12h2" }),
|
|
3921
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("path", { d: "M20 12h2" }),
|
|
3922
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("path", { d: "m6.34 17.66-1.41 1.41" }),
|
|
3923
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("path", { d: "m19.07 4.93-1.41 1.41" })
|
|
3609
3924
|
]
|
|
3610
3925
|
}
|
|
3611
3926
|
);
|
|
3612
3927
|
}
|
|
3613
3928
|
function MoonIcon({ className }) {
|
|
3614
|
-
return /* @__PURE__ */ (0,
|
|
3929
|
+
return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
3615
3930
|
"svg",
|
|
3616
3931
|
{
|
|
3617
3932
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -3622,7 +3937,7 @@ function MoonIcon({ className }) {
|
|
|
3622
3937
|
strokeLinecap: "round",
|
|
3623
3938
|
strokeLinejoin: "round",
|
|
3624
3939
|
className,
|
|
3625
|
-
children: /* @__PURE__ */ (0,
|
|
3940
|
+
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
3941
|
}
|
|
3627
3942
|
);
|
|
3628
3943
|
}
|
|
@@ -3634,7 +3949,7 @@ function DevShellInner({
|
|
|
3634
3949
|
onLogout
|
|
3635
3950
|
}) {
|
|
3636
3951
|
const theme = useThemeMode();
|
|
3637
|
-
const trpc = (0,
|
|
3952
|
+
const trpc = (0, import_react32.useMemo)(
|
|
3638
3953
|
() => {
|
|
3639
3954
|
const wsUrl = serverUrl.replace(/^http/, "ws") + "/trpc";
|
|
3640
3955
|
const wsClient = (0, import_client.createWSClient)({
|
|
@@ -3657,19 +3972,19 @@ function DevShellInner({
|
|
|
3657
3972
|
},
|
|
3658
3973
|
[serverUrl, token]
|
|
3659
3974
|
);
|
|
3660
|
-
const contextValue = (0,
|
|
3975
|
+
const contextValue = (0, import_react32.useMemo)(
|
|
3661
3976
|
() => ({ trpc, token, logout: onLogout }),
|
|
3662
3977
|
[trpc, token, onLogout]
|
|
3663
3978
|
);
|
|
3664
|
-
return /* @__PURE__ */ (0,
|
|
3665
|
-
/* @__PURE__ */ (0,
|
|
3666
|
-
/* @__PURE__ */ (0,
|
|
3667
|
-
/* @__PURE__ */ (0,
|
|
3668
|
-
title && /* @__PURE__ */ (0,
|
|
3669
|
-
/* @__PURE__ */ (0,
|
|
3979
|
+
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: [
|
|
3980
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className: "flex items-center justify-between border-b border-border bg-surface px-4 py-2", children: [
|
|
3981
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
3982
|
+
/* @__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" }),
|
|
3983
|
+
title && /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("span", { className: "text-sm font-medium text-foreground", children: title }),
|
|
3984
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("span", { className: "text-xs text-foreground-subtle", children: serverUrl })
|
|
3670
3985
|
] }),
|
|
3671
|
-
/* @__PURE__ */ (0,
|
|
3672
|
-
/* @__PURE__ */ (0,
|
|
3986
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
3987
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(
|
|
3673
3988
|
"button",
|
|
3674
3989
|
{
|
|
3675
3990
|
type: "button",
|
|
@@ -3677,12 +3992,12 @@ function DevShellInner({
|
|
|
3677
3992
|
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
3993
|
title: `Theme: ${theme.mode}`,
|
|
3679
3994
|
children: [
|
|
3680
|
-
theme.resolvedMode === "dark" ? /* @__PURE__ */ (0,
|
|
3995
|
+
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
3996
|
theme.mode === "dark" ? "Dark" : theme.mode === "light" ? "Light" : "System"
|
|
3682
3997
|
]
|
|
3683
3998
|
}
|
|
3684
3999
|
),
|
|
3685
|
-
/* @__PURE__ */ (0,
|
|
4000
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
3686
4001
|
"button",
|
|
3687
4002
|
{
|
|
3688
4003
|
type: "button",
|
|
@@ -3693,7 +4008,7 @@ function DevShellInner({
|
|
|
3693
4008
|
)
|
|
3694
4009
|
] })
|
|
3695
4010
|
] }),
|
|
3696
|
-
/* @__PURE__ */ (0,
|
|
4011
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { className: "p-4", children: children({ trpc, theme }) })
|
|
3697
4012
|
] }) });
|
|
3698
4013
|
}
|
|
3699
4014
|
function DevShell({
|
|
@@ -3701,8 +4016,8 @@ function DevShell({
|
|
|
3701
4016
|
serverUrl = "https://localhost:4443",
|
|
3702
4017
|
title
|
|
3703
4018
|
}) {
|
|
3704
|
-
const [token, setToken] = (0,
|
|
3705
|
-
const handleLogin = (0,
|
|
4019
|
+
const [token, setToken] = (0, import_react32.useState)(getStoredToken);
|
|
4020
|
+
const handleLogin = (0, import_react32.useCallback)(
|
|
3706
4021
|
async (username, password) => {
|
|
3707
4022
|
const anonClient = (0, import_client.createTRPCClient)({
|
|
3708
4023
|
links: [
|
|
@@ -3719,14 +4034,14 @@ function DevShell({
|
|
|
3719
4034
|
},
|
|
3720
4035
|
[serverUrl]
|
|
3721
4036
|
);
|
|
3722
|
-
const handleLogout = (0,
|
|
4037
|
+
const handleLogout = (0, import_react32.useCallback)(() => {
|
|
3723
4038
|
localStorage.removeItem(STORAGE_KEY);
|
|
3724
4039
|
setToken(null);
|
|
3725
4040
|
}, []);
|
|
3726
4041
|
if (!token) {
|
|
3727
|
-
return /* @__PURE__ */ (0,
|
|
4042
|
+
return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(ThemeProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(LoginForm, { onLogin: handleLogin, serverUrl }) });
|
|
3728
4043
|
}
|
|
3729
|
-
return /* @__PURE__ */ (0,
|
|
4044
|
+
return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(ThemeProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
3730
4045
|
DevShellInner,
|
|
3731
4046
|
{
|
|
3732
4047
|
serverUrl,
|
|
@@ -3751,10 +4066,10 @@ function mountAddonPage(PageComponent, options = {}) {
|
|
|
3751
4066
|
return;
|
|
3752
4067
|
}
|
|
3753
4068
|
(0, import_client2.createRoot)(root).render(
|
|
3754
|
-
(0,
|
|
4069
|
+
(0, import_react33.createElement)(DevShell, {
|
|
3755
4070
|
serverUrl,
|
|
3756
4071
|
title,
|
|
3757
|
-
children: ({ trpc, theme }) => (0,
|
|
4072
|
+
children: ({ trpc, theme }) => (0, import_react33.createElement)(PageComponent, {
|
|
3758
4073
|
trpc,
|
|
3759
4074
|
theme: { isDark: theme.resolvedMode === "dark" },
|
|
3760
4075
|
navigate: (path) => {
|
|
@@ -3768,6 +4083,7 @@ function mountAddonPage(PageComponent, options = {}) {
|
|
|
3768
4083
|
0 && (module.exports = {
|
|
3769
4084
|
AppShell,
|
|
3770
4085
|
Badge,
|
|
4086
|
+
BottomSheet,
|
|
3771
4087
|
Button,
|
|
3772
4088
|
CLASS_COLORS,
|
|
3773
4089
|
Card,
|
|
@@ -3804,6 +4120,7 @@ function mountAddonPage(PageComponent, options = {}) {
|
|
|
3804
4120
|
KeyValueList,
|
|
3805
4121
|
Label,
|
|
3806
4122
|
LoginForm,
|
|
4123
|
+
MobileDrawer,
|
|
3807
4124
|
PageHeader,
|
|
3808
4125
|
PipelineBuilder,
|
|
3809
4126
|
PipelineRuntimeSelector,
|
|
@@ -3843,6 +4160,7 @@ function mountAddonPage(PageComponent, options = {}) {
|
|
|
3843
4160
|
statusIcons,
|
|
3844
4161
|
themeToCss,
|
|
3845
4162
|
useDevShell,
|
|
4163
|
+
useIsMobile,
|
|
3846
4164
|
useThemeMode
|
|
3847
4165
|
});
|
|
3848
4166
|
//# sourceMappingURL=index.cjs.map
|