@camstack/ui-library 0.1.35 → 0.1.37
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 +316 -192
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +403 -279
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -917,12 +917,92 @@ import {
|
|
|
917
917
|
createContext as createContext5,
|
|
918
918
|
useCallback as useCallback4,
|
|
919
919
|
useContext as useContext5,
|
|
920
|
-
useEffect as
|
|
920
|
+
useEffect as useEffect5,
|
|
921
921
|
useId as useId4,
|
|
922
922
|
useRef as useRef4,
|
|
923
923
|
useState as useState5
|
|
924
924
|
} from "react";
|
|
925
|
-
|
|
925
|
+
|
|
926
|
+
// src/hooks/use-is-mobile.ts
|
|
927
|
+
import { useSyncExternalStore } from "react";
|
|
928
|
+
var MOBILE_QUERY = "(max-width: 767px)";
|
|
929
|
+
function subscribe(callback) {
|
|
930
|
+
const mql = window.matchMedia(MOBILE_QUERY);
|
|
931
|
+
mql.addEventListener("change", callback);
|
|
932
|
+
return () => mql.removeEventListener("change", callback);
|
|
933
|
+
}
|
|
934
|
+
function getSnapshot() {
|
|
935
|
+
return window.matchMedia(MOBILE_QUERY).matches;
|
|
936
|
+
}
|
|
937
|
+
function getServerSnapshot() {
|
|
938
|
+
return false;
|
|
939
|
+
}
|
|
940
|
+
function useIsMobile() {
|
|
941
|
+
return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
// src/primitives/bottom-sheet.tsx
|
|
945
|
+
import { useEffect as useEffect4 } from "react";
|
|
946
|
+
import { X } from "lucide-react";
|
|
947
|
+
import { Fragment, jsx as jsx16, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
948
|
+
function BottomSheet({ open, onClose, title, children, className }) {
|
|
949
|
+
useEffect4(() => {
|
|
950
|
+
if (!open) return;
|
|
951
|
+
const handleKeyDown = (e) => {
|
|
952
|
+
if (e.key === "Escape") onClose();
|
|
953
|
+
};
|
|
954
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
955
|
+
document.body.style.overflow = "hidden";
|
|
956
|
+
return () => {
|
|
957
|
+
document.removeEventListener("keydown", handleKeyDown);
|
|
958
|
+
document.body.style.overflow = "";
|
|
959
|
+
};
|
|
960
|
+
}, [open, onClose]);
|
|
961
|
+
return /* @__PURE__ */ jsxs5(Fragment, { children: [
|
|
962
|
+
/* @__PURE__ */ jsx16(
|
|
963
|
+
"div",
|
|
964
|
+
{
|
|
965
|
+
className: cn(
|
|
966
|
+
"fixed inset-0 z-40 bg-black/50 transition-opacity duration-200",
|
|
967
|
+
open ? "opacity-100" : "pointer-events-none opacity-0"
|
|
968
|
+
),
|
|
969
|
+
onClick: onClose,
|
|
970
|
+
"aria-hidden": "true"
|
|
971
|
+
}
|
|
972
|
+
),
|
|
973
|
+
/* @__PURE__ */ jsxs5(
|
|
974
|
+
"div",
|
|
975
|
+
{
|
|
976
|
+
role: "dialog",
|
|
977
|
+
"aria-modal": "true",
|
|
978
|
+
className: cn(
|
|
979
|
+
"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",
|
|
980
|
+
"max-h-[80dvh]",
|
|
981
|
+
open ? "translate-y-0" : "translate-y-full",
|
|
982
|
+
className
|
|
983
|
+
),
|
|
984
|
+
children: [
|
|
985
|
+
/* @__PURE__ */ jsx16("div", { className: "flex justify-center pt-2 pb-1", children: /* @__PURE__ */ jsx16("div", { className: "h-1 w-8 rounded-full bg-foreground-subtle/30" }) }),
|
|
986
|
+
title && /* @__PURE__ */ jsxs5("div", { className: "flex items-center justify-between px-4 pb-2", children: [
|
|
987
|
+
/* @__PURE__ */ jsx16("span", { className: "text-sm font-medium text-foreground", children: title }),
|
|
988
|
+
/* @__PURE__ */ jsx16(
|
|
989
|
+
"button",
|
|
990
|
+
{
|
|
991
|
+
onClick: onClose,
|
|
992
|
+
className: "p-1 rounded-md hover:bg-surface-hover text-foreground-muted transition-colors",
|
|
993
|
+
children: /* @__PURE__ */ jsx16(X, { className: "h-4 w-4" })
|
|
994
|
+
}
|
|
995
|
+
)
|
|
996
|
+
] }),
|
|
997
|
+
/* @__PURE__ */ jsx16("div", { className: "flex-1 overflow-y-auto px-4 pb-4", children })
|
|
998
|
+
]
|
|
999
|
+
}
|
|
1000
|
+
)
|
|
1001
|
+
] });
|
|
1002
|
+
}
|
|
1003
|
+
|
|
1004
|
+
// src/primitives/popover.tsx
|
|
1005
|
+
import { jsx as jsx17 } from "react/jsx-runtime";
|
|
926
1006
|
var PopoverContext = createContext5(null);
|
|
927
1007
|
function usePopoverContext() {
|
|
928
1008
|
const ctx = useContext5(PopoverContext);
|
|
@@ -941,11 +1021,11 @@ function Popover({ children, open: controlledOpen, onOpenChange }) {
|
|
|
941
1021
|
},
|
|
942
1022
|
[controlledOpen, onOpenChange]
|
|
943
1023
|
);
|
|
944
|
-
return /* @__PURE__ */
|
|
1024
|
+
return /* @__PURE__ */ jsx17(PopoverContext.Provider, { value: { open, setOpen, triggerId, contentId }, children: /* @__PURE__ */ jsx17("div", { className: "relative inline-block", children }) });
|
|
945
1025
|
}
|
|
946
1026
|
function PopoverTrigger({ children, ...props }) {
|
|
947
1027
|
const { open, setOpen, triggerId, contentId } = usePopoverContext();
|
|
948
|
-
return /* @__PURE__ */
|
|
1028
|
+
return /* @__PURE__ */ jsx17(
|
|
949
1029
|
"button",
|
|
950
1030
|
{
|
|
951
1031
|
type: "button",
|
|
@@ -961,9 +1041,10 @@ function PopoverTrigger({ children, ...props }) {
|
|
|
961
1041
|
}
|
|
962
1042
|
function PopoverContent({ className, children, ...props }) {
|
|
963
1043
|
const { open, setOpen, contentId, triggerId } = usePopoverContext();
|
|
1044
|
+
const isMobile = useIsMobile();
|
|
964
1045
|
const ref = useRef4(null);
|
|
965
|
-
|
|
966
|
-
if (!open) return;
|
|
1046
|
+
useEffect5(() => {
|
|
1047
|
+
if (!open || isMobile) return;
|
|
967
1048
|
const handler = (e) => {
|
|
968
1049
|
const el = ref.current;
|
|
969
1050
|
const trigger = document.getElementById(triggerId);
|
|
@@ -980,9 +1061,12 @@ function PopoverContent({ className, children, ...props }) {
|
|
|
980
1061
|
document.removeEventListener("mousedown", handler);
|
|
981
1062
|
document.removeEventListener("keydown", escHandler);
|
|
982
1063
|
};
|
|
983
|
-
}, [open, setOpen, triggerId]);
|
|
1064
|
+
}, [open, setOpen, triggerId, isMobile]);
|
|
984
1065
|
if (!open) return null;
|
|
985
|
-
|
|
1066
|
+
if (isMobile) {
|
|
1067
|
+
return /* @__PURE__ */ jsx17(BottomSheet, { open, onClose: () => setOpen(false), children });
|
|
1068
|
+
}
|
|
1069
|
+
return /* @__PURE__ */ jsx17(
|
|
986
1070
|
"div",
|
|
987
1071
|
{
|
|
988
1072
|
ref,
|
|
@@ -1006,7 +1090,7 @@ import {
|
|
|
1006
1090
|
useContext as useContext6,
|
|
1007
1091
|
useState as useState6
|
|
1008
1092
|
} from "react";
|
|
1009
|
-
import { jsx as
|
|
1093
|
+
import { jsx as jsx18 } from "react/jsx-runtime";
|
|
1010
1094
|
var TabsContext = createContext6(null);
|
|
1011
1095
|
function useTabsContext() {
|
|
1012
1096
|
const ctx = useContext6(TabsContext);
|
|
@@ -1029,10 +1113,10 @@ function Tabs({
|
|
|
1029
1113
|
},
|
|
1030
1114
|
[controlledValue, onValueChange]
|
|
1031
1115
|
);
|
|
1032
|
-
return /* @__PURE__ */
|
|
1116
|
+
return /* @__PURE__ */ jsx18(TabsContext.Provider, { value: { value, setValue }, children: /* @__PURE__ */ jsx18("div", { className, ...props }) });
|
|
1033
1117
|
}
|
|
1034
1118
|
function TabsList({ className, ...props }) {
|
|
1035
|
-
return /* @__PURE__ */
|
|
1119
|
+
return /* @__PURE__ */ jsx18(
|
|
1036
1120
|
"div",
|
|
1037
1121
|
{
|
|
1038
1122
|
role: "tablist",
|
|
@@ -1045,7 +1129,7 @@ function TabsTrigger({ value, className, ...props }) {
|
|
|
1045
1129
|
const { value: activeValue, setValue } = useTabsContext();
|
|
1046
1130
|
const isActive = value === activeValue;
|
|
1047
1131
|
const panelId = `tabpanel-${value}`;
|
|
1048
|
-
return /* @__PURE__ */
|
|
1132
|
+
return /* @__PURE__ */ jsx18(
|
|
1049
1133
|
"button",
|
|
1050
1134
|
{
|
|
1051
1135
|
type: "button",
|
|
@@ -1066,7 +1150,7 @@ function TabsTrigger({ value, className, ...props }) {
|
|
|
1066
1150
|
function TabsContent({ value, className, ...props }) {
|
|
1067
1151
|
const { value: activeValue } = useTabsContext();
|
|
1068
1152
|
if (value !== activeValue) return null;
|
|
1069
|
-
return /* @__PURE__ */
|
|
1153
|
+
return /* @__PURE__ */ jsx18(
|
|
1070
1154
|
"div",
|
|
1071
1155
|
{
|
|
1072
1156
|
role: "tabpanel",
|
|
@@ -1079,10 +1163,10 @@ function TabsContent({ value, className, ...props }) {
|
|
|
1079
1163
|
|
|
1080
1164
|
// src/primitives/scroll-area.tsx
|
|
1081
1165
|
import { forwardRef as forwardRef13 } from "react";
|
|
1082
|
-
import { jsx as
|
|
1166
|
+
import { jsx as jsx19 } from "react/jsx-runtime";
|
|
1083
1167
|
var ScrollArea = forwardRef13(
|
|
1084
1168
|
({ className, ...props }, ref) => {
|
|
1085
|
-
return /* @__PURE__ */
|
|
1169
|
+
return /* @__PURE__ */ jsx19(
|
|
1086
1170
|
"div",
|
|
1087
1171
|
{
|
|
1088
1172
|
ref,
|
|
@@ -1098,29 +1182,9 @@ var ScrollArea = forwardRef13(
|
|
|
1098
1182
|
ScrollArea.displayName = "ScrollArea";
|
|
1099
1183
|
|
|
1100
1184
|
// src/primitives/floating-panel.tsx
|
|
1101
|
-
import { useRef as useRef5, useState as useState7, useCallback as useCallback6, useEffect as
|
|
1102
|
-
import { X, Minimize2, Maximize2, GripHorizontal } from "lucide-react";
|
|
1103
|
-
|
|
1104
|
-
// src/hooks/use-is-mobile.ts
|
|
1105
|
-
import { useSyncExternalStore } from "react";
|
|
1106
|
-
var MOBILE_QUERY = "(max-width: 767px)";
|
|
1107
|
-
function subscribe(callback) {
|
|
1108
|
-
const mql = window.matchMedia(MOBILE_QUERY);
|
|
1109
|
-
mql.addEventListener("change", callback);
|
|
1110
|
-
return () => mql.removeEventListener("change", callback);
|
|
1111
|
-
}
|
|
1112
|
-
function getSnapshot() {
|
|
1113
|
-
return window.matchMedia(MOBILE_QUERY).matches;
|
|
1114
|
-
}
|
|
1115
|
-
function getServerSnapshot() {
|
|
1116
|
-
return false;
|
|
1117
|
-
}
|
|
1118
|
-
function useIsMobile() {
|
|
1119
|
-
return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
|
|
1120
|
-
}
|
|
1121
|
-
|
|
1122
|
-
// src/primitives/floating-panel.tsx
|
|
1123
|
-
import { jsx as jsx19, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1185
|
+
import { useRef as useRef5, useState as useState7, useCallback as useCallback6, useEffect as useEffect6 } from "react";
|
|
1186
|
+
import { X as X2, Minimize2, Maximize2, GripHorizontal } from "lucide-react";
|
|
1187
|
+
import { jsx as jsx20, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1124
1188
|
function FloatingPanel({
|
|
1125
1189
|
title,
|
|
1126
1190
|
onClose,
|
|
@@ -1150,7 +1214,7 @@ function FloatingPanel({
|
|
|
1150
1214
|
resizing.current = true;
|
|
1151
1215
|
offset.current = { x: e.clientX, y: e.clientY };
|
|
1152
1216
|
}, []);
|
|
1153
|
-
|
|
1217
|
+
useEffect6(() => {
|
|
1154
1218
|
const onMouseMove = (e) => {
|
|
1155
1219
|
if (dragging.current) setPos({ x: e.clientX - offset.current.x, y: e.clientY - offset.current.y });
|
|
1156
1220
|
if (resizing.current) {
|
|
@@ -1172,7 +1236,7 @@ function FloatingPanel({
|
|
|
1172
1236
|
};
|
|
1173
1237
|
}, [minWidth, minHeight]);
|
|
1174
1238
|
if (isMobile) {
|
|
1175
|
-
return /* @__PURE__ */
|
|
1239
|
+
return /* @__PURE__ */ jsxs6(
|
|
1176
1240
|
"div",
|
|
1177
1241
|
{
|
|
1178
1242
|
className: cn(
|
|
@@ -1181,33 +1245,33 @@ function FloatingPanel({
|
|
|
1181
1245
|
),
|
|
1182
1246
|
style: { maxHeight: "60dvh" },
|
|
1183
1247
|
children: [
|
|
1184
|
-
/* @__PURE__ */
|
|
1185
|
-
/* @__PURE__ */
|
|
1186
|
-
/* @__PURE__ */
|
|
1187
|
-
/* @__PURE__ */
|
|
1248
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex items-center justify-between gap-2 px-3 py-2 border-b border-border shrink-0 bg-surface", children: [
|
|
1249
|
+
/* @__PURE__ */ jsx20("span", { className: "text-[11px] font-medium truncate", children: title }),
|
|
1250
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-1 shrink-0", children: [
|
|
1251
|
+
/* @__PURE__ */ jsx20(
|
|
1188
1252
|
"button",
|
|
1189
1253
|
{
|
|
1190
1254
|
onClick: () => setMinimized(!minimized),
|
|
1191
1255
|
className: "p-0.5 rounded hover:bg-surface-hover text-foreground-muted transition-colors",
|
|
1192
|
-
children: minimized ? /* @__PURE__ */
|
|
1256
|
+
children: minimized ? /* @__PURE__ */ jsx20(Maximize2, { size: 12 }) : /* @__PURE__ */ jsx20(Minimize2, { size: 12 })
|
|
1193
1257
|
}
|
|
1194
1258
|
),
|
|
1195
|
-
/* @__PURE__ */
|
|
1259
|
+
/* @__PURE__ */ jsx20(
|
|
1196
1260
|
"button",
|
|
1197
1261
|
{
|
|
1198
1262
|
onClick: onClose,
|
|
1199
1263
|
className: "p-0.5 rounded hover:bg-danger/20 text-foreground-muted hover:text-danger transition-colors",
|
|
1200
|
-
children: /* @__PURE__ */
|
|
1264
|
+
children: /* @__PURE__ */ jsx20(X2, { size: 12 })
|
|
1201
1265
|
}
|
|
1202
1266
|
)
|
|
1203
1267
|
] })
|
|
1204
1268
|
] }),
|
|
1205
|
-
!minimized && /* @__PURE__ */
|
|
1269
|
+
!minimized && /* @__PURE__ */ jsx20("div", { className: "flex-1 min-h-0 overflow-y-auto", children })
|
|
1206
1270
|
]
|
|
1207
1271
|
}
|
|
1208
1272
|
);
|
|
1209
1273
|
}
|
|
1210
|
-
return /* @__PURE__ */
|
|
1274
|
+
return /* @__PURE__ */ jsxs6(
|
|
1211
1275
|
"div",
|
|
1212
1276
|
{
|
|
1213
1277
|
className: cn(
|
|
@@ -1216,42 +1280,42 @@ function FloatingPanel({
|
|
|
1216
1280
|
),
|
|
1217
1281
|
style: { left: pos.x, top: pos.y, width: minimized ? 280 : size.w, height: minimized ? "auto" : size.h },
|
|
1218
1282
|
children: [
|
|
1219
|
-
/* @__PURE__ */
|
|
1283
|
+
/* @__PURE__ */ jsxs6(
|
|
1220
1284
|
"div",
|
|
1221
1285
|
{
|
|
1222
1286
|
onMouseDown: onDragStart,
|
|
1223
1287
|
className: "flex items-center justify-between gap-2 px-3 py-2 border-b border-border cursor-move select-none shrink-0 bg-surface",
|
|
1224
1288
|
children: [
|
|
1225
|
-
/* @__PURE__ */
|
|
1226
|
-
/* @__PURE__ */
|
|
1227
|
-
/* @__PURE__ */
|
|
1289
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2 min-w-0", children: [
|
|
1290
|
+
/* @__PURE__ */ jsx20(GripHorizontal, { size: 12, className: "text-foreground-subtle shrink-0" }),
|
|
1291
|
+
/* @__PURE__ */ jsx20("span", { className: "text-[11px] font-medium truncate", children: title })
|
|
1228
1292
|
] }),
|
|
1229
|
-
/* @__PURE__ */
|
|
1230
|
-
/* @__PURE__ */
|
|
1293
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-1 shrink-0", children: [
|
|
1294
|
+
/* @__PURE__ */ jsx20(
|
|
1231
1295
|
"button",
|
|
1232
1296
|
{
|
|
1233
1297
|
onClick: () => setMinimized(!minimized),
|
|
1234
1298
|
className: "p-0.5 rounded hover:bg-surface-hover text-foreground-muted transition-colors",
|
|
1235
1299
|
title: minimized ? "Restore" : "Minimize",
|
|
1236
|
-
children: minimized ? /* @__PURE__ */
|
|
1300
|
+
children: minimized ? /* @__PURE__ */ jsx20(Maximize2, { size: 12 }) : /* @__PURE__ */ jsx20(Minimize2, { size: 12 })
|
|
1237
1301
|
}
|
|
1238
1302
|
),
|
|
1239
|
-
/* @__PURE__ */
|
|
1303
|
+
/* @__PURE__ */ jsx20(
|
|
1240
1304
|
"button",
|
|
1241
1305
|
{
|
|
1242
1306
|
onClick: onClose,
|
|
1243
1307
|
className: "p-0.5 rounded hover:bg-danger/20 text-foreground-muted hover:text-danger transition-colors",
|
|
1244
1308
|
title: "Close",
|
|
1245
|
-
children: /* @__PURE__ */
|
|
1309
|
+
children: /* @__PURE__ */ jsx20(X2, { size: 12 })
|
|
1246
1310
|
}
|
|
1247
1311
|
)
|
|
1248
1312
|
] })
|
|
1249
1313
|
]
|
|
1250
1314
|
}
|
|
1251
1315
|
),
|
|
1252
|
-
!minimized && /* @__PURE__ */
|
|
1316
|
+
!minimized && /* @__PURE__ */ jsxs6("div", { className: "flex-1 min-h-0 overflow-y-auto relative", children: [
|
|
1253
1317
|
children,
|
|
1254
|
-
/* @__PURE__ */
|
|
1318
|
+
/* @__PURE__ */ jsx20(
|
|
1255
1319
|
"div",
|
|
1256
1320
|
{
|
|
1257
1321
|
onMouseDown: onResizeStart,
|
|
@@ -1266,11 +1330,11 @@ function FloatingPanel({
|
|
|
1266
1330
|
}
|
|
1267
1331
|
|
|
1268
1332
|
// src/primitives/mobile-drawer.tsx
|
|
1269
|
-
import { useEffect as
|
|
1270
|
-
import { Fragment, jsx as
|
|
1333
|
+
import { useEffect as useEffect7, useRef as useRef6 } from "react";
|
|
1334
|
+
import { Fragment as Fragment2, jsx as jsx21, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1271
1335
|
function MobileDrawer({ open, onClose, children, className, width = "w-64" }) {
|
|
1272
1336
|
const drawerRef = useRef6(null);
|
|
1273
|
-
|
|
1337
|
+
useEffect7(() => {
|
|
1274
1338
|
if (!open) return;
|
|
1275
1339
|
const handleKeyDown = (e) => {
|
|
1276
1340
|
if (e.key === "Escape") onClose();
|
|
@@ -1282,8 +1346,8 @@ function MobileDrawer({ open, onClose, children, className, width = "w-64" }) {
|
|
|
1282
1346
|
document.body.style.overflow = "";
|
|
1283
1347
|
};
|
|
1284
1348
|
}, [open, onClose]);
|
|
1285
|
-
return /* @__PURE__ */
|
|
1286
|
-
/* @__PURE__ */
|
|
1349
|
+
return /* @__PURE__ */ jsxs7(Fragment2, { children: [
|
|
1350
|
+
/* @__PURE__ */ jsx21(
|
|
1287
1351
|
"div",
|
|
1288
1352
|
{
|
|
1289
1353
|
className: cn(
|
|
@@ -1294,7 +1358,7 @@ function MobileDrawer({ open, onClose, children, className, width = "w-64" }) {
|
|
|
1294
1358
|
"aria-hidden": "true"
|
|
1295
1359
|
}
|
|
1296
1360
|
),
|
|
1297
|
-
/* @__PURE__ */
|
|
1361
|
+
/* @__PURE__ */ jsx21(
|
|
1298
1362
|
"div",
|
|
1299
1363
|
{
|
|
1300
1364
|
ref: drawerRef,
|
|
@@ -1312,66 +1376,6 @@ function MobileDrawer({ open, onClose, children, className, width = "w-64" }) {
|
|
|
1312
1376
|
] });
|
|
1313
1377
|
}
|
|
1314
1378
|
|
|
1315
|
-
// src/primitives/bottom-sheet.tsx
|
|
1316
|
-
import { useEffect as useEffect7 } from "react";
|
|
1317
|
-
import { X as X2 } from "lucide-react";
|
|
1318
|
-
import { Fragment as Fragment2, jsx as jsx21, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1319
|
-
function BottomSheet({ open, onClose, title, children, className }) {
|
|
1320
|
-
useEffect7(() => {
|
|
1321
|
-
if (!open) return;
|
|
1322
|
-
const handleKeyDown = (e) => {
|
|
1323
|
-
if (e.key === "Escape") onClose();
|
|
1324
|
-
};
|
|
1325
|
-
document.addEventListener("keydown", handleKeyDown);
|
|
1326
|
-
document.body.style.overflow = "hidden";
|
|
1327
|
-
return () => {
|
|
1328
|
-
document.removeEventListener("keydown", handleKeyDown);
|
|
1329
|
-
document.body.style.overflow = "";
|
|
1330
|
-
};
|
|
1331
|
-
}, [open, onClose]);
|
|
1332
|
-
return /* @__PURE__ */ jsxs7(Fragment2, { children: [
|
|
1333
|
-
/* @__PURE__ */ jsx21(
|
|
1334
|
-
"div",
|
|
1335
|
-
{
|
|
1336
|
-
className: cn(
|
|
1337
|
-
"fixed inset-0 z-40 bg-black/50 transition-opacity duration-200",
|
|
1338
|
-
open ? "opacity-100" : "pointer-events-none opacity-0"
|
|
1339
|
-
),
|
|
1340
|
-
onClick: onClose,
|
|
1341
|
-
"aria-hidden": "true"
|
|
1342
|
-
}
|
|
1343
|
-
),
|
|
1344
|
-
/* @__PURE__ */ jsxs7(
|
|
1345
|
-
"div",
|
|
1346
|
-
{
|
|
1347
|
-
role: "dialog",
|
|
1348
|
-
"aria-modal": "true",
|
|
1349
|
-
className: cn(
|
|
1350
|
-
"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",
|
|
1351
|
-
"max-h-[80dvh]",
|
|
1352
|
-
open ? "translate-y-0" : "translate-y-full",
|
|
1353
|
-
className
|
|
1354
|
-
),
|
|
1355
|
-
children: [
|
|
1356
|
-
/* @__PURE__ */ jsx21("div", { className: "flex justify-center pt-2 pb-1", children: /* @__PURE__ */ jsx21("div", { className: "h-1 w-8 rounded-full bg-foreground-subtle/30" }) }),
|
|
1357
|
-
title && /* @__PURE__ */ jsxs7("div", { className: "flex items-center justify-between px-4 pb-2", children: [
|
|
1358
|
-
/* @__PURE__ */ jsx21("span", { className: "text-sm font-medium text-foreground", children: title }),
|
|
1359
|
-
/* @__PURE__ */ jsx21(
|
|
1360
|
-
"button",
|
|
1361
|
-
{
|
|
1362
|
-
onClick: onClose,
|
|
1363
|
-
className: "p-1 rounded-md hover:bg-surface-hover text-foreground-muted transition-colors",
|
|
1364
|
-
children: /* @__PURE__ */ jsx21(X2, { className: "h-4 w-4" })
|
|
1365
|
-
}
|
|
1366
|
-
)
|
|
1367
|
-
] }),
|
|
1368
|
-
/* @__PURE__ */ jsx21("div", { className: "flex-1 overflow-y-auto px-4 pb-4", children })
|
|
1369
|
-
]
|
|
1370
|
-
}
|
|
1371
|
-
)
|
|
1372
|
-
] });
|
|
1373
|
-
}
|
|
1374
|
-
|
|
1375
1379
|
// src/composites/status-badge.tsx
|
|
1376
1380
|
import { jsx as jsx22, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1377
1381
|
var statusConfig = {
|
|
@@ -1627,12 +1631,79 @@ function CodeBlock({ children, maxHeight = 300, className }) {
|
|
|
1627
1631
|
}
|
|
1628
1632
|
|
|
1629
1633
|
// src/composites/filter-bar.tsx
|
|
1630
|
-
import {
|
|
1631
|
-
import {
|
|
1634
|
+
import { useState as useState9 } from "react";
|
|
1635
|
+
import { Search, SlidersHorizontal } from "lucide-react";
|
|
1636
|
+
import { Fragment as Fragment3, jsx as jsx32, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
1632
1637
|
function FilterBar({ filters, values, onChange, className }) {
|
|
1638
|
+
const isMobile = useIsMobile();
|
|
1639
|
+
const [sheetOpen, setSheetOpen] = useState9(false);
|
|
1633
1640
|
const handleChange = (key, value) => {
|
|
1634
1641
|
onChange({ ...values, [key]: value });
|
|
1635
1642
|
};
|
|
1643
|
+
const activeCount = Object.values(values).filter((v) => v !== void 0 && v !== "").length;
|
|
1644
|
+
if (isMobile) {
|
|
1645
|
+
const searchFilter = filters.find((f) => f.type === "search");
|
|
1646
|
+
const hasNonSearchFilters = filters.some((f) => f.type !== "search");
|
|
1647
|
+
return /* @__PURE__ */ jsxs17("div", { className: cn("flex items-center gap-2", className), children: [
|
|
1648
|
+
searchFilter && /* @__PURE__ */ jsx32(
|
|
1649
|
+
Input,
|
|
1650
|
+
{
|
|
1651
|
+
placeholder: searchFilter.placeholder ?? "Search...",
|
|
1652
|
+
value: values[searchFilter.key] ?? "",
|
|
1653
|
+
onChange: (e) => handleChange(searchFilter.key, e.target.value),
|
|
1654
|
+
leftSlot: /* @__PURE__ */ jsx32(Search, { className: "h-3 w-3 text-foreground-subtle" }),
|
|
1655
|
+
className: "flex-1"
|
|
1656
|
+
}
|
|
1657
|
+
),
|
|
1658
|
+
hasNonSearchFilters && /* @__PURE__ */ jsxs17(Fragment3, { children: [
|
|
1659
|
+
/* @__PURE__ */ jsxs17(
|
|
1660
|
+
"button",
|
|
1661
|
+
{
|
|
1662
|
+
onClick: () => setSheetOpen(true),
|
|
1663
|
+
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",
|
|
1664
|
+
children: [
|
|
1665
|
+
/* @__PURE__ */ jsx32(SlidersHorizontal, { className: "h-3.5 w-3.5" }),
|
|
1666
|
+
"Filters",
|
|
1667
|
+
activeCount > 0 && /* @__PURE__ */ jsx32(Badge, { variant: "info", className: "ml-1 text-[10px] px-1 py-0", children: activeCount })
|
|
1668
|
+
]
|
|
1669
|
+
}
|
|
1670
|
+
),
|
|
1671
|
+
/* @__PURE__ */ jsx32(BottomSheet, { open: sheetOpen, onClose: () => setSheetOpen(false), title: "Filters", children: /* @__PURE__ */ jsx32("div", { className: "flex flex-col gap-3", children: filters.filter((f) => f.type !== "search").map((filter) => {
|
|
1672
|
+
switch (filter.type) {
|
|
1673
|
+
case "select":
|
|
1674
|
+
return /* @__PURE__ */ jsxs17("div", { children: [
|
|
1675
|
+
/* @__PURE__ */ jsx32("label", { className: "text-xs text-foreground-muted mb-1 block", children: filter.label }),
|
|
1676
|
+
/* @__PURE__ */ jsx32(
|
|
1677
|
+
Select,
|
|
1678
|
+
{
|
|
1679
|
+
options: filter.options,
|
|
1680
|
+
value: values[filter.key] ?? "",
|
|
1681
|
+
onChange: (e) => handleChange(filter.key, e.target.value),
|
|
1682
|
+
className: "w-full"
|
|
1683
|
+
}
|
|
1684
|
+
)
|
|
1685
|
+
] }, filter.key);
|
|
1686
|
+
case "badge-toggle":
|
|
1687
|
+
return /* @__PURE__ */ jsx32("div", { className: "flex items-center gap-1 flex-wrap", children: filter.options.map((option) => {
|
|
1688
|
+
const currentValue = values[filter.key];
|
|
1689
|
+
const isActive = currentValue === option.value;
|
|
1690
|
+
return /* @__PURE__ */ jsx32(
|
|
1691
|
+
"button",
|
|
1692
|
+
{
|
|
1693
|
+
type: "button",
|
|
1694
|
+
onClick: () => handleChange(filter.key, isActive ? void 0 : option.value),
|
|
1695
|
+
children: /* @__PURE__ */ jsx32(Badge, { variant: isActive ? "info" : "default", className: "cursor-pointer", children: option.label })
|
|
1696
|
+
},
|
|
1697
|
+
option.value
|
|
1698
|
+
);
|
|
1699
|
+
}) }, filter.key);
|
|
1700
|
+
default:
|
|
1701
|
+
return null;
|
|
1702
|
+
}
|
|
1703
|
+
}) }) })
|
|
1704
|
+
] })
|
|
1705
|
+
] });
|
|
1706
|
+
}
|
|
1636
1707
|
return /* @__PURE__ */ jsx32("div", { className: cn("flex items-center gap-2 flex-wrap", className), children: filters.map((filter) => {
|
|
1637
1708
|
switch (filter.type) {
|
|
1638
1709
|
case "search":
|
|
@@ -1666,18 +1737,8 @@ function FilterBar({ filters, values, onChange, className }) {
|
|
|
1666
1737
|
"button",
|
|
1667
1738
|
{
|
|
1668
1739
|
type: "button",
|
|
1669
|
-
onClick: () => handleChange(
|
|
1670
|
-
|
|
1671
|
-
isActive ? void 0 : option.value
|
|
1672
|
-
),
|
|
1673
|
-
children: /* @__PURE__ */ jsx32(
|
|
1674
|
-
Badge,
|
|
1675
|
-
{
|
|
1676
|
-
variant: isActive ? "info" : "default",
|
|
1677
|
-
className: "cursor-pointer",
|
|
1678
|
-
children: option.label
|
|
1679
|
-
}
|
|
1680
|
-
)
|
|
1740
|
+
onClick: () => handleChange(filter.key, isActive ? void 0 : option.value),
|
|
1741
|
+
children: /* @__PURE__ */ jsx32(Badge, { variant: isActive ? "info" : "default", className: "cursor-pointer", children: option.label })
|
|
1681
1742
|
},
|
|
1682
1743
|
option.value
|
|
1683
1744
|
);
|
|
@@ -1689,7 +1750,7 @@ function FilterBar({ filters, values, onChange, className }) {
|
|
|
1689
1750
|
}
|
|
1690
1751
|
|
|
1691
1752
|
// src/composites/app-shell/sidebar-item.tsx
|
|
1692
|
-
import { jsx as jsx33, jsxs as
|
|
1753
|
+
import { jsx as jsx33, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
1693
1754
|
function SidebarItem({
|
|
1694
1755
|
label,
|
|
1695
1756
|
icon: Icon,
|
|
@@ -1698,7 +1759,7 @@ function SidebarItem({
|
|
|
1698
1759
|
active = false,
|
|
1699
1760
|
className
|
|
1700
1761
|
}) {
|
|
1701
|
-
return /* @__PURE__ */
|
|
1762
|
+
return /* @__PURE__ */ jsxs18(
|
|
1702
1763
|
"a",
|
|
1703
1764
|
{
|
|
1704
1765
|
href,
|
|
@@ -1717,9 +1778,9 @@ function SidebarItem({
|
|
|
1717
1778
|
}
|
|
1718
1779
|
|
|
1719
1780
|
// src/composites/app-shell/sidebar.tsx
|
|
1720
|
-
import { jsx as jsx34, jsxs as
|
|
1781
|
+
import { jsx as jsx34, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
1721
1782
|
function Sidebar({ logo, sections, footer, onNavigate, className }) {
|
|
1722
|
-
return /* @__PURE__ */
|
|
1783
|
+
return /* @__PURE__ */ jsxs19(
|
|
1723
1784
|
"nav",
|
|
1724
1785
|
{
|
|
1725
1786
|
className: cn(
|
|
@@ -1728,11 +1789,11 @@ function Sidebar({ logo, sections, footer, onNavigate, className }) {
|
|
|
1728
1789
|
),
|
|
1729
1790
|
children: [
|
|
1730
1791
|
logo && /* @__PURE__ */ jsx34("div", { className: "px-3 py-2 shrink-0", children: logo }),
|
|
1731
|
-
/* @__PURE__ */ jsx34("div", { className: "flex-1 overflow-auto px-1 py-1", children: sections.map((section, sectionIndex) => /* @__PURE__ */
|
|
1792
|
+
/* @__PURE__ */ jsx34("div", { className: "flex-1 overflow-auto px-1 py-1", children: sections.map((section, sectionIndex) => /* @__PURE__ */ jsxs19("div", { className: cn(sectionIndex > 0 ? "mt-3" : ""), children: [
|
|
1732
1793
|
section.label && /* @__PURE__ */ jsx34("span", { className: "text-[10px] text-foreground-disabled uppercase tracking-wider px-2 mb-1 block", children: section.label }),
|
|
1733
1794
|
/* @__PURE__ */ jsx34("div", { className: "flex flex-col gap-0.5", onClick: onNavigate, children: section.items.map((item) => /* @__PURE__ */ jsx34(SidebarItem, { ...item }, item.href)) })
|
|
1734
1795
|
] }, sectionIndex)) }),
|
|
1735
|
-
footer && footer.length > 0 && /* @__PURE__ */
|
|
1796
|
+
footer && footer.length > 0 && /* @__PURE__ */ jsxs19("div", { className: "shrink-0 px-1 pb-1", children: [
|
|
1736
1797
|
/* @__PURE__ */ jsx34(Separator, { className: "mb-1" }),
|
|
1737
1798
|
/* @__PURE__ */ jsx34("div", { className: "flex flex-col gap-0.5", onClick: onNavigate, children: footer.map((item) => /* @__PURE__ */ jsx34(SidebarItem, { ...item }, item.href)) })
|
|
1738
1799
|
] })
|
|
@@ -1742,13 +1803,13 @@ function Sidebar({ logo, sections, footer, onNavigate, className }) {
|
|
|
1742
1803
|
}
|
|
1743
1804
|
|
|
1744
1805
|
// src/composites/app-shell/app-shell.tsx
|
|
1745
|
-
import { useState as
|
|
1806
|
+
import { useState as useState10 } from "react";
|
|
1746
1807
|
import { ChevronRight, Menu } from "lucide-react";
|
|
1747
|
-
import { jsx as jsx35, jsxs as
|
|
1808
|
+
import { jsx as jsx35, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
1748
1809
|
function AppShell({ sidebar, header, mobileLogo, mobileActions, children, className }) {
|
|
1749
1810
|
const isMobile = useIsMobile();
|
|
1750
|
-
const [drawerOpen, setDrawerOpen] =
|
|
1751
|
-
return /* @__PURE__ */
|
|
1811
|
+
const [drawerOpen, setDrawerOpen] = useState10(false);
|
|
1812
|
+
return /* @__PURE__ */ jsxs20("div", { className: cn("flex h-screen", className), children: [
|
|
1752
1813
|
!isMobile && /* @__PURE__ */ jsx35(Sidebar, { ...sidebar, className: cn("w-44", sidebar.className) }),
|
|
1753
1814
|
isMobile && /* @__PURE__ */ jsx35(MobileDrawer, { open: drawerOpen, onClose: () => setDrawerOpen(false), width: "w-64", children: /* @__PURE__ */ jsx35(
|
|
1754
1815
|
Sidebar,
|
|
@@ -1758,8 +1819,8 @@ function AppShell({ sidebar, header, mobileLogo, mobileActions, children, classN
|
|
|
1758
1819
|
className: "w-full border-r-0"
|
|
1759
1820
|
}
|
|
1760
1821
|
) }),
|
|
1761
|
-
/* @__PURE__ */
|
|
1762
|
-
isMobile && /* @__PURE__ */
|
|
1822
|
+
/* @__PURE__ */ jsxs20("div", { className: "flex flex-1 flex-col min-w-0", children: [
|
|
1823
|
+
isMobile && /* @__PURE__ */ jsxs20("header", { className: "flex items-center h-12 border-b border-border px-3 shrink-0 bg-surface/80 backdrop-blur-sm", children: [
|
|
1763
1824
|
/* @__PURE__ */ jsx35(
|
|
1764
1825
|
"button",
|
|
1765
1826
|
{
|
|
@@ -1772,10 +1833,10 @@ function AppShell({ sidebar, header, mobileLogo, mobileActions, children, classN
|
|
|
1772
1833
|
mobileLogo && /* @__PURE__ */ jsx35("div", { className: "flex-1 flex justify-center", children: mobileLogo }),
|
|
1773
1834
|
mobileActions && /* @__PURE__ */ jsx35("div", { className: "shrink-0", children: mobileActions })
|
|
1774
1835
|
] }),
|
|
1775
|
-
!isMobile && header && /* @__PURE__ */
|
|
1836
|
+
!isMobile && header && /* @__PURE__ */ jsxs20("header", { className: "flex items-center h-10 border-b border-border px-4 shrink-0", children: [
|
|
1776
1837
|
header.breadcrumbs && header.breadcrumbs.length > 0 && /* @__PURE__ */ jsx35("nav", { className: "flex items-center gap-1 text-xs flex-1 min-w-0", children: header.breadcrumbs.map((crumb, index) => {
|
|
1777
1838
|
const isLast = index === header.breadcrumbs.length - 1;
|
|
1778
|
-
return /* @__PURE__ */
|
|
1839
|
+
return /* @__PURE__ */ jsxs20("span", { className: "flex items-center gap-1", children: [
|
|
1779
1840
|
index > 0 && /* @__PURE__ */ jsx35(ChevronRight, { className: "h-3 w-3 text-foreground-subtle shrink-0" }),
|
|
1780
1841
|
crumb.href && !isLast ? /* @__PURE__ */ jsx35(
|
|
1781
1842
|
"a",
|
|
@@ -1807,7 +1868,7 @@ import {
|
|
|
1807
1868
|
|
|
1808
1869
|
// src/composites/data-table/data-table-header.tsx
|
|
1809
1870
|
import { ArrowUpDown, ArrowUp, ArrowDown } from "lucide-react";
|
|
1810
|
-
import { jsx as jsx36, jsxs as
|
|
1871
|
+
import { jsx as jsx36, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
1811
1872
|
function DataTableHeader({
|
|
1812
1873
|
headerGroups,
|
|
1813
1874
|
onSortingChange,
|
|
@@ -1843,7 +1904,7 @@ function HeaderCell({ header, sortable, flexRender: render }) {
|
|
|
1843
1904
|
sortable && "cursor-pointer select-none"
|
|
1844
1905
|
),
|
|
1845
1906
|
onClick: sortable ? header.column.getToggleSortingHandler() : void 0,
|
|
1846
|
-
children: /* @__PURE__ */
|
|
1907
|
+
children: /* @__PURE__ */ jsxs21("span", { className: "inline-flex items-center gap-1", children: [
|
|
1847
1908
|
header.isPlaceholder ? null : render(header.column.columnDef.header, header.getContext()),
|
|
1848
1909
|
sortable && /* @__PURE__ */ jsx36(SortIcon, { className: "h-3 w-3" })
|
|
1849
1910
|
] })
|
|
@@ -1853,7 +1914,7 @@ function HeaderCell({ header, sortable, flexRender: render }) {
|
|
|
1853
1914
|
|
|
1854
1915
|
// src/composites/data-table/data-table-row.tsx
|
|
1855
1916
|
import { MoreHorizontal } from "lucide-react";
|
|
1856
|
-
import { jsx as jsx37, jsxs as
|
|
1917
|
+
import { jsx as jsx37, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
1857
1918
|
function DataTableRow({
|
|
1858
1919
|
row,
|
|
1859
1920
|
onRowClick,
|
|
@@ -1861,7 +1922,7 @@ function DataTableRow({
|
|
|
1861
1922
|
flexRender: render
|
|
1862
1923
|
}) {
|
|
1863
1924
|
const actions = rowActions ? rowActions(row.original) : [];
|
|
1864
|
-
return /* @__PURE__ */
|
|
1925
|
+
return /* @__PURE__ */ jsxs22(
|
|
1865
1926
|
"tr",
|
|
1866
1927
|
{
|
|
1867
1928
|
className: cn(
|
|
@@ -1872,7 +1933,7 @@ function DataTableRow({
|
|
|
1872
1933
|
onClick: onRowClick ? () => onRowClick(row.original) : void 0,
|
|
1873
1934
|
children: [
|
|
1874
1935
|
row.getVisibleCells().map((cell) => /* @__PURE__ */ jsx37(DataTableCell, { cell, flexRender: render }, cell.id)),
|
|
1875
|
-
actions.length > 0 && /* @__PURE__ */ jsx37("td", { className: "px-2 py-1.5 w-8", children: /* @__PURE__ */
|
|
1936
|
+
actions.length > 0 && /* @__PURE__ */ jsx37("td", { className: "px-2 py-1.5 w-8", children: /* @__PURE__ */ jsxs22(Dropdown, { children: [
|
|
1876
1937
|
/* @__PURE__ */ jsx37(
|
|
1877
1938
|
DropdownTrigger,
|
|
1878
1939
|
{
|
|
@@ -1905,7 +1966,7 @@ function DataTableCell({ cell, flexRender: render }) {
|
|
|
1905
1966
|
|
|
1906
1967
|
// src/composites/data-table/data-table-pagination.tsx
|
|
1907
1968
|
import { ChevronLeft, ChevronRight as ChevronRight2 } from "lucide-react";
|
|
1908
|
-
import { jsx as jsx38, jsxs as
|
|
1969
|
+
import { jsx as jsx38, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
1909
1970
|
var PAGE_SIZE_OPTIONS = [
|
|
1910
1971
|
{ value: "10", label: "10" },
|
|
1911
1972
|
{ value: "25", label: "25" },
|
|
@@ -1920,8 +1981,8 @@ function DataTablePagination({
|
|
|
1920
1981
|
}) {
|
|
1921
1982
|
const totalPages = Math.max(1, Math.ceil(total / pageSize));
|
|
1922
1983
|
const currentPage = page + 1;
|
|
1923
|
-
return /* @__PURE__ */
|
|
1924
|
-
/* @__PURE__ */
|
|
1984
|
+
return /* @__PURE__ */ jsxs23("div", { className: "flex items-center justify-between px-2 py-2 text-xs text-foreground-muted", children: [
|
|
1985
|
+
/* @__PURE__ */ jsxs23("div", { className: "flex items-center gap-2", children: [
|
|
1925
1986
|
/* @__PURE__ */ jsx38("span", { children: "Rows per page" }),
|
|
1926
1987
|
/* @__PURE__ */ jsx38("div", { className: "w-16", children: /* @__PURE__ */ jsx38(
|
|
1927
1988
|
Select,
|
|
@@ -1935,8 +1996,8 @@ function DataTablePagination({
|
|
|
1935
1996
|
}
|
|
1936
1997
|
) })
|
|
1937
1998
|
] }),
|
|
1938
|
-
/* @__PURE__ */
|
|
1939
|
-
/* @__PURE__ */
|
|
1999
|
+
/* @__PURE__ */ jsxs23("div", { className: "flex items-center gap-2", children: [
|
|
2000
|
+
/* @__PURE__ */ jsxs23("span", { children: [
|
|
1940
2001
|
"Page ",
|
|
1941
2002
|
currentPage,
|
|
1942
2003
|
" of ",
|
|
@@ -1969,7 +2030,7 @@ function DataTablePagination({
|
|
|
1969
2030
|
}
|
|
1970
2031
|
|
|
1971
2032
|
// src/composites/data-table/data-table.tsx
|
|
1972
|
-
import { Fragment as
|
|
2033
|
+
import { Fragment as Fragment4, jsx as jsx39, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
1973
2034
|
function DataTable({
|
|
1974
2035
|
data,
|
|
1975
2036
|
columns: userColumns,
|
|
@@ -1986,7 +2047,8 @@ function DataTable({
|
|
|
1986
2047
|
selectable = false,
|
|
1987
2048
|
compact = true,
|
|
1988
2049
|
stickyHeader = false,
|
|
1989
|
-
className
|
|
2050
|
+
className,
|
|
2051
|
+
mobileMode = "scroll"
|
|
1990
2052
|
}) {
|
|
1991
2053
|
const columns = useMemo2(() => {
|
|
1992
2054
|
if (!selectable) return userColumns;
|
|
@@ -2038,8 +2100,70 @@ function DataTable({
|
|
|
2038
2100
|
pageCount: pagination ? Math.ceil(pagination.total / pagination.pageSize) : void 0
|
|
2039
2101
|
});
|
|
2040
2102
|
const hasActions = !!rowActions;
|
|
2041
|
-
|
|
2042
|
-
|
|
2103
|
+
const isMobile = useIsMobile();
|
|
2104
|
+
const showCards = isMobile && mobileMode === "cards";
|
|
2105
|
+
if (showCards) {
|
|
2106
|
+
const rows = table.getRowModel().rows;
|
|
2107
|
+
if (loading) {
|
|
2108
|
+
return /* @__PURE__ */ jsx39("div", { className: cn("space-y-2", className), children: Array.from({ length: 3 }).map((_, i) => /* @__PURE__ */ jsxs24("div", { className: "rounded-lg border border-border bg-surface p-3 space-y-2", children: [
|
|
2109
|
+
/* @__PURE__ */ jsx39(Skeleton, { className: "h-3 w-3/4" }),
|
|
2110
|
+
/* @__PURE__ */ jsx39(Skeleton, { className: "h-3 w-1/2" }),
|
|
2111
|
+
/* @__PURE__ */ jsx39(Skeleton, { className: "h-3 w-2/3" })
|
|
2112
|
+
] }, i)) });
|
|
2113
|
+
}
|
|
2114
|
+
if (rows.length === 0) {
|
|
2115
|
+
return /* @__PURE__ */ jsx39("div", { className: cn("text-center py-8 text-xs text-foreground-muted", className), children: emptyState ?? "No data" });
|
|
2116
|
+
}
|
|
2117
|
+
return /* @__PURE__ */ jsxs24("div", { className: cn("space-y-2", className), children: [
|
|
2118
|
+
rows.map((row) => /* @__PURE__ */ jsxs24(
|
|
2119
|
+
"div",
|
|
2120
|
+
{
|
|
2121
|
+
className: cn(
|
|
2122
|
+
"rounded-lg border border-border bg-surface p-3 space-y-1.5",
|
|
2123
|
+
onRowClick && "cursor-pointer hover:bg-surface-hover transition-colors"
|
|
2124
|
+
),
|
|
2125
|
+
onClick: onRowClick ? () => onRowClick(row.original) : void 0,
|
|
2126
|
+
children: [
|
|
2127
|
+
row.getVisibleCells().filter((cell) => cell.column.id !== "__select").map((cell) => {
|
|
2128
|
+
const header = cell.column.columnDef.header;
|
|
2129
|
+
const label = typeof header === "string" ? header : cell.column.id;
|
|
2130
|
+
return /* @__PURE__ */ jsxs24("div", { className: "flex items-baseline justify-between gap-2 text-xs", children: [
|
|
2131
|
+
/* @__PURE__ */ jsx39("span", { className: "text-foreground-muted shrink-0", children: label }),
|
|
2132
|
+
/* @__PURE__ */ jsx39("span", { className: "text-foreground text-right truncate", children: flexRender(cell.column.columnDef.cell, cell.getContext()) })
|
|
2133
|
+
] }, cell.id);
|
|
2134
|
+
}),
|
|
2135
|
+
rowActions && /* @__PURE__ */ jsx39("div", { className: "flex items-center gap-1 pt-1 border-t border-border mt-1.5", children: rowActions(row.original).map((action, i) => /* @__PURE__ */ jsx39(
|
|
2136
|
+
"button",
|
|
2137
|
+
{
|
|
2138
|
+
onClick: (e) => {
|
|
2139
|
+
e.stopPropagation();
|
|
2140
|
+
action.onClick();
|
|
2141
|
+
},
|
|
2142
|
+
className: cn(
|
|
2143
|
+
"text-[11px] px-2 py-1 rounded-md transition-colors",
|
|
2144
|
+
action.variant === "danger" ? "text-danger hover:bg-danger/10" : "text-foreground-muted hover:bg-surface-hover"
|
|
2145
|
+
),
|
|
2146
|
+
children: action.label
|
|
2147
|
+
},
|
|
2148
|
+
i
|
|
2149
|
+
)) })
|
|
2150
|
+
]
|
|
2151
|
+
},
|
|
2152
|
+
row.id
|
|
2153
|
+
)),
|
|
2154
|
+
pagination && /* @__PURE__ */ jsx39(
|
|
2155
|
+
DataTablePagination,
|
|
2156
|
+
{
|
|
2157
|
+
page: pagination.page,
|
|
2158
|
+
pageSize: pagination.pageSize,
|
|
2159
|
+
total: pagination.total,
|
|
2160
|
+
onPaginationChange
|
|
2161
|
+
}
|
|
2162
|
+
)
|
|
2163
|
+
] });
|
|
2164
|
+
}
|
|
2165
|
+
return /* @__PURE__ */ jsxs24("div", { className: cn("overflow-x-auto", className), children: [
|
|
2166
|
+
/* @__PURE__ */ jsxs24("table", { className: "w-full border-collapse", children: [
|
|
2043
2167
|
/* @__PURE__ */ jsx39(
|
|
2044
2168
|
DataTableHeader,
|
|
2045
2169
|
{
|
|
@@ -2079,11 +2203,11 @@ function DataTable({
|
|
|
2079
2203
|
] });
|
|
2080
2204
|
}
|
|
2081
2205
|
function LoadingRows({ colSpan, compact }) {
|
|
2082
|
-
return /* @__PURE__ */ jsx39(
|
|
2206
|
+
return /* @__PURE__ */ jsx39(Fragment4, { children: Array.from({ length: 5 }).map((_, rowIdx) => /* @__PURE__ */ jsx39("tr", { className: compact ? "h-7" : "h-9", children: Array.from({ length: colSpan }).map((_2, colIdx) => /* @__PURE__ */ jsx39("td", { className: "px-2 py-1.5", children: /* @__PURE__ */ jsx39(Skeleton, { className: "h-3 w-full" }) }, colIdx)) }, rowIdx)) });
|
|
2083
2207
|
}
|
|
2084
2208
|
|
|
2085
2209
|
// src/composites/device-card.tsx
|
|
2086
|
-
import { jsx as jsx40, jsxs as
|
|
2210
|
+
import { jsx as jsx40, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
2087
2211
|
var STATUS_COLORS = {
|
|
2088
2212
|
online: "bg-success",
|
|
2089
2213
|
offline: "bg-danger",
|
|
@@ -2102,7 +2226,7 @@ function DeviceCard({
|
|
|
2102
2226
|
className
|
|
2103
2227
|
}) {
|
|
2104
2228
|
const isOffline = status === "offline";
|
|
2105
|
-
return /* @__PURE__ */
|
|
2229
|
+
return /* @__PURE__ */ jsxs25(
|
|
2106
2230
|
"div",
|
|
2107
2231
|
{
|
|
2108
2232
|
onClick,
|
|
@@ -2114,7 +2238,7 @@ function DeviceCard({
|
|
|
2114
2238
|
className
|
|
2115
2239
|
),
|
|
2116
2240
|
children: [
|
|
2117
|
-
/* @__PURE__ */
|
|
2241
|
+
/* @__PURE__ */ jsxs25("div", { className: "flex items-center justify-between mb-2", children: [
|
|
2118
2242
|
/* @__PURE__ */ jsx40("span", { className: "text-sm font-medium truncate", children: title }),
|
|
2119
2243
|
status && /* @__PURE__ */ jsx40("span", { className: cn("h-2 w-2 rounded-full shrink-0", STATUS_COLORS[status]) })
|
|
2120
2244
|
] }),
|
|
@@ -2125,7 +2249,7 @@ function DeviceCard({
|
|
|
2125
2249
|
selected ? "bg-primary/20" : "bg-surface-hover",
|
|
2126
2250
|
badge.onClick && "hover:opacity-80 transition-opacity cursor-pointer"
|
|
2127
2251
|
);
|
|
2128
|
-
return badge.onClick ? /* @__PURE__ */
|
|
2252
|
+
return badge.onClick ? /* @__PURE__ */ jsxs25(
|
|
2129
2253
|
"button",
|
|
2130
2254
|
{
|
|
2131
2255
|
onClick: (e) => {
|
|
@@ -2139,7 +2263,7 @@ function DeviceCard({
|
|
|
2139
2263
|
]
|
|
2140
2264
|
},
|
|
2141
2265
|
i
|
|
2142
|
-
) : /* @__PURE__ */
|
|
2266
|
+
) : /* @__PURE__ */ jsxs25("span", { className: cls, children: [
|
|
2143
2267
|
badge.icon,
|
|
2144
2268
|
badge.label
|
|
2145
2269
|
] }, i);
|
|
@@ -2190,9 +2314,9 @@ function DeviceGrid({
|
|
|
2190
2314
|
}
|
|
2191
2315
|
|
|
2192
2316
|
// src/composites/pipeline-step.tsx
|
|
2193
|
-
import { useState as
|
|
2317
|
+
import { useState as useState11 } from "react";
|
|
2194
2318
|
import { ChevronRight as ChevronRight3, ChevronDown as ChevronDown2 } from "lucide-react";
|
|
2195
|
-
import { jsx as jsx42, jsxs as
|
|
2319
|
+
import { jsx as jsx42, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
2196
2320
|
var ADDON_COLORS = {
|
|
2197
2321
|
"object-detection": "border-l-blue-500",
|
|
2198
2322
|
"motion-detection": "border-l-amber-500",
|
|
@@ -2268,7 +2392,7 @@ function PipelineStep({
|
|
|
2268
2392
|
onDelete,
|
|
2269
2393
|
readOnly = false
|
|
2270
2394
|
}) {
|
|
2271
|
-
const [expanded, setExpanded] =
|
|
2395
|
+
const [expanded, setExpanded] = useState11(false);
|
|
2272
2396
|
const color = borderColor(step.addonId, step.slot);
|
|
2273
2397
|
const backends = backendsForRuntime(step.runtime, capabilities, schema);
|
|
2274
2398
|
const rtOptions = runtimeOptions(capabilities);
|
|
@@ -2291,7 +2415,7 @@ function PipelineStep({
|
|
|
2291
2415
|
if (e.target.closest(".step-config")) return;
|
|
2292
2416
|
setExpanded((v) => !v);
|
|
2293
2417
|
}
|
|
2294
|
-
return /* @__PURE__ */ jsx42("div", { className: "space-y-2", children: /* @__PURE__ */
|
|
2418
|
+
return /* @__PURE__ */ jsx42("div", { className: "space-y-2", children: /* @__PURE__ */ jsxs26(
|
|
2295
2419
|
"div",
|
|
2296
2420
|
{
|
|
2297
2421
|
className: cn(
|
|
@@ -2300,12 +2424,12 @@ function PipelineStep({
|
|
|
2300
2424
|
!step.enabled && "opacity-[0.45]"
|
|
2301
2425
|
),
|
|
2302
2426
|
children: [
|
|
2303
|
-
/* @__PURE__ */
|
|
2427
|
+
/* @__PURE__ */ jsxs26("div", { className: "flex items-center gap-2.5 px-3 py-2.5 cursor-pointer select-none", onClick: handleClick, children: [
|
|
2304
2428
|
/* @__PURE__ */ jsx42("span", { className: "text-foreground-subtle", children: expanded ? /* @__PURE__ */ jsx42(ChevronDown2, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx42(ChevronRight3, { className: "h-4 w-4" }) }),
|
|
2305
|
-
/* @__PURE__ */
|
|
2429
|
+
/* @__PURE__ */ jsxs26("div", { className: "flex-1 min-w-0", children: [
|
|
2306
2430
|
/* @__PURE__ */ jsx42("span", { className: "text-[10px] uppercase tracking-wider font-medium text-foreground-subtle/60 block leading-none", children: step.slot }),
|
|
2307
2431
|
/* @__PURE__ */ jsx42("span", { className: "text-sm font-semibold text-foreground truncate block leading-tight", children: step.addonName }),
|
|
2308
|
-
/* @__PURE__ */
|
|
2432
|
+
/* @__PURE__ */ jsxs26("div", { className: "flex items-center gap-1 mt-0.5 flex-wrap", children: [
|
|
2309
2433
|
step.inputClasses.map((c) => /* @__PURE__ */ jsx42("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)),
|
|
2310
2434
|
step.inputClasses.length > 0 && step.outputClasses.length > 0 && /* @__PURE__ */ jsx42("span", { className: "text-foreground-subtle/40 text-[10px]", children: "\u2192" }),
|
|
2311
2435
|
step.outputClasses.map((c) => /* @__PURE__ */ jsx42("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))
|
|
@@ -2329,8 +2453,8 @@ function PipelineStep({
|
|
|
2329
2453
|
}
|
|
2330
2454
|
)
|
|
2331
2455
|
] }),
|
|
2332
|
-
expanded && /* @__PURE__ */
|
|
2333
|
-
/* @__PURE__ */
|
|
2456
|
+
expanded && /* @__PURE__ */ jsxs26("div", { className: "step-config border-t border-border bg-background px-4 py-4 space-y-3", children: [
|
|
2457
|
+
/* @__PURE__ */ jsxs26("div", { className: "grid grid-cols-2 gap-3", children: [
|
|
2334
2458
|
/* @__PURE__ */ jsx42(
|
|
2335
2459
|
ConfigSelect,
|
|
2336
2460
|
{
|
|
@@ -2372,10 +2496,10 @@ function PipelineStep({
|
|
|
2372
2496
|
}
|
|
2373
2497
|
)
|
|
2374
2498
|
] }),
|
|
2375
|
-
/* @__PURE__ */
|
|
2376
|
-
/* @__PURE__ */
|
|
2499
|
+
/* @__PURE__ */ jsxs26("div", { children: [
|
|
2500
|
+
/* @__PURE__ */ jsxs26("div", { className: "flex items-center justify-between mb-1", children: [
|
|
2377
2501
|
/* @__PURE__ */ jsx42("span", { className: "text-[10px] font-medium text-foreground-subtle uppercase tracking-wide", children: "Confidence" }),
|
|
2378
|
-
/* @__PURE__ */
|
|
2502
|
+
/* @__PURE__ */ jsxs26("span", { className: "text-xs font-medium text-foreground tabular-nums", children: [
|
|
2379
2503
|
(step.confidence * 100).toFixed(0),
|
|
2380
2504
|
"%"
|
|
2381
2505
|
] })
|
|
@@ -2400,9 +2524,9 @@ function PipelineStep({
|
|
|
2400
2524
|
) });
|
|
2401
2525
|
}
|
|
2402
2526
|
function ConfigSelect({ label, value, options, disabled, onChange }) {
|
|
2403
|
-
return /* @__PURE__ */
|
|
2527
|
+
return /* @__PURE__ */ jsxs26("div", { children: [
|
|
2404
2528
|
/* @__PURE__ */ jsx42("label", { className: "block text-[10px] font-medium text-foreground-subtle uppercase tracking-wide mb-1.5", children: label }),
|
|
2405
|
-
/* @__PURE__ */
|
|
2529
|
+
/* @__PURE__ */ jsxs26(
|
|
2406
2530
|
"select",
|
|
2407
2531
|
{
|
|
2408
2532
|
value,
|
|
@@ -2420,11 +2544,11 @@ function ConfigSelect({ label, value, options, disabled, onChange }) {
|
|
|
2420
2544
|
|
|
2421
2545
|
// src/composites/pipeline-runtime-selector.tsx
|
|
2422
2546
|
import { Cpu, Star } from "lucide-react";
|
|
2423
|
-
import { jsx as jsx43, jsxs as
|
|
2547
|
+
import { jsx as jsx43, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
2424
2548
|
function PipelineRuntimeSelector({ options, value, onChange }) {
|
|
2425
2549
|
return /* @__PURE__ */ jsx43("div", { className: "flex flex-wrap gap-2", children: options.map((opt) => {
|
|
2426
2550
|
const active = opt.id === value;
|
|
2427
|
-
return /* @__PURE__ */
|
|
2551
|
+
return /* @__PURE__ */ jsxs27(
|
|
2428
2552
|
"button",
|
|
2429
2553
|
{
|
|
2430
2554
|
onClick: () => opt.available && onChange(opt.id),
|
|
@@ -2433,11 +2557,11 @@ function PipelineRuntimeSelector({ options, value, onChange }) {
|
|
|
2433
2557
|
children: [
|
|
2434
2558
|
/* @__PURE__ */ jsx43(Cpu, { className: "h-3.5 w-3.5 shrink-0" }),
|
|
2435
2559
|
opt.label,
|
|
2436
|
-
opt.isBest && /* @__PURE__ */
|
|
2560
|
+
opt.isBest && /* @__PURE__ */ jsxs27("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: [
|
|
2437
2561
|
/* @__PURE__ */ jsx43(Star, { className: "h-2.5 w-2.5" }),
|
|
2438
2562
|
"Best"
|
|
2439
2563
|
] }),
|
|
2440
|
-
opt.platformScore != null && /* @__PURE__ */
|
|
2564
|
+
opt.platformScore != null && /* @__PURE__ */ jsxs27("span", { className: "text-[10px] text-foreground-subtle/60", children: [
|
|
2441
2565
|
"(",
|
|
2442
2566
|
opt.platformScore,
|
|
2443
2567
|
")"
|
|
@@ -2456,7 +2580,7 @@ function PipelineRuntimeSelector({ options, value, onChange }) {
|
|
|
2456
2580
|
}
|
|
2457
2581
|
|
|
2458
2582
|
// src/composites/pipeline-builder.tsx
|
|
2459
|
-
import { useMemo as useMemo3, useState as
|
|
2583
|
+
import { useMemo as useMemo3, useState as useState12 } from "react";
|
|
2460
2584
|
import { Save, CopyPlus, Trash2, PlusCircle, X as X3 } from "lucide-react";
|
|
2461
2585
|
|
|
2462
2586
|
// src/lib/validate-template.ts
|
|
@@ -2489,7 +2613,7 @@ function validateTemplate(steps, schema) {
|
|
|
2489
2613
|
}
|
|
2490
2614
|
|
|
2491
2615
|
// src/composites/pipeline-builder.tsx
|
|
2492
|
-
import { jsx as jsx44, jsxs as
|
|
2616
|
+
import { jsx as jsx44, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
2493
2617
|
function buildSchemaMap(schema) {
|
|
2494
2618
|
const map = /* @__PURE__ */ new Map();
|
|
2495
2619
|
for (const slot of schema.slots) {
|
|
@@ -2524,11 +2648,11 @@ function PlaceholderStep({ addon, onClick }) {
|
|
|
2524
2648
|
type: "button",
|
|
2525
2649
|
onClick,
|
|
2526
2650
|
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",
|
|
2527
|
-
children: /* @__PURE__ */
|
|
2651
|
+
children: /* @__PURE__ */ jsxs28("div", { className: "flex items-center gap-3", children: [
|
|
2528
2652
|
/* @__PURE__ */ jsx44(PlusCircle, { className: "h-[18px] w-[18px] text-foreground-subtle/30 group-hover:text-primary/60 shrink-0" }),
|
|
2529
|
-
/* @__PURE__ */
|
|
2653
|
+
/* @__PURE__ */ jsxs28("div", { className: "flex-1 min-w-0", children: [
|
|
2530
2654
|
/* @__PURE__ */ jsx44("span", { className: "text-[13px] font-medium text-foreground-subtle/50 group-hover:text-foreground-subtle block truncate", children: addon.name }),
|
|
2531
|
-
/* @__PURE__ */
|
|
2655
|
+
/* @__PURE__ */ jsxs28("div", { className: "flex items-center gap-1 mt-0.5 flex-wrap", children: [
|
|
2532
2656
|
addon.inputClasses.map((c) => /* @__PURE__ */ jsx44("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)),
|
|
2533
2657
|
addon.inputClasses.length > 0 && addon.outputClasses.length > 0 && /* @__PURE__ */ jsx44("span", { className: "text-foreground-subtle/25 text-[10px]", children: "\u2192" }),
|
|
2534
2658
|
addon.outputClasses.map((c) => /* @__PURE__ */ jsx44("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))
|
|
@@ -2554,7 +2678,7 @@ function PipelineBuilder({
|
|
|
2554
2678
|
}) {
|
|
2555
2679
|
const excluded = useMemo3(() => new Set(excludeAddons), [excludeAddons]);
|
|
2556
2680
|
const schemaMap = useMemo3(() => buildSchemaMap(schema), [schema]);
|
|
2557
|
-
const [warnings, setWarnings] =
|
|
2681
|
+
const [warnings, setWarnings] = useState12([]);
|
|
2558
2682
|
const bestPlatformScore = capabilities.platformScores?.find((s) => s.available);
|
|
2559
2683
|
const hasPython = capabilities.runtimes.python.available && capabilities.runtimes.python.backends.some((b) => b.available);
|
|
2560
2684
|
const defaultRuntime = bestPlatformScore?.runtime ?? (hasPython ? "python" : "node");
|
|
@@ -2643,7 +2767,7 @@ function PipelineBuilder({
|
|
|
2643
2767
|
}
|
|
2644
2768
|
function renderStep(step) {
|
|
2645
2769
|
const childPlaceholders = getChildPlaceholders(step);
|
|
2646
|
-
return /* @__PURE__ */
|
|
2770
|
+
return /* @__PURE__ */ jsxs28("div", { className: "space-y-1.5", children: [
|
|
2647
2771
|
/* @__PURE__ */ jsx44(
|
|
2648
2772
|
PipelineStep,
|
|
2649
2773
|
{
|
|
@@ -2656,11 +2780,11 @@ function PipelineBuilder({
|
|
|
2656
2780
|
readOnly
|
|
2657
2781
|
}
|
|
2658
2782
|
),
|
|
2659
|
-
(step.children.length > 0 || childPlaceholders.length > 0) && /* @__PURE__ */
|
|
2783
|
+
(step.children.length > 0 || childPlaceholders.length > 0) && /* @__PURE__ */ jsxs28("div", { className: "ml-6 pl-4 border-l-2 border-dashed border-border/40 space-y-1.5", children: [
|
|
2660
2784
|
/* @__PURE__ */ jsx44("span", { className: "text-[10px] font-semibold uppercase tracking-widest text-foreground-subtle/40", children: "Slot: Cropper / Classifier" }),
|
|
2661
2785
|
step.children.map((child) => {
|
|
2662
2786
|
const childChildPlaceholders = getChildPlaceholders(child);
|
|
2663
|
-
return /* @__PURE__ */
|
|
2787
|
+
return /* @__PURE__ */ jsxs28("div", { className: "space-y-1.5", children: [
|
|
2664
2788
|
/* @__PURE__ */ jsx44(
|
|
2665
2789
|
PipelineStep,
|
|
2666
2790
|
{
|
|
@@ -2684,7 +2808,7 @@ function PipelineBuilder({
|
|
|
2684
2808
|
readOnly
|
|
2685
2809
|
}
|
|
2686
2810
|
),
|
|
2687
|
-
(child.children.length > 0 || childChildPlaceholders.length > 0) && /* @__PURE__ */
|
|
2811
|
+
(child.children.length > 0 || childChildPlaceholders.length > 0) && /* @__PURE__ */ jsxs28("div", { className: "ml-6 pl-4 border-l-2 border-dashed border-border/30 space-y-1.5", children: [
|
|
2688
2812
|
/* @__PURE__ */ jsx44("span", { className: "text-[10px] font-semibold uppercase tracking-widest text-foreground-subtle/30", children: "Slot: Recognizer" }),
|
|
2689
2813
|
child.children.map((grandchild) => /* @__PURE__ */ jsx44(
|
|
2690
2814
|
PipelineStep,
|
|
@@ -2745,9 +2869,9 @@ function PipelineBuilder({
|
|
|
2745
2869
|
] }, step.addonId);
|
|
2746
2870
|
}
|
|
2747
2871
|
const rootSlots = schema.slots.filter((s) => s.parentSlot === null).sort((a, b) => a.priority - b.priority);
|
|
2748
|
-
return /* @__PURE__ */
|
|
2749
|
-
/* @__PURE__ */ jsx44("div", { className: "rounded-xl border border-border bg-surface p-3", children: /* @__PURE__ */
|
|
2750
|
-
/* @__PURE__ */ jsx44("div", { className: "relative flex-1 min-w-0", children: /* @__PURE__ */
|
|
2872
|
+
return /* @__PURE__ */ jsxs28("div", { className: "space-y-4", children: [
|
|
2873
|
+
/* @__PURE__ */ jsx44("div", { className: "rounded-xl border border-border bg-surface p-3", children: /* @__PURE__ */ jsxs28("div", { className: "flex items-center gap-2", children: [
|
|
2874
|
+
/* @__PURE__ */ jsx44("div", { className: "relative flex-1 min-w-0", children: /* @__PURE__ */ jsxs28(
|
|
2751
2875
|
"select",
|
|
2752
2876
|
{
|
|
2753
2877
|
value: selectedTemplateId ?? "",
|
|
@@ -2800,12 +2924,12 @@ function PipelineBuilder({
|
|
|
2800
2924
|
}
|
|
2801
2925
|
)
|
|
2802
2926
|
] }) }),
|
|
2803
|
-
warnings.length > 0 && /* @__PURE__ */
|
|
2804
|
-
/* @__PURE__ */
|
|
2927
|
+
warnings.length > 0 && /* @__PURE__ */ jsxs28("div", { className: "rounded-lg border border-amber-500/30 bg-amber-500/5 p-3 text-xs text-amber-400 space-y-1", children: [
|
|
2928
|
+
/* @__PURE__ */ jsxs28("div", { className: "flex items-center justify-between", children: [
|
|
2805
2929
|
/* @__PURE__ */ jsx44("span", { className: "font-medium", children: "Template loaded with warnings:" }),
|
|
2806
2930
|
/* @__PURE__ */ jsx44("button", { onClick: () => setWarnings([]), className: "text-amber-400/60 hover:text-amber-400", children: /* @__PURE__ */ jsx44(X3, { className: "h-3.5 w-3.5" }) })
|
|
2807
2931
|
] }),
|
|
2808
|
-
warnings.map((w, i) => /* @__PURE__ */
|
|
2932
|
+
warnings.map((w, i) => /* @__PURE__ */ jsxs28("div", { children: [
|
|
2809
2933
|
"\u2022 ",
|
|
2810
2934
|
w
|
|
2811
2935
|
] }, i))
|
|
@@ -2813,8 +2937,8 @@ function PipelineBuilder({
|
|
|
2813
2937
|
rootSlots.map((slot) => {
|
|
2814
2938
|
const slotSteps = steps.filter((s) => s.slot === slot.id && !excluded.has(s.addonId));
|
|
2815
2939
|
const missingRootAddons = slot.addons.filter((a) => !existingIds.has(a.id) && !excluded.has(a.id));
|
|
2816
|
-
return /* @__PURE__ */
|
|
2817
|
-
/* @__PURE__ */
|
|
2940
|
+
return /* @__PURE__ */ jsxs28("div", { className: "space-y-2", children: [
|
|
2941
|
+
/* @__PURE__ */ jsxs28("span", { className: "text-[10px] font-semibold uppercase tracking-widest text-foreground-subtle/50", children: [
|
|
2818
2942
|
"Slot: ",
|
|
2819
2943
|
slot.label
|
|
2820
2944
|
] }),
|
|
@@ -2900,7 +3024,7 @@ function getClassColor(className, customColors) {
|
|
|
2900
3024
|
|
|
2901
3025
|
// src/composites/detection-canvas.tsx
|
|
2902
3026
|
import { useRef as useRef7, useEffect as useEffect8 } from "react";
|
|
2903
|
-
import { Fragment as
|
|
3027
|
+
import { Fragment as Fragment5, jsx as jsx45, jsxs as jsxs29 } from "react/jsx-runtime";
|
|
2904
3028
|
var DEFAULT_CLASS_COLORS = CLASS_COLORS;
|
|
2905
3029
|
function DetectionCanvas({
|
|
2906
3030
|
src,
|
|
@@ -2928,7 +3052,7 @@ function DetectionCanvas({
|
|
|
2928
3052
|
className
|
|
2929
3053
|
),
|
|
2930
3054
|
style: { aspectRatio: ratio },
|
|
2931
|
-
children: src ? /* @__PURE__ */
|
|
3055
|
+
children: src ? /* @__PURE__ */ jsxs29(Fragment5, { children: [
|
|
2932
3056
|
/* @__PURE__ */ jsx45("img", { src, className: "absolute inset-0 w-full h-full object-fill", alt: "" }),
|
|
2933
3057
|
filteredDetections.map(
|
|
2934
3058
|
(d, i) => d.mask && d.maskWidth && d.maskHeight ? /* @__PURE__ */ jsx45(
|
|
@@ -2997,13 +3121,13 @@ function BoundingBox({
|
|
|
2997
3121
|
const topPct = y1 / imageHeight * 100;
|
|
2998
3122
|
const containerRef = useRef7(null);
|
|
2999
3123
|
const showBelow = topPct < labelHeightPx / imageHeight * 100 * 1.5;
|
|
3000
|
-
const labelsElement = /* @__PURE__ */
|
|
3124
|
+
const labelsElement = /* @__PURE__ */ jsxs29(
|
|
3001
3125
|
"div",
|
|
3002
3126
|
{
|
|
3003
3127
|
className: `absolute left-0 flex flex-col items-start gap-px ${showBelow ? "" : ""}`,
|
|
3004
3128
|
style: showBelow ? { top: "100%", marginTop: "2px" } : { bottom: "100%", marginBottom: "2px" },
|
|
3005
3129
|
children: [
|
|
3006
|
-
/* @__PURE__ */
|
|
3130
|
+
/* @__PURE__ */ jsxs29(
|
|
3007
3131
|
"span",
|
|
3008
3132
|
{
|
|
3009
3133
|
className: "text-[10px] px-1 rounded-sm whitespace-nowrap text-white",
|
|
@@ -3014,7 +3138,7 @@ function BoundingBox({
|
|
|
3014
3138
|
]
|
|
3015
3139
|
}
|
|
3016
3140
|
),
|
|
3017
|
-
detection.labelsData?.map((l, k) => /* @__PURE__ */
|
|
3141
|
+
detection.labelsData?.map((l, k) => /* @__PURE__ */ jsxs29(
|
|
3018
3142
|
"span",
|
|
3019
3143
|
{
|
|
3020
3144
|
className: "text-[9px] font-semibold px-1 rounded-sm whitespace-nowrap text-white",
|
|
@@ -3031,7 +3155,7 @@ function BoundingBox({
|
|
|
3031
3155
|
]
|
|
3032
3156
|
}
|
|
3033
3157
|
);
|
|
3034
|
-
return /* @__PURE__ */
|
|
3158
|
+
return /* @__PURE__ */ jsxs29(
|
|
3035
3159
|
"div",
|
|
3036
3160
|
{
|
|
3037
3161
|
ref: containerRef,
|
|
@@ -3133,13 +3257,13 @@ function ChildBoundingBox({
|
|
|
3133
3257
|
const labelCount = 1 + (child.labelsData?.length ?? 0);
|
|
3134
3258
|
const relTop = (cy1 - py1) / ph * 100;
|
|
3135
3259
|
const showBelow = relTop < labelCount * 6;
|
|
3136
|
-
return /* @__PURE__ */
|
|
3260
|
+
return /* @__PURE__ */ jsxs29(
|
|
3137
3261
|
"div",
|
|
3138
3262
|
{
|
|
3139
3263
|
className: "absolute left-0 flex flex-col items-start gap-px",
|
|
3140
3264
|
style: showBelow ? { top: "100%", marginTop: "1px" } : { bottom: "100%", marginBottom: "1px" },
|
|
3141
3265
|
children: [
|
|
3142
|
-
/* @__PURE__ */
|
|
3266
|
+
/* @__PURE__ */ jsxs29(
|
|
3143
3267
|
"span",
|
|
3144
3268
|
{
|
|
3145
3269
|
className: "text-[9px] px-0.5 rounded-sm whitespace-nowrap text-white",
|
|
@@ -3150,7 +3274,7 @@ function ChildBoundingBox({
|
|
|
3150
3274
|
]
|
|
3151
3275
|
}
|
|
3152
3276
|
),
|
|
3153
|
-
child.labelsData?.map((l, k) => /* @__PURE__ */
|
|
3277
|
+
child.labelsData?.map((l, k) => /* @__PURE__ */ jsxs29(
|
|
3154
3278
|
"span",
|
|
3155
3279
|
{
|
|
3156
3280
|
className: "text-[8px] font-semibold px-0.5 rounded-sm whitespace-nowrap text-white",
|
|
@@ -3173,7 +3297,7 @@ function ChildBoundingBox({
|
|
|
3173
3297
|
}
|
|
3174
3298
|
|
|
3175
3299
|
// src/composites/detection-result-tree.tsx
|
|
3176
|
-
import { jsx as jsx46, jsxs as
|
|
3300
|
+
import { jsx as jsx46, jsxs as jsxs30 } from "react/jsx-runtime";
|
|
3177
3301
|
function DetectionResultTree({
|
|
3178
3302
|
detections,
|
|
3179
3303
|
classColors,
|
|
@@ -3185,8 +3309,8 @@ function DetectionResultTree({
|
|
|
3185
3309
|
if (detections.length === 0) {
|
|
3186
3310
|
return /* @__PURE__ */ jsx46("div", { className: "text-sm text-foreground-subtle italic text-center py-4", children: "No detections" });
|
|
3187
3311
|
}
|
|
3188
|
-
return /* @__PURE__ */
|
|
3189
|
-
/* @__PURE__ */
|
|
3312
|
+
return /* @__PURE__ */ jsxs30("div", { className, children: [
|
|
3313
|
+
/* @__PURE__ */ jsxs30("div", { className: "text-xs font-medium text-foreground-subtle uppercase tracking-wide mb-2", children: [
|
|
3190
3314
|
"Detections (",
|
|
3191
3315
|
detections.length,
|
|
3192
3316
|
")"
|
|
@@ -3213,9 +3337,9 @@ function DetectionNode({
|
|
|
3213
3337
|
}) {
|
|
3214
3338
|
const color = getClassColor(detection.className, colors);
|
|
3215
3339
|
const isVisible = !hiddenKeys?.has(path);
|
|
3216
|
-
return /* @__PURE__ */
|
|
3217
|
-
/* @__PURE__ */
|
|
3218
|
-
/* @__PURE__ */
|
|
3340
|
+
return /* @__PURE__ */ jsxs30("div", { className: `rounded-md border border-border bg-surface p-3 space-y-1 ${isVisible ? "" : "opacity-40"}`, children: [
|
|
3341
|
+
/* @__PURE__ */ jsxs30("div", { className: "flex justify-between items-center", children: [
|
|
3342
|
+
/* @__PURE__ */ jsxs30("div", { className: "flex items-center gap-2", children: [
|
|
3219
3343
|
onToggleVisibility && /* @__PURE__ */ jsx46(
|
|
3220
3344
|
"input",
|
|
3221
3345
|
{
|
|
@@ -3233,7 +3357,7 @@ function DetectionNode({
|
|
|
3233
3357
|
}
|
|
3234
3358
|
),
|
|
3235
3359
|
/* @__PURE__ */ jsx46("span", { className: "text-sm font-medium text-foreground", children: detection.className }),
|
|
3236
|
-
detection.mask && detection.maskWidth && detection.maskHeight && /* @__PURE__ */
|
|
3360
|
+
detection.mask && detection.maskWidth && detection.maskHeight && /* @__PURE__ */ jsxs30("span", { className: "text-[9px] font-mono px-1 py-0.5 rounded bg-primary/10 text-primary", children: [
|
|
3237
3361
|
"mask ",
|
|
3238
3362
|
detection.maskWidth,
|
|
3239
3363
|
"x",
|
|
@@ -3242,19 +3366,19 @@ function DetectionNode({
|
|
|
3242
3366
|
] }),
|
|
3243
3367
|
/* @__PURE__ */ jsx46(ConfidenceBadge, { confidence: detection.confidence })
|
|
3244
3368
|
] }),
|
|
3245
|
-
/* @__PURE__ */
|
|
3369
|
+
/* @__PURE__ */ jsxs30("div", { className: "text-[10px] text-foreground-subtle font-mono", children: [
|
|
3246
3370
|
"bbox: [",
|
|
3247
3371
|
detection.bbox.map((v) => Math.round(v)).join(", "),
|
|
3248
3372
|
"]"
|
|
3249
3373
|
] }),
|
|
3250
|
-
detection.labelsData && detection.labelsData.length > 0 && /* @__PURE__ */ jsx46("div", { className: "flex flex-wrap gap-1 mt-1", children: detection.labelsData.map((l, k) => /* @__PURE__ */
|
|
3374
|
+
detection.labelsData && detection.labelsData.length > 0 && /* @__PURE__ */ jsx46("div", { className: "flex flex-wrap gap-1 mt-1", children: detection.labelsData.map((l, k) => /* @__PURE__ */ jsxs30(
|
|
3251
3375
|
"span",
|
|
3252
3376
|
{
|
|
3253
3377
|
className: "inline-flex items-center gap-1 text-[10px] font-medium px-1.5 py-0.5 rounded-full",
|
|
3254
3378
|
style: { backgroundColor: getClassColor(l.addonId ?? l.label, colors) + "20", color: getClassColor(l.addonId ?? l.label, colors) },
|
|
3255
3379
|
children: [
|
|
3256
3380
|
l.label,
|
|
3257
|
-
/* @__PURE__ */
|
|
3381
|
+
/* @__PURE__ */ jsxs30("span", { className: "opacity-60", children: [
|
|
3258
3382
|
(l.score * 100).toFixed(0),
|
|
3259
3383
|
"%"
|
|
3260
3384
|
] }),
|
|
@@ -3286,8 +3410,8 @@ function ChildrenTree({
|
|
|
3286
3410
|
const childPath = `${parentPath}.${j}`;
|
|
3287
3411
|
const childColor = getClassColor(child.className, colors);
|
|
3288
3412
|
const isVisible = !hiddenKeys?.has(childPath);
|
|
3289
|
-
return /* @__PURE__ */
|
|
3290
|
-
/* @__PURE__ */
|
|
3413
|
+
return /* @__PURE__ */ jsxs30("div", { className: `text-xs space-y-0.5 ${isVisible ? "" : "opacity-40"}`, children: [
|
|
3414
|
+
/* @__PURE__ */ jsxs30("div", { className: "flex items-center gap-1.5", children: [
|
|
3291
3415
|
onToggleVisibility && /* @__PURE__ */ jsx46(
|
|
3292
3416
|
"input",
|
|
3293
3417
|
{
|
|
@@ -3305,18 +3429,18 @@ function ChildrenTree({
|
|
|
3305
3429
|
}
|
|
3306
3430
|
),
|
|
3307
3431
|
/* @__PURE__ */ jsx46("span", { className: "font-medium", style: { color: childColor }, children: child.className }),
|
|
3308
|
-
/* @__PURE__ */
|
|
3432
|
+
/* @__PURE__ */ jsxs30("span", { className: "text-foreground-subtle", children: [
|
|
3309
3433
|
(child.confidence * 100).toFixed(0),
|
|
3310
3434
|
"%"
|
|
3311
3435
|
] }),
|
|
3312
|
-
child.mask && child.maskWidth && child.maskHeight && /* @__PURE__ */
|
|
3436
|
+
child.mask && child.maskWidth && child.maskHeight && /* @__PURE__ */ jsxs30("span", { className: "text-[9px] font-mono px-1 py-0.5 rounded bg-primary/10 text-primary", children: [
|
|
3313
3437
|
"mask ",
|
|
3314
3438
|
child.maskWidth,
|
|
3315
3439
|
"x",
|
|
3316
3440
|
child.maskHeight
|
|
3317
3441
|
] })
|
|
3318
3442
|
] }),
|
|
3319
|
-
child.labelsData && child.labelsData.length > 0 && /* @__PURE__ */ jsx46("div", { className: "flex flex-wrap gap-1 ml-5 mt-0.5", children: child.labelsData.map((l, k) => /* @__PURE__ */
|
|
3443
|
+
child.labelsData && child.labelsData.length > 0 && /* @__PURE__ */ jsx46("div", { className: "flex flex-wrap gap-1 ml-5 mt-0.5", children: child.labelsData.map((l, k) => /* @__PURE__ */ jsxs30(
|
|
3320
3444
|
"span",
|
|
3321
3445
|
{
|
|
3322
3446
|
className: "inline-flex items-center gap-0.5 text-[9px] font-medium px-1 py-0.5 rounded-full",
|
|
@@ -3324,7 +3448,7 @@ function ChildrenTree({
|
|
|
3324
3448
|
children: [
|
|
3325
3449
|
l.label,
|
|
3326
3450
|
" ",
|
|
3327
|
-
/* @__PURE__ */
|
|
3451
|
+
/* @__PURE__ */ jsxs30("span", { className: "opacity-60", children: [
|
|
3328
3452
|
(l.score * 100).toFixed(0),
|
|
3329
3453
|
"%"
|
|
3330
3454
|
] })
|
|
@@ -3347,30 +3471,30 @@ function ChildrenTree({
|
|
|
3347
3471
|
}
|
|
3348
3472
|
function ConfidenceBadge({ confidence }) {
|
|
3349
3473
|
const level = confidence >= 0.8 ? "bg-success/10 text-success" : confidence >= 0.5 ? "bg-warning/10 text-warning" : "bg-danger/10 text-danger";
|
|
3350
|
-
return /* @__PURE__ */
|
|
3474
|
+
return /* @__PURE__ */ jsxs30("span", { className: `text-xs font-medium px-2 py-0.5 rounded-full ${level}`, children: [
|
|
3351
3475
|
(confidence * 100).toFixed(1),
|
|
3352
3476
|
"%"
|
|
3353
3477
|
] });
|
|
3354
3478
|
}
|
|
3355
3479
|
|
|
3356
3480
|
// src/composites/step-timings.tsx
|
|
3357
|
-
import { jsx as jsx47, jsxs as
|
|
3481
|
+
import { jsx as jsx47, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
3358
3482
|
function StepTimings({ timings, totalMs, className }) {
|
|
3359
3483
|
const entries = Object.entries(timings);
|
|
3360
3484
|
if (entries.length === 0 && totalMs === void 0) return null;
|
|
3361
|
-
return /* @__PURE__ */
|
|
3485
|
+
return /* @__PURE__ */ jsxs31("div", { className: `rounded-lg border border-border bg-surface p-3 space-y-2 ${className ?? ""}`, children: [
|
|
3362
3486
|
/* @__PURE__ */ jsx47("div", { className: "text-xs font-medium text-foreground-subtle uppercase tracking-wide", children: "Timings" }),
|
|
3363
|
-
/* @__PURE__ */
|
|
3364
|
-
entries.map(([step, ms]) => /* @__PURE__ */
|
|
3487
|
+
/* @__PURE__ */ jsxs31("div", { className: "space-y-1 text-xs", children: [
|
|
3488
|
+
entries.map(([step, ms]) => /* @__PURE__ */ jsxs31("div", { className: "flex justify-between", children: [
|
|
3365
3489
|
/* @__PURE__ */ jsx47("span", { className: "text-foreground-subtle", children: step }),
|
|
3366
|
-
/* @__PURE__ */
|
|
3490
|
+
/* @__PURE__ */ jsxs31("span", { className: "font-mono text-foreground", children: [
|
|
3367
3491
|
ms.toFixed(1),
|
|
3368
3492
|
"ms"
|
|
3369
3493
|
] })
|
|
3370
3494
|
] }, step)),
|
|
3371
|
-
totalMs !== void 0 && /* @__PURE__ */
|
|
3495
|
+
totalMs !== void 0 && /* @__PURE__ */ jsxs31("div", { className: "flex justify-between pt-1 border-t border-border font-medium text-foreground", children: [
|
|
3372
3496
|
/* @__PURE__ */ jsx47("span", { children: "Total" }),
|
|
3373
|
-
/* @__PURE__ */
|
|
3497
|
+
/* @__PURE__ */ jsxs31("span", { className: "font-mono", children: [
|
|
3374
3498
|
totalMs.toFixed(1),
|
|
3375
3499
|
"ms"
|
|
3376
3500
|
] })
|
|
@@ -3380,7 +3504,7 @@ function StepTimings({ timings, totalMs, className }) {
|
|
|
3380
3504
|
}
|
|
3381
3505
|
|
|
3382
3506
|
// src/composites/image-selector.tsx
|
|
3383
|
-
import { jsx as jsx48, jsxs as
|
|
3507
|
+
import { jsx as jsx48, jsxs as jsxs32 } from "react/jsx-runtime";
|
|
3384
3508
|
function ImageSelector({
|
|
3385
3509
|
images,
|
|
3386
3510
|
selectedFilename,
|
|
@@ -3406,7 +3530,7 @@ function ImageSelector({
|
|
|
3406
3530
|
};
|
|
3407
3531
|
input.click();
|
|
3408
3532
|
};
|
|
3409
|
-
return /* @__PURE__ */
|
|
3533
|
+
return /* @__PURE__ */ jsxs32("div", { className: `flex flex-wrap items-center gap-2 ${className ?? ""}`, children: [
|
|
3410
3534
|
images.map((img) => /* @__PURE__ */ jsx48(
|
|
3411
3535
|
"button",
|
|
3412
3536
|
{
|
|
@@ -3429,7 +3553,7 @@ function ImageSelector({
|
|
|
3429
3553
|
}
|
|
3430
3554
|
|
|
3431
3555
|
// src/composites/inference-config-selector.tsx
|
|
3432
|
-
import { jsx as jsx49, jsxs as
|
|
3556
|
+
import { jsx as jsx49, jsxs as jsxs33 } from "react/jsx-runtime";
|
|
3433
3557
|
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";
|
|
3434
3558
|
function InferenceConfigSelector({
|
|
3435
3559
|
runtime,
|
|
@@ -3449,8 +3573,8 @@ function InferenceConfigSelector({
|
|
|
3449
3573
|
showAgent = false
|
|
3450
3574
|
}) {
|
|
3451
3575
|
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";
|
|
3452
|
-
return /* @__PURE__ */
|
|
3453
|
-
showAgent && agents.length > 0 && /* @__PURE__ */
|
|
3576
|
+
return /* @__PURE__ */ jsxs33("div", { className: `${containerClass} ${className ?? ""}`, children: [
|
|
3577
|
+
showAgent && agents.length > 0 && /* @__PURE__ */ jsxs33("label", { className: "space-y-1", children: [
|
|
3454
3578
|
/* @__PURE__ */ jsx49("span", { className: "text-xs font-medium text-foreground-subtle", children: "Agent" }),
|
|
3455
3579
|
/* @__PURE__ */ jsx49(
|
|
3456
3580
|
"select",
|
|
@@ -3458,7 +3582,7 @@ function InferenceConfigSelector({
|
|
|
3458
3582
|
value: agentId,
|
|
3459
3583
|
onChange: (e) => onAgentChange?.(e.target.value),
|
|
3460
3584
|
className: SELECT_CLASS,
|
|
3461
|
-
children: agents.map((a) => /* @__PURE__ */
|
|
3585
|
+
children: agents.map((a) => /* @__PURE__ */ jsxs33("option", { value: a.id, children: [
|
|
3462
3586
|
a.name,
|
|
3463
3587
|
" (",
|
|
3464
3588
|
a.status,
|
|
@@ -3467,7 +3591,7 @@ function InferenceConfigSelector({
|
|
|
3467
3591
|
}
|
|
3468
3592
|
)
|
|
3469
3593
|
] }),
|
|
3470
|
-
/* @__PURE__ */
|
|
3594
|
+
/* @__PURE__ */ jsxs33("label", { className: "space-y-1", children: [
|
|
3471
3595
|
/* @__PURE__ */ jsx49("span", { className: "text-xs font-medium text-foreground-subtle", children: "Runtime" }),
|
|
3472
3596
|
/* @__PURE__ */ jsx49(
|
|
3473
3597
|
"select",
|
|
@@ -3475,14 +3599,14 @@ function InferenceConfigSelector({
|
|
|
3475
3599
|
value: runtime,
|
|
3476
3600
|
onChange: (e) => onRuntimeChange(e.target.value),
|
|
3477
3601
|
className: SELECT_CLASS,
|
|
3478
|
-
children: runtimes.map((r) => /* @__PURE__ */
|
|
3602
|
+
children: runtimes.map((r) => /* @__PURE__ */ jsxs33("option", { value: r.value, disabled: !r.available, children: [
|
|
3479
3603
|
r.label,
|
|
3480
3604
|
!r.available ? " (unavailable)" : ""
|
|
3481
3605
|
] }, r.value))
|
|
3482
3606
|
}
|
|
3483
3607
|
)
|
|
3484
3608
|
] }),
|
|
3485
|
-
/* @__PURE__ */
|
|
3609
|
+
/* @__PURE__ */ jsxs33("label", { className: "space-y-1", children: [
|
|
3486
3610
|
/* @__PURE__ */ jsx49("span", { className: "text-xs font-medium text-foreground-subtle", children: "Backend" }),
|
|
3487
3611
|
/* @__PURE__ */ jsx49(
|
|
3488
3612
|
"select",
|
|
@@ -3490,14 +3614,14 @@ function InferenceConfigSelector({
|
|
|
3490
3614
|
value: backend,
|
|
3491
3615
|
onChange: (e) => onBackendChange(e.target.value),
|
|
3492
3616
|
className: SELECT_CLASS,
|
|
3493
|
-
children: backends.map((b) => /* @__PURE__ */
|
|
3617
|
+
children: backends.map((b) => /* @__PURE__ */ jsxs33("option", { value: b.id, disabled: !b.available, children: [
|
|
3494
3618
|
b.label,
|
|
3495
3619
|
!b.available ? " (unavailable)" : ""
|
|
3496
3620
|
] }, b.id))
|
|
3497
3621
|
}
|
|
3498
3622
|
)
|
|
3499
3623
|
] }),
|
|
3500
|
-
/* @__PURE__ */
|
|
3624
|
+
/* @__PURE__ */ jsxs33("label", { className: "space-y-1", children: [
|
|
3501
3625
|
/* @__PURE__ */ jsx49("span", { className: "text-xs font-medium text-foreground-subtle", children: "Model" }),
|
|
3502
3626
|
/* @__PURE__ */ jsx49(
|
|
3503
3627
|
"select",
|
|
@@ -3505,7 +3629,7 @@ function InferenceConfigSelector({
|
|
|
3505
3629
|
value: modelId,
|
|
3506
3630
|
onChange: (e) => onModelChange(e.target.value),
|
|
3507
3631
|
className: SELECT_CLASS,
|
|
3508
|
-
children: models.length === 0 ? /* @__PURE__ */ jsx49("option", { value: "", children: "No compatible models" }) : models.map((m) => /* @__PURE__ */
|
|
3632
|
+
children: models.length === 0 ? /* @__PURE__ */ jsx49("option", { value: "", children: "No compatible models" }) : models.map((m) => /* @__PURE__ */ jsxs33("option", { value: m.id, children: [
|
|
3509
3633
|
m.name,
|
|
3510
3634
|
m.downloaded ? " \u2713" : ""
|
|
3511
3635
|
] }, m.id))
|
|
@@ -3520,15 +3644,15 @@ import { createElement } from "react";
|
|
|
3520
3644
|
import { createRoot } from "react-dom/client";
|
|
3521
3645
|
|
|
3522
3646
|
// src/composites/dev-shell.tsx
|
|
3523
|
-
import { createContext as createContext7, useCallback as useCallback8, useContext as useContext7, useMemo as useMemo4, useState as
|
|
3647
|
+
import { createContext as createContext7, useCallback as useCallback8, useContext as useContext7, useMemo as useMemo4, useState as useState14 } from "react";
|
|
3524
3648
|
import { createTRPCClient, createWSClient, wsLink, httpLink, splitLink } from "@trpc/client";
|
|
3525
3649
|
import superjson from "superjson";
|
|
3526
3650
|
|
|
3527
3651
|
// src/composites/login-form.tsx
|
|
3528
|
-
import { useState as
|
|
3529
|
-
import { jsx as jsx50, jsxs as
|
|
3652
|
+
import { useState as useState13 } from "react";
|
|
3653
|
+
import { jsx as jsx50, jsxs as jsxs34 } from "react/jsx-runtime";
|
|
3530
3654
|
function EyeIcon({ className }) {
|
|
3531
|
-
return /* @__PURE__ */
|
|
3655
|
+
return /* @__PURE__ */ jsxs34(
|
|
3532
3656
|
"svg",
|
|
3533
3657
|
{
|
|
3534
3658
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -3547,7 +3671,7 @@ function EyeIcon({ className }) {
|
|
|
3547
3671
|
);
|
|
3548
3672
|
}
|
|
3549
3673
|
function EyeOffIcon({ className }) {
|
|
3550
|
-
return /* @__PURE__ */
|
|
3674
|
+
return /* @__PURE__ */ jsxs34(
|
|
3551
3675
|
"svg",
|
|
3552
3676
|
{
|
|
3553
3677
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -3590,11 +3714,11 @@ function LoginForm({
|
|
|
3590
3714
|
error: externalError,
|
|
3591
3715
|
className
|
|
3592
3716
|
}) {
|
|
3593
|
-
const [username, setUsername] =
|
|
3594
|
-
const [password, setPassword] =
|
|
3595
|
-
const [showPassword, setShowPassword] =
|
|
3596
|
-
const [submitting, setSubmitting] =
|
|
3597
|
-
const [internalError, setInternalError] =
|
|
3717
|
+
const [username, setUsername] = useState13("");
|
|
3718
|
+
const [password, setPassword] = useState13("");
|
|
3719
|
+
const [showPassword, setShowPassword] = useState13(false);
|
|
3720
|
+
const [submitting, setSubmitting] = useState13(false);
|
|
3721
|
+
const [internalError, setInternalError] = useState13(null);
|
|
3598
3722
|
const error = externalError ?? internalError;
|
|
3599
3723
|
const handleSubmit = async (e) => {
|
|
3600
3724
|
e.preventDefault();
|
|
@@ -3617,17 +3741,17 @@ function LoginForm({
|
|
|
3617
3741
|
"flex min-h-screen items-center justify-center bg-background p-4",
|
|
3618
3742
|
className
|
|
3619
3743
|
),
|
|
3620
|
-
children: /* @__PURE__ */
|
|
3744
|
+
children: /* @__PURE__ */ jsxs34("div", { className: "w-full max-w-sm", children: [
|
|
3621
3745
|
logoSrc && /* @__PURE__ */ jsx50("div", { className: "flex justify-center mb-8", children: /* @__PURE__ */ jsx50("img", { src: logoSrc, alt: "Logo", className: "h-12" }) }),
|
|
3622
3746
|
serverUrl && /* @__PURE__ */ jsx50("p", { className: "mb-4 text-center text-xs text-foreground-subtle truncate", children: serverUrl }),
|
|
3623
|
-
/* @__PURE__ */
|
|
3747
|
+
/* @__PURE__ */ jsxs34(
|
|
3624
3748
|
"form",
|
|
3625
3749
|
{
|
|
3626
3750
|
onSubmit: handleSubmit,
|
|
3627
3751
|
className: "space-y-4 rounded-xl border border-border bg-surface p-6 shadow-xl shadow-black/10",
|
|
3628
3752
|
children: [
|
|
3629
3753
|
error && /* @__PURE__ */ jsx50("div", { className: "rounded-md bg-danger/10 border border-danger/20 px-3 py-2 text-xs text-danger", children: error }),
|
|
3630
|
-
/* @__PURE__ */
|
|
3754
|
+
/* @__PURE__ */ jsxs34("div", { className: "space-y-1.5", children: [
|
|
3631
3755
|
/* @__PURE__ */ jsx50("label", { className: "text-xs font-medium text-foreground-subtle", children: "Username" }),
|
|
3632
3756
|
/* @__PURE__ */ jsx50(
|
|
3633
3757
|
"input",
|
|
@@ -3641,9 +3765,9 @@ function LoginForm({
|
|
|
3641
3765
|
}
|
|
3642
3766
|
)
|
|
3643
3767
|
] }),
|
|
3644
|
-
/* @__PURE__ */
|
|
3768
|
+
/* @__PURE__ */ jsxs34("div", { className: "space-y-1.5", children: [
|
|
3645
3769
|
/* @__PURE__ */ jsx50("label", { className: "text-xs font-medium text-foreground-subtle", children: "Password" }),
|
|
3646
|
-
/* @__PURE__ */
|
|
3770
|
+
/* @__PURE__ */ jsxs34("div", { className: "relative", children: [
|
|
3647
3771
|
/* @__PURE__ */ jsx50(
|
|
3648
3772
|
"input",
|
|
3649
3773
|
{
|
|
@@ -3667,7 +3791,7 @@ function LoginForm({
|
|
|
3667
3791
|
)
|
|
3668
3792
|
] })
|
|
3669
3793
|
] }),
|
|
3670
|
-
/* @__PURE__ */
|
|
3794
|
+
/* @__PURE__ */ jsxs34(
|
|
3671
3795
|
"button",
|
|
3672
3796
|
{
|
|
3673
3797
|
type: "submit",
|
|
@@ -3688,7 +3812,7 @@ function LoginForm({
|
|
|
3688
3812
|
}
|
|
3689
3813
|
|
|
3690
3814
|
// src/composites/dev-shell.tsx
|
|
3691
|
-
import { jsx as jsx51, jsxs as
|
|
3815
|
+
import { jsx as jsx51, jsxs as jsxs35 } from "react/jsx-runtime";
|
|
3692
3816
|
var STORAGE_KEY = "camstack_dev_token";
|
|
3693
3817
|
var DevShellContext = createContext7(null);
|
|
3694
3818
|
function useDevShell() {
|
|
@@ -3703,7 +3827,7 @@ function getStoredToken() {
|
|
|
3703
3827
|
return localStorage.getItem(STORAGE_KEY);
|
|
3704
3828
|
}
|
|
3705
3829
|
function SunIcon({ className }) {
|
|
3706
|
-
return /* @__PURE__ */
|
|
3830
|
+
return /* @__PURE__ */ jsxs35(
|
|
3707
3831
|
"svg",
|
|
3708
3832
|
{
|
|
3709
3833
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -3779,15 +3903,15 @@ function DevShellInner({
|
|
|
3779
3903
|
() => ({ trpc, token, logout: onLogout }),
|
|
3780
3904
|
[trpc, token, onLogout]
|
|
3781
3905
|
);
|
|
3782
|
-
return /* @__PURE__ */ jsx51(DevShellContext.Provider, { value: contextValue, children: /* @__PURE__ */
|
|
3783
|
-
/* @__PURE__ */
|
|
3784
|
-
/* @__PURE__ */
|
|
3906
|
+
return /* @__PURE__ */ jsx51(DevShellContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxs35("div", { className: "min-h-screen bg-background text-foreground", children: [
|
|
3907
|
+
/* @__PURE__ */ jsxs35("div", { className: "flex items-center justify-between border-b border-border bg-surface px-4 py-2", children: [
|
|
3908
|
+
/* @__PURE__ */ jsxs35("div", { className: "flex items-center gap-2", children: [
|
|
3785
3909
|
/* @__PURE__ */ jsx51("span", { className: "rounded bg-warning/20 px-2 py-0.5 text-xs font-bold text-warning", children: "DEV MODE" }),
|
|
3786
3910
|
title && /* @__PURE__ */ jsx51("span", { className: "text-sm font-medium text-foreground", children: title }),
|
|
3787
3911
|
/* @__PURE__ */ jsx51("span", { className: "text-xs text-foreground-subtle", children: serverUrl })
|
|
3788
3912
|
] }),
|
|
3789
|
-
/* @__PURE__ */
|
|
3790
|
-
/* @__PURE__ */
|
|
3913
|
+
/* @__PURE__ */ jsxs35("div", { className: "flex items-center gap-2", children: [
|
|
3914
|
+
/* @__PURE__ */ jsxs35(
|
|
3791
3915
|
"button",
|
|
3792
3916
|
{
|
|
3793
3917
|
type: "button",
|
|
@@ -3819,7 +3943,7 @@ function DevShell({
|
|
|
3819
3943
|
serverUrl = "https://localhost:4443",
|
|
3820
3944
|
title
|
|
3821
3945
|
}) {
|
|
3822
|
-
const [token, setToken] =
|
|
3946
|
+
const [token, setToken] = useState14(getStoredToken);
|
|
3823
3947
|
const handleLogin = useCallback8(
|
|
3824
3948
|
async (username, password) => {
|
|
3825
3949
|
const anonClient = createTRPCClient({
|