@hot-updater/console 0.32.0 → 0.33.1
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/.output/nitro.json +3 -3
- package/.output/public/assets/dist-DJX53faP.js +3 -0
- package/.output/public/assets/index-CCUspZZV.js +10 -0
- package/.output/public/assets/routes-D0t6y5Fr.js +54 -0
- package/.output/public/assets/styles-C0q26dS-.css +2 -0
- package/.output/server/{__tanstack-start-server-fn-resolver-ySzPUDlM.mjs → __23tanstack-start-server-fn-resolver-B12pVvhf.mjs} +32 -39
- package/.output/server/_chunks/ssr-renderer.mjs +14 -3
- package/.output/server/_libs/@floating-ui/react-dom+[...].mjs +7 -7
- package/.output/server/_libs/@radix-ui/react-alert-dialog+[...].mjs +142 -93
- package/.output/server/_libs/@radix-ui/react-popper+[...].mjs +32 -11
- package/.output/server/_libs/@radix-ui/react-select+[...].mjs +130 -95
- package/.output/server/_libs/@tanstack/form-core+[...].mjs +1138 -306
- package/.output/server/_libs/@tanstack/react-form+[...].mjs +156 -24
- package/.output/server/_libs/@tanstack/react-router+[...].mjs +2658 -1395
- package/.output/server/_libs/@tanstack/react-table+[...].mjs +1 -1
- package/.output/server/_libs/dayjs.mjs +6 -6
- package/.output/server/_libs/h3+rou3+srvx.mjs +30 -42
- package/.output/server/_libs/lucide-react.mjs +54 -9
- package/.output/server/_libs/next-themes.mjs +1 -1
- package/.output/server/_libs/radix-ui__number.mjs +1 -1
- package/.output/server/_libs/radix-ui__react-arrow.mjs +2 -2
- package/.output/server/_libs/radix-ui__react-collection.mjs +2 -2
- package/.output/server/_libs/radix-ui__react-direction.mjs +2 -2
- package/.output/server/_libs/radix-ui__react-label.mjs +2 -2
- package/.output/server/_libs/radix-ui__react-separator.mjs +2 -2
- package/.output/server/_libs/radix-ui__react-slider.mjs +103 -44
- package/.output/server/_libs/radix-ui__react-switch.mjs +88 -49
- package/.output/server/_libs/radix-ui__react-tooltip.mjs +6 -4
- package/.output/server/_libs/semver.mjs +97 -52
- package/.output/server/_libs/sonner.mjs +1 -1
- package/.output/server/_libs/tailwind-merge.mjs +51 -3
- package/.output/server/_libs/tanstack__history.mjs +28 -8
- package/.output/server/_libs/tanstack__query-core.mjs +200 -174
- package/.output/server/_libs/tanstack__react-query.mjs +14 -13
- package/.output/server/_ssr/{api-rpc-Bwustks9.mjs → api-rpc-ORImfBFu.mjs} +18 -18
- package/.output/server/_ssr/{config.server-xu3W-WAK.mjs → config.server-BSS366KT.mjs} +2 -2
- package/.output/server/_ssr/{createServerFn-CdeRXnVy.mjs → createServerFn-DzU0k62V.mjs} +129 -90
- package/.output/server/_ssr/{deleteBundle-CXxwjwEZ.mjs → deleteBundle-CuujBAH8.mjs} +2 -2
- package/.output/server/_ssr/{dist-CRiLZLfa.mjs → dist-KboydRVk.mjs} +1 -1
- package/.output/server/_ssr/empty-plugin-adapters-B4HCzgmM.mjs +5 -0
- package/.output/server/_ssr/{getBundleChildren-DFqZ6XMp.mjs → getBundleChildren-CVtSiH5t.mjs} +2 -2
- package/.output/server/_ssr/{router-DoC6G-mF.mjs → router-DmdnzGpe.mjs} +12 -10
- package/.output/server/_ssr/{routes-BHVpk6zR.mjs → routes-Be7gDfJS.mjs} +577 -305
- package/.output/server/_ssr/{sidebar-CgbtXkE2.mjs → sidebar-Cv_H0_Jv.mjs} +6 -6
- package/.output/server/_ssr/ssr.mjs +4222 -3153
- package/.output/server/_ssr/start-D4SBEASt.mjs +4 -0
- package/.output/server/_ssr/{storageProfile-wICk5nZZ.mjs → storageProfile-FVkjPoGb.mjs} +1 -1
- package/.output/server/_tanstack-start-manifest_v-BroBMdSR.mjs +20 -0
- package/.output/server/index.mjs +111 -155
- package/package.json +12 -9
- package/.output/public/assets/BaseTanStackRouterDevtoolsPanel-Bmws3ikM-q5p5qKUx.js +0 -486
- package/.output/public/assets/FloatingTanStackRouterDevtools-B7vy70jP-Bzs2Gthe.js +0 -1
- package/.output/public/assets/clsx-CbprLf2V.js +0 -1
- package/.output/public/assets/dist-B5egZOkC.js +0 -9
- package/.output/public/assets/main-DrVuFR7r.js +0 -10
- package/.output/public/assets/preload-helper-C5ST2IKa.js +0 -1
- package/.output/public/assets/routes-C_bgs7kg.js +0 -54
- package/.output/public/assets/styles-DZ0tCVA1.css +0 -2
- package/.output/server/_libs/hookable.mjs +0 -41
- package/.output/server/_libs/tanstack__router-core.mjs +0 -6
- package/.output/server/_libs/unctx.mjs +0 -82
- package/.output/server/_ssr/start-D0X4LIsd.mjs +0 -4
- package/.output/server/_tanstack-start-manifest_v-D2MqgD3d.mjs +0 -22
|
@@ -1,27 +1,27 @@
|
|
|
1
1
|
import { r as __toESM } from "../_runtime.mjs";
|
|
2
|
-
import { c as createServerFn, i as TSS_SERVER_FUNCTION } from "./createServerFn-
|
|
3
|
-
import { c as getPatchBaseFileHash, d as isValidCohort, f as normalizeCohortValue, l as getPatchFileHash, n as NUMERIC_COHORT_SIZE, o as getNumericCohortRolloutPosition, p as normalizeRolloutCohortCount, s as getPatchBaseBundleId, t as INVALID_COHORT_ERROR_MESSAGE } from "./dist-
|
|
4
|
-
import { A as Slot, P as require_jsx_runtime, a as Overlay2, c as Title2, d as Description, f as Overlay, g as Trigger, h as Title, i as Description2, l as Close, m as Root, n as Cancel, o as Portal2, p as Portal, r as Content2, s as Root2, t as Action, u as Content } from "../_libs/@radix-ui/react-alert-dialog+[...].mjs";
|
|
2
|
+
import { c as createServerFn, i as TSS_SERVER_FUNCTION } from "./createServerFn-DzU0k62V.mjs";
|
|
3
|
+
import { c as getPatchBaseFileHash, d as isValidCohort, f as normalizeCohortValue, l as getPatchFileHash, n as NUMERIC_COHORT_SIZE, o as getNumericCohortRolloutPosition, p as normalizeRolloutCohortCount, s as getPatchBaseBundleId, t as INVALID_COHORT_ERROR_MESSAGE } from "./dist-KboydRVk.mjs";
|
|
5
4
|
import { u as require_react } from "../_libs/@floating-ui/react-dom+[...].mjs";
|
|
6
|
-
import {
|
|
5
|
+
import { A as Slot, P as require_jsx_runtime, a as Overlay2, c as Title2, d as Description, f as Overlay, g as Trigger, h as Title, i as Description2, l as Close, m as Root, n as Cancel, o as Portal2, p as Portal, r as Content2, s as Root2, t as Action, u as Content } from "../_libs/@radix-ui/react-alert-dialog+[...].mjs";
|
|
6
|
+
import { C as ChevronLeft, E as ArrowRight, S as ChevronRight, T as Check, _ as ExternalLink, a as RotateCcw, b as CircleCheck, c as Package, d as Minus, f as LoaderCircle, g as FingerprintPattern, h as Funnel, n as TriangleAlert, o as Plus, p as List, r as Trash2, t as X, v as Download, w as ChevronDown, x as ChevronUp, y as CircleX } from "../_libs/lucide-react.mjs";
|
|
7
7
|
import { t as cva } from "../_libs/class-variance-authority+clsx.mjs";
|
|
8
|
-
import { a as
|
|
8
|
+
import { a as SelectItemIndicator, c as SelectScrollDownButton$1, d as SelectValue$1, f as SelectViewport, i as SelectItem$1, l as SelectScrollUpButton$1, n as SelectContent$1, o as SelectItemText, r as SelectIcon, s as SelectPortal, t as Select, u as SelectTrigger$1 } from "../_libs/@radix-ui/react-select+[...].mjs";
|
|
9
9
|
import { t as Root$1 } from "../_libs/radix-ui__react-label.mjs";
|
|
10
|
-
import { i as
|
|
11
|
-
import { n as
|
|
12
|
-
import { C as useIsMobile, S as cn, _ as Skeleton, g as SidebarTrigger, n as Input, r as Separator$1, t as Button, v as Tooltip$1, x as TooltipTrigger, y as TooltipContent } from "./sidebar-
|
|
13
|
-
import {
|
|
10
|
+
import { i as SliderTrack, n as SliderRange, r as SliderThumb, t as Slider } from "../_libs/radix-ui__react-slider.mjs";
|
|
11
|
+
import { n as SwitchThumb, t as Switch } from "../_libs/radix-ui__react-switch.mjs";
|
|
12
|
+
import { C as useIsMobile, S as cn, _ as Skeleton, g as SidebarTrigger, n as Input, r as Separator$1, t as Button, v as Tooltip$1, x as TooltipTrigger, y as TooltipContent } from "./sidebar-Cv_H0_Jv.mjs";
|
|
13
|
+
import { m as useSearch, p as useNavigate } from "../_libs/@tanstack/react-router+[...].mjs";
|
|
14
14
|
import { n as useStore, t as useForm } from "../_libs/@tanstack/react-form+[...].mjs";
|
|
15
15
|
import { i as useQueryClient, n as useQuery, t as useMutation } from "../_libs/tanstack__react-query.mjs";
|
|
16
16
|
import { n as toast } from "../_libs/sonner.mjs";
|
|
17
|
-
import { t as getServerFnById } from "../
|
|
17
|
+
import { t as getServerFnById } from "../__23tanstack-start-server-fn-resolver-B12pVvhf.mjs";
|
|
18
18
|
import { t as require_semver } from "../_libs/semver.mjs";
|
|
19
19
|
import { i as getCoreRowModel, n as useReactTable, r as createColumnHelper, t as flexRender } from "../_libs/@tanstack/react-table+[...].mjs";
|
|
20
20
|
import { n as require_dayjs_min, t as require_relativeTime } from "../_libs/dayjs.mjs";
|
|
21
|
-
//#region node_modules/.nitro/vite/services/ssr/assets/routes-
|
|
21
|
+
//#region node_modules/.nitro/vite/services/ssr/assets/routes-Be7gDfJS.js
|
|
22
|
+
var import_react = /* @__PURE__ */ __toESM(require_react());
|
|
22
23
|
var import_jsx_runtime = require_jsx_runtime();
|
|
23
24
|
var import_semver = /* @__PURE__ */ __toESM(require_semver());
|
|
24
|
-
var import_react = /* @__PURE__ */ __toESM(require_react());
|
|
25
25
|
var import_dayjs_min = /* @__PURE__ */ __toESM(require_dayjs_min());
|
|
26
26
|
var import_relativeTime = /* @__PURE__ */ __toESM(require_relativeTime());
|
|
27
27
|
var extractTimestampFromUUIDv7 = (uuid) => {
|
|
@@ -195,7 +195,6 @@ function BundleIdDisplay({ bundleId, className }) {
|
|
|
195
195
|
}
|
|
196
196
|
function AppleIcon({ className }) {
|
|
197
197
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", {
|
|
198
|
-
role: "img",
|
|
199
198
|
"aria-label": "iOS",
|
|
200
199
|
viewBox: "0 0 24 24",
|
|
201
200
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -206,7 +205,6 @@ function AppleIcon({ className }) {
|
|
|
206
205
|
}
|
|
207
206
|
function AndroidIcon({ className }) {
|
|
208
207
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", {
|
|
209
|
-
role: "img",
|
|
210
208
|
"aria-label": "Android",
|
|
211
209
|
viewBox: "0 0 24 24",
|
|
212
210
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -358,7 +356,7 @@ function Slider$1({ className, defaultValue, value, min = 0, max = 100, ...props
|
|
|
358
356
|
min,
|
|
359
357
|
max
|
|
360
358
|
]);
|
|
361
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
359
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Slider, {
|
|
362
360
|
"data-slot": "slider",
|
|
363
361
|
defaultValue,
|
|
364
362
|
value,
|
|
@@ -366,35 +364,35 @@ function Slider$1({ className, defaultValue, value, min = 0, max = 100, ...props
|
|
|
366
364
|
max,
|
|
367
365
|
className: cn("relative flex w-full touch-none select-none items-center", className),
|
|
368
366
|
...props,
|
|
369
|
-
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
367
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SliderTrack, {
|
|
370
368
|
"data-slot": "slider-track",
|
|
371
369
|
className: "relative h-1.5 w-full grow overflow-hidden rounded-full bg-primary/20",
|
|
372
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
370
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SliderRange, {
|
|
373
371
|
"data-slot": "slider-range",
|
|
374
372
|
className: "absolute h-full bg-primary"
|
|
375
373
|
})
|
|
376
|
-
}), Array.from({ length: _values.length }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
374
|
+
}), Array.from({ length: _values.length }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SliderThumb, {
|
|
377
375
|
"data-slot": "slider-thumb",
|
|
378
376
|
className: "block h-4 w-4 rounded-full border border-primary/50 bg-background shadow transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50"
|
|
379
377
|
}, index))]
|
|
380
378
|
});
|
|
381
379
|
}
|
|
382
380
|
function Switch$1({ className, ...props }) {
|
|
383
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
381
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Switch, {
|
|
384
382
|
"data-slot": "switch",
|
|
385
383
|
className: cn("peer inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input", className),
|
|
386
384
|
...props,
|
|
387
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
385
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SwitchThumb, {
|
|
388
386
|
"data-slot": "switch-thumb",
|
|
389
387
|
className: "pointer-events-none block h-4 w-4 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-4 data-[state=unchecked]:translate-x-0"
|
|
390
388
|
})
|
|
391
389
|
});
|
|
392
390
|
}
|
|
393
|
-
var createSsrRpc = (functionId
|
|
391
|
+
var createSsrRpc = (functionId) => {
|
|
394
392
|
const url = "/_serverFn/" + functionId;
|
|
395
393
|
const serverFnMeta = { id: functionId };
|
|
396
394
|
const fn = async (...args) => {
|
|
397
|
-
return (
|
|
395
|
+
return (await getServerFnById(functionId, { origin: "server" }))(...args);
|
|
398
396
|
};
|
|
399
397
|
return Object.assign(fn, {
|
|
400
398
|
url,
|
|
@@ -441,6 +439,17 @@ function replaceBundleInQueryData(data, updatedBundle) {
|
|
|
441
439
|
data: data.data.map((bundle) => bundle.id === updatedBundle.id ? updatedBundle : bundle)
|
|
442
440
|
};
|
|
443
441
|
}
|
|
442
|
+
function removeBundleFromQueryData(data, bundleId) {
|
|
443
|
+
if (!data) return data;
|
|
444
|
+
return {
|
|
445
|
+
...data,
|
|
446
|
+
data: data.data.filter((bundle) => bundle.id !== bundleId)
|
|
447
|
+
};
|
|
448
|
+
}
|
|
449
|
+
var hasOwn = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
450
|
+
var invalidateInBackground = (queryClient, queryKey) => {
|
|
451
|
+
queryClient.invalidateQueries({ queryKey }).catch(() => void 0);
|
|
452
|
+
};
|
|
444
453
|
function useConfigQuery() {
|
|
445
454
|
return useQuery({
|
|
446
455
|
queryKey: queryKeys.config,
|
|
@@ -495,15 +504,12 @@ function useUpdateBundleMutation() {
|
|
|
495
504
|
const queryClient = useQueryClient();
|
|
496
505
|
return useMutation({
|
|
497
506
|
mutationFn: (params) => updateBundle({ data: params }),
|
|
498
|
-
onSuccess:
|
|
507
|
+
onSuccess: ({ bundle: updatedBundle }, vars) => {
|
|
499
508
|
queryClient.setQueryData(queryKeys.bundle(vars.bundleId), updatedBundle);
|
|
500
509
|
queryClient.setQueriesData({ queryKey: queryKeys.bundles.all }, (data) => replaceBundleInQueryData(data, updatedBundle));
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
queryClient.invalidateQueries({ queryKey: queryKeys.bundle(vars.bundleId) }),
|
|
505
|
-
queryClient.invalidateQueries({ queryKey: queryKeys.channels })
|
|
506
|
-
]);
|
|
510
|
+
invalidateInBackground(queryClient, queryKeys.bundles.all);
|
|
511
|
+
if (hasOwn(vars.bundle, "patches") || hasOwn(vars.bundle, "channel") || hasOwn(vars.bundle, "platform")) invalidateInBackground(queryClient, queryKeys.bundleChildren.all);
|
|
512
|
+
if (hasOwn(vars.bundle, "channel")) invalidateInBackground(queryClient, queryKeys.channels);
|
|
507
513
|
}
|
|
508
514
|
});
|
|
509
515
|
}
|
|
@@ -526,13 +532,12 @@ function useDeleteBundleMutation() {
|
|
|
526
532
|
const queryClient = useQueryClient();
|
|
527
533
|
return useMutation({
|
|
528
534
|
mutationFn: (params) => deleteBundle({ data: params }),
|
|
529
|
-
onSuccess:
|
|
535
|
+
onSuccess: (_, vars) => {
|
|
530
536
|
queryClient.removeQueries({ queryKey: queryKeys.bundle(vars.bundleId) });
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
]);
|
|
537
|
+
queryClient.setQueriesData({ queryKey: queryKeys.bundles.all }, (data) => removeBundleFromQueryData(data, vars.bundleId));
|
|
538
|
+
invalidateInBackground(queryClient, queryKeys.bundles.all);
|
|
539
|
+
invalidateInBackground(queryClient, queryKeys.bundleChildren.all);
|
|
540
|
+
invalidateInBackground(queryClient, queryKeys.channels);
|
|
536
541
|
}
|
|
537
542
|
});
|
|
538
543
|
}
|
|
@@ -681,30 +686,30 @@ function DeleteBundleDialog({ bundle, open, onOpenChange, onSuccess }) {
|
|
|
681
686
|
});
|
|
682
687
|
}
|
|
683
688
|
function Select$1({ ...props }) {
|
|
684
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
689
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Select, {
|
|
685
690
|
"data-slot": "select",
|
|
686
691
|
...props
|
|
687
692
|
});
|
|
688
693
|
}
|
|
689
694
|
function SelectValue({ ...props }) {
|
|
690
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
695
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectValue$1, {
|
|
691
696
|
"data-slot": "select-value",
|
|
692
697
|
...props
|
|
693
698
|
});
|
|
694
699
|
}
|
|
695
700
|
function SelectTrigger({ className, children, ...props }) {
|
|
696
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
701
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(SelectTrigger$1, {
|
|
697
702
|
"data-slot": "select-trigger",
|
|
698
703
|
className: cn("flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1", className),
|
|
699
704
|
...props,
|
|
700
|
-
children: [children, /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
705
|
+
children: [children, /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectIcon, {
|
|
701
706
|
asChild: true,
|
|
702
707
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronDown, { className: "h-4 w-4 opacity-50" })
|
|
703
708
|
})]
|
|
704
709
|
});
|
|
705
710
|
}
|
|
706
711
|
function SelectContent({ className, children, position = "item-aligned", align = "center", ...props }) {
|
|
707
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
712
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectPortal, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(SelectContent$1, {
|
|
708
713
|
"data-slot": "select-content",
|
|
709
714
|
className: cn("bg-popover text-popover-foreground data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 border border-border min-w-32 rounded-lg shadow-md duration-100 relative z-50 max-h-(--radix-select-content-available-height) origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto", position === "popper" && "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1", className),
|
|
710
715
|
position,
|
|
@@ -712,7 +717,7 @@ function SelectContent({ className, children, position = "item-aligned", align =
|
|
|
712
717
|
...props,
|
|
713
718
|
children: [
|
|
714
719
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectScrollUpButton, {}),
|
|
715
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
720
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectViewport, {
|
|
716
721
|
"data-position": position,
|
|
717
722
|
className: cn("data-[position=popper]:h-[var(--radix-select-trigger-height)] data-[position=popper]:w-full data-[position=popper]:min-w-[var(--radix-select-trigger-width)]", position === "popper" && ""),
|
|
718
723
|
children
|
|
@@ -722,18 +727,18 @@ function SelectContent({ className, children, position = "item-aligned", align =
|
|
|
722
727
|
}) });
|
|
723
728
|
}
|
|
724
729
|
function SelectItem({ className, children, ...props }) {
|
|
725
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
730
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(SelectItem$1, {
|
|
726
731
|
"data-slot": "select-item",
|
|
727
732
|
className: cn("relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50", className),
|
|
728
733
|
...props,
|
|
729
734
|
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
730
735
|
className: "absolute right-2 flex h-3.5 w-3.5 items-center justify-center",
|
|
731
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
732
|
-
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
736
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectItemIndicator, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Check, { className: "h-4 w-4" }) })
|
|
737
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectItemText, { children })]
|
|
733
738
|
});
|
|
734
739
|
}
|
|
735
740
|
function SelectScrollUpButton({ className, ...props }) {
|
|
736
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
741
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectScrollUpButton$1, {
|
|
737
742
|
"data-slot": "select-scroll-up-button",
|
|
738
743
|
className: cn("bg-popover z-10 flex cursor-default items-center justify-center py-1 [&_svg:not([class*='size-'])]:size-3.5", className),
|
|
739
744
|
...props,
|
|
@@ -741,7 +746,7 @@ function SelectScrollUpButton({ className, ...props }) {
|
|
|
741
746
|
});
|
|
742
747
|
}
|
|
743
748
|
function SelectScrollDownButton({ className, ...props }) {
|
|
744
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
749
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectScrollDownButton$1, {
|
|
745
750
|
"data-slot": "select-scroll-down-button",
|
|
746
751
|
className: cn("bg-popover z-10 flex cursor-default items-center justify-center py-1 [&_svg:not([class*='size-'])]:size-3.5", className),
|
|
747
752
|
...props,
|
|
@@ -986,6 +991,7 @@ function PromoteChannelDialog({ bundle, open, onOpenChange, onSuccess }) {
|
|
|
986
991
|
type: "button",
|
|
987
992
|
variant: "outline",
|
|
988
993
|
size: "xs",
|
|
994
|
+
"aria-label": `Use ${channel} as target channel`,
|
|
989
995
|
onClick: () => setTargetChannel(channel),
|
|
990
996
|
disabled: isPromoting,
|
|
991
997
|
children: channel
|
|
@@ -2296,6 +2302,208 @@ var createBundleColumns = ({ expandedBundleId, patchCountsByBundleId, onDetailCl
|
|
|
2296
2302
|
cell: (info) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TimestampDisplay, { uuid: info.getValue() })
|
|
2297
2303
|
})
|
|
2298
2304
|
];
|
|
2305
|
+
var statusLabels = {
|
|
2306
|
+
queued: "Queued",
|
|
2307
|
+
deleting: "Deleting",
|
|
2308
|
+
deleted: "Deleted",
|
|
2309
|
+
failed: "Failed"
|
|
2310
|
+
};
|
|
2311
|
+
var getDeleteErrorMessage = (error) => error instanceof Error ? error.message : "Delete request failed";
|
|
2312
|
+
var createDeleteItems = (bundles) => bundles.map((bundle) => ({
|
|
2313
|
+
bundle,
|
|
2314
|
+
status: "queued"
|
|
2315
|
+
}));
|
|
2316
|
+
function getStatusIcon(status) {
|
|
2317
|
+
switch (status) {
|
|
2318
|
+
case "failed": return {
|
|
2319
|
+
className: "size-3.5 text-destructive",
|
|
2320
|
+
Icon: CircleX
|
|
2321
|
+
};
|
|
2322
|
+
case "deleting": return {
|
|
2323
|
+
className: "size-3.5 animate-spin text-primary",
|
|
2324
|
+
Icon: LoaderCircle
|
|
2325
|
+
};
|
|
2326
|
+
case "deleted": return {
|
|
2327
|
+
className: "size-3.5 text-primary",
|
|
2328
|
+
Icon: CircleCheck
|
|
2329
|
+
};
|
|
2330
|
+
}
|
|
2331
|
+
}
|
|
2332
|
+
function DeleteStatusIcon({ status }) {
|
|
2333
|
+
if (status === "queued") return null;
|
|
2334
|
+
const label = statusLabels[status];
|
|
2335
|
+
const { className, Icon } = getStatusIcon(status);
|
|
2336
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Tooltip$1, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(TooltipTrigger, {
|
|
2337
|
+
asChild: true,
|
|
2338
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
2339
|
+
"aria-label": label,
|
|
2340
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Icon, { className })
|
|
2341
|
+
})
|
|
2342
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TooltipContent, { children: label })] });
|
|
2343
|
+
}
|
|
2344
|
+
function SelectedBundlesDeleteDialog({ bundles, open, onOpenChange, onComplete }) {
|
|
2345
|
+
const deleteBundleMutation = useDeleteBundleMutation();
|
|
2346
|
+
const [phase, setPhase] = (0, import_react.useState)("confirming");
|
|
2347
|
+
const [items, setItems] = (0, import_react.useState)(() => createDeleteItems(bundles));
|
|
2348
|
+
const isDeleting = phase === "deleting";
|
|
2349
|
+
const totalCount = items.length;
|
|
2350
|
+
const activeCount = items.filter((item) => item.status === "deleted").length + items.filter((item) => item.status === "failed").length;
|
|
2351
|
+
const failedBundleIds = items.filter((item) => item.status === "failed").map((item) => item.bundle.id);
|
|
2352
|
+
const hasFailures = failedBundleIds.length > 0;
|
|
2353
|
+
const title = phase === "confirming" ? "Delete selected bundles?" : "Deleting bundles";
|
|
2354
|
+
const description = phase === "confirming" ? `This action cannot be undone. This will permanently delete ${bundles.length} bundles and remove them from storage.` : `${activeCount} of ${totalCount} delete requests finished.`;
|
|
2355
|
+
const deleteButtonLabel = (0, import_react.useMemo)(() => {
|
|
2356
|
+
if (!isDeleting) return "Delete";
|
|
2357
|
+
return `Deleting ${Math.min(activeCount + 1, totalCount)}/${totalCount}`;
|
|
2358
|
+
}, [
|
|
2359
|
+
activeCount,
|
|
2360
|
+
isDeleting,
|
|
2361
|
+
totalCount
|
|
2362
|
+
]);
|
|
2363
|
+
(0, import_react.useEffect)(() => {
|
|
2364
|
+
if (open && phase === "confirming") setItems(createDeleteItems(bundles));
|
|
2365
|
+
}, [
|
|
2366
|
+
bundles,
|
|
2367
|
+
open,
|
|
2368
|
+
phase
|
|
2369
|
+
]);
|
|
2370
|
+
const handleOpenChange = (nextOpen) => {
|
|
2371
|
+
if (!nextOpen && isDeleting) return;
|
|
2372
|
+
onOpenChange(nextOpen);
|
|
2373
|
+
if (!nextOpen) {
|
|
2374
|
+
setPhase("confirming");
|
|
2375
|
+
setItems(createDeleteItems(bundles));
|
|
2376
|
+
}
|
|
2377
|
+
};
|
|
2378
|
+
const runDeletion = async (bundleIds) => {
|
|
2379
|
+
if (isDeleting || bundleIds.length === 0) return;
|
|
2380
|
+
const bundleIdSet = new Set(bundleIds);
|
|
2381
|
+
const deletedBundleIds = [];
|
|
2382
|
+
const nextFailedBundleIds = [];
|
|
2383
|
+
setPhase("deleting");
|
|
2384
|
+
setItems((currentItems) => currentItems.map((item) => bundleIdSet.has(item.bundle.id) ? {
|
|
2385
|
+
bundle: item.bundle,
|
|
2386
|
+
status: "queued"
|
|
2387
|
+
} : item));
|
|
2388
|
+
for (const bundleId of bundleIds) {
|
|
2389
|
+
setItems((currentItems) => currentItems.map((item) => item.bundle.id === bundleId ? {
|
|
2390
|
+
bundle: item.bundle,
|
|
2391
|
+
status: "deleting"
|
|
2392
|
+
} : item));
|
|
2393
|
+
try {
|
|
2394
|
+
await deleteBundleMutation.mutateAsync({ bundleId });
|
|
2395
|
+
deletedBundleIds.push(bundleId);
|
|
2396
|
+
setItems((currentItems) => currentItems.map((item) => item.bundle.id === bundleId ? {
|
|
2397
|
+
bundle: item.bundle,
|
|
2398
|
+
status: "deleted"
|
|
2399
|
+
} : item));
|
|
2400
|
+
} catch (error) {
|
|
2401
|
+
nextFailedBundleIds.push(bundleId);
|
|
2402
|
+
setItems((currentItems) => currentItems.map((item) => item.bundle.id === bundleId ? {
|
|
2403
|
+
bundle: item.bundle,
|
|
2404
|
+
message: getDeleteErrorMessage(error),
|
|
2405
|
+
status: "failed"
|
|
2406
|
+
} : item));
|
|
2407
|
+
}
|
|
2408
|
+
}
|
|
2409
|
+
setPhase("complete");
|
|
2410
|
+
onComplete({
|
|
2411
|
+
deletedBundleIds,
|
|
2412
|
+
failedBundleIds: nextFailedBundleIds
|
|
2413
|
+
});
|
|
2414
|
+
if (nextFailedBundleIds.length > 0) {
|
|
2415
|
+
toast.error(`${deletedBundleIds.length} deleted, ${nextFailedBundleIds.length} failed`);
|
|
2416
|
+
return;
|
|
2417
|
+
}
|
|
2418
|
+
toast.success(`${deletedBundleIds.length} bundles deleted successfully`);
|
|
2419
|
+
};
|
|
2420
|
+
const handleDelete = () => {
|
|
2421
|
+
runDeletion(items.map((item) => item.bundle.id));
|
|
2422
|
+
};
|
|
2423
|
+
const handleRetryFailed = () => {
|
|
2424
|
+
runDeletion(failedBundleIds);
|
|
2425
|
+
};
|
|
2426
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Dialog$1, {
|
|
2427
|
+
open,
|
|
2428
|
+
onOpenChange: handleOpenChange,
|
|
2429
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(DialogContent, {
|
|
2430
|
+
showCloseButton: !isDeleting,
|
|
2431
|
+
className: "sm:max-w-lg",
|
|
2432
|
+
onEscapeKeyDown: (event) => {
|
|
2433
|
+
if (isDeleting) event.preventDefault();
|
|
2434
|
+
},
|
|
2435
|
+
onInteractOutside: (event) => {
|
|
2436
|
+
if (isDeleting) event.preventDefault();
|
|
2437
|
+
},
|
|
2438
|
+
children: [
|
|
2439
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(DialogHeader, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(DialogTitle, { children: title }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DialogDescription, { children: description })] }),
|
|
2440
|
+
phase === "confirming" ? null : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Card, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CardContent, {
|
|
2441
|
+
className: "max-h-[50vh] overflow-y-auto p-0",
|
|
2442
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Table, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(TableHeader, {
|
|
2443
|
+
className: "sticky top-0 bg-card",
|
|
2444
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(TableRow, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(TableHead, {
|
|
2445
|
+
className: "w-12 text-center",
|
|
2446
|
+
children: "Status"
|
|
2447
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TableHead, { children: "Bundle" })] })
|
|
2448
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TableBody, { children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(TableRow, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(TableCell, {
|
|
2449
|
+
className: "text-center align-middle",
|
|
2450
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
2451
|
+
className: "flex justify-center",
|
|
2452
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DeleteStatusIcon, { status: item.status })
|
|
2453
|
+
})
|
|
2454
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TableCell, {
|
|
2455
|
+
className: "whitespace-normal",
|
|
2456
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
2457
|
+
className: "min-w-0",
|
|
2458
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
2459
|
+
className: "break-all font-mono text-[11px] text-foreground",
|
|
2460
|
+
children: item.bundle.id
|
|
2461
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
2462
|
+
className: "mt-0.5 flex flex-wrap gap-x-2 gap-y-1 text-[11px] text-muted-foreground",
|
|
2463
|
+
children: [
|
|
2464
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: item.bundle.channel }),
|
|
2465
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: item.bundle.platform }),
|
|
2466
|
+
item.message ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
2467
|
+
className: "text-destructive",
|
|
2468
|
+
children: item.message
|
|
2469
|
+
}) : null
|
|
2470
|
+
]
|
|
2471
|
+
})]
|
|
2472
|
+
})
|
|
2473
|
+
})] }, item.bundle.id)) })] })
|
|
2474
|
+
}) }),
|
|
2475
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(DialogFooter, { children: [
|
|
2476
|
+
phase === "confirming" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
|
|
2477
|
+
variant: "outline",
|
|
2478
|
+
onClick: () => handleOpenChange(false),
|
|
2479
|
+
children: "Cancel"
|
|
2480
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Button, {
|
|
2481
|
+
variant: "destructive",
|
|
2482
|
+
onClick: handleDelete,
|
|
2483
|
+
disabled: totalCount === 0,
|
|
2484
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Trash2, { "data-icon": "inline-start" }), "Delete"]
|
|
2485
|
+
})] }) : null,
|
|
2486
|
+
phase === "deleting" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Button, {
|
|
2487
|
+
variant: "destructive",
|
|
2488
|
+
disabled: true,
|
|
2489
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(LoaderCircle, {
|
|
2490
|
+
"data-icon": "inline-start",
|
|
2491
|
+
className: "animate-spin"
|
|
2492
|
+
}), deleteButtonLabel]
|
|
2493
|
+
}) : null,
|
|
2494
|
+
phase === "complete" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
|
|
2495
|
+
variant: "outline",
|
|
2496
|
+
onClick: () => handleOpenChange(false),
|
|
2497
|
+
children: "Close"
|
|
2498
|
+
}), hasFailures ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Button, {
|
|
2499
|
+
onClick: handleRetryFailed,
|
|
2500
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(RotateCcw, { "data-icon": "inline-start" }), "Retry failed"]
|
|
2501
|
+
}) : null] }) : null
|
|
2502
|
+
] })
|
|
2503
|
+
]
|
|
2504
|
+
})
|
|
2505
|
+
});
|
|
2506
|
+
}
|
|
2299
2507
|
function MobileStatusBadge({ enabled, trueLabel, falseLabel, falseIcon = "x", trueTone = "success" }) {
|
|
2300
2508
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
|
|
2301
2509
|
className: cn("inline-flex items-center gap-1.5 rounded-full px-2.5 py-1 text-[11px] font-medium", enabled ? trueTone === "warning" ? "bg-amber-500/14 text-amber-700 dark:text-amber-300" : "bg-emerald-500/12 text-emerald-700 dark:text-emerald-300" : falseIcon === "minus" ? "bg-muted text-muted-foreground" : "bg-red-500/12 text-red-700 dark:text-red-300"),
|
|
@@ -2310,8 +2518,13 @@ function MobileStatusBadge({ enabled, trueLabel, falseLabel, falseIcon = "x", tr
|
|
|
2310
2518
|
function BundlesTable({ bundles, pagination, expandedBundleId, selectedBundleId, onExpandedBundleChange, onDetailClick }) {
|
|
2311
2519
|
const { setFilters } = useFilterParams();
|
|
2312
2520
|
const isMobile = useIsMobile();
|
|
2521
|
+
const [selectedBundleIds, setSelectedBundleIds] = (0, import_react.useState)([]);
|
|
2522
|
+
const [deleteDialogOpen, setDeleteDialogOpen] = (0, import_react.useState)(false);
|
|
2313
2523
|
const cursorPagination = pagination;
|
|
2314
|
-
const
|
|
2524
|
+
const bundleIds = bundles.map((bundle) => bundle.id);
|
|
2525
|
+
const selectedBundles = bundles.filter((bundle) => selectedBundleIds.includes(bundle.id));
|
|
2526
|
+
const allBundlesSelected = bundles.length > 0 && selectedBundles.length === bundles.length;
|
|
2527
|
+
const { data: patchCountsByBundleId = {} } = useBundleChildCountsQuery(bundleIds);
|
|
2315
2528
|
const { data: childBundles = [], isLoading: isChildBundlesLoading } = useBundleChildrenQuery(expandedBundleId ?? "");
|
|
2316
2529
|
const bundleColumns = createBundleColumns({
|
|
2317
2530
|
expandedBundleId,
|
|
@@ -2346,280 +2559,339 @@ function BundlesTable({ bundles, pagination, expandedBundleId, selectedBundleId,
|
|
|
2346
2559
|
before: void 0
|
|
2347
2560
|
});
|
|
2348
2561
|
};
|
|
2562
|
+
const toggleBundleSelection = (bundleId) => {
|
|
2563
|
+
setSelectedBundleIds((current) => current.includes(bundleId) ? current.filter((selectedBundleId) => selectedBundleId !== bundleId) : [...current, bundleId]);
|
|
2564
|
+
};
|
|
2565
|
+
const handleToggleAllBundles = () => {
|
|
2566
|
+
setSelectedBundleIds(allBundlesSelected ? [] : bundleIds);
|
|
2567
|
+
};
|
|
2349
2568
|
const startEntry = bundles.length === 0 ? 0 : (currentPage - 1) * 20 + 1;
|
|
2350
2569
|
const endEntry = startEntry === 0 ? 0 : startEntry + bundles.length - 1;
|
|
2351
2570
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
2352
|
-
className: "flex flex-col gap-4",
|
|
2353
|
-
children: [
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
className: "
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
2387
|
-
className: "shrink-0",
|
|
2388
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChannelBadge, { channel: bundle.channel })
|
|
2389
|
-
})]
|
|
2390
|
-
}),
|
|
2391
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
2392
|
-
className: "grid grid-cols-2 gap-3 text-sm",
|
|
2393
|
-
children: [
|
|
2394
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
2395
|
-
className: "rounded-md bg-muted/40 p-3",
|
|
2396
|
-
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
2397
|
-
className: "mb-1 text-[11px] font-medium uppercase text-muted-foreground/70",
|
|
2398
|
-
children: "Platform"
|
|
2399
|
-
}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
2400
|
-
className: "flex items-center gap-2",
|
|
2401
|
-
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(PlatformIcon, {
|
|
2402
|
-
platform: bundle.platform,
|
|
2403
|
-
className: "h-4 w-4"
|
|
2404
|
-
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: bundle.platform === "ios" ? "iOS" : "Android" })]
|
|
2405
|
-
})]
|
|
2406
|
-
}),
|
|
2407
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
2408
|
-
className: "rounded-md bg-muted/40 p-3",
|
|
2409
|
-
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
2410
|
-
className: "mb-1 text-[11px] font-medium uppercase text-muted-foreground/70",
|
|
2411
|
-
children: "Created"
|
|
2412
|
-
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
2413
|
-
className: "text-xs text-foreground",
|
|
2414
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TimestampDisplay, { uuid: bundle.id })
|
|
2415
|
-
})]
|
|
2416
|
-
}),
|
|
2417
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
2418
|
-
className: "rounded-md bg-muted/40 p-3",
|
|
2419
|
-
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
2420
|
-
className: "mb-1 text-[11px] font-medium uppercase text-muted-foreground/70",
|
|
2421
|
-
children: "Rollout"
|
|
2422
|
-
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RolloutPercentageBadge, { percentage: rolloutPercentage })]
|
|
2423
|
-
}),
|
|
2424
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
2425
|
-
className: "rounded-md bg-muted/40 p-3",
|
|
2571
|
+
className: "flex min-h-0 min-w-0 flex-1 flex-col gap-4",
|
|
2572
|
+
children: [
|
|
2573
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
2574
|
+
className: "min-h-0 min-w-0 flex-1 overflow-hidden rounded-lg border bg-card text-card-foreground shadow-sm [&_[data-slot=table-container]]:h-full [&_[data-slot=table-container]]:overflow-auto",
|
|
2575
|
+
children: isMobile ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
2576
|
+
className: "flex h-full flex-col overflow-y-auto",
|
|
2577
|
+
children: bundles.length ? bundles.map((bundle) => {
|
|
2578
|
+
const isExpanded = bundle.id === expandedBundleId;
|
|
2579
|
+
const panelId = `bundle-lineage-panel-${bundle.id}`;
|
|
2580
|
+
const rolloutPercentage = (bundle.rolloutCohortCount ?? 1e3) / 10;
|
|
2581
|
+
const patchCount = patchCountsByBundleId[bundle.id];
|
|
2582
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
2583
|
+
"data-state": bundle.id === selectedBundleId ? "selected" : void 0,
|
|
2584
|
+
className: cn("border-b border-border/60 last:border-b-0 data-[state=selected]:bg-muted/20", isExpanded && "bg-primary/5"),
|
|
2585
|
+
children: [
|
|
2586
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", {
|
|
2587
|
+
className: "flex items-center gap-2 border-b border-border/60 px-4 py-3 text-xs font-medium text-muted-foreground",
|
|
2588
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
|
|
2589
|
+
type: "checkbox",
|
|
2590
|
+
checked: selectedBundleIds.includes(bundle.id),
|
|
2591
|
+
className: "size-4 accent-primary",
|
|
2592
|
+
onChange: () => toggleBundleSelection(bundle.id)
|
|
2593
|
+
}), "Select bundle"]
|
|
2594
|
+
}),
|
|
2595
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", {
|
|
2596
|
+
type: "button",
|
|
2597
|
+
"aria-label": `Open bundle ${bundle.id}`,
|
|
2598
|
+
className: "flex w-full flex-col gap-4 p-4 text-left",
|
|
2599
|
+
onClick: () => onDetailClick(bundle),
|
|
2600
|
+
children: [
|
|
2601
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
2602
|
+
className: "flex items-start justify-between gap-3",
|
|
2603
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
2604
|
+
className: "min-w-0 space-y-2",
|
|
2426
2605
|
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
2427
|
-
className: "
|
|
2428
|
-
children: "
|
|
2606
|
+
className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-muted-foreground/70",
|
|
2607
|
+
children: "Bundle"
|
|
2429
2608
|
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
2430
|
-
className: "
|
|
2431
|
-
children:
|
|
2609
|
+
className: "min-w-0 text-sm font-medium",
|
|
2610
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(BundleIdDisplay, {
|
|
2611
|
+
bundleId: bundle.id,
|
|
2612
|
+
maxLength: 18,
|
|
2613
|
+
fullOnMobile: true
|
|
2614
|
+
})
|
|
2432
2615
|
})]
|
|
2433
|
-
}),
|
|
2434
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
2435
|
-
className: "rounded-md bg-muted/40 p-3",
|
|
2436
|
-
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
2437
|
-
className: "mb-1 text-[11px] font-medium uppercase text-muted-foreground/70",
|
|
2438
|
-
children: "Status"
|
|
2439
|
-
}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
2440
|
-
className: "flex flex-wrap items-center gap-2",
|
|
2441
|
-
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(MobileStatusBadge, {
|
|
2442
|
-
enabled: bundle.enabled,
|
|
2443
|
-
trueLabel: "Enabled",
|
|
2444
|
-
falseLabel: "Disabled"
|
|
2445
|
-
}), bundle.shouldForceUpdate ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MobileStatusBadge, {
|
|
2446
|
-
enabled: bundle.shouldForceUpdate,
|
|
2447
|
-
trueLabel: "Force update",
|
|
2448
|
-
falseLabel: "Optional",
|
|
2449
|
-
falseIcon: "minus",
|
|
2450
|
-
trueTone: "warning"
|
|
2451
|
-
}) : null]
|
|
2452
|
-
})]
|
|
2453
|
-
})
|
|
2454
|
-
]
|
|
2455
|
-
}),
|
|
2456
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
2457
|
-
className: "grid gap-2 rounded-md border border-border/70 bg-background/80 p-3 text-sm",
|
|
2458
|
-
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
2459
|
-
className: "flex items-center justify-between gap-3",
|
|
2460
|
-
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
2461
|
-
className: "text-muted-foreground",
|
|
2462
|
-
children: "Target"
|
|
2463
2616
|
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
2464
|
-
className: "
|
|
2465
|
-
children:
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2617
|
+
className: "shrink-0",
|
|
2618
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChannelBadge, { channel: bundle.channel })
|
|
2619
|
+
})]
|
|
2620
|
+
}),
|
|
2621
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
2622
|
+
className: "grid grid-cols-2 gap-3 text-sm",
|
|
2623
|
+
children: [
|
|
2624
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
2625
|
+
className: "rounded-md bg-muted/40 p-3",
|
|
2626
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
2627
|
+
className: "mb-1 text-[11px] font-medium uppercase text-muted-foreground/70",
|
|
2628
|
+
children: "Platform"
|
|
2629
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
2630
|
+
className: "flex items-center gap-2",
|
|
2631
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(PlatformIcon, {
|
|
2632
|
+
platform: bundle.platform,
|
|
2633
|
+
className: "h-4 w-4"
|
|
2634
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: bundle.platform === "ios" ? "iOS" : "Android" })]
|
|
2635
|
+
})]
|
|
2636
|
+
}),
|
|
2637
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
2638
|
+
className: "rounded-md bg-muted/40 p-3",
|
|
2639
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
2640
|
+
className: "mb-1 text-[11px] font-medium uppercase text-muted-foreground/70",
|
|
2641
|
+
children: "Created"
|
|
2642
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
2643
|
+
className: "text-xs text-foreground",
|
|
2644
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TimestampDisplay, { uuid: bundle.id })
|
|
2645
|
+
})]
|
|
2646
|
+
}),
|
|
2647
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
2648
|
+
className: "rounded-md bg-muted/40 p-3",
|
|
2649
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
2650
|
+
className: "mb-1 text-[11px] font-medium uppercase text-muted-foreground/70",
|
|
2651
|
+
children: "Rollout"
|
|
2652
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RolloutPercentageBadge, { percentage: rolloutPercentage })]
|
|
2653
|
+
}),
|
|
2654
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
2655
|
+
className: "rounded-md bg-muted/40 p-3",
|
|
2656
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
2657
|
+
className: "mb-1 text-[11px] font-medium uppercase text-muted-foreground/70",
|
|
2658
|
+
children: "Patches"
|
|
2659
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
2660
|
+
className: "text-xs text-foreground",
|
|
2661
|
+
children: patchCount === void 0 ? "Checking" : patchCount > 0 ? `${patchCount} ${patchCount === 1 ? "patch" : "patches"}` : "-"
|
|
2662
|
+
})]
|
|
2663
|
+
}),
|
|
2664
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
2665
|
+
className: "rounded-md bg-muted/40 p-3",
|
|
2666
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
2667
|
+
className: "mb-1 text-[11px] font-medium uppercase text-muted-foreground/70",
|
|
2668
|
+
children: "Status"
|
|
2669
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
2670
|
+
className: "flex flex-wrap items-center gap-2",
|
|
2671
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(MobileStatusBadge, {
|
|
2672
|
+
enabled: bundle.enabled,
|
|
2673
|
+
trueLabel: "Enabled",
|
|
2674
|
+
falseLabel: "Disabled"
|
|
2675
|
+
}), bundle.shouldForceUpdate ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MobileStatusBadge, {
|
|
2676
|
+
enabled: bundle.shouldForceUpdate,
|
|
2677
|
+
trueLabel: "Force update",
|
|
2678
|
+
falseLabel: "Optional",
|
|
2679
|
+
falseIcon: "minus",
|
|
2680
|
+
trueTone: "warning"
|
|
2681
|
+
}) : null]
|
|
2471
2682
|
})]
|
|
2472
|
-
}) : bundle.targetAppVersion ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
|
|
2473
|
-
translate: "no",
|
|
2474
|
-
className: "inline-flex items-center gap-2 text-xs",
|
|
2475
|
-
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Package, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }), bundle.targetAppVersion]
|
|
2476
|
-
}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
2477
|
-
className: "text-xs text-muted-foreground",
|
|
2478
|
-
children: "-"
|
|
2479
2683
|
})
|
|
2684
|
+
]
|
|
2685
|
+
}),
|
|
2686
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
2687
|
+
className: "grid gap-2 rounded-md border border-border/70 bg-background/80 p-3 text-sm",
|
|
2688
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
2689
|
+
className: "flex items-center justify-between gap-3",
|
|
2690
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
2691
|
+
className: "text-muted-foreground",
|
|
2692
|
+
children: "Target"
|
|
2693
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
2694
|
+
className: "min-w-0 text-right",
|
|
2695
|
+
children: bundle.fingerprintHash ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
|
|
2696
|
+
translate: "no",
|
|
2697
|
+
className: "inline-flex min-w-0 items-start gap-2 font-mono text-xs",
|
|
2698
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(FingerprintPattern, { className: "mt-0.5 h-3.5 w-3.5 shrink-0 text-muted-foreground" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(HashValueDisplay, {
|
|
2699
|
+
value: bundle.fingerprintHash,
|
|
2700
|
+
maxLength: 12
|
|
2701
|
+
})]
|
|
2702
|
+
}) : bundle.targetAppVersion ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
|
|
2703
|
+
translate: "no",
|
|
2704
|
+
className: "inline-flex items-center gap-2 text-xs",
|
|
2705
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Package, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }), bundle.targetAppVersion]
|
|
2706
|
+
}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
2707
|
+
className: "text-xs text-muted-foreground",
|
|
2708
|
+
children: "-"
|
|
2709
|
+
})
|
|
2710
|
+
})]
|
|
2711
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
2712
|
+
className: "flex items-start justify-between gap-3",
|
|
2713
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
2714
|
+
className: "text-muted-foreground",
|
|
2715
|
+
children: "Message"
|
|
2716
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
2717
|
+
className: "min-w-0 text-right text-xs text-foreground/80",
|
|
2718
|
+
children: bundle.message || "-"
|
|
2719
|
+
})]
|
|
2480
2720
|
})]
|
|
2481
|
-
})
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2721
|
+
})
|
|
2722
|
+
]
|
|
2723
|
+
}),
|
|
2724
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
2725
|
+
className: "border-t border-border/60 px-4 py-3",
|
|
2726
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Button, {
|
|
2727
|
+
type: "button",
|
|
2728
|
+
variant: "ghost",
|
|
2729
|
+
className: "h-9 w-full justify-between px-3 text-sm",
|
|
2730
|
+
"aria-label": isExpanded ? "Hide Lineage" : "Show Lineage",
|
|
2731
|
+
"aria-controls": panelId,
|
|
2732
|
+
"aria-expanded": isExpanded,
|
|
2733
|
+
onClick: () => onExpandedBundleChange(isExpanded ? void 0 : bundle.id),
|
|
2734
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: patchCount === void 0 ? "Patch lineage" : `Patch lineage (${patchCount})` }), isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronUp, {
|
|
2735
|
+
className: "h-4 w-4",
|
|
2736
|
+
"aria-hidden": "true"
|
|
2737
|
+
}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronDown, {
|
|
2738
|
+
className: "h-4 w-4",
|
|
2739
|
+
"aria-hidden": "true"
|
|
2490
2740
|
})]
|
|
2491
2741
|
})
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2742
|
+
}),
|
|
2743
|
+
isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(BundleChildrenPanel, {
|
|
2744
|
+
panelId,
|
|
2745
|
+
bundle,
|
|
2746
|
+
bundles: childBundles,
|
|
2747
|
+
loading: isChildBundlesLoading,
|
|
2748
|
+
onDetailClick
|
|
2749
|
+
}) : null
|
|
2750
|
+
]
|
|
2751
|
+
}, bundle.id);
|
|
2752
|
+
}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
2753
|
+
className: "flex h-32 items-center justify-center px-6 text-center text-sm text-muted-foreground",
|
|
2754
|
+
children: "No bundles found matching your filters."
|
|
2755
|
+
})
|
|
2756
|
+
}) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Table, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(TableHeader, {
|
|
2757
|
+
className: "bg-muted/40",
|
|
2758
|
+
children: table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(TableRow, {
|
|
2759
|
+
className: "border-b border-border/60 hover:bg-transparent",
|
|
2760
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(TableHead, {
|
|
2761
|
+
className: "w-10",
|
|
2762
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
|
|
2763
|
+
type: "checkbox",
|
|
2764
|
+
checked: allBundlesSelected,
|
|
2765
|
+
"aria-label": "Select all bundles",
|
|
2766
|
+
className: "size-4 accent-primary",
|
|
2767
|
+
onChange: handleToggleAllBundles
|
|
2768
|
+
})
|
|
2769
|
+
}), headerGroup.headers.map((header) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TableHead, {
|
|
2770
|
+
className: "h-10 text-xs font-semibold uppercase text-muted-foreground/70",
|
|
2771
|
+
children: header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())
|
|
2772
|
+
}, header.id))]
|
|
2773
|
+
}, headerGroup.id))
|
|
2774
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TableBody, { children: table.getRowModel().rows?.length ? table.getRowModel().rows.map((row) => {
|
|
2775
|
+
const isExpanded = row.original.id === expandedBundleId;
|
|
2776
|
+
const panelId = `bundle-lineage-panel-${row.original.id}`;
|
|
2777
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react.Fragment, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(TableRow, {
|
|
2778
|
+
"data-state": row.original.id === selectedBundleId ? "selected" : void 0,
|
|
2779
|
+
className: cn("cursor-pointer transition-colors hover:bg-muted/10 focus-within:bg-muted/15 data-[state=selected]:bg-muted/15", isExpanded && "bg-primary/5"),
|
|
2780
|
+
onClick: () => onDetailClick(row.original),
|
|
2781
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(TableCell, {
|
|
2782
|
+
className: "py-3",
|
|
2783
|
+
onClick: (event) => event.stopPropagation(),
|
|
2784
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
|
|
2785
|
+
type: "checkbox",
|
|
2786
|
+
checked: selectedBundleIds.includes(row.original.id),
|
|
2787
|
+
"aria-label": `Select bundle ${row.original.id}`,
|
|
2788
|
+
className: "size-4 accent-primary",
|
|
2789
|
+
onChange: () => toggleBundleSelection(row.original.id)
|
|
2790
|
+
})
|
|
2791
|
+
}), row.getVisibleCells().map((cell) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TableCell, {
|
|
2792
|
+
className: "py-3",
|
|
2793
|
+
children: flexRender(cell.column.columnDef.cell, cell.getContext())
|
|
2794
|
+
}, cell.id))]
|
|
2795
|
+
}), isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TableRow, {
|
|
2796
|
+
className: "hover:bg-transparent",
|
|
2797
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TableCell, {
|
|
2798
|
+
colSpan: bundleColumns.length + 1,
|
|
2799
|
+
className: "border-t-0 p-0",
|
|
2800
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(BundleChildrenPanel, {
|
|
2514
2801
|
panelId,
|
|
2515
|
-
bundle,
|
|
2802
|
+
bundle: row.original,
|
|
2516
2803
|
bundles: childBundles,
|
|
2517
2804
|
loading: isChildBundlesLoading,
|
|
2518
2805
|
onDetailClick
|
|
2519
|
-
})
|
|
2520
|
-
]
|
|
2521
|
-
}, bundle.id);
|
|
2522
|
-
}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
2523
|
-
className: "flex h-32 items-center justify-center px-6 text-center text-sm text-muted-foreground",
|
|
2524
|
-
children: "No bundles found matching your filters."
|
|
2525
|
-
})
|
|
2526
|
-
}) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Table, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(TableHeader, {
|
|
2527
|
-
className: "bg-muted/40",
|
|
2528
|
-
children: table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TableRow, {
|
|
2529
|
-
className: "border-b border-border/60 hover:bg-transparent",
|
|
2530
|
-
children: headerGroup.headers.map((header) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TableHead, {
|
|
2531
|
-
className: "h-10 text-xs font-semibold uppercase text-muted-foreground/70",
|
|
2532
|
-
children: header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())
|
|
2533
|
-
}, header.id))
|
|
2534
|
-
}, headerGroup.id))
|
|
2535
|
-
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TableBody, { children: table.getRowModel().rows?.length ? table.getRowModel().rows.map((row) => {
|
|
2536
|
-
const isExpanded = row.original.id === expandedBundleId;
|
|
2537
|
-
const panelId = `bundle-lineage-panel-${row.original.id}`;
|
|
2538
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react.Fragment, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(TableRow, {
|
|
2539
|
-
"data-state": row.original.id === selectedBundleId ? "selected" : void 0,
|
|
2540
|
-
className: cn("cursor-pointer transition-colors hover:bg-muted/10 focus-within:bg-muted/15 data-[state=selected]:bg-muted/15", isExpanded && "bg-primary/5"),
|
|
2541
|
-
onClick: () => onDetailClick(row.original),
|
|
2542
|
-
children: row.getVisibleCells().map((cell) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TableCell, {
|
|
2543
|
-
className: "py-3",
|
|
2544
|
-
children: flexRender(cell.column.columnDef.cell, cell.getContext())
|
|
2545
|
-
}, cell.id))
|
|
2546
|
-
}), isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TableRow, {
|
|
2547
|
-
className: "hover:bg-transparent",
|
|
2548
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TableCell, {
|
|
2549
|
-
colSpan: bundleColumns.length,
|
|
2550
|
-
className: "border-t-0 p-0",
|
|
2551
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(BundleChildrenPanel, {
|
|
2552
|
-
panelId,
|
|
2553
|
-
bundle: row.original,
|
|
2554
|
-
bundles: childBundles,
|
|
2555
|
-
loading: isChildBundlesLoading,
|
|
2556
|
-
onDetailClick
|
|
2806
|
+
})
|
|
2557
2807
|
})
|
|
2558
|
-
})
|
|
2559
|
-
}) :
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
})
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
"
|
|
2808
|
+
}) : null] }, row.original.id);
|
|
2809
|
+
}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TableRow, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TableCell, {
|
|
2810
|
+
colSpan: bundleColumns.length + 1,
|
|
2811
|
+
className: "h-32 text-center text-muted-foreground",
|
|
2812
|
+
children: "No bundles found matching your filters."
|
|
2813
|
+
}) }) })] })
|
|
2814
|
+
}),
|
|
2815
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
2816
|
+
className: "flex flex-col gap-3 px-2 sm:flex-row sm:items-center sm:justify-between",
|
|
2817
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
2818
|
+
className: "text-xs font-medium text-muted-foreground",
|
|
2819
|
+
children: [
|
|
2820
|
+
"Showing ",
|
|
2821
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
2822
|
+
className: "text-foreground",
|
|
2823
|
+
children: startEntry
|
|
2824
|
+
}),
|
|
2825
|
+
" to",
|
|
2826
|
+
" ",
|
|
2827
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
2828
|
+
className: "text-foreground",
|
|
2829
|
+
children: endEntry
|
|
2830
|
+
}),
|
|
2831
|
+
" entries"
|
|
2832
|
+
]
|
|
2833
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
2834
|
+
className: "flex flex-wrap items-center gap-3 sm:justify-end",
|
|
2835
|
+
children: [
|
|
2836
|
+
selectedBundles.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Button, {
|
|
2837
|
+
type: "button",
|
|
2838
|
+
variant: "destructive",
|
|
2839
|
+
size: "sm",
|
|
2840
|
+
className: "h-8 flex-1 px-3 text-xs sm:flex-none",
|
|
2841
|
+
onClick: () => setDeleteDialogOpen(true),
|
|
2842
|
+
children: [
|
|
2843
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Trash2, { "data-icon": "inline-start" }),
|
|
2844
|
+
"Delete selected (",
|
|
2845
|
+
selectedBundles.length,
|
|
2846
|
+
")"
|
|
2847
|
+
]
|
|
2848
|
+
}) : null,
|
|
2849
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
2850
|
+
className: "text-xs font-medium text-muted-foreground",
|
|
2851
|
+
children: [
|
|
2852
|
+
"Page ",
|
|
2597
2853
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
2598
2854
|
className: "text-foreground",
|
|
2599
|
-
children:
|
|
2600
|
-
})
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2855
|
+
children: currentPage
|
|
2856
|
+
}),
|
|
2857
|
+
totalPages > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
2858
|
+
" ",
|
|
2859
|
+
"of ",
|
|
2860
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
2861
|
+
className: "text-foreground",
|
|
2862
|
+
children: totalPages
|
|
2863
|
+
})
|
|
2864
|
+
] }) : null
|
|
2865
|
+
]
|
|
2866
|
+
}),
|
|
2867
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Button, {
|
|
2868
|
+
variant: "outline",
|
|
2869
|
+
size: "sm",
|
|
2870
|
+
onClick: handlePreviousPage,
|
|
2871
|
+
disabled: !hasPreviousPage,
|
|
2872
|
+
className: "h-8 flex-1 px-3 text-xs sm:flex-none",
|
|
2873
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronLeft, { "data-icon": "inline-start" }), "Previous"]
|
|
2874
|
+
}),
|
|
2875
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Button, {
|
|
2876
|
+
variant: "outline",
|
|
2877
|
+
size: "sm",
|
|
2878
|
+
onClick: handleNextPage,
|
|
2879
|
+
disabled: !hasNextPage,
|
|
2880
|
+
className: "h-8 flex-1 px-3 text-xs sm:flex-none",
|
|
2881
|
+
children: ["Next", /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronRight, { "data-icon": "inline-end" })]
|
|
2882
|
+
})
|
|
2883
|
+
]
|
|
2884
|
+
})]
|
|
2885
|
+
}),
|
|
2886
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectedBundlesDeleteDialog, {
|
|
2887
|
+
bundles: selectedBundles,
|
|
2888
|
+
open: deleteDialogOpen,
|
|
2889
|
+
onOpenChange: setDeleteDialogOpen,
|
|
2890
|
+
onComplete: ({ failedBundleIds }) => {
|
|
2891
|
+
setSelectedBundleIds([...failedBundleIds]);
|
|
2892
|
+
}
|
|
2893
|
+
})
|
|
2894
|
+
]
|
|
2623
2895
|
});
|
|
2624
2896
|
}
|
|
2625
2897
|
function FilterToolbar() {
|
|
@@ -2704,7 +2976,7 @@ function BundlesPage() {
|
|
|
2704
2976
|
if (expandedBundleId && !bundles.some((bundle) => bundle.id === expandedBundleId)) setExpandedBundleId(void 0);
|
|
2705
2977
|
}, [bundles, expandedBundleId]);
|
|
2706
2978
|
if (isLoading) return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
2707
|
-
className: "flex flex-col
|
|
2979
|
+
className: "flex h-svh flex-col",
|
|
2708
2980
|
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(FilterToolbar, {}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
2709
2981
|
className: "flex flex-1 flex-col gap-4 bg-muted/5 p-3 sm:p-6",
|
|
2710
2982
|
children: [
|
|
@@ -2716,11 +2988,11 @@ function BundlesPage() {
|
|
|
2716
2988
|
})]
|
|
2717
2989
|
});
|
|
2718
2990
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
2719
|
-
className: "flex
|
|
2991
|
+
className: "flex h-svh min-h-0 flex-col",
|
|
2720
2992
|
children: [
|
|
2721
2993
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(FilterToolbar, {}),
|
|
2722
2994
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
2723
|
-
className: "flex flex-1 flex-col gap-6 bg-muted/5 p-3 sm:p-6",
|
|
2995
|
+
className: "flex min-h-0 min-w-0 flex-1 flex-col gap-6 bg-muted/5 p-3 sm:p-6",
|
|
2724
2996
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(BundlesTable, {
|
|
2725
2997
|
bundles,
|
|
2726
2998
|
pagination,
|