@proveanything/smartlinks-utils-ui 0.12.5 → 0.12.7
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-WCUKTVWC.js +382 -0
- package/dist/chunk-WCUKTVWC.js.map +1 -0
- package/dist/components/AssetPicker/index.css +9 -2
- package/dist/components/AssetPicker/index.css.map +1 -1
- package/dist/components/ConditionsEditor/index.css +9 -2
- package/dist/components/ConditionsEditor/index.css.map +1 -1
- package/dist/components/ConditionsEditor/index.js +1 -1
- package/dist/components/FontPicker/index.css +9 -2
- package/dist/components/FontPicker/index.css.map +1 -1
- package/dist/components/IconPicker/index.css +9 -2
- package/dist/components/IconPicker/index.css.map +1 -1
- package/dist/components/LinkPicker/index.css +3989 -0
- package/dist/components/LinkPicker/index.css.map +1 -0
- package/dist/components/LinkPicker/index.d.ts +131 -0
- package/dist/components/LinkPicker/index.js +6 -0
- package/dist/components/LinkPicker/index.js.map +1 -0
- package/dist/components/RecordsAdmin/index.css +9 -2
- package/dist/components/RecordsAdmin/index.css.map +1 -1
- package/dist/components/RecordsAdmin/index.d.ts +37 -2
- package/dist/components/RecordsAdmin/index.js +406 -127
- package/dist/components/RecordsAdmin/index.js.map +1 -1
- package/dist/index.css +9 -2
- package/dist/index.css.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/package.json +5 -1
|
@@ -1,11 +1,11 @@
|
|
|
1
|
+
import { parsedRefToTarget, parsedRefToScope, matchRecords, scopesEqual, getRecordById, listRecords, upsertRecord, updateRecord, createRecord, removeRecord } from '../../chunk-KA4MKRHL.js';
|
|
2
|
+
export { bulkDelete, bulkUpsert, createRecord, getRecordById, listRecords, matchRecords, parsedRefToScope, parsedRefToTarget, removeRecord, restoreRecord, scopesEqual, upsertRecord } from '../../chunk-KA4MKRHL.js';
|
|
1
3
|
import { useIntroState, AdminPageHeader } from '../../chunk-3RRHM4LP.js';
|
|
2
|
-
import { assertComponentStylesLoaded } from '../../chunk-OLYC54YT.js';
|
|
3
|
-
import '../../chunk-5UQQYXCX.js';
|
|
4
4
|
import { FacetRuleEditor } from '../../chunk-JMCV6FOW.js';
|
|
5
5
|
import { useFacets } from '../../chunk-4LHF5JB7.js';
|
|
6
|
+
import { assertComponentStylesLoaded } from '../../chunk-OLYC54YT.js';
|
|
7
|
+
import '../../chunk-5UQQYXCX.js';
|
|
6
8
|
import { cn } from '../../chunk-L7FQ52F5.js';
|
|
7
|
-
import { parsedRefToTarget, parsedRefToScope, matchRecords, scopesEqual, getRecordById, listRecords, upsertRecord, updateRecord, createRecord, removeRecord } from '../../chunk-KA4MKRHL.js';
|
|
8
|
-
export { bulkDelete, bulkUpsert, createRecord, getRecordById, listRecords, matchRecords, parsedRefToScope, parsedRefToTarget, removeRecord, restoreRecord, scopesEqual, upsertRecord } from '../../chunk-KA4MKRHL.js';
|
|
9
9
|
import { createContext, useMemo, useState, useEffect, useCallback, useRef, isValidElement, useLayoutEffect, useContext, useSyncExternalStore, createElement } from 'react';
|
|
10
10
|
import { ChevronDown, Database, Lightbulb, SearchX, Inbox, LayoutGrid, Eye, MoreHorizontal, Download, Upload, Trash2, Copy, Pencil, Plus, CircleDashed, ArrowDownLeft, CheckCircle2, List, SlidersHorizontal, Globe, Tag, Boxes, Layers, Package, Target, Check, Rows3, ChevronRight, Eraser, FilePlus2, CopyPlus, ClipboardPaste, Box, X, Search, Image, Table, ArrowLeft, ChevronLeft, AlertTriangle, Info, HelpCircle, CornerDownLeft, Circle, ArrowUpDown, ArrowUp, ArrowDown, MinusCircle, XCircle, AlertCircle, Undo2, Save, Loader2, Archive, ArrowRight, Globe2, Sparkles, Settings2 } from 'lucide-react';
|
|
11
11
|
import { useQuery, useQueryClient, useInfiniteQuery } from '@tanstack/react-query';
|
|
@@ -276,7 +276,15 @@ var DEFAULT_I18N = {
|
|
|
276
276
|
conflictArchiveDuplicates: "Archive duplicates",
|
|
277
277
|
conflictDeleteDuplicates: "Delete duplicates",
|
|
278
278
|
conflictDeleteConfirm: "Permanently delete {n} duplicate record(s)? This cannot be undone.",
|
|
279
|
-
conflictResolveLabel: "Resolve"
|
|
279
|
+
conflictResolveLabel: "Resolve",
|
|
280
|
+
ruleSortLabel: "Sort",
|
|
281
|
+
ruleSortRecent: "Recently updated",
|
|
282
|
+
ruleSortName: "Name",
|
|
283
|
+
ruleSortActiveCount: "Active count",
|
|
284
|
+
ruleSortHasArchived: "Has archived",
|
|
285
|
+
lifecycleBadgeActive: "{n} active",
|
|
286
|
+
lifecycleBadgeArchived: "{n} archived",
|
|
287
|
+
lifecycleBadgeDraft: "{n} draft"
|
|
280
288
|
};
|
|
281
289
|
|
|
282
290
|
// src/components/RecordsAdmin/types/presentation.ts
|
|
@@ -851,6 +859,24 @@ var useRecordList = (args) => {
|
|
|
851
859
|
}
|
|
852
860
|
return map;
|
|
853
861
|
}, [historyItems]);
|
|
862
|
+
const ruleLifecycleCounts = useMemo(() => {
|
|
863
|
+
const map = /* @__PURE__ */ new Map();
|
|
864
|
+
for (const r of items) {
|
|
865
|
+
const h = ruleHash(r.facetRule ?? null);
|
|
866
|
+
if (!h) continue;
|
|
867
|
+
let bucket = map.get(h);
|
|
868
|
+
if (!bucket) {
|
|
869
|
+
bucket = { active: 0, archived: 0, draft: 0, other: 0 };
|
|
870
|
+
map.set(h, bucket);
|
|
871
|
+
}
|
|
872
|
+
const ls = r.lifecycleStatus;
|
|
873
|
+
if (ls == null || ls === "" || activeStatuses.includes(ls)) bucket.active += 1;
|
|
874
|
+
else if (ls === "archived") bucket.archived += 1;
|
|
875
|
+
else if (ls === "draft") bucket.draft += 1;
|
|
876
|
+
else bucket.other += 1;
|
|
877
|
+
}
|
|
878
|
+
return map;
|
|
879
|
+
}, [items, activeStatuses]);
|
|
854
880
|
const refetch = useCallback(() => queryClient.refetchQueries({
|
|
855
881
|
queryKey: [...QK_BASE2, ctx.collectionId, ctx.appId, ctx.recordType]
|
|
856
882
|
}), [queryClient, ctx.collectionId, ctx.appId, ctx.recordType]);
|
|
@@ -861,6 +887,7 @@ var useRecordList = (args) => {
|
|
|
861
887
|
activeItems,
|
|
862
888
|
historyItems,
|
|
863
889
|
historyBySlot,
|
|
890
|
+
ruleLifecycleCounts,
|
|
864
891
|
total,
|
|
865
892
|
counts,
|
|
866
893
|
isLoading: query.isLoading,
|
|
@@ -2046,7 +2073,11 @@ function useShellClipboard(args) {
|
|
|
2046
2073
|
const newId = create(scopeArg);
|
|
2047
2074
|
if (!newId) return;
|
|
2048
2075
|
setPendingPasteTarget({ kind: "record", recordId: newId });
|
|
2049
|
-
setPendingSeed({
|
|
2076
|
+
setPendingSeed({
|
|
2077
|
+
value: transformed,
|
|
2078
|
+
sourceScope: source.scope,
|
|
2079
|
+
sourceLabel: source.label
|
|
2080
|
+
});
|
|
2050
2081
|
onTelemetry?.({
|
|
2051
2082
|
type: "clipboard.copy",
|
|
2052
2083
|
recordType,
|
|
@@ -2076,7 +2107,11 @@ function useShellClipboard(args) {
|
|
|
2076
2107
|
if (pendingSeed) {
|
|
2077
2108
|
const seed = pendingSeed;
|
|
2078
2109
|
setPendingSeed(null);
|
|
2079
|
-
|
|
2110
|
+
const finalValue = onPasteOverride ? onPasteOverride(
|
|
2111
|
+
{ value: seed.value, sourceScope: seed.sourceScope },
|
|
2112
|
+
{ scope: editingScope, currentValue: null }
|
|
2113
|
+
) ?? seed.value : seed.value;
|
|
2114
|
+
editorCtx.onChange(finalValue);
|
|
2080
2115
|
onTelemetry?.({
|
|
2081
2116
|
type: "clipboard.paste",
|
|
2082
2117
|
recordType,
|
|
@@ -2089,7 +2124,7 @@ function useShellClipboard(args) {
|
|
|
2089
2124
|
void pasteCurrent();
|
|
2090
2125
|
}, 0);
|
|
2091
2126
|
return () => window.clearTimeout(t);
|
|
2092
|
-
}, [pendingPasteTarget, editingScope, isCollection, selectedItemId, selectedRecordId, pasteCurrent, pendingSeed, editorCtx, onTelemetry, recordType]);
|
|
2127
|
+
}, [pendingPasteTarget, editingScope, isCollection, selectedItemId, selectedRecordId, pasteCurrent, pendingSeed, editorCtx, onTelemetry, recordType, onPasteOverride]);
|
|
2093
2128
|
const rowClipboard = enabled ? (record) => {
|
|
2094
2129
|
const summaryHasData = record.data != null;
|
|
2095
2130
|
const sourceParsed = record.scope;
|
|
@@ -6873,6 +6908,8 @@ function ItemListView({
|
|
|
6873
6908
|
hasNextPage,
|
|
6874
6909
|
isFetchingNextPage,
|
|
6875
6910
|
onLoadMore,
|
|
6911
|
+
groupByLifecycle = false,
|
|
6912
|
+
lifecycle,
|
|
6876
6913
|
i18n
|
|
6877
6914
|
}) {
|
|
6878
6915
|
const newLabel = i18n.newItem.includes("{noun}") ? i18n.newItem.replace("{noun}", itemNoun) : i18n.newItem;
|
|
@@ -6947,6 +6984,69 @@ function ItemListView({
|
|
|
6947
6984
|
}), [ctx]);
|
|
6948
6985
|
const confirmName = pendingRecord?.label ?? itemNoun;
|
|
6949
6986
|
const confirmBody = i18n.deleteConfirmBody.includes("{name}") ? i18n.deleteConfirmBody.replace("{name}", confirmName) : i18n.deleteConfirmBody;
|
|
6987
|
+
const activeValues = useMemo(
|
|
6988
|
+
() => getActiveStatusValues(lifecycle),
|
|
6989
|
+
[lifecycle]
|
|
6990
|
+
);
|
|
6991
|
+
const buckets = useMemo(() => {
|
|
6992
|
+
if (!groupByLifecycle) return null;
|
|
6993
|
+
const map = /* @__PURE__ */ new Map();
|
|
6994
|
+
for (const item of visibleItems) {
|
|
6995
|
+
const def = resolveLifecycleStatus(item, lifecycle);
|
|
6996
|
+
const existing = map.get(def.value);
|
|
6997
|
+
if (existing) existing.items.push(item);
|
|
6998
|
+
else map.set(def.value, { label: def.label, items: [item] });
|
|
6999
|
+
}
|
|
7000
|
+
return Array.from(map.entries()).map(([key, v]) => ({
|
|
7001
|
+
key,
|
|
7002
|
+
label: v.label,
|
|
7003
|
+
items: v.items,
|
|
7004
|
+
isActive: activeValues.includes(key)
|
|
7005
|
+
})).sort((a, b) => compareLifecycleBuckets(a.key, b.key)).filter((b) => b.items.length > 0);
|
|
7006
|
+
}, [groupByLifecycle, visibleItems, lifecycle, activeValues]);
|
|
7007
|
+
const [collapsedBuckets, setCollapsedBuckets] = useState(() => /* @__PURE__ */ new Set());
|
|
7008
|
+
const toggleBucket = (key) => {
|
|
7009
|
+
setCollapsedBuckets((prev) => {
|
|
7010
|
+
const next = new Set(prev);
|
|
7011
|
+
if (next.has(key)) next.delete(key);
|
|
7012
|
+
else next.add(key);
|
|
7013
|
+
return next;
|
|
7014
|
+
});
|
|
7015
|
+
};
|
|
7016
|
+
const renderBody = (rows) => {
|
|
7017
|
+
if (renderItemList) return renderItemList(rows, guardedCtx);
|
|
7018
|
+
if (view === "table") {
|
|
7019
|
+
return /* @__PURE__ */ jsx(
|
|
7020
|
+
DefaultItemTable,
|
|
7021
|
+
{
|
|
7022
|
+
items: rows,
|
|
7023
|
+
columns: itemColumns,
|
|
7024
|
+
selectedId: guardedCtx.selectedId,
|
|
7025
|
+
onOpen: guardedCtx.onOpen,
|
|
7026
|
+
onDelete: guardedCtx.onDelete,
|
|
7027
|
+
sort,
|
|
7028
|
+
onToggleSort,
|
|
7029
|
+
rowActions,
|
|
7030
|
+
rowClipboard,
|
|
7031
|
+
i18n
|
|
7032
|
+
}
|
|
7033
|
+
);
|
|
7034
|
+
}
|
|
7035
|
+
return /* @__PURE__ */ jsx(
|
|
7036
|
+
DefaultItemCards,
|
|
7037
|
+
{
|
|
7038
|
+
items: rows,
|
|
7039
|
+
variant: view,
|
|
7040
|
+
selectedId: guardedCtx.selectedId,
|
|
7041
|
+
ctx: guardedCtx,
|
|
7042
|
+
renderCard: renderItemCard,
|
|
7043
|
+
cardSize,
|
|
7044
|
+
rowActions,
|
|
7045
|
+
rowClipboard,
|
|
7046
|
+
i18n
|
|
7047
|
+
}
|
|
7048
|
+
);
|
|
7049
|
+
};
|
|
6950
7050
|
const toolbar = /* @__PURE__ */ jsxs("div", { className: "ra-item-toolbar", children: [
|
|
6951
7051
|
/* @__PURE__ */ jsxs("div", { className: "ra-item-toolbar-title", children: [
|
|
6952
7052
|
/* @__PURE__ */ jsx("h2", { className: "ra-display", style: { fontSize: "0.95rem", margin: 0 }, children: i18n.itemListTitle }),
|
|
@@ -7064,39 +7164,62 @@ function ItemListView({
|
|
|
7064
7164
|
body: `No ${itemNoun}s match "${search}".`
|
|
7065
7165
|
}
|
|
7066
7166
|
);
|
|
7067
|
-
} else if (
|
|
7068
|
-
body =
|
|
7069
|
-
|
|
7070
|
-
|
|
7071
|
-
|
|
7072
|
-
|
|
7073
|
-
|
|
7074
|
-
|
|
7075
|
-
|
|
7076
|
-
|
|
7077
|
-
|
|
7078
|
-
|
|
7079
|
-
|
|
7080
|
-
|
|
7081
|
-
|
|
7082
|
-
|
|
7083
|
-
|
|
7084
|
-
|
|
7167
|
+
} else if (buckets && buckets.length > 0) {
|
|
7168
|
+
body = /* @__PURE__ */ jsx("div", { className: "ra-item-buckets", children: buckets.map((bucket) => {
|
|
7169
|
+
const open = bucket.isActive || !collapsedBuckets.has(bucket.key);
|
|
7170
|
+
return /* @__PURE__ */ jsxs(
|
|
7171
|
+
"section",
|
|
7172
|
+
{
|
|
7173
|
+
className: "ra-item-bucket",
|
|
7174
|
+
"data-bucket": bucket.key,
|
|
7175
|
+
children: [
|
|
7176
|
+
/* @__PURE__ */ jsxs(
|
|
7177
|
+
"button",
|
|
7178
|
+
{
|
|
7179
|
+
type: "button",
|
|
7180
|
+
className: "ra-item-bucket-header",
|
|
7181
|
+
onClick: () => !bucket.isActive && toggleBucket(bucket.key),
|
|
7182
|
+
"aria-expanded": open,
|
|
7183
|
+
disabled: bucket.isActive,
|
|
7184
|
+
style: {
|
|
7185
|
+
display: "flex",
|
|
7186
|
+
alignItems: "center",
|
|
7187
|
+
gap: "6px",
|
|
7188
|
+
width: "100%",
|
|
7189
|
+
padding: "6px 12px",
|
|
7190
|
+
background: "transparent",
|
|
7191
|
+
border: 0,
|
|
7192
|
+
borderTop: "1px solid hsl(var(--ra-border))",
|
|
7193
|
+
font: "inherit",
|
|
7194
|
+
fontSize: "11px",
|
|
7195
|
+
fontWeight: 600,
|
|
7196
|
+
textTransform: "uppercase",
|
|
7197
|
+
letterSpacing: "0.04em",
|
|
7198
|
+
color: "hsl(var(--ra-muted-text))",
|
|
7199
|
+
cursor: bucket.isActive ? "default" : "pointer"
|
|
7200
|
+
},
|
|
7201
|
+
children: [
|
|
7202
|
+
!bucket.isActive ? open ? /* @__PURE__ */ jsx(ChevronDown, { className: "w-3 h-3", "aria-hidden": "true" }) : /* @__PURE__ */ jsx(ChevronRight, { className: "w-3 h-3", "aria-hidden": "true" }) : null,
|
|
7203
|
+
/* @__PURE__ */ jsx("span", { children: bucket.label }),
|
|
7204
|
+
/* @__PURE__ */ jsx("span", { style: { marginLeft: "auto", fontWeight: 500 }, children: bucket.items.length })
|
|
7205
|
+
]
|
|
7206
|
+
}
|
|
7207
|
+
),
|
|
7208
|
+
open && /* @__PURE__ */ jsx(
|
|
7209
|
+
"div",
|
|
7210
|
+
{
|
|
7211
|
+
className: "ra-item-bucket-body",
|
|
7212
|
+
style: bucket.isActive ? void 0 : { opacity: 0.75 },
|
|
7213
|
+
children: renderBody(bucket.items)
|
|
7214
|
+
}
|
|
7215
|
+
)
|
|
7216
|
+
]
|
|
7217
|
+
},
|
|
7218
|
+
bucket.key
|
|
7219
|
+
);
|
|
7220
|
+
}) });
|
|
7085
7221
|
} else {
|
|
7086
|
-
body =
|
|
7087
|
-
DefaultItemCards,
|
|
7088
|
-
{
|
|
7089
|
-
items: visibleItems,
|
|
7090
|
-
variant: view,
|
|
7091
|
-
selectedId: guardedCtx.selectedId,
|
|
7092
|
-
ctx: guardedCtx,
|
|
7093
|
-
renderCard: renderItemCard,
|
|
7094
|
-
cardSize,
|
|
7095
|
-
rowActions,
|
|
7096
|
-
rowClipboard,
|
|
7097
|
-
i18n
|
|
7098
|
-
}
|
|
7099
|
-
);
|
|
7222
|
+
body = renderBody(visibleItems);
|
|
7100
7223
|
}
|
|
7101
7224
|
return /* @__PURE__ */ jsxs("div", { className: "ra-item-list", children: [
|
|
7102
7225
|
toolbar,
|
|
@@ -7239,10 +7362,42 @@ function SiblingRail({
|
|
|
7239
7362
|
isFetchingNextPage,
|
|
7240
7363
|
onLoadMore,
|
|
7241
7364
|
rowClipboard,
|
|
7242
|
-
rowActions
|
|
7365
|
+
rowActions,
|
|
7366
|
+
groupByLifecycle = false,
|
|
7367
|
+
lifecycle
|
|
7243
7368
|
}) {
|
|
7244
7369
|
const ruleLabelLookup = useRuleLabelLookup();
|
|
7245
7370
|
const newLabel = i18n.newItem.includes("{noun}") ? i18n.newItem.replace("{noun}", itemNoun ?? "item") : i18n.newItem;
|
|
7371
|
+
const activeValues = useMemo(
|
|
7372
|
+
() => getActiveStatusValues(lifecycle),
|
|
7373
|
+
[lifecycle]
|
|
7374
|
+
);
|
|
7375
|
+
const buckets = useMemo(() => {
|
|
7376
|
+
if (!groupByLifecycle) return null;
|
|
7377
|
+
const map = /* @__PURE__ */ new Map();
|
|
7378
|
+
for (const item of items) {
|
|
7379
|
+
const def = resolveLifecycleStatus(item, lifecycle);
|
|
7380
|
+
const key = def.value;
|
|
7381
|
+
const existing = map.get(key);
|
|
7382
|
+
if (existing) existing.items.push(item);
|
|
7383
|
+
else map.set(key, { label: def.label, items: [item] });
|
|
7384
|
+
}
|
|
7385
|
+
return Array.from(map.entries()).map(([key, v]) => ({
|
|
7386
|
+
key,
|
|
7387
|
+
label: v.label,
|
|
7388
|
+
items: v.items,
|
|
7389
|
+
isActive: activeValues.includes(key)
|
|
7390
|
+
})).sort((a, b) => compareLifecycleBuckets(a.key, b.key)).filter((b) => b.items.length > 0);
|
|
7391
|
+
}, [groupByLifecycle, items, lifecycle, activeValues]);
|
|
7392
|
+
const [collapsed, setCollapsed] = useState(() => /* @__PURE__ */ new Set());
|
|
7393
|
+
const toggleBucket = (key) => {
|
|
7394
|
+
setCollapsed((prev) => {
|
|
7395
|
+
const next = new Set(prev);
|
|
7396
|
+
if (next.has(key)) next.delete(key);
|
|
7397
|
+
else next.add(key);
|
|
7398
|
+
return next;
|
|
7399
|
+
});
|
|
7400
|
+
};
|
|
7246
7401
|
return /* @__PURE__ */ jsxs("div", { className: "ra-sibling-rail", children: [
|
|
7247
7402
|
(onBack || contextKind) && /* @__PURE__ */ jsxs("div", { className: "ra-sibling-context", children: [
|
|
7248
7403
|
onBack && /* @__PURE__ */ jsx(
|
|
@@ -7268,79 +7423,125 @@ function SiblingRail({
|
|
|
7268
7423
|
isLoading && /* @__PURE__ */ jsx(LoadingState, {}),
|
|
7269
7424
|
!isLoading && error && /* @__PURE__ */ jsx(ErrorState, { error }),
|
|
7270
7425
|
!isLoading && !error && items.length === 0 && /* @__PURE__ */ jsx(EmptyState, { title: i18n.noItemsTitle, body: i18n.noItemsBody }),
|
|
7271
|
-
!isLoading && !error && items.length > 0 &&
|
|
7272
|
-
const
|
|
7273
|
-
|
|
7274
|
-
|
|
7275
|
-
|
|
7276
|
-
|
|
7277
|
-
|
|
7278
|
-
|
|
7279
|
-
|
|
7280
|
-
|
|
7281
|
-
|
|
7282
|
-
/* @__PURE__ */ jsxs(
|
|
7283
|
-
|
|
7284
|
-
|
|
7285
|
-
type: "button",
|
|
7286
|
-
onClick: () => onSelect(id),
|
|
7287
|
-
className: "ra-row",
|
|
7288
|
-
"data-selected": selected,
|
|
7289
|
-
children: [
|
|
7290
|
-
/* @__PURE__ */ jsxs("div", { className: "ra-row-body", children: [
|
|
7291
|
-
/* @__PURE__ */ jsx("div", { className: "ra-row-title", children: item.label }),
|
|
7292
|
-
item.subtitle && /* @__PURE__ */ jsx("div", { className: "ra-row-sub", children: item.subtitle })
|
|
7293
|
-
] }),
|
|
7294
|
-
isTargeted && /* @__PURE__ */ jsx(
|
|
7295
|
-
"span",
|
|
7296
|
-
{
|
|
7297
|
-
className: "ra-row-rule-pip",
|
|
7298
|
-
title: ruleSummary ? `Targeted: ${ruleSummary}` : "This item has targeting rules",
|
|
7299
|
-
"aria-label": ruleSummary ? `Targeted: ${ruleSummary}` : "This item has targeting rules",
|
|
7300
|
-
children: /* @__PURE__ */ jsx(Target, { className: "w-3 h-3", "aria-hidden": "true" })
|
|
7301
|
-
}
|
|
7302
|
-
),
|
|
7303
|
-
hasError ? /* @__PURE__ */ jsx(
|
|
7304
|
-
"span",
|
|
7305
|
-
{
|
|
7306
|
-
className: "ra-error-pip",
|
|
7307
|
-
title: "Save failed",
|
|
7308
|
-
"aria-label": "Save failed"
|
|
7309
|
-
}
|
|
7310
|
-
) : isDirty ? /* @__PURE__ */ jsx(
|
|
7311
|
-
"span",
|
|
7312
|
-
{
|
|
7313
|
-
className: "ra-dirty-pip",
|
|
7314
|
-
title: "Unsaved changes",
|
|
7315
|
-
"aria-label": "Unsaved changes"
|
|
7316
|
-
}
|
|
7317
|
-
) : null
|
|
7318
|
-
]
|
|
7319
|
-
}
|
|
7320
|
-
),
|
|
7321
|
-
(() => {
|
|
7322
|
-
const cb = rowClipboard ? rowClipboard(item) : null;
|
|
7323
|
-
const extra = rowActions ? rowActions(item) ?? void 0 : void 0;
|
|
7324
|
-
if (!cb?.onCopy && !cb?.onDuplicate && !cb?.onCopyAndNewRule && !(extra && extra.length)) {
|
|
7325
|
-
return null;
|
|
7326
|
-
}
|
|
7327
|
-
return /* @__PURE__ */ jsx(
|
|
7328
|
-
RowContextMenu,
|
|
7426
|
+
!isLoading && !error && items.length > 0 && (() => {
|
|
7427
|
+
const renderRow = (item, idx, dimmed) => {
|
|
7428
|
+
const id = item.itemId ?? "";
|
|
7429
|
+
const key = item.id ?? (id || anchorKey(item.scope) || `pos:${idx}`);
|
|
7430
|
+
const akey = anchorKey(item.scope);
|
|
7431
|
+
const selected = selectedItemId === id;
|
|
7432
|
+
const isDirty = !!(id && dirtyKeys?.has(id) || akey && dirtyKeys?.has(akey));
|
|
7433
|
+
const hasError = !!(id && errorKeys?.has(id) || akey && errorKeys?.has(akey));
|
|
7434
|
+
const ruleClauses = item.facetRule ? summarizeFacetRule(item.facetRule, ruleLabelLookup) : [];
|
|
7435
|
+
const isTargeted = ruleClauses.length > 0;
|
|
7436
|
+
const ruleSummary = isTargeted ? ruleClauses.map((c) => c.label).join(" \xB7 ") : null;
|
|
7437
|
+
return /* @__PURE__ */ jsx("li", { "data-dimmed": dimmed || void 0, children: /* @__PURE__ */ jsxs("div", { className: "ra-row-shell", "data-selected": selected, children: [
|
|
7438
|
+
/* @__PURE__ */ jsxs(
|
|
7439
|
+
"button",
|
|
7329
7440
|
{
|
|
7330
|
-
|
|
7331
|
-
|
|
7332
|
-
|
|
7333
|
-
|
|
7334
|
-
|
|
7335
|
-
|
|
7336
|
-
|
|
7337
|
-
|
|
7441
|
+
type: "button",
|
|
7442
|
+
onClick: () => onSelect(id),
|
|
7443
|
+
className: "ra-row",
|
|
7444
|
+
"data-selected": selected,
|
|
7445
|
+
style: dimmed ? { opacity: 0.7 } : void 0,
|
|
7446
|
+
children: [
|
|
7447
|
+
/* @__PURE__ */ jsxs("div", { className: "ra-row-body", children: [
|
|
7448
|
+
/* @__PURE__ */ jsx("div", { className: "ra-row-title", children: item.label }),
|
|
7449
|
+
item.subtitle && /* @__PURE__ */ jsx("div", { className: "ra-row-sub", children: item.subtitle })
|
|
7450
|
+
] }),
|
|
7451
|
+
isTargeted && /* @__PURE__ */ jsx(
|
|
7452
|
+
"span",
|
|
7453
|
+
{
|
|
7454
|
+
className: "ra-row-rule-pip",
|
|
7455
|
+
title: ruleSummary ? `Targeted: ${ruleSummary}` : "This item has targeting rules",
|
|
7456
|
+
"aria-label": ruleSummary ? `Targeted: ${ruleSummary}` : "This item has targeting rules",
|
|
7457
|
+
children: /* @__PURE__ */ jsx(Target, { className: "w-3 h-3", "aria-hidden": "true" })
|
|
7458
|
+
}
|
|
7459
|
+
),
|
|
7460
|
+
hasError ? /* @__PURE__ */ jsx(
|
|
7461
|
+
"span",
|
|
7462
|
+
{
|
|
7463
|
+
className: "ra-error-pip",
|
|
7464
|
+
title: "Save failed",
|
|
7465
|
+
"aria-label": "Save failed"
|
|
7466
|
+
}
|
|
7467
|
+
) : isDirty ? /* @__PURE__ */ jsx(
|
|
7468
|
+
"span",
|
|
7469
|
+
{
|
|
7470
|
+
className: "ra-dirty-pip",
|
|
7471
|
+
title: "Unsaved changes",
|
|
7472
|
+
"aria-label": "Unsaved changes"
|
|
7473
|
+
}
|
|
7474
|
+
) : null
|
|
7475
|
+
]
|
|
7476
|
+
}
|
|
7477
|
+
),
|
|
7478
|
+
(() => {
|
|
7479
|
+
const cb = rowClipboard ? rowClipboard(item) : null;
|
|
7480
|
+
const extra = rowActions ? rowActions(item) ?? void 0 : void 0;
|
|
7481
|
+
if (!cb?.onCopy && !cb?.onDuplicate && !cb?.onCopyAndNewRule && !(extra && extra.length)) {
|
|
7482
|
+
return null;
|
|
7483
|
+
}
|
|
7484
|
+
return /* @__PURE__ */ jsx(
|
|
7485
|
+
RowContextMenu,
|
|
7486
|
+
{
|
|
7487
|
+
onCopy: cb?.onCopy,
|
|
7488
|
+
onDuplicate: cb?.onDuplicate,
|
|
7489
|
+
onCopyAndNewRule: cb?.onCopyAndNewRule,
|
|
7490
|
+
actions: extra,
|
|
7491
|
+
i18n: {
|
|
7492
|
+
copy: i18n.copy,
|
|
7493
|
+
duplicateAction: i18n.duplicateAction,
|
|
7494
|
+
copyAndNewRuleAction: i18n.copyAndNewRuleAction
|
|
7495
|
+
}
|
|
7338
7496
|
}
|
|
7497
|
+
);
|
|
7498
|
+
})()
|
|
7499
|
+
] }) }, key);
|
|
7500
|
+
};
|
|
7501
|
+
if (!buckets) {
|
|
7502
|
+
return /* @__PURE__ */ jsx("ul", { className: "ra-sibling-list", children: items.map((item, idx) => renderRow(item, idx, false)) });
|
|
7503
|
+
}
|
|
7504
|
+
return /* @__PURE__ */ jsx("div", { className: "ra-sibling-buckets", children: buckets.map((bucket) => {
|
|
7505
|
+
const open = bucket.isActive || !collapsed.has(bucket.key);
|
|
7506
|
+
return /* @__PURE__ */ jsxs("section", { className: "ra-sibling-bucket", "data-bucket": bucket.key, children: [
|
|
7507
|
+
/* @__PURE__ */ jsxs(
|
|
7508
|
+
"button",
|
|
7509
|
+
{
|
|
7510
|
+
type: "button",
|
|
7511
|
+
className: "ra-sibling-bucket-header",
|
|
7512
|
+
onClick: () => !bucket.isActive && toggleBucket(bucket.key),
|
|
7513
|
+
"aria-expanded": open,
|
|
7514
|
+
disabled: bucket.isActive,
|
|
7515
|
+
style: {
|
|
7516
|
+
display: "flex",
|
|
7517
|
+
alignItems: "center",
|
|
7518
|
+
gap: "6px",
|
|
7519
|
+
width: "100%",
|
|
7520
|
+
padding: "6px 10px",
|
|
7521
|
+
background: "transparent",
|
|
7522
|
+
border: 0,
|
|
7523
|
+
borderTop: "1px solid hsl(var(--ra-border))",
|
|
7524
|
+
font: "inherit",
|
|
7525
|
+
fontSize: "11px",
|
|
7526
|
+
fontWeight: 600,
|
|
7527
|
+
textTransform: "uppercase",
|
|
7528
|
+
letterSpacing: "0.04em",
|
|
7529
|
+
color: "hsl(var(--ra-muted-text))",
|
|
7530
|
+
cursor: bucket.isActive ? "default" : "pointer"
|
|
7531
|
+
},
|
|
7532
|
+
children: [
|
|
7533
|
+
!bucket.isActive ? open ? /* @__PURE__ */ jsx(ChevronDown, { className: "w-3 h-3", "aria-hidden": "true" }) : /* @__PURE__ */ jsx(ChevronRight, { className: "w-3 h-3", "aria-hidden": "true" }) : null,
|
|
7534
|
+
/* @__PURE__ */ jsx("span", { children: bucket.label }),
|
|
7535
|
+
/* @__PURE__ */ jsx("span", { style: { marginLeft: "auto", fontWeight: 500 }, children: bucket.items.length })
|
|
7536
|
+
]
|
|
7339
7537
|
}
|
|
7340
|
-
)
|
|
7341
|
-
|
|
7342
|
-
|
|
7343
|
-
|
|
7538
|
+
),
|
|
7539
|
+
open && /* @__PURE__ */ jsx("ul", { className: "ra-sibling-list", children: bucket.items.map(
|
|
7540
|
+
(item, idx) => renderRow(item, idx, !bucket.isActive)
|
|
7541
|
+
) })
|
|
7542
|
+
] }, bucket.key);
|
|
7543
|
+
}) });
|
|
7544
|
+
})()
|
|
7344
7545
|
] }),
|
|
7345
7546
|
onLoadMore && /* @__PURE__ */ jsx(
|
|
7346
7547
|
LoadMoreFooter,
|
|
@@ -8884,6 +9085,7 @@ function RecordsAdminShellInner(props) {
|
|
|
8884
9085
|
onTelemetry?.({ type: "presentation.change", recordType, from: presentation, to: next });
|
|
8885
9086
|
setPresentation(next);
|
|
8886
9087
|
}, [onTelemetry, recordType, presentation, setPresentation]);
|
|
9088
|
+
const [ruleSort, setRuleSort] = useState("recent");
|
|
8887
9089
|
const [itemView, setItemView] = useItemViewPref({
|
|
8888
9090
|
appId,
|
|
8889
9091
|
recordType,
|
|
@@ -9524,7 +9726,7 @@ function RecordsAdminShellInner(props) {
|
|
|
9524
9726
|
setDrawerOpen,
|
|
9525
9727
|
sidePreviewOpen,
|
|
9526
9728
|
setSidePreviewOpen,
|
|
9527
|
-
editorHeaderLabel,
|
|
9729
|
+
editorHeaderLabel: editorHeaderLabelRaw,
|
|
9528
9730
|
editorHeaderSubtitle,
|
|
9529
9731
|
editorHeaderMeta
|
|
9530
9732
|
} = useShellPreviewPane({
|
|
@@ -9533,6 +9735,14 @@ function RecordsAdminShellInner(props) {
|
|
|
9533
9735
|
selectedProductId,
|
|
9534
9736
|
productBrowseItems: productLookupItems
|
|
9535
9737
|
});
|
|
9738
|
+
const editorHeaderLabel = useMemo(() => {
|
|
9739
|
+
if (editorHeaderLabelRaw) return editorHeaderLabelRaw;
|
|
9740
|
+
if (isCollection && selectedItemId && !isDraftId3(selectedItemId)) {
|
|
9741
|
+
const hit = collectionItems.items.find((r) => r.id === selectedItemId || r.itemId === selectedItemId);
|
|
9742
|
+
if (hit?.label) return hit.label;
|
|
9743
|
+
}
|
|
9744
|
+
return void 0;
|
|
9745
|
+
}, [editorHeaderLabelRaw, isCollection, selectedItemId, collectionItems.items]);
|
|
9536
9746
|
const shellClipboard = useShellClipboard({
|
|
9537
9747
|
enabled: !!enableClipboard,
|
|
9538
9748
|
appId,
|
|
@@ -10053,6 +10263,11 @@ function RecordsAdminShellInner(props) {
|
|
|
10053
10263
|
const onRuleWizardNext = useCallback(() => {
|
|
10054
10264
|
if (cardinality === "collection") {
|
|
10055
10265
|
setRuleWizardStep(2);
|
|
10266
|
+
if (ruleWizardSeedMode) {
|
|
10267
|
+
skipNextItemResetRef.current = true;
|
|
10268
|
+
const id = coerceDraftItemId2(generateItemId);
|
|
10269
|
+
setSelectedItemId(id);
|
|
10270
|
+
}
|
|
10056
10271
|
} else {
|
|
10057
10272
|
setRuleWizardStep(2);
|
|
10058
10273
|
if (ruleWizardSeedMode) {
|
|
@@ -10060,7 +10275,7 @@ function RecordsAdminShellInner(props) {
|
|
|
10060
10275
|
setSelectedRecordId(DRAFT_ID3);
|
|
10061
10276
|
}
|
|
10062
10277
|
}
|
|
10063
|
-
}, [cardinality, ruleWizardSeedMode, mintRuleWizardDraftKey]);
|
|
10278
|
+
}, [cardinality, ruleWizardSeedMode, mintRuleWizardDraftKey, generateItemId, skipNextItemResetRef]);
|
|
10064
10279
|
const startRuleWizardDraft = useCallback((seed) => {
|
|
10065
10280
|
setRuleWizardSeedMode(seed);
|
|
10066
10281
|
setRuleWizardDraftKey(mintRuleWizardDraftKey());
|
|
@@ -10114,17 +10329,51 @@ function RecordsAdminShellInner(props) {
|
|
|
10114
10329
|
buckets.set(hash, { rep: item, count: 1 });
|
|
10115
10330
|
}
|
|
10116
10331
|
}
|
|
10117
|
-
|
|
10118
|
-
|
|
10119
|
-
|
|
10120
|
-
|
|
10121
|
-
|
|
10122
|
-
|
|
10123
|
-
|
|
10124
|
-
|
|
10125
|
-
|
|
10126
|
-
|
|
10127
|
-
|
|
10332
|
+
const counts = recordList.ruleLifecycleCounts;
|
|
10333
|
+
return Array.from(buckets.entries()).map(([hash, { rep, count }]) => {
|
|
10334
|
+
const lc = counts.get(hash) ?? { active: 0, archived: 0, draft: 0, other: 0 };
|
|
10335
|
+
const lifecycleBadges = [];
|
|
10336
|
+
if (lc.active > 0) lifecycleBadges.push({
|
|
10337
|
+
label: i18n.lifecycleBadgeActive.replace("{n}", String(lc.active)),
|
|
10338
|
+
tone: "success"
|
|
10339
|
+
});
|
|
10340
|
+
if (lc.draft > 0) lifecycleBadges.push({
|
|
10341
|
+
label: i18n.lifecycleBadgeDraft.replace("{n}", String(lc.draft)),
|
|
10342
|
+
tone: "warning"
|
|
10343
|
+
});
|
|
10344
|
+
if (lc.archived > 0) lifecycleBadges.push({
|
|
10345
|
+
label: i18n.lifecycleBadgeArchived.replace("{n}", String(lc.archived)),
|
|
10346
|
+
tone: "neutral"
|
|
10347
|
+
});
|
|
10348
|
+
return {
|
|
10349
|
+
...rep,
|
|
10350
|
+
// Title carries the count + identity; the rule chips below render
|
|
10351
|
+
// the friendly facet/value labels (via the lookup) so we don't
|
|
10352
|
+
// repeat the same information in two places.
|
|
10353
|
+
label: `${count} ${itemNoun}${count === 1 ? "" : "s"}`,
|
|
10354
|
+
subtitle: void 0,
|
|
10355
|
+
badges: [...rep.badges ?? [], ...lifecycleBadges],
|
|
10356
|
+
// Stash counts on the row for the sort comparator below.
|
|
10357
|
+
__lifecycleCounts: lc
|
|
10358
|
+
};
|
|
10359
|
+
});
|
|
10360
|
+
}, [isRuleTab, isCollection, filteredRuleItems, itemNoun, recordList.ruleLifecycleCounts, i18n]);
|
|
10361
|
+
const sortedCollectionRuleRailItems = useMemo(() => {
|
|
10362
|
+
if (!isRuleTab || !isCollection || ruleSort === "recent") return collectionRuleRailItems;
|
|
10363
|
+
const arr = [...collectionRuleRailItems];
|
|
10364
|
+
const counts = (r) => r.__lifecycleCounts ?? { active: 0, archived: 0 };
|
|
10365
|
+
if (ruleSort === "name") arr.sort((a, b) => a.label.localeCompare(b.label));
|
|
10366
|
+
else if (ruleSort === "activeCount") arr.sort((a, b) => counts(b).active - counts(a).active);
|
|
10367
|
+
else if (ruleSort === "hasArchived") {
|
|
10368
|
+
arr.sort((a, b) => {
|
|
10369
|
+
const ah = counts(a).archived > 0 ? 1 : 0;
|
|
10370
|
+
const bh = counts(b).archived > 0 ? 1 : 0;
|
|
10371
|
+
if (ah !== bh) return bh - ah;
|
|
10372
|
+
return counts(b).archived - counts(a).archived;
|
|
10373
|
+
});
|
|
10374
|
+
}
|
|
10375
|
+
return arr;
|
|
10376
|
+
}, [collectionRuleRailItems, isRuleTab, isCollection, ruleSort]);
|
|
10128
10377
|
const activeRuleSummary = useMemo(() => {
|
|
10129
10378
|
if (!isRuleTab || !isCollection) return null;
|
|
10130
10379
|
if (!selectedRecordId || isDraftId3(selectedRecordId)) return null;
|
|
@@ -10263,9 +10512,9 @@ function RecordsAdminShellInner(props) {
|
|
|
10263
10512
|
});
|
|
10264
10513
|
}, [isLifecycleRail, selectedLifecycleKey, lcGroupBy, collectionItems.items]);
|
|
10265
10514
|
const leftItems = isProductTab ? productListItems : isRuleTab ? applyFacetBrowseFilter(
|
|
10266
|
-
isCollection ?
|
|
10515
|
+
isCollection ? sortedCollectionRuleRailItems : filteredRuleItems
|
|
10267
10516
|
) : isLifecycleRail ? lifecycleRows : (isGlobalTab || isAllTab) && isCollection ? [collectionGlobalAllRow] : isRecordsTab ? applyFacetBrowseFilter(recordList.items) : [];
|
|
10268
|
-
const railShowsHistoryDisclosure = isRecordsTab && !isLifecycleRail && !
|
|
10517
|
+
const railShowsHistoryDisclosure = isRecordsTab && !isLifecycleRail && !isCollection;
|
|
10269
10518
|
const filteredLeftItems = useMemo(() => {
|
|
10270
10519
|
if (!railShowsHistoryDisclosure) return leftItems;
|
|
10271
10520
|
return leftItems.filter((r) => {
|
|
@@ -10533,6 +10782,8 @@ function RecordsAdminShellInner(props) {
|
|
|
10533
10782
|
},
|
|
10534
10783
|
rowClipboard,
|
|
10535
10784
|
rowActions: wrappedRecordActions,
|
|
10785
|
+
groupByLifecycle: true,
|
|
10786
|
+
lifecycle: lifecycleConfig,
|
|
10536
10787
|
contextKind: isLifecycleRailEarly && lifecycleBucketLabel ? lifecycleBucketLabel : activeScope === "rule" ? "Rule" : activeScope === "product" ? "Product" : activeScope === "collection" ? "Global" : activeScope === "all" ? "All records" : activeScope === "variant" ? "Variant" : activeScope === "batch" ? "Batch" : activeScope === "facet" ? "Facet" : void 0,
|
|
10537
10788
|
contextSummary: isLifecycleRailEarly && lifecycleBucketLabel ? `${scopedCollectionItemsList.length} ${itemNounLabel}${scopedCollectionItemsList.length === 1 ? "" : "s"}` : activeScope === "rule" ? activeRuleSummary : activeScope === "product" ? editorHeaderLabel ?? null : null,
|
|
10538
10789
|
i18n
|
|
@@ -10663,7 +10914,33 @@ function RecordsAdminShellInner(props) {
|
|
|
10663
10914
|
onChange: setFacetBrowseFilter,
|
|
10664
10915
|
isLoading: facetBrowse.isLoading
|
|
10665
10916
|
}
|
|
10666
|
-
)
|
|
10917
|
+
),
|
|
10918
|
+
isRuleTab && isCollection && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-xs", children: [
|
|
10919
|
+
/* @__PURE__ */ jsx(
|
|
10920
|
+
"label",
|
|
10921
|
+
{
|
|
10922
|
+
htmlFor: "ra-rule-sort",
|
|
10923
|
+
style: { color: "hsl(var(--ra-text-muted))" },
|
|
10924
|
+
children: i18n.ruleSortLabel
|
|
10925
|
+
}
|
|
10926
|
+
),
|
|
10927
|
+
/* @__PURE__ */ jsxs(
|
|
10928
|
+
"select",
|
|
10929
|
+
{
|
|
10930
|
+
id: "ra-rule-sort",
|
|
10931
|
+
value: ruleSort,
|
|
10932
|
+
onChange: (e) => setRuleSort(e.target.value),
|
|
10933
|
+
className: "text-xs px-2 py-1 rounded-md border bg-transparent focus:outline-none focus:ring-1",
|
|
10934
|
+
style: { borderColor: "hsl(var(--ra-border))", color: "hsl(var(--ra-text))" },
|
|
10935
|
+
children: [
|
|
10936
|
+
/* @__PURE__ */ jsx("option", { value: "recent", children: i18n.ruleSortRecent }),
|
|
10937
|
+
/* @__PURE__ */ jsx("option", { value: "name", children: i18n.ruleSortName }),
|
|
10938
|
+
/* @__PURE__ */ jsx("option", { value: "activeCount", children: i18n.ruleSortActiveCount }),
|
|
10939
|
+
/* @__PURE__ */ jsx("option", { value: "hasArchived", children: i18n.ruleSortHasArchived })
|
|
10940
|
+
]
|
|
10941
|
+
}
|
|
10942
|
+
)
|
|
10943
|
+
] })
|
|
10667
10944
|
] })
|
|
10668
10945
|
] }),
|
|
10669
10946
|
/* @__PURE__ */ jsxs("div", { className: "flex-1 overflow-y-auto", children: [
|
|
@@ -10900,6 +11177,8 @@ function RecordsAdminShellInner(props) {
|
|
|
10900
11177
|
onLoadMore: () => {
|
|
10901
11178
|
void collectionItems.fetchNextPage();
|
|
10902
11179
|
},
|
|
11180
|
+
groupByLifecycle: true,
|
|
11181
|
+
lifecycle: lifecycleConfig,
|
|
10903
11182
|
i18n
|
|
10904
11183
|
}
|
|
10905
11184
|
),
|