@proveanything/smartlinks-utils-ui 0.12.2 → 0.12.4
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/components/AssetPicker/index.css +27 -0
- package/dist/components/AssetPicker/index.css.map +1 -1
- package/dist/components/ConditionsEditor/index.css +27 -0
- package/dist/components/ConditionsEditor/index.css.map +1 -1
- package/dist/components/FontPicker/index.css +27 -0
- package/dist/components/FontPicker/index.css.map +1 -1
- package/dist/components/IconPicker/index.css +27 -0
- package/dist/components/IconPicker/index.css.map +1 -1
- package/dist/components/RecordsAdmin/index.css +27 -0
- package/dist/components/RecordsAdmin/index.css.map +1 -1
- package/dist/components/RecordsAdmin/index.d.ts +24 -3
- package/dist/components/RecordsAdmin/index.js +142 -72
- package/dist/components/RecordsAdmin/index.js.map +1 -1
- package/dist/index.css +27 -0
- package/dist/index.css.map +1 -1
- package/package.json +1 -1
|
@@ -1689,6 +1689,14 @@ interface Props$c<T> {
|
|
|
1689
1689
|
onCopyAndNewRule?: () => void;
|
|
1690
1690
|
/** Label for the "Copy and start new rule" button. */
|
|
1691
1691
|
copyAndNewRuleLabel?: string;
|
|
1692
|
+
/**
|
|
1693
|
+
* Collection-cardinality affordance — clone the current editor value
|
|
1694
|
+
* into a fresh draft item under the same scope. Mirrors the row menu
|
|
1695
|
+
* Duplicate action.
|
|
1696
|
+
*/
|
|
1697
|
+
onDuplicate?: () => void;
|
|
1698
|
+
/** Optional label override for the Duplicate button. */
|
|
1699
|
+
duplicateLabel?: string;
|
|
1692
1700
|
};
|
|
1693
1701
|
/** Host-provided labels for save / discard / delete (resting state only). */
|
|
1694
1702
|
actionLabels?: Partial<Record<RecordsAdminActionKey, string>>;
|
|
@@ -2885,9 +2893,22 @@ interface Props$1<T> {
|
|
|
2885
2893
|
hasNextPage?: boolean;
|
|
2886
2894
|
isFetchingNextPage?: boolean;
|
|
2887
2895
|
onLoadMore?: () => void;
|
|
2888
|
-
|
|
2896
|
+
/**
|
|
2897
|
+
* Per-row clipboard actions (Copy / Duplicate / Copy and start new
|
|
2898
|
+
* rule). Mirrors the menu surfaced by `ItemListView` so the open-item
|
|
2899
|
+
* sibling rail offers the same affordances without bouncing back to
|
|
2900
|
+
* the list. Hidden when omitted.
|
|
2901
|
+
*/
|
|
2902
|
+
rowClipboard?: (record: RecordSummary<T>) => {
|
|
2903
|
+
onCopy?: () => void;
|
|
2904
|
+
onDuplicate?: () => void;
|
|
2905
|
+
onCopyAndNewRule?: () => void;
|
|
2906
|
+
} | null | undefined;
|
|
2907
|
+
/** Host-defined extra row actions, surfaced below the built-ins. */
|
|
2908
|
+
rowActions?: (record: RecordSummary<T>) => RecordAction[] | null | undefined;
|
|
2909
|
+
i18n: Pick<RecordsAdminI18n, 'backToScopes' | 'siblingsHeading' | 'noItemsTitle' | 'noItemsBody' | 'backToList' | 'newItem' | 'copy' | 'duplicateAction' | 'copyAndNewRuleAction'>;
|
|
2889
2910
|
}
|
|
2890
|
-
declare function SiblingRail<T>({ items, selectedItemId, isLoading, error, onBack, onSelect, contextKind, contextSummary, onCreate, itemNoun, dirtyKeys, errorKeys, i18n, total, hasNextPage, isFetchingNextPage, onLoadMore, }: Props$1<T>): react_jsx_runtime.JSX.Element;
|
|
2911
|
+
declare function SiblingRail<T>({ items, selectedItemId, isLoading, error, onBack, onSelect, contextKind, contextSummary, onCreate, itemNoun, dirtyKeys, errorKeys, i18n, total, hasNextPage, isFetchingNextPage, onLoadMore, rowClipboard, rowActions, }: Props$1<T>): react_jsx_runtime.JSX.Element;
|
|
2891
2912
|
|
|
2892
2913
|
interface ClipboardEntry<T = unknown> {
|
|
2893
2914
|
value: T;
|
|
@@ -2974,7 +2995,7 @@ interface Props {
|
|
|
2974
2995
|
/** Optional veto hook — return false / throw to abort the change. */
|
|
2975
2996
|
beforeChange?: (ctx: LifecycleChangeCtx) => boolean | Promise<boolean>;
|
|
2976
2997
|
/** Fires after a successful flip with the new value. */
|
|
2977
|
-
onChanged?: (next: string) => void;
|
|
2998
|
+
onChanged?: (next: string, record?: AppRecord) => void;
|
|
2978
2999
|
/** Telemetry hook — receives `{ from, to }`. */
|
|
2979
3000
|
onTelemetry?: (event: {
|
|
2980
3001
|
from: string | undefined;
|
|
@@ -7,7 +7,7 @@ import { cn } from '../../chunk-L7FQ52F5.js';
|
|
|
7
7
|
import { parsedRefToTarget, parsedRefToScope, matchRecords, scopesEqual, getRecordById, listRecords, upsertRecord, updateRecord, createRecord, removeRecord } from '../../chunk-KA4MKRHL.js';
|
|
8
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
|
-
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, ClipboardPaste, Box, X, Search, Image, Table, ArrowLeft, ChevronLeft, AlertTriangle, Info, HelpCircle, CornerDownLeft, Circle, ArrowUpDown, ArrowUp, ArrowDown, MinusCircle, XCircle,
|
|
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, Settings2 } from 'lucide-react';
|
|
11
11
|
import { useQuery, useQueryClient, useInfiniteQuery } from '@tanstack/react-query';
|
|
12
12
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
13
13
|
import { createPortal } from 'react-dom';
|
|
@@ -1765,6 +1765,19 @@ function useShellClipboard(args) {
|
|
|
1765
1765
|
window.setTimeout(() => {
|
|
1766
1766
|
onCreateRuleFromClipboardRef?.current?.();
|
|
1767
1767
|
}, 0);
|
|
1768
|
+
} : void 0,
|
|
1769
|
+
// Collection-cardinality clone affordance — only shown when the host
|
|
1770
|
+
// wired item-draft creation. Pushes the editor value to the clipboard
|
|
1771
|
+
// (so the existing pendingPasteTarget effect lands it on the new
|
|
1772
|
+
// draft) and mints a fresh draft.
|
|
1773
|
+
onDuplicate: isCollection && !!onCreateItemDraftRef ? () => {
|
|
1774
|
+
copyCurrent();
|
|
1775
|
+
window.setTimeout(() => {
|
|
1776
|
+
const create = onCreateItemDraftRef?.current;
|
|
1777
|
+
if (!create) return;
|
|
1778
|
+
const newId = create();
|
|
1779
|
+
if (newId) setPendingPasteTarget({ kind: "record", recordId: newId });
|
|
1780
|
+
}, 0);
|
|
1768
1781
|
} : void 0
|
|
1769
1782
|
} : void 0;
|
|
1770
1783
|
const [pendingPasteTarget, setPendingPasteTarget] = useState(null);
|
|
@@ -3981,8 +3994,8 @@ var LifecycleStatusControl = ({
|
|
|
3981
3994
|
if (next === value) return;
|
|
3982
3995
|
setBusy(true);
|
|
3983
3996
|
try {
|
|
3984
|
-
await SL.app.records.update(collectionId, appId, recordId, { status: next }, true);
|
|
3985
|
-
onChanged?.(next);
|
|
3997
|
+
const updated = await SL.app.records.update(collectionId, appId, recordId, { status: next }, true);
|
|
3998
|
+
onChanged?.(next, updated);
|
|
3986
3999
|
} catch (err) {
|
|
3987
4000
|
console.warn("[LifecycleStatusControl] update failed", err);
|
|
3988
4001
|
} finally {
|
|
@@ -4176,9 +4189,9 @@ var LifecycleStatusMenu = ({
|
|
|
4176
4189
|
}
|
|
4177
4190
|
setBusy(next.value);
|
|
4178
4191
|
try {
|
|
4179
|
-
await SL.app.records.update(collectionId, appId, recordId, { status: next.value }, true);
|
|
4192
|
+
const updated = await SL.app.records.update(collectionId, appId, recordId, { status: next.value }, true);
|
|
4180
4193
|
onTelemetry?.({ from: current, to: next.value });
|
|
4181
|
-
onChanged?.(next.value);
|
|
4194
|
+
onChanged?.(next.value, updated);
|
|
4182
4195
|
} catch (err) {
|
|
4183
4196
|
console.warn("[LifecycleStatusMenu] update failed", err);
|
|
4184
4197
|
} finally {
|
|
@@ -4684,7 +4697,8 @@ function useCollectionItems(args) {
|
|
|
4684
4697
|
label: stableItemId,
|
|
4685
4698
|
updatedAt: rec.updatedAt,
|
|
4686
4699
|
itemId: stableItemId,
|
|
4687
|
-
facetRule: recFacetRule
|
|
4700
|
+
facetRule: recFacetRule,
|
|
4701
|
+
lifecycleStatus: rec.status ?? void 0
|
|
4688
4702
|
};
|
|
4689
4703
|
return toSummary2(rec, base);
|
|
4690
4704
|
}).filter((x) => x !== null);
|
|
@@ -5159,6 +5173,22 @@ function RecordEditor({
|
|
|
5159
5173
|
]
|
|
5160
5174
|
}
|
|
5161
5175
|
),
|
|
5176
|
+
clipboard.onDuplicate && /* @__PURE__ */ jsxs(
|
|
5177
|
+
"button",
|
|
5178
|
+
{
|
|
5179
|
+
type: "button",
|
|
5180
|
+
onClick: clipboard.onDuplicate,
|
|
5181
|
+
disabled: !clipboard.canCopy || !!ctx.isSaving,
|
|
5182
|
+
title: clipboard.duplicateLabel ?? i18n.duplicateAction ?? "Duplicate",
|
|
5183
|
+
"aria-label": clipboard.duplicateLabel ?? i18n.duplicateAction ?? "Duplicate",
|
|
5184
|
+
className: "text-xs px-2.5 py-1.5 rounded-md border transition-opacity disabled:opacity-40 hover:bg-[hsl(var(--ra-muted))] inline-flex items-center gap-1.5",
|
|
5185
|
+
style: { borderColor: "hsl(var(--ra-border))", color: "hsl(var(--ra-text))" },
|
|
5186
|
+
children: [
|
|
5187
|
+
/* @__PURE__ */ jsx(CopyPlus, { className: "w-3 h-3" }),
|
|
5188
|
+
clipboard.duplicateLabel ?? i18n.duplicateAction ?? "Duplicate"
|
|
5189
|
+
]
|
|
5190
|
+
}
|
|
5191
|
+
),
|
|
5162
5192
|
/* @__PURE__ */ jsxs(
|
|
5163
5193
|
"button",
|
|
5164
5194
|
{
|
|
@@ -6895,7 +6925,9 @@ function SiblingRail({
|
|
|
6895
6925
|
total,
|
|
6896
6926
|
hasNextPage,
|
|
6897
6927
|
isFetchingNextPage,
|
|
6898
|
-
onLoadMore
|
|
6928
|
+
onLoadMore,
|
|
6929
|
+
rowClipboard,
|
|
6930
|
+
rowActions
|
|
6899
6931
|
}) {
|
|
6900
6932
|
const ruleLabelLookup = useRuleLabelLookup();
|
|
6901
6933
|
const newLabel = i18n.newItem.includes("{noun}") ? i18n.newItem.replace("{noun}", itemNoun ?? "item") : i18n.newItem;
|
|
@@ -6934,45 +6966,68 @@ function SiblingRail({
|
|
|
6934
6966
|
const ruleClauses = item.facetRule ? summarizeFacetRule(item.facetRule, ruleLabelLookup) : [];
|
|
6935
6967
|
const isTargeted = ruleClauses.length > 0;
|
|
6936
6968
|
const ruleSummary = isTargeted ? ruleClauses.map((c) => c.label).join(" \xB7 ") : null;
|
|
6937
|
-
return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs(
|
|
6938
|
-
|
|
6939
|
-
|
|
6940
|
-
|
|
6941
|
-
|
|
6942
|
-
|
|
6943
|
-
|
|
6944
|
-
|
|
6945
|
-
|
|
6946
|
-
/* @__PURE__ */
|
|
6947
|
-
|
|
6948
|
-
|
|
6949
|
-
|
|
6950
|
-
|
|
6951
|
-
|
|
6952
|
-
|
|
6953
|
-
|
|
6954
|
-
|
|
6955
|
-
|
|
6956
|
-
|
|
6957
|
-
|
|
6958
|
-
|
|
6959
|
-
|
|
6960
|
-
|
|
6961
|
-
|
|
6962
|
-
|
|
6963
|
-
|
|
6964
|
-
|
|
6965
|
-
|
|
6966
|
-
|
|
6967
|
-
|
|
6968
|
-
|
|
6969
|
-
|
|
6970
|
-
|
|
6969
|
+
return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs("div", { className: "ra-row-shell", "data-selected": selected, children: [
|
|
6970
|
+
/* @__PURE__ */ jsxs(
|
|
6971
|
+
"button",
|
|
6972
|
+
{
|
|
6973
|
+
type: "button",
|
|
6974
|
+
onClick: () => onSelect(id),
|
|
6975
|
+
className: "ra-row",
|
|
6976
|
+
"data-selected": selected,
|
|
6977
|
+
children: [
|
|
6978
|
+
/* @__PURE__ */ jsxs("div", { className: "ra-row-body", children: [
|
|
6979
|
+
/* @__PURE__ */ jsx("div", { className: "ra-row-title", children: item.label }),
|
|
6980
|
+
item.subtitle && /* @__PURE__ */ jsx("div", { className: "ra-row-sub", children: item.subtitle })
|
|
6981
|
+
] }),
|
|
6982
|
+
isTargeted && /* @__PURE__ */ jsx(
|
|
6983
|
+
"span",
|
|
6984
|
+
{
|
|
6985
|
+
className: "ra-row-rule-pip",
|
|
6986
|
+
title: ruleSummary ? `Targeted: ${ruleSummary}` : "This item has targeting rules",
|
|
6987
|
+
"aria-label": ruleSummary ? `Targeted: ${ruleSummary}` : "This item has targeting rules",
|
|
6988
|
+
children: /* @__PURE__ */ jsx(Target, { className: "w-3 h-3", "aria-hidden": "true" })
|
|
6989
|
+
}
|
|
6990
|
+
),
|
|
6991
|
+
hasError ? /* @__PURE__ */ jsx(
|
|
6992
|
+
"span",
|
|
6993
|
+
{
|
|
6994
|
+
className: "ra-error-pip",
|
|
6995
|
+
title: "Save failed",
|
|
6996
|
+
"aria-label": "Save failed"
|
|
6997
|
+
}
|
|
6998
|
+
) : isDirty ? /* @__PURE__ */ jsx(
|
|
6999
|
+
"span",
|
|
7000
|
+
{
|
|
7001
|
+
className: "ra-dirty-pip",
|
|
7002
|
+
title: "Unsaved changes",
|
|
7003
|
+
"aria-label": "Unsaved changes"
|
|
7004
|
+
}
|
|
7005
|
+
) : null
|
|
7006
|
+
]
|
|
7007
|
+
}
|
|
7008
|
+
),
|
|
7009
|
+
(() => {
|
|
7010
|
+
const cb = rowClipboard ? rowClipboard(item) : null;
|
|
7011
|
+
const extra = rowActions ? rowActions(item) ?? void 0 : void 0;
|
|
7012
|
+
if (!cb?.onCopy && !cb?.onDuplicate && !cb?.onCopyAndNewRule && !(extra && extra.length)) {
|
|
7013
|
+
return null;
|
|
7014
|
+
}
|
|
7015
|
+
return /* @__PURE__ */ jsx(
|
|
7016
|
+
RowContextMenu,
|
|
7017
|
+
{
|
|
7018
|
+
onCopy: cb?.onCopy,
|
|
7019
|
+
onDuplicate: cb?.onDuplicate,
|
|
7020
|
+
onCopyAndNewRule: cb?.onCopyAndNewRule,
|
|
7021
|
+
actions: extra,
|
|
7022
|
+
i18n: {
|
|
7023
|
+
copy: i18n.copy,
|
|
7024
|
+
duplicateAction: i18n.duplicateAction,
|
|
7025
|
+
copyAndNewRuleAction: i18n.copyAndNewRuleAction
|
|
6971
7026
|
}
|
|
6972
|
-
|
|
6973
|
-
|
|
6974
|
-
}
|
|
6975
|
-
) }, key);
|
|
7027
|
+
}
|
|
7028
|
+
);
|
|
7029
|
+
})()
|
|
7030
|
+
] }) }, key);
|
|
6976
7031
|
}) })
|
|
6977
7032
|
] }),
|
|
6978
7033
|
onLoadMore && /* @__PURE__ */ jsx(
|
|
@@ -8327,14 +8382,14 @@ var coerceDraftItemId2 = (generateItemId) => {
|
|
|
8327
8382
|
const candidate = generateItemId ? generateItemId() : mintDraftItemId2();
|
|
8328
8383
|
return isDraftId3(candidate) ? candidate : `draft:${candidate}`;
|
|
8329
8384
|
};
|
|
8330
|
-
var productItemToSummary = (p) => {
|
|
8385
|
+
var productItemToSummary = (p, configured) => {
|
|
8331
8386
|
const ref = buildRef({ productId: p.id });
|
|
8332
8387
|
return {
|
|
8333
8388
|
id: null,
|
|
8334
8389
|
ref,
|
|
8335
8390
|
scope: parseRef(ref),
|
|
8336
8391
|
data: null,
|
|
8337
|
-
status: "empty",
|
|
8392
|
+
status: configured?.has(p.id) ? "configured" : "empty",
|
|
8338
8393
|
label: p.name,
|
|
8339
8394
|
subtitle: p.sku ?? void 0
|
|
8340
8395
|
};
|
|
@@ -9219,11 +9274,12 @@ function RecordsAdminShellInner(props) {
|
|
|
9219
9274
|
label: label2,
|
|
9220
9275
|
onAction: async () => {
|
|
9221
9276
|
try {
|
|
9222
|
-
await SL.app.records.update(collectionId, appId, record.id, { status: next }, true);
|
|
9223
|
-
|
|
9224
|
-
|
|
9225
|
-
|
|
9226
|
-
|
|
9277
|
+
const updated = await SL.app.records.update(collectionId, appId, record.id, { status: next }, true);
|
|
9278
|
+
if (updated) {
|
|
9279
|
+
patchRecordIntoCaches(queryClient, ctx, updated);
|
|
9280
|
+
queryClient.invalidateQueries({
|
|
9281
|
+
queryKey: scopeCountsQueryKey(ctx.collectionId, ctx.appId, ctx.recordType)
|
|
9282
|
+
});
|
|
9227
9283
|
}
|
|
9228
9284
|
} catch (err) {
|
|
9229
9285
|
console.warn("[RecordsAdminShell] lifecycle update failed", err);
|
|
@@ -9263,6 +9319,14 @@ function RecordsAdminShellInner(props) {
|
|
|
9263
9319
|
const itemViewCtx = baseItemViewCtx;
|
|
9264
9320
|
const renderEditorWithPreview = () => {
|
|
9265
9321
|
if (!editingTargetScope) return null;
|
|
9322
|
+
const targetingSavedRecord = isCollection && selectedItemId && !isDraftId3(selectedItemId) || !!selectedRecordId && !isDraftId3(selectedRecordId);
|
|
9323
|
+
if (resolved.isLoading && targetingSavedRecord && resolved.source !== "self") {
|
|
9324
|
+
return /* @__PURE__ */ jsxs("div", { className: "p-4 space-y-3", "aria-busy": "true", "aria-live": "polite", children: [
|
|
9325
|
+
/* @__PURE__ */ jsx("div", { className: "h-6 rounded-md animate-pulse", style: { background: "hsl(var(--ra-muted))", width: "40%" } }),
|
|
9326
|
+
/* @__PURE__ */ jsx("div", { className: "h-24 rounded-md animate-pulse", style: { background: "hsl(var(--ra-muted))" } }),
|
|
9327
|
+
/* @__PURE__ */ jsx("div", { className: "h-24 rounded-md animate-pulse", style: { background: "hsl(var(--ra-muted))" } })
|
|
9328
|
+
] });
|
|
9329
|
+
}
|
|
9266
9330
|
const previewAnchorRef = previewReopenAnchorRef;
|
|
9267
9331
|
const previewBody = renderPreview && effectivePreviewScope ? renderPreview({ resolved: editorCtx.value, previewScope: effectivePreviewScope }) : null;
|
|
9268
9332
|
const scopePicker = previewScopePicker && effectivePreviewScope ? /* @__PURE__ */ jsx(
|
|
@@ -9314,7 +9378,7 @@ function RecordsAdminShellInner(props) {
|
|
|
9314
9378
|
]
|
|
9315
9379
|
}
|
|
9316
9380
|
) : null;
|
|
9317
|
-
const selectedSummary = selectedRecordId && selectedRecordId !== DRAFT_ID3 ? recordList.items.find((r) => r.id === selectedRecordId) ?? globalScopedList.items.find((r) => r.id === selectedRecordId) ?? ruleScopedList.items.find((r) => r.id === selectedRecordId) : void 0;
|
|
9381
|
+
const selectedSummary = selectedRecordId && selectedRecordId !== DRAFT_ID3 ? recordList.items.find((r) => r.id === selectedRecordId) ?? globalScopedList.items.find((r) => r.id === selectedRecordId) ?? ruleScopedList.items.find((r) => r.id === selectedRecordId) ?? collectionItems.items.find((r) => r.id === selectedRecordId) : isCollection && selectedItemId && !isDraftId3(selectedItemId) ? collectionItems.items.find((r) => r.id === selectedItemId) : void 0;
|
|
9318
9382
|
const editorLifecycleControl = selectedSummary?.id ? /* @__PURE__ */ jsx(
|
|
9319
9383
|
LifecycleStatusControl,
|
|
9320
9384
|
{
|
|
@@ -9324,8 +9388,13 @@ function RecordsAdminShellInner(props) {
|
|
|
9324
9388
|
recordId: selectedSummary.id,
|
|
9325
9389
|
current: selectedSummary.lifecycleStatus,
|
|
9326
9390
|
i18n,
|
|
9327
|
-
onChanged: () => {
|
|
9328
|
-
|
|
9391
|
+
onChanged: (_next, updated) => {
|
|
9392
|
+
if (updated) {
|
|
9393
|
+
patchRecordIntoCaches(queryClient, ctx, updated);
|
|
9394
|
+
queryClient.invalidateQueries({
|
|
9395
|
+
queryKey: scopeCountsQueryKey(ctx.collectionId, ctx.appId, ctx.recordType)
|
|
9396
|
+
});
|
|
9397
|
+
}
|
|
9329
9398
|
}
|
|
9330
9399
|
}
|
|
9331
9400
|
) : null;
|
|
@@ -9348,11 +9417,12 @@ function RecordsAdminShellInner(props) {
|
|
|
9348
9417
|
from: e.from,
|
|
9349
9418
|
to: e.to
|
|
9350
9419
|
}),
|
|
9351
|
-
onChanged: () => {
|
|
9352
|
-
|
|
9353
|
-
|
|
9354
|
-
|
|
9355
|
-
|
|
9420
|
+
onChanged: (_next, updated) => {
|
|
9421
|
+
if (updated) {
|
|
9422
|
+
patchRecordIntoCaches(queryClient, ctx, updated);
|
|
9423
|
+
queryClient.invalidateQueries({
|
|
9424
|
+
queryKey: scopeCountsQueryKey(ctx.collectionId, ctx.appId, ctx.recordType)
|
|
9425
|
+
});
|
|
9356
9426
|
}
|
|
9357
9427
|
}
|
|
9358
9428
|
}
|
|
@@ -9524,7 +9594,7 @@ function RecordsAdminShellInner(props) {
|
|
|
9524
9594
|
}];
|
|
9525
9595
|
}
|
|
9526
9596
|
const configured = scopeCounts.productIds;
|
|
9527
|
-
const all = productBrowse.items.map(productItemToSummary);
|
|
9597
|
+
const all = productBrowse.items.map((p) => productItemToSummary(p, configured));
|
|
9528
9598
|
const isConfigured = (s) => {
|
|
9529
9599
|
const pid = s.scope.productId;
|
|
9530
9600
|
return !!pid && configured.has(pid);
|
|
@@ -10123,6 +10193,8 @@ function RecordsAdminShellInner(props) {
|
|
|
10123
10193
|
onLoadMore: () => {
|
|
10124
10194
|
void collectionItems.fetchNextPage();
|
|
10125
10195
|
},
|
|
10196
|
+
rowClipboard,
|
|
10197
|
+
rowActions: wrappedRecordActions,
|
|
10126
10198
|
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,
|
|
10127
10199
|
contextSummary: isLifecycleRailEarly && lifecycleBucketLabel ? `${scopedCollectionItemsList.length} ${itemNounLabel}${scopedCollectionItemsList.length === 1 ? "" : "s"}` : activeScope === "rule" ? activeRuleSummary : activeScope === "product" ? editorHeaderLabel ?? null : null,
|
|
10128
10200
|
i18n
|
|
@@ -10274,7 +10346,8 @@ function RecordsAdminShellInner(props) {
|
|
|
10274
10346
|
const ids = singletonConflicts.flatMap((c) => c.duplicates.map((d) => d.id)).filter((id) => !!id);
|
|
10275
10347
|
for (const id of ids) {
|
|
10276
10348
|
try {
|
|
10277
|
-
await SL.app.records.update(collectionId, appId, id, { status: archivedStatusValue }, true);
|
|
10349
|
+
const updated = await SL.app.records.update(collectionId, appId, id, { status: archivedStatusValue }, true);
|
|
10350
|
+
if (updated) patchRecordIntoCaches(queryClient, ctx, updated);
|
|
10278
10351
|
onTelemetry?.({
|
|
10279
10352
|
type: "recordAction.invoke",
|
|
10280
10353
|
recordType,
|
|
@@ -10285,17 +10358,16 @@ function RecordsAdminShellInner(props) {
|
|
|
10285
10358
|
console.warn("[RecordsAdminShell] archive-duplicate failed", id, err);
|
|
10286
10359
|
}
|
|
10287
10360
|
}
|
|
10288
|
-
|
|
10289
|
-
|
|
10290
|
-
|
|
10291
|
-
}
|
|
10292
|
-
await refetchAll();
|
|
10361
|
+
queryClient.invalidateQueries({
|
|
10362
|
+
queryKey: scopeCountsQueryKey(ctx.collectionId, ctx.appId, ctx.recordType)
|
|
10363
|
+
});
|
|
10293
10364
|
} : void 0,
|
|
10294
10365
|
onDeleteDuplicates: enableDeleteDuplicates ? async () => {
|
|
10295
10366
|
const ids = singletonConflicts.flatMap((c) => c.duplicates.map((d) => d.id)).filter((id) => !!id);
|
|
10296
10367
|
for (const id of ids) {
|
|
10297
10368
|
try {
|
|
10298
10369
|
await SL.app.records.remove(collectionId, appId, id, true);
|
|
10370
|
+
removeRecordFromCaches(queryClient, ctx, id);
|
|
10299
10371
|
onTelemetry?.({
|
|
10300
10372
|
type: "recordAction.invoke",
|
|
10301
10373
|
recordType,
|
|
@@ -10306,11 +10378,9 @@ function RecordsAdminShellInner(props) {
|
|
|
10306
10378
|
console.warn("[RecordsAdminShell] delete-duplicate failed", id, err);
|
|
10307
10379
|
}
|
|
10308
10380
|
}
|
|
10309
|
-
|
|
10310
|
-
|
|
10311
|
-
|
|
10312
|
-
}
|
|
10313
|
-
await refetchAll();
|
|
10381
|
+
queryClient.invalidateQueries({
|
|
10382
|
+
queryKey: scopeCountsQueryKey(ctx.collectionId, ctx.appId, ctx.recordType)
|
|
10383
|
+
});
|
|
10314
10384
|
} : void 0,
|
|
10315
10385
|
i18n: {
|
|
10316
10386
|
title: i18n.conflictBannerTitle,
|