@proveanything/smartlinks-utils-ui 0.3.7 → 0.3.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-NIAIQRFC.js +28 -0
- package/dist/chunk-NIAIQRFC.js.map +1 -0
- package/dist/components/AssetPicker/index.js +1 -1
- package/dist/components/ConditionsEditor/index.js +1 -1
- package/dist/components/FontPicker/index.js +1 -1
- package/dist/components/IconPicker/index.js +1 -1
- package/dist/components/RecordsAdmin/index.d.ts +34 -4
- package/dist/components/RecordsAdmin/index.js +443 -34
- package/dist/components/RecordsAdmin/index.js.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-WFNEZQCD.js +0 -28
- package/dist/chunk-WFNEZQCD.js.map +0 -1
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { styleInject } from '../../chunk-
|
|
1
|
+
import { styleInject } from '../../chunk-NIAIQRFC.js';
|
|
2
2
|
import { cn } from '../../chunk-L7FQ52F5.js';
|
|
3
3
|
import { createContext, useMemo, useState, useEffect, useCallback, useRef, useContext, createElement } from 'react';
|
|
4
|
-
import { ChevronDown, Database, Lightbulb, SearchX, Inbox, LayoutGrid, Eye, MoreHorizontal, Download, Upload, Trash2, Copy, Pencil, Plus, CircleDashed, ArrowDownLeft, CheckCircle2, Globe, Tag, Boxes, Layers, Package, Rows3, Image, List, ChevronRight, Eraser, Box, AlertTriangle, Info,
|
|
4
|
+
import { ChevronDown, Database, Lightbulb, SearchX, Inbox, LayoutGrid, Eye, MoreHorizontal, Download, Upload, Trash2, Copy, Pencil, Plus, CircleDashed, ArrowDownLeft, CheckCircle2, Globe, Tag, Boxes, Layers, Package, Rows3, Image, List, ChevronRight, Eraser, Box, X, AlertTriangle, Info, HelpCircle, Search, CornerDownLeft, Circle, AlertCircle, Undo2, Save } from 'lucide-react';
|
|
5
5
|
import { useQueryClient, useInfiniteQuery, useQuery } from '@tanstack/react-query';
|
|
6
|
+
import { createPortal } from 'react-dom';
|
|
6
7
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
7
8
|
|
|
8
9
|
var DEFAULT_ICONS = {
|
|
@@ -83,6 +84,7 @@ var DEFAULT_I18N = {
|
|
|
83
84
|
unsavedPromptDiscard: "Discard changes",
|
|
84
85
|
unsavedPromptCancel: "Stay here",
|
|
85
86
|
unsavedPromptSave: "Save & continue",
|
|
87
|
+
unsavedBannerBody: "Unsaved changes on {name}",
|
|
86
88
|
presentationList: "List",
|
|
87
89
|
presentationGrid: "Grid",
|
|
88
90
|
presentationGallery: "Gallery",
|
|
@@ -455,12 +457,24 @@ var resolveRecord = async (args) => {
|
|
|
455
457
|
const editingScope = parsedRefToScope(args.target);
|
|
456
458
|
const result = await matchRecords(args.ctx, target, { strategy: "all" }).catch(() => null);
|
|
457
459
|
const records = result?.records ?? [];
|
|
460
|
+
console.info("[RecordsAdmin/resolveRecord]", {
|
|
461
|
+
editingScope,
|
|
462
|
+
target,
|
|
463
|
+
matchCount: records.length,
|
|
464
|
+
winnerScope: records[0]?.record?.scope,
|
|
465
|
+
winnerRef: records[0]?.record?.ref
|
|
466
|
+
});
|
|
458
467
|
if (records.length === 0) {
|
|
459
468
|
return { data: null, source: "empty" };
|
|
460
469
|
}
|
|
461
470
|
const winnerEntry = records[0];
|
|
462
471
|
const winner = winnerEntry.record;
|
|
463
472
|
const winnerIsSelf = scopesEqual(winner.scope, editingScope);
|
|
473
|
+
console.info("[RecordsAdmin/resolveRecord] classification", {
|
|
474
|
+
winnerIsSelf,
|
|
475
|
+
winnerScope: winner.scope,
|
|
476
|
+
editingScope
|
|
477
|
+
});
|
|
464
478
|
if (winnerIsSelf) {
|
|
465
479
|
const parent = records[1]?.record;
|
|
466
480
|
return {
|
|
@@ -1101,6 +1115,144 @@ var useDirtyNavigation = ({
|
|
|
1101
1115
|
);
|
|
1102
1116
|
return { runWithGuard };
|
|
1103
1117
|
};
|
|
1118
|
+
var ConfirmDialog = ({
|
|
1119
|
+
open,
|
|
1120
|
+
title,
|
|
1121
|
+
body,
|
|
1122
|
+
saveLabel,
|
|
1123
|
+
discardLabel,
|
|
1124
|
+
cancelLabel,
|
|
1125
|
+
onChoice
|
|
1126
|
+
}) => {
|
|
1127
|
+
const saveBtnRef = useRef(null);
|
|
1128
|
+
useEffect(() => {
|
|
1129
|
+
if (!open) return;
|
|
1130
|
+
const prev = document.body.style.overflow;
|
|
1131
|
+
document.body.style.overflow = "hidden";
|
|
1132
|
+
const t = window.setTimeout(() => saveBtnRef.current?.focus(), 0);
|
|
1133
|
+
const onKey = (e) => {
|
|
1134
|
+
if (e.key === "Escape") {
|
|
1135
|
+
e.stopPropagation();
|
|
1136
|
+
onChoice("cancel");
|
|
1137
|
+
}
|
|
1138
|
+
};
|
|
1139
|
+
window.addEventListener("keydown", onKey, true);
|
|
1140
|
+
return () => {
|
|
1141
|
+
window.clearTimeout(t);
|
|
1142
|
+
window.removeEventListener("keydown", onKey, true);
|
|
1143
|
+
document.body.style.overflow = prev;
|
|
1144
|
+
};
|
|
1145
|
+
}, [open, onChoice]);
|
|
1146
|
+
if (!open || typeof document === "undefined") return null;
|
|
1147
|
+
return createPortal(
|
|
1148
|
+
/* @__PURE__ */ jsxs(
|
|
1149
|
+
"div",
|
|
1150
|
+
{
|
|
1151
|
+
className: "ra-shell ra-confirm-root",
|
|
1152
|
+
role: "presentation",
|
|
1153
|
+
onMouseDown: (e) => e.stopPropagation(),
|
|
1154
|
+
onClick: (e) => e.stopPropagation(),
|
|
1155
|
+
children: [
|
|
1156
|
+
/* @__PURE__ */ jsx("div", { className: "ra-confirm-backdrop", onClick: () => onChoice("cancel") }),
|
|
1157
|
+
/* @__PURE__ */ jsxs(
|
|
1158
|
+
"div",
|
|
1159
|
+
{
|
|
1160
|
+
role: "alertdialog",
|
|
1161
|
+
"aria-modal": "true",
|
|
1162
|
+
"aria-labelledby": "ra-confirm-title",
|
|
1163
|
+
"aria-describedby": "ra-confirm-body",
|
|
1164
|
+
className: "ra-confirm-card",
|
|
1165
|
+
children: [
|
|
1166
|
+
/* @__PURE__ */ jsxs("div", { className: "ra-confirm-header", children: [
|
|
1167
|
+
/* @__PURE__ */ jsx("span", { className: "ra-confirm-icon", "aria-hidden": "true", children: /* @__PURE__ */ jsx(AlertTriangle, { className: "w-4 h-4" }) }),
|
|
1168
|
+
/* @__PURE__ */ jsx("h2", { id: "ra-confirm-title", className: "ra-confirm-title", children: title })
|
|
1169
|
+
] }),
|
|
1170
|
+
/* @__PURE__ */ jsx("p", { id: "ra-confirm-body", className: "ra-confirm-body", children: body }),
|
|
1171
|
+
/* @__PURE__ */ jsxs("div", { className: "ra-confirm-actions", children: [
|
|
1172
|
+
/* @__PURE__ */ jsx(
|
|
1173
|
+
"button",
|
|
1174
|
+
{
|
|
1175
|
+
type: "button",
|
|
1176
|
+
className: "ra-confirm-btn ra-confirm-btn-ghost",
|
|
1177
|
+
onClick: () => onChoice("cancel"),
|
|
1178
|
+
children: cancelLabel
|
|
1179
|
+
}
|
|
1180
|
+
),
|
|
1181
|
+
/* @__PURE__ */ jsx(
|
|
1182
|
+
"button",
|
|
1183
|
+
{
|
|
1184
|
+
type: "button",
|
|
1185
|
+
className: "ra-confirm-btn ra-confirm-btn-danger",
|
|
1186
|
+
onClick: () => onChoice("discard"),
|
|
1187
|
+
children: discardLabel
|
|
1188
|
+
}
|
|
1189
|
+
),
|
|
1190
|
+
/* @__PURE__ */ jsx(
|
|
1191
|
+
"button",
|
|
1192
|
+
{
|
|
1193
|
+
type: "button",
|
|
1194
|
+
ref: saveBtnRef,
|
|
1195
|
+
className: "ra-confirm-btn ra-confirm-btn-primary",
|
|
1196
|
+
onClick: () => onChoice("save"),
|
|
1197
|
+
children: saveLabel
|
|
1198
|
+
}
|
|
1199
|
+
)
|
|
1200
|
+
] })
|
|
1201
|
+
]
|
|
1202
|
+
}
|
|
1203
|
+
)
|
|
1204
|
+
]
|
|
1205
|
+
}
|
|
1206
|
+
),
|
|
1207
|
+
document.body
|
|
1208
|
+
);
|
|
1209
|
+
};
|
|
1210
|
+
var DEFAULTS = {
|
|
1211
|
+
title: "Unsaved changes",
|
|
1212
|
+
body: "You have unsaved changes. Save them, discard them, or stay on this record?",
|
|
1213
|
+
saveLabel: "Save & continue",
|
|
1214
|
+
discardLabel: "Discard",
|
|
1215
|
+
cancelLabel: "Stay here"
|
|
1216
|
+
};
|
|
1217
|
+
var useConfirmDialog = () => {
|
|
1218
|
+
const [open, setOpen] = useState(false);
|
|
1219
|
+
const [state, setState] = useState(DEFAULTS);
|
|
1220
|
+
const resolverRef = useRef(null);
|
|
1221
|
+
const confirm = useCallback((i18n) => {
|
|
1222
|
+
setState({
|
|
1223
|
+
title: i18n?.title ?? DEFAULTS.title,
|
|
1224
|
+
body: i18n?.body ?? DEFAULTS.body,
|
|
1225
|
+
saveLabel: i18n?.save ?? DEFAULTS.saveLabel,
|
|
1226
|
+
discardLabel: i18n?.discard ?? DEFAULTS.discardLabel,
|
|
1227
|
+
cancelLabel: i18n?.cancel ?? DEFAULTS.cancelLabel
|
|
1228
|
+
});
|
|
1229
|
+
setOpen(true);
|
|
1230
|
+
return new Promise((resolve) => {
|
|
1231
|
+
resolverRef.current = resolve;
|
|
1232
|
+
});
|
|
1233
|
+
}, []);
|
|
1234
|
+
const handleChoice = useCallback((choice) => {
|
|
1235
|
+
setOpen(false);
|
|
1236
|
+
const r = resolverRef.current;
|
|
1237
|
+
resolverRef.current = null;
|
|
1238
|
+
r?.(choice);
|
|
1239
|
+
}, []);
|
|
1240
|
+
return {
|
|
1241
|
+
confirm,
|
|
1242
|
+
dialog: /* @__PURE__ */ jsx(
|
|
1243
|
+
ConfirmDialog,
|
|
1244
|
+
{
|
|
1245
|
+
open,
|
|
1246
|
+
title: state.title,
|
|
1247
|
+
body: state.body,
|
|
1248
|
+
saveLabel: state.saveLabel,
|
|
1249
|
+
discardLabel: state.discardLabel,
|
|
1250
|
+
cancelLabel: state.cancelLabel,
|
|
1251
|
+
onChoice: handleChoice
|
|
1252
|
+
}
|
|
1253
|
+
)
|
|
1254
|
+
};
|
|
1255
|
+
};
|
|
1104
1256
|
var LABELS = {
|
|
1105
1257
|
product: "Products",
|
|
1106
1258
|
facet: "Shared",
|
|
@@ -1139,14 +1291,17 @@ var ScopeTabs = ({
|
|
|
1139
1291
|
);
|
|
1140
1292
|
}) });
|
|
1141
1293
|
};
|
|
1142
|
-
var StatusFilterPills = ({ value, onChange, counts, i18n }) => {
|
|
1294
|
+
var StatusFilterPills = ({ value, onChange, counts, i18n, hideZero }) => {
|
|
1143
1295
|
const opts = [
|
|
1144
1296
|
{ key: "all", label: i18n.filterAll, count: counts.all },
|
|
1145
1297
|
{ key: "configured", label: i18n.filterConfigured, count: counts.configured },
|
|
1146
1298
|
{ key: "partial", label: i18n.filterPartial, count: counts.partial },
|
|
1147
1299
|
{ key: "empty", label: i18n.filterEmpty, count: counts.empty }
|
|
1148
1300
|
];
|
|
1149
|
-
|
|
1301
|
+
const visible = opts.filter(
|
|
1302
|
+
(o) => o.key === value || !hideZero?.includes(o.key) || o.count > 0
|
|
1303
|
+
);
|
|
1304
|
+
return /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1.5", children: visible.map((o) => {
|
|
1150
1305
|
const active = value === o.key;
|
|
1151
1306
|
return /* @__PURE__ */ jsxs(
|
|
1152
1307
|
"button",
|
|
@@ -1641,25 +1796,49 @@ function RecordEditor({
|
|
|
1641
1796
|
preview,
|
|
1642
1797
|
bulkActions,
|
|
1643
1798
|
footerExtra,
|
|
1644
|
-
onBeforeDelete
|
|
1799
|
+
onBeforeDelete,
|
|
1800
|
+
headerLabel,
|
|
1801
|
+
headerSubtitle,
|
|
1802
|
+
headerMeta
|
|
1645
1803
|
}) {
|
|
1646
|
-
const sourceLabel = ctx.source === "self" ? "
|
|
1804
|
+
const sourceLabel = ctx.source === "self" ? "Customised" : ctx.source === "inherited" ? "Inherited" : null;
|
|
1647
1805
|
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col h-full", children: [
|
|
1648
1806
|
/* @__PURE__ */ jsxs(
|
|
1649
1807
|
"header",
|
|
1650
1808
|
{
|
|
1651
|
-
className: "sticky top-0 z-
|
|
1809
|
+
className: "sticky top-0 z-40 px-5 py-3 border-b flex items-start justify-between gap-3",
|
|
1652
1810
|
style: { borderColor: "hsl(var(--ra-border))", background: "hsl(var(--ra-surface))" },
|
|
1653
1811
|
children: [
|
|
1654
1812
|
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
1655
|
-
/* @__PURE__ */
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1813
|
+
headerLabel ? /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
|
|
1814
|
+
/* @__PURE__ */ jsx(
|
|
1815
|
+
"div",
|
|
1816
|
+
{
|
|
1817
|
+
className: "text-sm font-medium truncate",
|
|
1818
|
+
style: { color: "hsl(var(--ra-text))" },
|
|
1819
|
+
title: headerLabel,
|
|
1820
|
+
children: headerLabel
|
|
1821
|
+
}
|
|
1822
|
+
),
|
|
1823
|
+
headerSubtitle && /* @__PURE__ */ jsx(
|
|
1824
|
+
"div",
|
|
1825
|
+
{
|
|
1826
|
+
className: "text-xs truncate",
|
|
1827
|
+
style: { color: "hsl(var(--ra-muted-text))" },
|
|
1828
|
+
title: headerSubtitle,
|
|
1829
|
+
children: headerSubtitle
|
|
1830
|
+
}
|
|
1831
|
+
)
|
|
1832
|
+
] }) : /* @__PURE__ */ jsx(ScopeBreadcrumb, { scope: ctx.scope }),
|
|
1833
|
+
(sourceLabel || ctx.isDirty) && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 mt-1", children: [
|
|
1834
|
+
sourceLabel && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1835
|
+
/* @__PURE__ */ jsx(StatusDot, { source: ctx.source }),
|
|
1836
|
+
/* @__PURE__ */ jsx("span", { className: "text-[10px] uppercase tracking-wide", style: { color: "hsl(var(--ra-muted-text))" }, children: sourceLabel })
|
|
1837
|
+
] }),
|
|
1659
1838
|
ctx.isDirty && /* @__PURE__ */ jsxs(
|
|
1660
1839
|
"span",
|
|
1661
1840
|
{
|
|
1662
|
-
className:
|
|
1841
|
+
className: `flex items-center gap-1 text-[10px] uppercase tracking-wide ${sourceLabel ? "ml-2" : ""}`,
|
|
1663
1842
|
style: { color: "hsl(var(--ra-accent))" },
|
|
1664
1843
|
children: [
|
|
1665
1844
|
/* @__PURE__ */ jsx("span", { className: "ra-status-dot ra-status-shared", "aria-hidden": "true" }),
|
|
@@ -1669,7 +1848,22 @@ function RecordEditor({
|
|
|
1669
1848
|
)
|
|
1670
1849
|
] })
|
|
1671
1850
|
] }),
|
|
1672
|
-
|
|
1851
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-start gap-2 shrink-0", children: [
|
|
1852
|
+
headerMeta && /* @__PURE__ */ jsx(
|
|
1853
|
+
"code",
|
|
1854
|
+
{
|
|
1855
|
+
className: "text-[10px] font-mono px-1.5 py-0.5 rounded truncate max-w-[14rem] mt-0.5",
|
|
1856
|
+
style: {
|
|
1857
|
+
color: "hsl(var(--ra-muted-text) / 0.85)",
|
|
1858
|
+
background: "hsl(var(--ra-muted) / 0.5)",
|
|
1859
|
+
border: "1px solid hsl(var(--ra-border) / 0.6)"
|
|
1860
|
+
},
|
|
1861
|
+
title: headerMeta,
|
|
1862
|
+
children: headerMeta
|
|
1863
|
+
}
|
|
1864
|
+
),
|
|
1865
|
+
bulkActions && /* @__PURE__ */ jsx(BulkActionsMenu, { ...bulkActions, i18n })
|
|
1866
|
+
] })
|
|
1673
1867
|
]
|
|
1674
1868
|
}
|
|
1675
1869
|
),
|
|
@@ -1884,13 +2078,29 @@ var InlinePreview = ({ children, scopePicker, label = "Preview" }) => /* @__PURE
|
|
|
1884
2078
|
] }),
|
|
1885
2079
|
children
|
|
1886
2080
|
] });
|
|
1887
|
-
var SidePreview = ({
|
|
2081
|
+
var SidePreview = ({
|
|
2082
|
+
children,
|
|
2083
|
+
scopePicker,
|
|
2084
|
+
label = "Preview",
|
|
2085
|
+
onClose
|
|
2086
|
+
}) => /* @__PURE__ */ jsxs("div", { className: "ra-preview-rail", children: [
|
|
1888
2087
|
/* @__PURE__ */ jsxs("header", { className: "ra-preview-rail-header", children: [
|
|
1889
2088
|
/* @__PURE__ */ jsxs("div", { className: "ra-preview-rail-title", children: [
|
|
1890
2089
|
/* @__PURE__ */ jsx(Eye, { className: "w-3 h-3" }),
|
|
1891
2090
|
label
|
|
1892
2091
|
] }),
|
|
1893
|
-
scopePicker && /* @__PURE__ */ jsx("div", { className: "ml-auto", children: scopePicker })
|
|
2092
|
+
scopePicker && /* @__PURE__ */ jsx("div", { className: "ml-auto", children: scopePicker }),
|
|
2093
|
+
onClose && /* @__PURE__ */ jsx(
|
|
2094
|
+
"button",
|
|
2095
|
+
{
|
|
2096
|
+
type: "button",
|
|
2097
|
+
onClick: onClose,
|
|
2098
|
+
"aria-label": "Close preview",
|
|
2099
|
+
className: scopePicker ? "p-1 rounded hover:bg-[hsl(var(--ra-muted))]" : "ml-auto p-1 rounded hover:bg-[hsl(var(--ra-muted))]",
|
|
2100
|
+
style: { color: "hsl(var(--ra-muted-text))" },
|
|
2101
|
+
children: /* @__PURE__ */ jsx(X, { className: "w-3.5 h-3.5" })
|
|
2102
|
+
}
|
|
2103
|
+
)
|
|
1894
2104
|
] }),
|
|
1895
2105
|
/* @__PURE__ */ jsx("div", { className: "ra-preview-rail-body", children })
|
|
1896
2106
|
] });
|
|
@@ -2004,7 +2214,13 @@ var PreviewScopePicker = ({
|
|
|
2004
2214
|
showBatches,
|
|
2005
2215
|
i18n
|
|
2006
2216
|
}) => {
|
|
2007
|
-
const
|
|
2217
|
+
const productPinned = !!editingScope.productId;
|
|
2218
|
+
const products = useProductBrowse({
|
|
2219
|
+
SL,
|
|
2220
|
+
collectionId,
|
|
2221
|
+
pageSize: 100,
|
|
2222
|
+
enabled: !productPinned
|
|
2223
|
+
});
|
|
2008
2224
|
const variants = useProductChildren({
|
|
2009
2225
|
SL,
|
|
2010
2226
|
collectionId,
|
|
@@ -2021,6 +2237,27 @@ var PreviewScopePicker = ({
|
|
|
2021
2237
|
() => value.raw === editingScope.raw,
|
|
2022
2238
|
[value.raw, editingScope.raw]
|
|
2023
2239
|
);
|
|
2240
|
+
useEffect(() => {
|
|
2241
|
+
if (productPinned) return;
|
|
2242
|
+
if (value.productId) return;
|
|
2243
|
+
const first = products.items[0];
|
|
2244
|
+
if (!first) return;
|
|
2245
|
+
onChange({
|
|
2246
|
+
...value,
|
|
2247
|
+
productId: first.id,
|
|
2248
|
+
variantId: void 0,
|
|
2249
|
+
batchId: void 0,
|
|
2250
|
+
raw: `product:${first.id}`
|
|
2251
|
+
});
|
|
2252
|
+
}, [productPinned, value.productId, products.items]);
|
|
2253
|
+
const [productPickerOpen, setProductPickerOpen] = useState(false);
|
|
2254
|
+
const showProductPicker = !productPinned && products.items.length > 1;
|
|
2255
|
+
const showVariantPicker = showVariants && !!value.productId && variants.items.length > 0;
|
|
2256
|
+
const showBatchPicker = showBatches && !!value.productId && batches.items.length > 0;
|
|
2257
|
+
if (!showProductPicker && !showVariantPicker && !showBatchPicker) {
|
|
2258
|
+
return null;
|
|
2259
|
+
}
|
|
2260
|
+
const currentProductName = products.items.find((p) => p.id === value.productId)?.name ?? value.productId ?? "";
|
|
2024
2261
|
const selectStyle = {
|
|
2025
2262
|
borderColor: "hsl(var(--ra-border))",
|
|
2026
2263
|
color: "hsl(var(--ra-text))"
|
|
@@ -2050,30 +2287,44 @@ var PreviewScopePicker = ({
|
|
|
2050
2287
|
]
|
|
2051
2288
|
}
|
|
2052
2289
|
),
|
|
2053
|
-
/* @__PURE__ */ jsxs(
|
|
2290
|
+
showProductPicker && !productPickerOpen && currentProductName && /* @__PURE__ */ jsxs(
|
|
2291
|
+
"button",
|
|
2292
|
+
{
|
|
2293
|
+
type: "button",
|
|
2294
|
+
onClick: () => setProductPickerOpen(true),
|
|
2295
|
+
className: "text-[10px] px-2 py-1 rounded-md border hover:bg-[hsl(var(--ra-muted))] inline-flex items-center gap-1 max-w-[12rem] truncate",
|
|
2296
|
+
style: selectStyle,
|
|
2297
|
+
title: `Preview as ${currentProductName} \u2014 click to change`,
|
|
2298
|
+
children: [
|
|
2299
|
+
"as ",
|
|
2300
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium truncate", children: currentProductName }),
|
|
2301
|
+
/* @__PURE__ */ jsx(ChevronDown, { className: "w-3 h-3 opacity-60" })
|
|
2302
|
+
]
|
|
2303
|
+
}
|
|
2304
|
+
),
|
|
2305
|
+
showProductPicker && productPickerOpen && /* @__PURE__ */ jsx(
|
|
2054
2306
|
"select",
|
|
2055
2307
|
{
|
|
2056
2308
|
className: SELECT_CLS,
|
|
2057
2309
|
style: selectStyle,
|
|
2310
|
+
autoFocus: true,
|
|
2311
|
+
onBlur: () => setProductPickerOpen(false),
|
|
2058
2312
|
value: value.productId ?? "",
|
|
2059
2313
|
onChange: (e) => {
|
|
2060
2314
|
const productId = e.target.value || void 0;
|
|
2061
2315
|
onChange({
|
|
2062
2316
|
...value,
|
|
2063
2317
|
productId,
|
|
2064
|
-
// Clear variant/batch when switching products.
|
|
2065
2318
|
variantId: void 0,
|
|
2066
2319
|
batchId: void 0,
|
|
2067
2320
|
raw: productId ? `product:${productId}` : ""
|
|
2068
2321
|
});
|
|
2322
|
+
setProductPickerOpen(false);
|
|
2069
2323
|
},
|
|
2070
|
-
children:
|
|
2071
|
-
/* @__PURE__ */ jsx("option", { value: "", children: "\u2014 Any product \u2014" }),
|
|
2072
|
-
products.items.map((p) => /* @__PURE__ */ jsx("option", { value: p.id, children: p.name }, p.id))
|
|
2073
|
-
]
|
|
2324
|
+
children: products.items.map((p) => /* @__PURE__ */ jsx("option", { value: p.id, children: p.name }, p.id))
|
|
2074
2325
|
}
|
|
2075
2326
|
),
|
|
2076
|
-
|
|
2327
|
+
showVariantPicker && /* @__PURE__ */ jsxs(
|
|
2077
2328
|
"select",
|
|
2078
2329
|
{
|
|
2079
2330
|
className: SELECT_CLS,
|
|
@@ -2094,7 +2345,7 @@ var PreviewScopePicker = ({
|
|
|
2094
2345
|
]
|
|
2095
2346
|
}
|
|
2096
2347
|
),
|
|
2097
|
-
|
|
2348
|
+
showBatchPicker && /* @__PURE__ */ jsxs(
|
|
2098
2349
|
"select",
|
|
2099
2350
|
{
|
|
2100
2351
|
className: SELECT_CLS,
|
|
@@ -2241,6 +2492,61 @@ function ShellHeader({
|
|
|
2241
2492
|
] })
|
|
2242
2493
|
] });
|
|
2243
2494
|
}
|
|
2495
|
+
var UnsavedBanner = ({
|
|
2496
|
+
label,
|
|
2497
|
+
context,
|
|
2498
|
+
isSaving,
|
|
2499
|
+
saveError,
|
|
2500
|
+
onSave,
|
|
2501
|
+
onDiscard,
|
|
2502
|
+
saveLabel,
|
|
2503
|
+
discardLabel,
|
|
2504
|
+
bodyTemplate,
|
|
2505
|
+
savingLabel,
|
|
2506
|
+
errorLabel
|
|
2507
|
+
}) => {
|
|
2508
|
+
const name = label ?? context ?? "this record";
|
|
2509
|
+
const message = bodyTemplate.replace("{name}", name);
|
|
2510
|
+
return /* @__PURE__ */ jsxs("div", { className: "ra-unsaved-banner", role: "status", "aria-live": "polite", children: [
|
|
2511
|
+
/* @__PURE__ */ jsx("span", { className: "ra-unsaved-icon", "aria-hidden": "true", children: /* @__PURE__ */ jsx(AlertCircle, { className: "w-3.5 h-3.5" }) }),
|
|
2512
|
+
/* @__PURE__ */ jsxs("span", { className: "ra-unsaved-text", children: [
|
|
2513
|
+
message,
|
|
2514
|
+
context && label && /* @__PURE__ */ jsxs("span", { className: "ra-unsaved-context", children: [
|
|
2515
|
+
" \xB7 ",
|
|
2516
|
+
context
|
|
2517
|
+
] })
|
|
2518
|
+
] }),
|
|
2519
|
+
saveError != null && !isSaving && /* @__PURE__ */ jsx("span", { className: "ra-unsaved-error", role: "alert", children: errorLabel ?? "Save failed" }),
|
|
2520
|
+
/* @__PURE__ */ jsxs("div", { className: "ra-unsaved-actions", children: [
|
|
2521
|
+
/* @__PURE__ */ jsxs(
|
|
2522
|
+
"button",
|
|
2523
|
+
{
|
|
2524
|
+
type: "button",
|
|
2525
|
+
className: "ra-unsaved-btn ra-unsaved-btn-ghost",
|
|
2526
|
+
onClick: onDiscard,
|
|
2527
|
+
disabled: isSaving,
|
|
2528
|
+
children: [
|
|
2529
|
+
/* @__PURE__ */ jsx(Undo2, { className: "w-3 h-3" }),
|
|
2530
|
+
discardLabel
|
|
2531
|
+
]
|
|
2532
|
+
}
|
|
2533
|
+
),
|
|
2534
|
+
/* @__PURE__ */ jsxs(
|
|
2535
|
+
"button",
|
|
2536
|
+
{
|
|
2537
|
+
type: "button",
|
|
2538
|
+
className: "ra-unsaved-btn ra-unsaved-btn-primary",
|
|
2539
|
+
onClick: onSave,
|
|
2540
|
+
disabled: isSaving,
|
|
2541
|
+
children: [
|
|
2542
|
+
/* @__PURE__ */ jsx(Save, { className: "w-3 h-3" }),
|
|
2543
|
+
isSaving ? savingLabel ?? "Saving\u2026" : saveLabel
|
|
2544
|
+
]
|
|
2545
|
+
}
|
|
2546
|
+
)
|
|
2547
|
+
] })
|
|
2548
|
+
] });
|
|
2549
|
+
};
|
|
2244
2550
|
|
|
2245
2551
|
// src/components/RecordsAdmin/data/csv.ts
|
|
2246
2552
|
var escapeCell = (s) => {
|
|
@@ -2350,8 +2656,8 @@ var downloadBlob = (blob, filename) => {
|
|
|
2350
2656
|
styleInject(':root {\n --ra-status-own: var(--ra-emerald, 142 71% 45%);\n --ra-status-shared: var(--ra-amber, 38 92% 50%);\n --ra-status-missing: var(--muted-foreground, 220 9% 46%);\n --ra-accent: var(--primary, 222 47% 11%);\n --ra-surface: var(--card, 0 0% 100%);\n --ra-border: var(--border, 220 13% 91%);\n --ra-text: var(--foreground, 222 47% 11%);\n --ra-muted: var(--muted, 220 14% 96%);\n --ra-muted-text: var(--muted-foreground, 220 9% 46%);\n --ra-radius: var(--radius, 0.625rem);\n --ra-dot-size: 0.5rem;\n --ra-page-bg: var(--background, 220 14% 98%);\n --ra-card-shadow: 0 1px 2px hsl(var(--ra-accent) / 0.04), 0 4px 12px hsl(var(--ra-accent) / 0.05);\n --ra-card-shadow-hover: 0 2px 4px hsl(var(--ra-accent) / 0.06), 0 8px 24px hsl(var(--ra-accent) / 0.08);\n --ra-row-hover: hsl(var(--ra-accent) / 0.05);\n --ra-row-active-bg: hsl(var(--ra-accent) / 0.10);\n --ra-row-active-bd: hsl(var(--ra-accent) / 0.45);\n --ra-focus-ring: hsl(var(--ra-accent) / 0.35);\n --ra-font-display: var(--font-display, var(--font-sans, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif));\n --ra-font-ui: var(--font-sans, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif);\n --ra-title-weight: 600;\n --ra-display-weight: 700;\n --ra-info: var(--ra-blue, 214 95% 55%);\n --ra-success: var(--ra-emerald, 142 71% 45%);\n --ra-warning: var(--ra-amber, 38 92% 50%);\n --ra-danger: var(--destructive, 0 72% 51%);\n}\n.ra-status-dot {\n display: inline-block;\n width: var(--ra-dot-size);\n height: var(--ra-dot-size);\n border-radius: 9999px;\n flex-shrink: 0;\n}\n.ra-status-own {\n background: hsl(var(--ra-status-own));\n}\n.ra-status-shared {\n background: hsl(var(--ra-status-shared));\n}\n.ra-status-missing {\n background: hsl(var(--ra-status-missing) / 0.4);\n border: 1px solid hsl(var(--ra-status-missing) / 0.6);\n}\n.ra-row-active {\n background: var(--ra-row-active-bg);\n border-color: var(--ra-row-active-bd) !important;\n}\n');
|
|
2351
2657
|
|
|
2352
2658
|
// src/components/RecordsAdmin/shell/shell.css
|
|
2353
|
-
styleInject(".ra-shell {\n color: hsl(var(--ra-text));\n background: hsl(var(--ra-page-bg));\n font-family: var(--ra-font-ui);\n}\n.ra-shell *,\n.ra-shell *::before,\n.ra-shell *::after {\n box-sizing: border-box;\n}\n.ra-shell .ra-card {\n background: hsl(var(--ra-surface));\n border: 1px solid hsl(var(--ra-border));\n border-radius: var(--ra-radius);\n box-shadow: var(--ra-card-shadow);\n}\n.ra-shell .ra-card-hover {\n transition:\n box-shadow .18s ease,\n transform .18s ease,\n border-color .18s ease;\n}\n.ra-shell .ra-card-hover:hover {\n box-shadow: var(--ra-card-shadow-hover);\n}\n.ra-shell .ra-display {\n font-family: var(--ra-font-display);\n font-weight: var(--ra-display-weight);\n letter-spacing: -0.01em;\n}\n.ra-shell .ra-title {\n font-weight: var(--ra-title-weight);\n}\n.ra-shell :where(button, [role=button], input, select, textarea, a):focus-visible {\n outline: none;\n box-shadow: 0 0 0 3px var(--ra-focus-ring);\n border-radius: calc(var(--ra-radius) * 0.6);\n}\n.ra-shell .ra-header {\n position: relative;\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.65rem 0.9rem;\n border-radius: var(--ra-radius);\n border: 1px solid hsl(var(--ra-accent) / 0.12);\n background:\n linear-gradient(\n 135deg,\n hsl(var(--ra-accent) / 0.08),\n hsl(var(--ra-accent) / 0.02) 60%,\n hsl(var(--ra-surface)) 100%);\n box-shadow: var(--ra-card-shadow);\n}\n.ra-shell .ra-header__main {\n flex: 1;\n min-width: 0;\n display: flex;\n align-items: center;\n gap: 0.625rem;\n}\n.ra-shell .ra-header-aside {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n flex-shrink: 0;\n}\n.ra-shell .ra-header-icon {\n flex-shrink: 0;\n width: 2rem;\n height: 2rem;\n border-radius: calc(var(--ra-radius) * 0.9);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n background: hsl(var(--ra-accent) / 0.12);\n color: hsl(var(--ra-accent));\n border: 1px solid hsl(var(--ra-accent) / 0.18);\n}\n.ra-shell .ra-header-text {\n flex: 1;\n min-width: 0;\n}\n.ra-shell .ra-header-title {\n font-family: var(--ra-font-display);\n font-weight: var(--ra-display-weight);\n font-size: 1rem;\n line-height: 1.2;\n color: hsl(var(--ra-text));\n letter-spacing: -0.01em;\n margin: 0;\n}\n.ra-shell .ra-header-subtitle {\n font-size: 0.75rem;\n color: hsl(var(--ra-muted-text));\n margin-top: 0.125rem;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.ra-shell .ra-header-stats {\n display: flex;\n align-items: stretch;\n gap: 0.15rem;\n padding: 0.15rem 0.4rem;\n border-radius: calc(var(--ra-radius) * 0.75);\n background: hsl(var(--ra-surface) / 0.7);\n border: 1px solid hsl(var(--ra-border));\n}\n.ra-shell .ra-header-stats--titled {\n flex-direction: column;\n align-items: stretch;\n padding: 0.4rem 0.55rem;\n gap: 0.3rem;\n}\n.ra-shell .ra-header-stats .ra-stats-items {\n display: flex;\n align-items: stretch;\n gap: 0.15rem;\n}\n.ra-shell .ra-header-stats .ra-stats-heading {\n display: flex;\n align-items: center;\n gap: 0.35rem;\n color: hsl(var(--ra-muted-text));\n font-size: 0.65rem;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n}\n.ra-shell .ra-header-stats .ra-stats-heading-icon {\n display: inline-flex;\n align-items: center;\n color: hsl(var(--ra-text));\n opacity: 0.75;\n}\n.ra-shell .ra-header-stats .ra-stats-heading-icon > svg {\n width: 0.85rem;\n height: 0.85rem;\n}\n.ra-shell .ra-stat {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 0.15rem 0.45rem;\n min-width: 2.5rem;\n}\n.ra-shell .ra-stat-value {\n font-family: var(--ra-font-display);\n font-weight: var(--ra-display-weight);\n font-size: 0.85rem;\n color: hsl(var(--ra-text));\n line-height: 1;\n}\n.ra-shell .ra-stat-label {\n font-size: 0.6rem;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: hsl(var(--ra-muted-text));\n margin-top: 0.15rem;\n}\n.ra-shell .ra-stat-divider {\n width: 1px;\n background: hsl(var(--ra-border));\n margin: 0.25rem 0;\n}\n.ra-shell .ra-header-actions {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n}\n.ra-shell .ra-tabs {\n display: flex;\n gap: 0.25rem;\n padding: 0.25rem;\n background: hsl(var(--ra-muted));\n border-radius: calc(var(--ra-radius) * 0.85);\n border: 1px solid hsl(var(--ra-border));\n}\n.ra-shell .ra-tab {\n display: inline-flex;\n align-items: center;\n gap: 0.4rem;\n padding: 0.4rem 0.7rem;\n border-radius: calc(var(--ra-radius) * 0.65);\n font-size: 0.78rem;\n font-weight: 500;\n color: hsl(var(--ra-muted-text));\n background: transparent;\n border: 0;\n cursor: pointer;\n transition:\n background .15s ease,\n color .15s ease,\n transform .15s ease;\n white-space: nowrap;\n}\n.ra-shell .ra-tab:hover {\n background: hsl(var(--ra-surface));\n color: hsl(var(--ra-text));\n}\n.ra-shell .ra-tab[aria-selected=true] {\n background: hsl(var(--ra-surface));\n color: hsl(var(--ra-text));\n box-shadow: var(--ra-card-shadow);\n font-weight: var(--ra-title-weight);\n}\n.ra-shell .ra-tab[aria-selected=true] .ra-tab-icon {\n color: hsl(var(--ra-accent));\n}\n.ra-shell .ra-tab[disabled] {\n opacity: .5;\n cursor: not-allowed;\n}\n.ra-shell .ra-tab-count {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 1.25rem;\n padding: 0 0.35rem;\n height: 1.1rem;\n border-radius: 999px;\n background: hsl(var(--ra-accent) / 0.12);\n color: hsl(var(--ra-accent));\n font-size: 0.625rem;\n font-weight: 600;\n line-height: 1;\n}\n.ra-shell .ra-tab[aria-selected=false] .ra-tab-count {\n background: hsl(var(--ra-muted-text) / 0.15);\n color: hsl(var(--ra-muted-text));\n}\n.ra-shell[data-density=compact] .ra-row {\n padding-block: 0.4rem;\n}\n.ra-shell[data-density=compact] .ra-header {\n padding: 0.75rem 1rem;\n}\n.ra-shell[data-density=compact] .ra-header-icon {\n width: 2.25rem;\n height: 2.25rem;\n}\n.ra-shell .ra-row {\n display: flex;\n align-items: center;\n gap: 0.65rem;\n width: 100%;\n text-align: left;\n padding: 0.65rem 0.85rem;\n border-left: 3px solid transparent;\n background: transparent;\n border-bottom: 1px solid transparent;\n transition: background .12s ease, border-color .12s ease;\n cursor: pointer;\n color: hsl(var(--ra-text));\n font-family: inherit;\n}\n.ra-shell .ra-row + .ra-row {\n border-top: 1px solid hsl(var(--ra-border) / 0.6);\n}\n.ra-shell .ra-row:hover {\n background: var(--ra-row-hover);\n}\n.ra-shell .ra-row[data-selected=true] {\n background: var(--ra-row-active-bg);\n border-left-color: var(--ra-row-active-bd);\n}\n.ra-shell .ra-row-icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 1.75rem;\n height: 1.75rem;\n border-radius: calc(var(--ra-radius) * 0.6);\n background: hsl(var(--ra-muted));\n color: hsl(var(--ra-muted-text));\n flex-shrink: 0;\n}\n.ra-shell .ra-row[data-selected=true] .ra-row-icon {\n background: hsl(var(--ra-accent) / 0.15);\n color: hsl(var(--ra-accent));\n}\n.ra-shell .ra-row-body {\n flex: 1;\n min-width: 0;\n}\n.ra-shell .ra-row-title {\n font-weight: var(--ra-title-weight);\n font-size: 0.875rem;\n line-height: 1.25;\n color: hsl(var(--ra-text));\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.ra-shell .ra-row-sub {\n font-size: 0.75rem;\n color: hsl(var(--ra-muted-text));\n margin-top: 0.15rem;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.ra-shell .ra-row-actions {\n display: inline-flex;\n align-items: center;\n gap: 0.15rem;\n margin-left: auto;\n opacity: 0;\n transition: opacity .15s ease;\n}\n.ra-shell .ra-row:hover .ra-row-actions,\n.ra-shell .ra-row:focus-within .ra-row-actions {\n opacity: 1;\n}\n.ra-shell .ra-row-action {\n width: 1.6rem;\n height: 1.6rem;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border-radius: 999px;\n background: transparent;\n color: hsl(var(--ra-muted-text));\n border: 0;\n cursor: pointer;\n transition: background .15s ease, color .15s ease;\n}\n.ra-shell .ra-row-action:hover {\n background: hsl(var(--ra-accent) / 0.10);\n color: hsl(var(--ra-text));\n}\n.ra-shell .ra-row-action[data-tone=danger]:hover {\n background: hsl(var(--ra-danger) / 0.12);\n color: hsl(var(--ra-danger));\n}\n.ra-shell .ra-chip {\n display: inline-flex;\n align-items: center;\n gap: 0.3rem;\n padding: 0.15rem 0.5rem;\n border-radius: 999px;\n font-size: 0.6875rem;\n font-weight: 500;\n background: hsl(var(--ra-muted));\n color: hsl(var(--ra-muted-text));\n border: 1px solid hsl(var(--ra-border));\n white-space: nowrap;\n max-width: 14rem;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.ra-shell .ra-chip[data-tone=success] {\n background: hsl(var(--ra-success) / 0.12);\n color: hsl(var(--ra-success));\n border-color: hsl(var(--ra-success) / 0.30);\n}\n.ra-shell .ra-chip[data-tone=warning] {\n background: hsl(var(--ra-warning) / 0.14);\n color: hsl(var(--ra-warning));\n border-color: hsl(var(--ra-warning) / 0.35);\n}\n.ra-shell .ra-chip[data-tone=info] {\n background: hsl(var(--ra-info) / 0.10);\n color: hsl(var(--ra-info));\n border-color: hsl(var(--ra-info) / 0.30);\n}\n.ra-shell .ra-chip[data-tone=danger] {\n background: hsl(var(--ra-danger) / 0.10);\n color: hsl(var(--ra-danger));\n border-color: hsl(var(--ra-danger) / 0.30);\n}\n.ra-shell .ra-chip[data-tone=muted] {\n background: transparent;\n color: hsl(var(--ra-muted-text));\n border-style: dashed;\n}\n.ra-shell .ra-group {\n border-bottom: 1px solid hsl(var(--ra-border));\n}\n.ra-shell .ra-group:last-child {\n border-bottom: 0;\n}\n.ra-shell .ra-group-summary {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n width: 100%;\n padding: 0.5rem 0.85rem;\n background: hsl(var(--ra-muted) / 0.6);\n font-size: 0.7rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: hsl(var(--ra-muted-text));\n border: 0;\n cursor: pointer;\n transition: background .12s ease;\n}\n.ra-shell .ra-group-summary:hover {\n background: hsl(var(--ra-muted));\n}\n.ra-shell .ra-group-summary .ra-group-chevron {\n transition: transform .15s ease;\n}\n.ra-shell .ra-group[data-open=false] .ra-group-chevron {\n transform: rotate(-90deg);\n}\n.ra-shell .ra-group-name {\n flex: 1;\n text-align: left;\n}\n.ra-shell .ra-group-count {\n font-size: 0.65rem;\n font-weight: 600;\n color: hsl(var(--ra-muted-text));\n background: hsl(var(--ra-surface));\n border: 1px solid hsl(var(--ra-border));\n border-radius: 999px;\n padding: 0.05rem 0.4rem;\n}\n.ra-shell .ra-group[data-open=false] .ra-group-body {\n display: none;\n}\n.ra-shell .ra-empty {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n text-align: center;\n padding: 2.5rem 1.5rem;\n gap: 0.75rem;\n}\n.ra-shell .ra-empty-icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 3.25rem;\n height: 3.25rem;\n border-radius: 999px;\n background: hsl(var(--ra-accent) / 0.08);\n color: hsl(var(--ra-accent));\n margin-bottom: 0.25rem;\n}\n.ra-shell .ra-empty-title {\n font-family: var(--ra-font-display);\n font-weight: var(--ra-display-weight);\n font-size: 1rem;\n color: hsl(var(--ra-text));\n margin: 0;\n letter-spacing: -0.01em;\n}\n.ra-shell .ra-empty-body {\n font-size: 0.8125rem;\n color: hsl(var(--ra-muted-text));\n max-width: 22rem;\n line-height: 1.45;\n}\n.ra-shell .ra-empty-actions {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n margin-top: 0.25rem;\n flex-wrap: wrap;\n justify-content: center;\n}\n.ra-shell .ra-btn {\n display: inline-flex;\n align-items: center;\n gap: 0.4rem;\n padding: 0.45rem 0.85rem;\n border-radius: calc(var(--ra-radius) * 0.7);\n font-size: 0.8125rem;\n font-weight: 500;\n border: 1px solid hsl(var(--ra-border));\n background: hsl(var(--ra-surface));\n color: hsl(var(--ra-text));\n cursor: pointer;\n transition:\n background .15s ease,\n border-color .15s ease,\n box-shadow .15s ease,\n transform .1s ease;\n}\n.ra-shell .ra-btn:hover {\n background: hsl(var(--ra-muted));\n box-shadow: var(--ra-card-shadow);\n}\n.ra-shell .ra-btn:active {\n transform: translateY(1px);\n}\n.ra-shell .ra-btn[data-variant=primary] {\n background: hsl(var(--ra-accent));\n color: hsl(var(--ra-surface));\n border-color: hsl(var(--ra-accent));\n}\n.ra-shell .ra-btn[data-variant=primary]:hover {\n background: hsl(var(--ra-accent) / 0.92);\n}\n.ra-shell .ra-btn[data-variant=ghost] {\n background: transparent;\n border-color: transparent;\n color: hsl(var(--ra-muted-text));\n}\n.ra-shell .ra-btn[data-variant=ghost]:hover {\n background: hsl(var(--ra-muted));\n color: hsl(var(--ra-text));\n}\n.ra-shell .ra-btn[data-variant=danger] {\n color: hsl(var(--ra-danger));\n}\n.ra-shell .ra-btn[data-variant=danger]:hover {\n background: hsl(var(--ra-danger) / 0.10);\n border-color: hsl(var(--ra-danger) / 0.40);\n}\n.ra-shell .ra-intro {\n position: relative;\n display: flex;\n gap: 0.85rem;\n padding: 0.9rem 1rem;\n border-radius: var(--ra-radius);\n border: 1px solid hsl(var(--ra-info) / 0.30);\n background: hsl(var(--ra-info) / 0.08);\n margin-bottom: 1rem;\n}\n.ra-shell .ra-intro[data-tone=success] {\n border-color: hsl(var(--ra-success) / 0.30);\n background: hsl(var(--ra-success) / 0.08);\n}\n.ra-shell .ra-intro[data-tone=warning] {\n border-color: hsl(var(--ra-warning) / 0.35);\n background: hsl(var(--ra-warning) / 0.10);\n}\n.ra-shell .ra-intro-icon {\n flex-shrink: 0;\n width: 2rem;\n height: 2rem;\n border-radius: 999px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n background: hsl(var(--ra-info) / 0.18);\n color: hsl(var(--ra-info));\n}\n.ra-shell .ra-intro[data-tone=success] .ra-intro-icon {\n background: hsl(var(--ra-success) / 0.18);\n color: hsl(var(--ra-success));\n}\n.ra-shell .ra-intro[data-tone=warning] .ra-intro-icon {\n background: hsl(var(--ra-warning) / 0.20);\n color: hsl(var(--ra-warning));\n}\n.ra-shell .ra-intro-body {\n flex: 1;\n min-width: 0;\n}\n.ra-shell .ra-intro-title {\n font-family: var(--ra-font-display);\n font-weight: var(--ra-title-weight);\n font-size: 0.875rem;\n color: hsl(var(--ra-text));\n margin: 0 0 0.2rem 0;\n}\n.ra-shell .ra-intro-text {\n font-size: 0.8125rem;\n color: hsl(var(--ra-text) / 0.85);\n line-height: 1.45;\n}\n.ra-shell .ra-intro-dismiss {\n position: absolute;\n top: 0.5rem;\n right: 0.5rem;\n width: 1.6rem;\n height: 1.6rem;\n border-radius: 999px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n border: 0;\n color: hsl(var(--ra-muted-text));\n cursor: pointer;\n}\n.ra-shell .ra-intro-dismiss:hover {\n background: hsl(var(--ra-text) / 0.06);\n color: hsl(var(--ra-text));\n}\n.ra-shell .ra-bulk-menu {\n min-width: 12rem;\n background: hsl(var(--ra-surface));\n border: 1px solid hsl(var(--ra-border));\n border-radius: calc(var(--ra-radius) * 0.85);\n box-shadow: var(--ra-card-shadow-hover);\n padding: 0.3rem;\n z-index: 30;\n}\n.ra-shell .ra-bulk-item {\n display: flex;\n align-items: center;\n gap: 0.55rem;\n width: 100%;\n padding: 0.45rem 0.6rem;\n border-radius: calc(var(--ra-radius) * 0.6);\n font-size: 0.8125rem;\n color: hsl(var(--ra-text));\n background: transparent;\n border: 0;\n cursor: pointer;\n text-align: left;\n transition: background .12s ease, color .12s ease;\n}\n.ra-shell .ra-bulk-item:hover {\n background: hsl(var(--ra-muted));\n}\n.ra-shell .ra-bulk-item[data-tone=danger] {\n color: hsl(var(--ra-danger));\n}\n.ra-shell .ra-bulk-item[data-tone=danger]:hover {\n background: hsl(var(--ra-danger) / 0.10);\n}\n.ra-shell .ra-bulk-divider {\n height: 1px;\n background: hsl(var(--ra-border));\n margin: 0.25rem 0;\n}\n.ra-shell .ra-preview-rail {\n background: hsl(var(--ra-surface));\n border-left: 1px solid hsl(var(--ra-border));\n box-shadow: -4px 0 16px hsl(var(--ra-accent) / 0.04);\n display: flex;\n flex-direction: column;\n height: 100%;\n overflow: hidden;\n}\n.ra-shell .ra-preview-rail-header {\n position: sticky;\n top: 0;\n z-index: 1;\n display: flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.75rem 1rem;\n background:\n linear-gradient(\n 180deg,\n hsl(var(--ra-surface)) 0%,\n hsl(var(--ra-surface) / 0.92) 100%);\n border-bottom: 1px solid hsl(var(--ra-border));\n backdrop-filter: blur(6px);\n}\n.ra-shell .ra-preview-rail-title {\n display: inline-flex;\n align-items: center;\n gap: 0.4rem;\n font-size: 0.7rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n color: hsl(var(--ra-muted-text));\n}\n.ra-shell .ra-preview-rail-body {\n flex: 1;\n overflow-y: auto;\n padding: 1rem;\n}\n");
|
|
2354
|
-
var TOP_LEVEL_SCOPES = ["
|
|
2659
|
+
styleInject(".ra-shell {\n color: hsl(var(--ra-text));\n background: hsl(var(--ra-page-bg));\n font-family: var(--ra-font-ui);\n}\n.ra-shell *,\n.ra-shell *::before,\n.ra-shell *::after {\n box-sizing: border-box;\n}\n.ra-shell .ra-card {\n background: hsl(var(--ra-surface));\n border: 1px solid hsl(var(--ra-border));\n border-radius: var(--ra-radius);\n box-shadow: var(--ra-card-shadow);\n}\n.ra-shell .ra-card-hover {\n transition:\n box-shadow .18s ease,\n transform .18s ease,\n border-color .18s ease;\n}\n.ra-shell .ra-card-hover:hover {\n box-shadow: var(--ra-card-shadow-hover);\n}\n.ra-shell .ra-display {\n font-family: var(--ra-font-display);\n font-weight: var(--ra-display-weight);\n letter-spacing: -0.01em;\n}\n.ra-shell .ra-title {\n font-weight: var(--ra-title-weight);\n}\n.ra-shell :where(button, [role=button], input, select, textarea, a):focus-visible {\n outline: none;\n box-shadow: 0 0 0 3px var(--ra-focus-ring);\n border-radius: calc(var(--ra-radius) * 0.6);\n}\n.ra-shell .ra-header {\n position: relative;\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.65rem 0.9rem;\n border-radius: var(--ra-radius);\n border: 1px solid hsl(var(--ra-accent) / 0.12);\n background:\n linear-gradient(\n 135deg,\n hsl(var(--ra-accent) / 0.08),\n hsl(var(--ra-accent) / 0.02) 60%,\n hsl(var(--ra-surface)) 100%);\n box-shadow: var(--ra-card-shadow);\n}\n.ra-shell .ra-header__main {\n flex: 1;\n min-width: 0;\n display: flex;\n align-items: center;\n gap: 0.625rem;\n}\n.ra-shell .ra-header-aside {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n flex-shrink: 0;\n}\n.ra-shell .ra-header-icon {\n flex-shrink: 0;\n width: 2rem;\n height: 2rem;\n border-radius: calc(var(--ra-radius) * 0.9);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n background: hsl(var(--ra-accent) / 0.12);\n color: hsl(var(--ra-accent));\n border: 1px solid hsl(var(--ra-accent) / 0.18);\n}\n.ra-shell .ra-header-text {\n flex: 1;\n min-width: 0;\n}\n.ra-shell .ra-header-title {\n font-family: var(--ra-font-display);\n font-weight: var(--ra-display-weight);\n font-size: 1rem;\n line-height: 1.2;\n color: hsl(var(--ra-text));\n letter-spacing: -0.01em;\n margin: 0;\n}\n.ra-shell .ra-header-subtitle {\n font-size: 0.75rem;\n color: hsl(var(--ra-muted-text));\n margin-top: 0.125rem;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.ra-shell .ra-header-stats {\n display: flex;\n align-items: stretch;\n gap: 0.15rem;\n padding: 0.15rem 0.4rem;\n border-radius: calc(var(--ra-radius) * 0.75);\n background: hsl(var(--ra-surface) / 0.7);\n border: 1px solid hsl(var(--ra-border));\n}\n.ra-shell .ra-header-stats--titled {\n flex-direction: column;\n align-items: stretch;\n padding: 0.4rem 0.55rem;\n gap: 0.3rem;\n}\n.ra-shell .ra-header-stats .ra-stats-items {\n display: flex;\n align-items: stretch;\n gap: 0.15rem;\n}\n.ra-shell .ra-header-stats .ra-stats-heading {\n display: flex;\n align-items: center;\n gap: 0.35rem;\n color: hsl(var(--ra-muted-text));\n font-size: 0.65rem;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n}\n.ra-shell .ra-header-stats .ra-stats-heading-icon {\n display: inline-flex;\n align-items: center;\n color: hsl(var(--ra-text));\n opacity: 0.75;\n}\n.ra-shell .ra-header-stats .ra-stats-heading-icon > svg {\n width: 0.85rem;\n height: 0.85rem;\n}\n.ra-shell .ra-stat {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 0.15rem 0.45rem;\n min-width: 2.5rem;\n}\n.ra-shell .ra-stat-value {\n font-family: var(--ra-font-display);\n font-weight: var(--ra-display-weight);\n font-size: 0.85rem;\n color: hsl(var(--ra-text));\n line-height: 1;\n}\n.ra-shell .ra-stat-label {\n font-size: 0.6rem;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: hsl(var(--ra-muted-text));\n margin-top: 0.15rem;\n}\n.ra-shell .ra-stat-divider {\n width: 1px;\n background: hsl(var(--ra-border));\n margin: 0.25rem 0;\n}\n.ra-shell .ra-header-actions {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n}\n.ra-shell .ra-tabs {\n display: flex;\n gap: 0.25rem;\n padding: 0.25rem;\n background: hsl(var(--ra-muted));\n border-radius: calc(var(--ra-radius) * 0.85);\n border: 1px solid hsl(var(--ra-border));\n}\n.ra-shell .ra-tab {\n display: inline-flex;\n align-items: center;\n gap: 0.4rem;\n padding: 0.4rem 0.7rem;\n border-radius: calc(var(--ra-radius) * 0.65);\n font-size: 0.78rem;\n font-weight: 500;\n color: hsl(var(--ra-muted-text));\n background: transparent;\n border: 0;\n cursor: pointer;\n transition:\n background .15s ease,\n color .15s ease,\n transform .15s ease;\n white-space: nowrap;\n}\n.ra-shell .ra-tab:hover {\n background: hsl(var(--ra-surface));\n color: hsl(var(--ra-text));\n}\n.ra-shell .ra-tab[aria-selected=true] {\n background: hsl(var(--ra-surface));\n color: hsl(var(--ra-text));\n box-shadow: var(--ra-card-shadow);\n font-weight: var(--ra-title-weight);\n}\n.ra-shell .ra-tab[aria-selected=true] .ra-tab-icon {\n color: hsl(var(--ra-accent));\n}\n.ra-shell .ra-tab[disabled] {\n opacity: .5;\n cursor: not-allowed;\n}\n.ra-shell .ra-tab-count {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 1.25rem;\n padding: 0 0.35rem;\n height: 1.1rem;\n border-radius: 999px;\n background: hsl(var(--ra-accent) / 0.12);\n color: hsl(var(--ra-accent));\n font-size: 0.625rem;\n font-weight: 600;\n line-height: 1;\n}\n.ra-shell .ra-tab[aria-selected=false] .ra-tab-count {\n background: hsl(var(--ra-muted-text) / 0.15);\n color: hsl(var(--ra-muted-text));\n}\n.ra-shell[data-density=compact] .ra-row {\n padding-block: 0.4rem;\n}\n.ra-shell[data-density=compact] .ra-header {\n padding: 0.75rem 1rem;\n}\n.ra-shell[data-density=compact] .ra-header-icon {\n width: 2.25rem;\n height: 2.25rem;\n}\n.ra-shell .ra-row {\n display: flex;\n align-items: center;\n gap: 0.65rem;\n width: 100%;\n text-align: left;\n padding: 0.65rem 0.85rem;\n border-left: 3px solid transparent;\n background: transparent;\n border-bottom: 1px solid transparent;\n transition: background .12s ease, border-color .12s ease;\n cursor: pointer;\n color: hsl(var(--ra-text));\n font-family: inherit;\n}\n.ra-shell .ra-row + .ra-row {\n border-top: 1px solid hsl(var(--ra-border) / 0.6);\n}\n.ra-shell .ra-row:hover {\n background: var(--ra-row-hover);\n}\n.ra-shell .ra-row[data-selected=true] {\n background: var(--ra-row-active-bg);\n border-left-color: var(--ra-row-active-bd);\n}\n.ra-shell .ra-row-icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 1.75rem;\n height: 1.75rem;\n border-radius: calc(var(--ra-radius) * 0.6);\n background: hsl(var(--ra-muted));\n color: hsl(var(--ra-muted-text));\n flex-shrink: 0;\n}\n.ra-shell .ra-row[data-selected=true] .ra-row-icon {\n background: hsl(var(--ra-accent) / 0.15);\n color: hsl(var(--ra-accent));\n}\n.ra-shell .ra-row-body {\n flex: 1;\n min-width: 0;\n}\n.ra-shell .ra-row-title {\n font-weight: var(--ra-title-weight);\n font-size: 0.875rem;\n line-height: 1.25;\n color: hsl(var(--ra-text));\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.ra-shell .ra-row-sub {\n font-size: 0.75rem;\n color: hsl(var(--ra-muted-text));\n margin-top: 0.15rem;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.ra-shell .ra-row-actions {\n display: inline-flex;\n align-items: center;\n gap: 0.15rem;\n margin-left: auto;\n opacity: 0;\n transition: opacity .15s ease;\n}\n.ra-shell .ra-row:hover .ra-row-actions,\n.ra-shell .ra-row:focus-within .ra-row-actions {\n opacity: 1;\n}\n.ra-shell .ra-row-action {\n width: 1.6rem;\n height: 1.6rem;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border-radius: 999px;\n background: transparent;\n color: hsl(var(--ra-muted-text));\n border: 0;\n cursor: pointer;\n transition: background .15s ease, color .15s ease;\n}\n.ra-shell .ra-row-action:hover {\n background: hsl(var(--ra-accent) / 0.10);\n color: hsl(var(--ra-text));\n}\n.ra-shell .ra-row-action[data-tone=danger]:hover {\n background: hsl(var(--ra-danger) / 0.12);\n color: hsl(var(--ra-danger));\n}\n.ra-shell .ra-chip {\n display: inline-flex;\n align-items: center;\n gap: 0.3rem;\n padding: 0.15rem 0.5rem;\n border-radius: 999px;\n font-size: 0.6875rem;\n font-weight: 500;\n background: hsl(var(--ra-muted));\n color: hsl(var(--ra-muted-text));\n border: 1px solid hsl(var(--ra-border));\n white-space: nowrap;\n max-width: 14rem;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.ra-shell .ra-chip[data-tone=success] {\n background: hsl(var(--ra-success) / 0.12);\n color: hsl(var(--ra-success));\n border-color: hsl(var(--ra-success) / 0.30);\n}\n.ra-shell .ra-chip[data-tone=warning] {\n background: hsl(var(--ra-warning) / 0.14);\n color: hsl(var(--ra-warning));\n border-color: hsl(var(--ra-warning) / 0.35);\n}\n.ra-shell .ra-chip[data-tone=info] {\n background: hsl(var(--ra-info) / 0.10);\n color: hsl(var(--ra-info));\n border-color: hsl(var(--ra-info) / 0.30);\n}\n.ra-shell .ra-chip[data-tone=danger] {\n background: hsl(var(--ra-danger) / 0.10);\n color: hsl(var(--ra-danger));\n border-color: hsl(var(--ra-danger) / 0.30);\n}\n.ra-shell .ra-chip[data-tone=muted] {\n background: transparent;\n color: hsl(var(--ra-muted-text));\n border-style: dashed;\n}\n.ra-shell .ra-group {\n border-bottom: 1px solid hsl(var(--ra-border));\n}\n.ra-shell .ra-group:last-child {\n border-bottom: 0;\n}\n.ra-shell .ra-group-summary {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n width: 100%;\n padding: 0.5rem 0.85rem;\n background: hsl(var(--ra-muted) / 0.6);\n font-size: 0.7rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: hsl(var(--ra-muted-text));\n border: 0;\n cursor: pointer;\n transition: background .12s ease;\n}\n.ra-shell .ra-group-summary:hover {\n background: hsl(var(--ra-muted));\n}\n.ra-shell .ra-group-summary .ra-group-chevron {\n transition: transform .15s ease;\n}\n.ra-shell .ra-group[data-open=false] .ra-group-chevron {\n transform: rotate(-90deg);\n}\n.ra-shell .ra-group-name {\n flex: 1;\n text-align: left;\n}\n.ra-shell .ra-group-count {\n font-size: 0.65rem;\n font-weight: 600;\n color: hsl(var(--ra-muted-text));\n background: hsl(var(--ra-surface));\n border: 1px solid hsl(var(--ra-border));\n border-radius: 999px;\n padding: 0.05rem 0.4rem;\n}\n.ra-shell .ra-group[data-open=false] .ra-group-body {\n display: none;\n}\n.ra-shell .ra-empty {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n text-align: center;\n padding: 2.5rem 1.5rem;\n gap: 0.75rem;\n}\n.ra-shell .ra-empty-icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 3.25rem;\n height: 3.25rem;\n border-radius: 999px;\n background: hsl(var(--ra-accent) / 0.08);\n color: hsl(var(--ra-accent));\n margin-bottom: 0.25rem;\n}\n.ra-shell .ra-empty-title {\n font-family: var(--ra-font-display);\n font-weight: var(--ra-display-weight);\n font-size: 1rem;\n color: hsl(var(--ra-text));\n margin: 0;\n letter-spacing: -0.01em;\n}\n.ra-shell .ra-empty-body {\n font-size: 0.8125rem;\n color: hsl(var(--ra-muted-text));\n max-width: 22rem;\n line-height: 1.45;\n}\n.ra-shell .ra-empty-actions {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n margin-top: 0.25rem;\n flex-wrap: wrap;\n justify-content: center;\n}\n.ra-shell .ra-btn {\n display: inline-flex;\n align-items: center;\n gap: 0.4rem;\n padding: 0.45rem 0.85rem;\n border-radius: calc(var(--ra-radius) * 0.7);\n font-size: 0.8125rem;\n font-weight: 500;\n border: 1px solid hsl(var(--ra-border));\n background: hsl(var(--ra-surface));\n color: hsl(var(--ra-text));\n cursor: pointer;\n transition:\n background .15s ease,\n border-color .15s ease,\n box-shadow .15s ease,\n transform .1s ease;\n}\n.ra-shell .ra-btn:hover {\n background: hsl(var(--ra-muted));\n box-shadow: var(--ra-card-shadow);\n}\n.ra-shell .ra-btn:active {\n transform: translateY(1px);\n}\n.ra-shell .ra-btn[data-variant=primary] {\n background: hsl(var(--ra-accent));\n color: hsl(var(--ra-surface));\n border-color: hsl(var(--ra-accent));\n}\n.ra-shell .ra-btn[data-variant=primary]:hover {\n background: hsl(var(--ra-accent) / 0.92);\n}\n.ra-shell .ra-btn[data-variant=ghost] {\n background: transparent;\n border-color: transparent;\n color: hsl(var(--ra-muted-text));\n}\n.ra-shell .ra-btn[data-variant=ghost]:hover {\n background: hsl(var(--ra-muted));\n color: hsl(var(--ra-text));\n}\n.ra-shell .ra-btn[data-variant=danger] {\n color: hsl(var(--ra-danger));\n}\n.ra-shell .ra-btn[data-variant=danger]:hover {\n background: hsl(var(--ra-danger) / 0.10);\n border-color: hsl(var(--ra-danger) / 0.40);\n}\n.ra-shell .ra-intro {\n position: relative;\n display: flex;\n gap: 0.85rem;\n padding: 0.9rem 1rem;\n border-radius: var(--ra-radius);\n border: 1px solid hsl(var(--ra-info) / 0.30);\n background: hsl(var(--ra-info) / 0.08);\n margin-bottom: 1rem;\n}\n.ra-shell .ra-intro[data-tone=success] {\n border-color: hsl(var(--ra-success) / 0.30);\n background: hsl(var(--ra-success) / 0.08);\n}\n.ra-shell .ra-intro[data-tone=warning] {\n border-color: hsl(var(--ra-warning) / 0.35);\n background: hsl(var(--ra-warning) / 0.10);\n}\n.ra-shell .ra-intro-icon {\n flex-shrink: 0;\n width: 2rem;\n height: 2rem;\n border-radius: 999px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n background: hsl(var(--ra-info) / 0.18);\n color: hsl(var(--ra-info));\n}\n.ra-shell .ra-intro[data-tone=success] .ra-intro-icon {\n background: hsl(var(--ra-success) / 0.18);\n color: hsl(var(--ra-success));\n}\n.ra-shell .ra-intro[data-tone=warning] .ra-intro-icon {\n background: hsl(var(--ra-warning) / 0.20);\n color: hsl(var(--ra-warning));\n}\n.ra-shell .ra-intro-body {\n flex: 1;\n min-width: 0;\n}\n.ra-shell .ra-intro-title {\n font-family: var(--ra-font-display);\n font-weight: var(--ra-title-weight);\n font-size: 0.875rem;\n color: hsl(var(--ra-text));\n margin: 0 0 0.2rem 0;\n}\n.ra-shell .ra-intro-text {\n font-size: 0.8125rem;\n color: hsl(var(--ra-text) / 0.85);\n line-height: 1.45;\n}\n.ra-shell .ra-intro-dismiss {\n position: absolute;\n top: 0.5rem;\n right: 0.5rem;\n width: 1.6rem;\n height: 1.6rem;\n border-radius: 999px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n border: 0;\n color: hsl(var(--ra-muted-text));\n cursor: pointer;\n}\n.ra-shell .ra-intro-dismiss:hover {\n background: hsl(var(--ra-text) / 0.06);\n color: hsl(var(--ra-text));\n}\n.ra-shell .ra-bulk-menu {\n min-width: 12rem;\n background: hsl(var(--ra-surface));\n border: 1px solid hsl(var(--ra-border));\n border-radius: calc(var(--ra-radius) * 0.85);\n box-shadow: var(--ra-card-shadow-hover);\n padding: 0.3rem;\n z-index: 60;\n}\n.ra-shell .ra-bulk-item {\n display: flex;\n align-items: center;\n gap: 0.55rem;\n width: 100%;\n padding: 0.45rem 0.6rem;\n border-radius: calc(var(--ra-radius) * 0.6);\n font-size: 0.8125rem;\n color: hsl(var(--ra-text));\n background: transparent;\n border: 0;\n cursor: pointer;\n text-align: left;\n transition: background .12s ease, color .12s ease;\n}\n.ra-shell .ra-bulk-item:hover {\n background: hsl(var(--ra-muted));\n}\n.ra-shell .ra-bulk-item[data-tone=danger] {\n color: hsl(var(--ra-danger));\n}\n.ra-shell .ra-bulk-item[data-tone=danger]:hover {\n background: hsl(var(--ra-danger) / 0.10);\n}\n.ra-shell .ra-bulk-divider {\n height: 1px;\n background: hsl(var(--ra-border));\n margin: 0.25rem 0;\n}\n.ra-shell .ra-preview-rail {\n background: hsl(var(--ra-surface));\n border-left: 1px solid hsl(var(--ra-border));\n box-shadow: -4px 0 16px hsl(var(--ra-accent) / 0.04);\n display: flex;\n flex-direction: column;\n height: 100%;\n overflow: hidden;\n}\n.ra-shell .ra-preview-rail-header {\n position: sticky;\n top: 0;\n z-index: 1;\n display: flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.75rem 1rem;\n background:\n linear-gradient(\n 180deg,\n hsl(var(--ra-surface)) 0%,\n hsl(var(--ra-surface) / 0.92) 100%);\n border-bottom: 1px solid hsl(var(--ra-border));\n backdrop-filter: blur(6px);\n}\n.ra-shell .ra-preview-rail-title {\n display: inline-flex;\n align-items: center;\n gap: 0.4rem;\n font-size: 0.7rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n color: hsl(var(--ra-muted-text));\n}\n.ra-shell .ra-preview-rail-body {\n flex: 1;\n overflow-y: auto;\n padding: 1rem;\n}\n.ra-confirm-root {\n position: fixed;\n inset: 0;\n z-index: 2147483000;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 1rem;\n}\n.ra-confirm-root .ra-confirm-backdrop {\n position: absolute;\n inset: 0;\n background: hsl(0 0% 0% / 0.45);\n backdrop-filter: blur(2px);\n animation: ra-confirm-fade .12s ease-out;\n}\n.ra-confirm-root .ra-confirm-card {\n position: relative;\n width: min(440px, 100%);\n background: hsl(var(--ra-surface));\n color: hsl(var(--ra-text));\n border: 1px solid hsl(var(--ra-border));\n border-radius: var(--ra-radius);\n box-shadow: 0 1px 2px hsl(0 0% 0% / 0.08), 0 24px 48px -12px hsl(0 0% 0% / 0.32);\n padding: 1.25rem;\n animation: ra-confirm-pop .14s ease-out;\n}\n.ra-confirm-root .ra-confirm-header {\n display: flex;\n align-items: center;\n gap: 0.6rem;\n margin-bottom: 0.5rem;\n}\n.ra-confirm-root .ra-confirm-icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 1.75rem;\n height: 1.75rem;\n border-radius: 999px;\n background: hsl(var(--ra-warning, 38 92% 50%) / 0.12);\n color: hsl(var(--ra-warning, 38 92% 50%));\n}\n.ra-confirm-root .ra-confirm-title {\n font-family: var(--ra-font-display);\n font-weight: 600;\n font-size: 1rem;\n margin: 0;\n}\n.ra-confirm-root .ra-confirm-body {\n font-size: 0.875rem;\n color: hsl(var(--ra-muted-text));\n margin: 0 0 1.1rem;\n line-height: 1.45;\n}\n.ra-confirm-root .ra-confirm-actions {\n display: flex;\n justify-content: flex-end;\n gap: 0.5rem;\n flex-wrap: wrap;\n}\n.ra-confirm-root .ra-confirm-btn {\n -webkit-appearance: none;\n -moz-appearance: none;\n appearance: none;\n border: 1px solid transparent;\n border-radius: calc(var(--ra-radius) - 2px);\n padding: 0.45rem 0.85rem;\n font-size: 0.8125rem;\n font-weight: 500;\n cursor: pointer;\n transition:\n background-color .12s ease,\n border-color .12s ease,\n color .12s ease;\n}\n.ra-confirm-root .ra-confirm-btn:focus-visible {\n outline: none;\n box-shadow: 0 0 0 3px var(--ra-focus-ring);\n}\n.ra-confirm-root .ra-confirm-btn-ghost {\n background: transparent;\n color: hsl(var(--ra-muted-text));\n border-color: hsl(var(--ra-border));\n}\n.ra-confirm-root .ra-confirm-btn-ghost:hover {\n background: hsl(var(--ra-muted));\n color: hsl(var(--ra-text));\n}\n.ra-confirm-root .ra-confirm-btn-danger {\n background: transparent;\n color: hsl(var(--ra-danger, 0 72% 51%));\n border-color: hsl(var(--ra-danger, 0 72% 51%) / 0.45);\n}\n.ra-confirm-root .ra-confirm-btn-danger:hover {\n background: hsl(var(--ra-danger, 0 72% 51%) / 0.08);\n border-color: hsl(var(--ra-danger, 0 72% 51%));\n}\n.ra-confirm-root .ra-confirm-btn-primary {\n background: hsl(var(--ra-accent));\n color: hsl(var(--ra-accent-fg, 0 0% 100%));\n border-color: hsl(var(--ra-accent));\n}\n.ra-confirm-root .ra-confirm-btn-primary:hover {\n filter: brightness(0.95);\n}\n@keyframes ra-confirm-fade {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n@keyframes ra-confirm-pop {\n from {\n opacity: 0;\n transform: translateY(4px) scale(.98);\n }\n to {\n opacity: 1;\n transform: translateY(0) scale(1);\n }\n}\n.ra-shell .ra-unsaved-banner {\n display: flex;\n align-items: center;\n gap: 0.6rem;\n padding: 0.5rem 0.75rem;\n border: 1px solid hsl(var(--ra-warning, 38 92% 50%) / 0.35);\n background: hsl(var(--ra-warning, 38 92% 50%) / 0.08);\n border-radius: var(--ra-radius);\n font-size: 0.8125rem;\n color: hsl(var(--ra-text));\n animation: ra-unsaved-slide .14s ease-out;\n}\n.ra-shell .ra-unsaved-icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n color: hsl(var(--ra-warning, 38 92% 50%));\n flex-shrink: 0;\n}\n.ra-shell .ra-unsaved-text {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.ra-shell .ra-unsaved-context {\n color: hsl(var(--ra-muted-text));\n font-weight: 400;\n}\n.ra-shell .ra-unsaved-error {\n color: hsl(var(--ra-danger, 0 72% 51%));\n font-size: 0.75rem;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n font-weight: 500;\n}\n.ra-shell .ra-unsaved-actions {\n display: inline-flex;\n gap: 0.4rem;\n flex-shrink: 0;\n}\n.ra-shell .ra-unsaved-btn {\n display: inline-flex;\n align-items: center;\n gap: 0.3rem;\n -webkit-appearance: none;\n -moz-appearance: none;\n appearance: none;\n border: 1px solid transparent;\n border-radius: calc(var(--ra-radius) - 2px);\n padding: 0.3rem 0.6rem;\n font-size: 0.75rem;\n font-weight: 500;\n cursor: pointer;\n transition:\n background-color .12s ease,\n border-color .12s ease,\n color .12s ease,\n opacity .12s ease;\n}\n.ra-shell .ra-unsaved-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.ra-shell .ra-unsaved-btn:focus-visible {\n outline: none;\n box-shadow: 0 0 0 3px var(--ra-focus-ring);\n}\n.ra-shell .ra-unsaved-btn-ghost {\n background: transparent;\n color: hsl(var(--ra-muted-text));\n border-color: hsl(var(--ra-border));\n}\n.ra-shell .ra-unsaved-btn-ghost:hover:not(:disabled) {\n background: hsl(var(--ra-muted));\n color: hsl(var(--ra-text));\n}\n.ra-shell .ra-unsaved-btn-primary {\n background: hsl(var(--ra-accent));\n color: hsl(var(--ra-accent-fg, 0 0% 100%));\n border-color: hsl(var(--ra-accent));\n}\n.ra-shell .ra-unsaved-btn-primary:hover:not(:disabled) {\n filter: brightness(0.95);\n}\n@keyframes ra-unsaved-slide {\n from {\n opacity: 0;\n transform: translateY(-3px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n");
|
|
2660
|
+
var TOP_LEVEL_SCOPES = ["facet", "product"];
|
|
2355
2661
|
var defaultItemId = () => {
|
|
2356
2662
|
const time = Date.now().toString(36);
|
|
2357
2663
|
const rand = Math.random().toString(36).slice(2, 8);
|
|
@@ -2390,7 +2696,11 @@ function RecordsAdminShell(props) {
|
|
|
2390
2696
|
className,
|
|
2391
2697
|
previewMode = "inline",
|
|
2392
2698
|
previewScopePicker = false,
|
|
2393
|
-
|
|
2699
|
+
// Default to `keep` — admins can tab around freely while edits are
|
|
2700
|
+
// preserved per editor mount, and the inline UnsavedBanner surfaces the
|
|
2701
|
+
// dirty state at the top of the shell with Save/Discard buttons. Hosts
|
|
2702
|
+
// that want the old blocking behaviour can opt back into `'prompt'`.
|
|
2703
|
+
dirtyStrategy = "keep",
|
|
2394
2704
|
onBeforeDelete,
|
|
2395
2705
|
disableBeforeUnload = false,
|
|
2396
2706
|
presentations = ["list"],
|
|
@@ -2434,7 +2744,7 @@ function RecordsAdminShell(props) {
|
|
|
2434
2744
|
);
|
|
2435
2745
|
const probe = useScopeProbe({ SL, collectionId });
|
|
2436
2746
|
const topLevelScopes = useMemo(
|
|
2437
|
-
() =>
|
|
2747
|
+
() => TOP_LEVEL_SCOPES.filter((s) => requestedScopes.includes(s)),
|
|
2438
2748
|
[requestedScopes]
|
|
2439
2749
|
);
|
|
2440
2750
|
const drillVariantsAllowed = useMemo(
|
|
@@ -2448,6 +2758,7 @@ function RecordsAdminShell(props) {
|
|
|
2448
2758
|
const initialScope = useMemo(() => {
|
|
2449
2759
|
if (contextScope?.productId && topLevelScopes.includes("product")) return "product";
|
|
2450
2760
|
if (defaultScope && topLevelScopes.includes(defaultScope)) return defaultScope;
|
|
2761
|
+
if (topLevelScopes.includes("facet")) return "facet";
|
|
2451
2762
|
return topLevelScopes[0] ?? "product";
|
|
2452
2763
|
}, [contextScope?.productId, defaultScope, topLevelScopes]);
|
|
2453
2764
|
const [activeScope, setActiveScope] = useState(initialScope);
|
|
@@ -2597,13 +2908,19 @@ function RecordsAdminShell(props) {
|
|
|
2597
2908
|
useUnsavedGuard({
|
|
2598
2909
|
isDirty: editorCtx.isDirty,
|
|
2599
2910
|
label: recordType,
|
|
2600
|
-
disableBeforeUnload
|
|
2911
|
+
disableBeforeUnload,
|
|
2912
|
+
// In `keep` mode we don't want the host iframe to pop its own native
|
|
2913
|
+
// confirm — the banner is the canonical surface. Hosts on `prompt` /
|
|
2914
|
+
// `autosave` opt back into platform notifications.
|
|
2915
|
+
disableParentMessage: dirtyStrategy === "keep"
|
|
2601
2916
|
});
|
|
2917
|
+
const dirtyConfirm = useConfirmDialog();
|
|
2602
2918
|
const { runWithGuard } = useDirtyNavigation({
|
|
2603
2919
|
strategy: dirtyStrategy,
|
|
2604
2920
|
isDirty: editorCtx.isDirty,
|
|
2605
2921
|
save: editorCtx.save,
|
|
2606
2922
|
reset: editorCtx.reset,
|
|
2923
|
+
confirm: dirtyConfirm.confirm,
|
|
2607
2924
|
i18n: {
|
|
2608
2925
|
title: i18n.unsavedPromptTitle,
|
|
2609
2926
|
body: i18n.unsavedPromptBody,
|
|
@@ -2640,11 +2957,40 @@ function RecordsAdminShell(props) {
|
|
|
2640
2957
|
const csvBulk = csvSchema ? { onImportCsv: handleImport, onExportCsv: handleExport } : {};
|
|
2641
2958
|
const [previewScope, setPreviewScope] = useState(null);
|
|
2642
2959
|
const [drawerOpen, setDrawerOpen] = useState(false);
|
|
2960
|
+
const [sidePreviewOpen, setSidePreviewOpen] = useState(true);
|
|
2643
2961
|
useEffect(() => {
|
|
2644
2962
|
if (!editingScope) return;
|
|
2645
2963
|
setPreviewScope((cur) => cur === null ? editingScope : cur);
|
|
2646
2964
|
}, [editingScope]);
|
|
2647
2965
|
const effectivePreviewScope = previewScope ?? editingScope;
|
|
2966
|
+
const editorHeaderLabel = useMemo(() => {
|
|
2967
|
+
if (!editingScope) return void 0;
|
|
2968
|
+
if (activeScope === "facet" && selectedFacetRef) {
|
|
2969
|
+
const hit = facetBrowse.items.find((it) => it.ref === selectedFacetRef);
|
|
2970
|
+
return hit?.label;
|
|
2971
|
+
}
|
|
2972
|
+
if (activeScope === "product" && selectedProductId) {
|
|
2973
|
+
const hit = productBrowse.items.find((it) => it.id === selectedProductId);
|
|
2974
|
+
return hit?.name ?? selectedProductId;
|
|
2975
|
+
}
|
|
2976
|
+
return void 0;
|
|
2977
|
+
}, [activeScope, editingScope, selectedFacetRef, selectedProductId, facetBrowse.items, productBrowse.items]);
|
|
2978
|
+
const editorHeaderSubtitle = useMemo(() => {
|
|
2979
|
+
if (!editingScope) return void 0;
|
|
2980
|
+
if (activeScope === "facet" && selectedFacetRef) {
|
|
2981
|
+
const hit = facetBrowse.items.find((it) => it.ref === selectedFacetRef);
|
|
2982
|
+
return hit?.subtitle;
|
|
2983
|
+
}
|
|
2984
|
+
return void 0;
|
|
2985
|
+
}, [activeScope, editingScope, selectedFacetRef, selectedProductId, facetBrowse.items, productBrowse.items]);
|
|
2986
|
+
const editorHeaderMeta = useMemo(() => {
|
|
2987
|
+
if (!editingScope) return void 0;
|
|
2988
|
+
if (activeScope === "product" && selectedProductId) {
|
|
2989
|
+
const hit = productBrowse.items.find((it) => it.id === selectedProductId);
|
|
2990
|
+
return hit?.sku ?? selectedProductId;
|
|
2991
|
+
}
|
|
2992
|
+
return void 0;
|
|
2993
|
+
}, [activeScope, editingScope, selectedProductId, productBrowse.items]);
|
|
2648
2994
|
const renderEditorWithPreview = () => {
|
|
2649
2995
|
if (!editingScope) return null;
|
|
2650
2996
|
const previewBody = renderPreview && effectivePreviewScope ? renderPreview({ resolved: editorCtx.value, previewScope: effectivePreviewScope }) : null;
|
|
@@ -2670,6 +3016,9 @@ function RecordsAdminShell(props) {
|
|
|
2670
3016
|
preview: inlinePreviewBody,
|
|
2671
3017
|
footerExtra: extraFooter,
|
|
2672
3018
|
onBeforeDelete: onBeforeDelete && editingScope ? () => onBeforeDelete(editingScope) : void 0,
|
|
3019
|
+
headerLabel: editorHeaderLabel,
|
|
3020
|
+
headerSubtitle: editorHeaderSubtitle,
|
|
3021
|
+
headerMeta: editorHeaderMeta,
|
|
2673
3022
|
children: renderEditor(editorCtx)
|
|
2674
3023
|
}
|
|
2675
3024
|
);
|
|
@@ -2681,9 +3030,28 @@ function RecordsAdminShell(props) {
|
|
|
2681
3030
|
);
|
|
2682
3031
|
}
|
|
2683
3032
|
if (previewMode === "side") {
|
|
3033
|
+
if (!sidePreviewOpen) {
|
|
3034
|
+
return /* @__PURE__ */ jsx("div", { className: "relative h-full", children: baseEditor(
|
|
3035
|
+
/* @__PURE__ */ jsx(
|
|
3036
|
+
PreviewToggleButton,
|
|
3037
|
+
{
|
|
3038
|
+
onClick: () => setSidePreviewOpen(true),
|
|
3039
|
+
label: i18n.openPreview
|
|
3040
|
+
}
|
|
3041
|
+
)
|
|
3042
|
+
) });
|
|
3043
|
+
}
|
|
2684
3044
|
return /* @__PURE__ */ jsxs("div", { className: "grid h-full", style: { gridTemplateColumns: "minmax(0, 1fr) minmax(280px, 420px)" }, children: [
|
|
2685
3045
|
/* @__PURE__ */ jsx("div", { className: "overflow-hidden", children: baseEditor() }),
|
|
2686
|
-
/* @__PURE__ */ jsx(
|
|
3046
|
+
/* @__PURE__ */ jsx(
|
|
3047
|
+
SidePreview,
|
|
3048
|
+
{
|
|
3049
|
+
label: i18n.preview,
|
|
3050
|
+
scopePicker,
|
|
3051
|
+
onClose: () => setSidePreviewOpen(false),
|
|
3052
|
+
children: previewBody
|
|
3053
|
+
}
|
|
3054
|
+
)
|
|
2687
3055
|
] });
|
|
2688
3056
|
}
|
|
2689
3057
|
if (previewMode === "tab") {
|
|
@@ -2715,6 +3083,18 @@ function RecordsAdminShell(props) {
|
|
|
2715
3083
|
};
|
|
2716
3084
|
const isProductTab = activeScope === "product";
|
|
2717
3085
|
const productPinned = !!contextScope?.productId;
|
|
3086
|
+
const effectivePresentation = isProductTab ? presentation : "list";
|
|
3087
|
+
const showPresentationSwitcher = isProductTab && presentations.length > 1;
|
|
3088
|
+
const effectiveGroupBy = useMemo(() => {
|
|
3089
|
+
if (groupBy) return groupBy;
|
|
3090
|
+
if (isProductTab) return void 0;
|
|
3091
|
+
return (record) => {
|
|
3092
|
+
const key = record.scope.facetId;
|
|
3093
|
+
if (!key) return null;
|
|
3094
|
+
const label2 = record.subtitle ?? key;
|
|
3095
|
+
return { key, label: label2 };
|
|
3096
|
+
};
|
|
3097
|
+
}, [groupBy, isProductTab]);
|
|
2718
3098
|
const productListItems = useMemo(() => {
|
|
2719
3099
|
if (productPinned) {
|
|
2720
3100
|
return [{
|
|
@@ -2751,6 +3131,7 @@ function RecordsAdminShell(props) {
|
|
|
2751
3131
|
className: `ra-shell flex flex-col h-full ${className ?? ""}`,
|
|
2752
3132
|
"data-density": density,
|
|
2753
3133
|
children: [
|
|
3134
|
+
dirtyConfirm.dialog,
|
|
2754
3135
|
/* @__PURE__ */ jsxs("div", { className: "px-4 pt-4 space-y-3", children: [
|
|
2755
3136
|
intro && !dismissed && /* @__PURE__ */ jsx(
|
|
2756
3137
|
IntroCard,
|
|
@@ -2795,6 +3176,25 @@ function RecordsAdminShell(props) {
|
|
|
2795
3176
|
introHidden: dismissed && !!intro,
|
|
2796
3177
|
onShowIntro: undismiss
|
|
2797
3178
|
}
|
|
3179
|
+
),
|
|
3180
|
+
editorCtx.isDirty && /* @__PURE__ */ jsx(
|
|
3181
|
+
UnsavedBanner,
|
|
3182
|
+
{
|
|
3183
|
+
label: editorHeaderLabel,
|
|
3184
|
+
context: editorHeaderSubtitle,
|
|
3185
|
+
isSaving: !!editorCtx.isSaving,
|
|
3186
|
+
saveError: editorCtx.saveError,
|
|
3187
|
+
onSave: () => {
|
|
3188
|
+
void editorCtx.save().catch(() => {
|
|
3189
|
+
});
|
|
3190
|
+
},
|
|
3191
|
+
onDiscard: editorCtx.reset,
|
|
3192
|
+
saveLabel: i18n.save,
|
|
3193
|
+
discardLabel: i18n.discard,
|
|
3194
|
+
savingLabel: i18n.saving,
|
|
3195
|
+
errorLabel: i18n.saveError,
|
|
3196
|
+
bodyTemplate: i18n.unsavedBannerBody
|
|
3197
|
+
}
|
|
2798
3198
|
)
|
|
2799
3199
|
] }),
|
|
2800
3200
|
/* @__PURE__ */ jsxs(
|
|
@@ -2842,14 +3242,23 @@ function RecordsAdminShell(props) {
|
|
|
2842
3242
|
/* @__PURE__ */ jsx(
|
|
2843
3243
|
PresentationSwitcher,
|
|
2844
3244
|
{
|
|
2845
|
-
options: presentations,
|
|
3245
|
+
options: showPresentationSwitcher ? presentations : [],
|
|
2846
3246
|
value: presentation,
|
|
2847
3247
|
onChange: onPresentationChange,
|
|
2848
3248
|
i18n
|
|
2849
3249
|
}
|
|
2850
3250
|
)
|
|
2851
3251
|
] }),
|
|
2852
|
-
!isProductTab && /* @__PURE__ */ jsx(
|
|
3252
|
+
!isProductTab && /* @__PURE__ */ jsx(
|
|
3253
|
+
StatusFilterPills,
|
|
3254
|
+
{
|
|
3255
|
+
value: filter,
|
|
3256
|
+
onChange: setFilter,
|
|
3257
|
+
counts: facetBrowse.counts,
|
|
3258
|
+
hideZero: ["partial"],
|
|
3259
|
+
i18n
|
|
3260
|
+
}
|
|
3261
|
+
),
|
|
2853
3262
|
cardinality === "collection" && !isProductTab && editingScope && /* @__PURE__ */ jsxs(
|
|
2854
3263
|
"button",
|
|
2855
3264
|
{
|
|
@@ -2891,10 +3300,10 @@ function RecordsAdminShell(props) {
|
|
|
2891
3300
|
selectedRef: leftSelectedRef,
|
|
2892
3301
|
onSelect: onLeftSelect,
|
|
2893
3302
|
dirtyRef: editorCtx.isDirty ? editingScope?.raw : void 0,
|
|
2894
|
-
presentation,
|
|
3303
|
+
presentation: effectivePresentation,
|
|
2895
3304
|
renderListRow,
|
|
2896
3305
|
renderCard,
|
|
2897
|
-
groupBy
|
|
3306
|
+
groupBy: effectiveGroupBy
|
|
2898
3307
|
}
|
|
2899
3308
|
),
|
|
2900
3309
|
isProductTab && !productPinned && productBrowse.hasNextPage && /* @__PURE__ */ jsx("div", { className: "p-2", children: /* @__PURE__ */ jsx(
|