@proveanything/smartlinks-utils-ui 0.11.7 → 0.11.9
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 +31 -0
- package/dist/components/AssetPicker/index.css.map +1 -1
- package/dist/components/ConditionsEditor/index.css +31 -0
- package/dist/components/ConditionsEditor/index.css.map +1 -1
- package/dist/components/FontPicker/index.css +31 -0
- package/dist/components/FontPicker/index.css.map +1 -1
- package/dist/components/IconPicker/index.css +31 -0
- package/dist/components/IconPicker/index.css.map +1 -1
- package/dist/components/RecordsAdmin/index.css +31 -0
- package/dist/components/RecordsAdmin/index.css.map +1 -1
- package/dist/components/RecordsAdmin/index.d.ts +28 -0
- package/dist/components/RecordsAdmin/index.js +265 -191
- package/dist/components/RecordsAdmin/index.js.map +1 -1
- package/dist/index.css +31 -0
- package/dist/index.css.map +1 -1
- package/package.json +1 -1
|
@@ -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, Rows3, ChevronRight, Eraser, ClipboardPaste, Box, X, Search, Image, Table, ArrowLeft, ChevronLeft, AlertTriangle, Info, HelpCircle, CornerDownLeft, Circle, ArrowUpDown, ArrowUp, ArrowDown, MinusCircle, XCircle, CopyPlus, AlertCircle, Undo2, Save, Loader2, ArrowRight, Globe2, Check, Settings2 } from 'lucide-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, Rows3, ChevronRight, Eraser, FilePlus2, ClipboardPaste, Box, X, Search, Image, Table, ArrowLeft, ChevronLeft, AlertTriangle, Info, HelpCircle, CornerDownLeft, Circle, ArrowUpDown, ArrowUp, ArrowDown, MinusCircle, XCircle, CopyPlus, AlertCircle, Undo2, Save, Loader2, ArrowRight, Globe2, Check, 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';
|
|
@@ -240,6 +240,7 @@ var DEFAULT_I18N = {
|
|
|
240
240
|
pasteWarnContinue: "Continue",
|
|
241
241
|
duplicateAction: "Duplicate",
|
|
242
242
|
duplicateToast: "Duplicated {name}. Review and Save.",
|
|
243
|
+
copyAndNewRuleAction: "Copy and start new rule",
|
|
243
244
|
itemsAllLabel: "All items",
|
|
244
245
|
subtitleEmpty: "Not set",
|
|
245
246
|
subtitleConfigured: "Configured",
|
|
@@ -1527,7 +1528,9 @@ function useShellClipboard(args) {
|
|
|
1527
1528
|
onCopyOverride,
|
|
1528
1529
|
onPasteOverride,
|
|
1529
1530
|
onLeftSelectRef,
|
|
1530
|
-
onCreateItemDraftRef
|
|
1531
|
+
onCreateItemDraftRef,
|
|
1532
|
+
onCreateRuleFromClipboardRef,
|
|
1533
|
+
isRuleTab
|
|
1531
1534
|
} = args;
|
|
1532
1535
|
const clipboard = useRecordClipboard({
|
|
1533
1536
|
appId,
|
|
@@ -1642,7 +1645,17 @@ function useShellClipboard(args) {
|
|
|
1642
1645
|
canCopy: true,
|
|
1643
1646
|
canPaste: !!clipboard.entry && editorPasteCompat?.status !== "denied",
|
|
1644
1647
|
pasteSourceLabel: clipboard.entry?.sourceLabel,
|
|
1645
|
-
pasteWillReplace: resolved.source === "self" && !!clipboard.entry
|
|
1648
|
+
pasteWillReplace: resolved.source === "self" && !!clipboard.entry,
|
|
1649
|
+
// Editor-pane sibling of the row menu's "Copy and start new rule".
|
|
1650
|
+
// Only meaningful in singleton mode on the rules tab — for the rule
|
|
1651
|
+
// record being edited OR the global record (so the admin can spin a
|
|
1652
|
+
// new rule off either in one click).
|
|
1653
|
+
onCopyAndNewRule: !isCollection && !!isRuleTab && !!onCreateRuleFromClipboardRef ? () => {
|
|
1654
|
+
copyCurrent();
|
|
1655
|
+
window.setTimeout(() => {
|
|
1656
|
+
onCreateRuleFromClipboardRef?.current?.();
|
|
1657
|
+
}, 0);
|
|
1658
|
+
} : void 0
|
|
1646
1659
|
} : void 0;
|
|
1647
1660
|
const [pendingPasteTarget, setPendingPasteTarget] = useState(null);
|
|
1648
1661
|
useEffect(() => {
|
|
@@ -1660,6 +1673,7 @@ function useShellClipboard(args) {
|
|
|
1660
1673
|
const summaryHasData = record.data != null;
|
|
1661
1674
|
const sourceParsed = record.scope;
|
|
1662
1675
|
const canDuplicate = summaryHasData && isCollection;
|
|
1676
|
+
const canCopyAndNewRule = summaryHasData && !isCollection && !!isRuleTab && !!onCreateRuleFromClipboardRef;
|
|
1663
1677
|
return {
|
|
1664
1678
|
onCopy: summaryHasData ? () => {
|
|
1665
1679
|
const value = onCopyOverride ? onCopyOverride({ value: record.data, scope: sourceParsed }) : cloneValue(record.data);
|
|
@@ -1675,6 +1689,19 @@ function useShellClipboard(args) {
|
|
|
1675
1689
|
variant: "copy"
|
|
1676
1690
|
});
|
|
1677
1691
|
} : void 0,
|
|
1692
|
+
onCopyAndNewRule: canCopyAndNewRule ? () => {
|
|
1693
|
+
const value = onCopyOverride ? onCopyOverride({ value: record.data, scope: sourceParsed }) : cloneValue(record.data);
|
|
1694
|
+
clipboard.set({
|
|
1695
|
+
value,
|
|
1696
|
+
sourceScope: sourceParsed,
|
|
1697
|
+
sourceRecordId: record.id ?? void 0,
|
|
1698
|
+
sourceLabel: record.label
|
|
1699
|
+
});
|
|
1700
|
+
onTelemetry?.({ type: "clipboard.copy", recordType, sourceRef: anchorKey(record.scope) });
|
|
1701
|
+
window.setTimeout(() => {
|
|
1702
|
+
onCreateRuleFromClipboardRef?.current?.();
|
|
1703
|
+
}, 0);
|
|
1704
|
+
} : void 0,
|
|
1678
1705
|
onDuplicate: canDuplicate ? () => {
|
|
1679
1706
|
const value = onCopyOverride ? onCopyOverride({ value: record.data, scope: sourceParsed }) : cloneValue(record.data);
|
|
1680
1707
|
clipboard.set({
|
|
@@ -2911,9 +2938,10 @@ function useEditorBridge(args) {
|
|
|
2911
2938
|
if (isEqualSpec(target, lastTargetRef.current)) return;
|
|
2912
2939
|
lastTargetRef.current = target;
|
|
2913
2940
|
const isCreate = !!target.createMode;
|
|
2941
|
+
const prefersExplicitInitialData = !target?.createMode && !target?.recordId && target?.initialData !== void 0;
|
|
2914
2942
|
const id = selection.selectTarget({
|
|
2915
2943
|
spec: target,
|
|
2916
|
-
seed: isCreate || resolved.source === "empty" ? void 0 : {
|
|
2944
|
+
seed: isCreate || prefersExplicitInitialData || resolved.source === "empty" ? void 0 : {
|
|
2917
2945
|
value: resolved.data ?? (defaultData?.() ?? null),
|
|
2918
2946
|
facetRule: resolved.facetRule ?? null,
|
|
2919
2947
|
source: resolved.source,
|
|
@@ -2929,6 +2957,7 @@ function useEditorBridge(args) {
|
|
|
2929
2957
|
if (!id) return;
|
|
2930
2958
|
if (resolved.source === "empty" && !resolved.recordId) return;
|
|
2931
2959
|
if (target?.createMode) return;
|
|
2960
|
+
if (!target?.recordId && target?.initialData !== void 0) return;
|
|
2932
2961
|
selection.hydrate(id, resolved);
|
|
2933
2962
|
}, [resolved.source, resolved.recordId, resolved.sourceRef, resolved.data, resolved.facetRule, target?.createMode]);
|
|
2934
2963
|
const editorId = selection.currentEditorId ?? editorIdRef.current;
|
|
@@ -3009,6 +3038,7 @@ function useShellEditorTarget(args) {
|
|
|
3009
3038
|
ruleWizardStep,
|
|
3010
3039
|
ruleWizardDraftKey,
|
|
3011
3040
|
ruleWizardInitialData,
|
|
3041
|
+
explicitSingletonInitialData,
|
|
3012
3042
|
ruleWizardRule,
|
|
3013
3043
|
resolved,
|
|
3014
3044
|
defaultData,
|
|
@@ -3022,7 +3052,8 @@ function useShellEditorTarget(args) {
|
|
|
3022
3052
|
const label = deriveDraftLabel ? deriveDraftLabel(resolved.data, editingTargetScope) : void 0;
|
|
3023
3053
|
const rawScope = editingTargetScope.raw ?? "";
|
|
3024
3054
|
const isDraftScope = rawScope.includes("__draft__") || rawScope.includes("item:draft:");
|
|
3025
|
-
const
|
|
3055
|
+
const explicitSingletonDraft = !isCollection && activeScope === "product" && draftKind !== null;
|
|
3056
|
+
const draftKey = isDraftScope ? isCollection && selectedItemId && isDraftId2(selectedItemId) ? `item:${selectedItemId}` : ruleWizardDraftKey ?? `${activeScope}:${draftKind ?? "wizard"}` : explicitSingletonDraft ? `singleton:${editingTargetScope.raw}:${draftKind}` : void 0;
|
|
3026
3057
|
const itemDraftCreate = isCollection && !!selectedItemId && isDraftId2(selectedItemId);
|
|
3027
3058
|
const createMode = itemDraftCreate || isDraftScope || isCollection && !!selectedItemId && !resolved.recordId;
|
|
3028
3059
|
return {
|
|
@@ -3031,7 +3062,7 @@ function useShellEditorTarget(args) {
|
|
|
3031
3062
|
// otherwise the store's findExistingEditorIdFor would match the rule's
|
|
3032
3063
|
// editor, focus it instead of minting a new draft, and the next save
|
|
3033
3064
|
// would update the rule record in place.
|
|
3034
|
-
recordId: createMode ? void 0 : resolved.recordId,
|
|
3065
|
+
recordId: createMode || explicitSingletonDraft ? void 0 : resolved.recordId,
|
|
3035
3066
|
createMode,
|
|
3036
3067
|
// We deliberately do NOT propagate `editingTargetScope.raw` (e.g.
|
|
3037
3068
|
// `rule:<ulid>`) into `spec.ref`. `record.ref` is a host-owned
|
|
@@ -3045,7 +3076,7 @@ function useShellEditorTarget(args) {
|
|
|
3045
3076
|
label,
|
|
3046
3077
|
draftKey,
|
|
3047
3078
|
isDraftScope,
|
|
3048
|
-
initialData: createMode ? ruleWizardInitialData : void 0
|
|
3079
|
+
initialData: createMode ? ruleWizardInitialData : explicitSingletonInitialData ?? void 0
|
|
3049
3080
|
};
|
|
3050
3081
|
}, [
|
|
3051
3082
|
editingTargetScope?.raw,
|
|
@@ -3059,6 +3090,7 @@ function useShellEditorTarget(args) {
|
|
|
3059
3090
|
ruleWizardStep,
|
|
3060
3091
|
ruleWizardDraftKey,
|
|
3061
3092
|
ruleWizardInitialData,
|
|
3093
|
+
explicitSingletonInitialData,
|
|
3062
3094
|
ruleWizardRule
|
|
3063
3095
|
]);
|
|
3064
3096
|
const editorCtx = useEditorBridge({
|
|
@@ -3305,6 +3337,7 @@ var statusToneLabel = (tone) => {
|
|
|
3305
3337
|
var RowContextMenu = ({
|
|
3306
3338
|
onCopy,
|
|
3307
3339
|
onDuplicate,
|
|
3340
|
+
onCopyAndNewRule,
|
|
3308
3341
|
actions,
|
|
3309
3342
|
i18n
|
|
3310
3343
|
}) => {
|
|
@@ -3355,8 +3388,8 @@ var RowContextMenu = ({
|
|
|
3355
3388
|
};
|
|
3356
3389
|
}, [open]);
|
|
3357
3390
|
const hasActions = (actions?.length ?? 0) > 0;
|
|
3358
|
-
if (!onCopy && !onDuplicate && !hasActions) return null;
|
|
3359
|
-
const showDivider = (onCopy || onDuplicate) && hasActions;
|
|
3391
|
+
if (!onCopy && !onDuplicate && !onCopyAndNewRule && !hasActions) return null;
|
|
3392
|
+
const showDivider = (onCopy || onDuplicate || onCopyAndNewRule) && hasActions;
|
|
3360
3393
|
return /* @__PURE__ */ jsxs("div", { ref: wrapperRef, className: "ra-row-menu-wrap relative", children: [
|
|
3361
3394
|
/* @__PURE__ */ jsx(
|
|
3362
3395
|
"button",
|
|
@@ -3419,6 +3452,23 @@ var RowContextMenu = ({
|
|
|
3419
3452
|
]
|
|
3420
3453
|
}
|
|
3421
3454
|
),
|
|
3455
|
+
onCopyAndNewRule && /* @__PURE__ */ jsxs(
|
|
3456
|
+
"button",
|
|
3457
|
+
{
|
|
3458
|
+
type: "button",
|
|
3459
|
+
role: "menuitem",
|
|
3460
|
+
className: "ra-row-menu-item",
|
|
3461
|
+
onClick: (e) => {
|
|
3462
|
+
e.stopPropagation();
|
|
3463
|
+
setOpen(false);
|
|
3464
|
+
onCopyAndNewRule();
|
|
3465
|
+
},
|
|
3466
|
+
children: [
|
|
3467
|
+
/* @__PURE__ */ jsx(FilePlus2, { className: "w-3.5 h-3.5 opacity-70", "aria-hidden": "true" }),
|
|
3468
|
+
/* @__PURE__ */ jsx("span", { children: i18n.copyAndNewRuleAction })
|
|
3469
|
+
]
|
|
3470
|
+
}
|
|
3471
|
+
),
|
|
3422
3472
|
showDivider && /* @__PURE__ */ jsx("div", { className: "ra-row-menu-divider", role: "separator" }),
|
|
3423
3473
|
hasActions && actions.map((action) => {
|
|
3424
3474
|
const Icon = action.icon;
|
|
@@ -3493,7 +3543,7 @@ var RuleLabelLookupProvider = ({
|
|
|
3493
3543
|
return /* @__PURE__ */ jsx(RuleLabelLookupContext.Provider, { value: v, children });
|
|
3494
3544
|
};
|
|
3495
3545
|
var DefaultRecordRow = ({ record, ctx, compact = false }) => {
|
|
3496
|
-
const { selected, onSelect, isDirty, hasError, onCopy, onDuplicate, actions } = ctx;
|
|
3546
|
+
const { selected, onSelect, isDirty, hasError, onCopy, onDuplicate, onCopyAndNewRule, actions } = ctx;
|
|
3497
3547
|
const ruleLabelLookup = useRuleLabelLookup();
|
|
3498
3548
|
const ScopeIcon = record.scope.kind && record.scope.kind !== "collection" ? DEFAULT_ICONS.scope[record.scope.kind] : DEFAULT_ICONS.scope.product;
|
|
3499
3549
|
const tone = resolveTone(void 0, record.status);
|
|
@@ -3567,15 +3617,17 @@ var DefaultRecordRow = ({ record, ctx, compact = false }) => {
|
|
|
3567
3617
|
}
|
|
3568
3618
|
)
|
|
3569
3619
|
] }),
|
|
3570
|
-
(onCopy || onDuplicate || actions && actions.length > 0) && /* @__PURE__ */ jsx(
|
|
3620
|
+
(onCopy || onDuplicate || onCopyAndNewRule || actions && actions.length > 0) && /* @__PURE__ */ jsx(
|
|
3571
3621
|
RowContextMenu,
|
|
3572
3622
|
{
|
|
3573
3623
|
onCopy,
|
|
3574
3624
|
onDuplicate,
|
|
3625
|
+
onCopyAndNewRule,
|
|
3575
3626
|
actions,
|
|
3576
3627
|
i18n: {
|
|
3577
3628
|
copy: DEFAULT_I18N.copy,
|
|
3578
|
-
duplicateAction: DEFAULT_I18N.duplicateAction
|
|
3629
|
+
duplicateAction: DEFAULT_I18N.duplicateAction,
|
|
3630
|
+
copyAndNewRuleAction: DEFAULT_I18N.copyAndNewRuleAction
|
|
3579
3631
|
}
|
|
3580
3632
|
}
|
|
3581
3633
|
)
|
|
@@ -4623,6 +4675,22 @@ function RecordEditor({
|
|
|
4623
4675
|
]
|
|
4624
4676
|
}
|
|
4625
4677
|
),
|
|
4678
|
+
clipboard.onCopyAndNewRule && /* @__PURE__ */ jsxs(
|
|
4679
|
+
"button",
|
|
4680
|
+
{
|
|
4681
|
+
type: "button",
|
|
4682
|
+
onClick: clipboard.onCopyAndNewRule,
|
|
4683
|
+
disabled: !clipboard.canCopy || !!ctx.isSaving,
|
|
4684
|
+
title: clipboard.copyAndNewRuleLabel ?? i18n.copyAndNewRuleAction ?? "Copy and start new rule",
|
|
4685
|
+
"aria-label": clipboard.copyAndNewRuleLabel ?? i18n.copyAndNewRuleAction ?? "Copy and start new rule",
|
|
4686
|
+
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",
|
|
4687
|
+
style: { borderColor: "hsl(var(--ra-border))", color: "hsl(var(--ra-text))" },
|
|
4688
|
+
children: [
|
|
4689
|
+
/* @__PURE__ */ jsx(FilePlus2, { className: "w-3 h-3" }),
|
|
4690
|
+
clipboard.copyAndNewRuleLabel ?? i18n.copyAndNewRuleAction ?? "Copy and start new rule"
|
|
4691
|
+
]
|
|
4692
|
+
}
|
|
4693
|
+
),
|
|
4626
4694
|
/* @__PURE__ */ jsxs(
|
|
4627
4695
|
"button",
|
|
4628
4696
|
{
|
|
@@ -5782,7 +5850,7 @@ function DefaultItemTable({
|
|
|
5782
5850
|
const extra = rowActions ? rowActions(item) ?? void 0 : void 0;
|
|
5783
5851
|
const cb = rowClipboard ? rowClipboard(item) : null;
|
|
5784
5852
|
const hasExtras = !!(extra && extra.length > 0);
|
|
5785
|
-
if (!cb?.onCopy && !cb?.onDuplicate && !hasExtras) return null;
|
|
5853
|
+
if (!cb?.onCopy && !cb?.onDuplicate && !cb?.onCopyAndNewRule && !hasExtras) return null;
|
|
5786
5854
|
return /* @__PURE__ */ jsx(
|
|
5787
5855
|
"span",
|
|
5788
5856
|
{
|
|
@@ -5793,10 +5861,12 @@ function DefaultItemTable({
|
|
|
5793
5861
|
{
|
|
5794
5862
|
onCopy: cb?.onCopy,
|
|
5795
5863
|
onDuplicate: cb?.onDuplicate,
|
|
5864
|
+
onCopyAndNewRule: cb?.onCopyAndNewRule,
|
|
5796
5865
|
actions: extra ?? void 0,
|
|
5797
5866
|
i18n: {
|
|
5798
5867
|
copy: DEFAULT_I18N.copy,
|
|
5799
|
-
duplicateAction: DEFAULT_I18N.duplicateAction
|
|
5868
|
+
duplicateAction: DEFAULT_I18N.duplicateAction,
|
|
5869
|
+
copyAndNewRuleAction: DEFAULT_I18N.copyAndNewRuleAction
|
|
5800
5870
|
}
|
|
5801
5871
|
}
|
|
5802
5872
|
)
|
|
@@ -5926,7 +5996,7 @@ function DefaultItemCards({
|
|
|
5926
5996
|
/* @__PURE__ */ jsx("div", { className: "ra-item-card-title", children: item.label }),
|
|
5927
5997
|
item.subtitle && /* @__PURE__ */ jsx("div", { className: "ra-item-card-sub", children: item.subtitle })
|
|
5928
5998
|
] }),
|
|
5929
|
-
(cb?.onCopy || cb?.onDuplicate || extraActions && extraActions.length > 0) && /* @__PURE__ */ jsx(
|
|
5999
|
+
(cb?.onCopy || cb?.onDuplicate || cb?.onCopyAndNewRule || extraActions && extraActions.length > 0) && /* @__PURE__ */ jsx(
|
|
5930
6000
|
"span",
|
|
5931
6001
|
{
|
|
5932
6002
|
className: "ra-item-card-menu",
|
|
@@ -5937,10 +6007,12 @@ function DefaultItemCards({
|
|
|
5937
6007
|
{
|
|
5938
6008
|
onCopy: cb?.onCopy,
|
|
5939
6009
|
onDuplicate: cb?.onDuplicate,
|
|
6010
|
+
onCopyAndNewRule: cb?.onCopyAndNewRule,
|
|
5940
6011
|
actions: extraActions,
|
|
5941
6012
|
i18n: {
|
|
5942
6013
|
copy: DEFAULT_I18N.copy,
|
|
5943
|
-
duplicateAction: DEFAULT_I18N.duplicateAction
|
|
6014
|
+
duplicateAction: DEFAULT_I18N.duplicateAction,
|
|
6015
|
+
copyAndNewRuleAction: DEFAULT_I18N.copyAndNewRuleAction
|
|
5944
6016
|
}
|
|
5945
6017
|
}
|
|
5946
6018
|
)
|
|
@@ -6591,18 +6663,12 @@ function NewRuleWizard({
|
|
|
6591
6663
|
onCancel,
|
|
6592
6664
|
onNext,
|
|
6593
6665
|
onBack,
|
|
6594
|
-
canChooseSeed = false,
|
|
6595
|
-
seedMode = null,
|
|
6596
|
-
onSeedModeChange,
|
|
6597
|
-
pasteSourceLabel,
|
|
6598
6666
|
facets,
|
|
6599
6667
|
children,
|
|
6600
|
-
itemNoun = "record"
|
|
6601
|
-
seedPromptMode = "inline"
|
|
6668
|
+
itemNoun = "record"
|
|
6602
6669
|
}) {
|
|
6603
6670
|
const preview = useRulePreview({ SL, collectionId, appId, rule });
|
|
6604
6671
|
const canProceed = isFacetRuleValid(rule);
|
|
6605
|
-
const showSeedPicker = (canChooseSeed || pasteSourceLabel) && seedPromptMode === "inline";
|
|
6606
6672
|
if (step === 1) {
|
|
6607
6673
|
return /* @__PURE__ */ jsxs("div", { className: "flex h-full flex-col overflow-hidden", children: [
|
|
6608
6674
|
/* @__PURE__ */ jsx(
|
|
@@ -6615,68 +6681,17 @@ function NewRuleWizard({
|
|
|
6615
6681
|
onCancel
|
|
6616
6682
|
}
|
|
6617
6683
|
),
|
|
6618
|
-
/* @__PURE__ */
|
|
6619
|
-
|
|
6620
|
-
|
|
6621
|
-
|
|
6622
|
-
|
|
6623
|
-
|
|
6624
|
-
|
|
6625
|
-
|
|
6626
|
-
|
|
6627
|
-
|
|
6628
|
-
|
|
6629
|
-
),
|
|
6630
|
-
showSeedPicker && /* @__PURE__ */ jsxs(
|
|
6631
|
-
"div",
|
|
6632
|
-
{
|
|
6633
|
-
className: "mt-4 rounded-lg border p-3",
|
|
6634
|
-
style: {
|
|
6635
|
-
borderColor: "hsl(var(--ra-border))",
|
|
6636
|
-
background: "hsl(var(--ra-surface))"
|
|
6637
|
-
},
|
|
6638
|
-
children: [
|
|
6639
|
-
/* @__PURE__ */ jsxs("div", { className: "mb-2", children: [
|
|
6640
|
-
/* @__PURE__ */ jsx("div", { className: "text-sm font-semibold", style: { color: "hsl(var(--ra-text))" }, children: "Start from" }),
|
|
6641
|
-
/* @__PURE__ */ jsx("div", { className: "text-xs", style: { color: "hsl(var(--ra-muted-text))" }, children: "Choose whether the new rule starts empty, copies the current global record, or pastes from your clipboard." })
|
|
6642
|
-
] }),
|
|
6643
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-2", children: [
|
|
6644
|
-
/* @__PURE__ */ jsx(
|
|
6645
|
-
"button",
|
|
6646
|
-
{
|
|
6647
|
-
type: "button",
|
|
6648
|
-
className: "ra-btn",
|
|
6649
|
-
"data-variant": seedMode === "blank" || seedMode == null ? "primary" : "ghost",
|
|
6650
|
-
onClick: () => onSeedModeChange?.("blank"),
|
|
6651
|
-
children: "Start blank"
|
|
6652
|
-
}
|
|
6653
|
-
),
|
|
6654
|
-
canChooseSeed && /* @__PURE__ */ jsx(
|
|
6655
|
-
"button",
|
|
6656
|
-
{
|
|
6657
|
-
type: "button",
|
|
6658
|
-
className: "ra-btn",
|
|
6659
|
-
"data-variant": seedMode === "global" ? "primary" : "ghost",
|
|
6660
|
-
onClick: () => onSeedModeChange?.("global"),
|
|
6661
|
-
children: "Copy from global"
|
|
6662
|
-
}
|
|
6663
|
-
),
|
|
6664
|
-
pasteSourceLabel && /* @__PURE__ */ jsx(
|
|
6665
|
-
"button",
|
|
6666
|
-
{
|
|
6667
|
-
type: "button",
|
|
6668
|
-
className: "ra-btn",
|
|
6669
|
-
"data-variant": seedMode === "paste" ? "primary" : "ghost",
|
|
6670
|
-
onClick: () => onSeedModeChange?.("paste"),
|
|
6671
|
-
title: `Paste from ${pasteSourceLabel}`,
|
|
6672
|
-
children: "Paste from clipboard"
|
|
6673
|
-
}
|
|
6674
|
-
)
|
|
6675
|
-
] })
|
|
6676
|
-
]
|
|
6677
|
-
}
|
|
6678
|
-
)
|
|
6679
|
-
] }),
|
|
6684
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1 min-h-0 overflow-auto px-5 py-4", children: /* @__PURE__ */ jsx(
|
|
6685
|
+
FacetRuleEditor,
|
|
6686
|
+
{
|
|
6687
|
+
value: rule,
|
|
6688
|
+
onChange: onRuleChange,
|
|
6689
|
+
facets,
|
|
6690
|
+
collectionId,
|
|
6691
|
+
preview,
|
|
6692
|
+
description: "The new rule will apply to every product whose facets match every clause below."
|
|
6693
|
+
}
|
|
6694
|
+
) }),
|
|
6680
6695
|
/* @__PURE__ */ jsx(
|
|
6681
6696
|
WizardFooter,
|
|
6682
6697
|
{
|
|
@@ -6832,6 +6847,78 @@ function WizardFooter({
|
|
|
6832
6847
|
}
|
|
6833
6848
|
);
|
|
6834
6849
|
}
|
|
6850
|
+
function CreateRecordChooser({
|
|
6851
|
+
title,
|
|
6852
|
+
body,
|
|
6853
|
+
primaryLabel,
|
|
6854
|
+
onPrimary,
|
|
6855
|
+
secondaryLabel,
|
|
6856
|
+
onSecondary,
|
|
6857
|
+
tertiaryLabel,
|
|
6858
|
+
onTertiary
|
|
6859
|
+
}) {
|
|
6860
|
+
return /* @__PURE__ */ jsx("div", { className: "h-full flex items-center justify-center px-6 py-10", children: /* @__PURE__ */ jsxs("div", { className: "max-w-xl w-full text-center space-y-4", children: [
|
|
6861
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
6862
|
+
/* @__PURE__ */ jsx(
|
|
6863
|
+
"h3",
|
|
6864
|
+
{
|
|
6865
|
+
className: "text-base font-semibold m-0",
|
|
6866
|
+
style: { color: "hsl(var(--ra-text))" },
|
|
6867
|
+
children: title
|
|
6868
|
+
}
|
|
6869
|
+
),
|
|
6870
|
+
/* @__PURE__ */ jsx(
|
|
6871
|
+
"p",
|
|
6872
|
+
{
|
|
6873
|
+
className: "text-sm m-0",
|
|
6874
|
+
style: { color: "hsl(var(--ra-muted-text))" },
|
|
6875
|
+
children: body
|
|
6876
|
+
}
|
|
6877
|
+
)
|
|
6878
|
+
] }),
|
|
6879
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center justify-center gap-2", children: [
|
|
6880
|
+
/* @__PURE__ */ jsxs(
|
|
6881
|
+
"button",
|
|
6882
|
+
{
|
|
6883
|
+
type: "button",
|
|
6884
|
+
onClick: onPrimary,
|
|
6885
|
+
className: "ra-btn",
|
|
6886
|
+
"data-variant": "primary",
|
|
6887
|
+
children: [
|
|
6888
|
+
/* @__PURE__ */ jsx(FilePlus2, { "aria-hidden": "true", className: "w-4 h-4" }),
|
|
6889
|
+
/* @__PURE__ */ jsx("span", { children: primaryLabel })
|
|
6890
|
+
]
|
|
6891
|
+
}
|
|
6892
|
+
),
|
|
6893
|
+
secondaryLabel && onSecondary && /* @__PURE__ */ jsxs(
|
|
6894
|
+
"button",
|
|
6895
|
+
{
|
|
6896
|
+
type: "button",
|
|
6897
|
+
onClick: onSecondary,
|
|
6898
|
+
className: "ra-btn",
|
|
6899
|
+
"data-variant": "ghost",
|
|
6900
|
+
children: [
|
|
6901
|
+
/* @__PURE__ */ jsx(Copy, { "aria-hidden": "true", className: "w-4 h-4" }),
|
|
6902
|
+
/* @__PURE__ */ jsx("span", { children: secondaryLabel })
|
|
6903
|
+
]
|
|
6904
|
+
}
|
|
6905
|
+
),
|
|
6906
|
+
tertiaryLabel && onTertiary && /* @__PURE__ */ jsxs(
|
|
6907
|
+
"button",
|
|
6908
|
+
{
|
|
6909
|
+
type: "button",
|
|
6910
|
+
onClick: onTertiary,
|
|
6911
|
+
className: "ra-btn",
|
|
6912
|
+
"data-variant": "ghost",
|
|
6913
|
+
children: [
|
|
6914
|
+
/* @__PURE__ */ jsx(Copy, { "aria-hidden": "true", className: "w-4 h-4" }),
|
|
6915
|
+
/* @__PURE__ */ jsx("span", { children: tertiaryLabel })
|
|
6916
|
+
]
|
|
6917
|
+
}
|
|
6918
|
+
)
|
|
6919
|
+
] })
|
|
6920
|
+
] }) });
|
|
6921
|
+
}
|
|
6835
6922
|
var RuleGroupEditDialog = ({
|
|
6836
6923
|
open,
|
|
6837
6924
|
ctx,
|
|
@@ -8200,6 +8287,33 @@ function RecordsAdminShellInner(props) {
|
|
|
8200
8287
|
}
|
|
8201
8288
|
return void 0;
|
|
8202
8289
|
}, [ruleWizardSeedMode, globalSourceRecord, directGlobalSeedData, resolvedGlobalSeed.data, onCopyOverride, defaultData, wizardClipboard.entry]);
|
|
8290
|
+
const explicitSingletonInitialData = useMemo(() => {
|
|
8291
|
+
if (isCollection || activeScope !== "product" || selectedRecordId !== DRAFT_ID3) return void 0;
|
|
8292
|
+
if (draftKind === "global") {
|
|
8293
|
+
const globalSeedSource = globalSourceRecord?.data ?? directGlobalSeedData ?? resolvedGlobalSeed.data;
|
|
8294
|
+
if (!globalSeedSource) return defaultData?.();
|
|
8295
|
+
const globalSeedScope = globalSourceRecord?.scope ?? parseRef("");
|
|
8296
|
+
if (onCopyOverride) {
|
|
8297
|
+
return onCopyOverride({ value: globalSeedSource, scope: globalSeedScope });
|
|
8298
|
+
}
|
|
8299
|
+
try {
|
|
8300
|
+
return structuredClone(globalSeedSource);
|
|
8301
|
+
} catch {
|
|
8302
|
+
return JSON.parse(JSON.stringify(globalSeedSource));
|
|
8303
|
+
}
|
|
8304
|
+
}
|
|
8305
|
+
return defaultData?.() ?? {};
|
|
8306
|
+
}, [
|
|
8307
|
+
isCollection,
|
|
8308
|
+
activeScope,
|
|
8309
|
+
selectedRecordId,
|
|
8310
|
+
draftKind,
|
|
8311
|
+
globalSourceRecord,
|
|
8312
|
+
directGlobalSeedData,
|
|
8313
|
+
resolvedGlobalSeed.data,
|
|
8314
|
+
onCopyOverride,
|
|
8315
|
+
defaultData
|
|
8316
|
+
]);
|
|
8203
8317
|
const refetchAll = useCallback(async () => {
|
|
8204
8318
|
await Promise.all([
|
|
8205
8319
|
recordList.refetch(),
|
|
@@ -8218,6 +8332,7 @@ function RecordsAdminShellInner(props) {
|
|
|
8218
8332
|
ruleWizardStep,
|
|
8219
8333
|
ruleWizardDraftKey,
|
|
8220
8334
|
ruleWizardInitialData,
|
|
8335
|
+
explicitSingletonInitialData,
|
|
8221
8336
|
ruleWizardRule,
|
|
8222
8337
|
resolved: {
|
|
8223
8338
|
data: resolved.data,
|
|
@@ -8341,6 +8456,7 @@ function RecordsAdminShellInner(props) {
|
|
|
8341
8456
|
]);
|
|
8342
8457
|
const onLeftSelectRef = useRef(null);
|
|
8343
8458
|
const onCreateItemDraftRef = useRef(null);
|
|
8459
|
+
const onCreateRuleFromClipboardRef = useRef(null);
|
|
8344
8460
|
const previewReopenAnchorRef = useRef(null);
|
|
8345
8461
|
const { runWithGuard } = useDirtyNavigation({
|
|
8346
8462
|
strategy: dirtyStrategy,
|
|
@@ -8397,7 +8513,9 @@ function RecordsAdminShellInner(props) {
|
|
|
8397
8513
|
onCopyOverride,
|
|
8398
8514
|
onPasteOverride,
|
|
8399
8515
|
onLeftSelectRef,
|
|
8400
|
-
onCreateItemDraftRef
|
|
8516
|
+
onCreateItemDraftRef,
|
|
8517
|
+
onCreateRuleFromClipboardRef,
|
|
8518
|
+
isRuleTab: activeScope === "rule" || activeScope === "collection"
|
|
8401
8519
|
});
|
|
8402
8520
|
const editorClipboard = shellClipboard.editorClipboard;
|
|
8403
8521
|
const rowClipboard = shellClipboard.rowClipboard;
|
|
@@ -8767,7 +8885,7 @@ function RecordsAdminShellInner(props) {
|
|
|
8767
8885
|
setSelectedRecordId(null);
|
|
8768
8886
|
setSelectedItemId(null);
|
|
8769
8887
|
setDraftKind("rule");
|
|
8770
|
-
setRuleWizardSeedMode(seed ??
|
|
8888
|
+
setRuleWizardSeedMode(seed ?? null);
|
|
8771
8889
|
setRuleWizardDraftKey(null);
|
|
8772
8890
|
setRuleWizardRule({ all: [] });
|
|
8773
8891
|
setRuleWizardStep(1);
|
|
@@ -8787,19 +8905,20 @@ function RecordsAdminShellInner(props) {
|
|
|
8787
8905
|
setRuleWizardStep(2);
|
|
8788
8906
|
} else {
|
|
8789
8907
|
setRuleWizardStep(2);
|
|
8790
|
-
if (ruleWizardSeedMode == null) {
|
|
8791
|
-
setRuleWizardSeedMode(singletonGlobalSeedAvailable ? "global" : "blank");
|
|
8792
|
-
}
|
|
8793
|
-
setRuleWizardDraftKey(mintRuleWizardDraftKey());
|
|
8794
|
-
setSelectedRecordId(DRAFT_ID3);
|
|
8795
8908
|
}
|
|
8796
|
-
}, [cardinality
|
|
8909
|
+
}, [cardinality]);
|
|
8910
|
+
const startRuleWizardDraft = useCallback((seed) => {
|
|
8911
|
+
setRuleWizardSeedMode(seed);
|
|
8912
|
+
setRuleWizardDraftKey(mintRuleWizardDraftKey());
|
|
8913
|
+
setSelectedRecordId(DRAFT_ID3);
|
|
8914
|
+
}, [mintRuleWizardDraftKey]);
|
|
8797
8915
|
const onRuleWizardBack = useCallback(() => {
|
|
8798
8916
|
setRuleWizardStep(1);
|
|
8799
8917
|
setRuleWizardDraftKey(null);
|
|
8918
|
+
setRuleWizardSeedMode(null);
|
|
8800
8919
|
setSelectedRecordId(null);
|
|
8801
8920
|
setSelectedItemId(null);
|
|
8802
|
-
}, [setRuleWizardDraftKey]);
|
|
8921
|
+
}, [setRuleWizardDraftKey, setRuleWizardSeedMode]);
|
|
8803
8922
|
const onRuleWizardCreateItem = useCallback(() => {
|
|
8804
8923
|
if (!isCollection) return;
|
|
8805
8924
|
const id = coerceDraftItemId2(generateItemId);
|
|
@@ -8817,6 +8936,13 @@ function RecordsAdminShellInner(props) {
|
|
|
8817
8936
|
setDraftKind("global");
|
|
8818
8937
|
});
|
|
8819
8938
|
}, [runWithGuard, activeScope]);
|
|
8939
|
+
const onCreateProductRecord = useCallback((seed) => {
|
|
8940
|
+
void runWithGuard(() => {
|
|
8941
|
+
if (activeScope !== "product") setActiveScope("product");
|
|
8942
|
+
setSelectedRecordId(DRAFT_ID3);
|
|
8943
|
+
setDraftKind(seed === "global" ? "global" : "item");
|
|
8944
|
+
});
|
|
8945
|
+
}, [runWithGuard, activeScope]);
|
|
8820
8946
|
const filteredRuleItems = useMemo(
|
|
8821
8947
|
() => isRuleTab ? applyRuleFilters(recordList.items, ruleFilters) : recordList.items,
|
|
8822
8948
|
[isRuleTab, recordList.items, ruleFilters]
|
|
@@ -9018,6 +9144,7 @@ function RecordsAdminShellInner(props) {
|
|
|
9018
9144
|
};
|
|
9019
9145
|
onLeftSelectRef.current = onLeftSelect;
|
|
9020
9146
|
onCreateItemDraftRef.current = onItemCreate;
|
|
9147
|
+
onCreateRuleFromClipboardRef.current = () => onCreateRule("paste");
|
|
9021
9148
|
return /* @__PURE__ */ jsx(RuleLabelLookupProvider, { value: ruleLabelLookup, children: /* @__PURE__ */ jsxs(
|
|
9022
9149
|
"div",
|
|
9023
9150
|
{
|
|
@@ -9239,37 +9366,20 @@ function RecordsAdminShellInner(props) {
|
|
|
9239
9366
|
}
|
|
9240
9367
|
) }),
|
|
9241
9368
|
/* @__PURE__ */ jsxs("div", { className: "p-3 space-y-2.5 border-b", style: { borderColor: "hsl(var(--ra-border))" }, children: [
|
|
9242
|
-
isRuleTab && /* @__PURE__ */
|
|
9243
|
-
|
|
9244
|
-
|
|
9245
|
-
|
|
9246
|
-
|
|
9247
|
-
|
|
9248
|
-
|
|
9249
|
-
|
|
9250
|
-
|
|
9251
|
-
|
|
9252
|
-
|
|
9253
|
-
|
|
9254
|
-
|
|
9255
|
-
|
|
9256
|
-
),
|
|
9257
|
-
wizardClipboard.entry && /* @__PURE__ */ jsxs(
|
|
9258
|
-
"button",
|
|
9259
|
-
{
|
|
9260
|
-
type: "button",
|
|
9261
|
-
onClick: () => onCreateRule("paste"),
|
|
9262
|
-
className: "ra-btn w-full",
|
|
9263
|
-
"data-variant": "ghost",
|
|
9264
|
-
"aria-label": "Paste as new rule",
|
|
9265
|
-
title: wizardClipboard.entry.sourceLabel ? `Paste from ${wizardClipboard.entry.sourceLabel}` : "Paste from clipboard",
|
|
9266
|
-
children: [
|
|
9267
|
-
/* @__PURE__ */ jsx(ClipboardPaste, { className: "w-3.5 h-3.5", "aria-hidden": "true" }),
|
|
9268
|
-
/* @__PURE__ */ jsx("span", { children: "Paste as new rule" })
|
|
9269
|
-
]
|
|
9270
|
-
}
|
|
9271
|
-
)
|
|
9272
|
-
] }),
|
|
9369
|
+
isRuleTab && /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-1.5", children: /* @__PURE__ */ jsxs(
|
|
9370
|
+
"button",
|
|
9371
|
+
{
|
|
9372
|
+
type: "button",
|
|
9373
|
+
onClick: () => onCreateRule(),
|
|
9374
|
+
className: "ra-btn w-full",
|
|
9375
|
+
"data-variant": "primary",
|
|
9376
|
+
"aria-label": "New rule",
|
|
9377
|
+
children: [
|
|
9378
|
+
/* @__PURE__ */ jsx(Plus, { className: "w-3.5 h-3.5", "aria-hidden": "true" }),
|
|
9379
|
+
/* @__PURE__ */ jsx("span", { children: "New rule" })
|
|
9380
|
+
]
|
|
9381
|
+
}
|
|
9382
|
+
) }),
|
|
9273
9383
|
showCreateGlobal && /* @__PURE__ */ jsxs(
|
|
9274
9384
|
"button",
|
|
9275
9385
|
{
|
|
@@ -9419,72 +9529,23 @@ function RecordsAdminShellInner(props) {
|
|
|
9419
9529
|
onCancel: onCancelRuleWizard,
|
|
9420
9530
|
onNext: onRuleWizardNext,
|
|
9421
9531
|
onBack: onRuleWizardBack,
|
|
9422
|
-
canChooseSeed: !isCollection && singletonGlobalSeedAvailable,
|
|
9423
|
-
seedMode: ruleWizardSeedMode,
|
|
9424
|
-
onSeedModeChange: setRuleWizardSeedMode,
|
|
9425
|
-
pasteSourceLabel: wizardClipboard.entry?.sourceLabel ?? (wizardClipboard.entry ? "clipboard" : void 0),
|
|
9426
9532
|
facets: ruleWizardFacets,
|
|
9427
9533
|
itemNoun,
|
|
9428
|
-
seedPromptMode: !isCollection ? "after-next" : "inline",
|
|
9429
9534
|
children: [
|
|
9430
|
-
ruleWizardStep === 2 && !isCollection && /* @__PURE__ */
|
|
9431
|
-
|
|
9432
|
-
|
|
9433
|
-
{
|
|
9434
|
-
|
|
9435
|
-
|
|
9436
|
-
|
|
9437
|
-
|
|
9438
|
-
|
|
9439
|
-
|
|
9440
|
-
|
|
9441
|
-
|
|
9442
|
-
|
|
9443
|
-
|
|
9444
|
-
{
|
|
9445
|
-
type: "button",
|
|
9446
|
-
className: "ra-btn",
|
|
9447
|
-
"data-variant": ruleWizardSeedMode === "blank" || ruleWizardSeedMode == null ? "primary" : "ghost",
|
|
9448
|
-
onClick: () => {
|
|
9449
|
-
setRuleWizardSeedMode("blank");
|
|
9450
|
-
setRuleWizardDraftKey(mintRuleWizardDraftKey());
|
|
9451
|
-
},
|
|
9452
|
-
children: "Start blank"
|
|
9453
|
-
}
|
|
9454
|
-
),
|
|
9455
|
-
singletonGlobalSeedAvailable && /* @__PURE__ */ jsx(
|
|
9456
|
-
"button",
|
|
9457
|
-
{
|
|
9458
|
-
type: "button",
|
|
9459
|
-
className: "ra-btn",
|
|
9460
|
-
"data-variant": ruleWizardSeedMode === "global" ? "primary" : "ghost",
|
|
9461
|
-
onClick: () => {
|
|
9462
|
-
setRuleWizardSeedMode("global");
|
|
9463
|
-
setRuleWizardDraftKey(mintRuleWizardDraftKey());
|
|
9464
|
-
},
|
|
9465
|
-
children: "Copy from global"
|
|
9466
|
-
}
|
|
9467
|
-
),
|
|
9468
|
-
wizardClipboard.entry && /* @__PURE__ */ jsx(
|
|
9469
|
-
"button",
|
|
9470
|
-
{
|
|
9471
|
-
type: "button",
|
|
9472
|
-
className: "ra-btn",
|
|
9473
|
-
"data-variant": ruleWizardSeedMode === "paste" ? "primary" : "ghost",
|
|
9474
|
-
onClick: () => {
|
|
9475
|
-
setRuleWizardSeedMode("paste");
|
|
9476
|
-
setRuleWizardDraftKey(mintRuleWizardDraftKey());
|
|
9477
|
-
},
|
|
9478
|
-
title: wizardClipboard.entry.sourceLabel ? `Paste from ${wizardClipboard.entry.sourceLabel}` : "Paste from clipboard",
|
|
9479
|
-
children: "Paste from clipboard"
|
|
9480
|
-
}
|
|
9481
|
-
)
|
|
9482
|
-
] })
|
|
9483
|
-
]
|
|
9484
|
-
}
|
|
9485
|
-
),
|
|
9486
|
-
/* @__PURE__ */ jsx("div", { className: "min-h-0 flex-1 overflow-hidden", children: editingTargetScope && renderEditorWithPreview() })
|
|
9487
|
-
] }),
|
|
9535
|
+
ruleWizardStep === 2 && !isCollection && !editingTargetScope && /* @__PURE__ */ jsx(
|
|
9536
|
+
CreateRecordChooser,
|
|
9537
|
+
{
|
|
9538
|
+
title: `Create your first ${itemNoun} for this rule`,
|
|
9539
|
+
body: `The rule is set. Now choose how to create the first ${itemNoun} that should apply to every matching product.`,
|
|
9540
|
+
primaryLabel: "Start blank",
|
|
9541
|
+
onPrimary: () => startRuleWizardDraft("blank"),
|
|
9542
|
+
secondaryLabel: singletonGlobalSeedAvailable ? "Copy from global" : void 0,
|
|
9543
|
+
onSecondary: singletonGlobalSeedAvailable ? () => startRuleWizardDraft("global") : void 0,
|
|
9544
|
+
tertiaryLabel: wizardClipboard.entry ? "Paste from clipboard" : void 0,
|
|
9545
|
+
onTertiary: wizardClipboard.entry ? () => startRuleWizardDraft("paste") : void 0
|
|
9546
|
+
}
|
|
9547
|
+
),
|
|
9548
|
+
ruleWizardStep === 2 && !isCollection && !!editingTargetScope && renderEditorWithPreview(),
|
|
9488
9549
|
ruleWizardStep === 2 && isCollection && !selectedItemId && /* @__PURE__ */ jsx("div", { className: "h-full flex items-center justify-center px-6 py-10", children: /* @__PURE__ */ jsxs("div", { className: "max-w-sm text-center space-y-3", children: [
|
|
9489
9550
|
/* @__PURE__ */ jsxs(
|
|
9490
9551
|
"h3",
|
|
@@ -9599,6 +9660,17 @@ function RecordsAdminShellInner(props) {
|
|
|
9599
9660
|
)
|
|
9600
9661
|
}
|
|
9601
9662
|
),
|
|
9663
|
+
ruleWizardStep === null && isProductTab && selectedProductId && !isCollection && editingTargetScope && resolved.source === "empty" && selectedRecordId === null ? /* @__PURE__ */ jsx(
|
|
9664
|
+
CreateRecordChooser,
|
|
9665
|
+
{
|
|
9666
|
+
title: "No record set for this product",
|
|
9667
|
+
body: `Choose whether to create a fresh ${itemNoun} for this product or start from the global default.`,
|
|
9668
|
+
primaryLabel: "Start blank",
|
|
9669
|
+
onPrimary: () => onCreateProductRecord("blank"),
|
|
9670
|
+
secondaryLabel: singletonGlobalSeedAvailable ? "Copy from global" : void 0,
|
|
9671
|
+
onSecondary: singletonGlobalSeedAvailable ? () => onCreateProductRecord("global") : void 0
|
|
9672
|
+
}
|
|
9673
|
+
) : null,
|
|
9602
9674
|
ruleWizardStep === null && !isProductTab && editingTargetScope && (!isCollection || selectedItemId) && renderEditorWithPreview()
|
|
9603
9675
|
] })
|
|
9604
9676
|
]
|
|
@@ -9725,7 +9797,7 @@ var RecordBrowser = ({
|
|
|
9725
9797
|
};
|
|
9726
9798
|
var initials2 = (s) => s.split(/\s+/).filter(Boolean).slice(0, 2).map((p) => p[0]?.toUpperCase() ?? "").join("") || "?";
|
|
9727
9799
|
var DefaultRecordCard = ({ record, ctx, variant = "grid" }) => {
|
|
9728
|
-
const { selected, onSelect, isDirty, hasError, onCopy, onDuplicate, actions } = ctx;
|
|
9800
|
+
const { selected, onSelect, isDirty, hasError, onCopy, onDuplicate, onCopyAndNewRule, actions } = ctx;
|
|
9729
9801
|
const aspect = variant === "gallery" ? "aspect-video" : "aspect-square";
|
|
9730
9802
|
return /* @__PURE__ */ jsxs(
|
|
9731
9803
|
"button",
|
|
@@ -9786,15 +9858,17 @@ var DefaultRecordCard = ({ record, ctx, variant = "grid" }) => {
|
|
|
9786
9858
|
/* @__PURE__ */ jsxs("div", { className: "p-2.5 min-w-0", children: [
|
|
9787
9859
|
/* @__PURE__ */ jsxs("div", { className: "flex items-start gap-1.5 min-w-0", children: [
|
|
9788
9860
|
/* @__PURE__ */ jsx("div", { className: "ra-row-title flex-1 min-w-0", children: record.label }),
|
|
9789
|
-
(onCopy || onDuplicate || actions && actions.length > 0) && /* @__PURE__ */ jsx(
|
|
9861
|
+
(onCopy || onDuplicate || onCopyAndNewRule || actions && actions.length > 0) && /* @__PURE__ */ jsx(
|
|
9790
9862
|
RowContextMenu,
|
|
9791
9863
|
{
|
|
9792
9864
|
onCopy,
|
|
9793
9865
|
onDuplicate,
|
|
9866
|
+
onCopyAndNewRule,
|
|
9794
9867
|
actions,
|
|
9795
9868
|
i18n: {
|
|
9796
9869
|
copy: DEFAULT_I18N.copy,
|
|
9797
|
-
duplicateAction: DEFAULT_I18N.duplicateAction
|
|
9870
|
+
duplicateAction: DEFAULT_I18N.duplicateAction,
|
|
9871
|
+
copyAndNewRuleAction: DEFAULT_I18N.copyAndNewRuleAction
|
|
9798
9872
|
}
|
|
9799
9873
|
}
|
|
9800
9874
|
)
|