@proveanything/smartlinks-utils-ui 0.11.6 → 0.11.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -432,6 +432,13 @@ interface RecordsAdminI18n {
432
432
  duplicateAction: string;
433
433
  /** Toast shown after a successful Duplicate. `{name}` = source label. */
434
434
  duplicateToast: string;
435
+ /**
436
+ * Row-menu label for the "Copy and start new rule" action — shown on
437
+ * the rules tab in singleton mode. One-click flow: copies the row to
438
+ * the clipboard and immediately opens the New Rule wizard seeded with
439
+ * it.
440
+ */
441
+ copyAndNewRuleAction: string;
435
442
  /** Confirm dialog when pasting onto a destination with an existing saved value. */
436
443
  pasteConfirmTitle: string;
437
444
  pasteConfirmBody: string;
@@ -728,6 +735,14 @@ interface RecordSlotContext {
728
735
  * `i18n.duplicateAction` (e.g. "Run this vote again").
729
736
  */
730
737
  onDuplicate?: () => void;
738
+ /**
739
+ * Singleton-mode rules-tab affordance — copy this row's value and
740
+ * immediately open the New Rule wizard pre-seeded with it. Replaces
741
+ * the two-step "Copy → Paste as new rule (sidebar)" flow when the
742
+ * admin wants to spin a new rule off an existing rule or the global
743
+ * record. Hidden in collection cardinality and outside the rules tab.
744
+ */
745
+ onCopyAndNewRule?: () => void;
731
746
  /**
732
747
  * Paste the current clipboard entry onto this row. Disabled when there is
733
748
  * nothing to paste, when the source ref equals this row, or when the
@@ -1339,6 +1354,7 @@ interface Props$d {
1339
1354
  rowClipboard?: (record: RecordSummary) => {
1340
1355
  onCopy?: () => void;
1341
1356
  onDuplicate?: () => void;
1357
+ onCopyAndNewRule?: () => void;
1342
1358
  } | null;
1343
1359
  /**
1344
1360
  * Optional host-supplied per-record action lookup. Returned actions are
@@ -1464,6 +1480,15 @@ interface Props$b<T> {
1464
1480
  canPaste: boolean;
1465
1481
  pasteSourceLabel?: string;
1466
1482
  pasteWillReplace?: boolean;
1483
+ /**
1484
+ * Singleton-mode rules-tab affordance — copies the current editor
1485
+ * value AND immediately opens the New Rule wizard pre-seeded with
1486
+ * it. Mirrors the row-menu action; rendered as a third button
1487
+ * between Copy and Paste when present.
1488
+ */
1489
+ onCopyAndNewRule?: () => void;
1490
+ /** Label for the "Copy and start new rule" button. */
1491
+ copyAndNewRuleLabel?: string;
1467
1492
  };
1468
1493
  /** Host-provided labels for save / discard / delete (resting state only). */
1469
1494
  actionLabels?: Partial<Record<RecordsAdminActionKey, string>>;
@@ -2510,6 +2535,7 @@ interface Props$5<T> {
2510
2535
  rowClipboard?: (record: RecordSummary<T>) => {
2511
2536
  onCopy?: () => void;
2512
2537
  onDuplicate?: () => void;
2538
+ onCopyAndNewRule?: () => void;
2513
2539
  } | null;
2514
2540
  /**
2515
2541
  * Optional projector returning extra strings to include in the search
@@ -2562,6 +2588,7 @@ interface Props$3<T> {
2562
2588
  rowClipboard?: (record: RecordSummary<T>) => {
2563
2589
  onCopy?: () => void;
2564
2590
  onDuplicate?: () => void;
2591
+ onCopyAndNewRule?: () => void;
2565
2592
  } | null;
2566
2593
  i18n: Pick<RecordsAdminI18n, 'itemColumnLabel' | 'itemColumnUpdated' | 'itemActions' | 'delete'>;
2567
2594
  }
@@ -2580,6 +2607,7 @@ interface Props$2<T> {
2580
2607
  rowClipboard?: (record: RecordSummary<T>) => {
2581
2608
  onCopy?: () => void;
2582
2609
  onDuplicate?: () => void;
2610
+ onCopyAndNewRule?: () => void;
2583
2611
  } | null;
2584
2612
  i18n: Pick<RecordsAdminI18n, 'delete'>;
2585
2613
  }
@@ -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({
@@ -3305,6 +3332,7 @@ var statusToneLabel = (tone) => {
3305
3332
  var RowContextMenu = ({
3306
3333
  onCopy,
3307
3334
  onDuplicate,
3335
+ onCopyAndNewRule,
3308
3336
  actions,
3309
3337
  i18n
3310
3338
  }) => {
@@ -3355,8 +3383,8 @@ var RowContextMenu = ({
3355
3383
  };
3356
3384
  }, [open]);
3357
3385
  const hasActions = (actions?.length ?? 0) > 0;
3358
- if (!onCopy && !onDuplicate && !hasActions) return null;
3359
- const showDivider = (onCopy || onDuplicate) && hasActions;
3386
+ if (!onCopy && !onDuplicate && !onCopyAndNewRule && !hasActions) return null;
3387
+ const showDivider = (onCopy || onDuplicate || onCopyAndNewRule) && hasActions;
3360
3388
  return /* @__PURE__ */ jsxs("div", { ref: wrapperRef, className: "ra-row-menu-wrap relative", children: [
3361
3389
  /* @__PURE__ */ jsx(
3362
3390
  "button",
@@ -3419,6 +3447,23 @@ var RowContextMenu = ({
3419
3447
  ]
3420
3448
  }
3421
3449
  ),
3450
+ onCopyAndNewRule && /* @__PURE__ */ jsxs(
3451
+ "button",
3452
+ {
3453
+ type: "button",
3454
+ role: "menuitem",
3455
+ className: "ra-row-menu-item",
3456
+ onClick: (e) => {
3457
+ e.stopPropagation();
3458
+ setOpen(false);
3459
+ onCopyAndNewRule();
3460
+ },
3461
+ children: [
3462
+ /* @__PURE__ */ jsx(FilePlus2, { className: "w-3.5 h-3.5 opacity-70", "aria-hidden": "true" }),
3463
+ /* @__PURE__ */ jsx("span", { children: i18n.copyAndNewRuleAction })
3464
+ ]
3465
+ }
3466
+ ),
3422
3467
  showDivider && /* @__PURE__ */ jsx("div", { className: "ra-row-menu-divider", role: "separator" }),
3423
3468
  hasActions && actions.map((action) => {
3424
3469
  const Icon = action.icon;
@@ -3493,7 +3538,7 @@ var RuleLabelLookupProvider = ({
3493
3538
  return /* @__PURE__ */ jsx(RuleLabelLookupContext.Provider, { value: v, children });
3494
3539
  };
3495
3540
  var DefaultRecordRow = ({ record, ctx, compact = false }) => {
3496
- const { selected, onSelect, isDirty, hasError, onCopy, onDuplicate, actions } = ctx;
3541
+ const { selected, onSelect, isDirty, hasError, onCopy, onDuplicate, onCopyAndNewRule, actions } = ctx;
3497
3542
  const ruleLabelLookup = useRuleLabelLookup();
3498
3543
  const ScopeIcon = record.scope.kind && record.scope.kind !== "collection" ? DEFAULT_ICONS.scope[record.scope.kind] : DEFAULT_ICONS.scope.product;
3499
3544
  const tone = resolveTone(void 0, record.status);
@@ -3567,15 +3612,17 @@ var DefaultRecordRow = ({ record, ctx, compact = false }) => {
3567
3612
  }
3568
3613
  )
3569
3614
  ] }),
3570
- (onCopy || onDuplicate || actions && actions.length > 0) && /* @__PURE__ */ jsx(
3615
+ (onCopy || onDuplicate || onCopyAndNewRule || actions && actions.length > 0) && /* @__PURE__ */ jsx(
3571
3616
  RowContextMenu,
3572
3617
  {
3573
3618
  onCopy,
3574
3619
  onDuplicate,
3620
+ onCopyAndNewRule,
3575
3621
  actions,
3576
3622
  i18n: {
3577
3623
  copy: DEFAULT_I18N.copy,
3578
- duplicateAction: DEFAULT_I18N.duplicateAction
3624
+ duplicateAction: DEFAULT_I18N.duplicateAction,
3625
+ copyAndNewRuleAction: DEFAULT_I18N.copyAndNewRuleAction
3579
3626
  }
3580
3627
  }
3581
3628
  )
@@ -4623,6 +4670,22 @@ function RecordEditor({
4623
4670
  ]
4624
4671
  }
4625
4672
  ),
4673
+ clipboard.onCopyAndNewRule && /* @__PURE__ */ jsxs(
4674
+ "button",
4675
+ {
4676
+ type: "button",
4677
+ onClick: clipboard.onCopyAndNewRule,
4678
+ disabled: !clipboard.canCopy || !!ctx.isSaving,
4679
+ title: clipboard.copyAndNewRuleLabel ?? i18n.copyAndNewRuleAction ?? "Copy and start new rule",
4680
+ "aria-label": clipboard.copyAndNewRuleLabel ?? i18n.copyAndNewRuleAction ?? "Copy and start new rule",
4681
+ 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",
4682
+ style: { borderColor: "hsl(var(--ra-border))", color: "hsl(var(--ra-text))" },
4683
+ children: [
4684
+ /* @__PURE__ */ jsx(FilePlus2, { className: "w-3 h-3" }),
4685
+ clipboard.copyAndNewRuleLabel ?? i18n.copyAndNewRuleAction ?? "Copy and start new rule"
4686
+ ]
4687
+ }
4688
+ ),
4626
4689
  /* @__PURE__ */ jsxs(
4627
4690
  "button",
4628
4691
  {
@@ -5782,7 +5845,7 @@ function DefaultItemTable({
5782
5845
  const extra = rowActions ? rowActions(item) ?? void 0 : void 0;
5783
5846
  const cb = rowClipboard ? rowClipboard(item) : null;
5784
5847
  const hasExtras = !!(extra && extra.length > 0);
5785
- if (!cb?.onCopy && !cb?.onDuplicate && !hasExtras) return null;
5848
+ if (!cb?.onCopy && !cb?.onDuplicate && !cb?.onCopyAndNewRule && !hasExtras) return null;
5786
5849
  return /* @__PURE__ */ jsx(
5787
5850
  "span",
5788
5851
  {
@@ -5793,10 +5856,12 @@ function DefaultItemTable({
5793
5856
  {
5794
5857
  onCopy: cb?.onCopy,
5795
5858
  onDuplicate: cb?.onDuplicate,
5859
+ onCopyAndNewRule: cb?.onCopyAndNewRule,
5796
5860
  actions: extra ?? void 0,
5797
5861
  i18n: {
5798
5862
  copy: DEFAULT_I18N.copy,
5799
- duplicateAction: DEFAULT_I18N.duplicateAction
5863
+ duplicateAction: DEFAULT_I18N.duplicateAction,
5864
+ copyAndNewRuleAction: DEFAULT_I18N.copyAndNewRuleAction
5800
5865
  }
5801
5866
  }
5802
5867
  )
@@ -5926,7 +5991,7 @@ function DefaultItemCards({
5926
5991
  /* @__PURE__ */ jsx("div", { className: "ra-item-card-title", children: item.label }),
5927
5992
  item.subtitle && /* @__PURE__ */ jsx("div", { className: "ra-item-card-sub", children: item.subtitle })
5928
5993
  ] }),
5929
- (cb?.onCopy || cb?.onDuplicate || extraActions && extraActions.length > 0) && /* @__PURE__ */ jsx(
5994
+ (cb?.onCopy || cb?.onDuplicate || cb?.onCopyAndNewRule || extraActions && extraActions.length > 0) && /* @__PURE__ */ jsx(
5930
5995
  "span",
5931
5996
  {
5932
5997
  className: "ra-item-card-menu",
@@ -5937,10 +6002,12 @@ function DefaultItemCards({
5937
6002
  {
5938
6003
  onCopy: cb?.onCopy,
5939
6004
  onDuplicate: cb?.onDuplicate,
6005
+ onCopyAndNewRule: cb?.onCopyAndNewRule,
5940
6006
  actions: extraActions,
5941
6007
  i18n: {
5942
6008
  copy: DEFAULT_I18N.copy,
5943
- duplicateAction: DEFAULT_I18N.duplicateAction
6009
+ duplicateAction: DEFAULT_I18N.duplicateAction,
6010
+ copyAndNewRuleAction: DEFAULT_I18N.copyAndNewRuleAction
5944
6011
  }
5945
6012
  }
5946
6013
  )
@@ -8341,6 +8408,7 @@ function RecordsAdminShellInner(props) {
8341
8408
  ]);
8342
8409
  const onLeftSelectRef = useRef(null);
8343
8410
  const onCreateItemDraftRef = useRef(null);
8411
+ const onCreateRuleFromClipboardRef = useRef(null);
8344
8412
  const previewReopenAnchorRef = useRef(null);
8345
8413
  const { runWithGuard } = useDirtyNavigation({
8346
8414
  strategy: dirtyStrategy,
@@ -8397,7 +8465,9 @@ function RecordsAdminShellInner(props) {
8397
8465
  onCopyOverride,
8398
8466
  onPasteOverride,
8399
8467
  onLeftSelectRef,
8400
- onCreateItemDraftRef
8468
+ onCreateItemDraftRef,
8469
+ onCreateRuleFromClipboardRef,
8470
+ isRuleTab: activeScope === "rule"
8401
8471
  });
8402
8472
  const editorClipboard = shellClipboard.editorClipboard;
8403
8473
  const rowClipboard = shellClipboard.rowClipboard;
@@ -9018,6 +9088,7 @@ function RecordsAdminShellInner(props) {
9018
9088
  };
9019
9089
  onLeftSelectRef.current = onLeftSelect;
9020
9090
  onCreateItemDraftRef.current = onItemCreate;
9091
+ onCreateRuleFromClipboardRef.current = () => onCreateRule("paste");
9021
9092
  return /* @__PURE__ */ jsx(RuleLabelLookupProvider, { value: ruleLabelLookup, children: /* @__PURE__ */ jsxs(
9022
9093
  "div",
9023
9094
  {
@@ -9239,37 +9310,20 @@ function RecordsAdminShellInner(props) {
9239
9310
  }
9240
9311
  ) }),
9241
9312
  /* @__PURE__ */ jsxs("div", { className: "p-3 space-y-2.5 border-b", style: { borderColor: "hsl(var(--ra-border))" }, children: [
9242
- isRuleTab && /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5", children: [
9243
- /* @__PURE__ */ jsxs(
9244
- "button",
9245
- {
9246
- type: "button",
9247
- onClick: () => onCreateRule(),
9248
- className: "ra-btn w-full",
9249
- "data-variant": "primary",
9250
- "aria-label": "New rule",
9251
- children: [
9252
- /* @__PURE__ */ jsx(Plus, { className: "w-3.5 h-3.5", "aria-hidden": "true" }),
9253
- /* @__PURE__ */ jsx("span", { children: "New rule" })
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
- ] }),
9313
+ isRuleTab && /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-1.5", children: /* @__PURE__ */ jsxs(
9314
+ "button",
9315
+ {
9316
+ type: "button",
9317
+ onClick: () => onCreateRule(),
9318
+ className: "ra-btn w-full",
9319
+ "data-variant": "primary",
9320
+ "aria-label": "New rule",
9321
+ children: [
9322
+ /* @__PURE__ */ jsx(Plus, { className: "w-3.5 h-3.5", "aria-hidden": "true" }),
9323
+ /* @__PURE__ */ jsx("span", { children: "New rule" })
9324
+ ]
9325
+ }
9326
+ ) }),
9273
9327
  showCreateGlobal && /* @__PURE__ */ jsxs(
9274
9328
  "button",
9275
9329
  {
@@ -9725,7 +9779,7 @@ var RecordBrowser = ({
9725
9779
  };
9726
9780
  var initials2 = (s) => s.split(/\s+/).filter(Boolean).slice(0, 2).map((p) => p[0]?.toUpperCase() ?? "").join("") || "?";
9727
9781
  var DefaultRecordCard = ({ record, ctx, variant = "grid" }) => {
9728
- const { selected, onSelect, isDirty, hasError, onCopy, onDuplicate, actions } = ctx;
9782
+ const { selected, onSelect, isDirty, hasError, onCopy, onDuplicate, onCopyAndNewRule, actions } = ctx;
9729
9783
  const aspect = variant === "gallery" ? "aspect-video" : "aspect-square";
9730
9784
  return /* @__PURE__ */ jsxs(
9731
9785
  "button",
@@ -9786,15 +9840,17 @@ var DefaultRecordCard = ({ record, ctx, variant = "grid" }) => {
9786
9840
  /* @__PURE__ */ jsxs("div", { className: "p-2.5 min-w-0", children: [
9787
9841
  /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-1.5 min-w-0", children: [
9788
9842
  /* @__PURE__ */ jsx("div", { className: "ra-row-title flex-1 min-w-0", children: record.label }),
9789
- (onCopy || onDuplicate || actions && actions.length > 0) && /* @__PURE__ */ jsx(
9843
+ (onCopy || onDuplicate || onCopyAndNewRule || actions && actions.length > 0) && /* @__PURE__ */ jsx(
9790
9844
  RowContextMenu,
9791
9845
  {
9792
9846
  onCopy,
9793
9847
  onDuplicate,
9848
+ onCopyAndNewRule,
9794
9849
  actions,
9795
9850
  i18n: {
9796
9851
  copy: DEFAULT_I18N.copy,
9797
- duplicateAction: DEFAULT_I18N.duplicateAction
9852
+ duplicateAction: DEFAULT_I18N.duplicateAction,
9853
+ copyAndNewRuleAction: DEFAULT_I18N.copyAndNewRuleAction
9798
9854
  }
9799
9855
  }
9800
9856
  )