@proveanything/smartlinks-utils-ui 0.10.9 → 0.11.1

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.
@@ -1,4 +1,4 @@
1
- import { AdminPageHeader } from '../../chunk-2MW54ZVG.js';
1
+ import { useIntroState, AdminPageHeader } from '../../chunk-3RRHM4LP.js';
2
2
  import { assertComponentStylesLoaded } from '../../chunk-OLYC54YT.js';
3
3
  import '../../chunk-5UQQYXCX.js';
4
4
  import { FacetRuleEditor } from '../../chunk-JMCV6FOW.js';
@@ -6,12 +6,105 @@ import { useFacets } from '../../chunk-4LHF5JB7.js';
6
6
  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
- import { createContext, useState, useEffect, useCallback, useMemo, useRef, isValidElement, useContext, useSyncExternalStore, useLayoutEffect, 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, MinusCircle, XCircle, CopyPlus, AlertCircle, Undo2, Save, Loader2, ArrowRight, Globe2, Check, Settings2 } from 'lucide-react';
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';
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';
14
14
 
15
+ // src/components/RecordsAdmin/data/recordCache.ts
16
+ var RECORD_LIST_QK = ["records-admin", "list"];
17
+ var COLLECTION_ITEMS_QK = ["records-admin", "collection-items"];
18
+ var matchesCtx = (queryKey, prefix, ctx) => {
19
+ if (queryKey.length < prefix.length + 3) return false;
20
+ for (let i = 0; i < prefix.length; i += 1) {
21
+ if (queryKey[i] !== prefix[i]) return false;
22
+ }
23
+ if (queryKey[prefix.length] !== ctx.collectionId) return false;
24
+ if (queryKey[prefix.length + 1] !== ctx.appId) return false;
25
+ if (queryKey[prefix.length + 2] !== (ctx.recordType ?? void 0) && queryKey[prefix.length + 2] !== ctx.recordType) {
26
+ const slot = queryKey[prefix.length + 2];
27
+ if (slot !== void 0 && slot !== ctx.recordType) return false;
28
+ if (slot === void 0 && ctx.recordType) return false;
29
+ }
30
+ return true;
31
+ };
32
+ var replaceOrAppend = (cache, record) => {
33
+ let replaced = false;
34
+ const nextPages = cache.pages.map((page) => {
35
+ const idx = page.data.findIndex((r) => r.id === record.id);
36
+ if (idx === -1) return page;
37
+ replaced = true;
38
+ const nextData = [...page.data];
39
+ nextData[idx] = record;
40
+ return { ...page, data: nextData };
41
+ });
42
+ if (replaced) return { ...cache, pages: nextPages };
43
+ if (nextPages.length === 0) {
44
+ return {
45
+ pageParams: [0],
46
+ pages: [{ data: [record], total: 1, hasMore: false, nextOffset: 1 }]
47
+ };
48
+ }
49
+ const last = nextPages[nextPages.length - 1];
50
+ const updatedLast = {
51
+ ...last,
52
+ data: [...last.data, record],
53
+ total: (last.total ?? 0) + 1,
54
+ nextOffset: (last.nextOffset ?? last.data.length) + 1
55
+ };
56
+ const bumped = nextPages.map((p, i) => i === nextPages.length - 1 ? updatedLast : { ...p, total: (p.total ?? 0) + 1 });
57
+ return { ...cache, pages: bumped };
58
+ };
59
+ var removeFromPages = (cache, recordId) => {
60
+ let found = false;
61
+ const nextPages = cache.pages.map((page) => {
62
+ const idx = page.data.findIndex((r) => r.id === recordId);
63
+ if (idx === -1) return page;
64
+ found = true;
65
+ return {
66
+ ...page,
67
+ data: page.data.filter((r) => r.id !== recordId),
68
+ total: Math.max(0, (page.total ?? 0) - 1)
69
+ };
70
+ });
71
+ if (!found) return null;
72
+ const bumped = nextPages.map((p) => p.data.some((r) => r.id === recordId) ? p : { ...p, total: Math.max(0, p.total ?? 0) });
73
+ return { ...cache, pages: bumped };
74
+ };
75
+ function patchRecordIntoCaches(queryClient, ctx, record) {
76
+ if (!record || !record.id) return;
77
+ const all = [
78
+ ...queryClient.getQueriesData({ queryKey: RECORD_LIST_QK }),
79
+ ...queryClient.getQueriesData({ queryKey: COLLECTION_ITEMS_QK })
80
+ ];
81
+ for (const [key, cache] of all) {
82
+ if (!cache || !Array.isArray(cache.pages)) continue;
83
+ const prefix = key[0] === RECORD_LIST_QK[0] && key[1] === RECORD_LIST_QK[1] ? RECORD_LIST_QK : COLLECTION_ITEMS_QK;
84
+ if (!matchesCtx(key, prefix, ctx)) continue;
85
+ queryClient.setQueryData(key, (prev) => {
86
+ if (!prev || !Array.isArray(prev.pages)) return prev;
87
+ return replaceOrAppend(prev, record);
88
+ });
89
+ }
90
+ }
91
+ function removeRecordFromCaches(queryClient, ctx, recordId) {
92
+ if (!recordId) return;
93
+ const all = [
94
+ ...queryClient.getQueriesData({ queryKey: RECORD_LIST_QK }),
95
+ ...queryClient.getQueriesData({ queryKey: COLLECTION_ITEMS_QK })
96
+ ];
97
+ for (const [key, cache] of all) {
98
+ if (!cache || !Array.isArray(cache.pages)) continue;
99
+ const prefix = key[0] === RECORD_LIST_QK[0] && key[1] === RECORD_LIST_QK[1] ? RECORD_LIST_QK : COLLECTION_ITEMS_QK;
100
+ if (!matchesCtx(key, prefix, ctx)) continue;
101
+ queryClient.setQueryData(key, (prev) => {
102
+ if (!prev || !Array.isArray(prev.pages)) return prev;
103
+ const next = removeFromPages(prev, recordId);
104
+ return next ?? prev;
105
+ });
106
+ }
107
+ }
15
108
  var DEFAULT_ICONS = {
16
109
  scope: {
17
110
  collection: Globe,
@@ -412,58 +505,12 @@ function useResolvedRecord(args) {
412
505
  error: query.error ?? null
413
506
  };
414
507
  }
415
- var RT_KEY = (recordType) => recordType ?? "_default";
416
- var lsKey = (appId, recordType) => `ra:intro:${appId}:${RT_KEY(recordType)}`;
417
- var useIntroDismissed = (SL, collectionId, appId, recordType) => {
418
- const [dismissed, setDismissed] = useState(() => {
419
- try {
420
- return localStorage.getItem(lsKey(appId, recordType)) === "1";
421
- } catch {
422
- return false;
423
- }
424
- });
425
- useEffect(() => {
426
- let cancelled = false;
427
- (async () => {
428
- try {
429
- const cfg = await SL?.appConfiguration?.getConfig?.({ collectionId, appId, admin: true });
430
- if (cancelled) return;
431
- const flag = cfg?._meta?.introDismissed?.[RT_KEY(recordType)];
432
- if (flag) setDismissed(true);
433
- } catch {
434
- }
435
- })();
436
- return () => {
437
- cancelled = true;
438
- };
439
- }, [SL, collectionId, appId, recordType]);
440
- const dismiss = useCallback(async () => {
441
- setDismissed(true);
442
- try {
443
- localStorage.setItem(lsKey(appId, recordType), "1");
444
- } catch {
445
- }
446
- try {
447
- const cfg = await SL?.appConfiguration?.getConfig?.({ collectionId, appId, admin: true }).catch(() => ({}));
448
- const next = {
449
- ...cfg ?? {},
450
- _meta: {
451
- ...cfg?._meta ?? {},
452
- introDismissed: { ...cfg?._meta?.introDismissed ?? {}, [RT_KEY(recordType)]: true }
453
- }
454
- };
455
- await SL?.appConfiguration?.setConfig?.({ collectionId, appId, admin: true, config: next });
456
- } catch {
457
- }
458
- }, [SL, collectionId, appId, recordType]);
459
- const undismiss = useCallback(() => {
460
- setDismissed(false);
461
- try {
462
- localStorage.removeItem(lsKey(appId, recordType));
463
- } catch {
464
- }
465
- }, [appId, recordType]);
466
- return { dismissed, dismiss, undismiss };
508
+
509
+ // src/components/RecordsAdmin/hooks/useIntroDismissed.ts
510
+ var useIntroDismissed = (SL, _collectionId, appId, recordType) => {
511
+ const persistKey = recordType ? `${appId}:${recordType}` : appId;
512
+ const { dismissed, onDismiss, onReopen } = useIntroState({ SL, persistKey });
513
+ return { dismissed, dismiss: onDismiss, undismiss: onReopen };
467
514
  };
468
515
  var useScopeProbe = ({ SL, collectionId, admin = true, enabled = true }) => {
469
516
  const query = useQuery({
@@ -1055,7 +1102,8 @@ function useShellBrowser(opts) {
1055
1102
  probeIsLoading,
1056
1103
  selectedProductId,
1057
1104
  drillTab,
1058
- classify: classify3
1105
+ classify: classify3,
1106
+ pageSize
1059
1107
  } = opts;
1060
1108
  const [search, setSearch] = useState("");
1061
1109
  const [filter, setFilter] = useState("all");
@@ -1081,7 +1129,8 @@ function useShellBrowser(opts) {
1081
1129
  filter,
1082
1130
  classify: classify3,
1083
1131
  contextScope,
1084
- enabled: recordListEnabled
1132
+ enabled: recordListEnabled,
1133
+ pageSize
1085
1134
  });
1086
1135
  const facetBrowse = useFacetBrowse({
1087
1136
  SL,
@@ -2352,6 +2401,7 @@ var createEditorStore = () => {
2352
2401
  let nextOrder = 0;
2353
2402
  let hooksBundle = null;
2354
2403
  let notifier = null;
2404
+ let recordChangeNotifier = null;
2355
2405
  const buildRecordSummary = (entry, value) => ({
2356
2406
  id: entry.recordId ?? null,
2357
2407
  ref: entry.spec.scope.raw,
@@ -2557,8 +2607,9 @@ var createEditorStore = () => {
2557
2607
  });
2558
2608
  try {
2559
2609
  let nextRecordId = entry.recordId;
2610
+ let savedRecord = null;
2560
2611
  if (entry.recordId && entry.source === "self") {
2561
- await updateRecord(ctx, entry.recordId, {
2612
+ savedRecord = await updateRecord(ctx, entry.recordId, {
2562
2613
  data: persistedValue,
2563
2614
  facetRule: persistedFacetRule
2564
2615
  });
@@ -2577,6 +2628,7 @@ var createEditorStore = () => {
2577
2628
  facetRule: persistedFacetRule
2578
2629
  });
2579
2630
  nextRecordId = created?.id ?? nextRecordId;
2631
+ savedRecord = created;
2580
2632
  } else {
2581
2633
  const upserted = await upsertRecord(ctx, {
2582
2634
  ref: spec.ref,
@@ -2585,6 +2637,7 @@ var createEditorStore = () => {
2585
2637
  facetRule: persistedFacetRule
2586
2638
  });
2587
2639
  nextRecordId = upserted.record?.id ?? nextRecordId;
2640
+ savedRecord = upserted.record;
2588
2641
  }
2589
2642
  update(editorId, (e) => {
2590
2643
  if (persistedValue !== entry.value) {
@@ -2597,6 +2650,12 @@ var createEditorStore = () => {
2597
2650
  e.status = "saved";
2598
2651
  e.error = void 0;
2599
2652
  });
2653
+ if (savedRecord && savedRecord.id) {
2654
+ try {
2655
+ recordChangeNotifier?.({ kind: "saved", record: savedRecord, isCreate, ctx });
2656
+ } catch {
2657
+ }
2658
+ }
2600
2659
  if (hooksBundle?.afterSave) {
2601
2660
  const refreshed = map.get(editorId);
2602
2661
  const hookCtx = {
@@ -2654,6 +2713,10 @@ var createEditorStore = () => {
2654
2713
  await removeRecord(entry.saveSpec.ctx, entry.recordId);
2655
2714
  map.delete(editorId);
2656
2715
  emit();
2716
+ try {
2717
+ recordChangeNotifier?.({ kind: "deleted", recordId: entry.recordId, ctx: entry.saveSpec.ctx });
2718
+ } catch {
2719
+ }
2657
2720
  if (hooksBundle?.afterDelete && deletedSnapshot) {
2658
2721
  try {
2659
2722
  await hooksBundle.afterDelete(deletedSnapshot);
@@ -2688,6 +2751,9 @@ var createEditorStore = () => {
2688
2751
  },
2689
2752
  setNotifier(notify2) {
2690
2753
  notifier = notify2 ?? null;
2754
+ },
2755
+ setRecordChangeNotifier(notify2) {
2756
+ recordChangeNotifier = notify2 ?? null;
2691
2757
  }
2692
2758
  };
2693
2759
  };
@@ -2711,12 +2777,14 @@ var EditorSessionProvider = ({
2711
2777
  maxOpenEditors = 8,
2712
2778
  defaultValueFactory,
2713
2779
  hooks,
2714
- onHookNotice
2780
+ onHookNotice,
2781
+ onRecordChange
2715
2782
  }) => {
2716
2783
  const storeRef = useRef(null);
2717
2784
  if (!storeRef.current) storeRef.current = createEditorStore();
2718
2785
  storeRef.current.setHooks(hooks ?? null);
2719
2786
  storeRef.current.setNotifier(onHookNotice ?? null);
2787
+ storeRef.current.setRecordChangeNotifier(onRecordChange ?? null);
2720
2788
  const currentRef = useRef(void 0);
2721
2789
  const listenersRef = useRef(/* @__PURE__ */ new Set());
2722
2790
  const subscribeCurrent = useCallback((cb) => {
@@ -3749,6 +3817,56 @@ var ProductList = RecordList;
3749
3817
  var FacetList = RecordList;
3750
3818
  var VariantList = RecordList;
3751
3819
  var BatchList = RecordList;
3820
+ function LoadMoreFooter({
3821
+ shown,
3822
+ total,
3823
+ hasNextPage,
3824
+ isFetchingNextPage,
3825
+ onLoadMore,
3826
+ label
3827
+ }) {
3828
+ if (!hasNextPage && (total === void 0 || total <= shown)) return null;
3829
+ const knownTotal = typeof total === "number" && total >= shown;
3830
+ const summary = knownTotal ? `Showing ${shown} of ${total}` : `${shown} shown`;
3831
+ return /* @__PURE__ */ jsxs(
3832
+ "div",
3833
+ {
3834
+ className: "ra-loadmore",
3835
+ style: {
3836
+ display: "flex",
3837
+ alignItems: "center",
3838
+ gap: "8px",
3839
+ padding: "8px 12px",
3840
+ borderTop: "1px solid hsl(var(--ra-border))",
3841
+ background: "hsl(var(--ra-surface))"
3842
+ },
3843
+ children: [
3844
+ /* @__PURE__ */ jsx(
3845
+ "span",
3846
+ {
3847
+ style: {
3848
+ fontSize: "11px",
3849
+ color: "hsl(var(--ra-muted-text))",
3850
+ flex: 1
3851
+ },
3852
+ children: summary
3853
+ }
3854
+ ),
3855
+ hasNextPage && /* @__PURE__ */ jsx(
3856
+ "button",
3857
+ {
3858
+ type: "button",
3859
+ onClick: onLoadMore,
3860
+ disabled: isFetchingNextPage,
3861
+ className: "ra-btn",
3862
+ style: { fontSize: "11px", padding: "4px 10px" },
3863
+ children: isFetchingNextPage ? "Loading\u2026" : label ?? "Load more"
3864
+ }
3865
+ )
3866
+ ]
3867
+ }
3868
+ );
3869
+ }
3752
3870
  var COLLAPSED_FACET_CAP = 6;
3753
3871
  var COLLAPSED_VALUE_CAP = 12;
3754
3872
  var VALUE_SEARCH_THRESHOLD = 12;
@@ -5659,18 +5777,52 @@ function DefaultItemTable({
5659
5777
  selectedId,
5660
5778
  onOpen,
5661
5779
  onDelete,
5780
+ sort,
5781
+ onToggleSort,
5662
5782
  rowActions,
5663
5783
  rowClipboard,
5664
5784
  i18n
5665
5785
  }) {
5666
5786
  const cols = columns ?? [];
5667
5787
  const useFallback = cols.length === 0;
5788
+ const renderSortIcon = (key, sortable) => {
5789
+ if (!sortable) return null;
5790
+ if (sort?.key !== key || !sort?.dir) {
5791
+ return /* @__PURE__ */ jsx(ArrowUpDown, { className: "w-3 h-3 opacity-40", "aria-hidden": "true" });
5792
+ }
5793
+ return sort.dir === "asc" ? /* @__PURE__ */ jsx(ArrowUp, { className: "w-3 h-3", "aria-hidden": "true" }) : /* @__PURE__ */ jsx(ArrowDown, { className: "w-3 h-3", "aria-hidden": "true" });
5794
+ };
5668
5795
  return /* @__PURE__ */ jsx("div", { className: "ra-item-table-wrap", children: /* @__PURE__ */ jsxs("table", { className: "ra-item-table", children: [
5669
5796
  /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { children: [
5670
5797
  useFallback ? /* @__PURE__ */ jsxs(Fragment, { children: [
5671
- /* @__PURE__ */ jsx("th", { children: i18n.itemColumnLabel }),
5672
- /* @__PURE__ */ jsx("th", { style: { width: "12rem" }, children: i18n.itemColumnUpdated })
5673
- ] }) : cols.map((c) => /* @__PURE__ */ jsx("th", { style: { width: c.width, textAlign: c.align ?? "left" }, children: c.header }, c.key)),
5798
+ /* @__PURE__ */ jsx("th", { children: /* @__PURE__ */ jsx(
5799
+ SortableHeader,
5800
+ {
5801
+ label: i18n.itemColumnLabel,
5802
+ sortable: !!onToggleSort,
5803
+ icon: renderSortIcon("__label", !!onToggleSort),
5804
+ onClick: () => onToggleSort?.("__label")
5805
+ }
5806
+ ) }),
5807
+ /* @__PURE__ */ jsx("th", { style: { width: "12rem" }, children: /* @__PURE__ */ jsx(
5808
+ SortableHeader,
5809
+ {
5810
+ label: i18n.itemColumnUpdated,
5811
+ sortable: !!onToggleSort,
5812
+ icon: renderSortIcon("__updated", !!onToggleSort),
5813
+ onClick: () => onToggleSort?.("__updated")
5814
+ }
5815
+ ) })
5816
+ ] }) : cols.map((c) => /* @__PURE__ */ jsx("th", { style: { width: c.width, textAlign: c.align ?? "left" }, children: /* @__PURE__ */ jsx(
5817
+ SortableHeader,
5818
+ {
5819
+ label: c.header,
5820
+ sortable: !!c.sortBy && !!onToggleSort,
5821
+ icon: renderSortIcon(c.key, !!c.sortBy && !!onToggleSort),
5822
+ onClick: () => onToggleSort?.(c.key),
5823
+ align: c.align ?? "left"
5824
+ }
5825
+ ) }, c.key)),
5674
5826
  /* @__PURE__ */ jsx(
5675
5827
  "th",
5676
5828
  {
@@ -5758,6 +5910,39 @@ function DefaultItemTable({
5758
5910
  }) })
5759
5911
  ] }) });
5760
5912
  }
5913
+ function SortableHeader({
5914
+ label,
5915
+ sortable,
5916
+ icon,
5917
+ onClick,
5918
+ align = "left"
5919
+ }) {
5920
+ if (!sortable) return /* @__PURE__ */ jsx(Fragment, { children: label });
5921
+ return /* @__PURE__ */ jsxs(
5922
+ "button",
5923
+ {
5924
+ type: "button",
5925
+ onClick,
5926
+ className: "ra-item-th-sort",
5927
+ style: {
5928
+ display: "inline-flex",
5929
+ alignItems: "center",
5930
+ gap: "4px",
5931
+ background: "transparent",
5932
+ border: 0,
5933
+ padding: 0,
5934
+ font: "inherit",
5935
+ color: "inherit",
5936
+ cursor: "pointer",
5937
+ textAlign: align
5938
+ },
5939
+ children: [
5940
+ /* @__PURE__ */ jsx("span", { children: label }),
5941
+ icon
5942
+ ]
5943
+ }
5944
+ );
5945
+ }
5761
5946
  var initials = (label) => label.split(/\s+/).slice(0, 2).map((s) => s[0]?.toUpperCase() ?? "").join("") || "?";
5762
5947
  function DefaultItemCards({
5763
5948
  items,
@@ -5872,9 +6057,75 @@ function ItemListView({
5872
6057
  cardSize = "md",
5873
6058
  rowActions,
5874
6059
  rowClipboard,
6060
+ searchableFields,
6061
+ searchable = true,
6062
+ total,
6063
+ hasNextPage,
6064
+ isFetchingNextPage,
6065
+ onLoadMore,
5875
6066
  i18n
5876
6067
  }) {
5877
6068
  const newLabel = i18n.newItem.includes("{noun}") ? i18n.newItem.replace("{noun}", itemNoun) : i18n.newItem;
6069
+ const [search, setSearch] = useState("");
6070
+ const [sort, setSort] = useState({ key: null, dir: null });
6071
+ const onToggleSort = (key) => {
6072
+ setSort((cur) => {
6073
+ if (cur.key !== key) return { key, dir: "asc" };
6074
+ const next = cur.dir === "asc" ? "desc" : cur.dir === "desc" ? null : "asc";
6075
+ return { key: next ? key : null, dir: next };
6076
+ });
6077
+ };
6078
+ const wantsFullSet = search.trim().length > 0 || sort.dir !== null;
6079
+ const loadingNextRef = useRef(false);
6080
+ useEffect(() => {
6081
+ if (!wantsFullSet || !hasNextPage || !onLoadMore) return;
6082
+ if (isFetchingNextPage || loadingNextRef.current) return;
6083
+ loadingNextRef.current = true;
6084
+ onLoadMore();
6085
+ }, [wantsFullSet, hasNextPage, onLoadMore, isFetchingNextPage]);
6086
+ useEffect(() => {
6087
+ if (!isFetchingNextPage) loadingNextRef.current = false;
6088
+ }, [isFetchingNextPage]);
6089
+ const lookupColumn = useMemo(() => {
6090
+ const m = /* @__PURE__ */ new Map();
6091
+ (itemColumns ?? []).forEach((c) => m.set(c.key, c));
6092
+ return m;
6093
+ }, [itemColumns]);
6094
+ const visibleItems = useMemo(() => {
6095
+ let out = items;
6096
+ const q = search.trim().toLowerCase();
6097
+ if (q) {
6098
+ out = out.filter((it) => {
6099
+ const fields = [it.label, it.subtitle];
6100
+ if (searchableFields) fields.push(...searchableFields(it));
6101
+ return fields.some((f) => typeof f === "string" && f.toLowerCase().includes(q));
6102
+ });
6103
+ }
6104
+ if (sort.key && sort.dir) {
6105
+ const dir = sort.dir === "asc" ? 1 : -1;
6106
+ const getter = (it) => {
6107
+ if (sort.key === "__label") return it.label;
6108
+ if (sort.key === "__updated") return it.updatedAt;
6109
+ const col = lookupColumn.get(sort.key);
6110
+ return col?.sortBy ? col.sortBy(it) : void 0;
6111
+ };
6112
+ const norm = (v) => {
6113
+ if (v == null) return Number.POSITIVE_INFINITY;
6114
+ if (v instanceof Date) return v.getTime();
6115
+ if (typeof v === "boolean") return v ? 1 : 0;
6116
+ if (typeof v === "number") return v;
6117
+ return String(v).toLowerCase();
6118
+ };
6119
+ out = [...out].sort((a, b) => {
6120
+ const av = norm(getter(a));
6121
+ const bv = norm(getter(b));
6122
+ if (av < bv) return -1 * dir;
6123
+ if (av > bv) return 1 * dir;
6124
+ return 0;
6125
+ });
6126
+ }
6127
+ return out;
6128
+ }, [items, search, sort, lookupColumn, searchableFields]);
5878
6129
  const [pendingDeleteId, setPendingDeleteId] = useState(null);
5879
6130
  const pendingRecord = useMemo(
5880
6131
  () => pendingDeleteId ? items.find((it) => (it.itemId ?? "") === pendingDeleteId) ?? null : null,
@@ -5889,9 +6140,62 @@ function ItemListView({
5889
6140
  const toolbar = /* @__PURE__ */ jsxs("div", { className: "ra-item-toolbar", children: [
5890
6141
  /* @__PURE__ */ jsxs("div", { className: "ra-item-toolbar-title", children: [
5891
6142
  /* @__PURE__ */ jsx("h2", { className: "ra-display", style: { fontSize: "0.95rem", margin: 0 }, children: i18n.itemListTitle }),
5892
- /* @__PURE__ */ jsx("span", { className: "ra-item-toolbar-count", children: items.length })
6143
+ /* @__PURE__ */ jsx("span", { className: "ra-item-toolbar-count", children: visibleItems.length === items.length ? items.length : `${visibleItems.length} / ${items.length}` })
5893
6144
  ] }),
5894
6145
  /* @__PURE__ */ jsxs("div", { className: "ra-item-toolbar-actions", children: [
6146
+ searchable && items.length > 0 && /* @__PURE__ */ jsxs(
6147
+ "div",
6148
+ {
6149
+ className: "ra-item-search",
6150
+ style: {
6151
+ display: "inline-flex",
6152
+ alignItems: "center",
6153
+ gap: "6px",
6154
+ padding: "4px 8px",
6155
+ border: "1px solid hsl(var(--ra-border))",
6156
+ borderRadius: "6px",
6157
+ background: "hsl(var(--ra-surface))"
6158
+ },
6159
+ children: [
6160
+ /* @__PURE__ */ jsx(Search, { className: "w-3.5 h-3.5", "aria-hidden": "true", style: { opacity: 0.6 } }),
6161
+ /* @__PURE__ */ jsx(
6162
+ "input",
6163
+ {
6164
+ type: "text",
6165
+ value: search,
6166
+ onChange: (e) => setSearch(e.target.value),
6167
+ placeholder: `Search ${itemNoun}s`,
6168
+ "aria-label": `Search ${itemNoun}s`,
6169
+ style: {
6170
+ background: "transparent",
6171
+ border: 0,
6172
+ outline: "none",
6173
+ font: "inherit",
6174
+ fontSize: "12px",
6175
+ color: "inherit",
6176
+ width: "160px"
6177
+ }
6178
+ }
6179
+ ),
6180
+ search && /* @__PURE__ */ jsx(
6181
+ "button",
6182
+ {
6183
+ type: "button",
6184
+ onClick: () => setSearch(""),
6185
+ "aria-label": "Clear search",
6186
+ style: {
6187
+ background: "transparent",
6188
+ border: 0,
6189
+ padding: 0,
6190
+ cursor: "pointer",
6191
+ color: "hsl(var(--ra-muted-text))"
6192
+ },
6193
+ children: /* @__PURE__ */ jsx(X, { className: "w-3.5 h-3.5", "aria-hidden": "true" })
6194
+ }
6195
+ )
6196
+ ]
6197
+ }
6198
+ ),
5895
6199
  !renderItemList && /* @__PURE__ */ jsx(
5896
6200
  ItemViewSwitcher,
5897
6201
  {
@@ -5942,17 +6246,27 @@ function ItemListView({
5942
6246
  )
5943
6247
  }
5944
6248
  );
6249
+ } else if (visibleItems.length === 0) {
6250
+ body = /* @__PURE__ */ jsx(
6251
+ EmptyState,
6252
+ {
6253
+ title: "No matches",
6254
+ body: `No ${itemNoun}s match "${search}".`
6255
+ }
6256
+ );
5945
6257
  } else if (renderItemList) {
5946
- body = renderItemList(items, guardedCtx);
6258
+ body = renderItemList(visibleItems, guardedCtx);
5947
6259
  } else if (view === "table") {
5948
6260
  body = /* @__PURE__ */ jsx(
5949
6261
  DefaultItemTable,
5950
6262
  {
5951
- items,
6263
+ items: visibleItems,
5952
6264
  columns: itemColumns,
5953
6265
  selectedId: guardedCtx.selectedId,
5954
6266
  onOpen: guardedCtx.onOpen,
5955
6267
  onDelete: guardedCtx.onDelete,
6268
+ sort,
6269
+ onToggleSort,
5956
6270
  rowActions,
5957
6271
  rowClipboard,
5958
6272
  i18n
@@ -5962,7 +6276,7 @@ function ItemListView({
5962
6276
  body = /* @__PURE__ */ jsx(
5963
6277
  DefaultItemCards,
5964
6278
  {
5965
- items,
6279
+ items: visibleItems,
5966
6280
  variant: view,
5967
6281
  selectedId: guardedCtx.selectedId,
5968
6282
  ctx: guardedCtx,
@@ -5998,6 +6312,29 @@ function ItemListView({
5998
6312
  }
5999
6313
  ) : null,
6000
6314
  /* @__PURE__ */ jsx("div", { className: "ra-item-list-body", children: body }),
6315
+ wantsFullSet && hasNextPage && /* @__PURE__ */ jsx(
6316
+ "div",
6317
+ {
6318
+ style: {
6319
+ padding: "6px 12px",
6320
+ fontSize: "11px",
6321
+ color: "hsl(var(--ra-muted-text))",
6322
+ borderTop: "1px solid hsl(var(--ra-border))",
6323
+ background: "hsl(var(--ra-muted) / 0.4)"
6324
+ },
6325
+ children: isFetchingNextPage ? `Loading more ${itemNoun}s to ${search ? "search" : "sort"}\u2026` : `${search ? "Searching" : "Sorting"} the ${items.length} ${itemNoun}s loaded so far. More available \u2014 keep loading for the full set.`
6326
+ }
6327
+ ),
6328
+ onLoadMore && /* @__PURE__ */ jsx(
6329
+ LoadMoreFooter,
6330
+ {
6331
+ shown: items.length,
6332
+ total,
6333
+ hasNextPage: !!hasNextPage,
6334
+ isFetchingNextPage: !!isFetchingNextPage,
6335
+ onLoadMore
6336
+ }
6337
+ ),
6001
6338
  /* @__PURE__ */ jsx(
6002
6339
  ConfirmDialog,
6003
6340
  {
@@ -6086,7 +6423,11 @@ function SiblingRail({
6086
6423
  itemNoun,
6087
6424
  dirtyKeys,
6088
6425
  errorKeys,
6089
- i18n
6426
+ i18n,
6427
+ total,
6428
+ hasNextPage,
6429
+ isFetchingNextPage,
6430
+ onLoadMore
6090
6431
  }) {
6091
6432
  const ruleLabelLookup = useRuleLabelLookup();
6092
6433
  const newLabel = i18n.newItem.includes("{noun}") ? i18n.newItem.replace("{noun}", itemNoun ?? "item") : i18n.newItem;
@@ -6166,6 +6507,16 @@ function SiblingRail({
6166
6507
  ) }, key);
6167
6508
  }) })
6168
6509
  ] }),
6510
+ onLoadMore && /* @__PURE__ */ jsx(
6511
+ LoadMoreFooter,
6512
+ {
6513
+ shown: items.length,
6514
+ total,
6515
+ hasNextPage: !!hasNextPage,
6516
+ isFetchingNextPage: !!isFetchingNextPage,
6517
+ onLoadMore
6518
+ }
6519
+ ),
6169
6520
  onCreate && /* @__PURE__ */ jsx("div", { className: "ra-sibling-footer", children: /* @__PURE__ */ jsxs(
6170
6521
  "button",
6171
6522
  {
@@ -7039,12 +7390,19 @@ function PreviewReopenPill({ anchorRef, onClick, ariaLabel, title, children }) {
7039
7390
  const rafRef = useRef(null);
7040
7391
  useLayoutEffect(() => {
7041
7392
  const el = anchorRef.current;
7042
- if (!el || typeof window === "undefined") return;
7393
+ if (typeof window === "undefined") return;
7394
+ if (!el) {
7395
+ setPos({ top: window.innerHeight / 2, right: 8 });
7396
+ return;
7397
+ }
7043
7398
  const measure = () => {
7044
7399
  if (rafRef.current != null) cancelAnimationFrame(rafRef.current);
7045
7400
  rafRef.current = requestAnimationFrame(() => {
7046
7401
  const rect = el.getBoundingClientRect();
7047
- if (rect.width === 0 && rect.height === 0) return;
7402
+ if (rect.width === 0 && rect.height === 0) {
7403
+ setPos({ top: window.innerHeight / 2, right: 8 });
7404
+ return;
7405
+ }
7048
7406
  setPos({
7049
7407
  top: rect.top + rect.height / 2,
7050
7408
  right: Math.max(0, window.innerWidth - rect.right)
@@ -7064,7 +7422,11 @@ function PreviewReopenPill({ anchorRef, onClick, ariaLabel, title, children }) {
7064
7422
  if (rafRef.current != null) cancelAnimationFrame(rafRef.current);
7065
7423
  };
7066
7424
  }, [anchorRef]);
7067
- if (typeof document === "undefined" || !pos) return null;
7425
+ if (typeof document === "undefined") return null;
7426
+ const effectivePos = pos ?? {
7427
+ top: typeof window !== "undefined" ? window.innerHeight / 2 : 200,
7428
+ right: 8
7429
+ };
7068
7430
  return createPortal(
7069
7431
  /* @__PURE__ */ jsx(
7070
7432
  "button",
@@ -7076,8 +7438,8 @@ function PreviewReopenPill({ anchorRef, onClick, ariaLabel, title, children }) {
7076
7438
  title,
7077
7439
  style: {
7078
7440
  position: "fixed",
7079
- top: pos.top,
7080
- right: pos.right,
7441
+ top: effectivePos.top,
7442
+ right: effectivePos.right,
7081
7443
  // Pull half the pill width out into the gutter so it visually
7082
7444
  // anchors *to* the editor edge rather than sitting inside it.
7083
7445
  transform: "translate(50%, -50%)"
@@ -7334,12 +7696,17 @@ function RecordsAdminShell(props) {
7334
7696
  }),
7335
7697
  [props.SL, props.collectionId, props.appId, props.recordType]
7336
7698
  );
7699
+ const recordChangeRef = useRef(null);
7700
+ const onRecordChange = useCallback((notice) => {
7701
+ recordChangeRef.current?.(notice);
7702
+ }, []);
7337
7703
  return /* @__PURE__ */ jsx(
7338
7704
  EditorSessionProvider,
7339
7705
  {
7340
7706
  ctx,
7341
7707
  defaultValueFactory: props.defaultData,
7342
7708
  hooks: props.hooks,
7709
+ onRecordChange,
7343
7710
  onHookNotice: (notice) => {
7344
7711
  console.warn(`[RecordsAdmin] ${notice.kind} hook failed`, notice.error);
7345
7712
  try {
@@ -7352,7 +7719,7 @@ function RecordsAdminShell(props) {
7352
7719
  } catch {
7353
7720
  }
7354
7721
  },
7355
- children: /* @__PURE__ */ jsx(RecordsAdminShellInner, { ...props })
7722
+ children: /* @__PURE__ */ jsx(RecordsAdminShellInner, { ...props, recordChangeRef })
7356
7723
  }
7357
7724
  );
7358
7725
  }
@@ -7385,7 +7752,8 @@ function RecordsAdminShellInner(props) {
7385
7752
  recordActions,
7386
7753
  icons: iconsOverride,
7387
7754
  // Deep linking
7388
- deepLink
7755
+ deepLink,
7756
+ recordChangeRef
7389
7757
  } = props;
7390
7758
  const {
7391
7759
  show: showHeader,
@@ -7412,7 +7780,8 @@ function RecordsAdminShellInner(props) {
7412
7780
  groupBy,
7413
7781
  defaultGroupKey,
7414
7782
  onGroupExpanded,
7415
- density = "comfortable"
7783
+ density = "comfortable",
7784
+ pageSize: railPageSize
7416
7785
  } = rail ?? {};
7417
7786
  const {
7418
7787
  tabs: editorTabs = "off",
@@ -7435,7 +7804,10 @@ function RecordsAdminShellInner(props) {
7435
7804
  renderEmpty: renderItemEmpty,
7436
7805
  cardSize: itemCardSize = "md",
7437
7806
  railMode: collectionRailMode = "siblings",
7438
- toSummary: itemToSummary
7807
+ toSummary: itemToSummary,
7808
+ pageSize: itemsPageSize,
7809
+ searchableFields: itemsSearchableFields,
7810
+ searchable: itemsSearchable
7439
7811
  } = items ?? {};
7440
7812
  const {
7441
7813
  strategy: dirtyStrategy = "keep",
@@ -7495,6 +7867,21 @@ function RecordsAdminShellInner(props) {
7495
7867
  [SL, collectionId, appId, recordType]
7496
7868
  );
7497
7869
  const queryClient = useQueryClient();
7870
+ useEffect(() => {
7871
+ recordChangeRef.current = (notice) => {
7872
+ if (notice.kind === "saved") {
7873
+ patchRecordIntoCaches(queryClient, notice.ctx, notice.record);
7874
+ } else {
7875
+ removeRecordFromCaches(queryClient, notice.ctx, notice.recordId);
7876
+ }
7877
+ queryClient.invalidateQueries({
7878
+ queryKey: scopeCountsQueryKey(notice.ctx.collectionId, notice.ctx.appId, notice.ctx.recordType)
7879
+ });
7880
+ };
7881
+ return () => {
7882
+ recordChangeRef.current = null;
7883
+ };
7884
+ }, [queryClient, recordChangeRef]);
7498
7885
  const probe = useScopeProbe({ SL, collectionId });
7499
7886
  const scopeCounts = useScopeCounts({ ctx });
7500
7887
  const topLevelScopes = useMemo(() => {
@@ -7577,7 +7964,8 @@ function RecordsAdminShellInner(props) {
7577
7964
  probeIsLoading: probe.isLoading,
7578
7965
  selectedProductId,
7579
7966
  drillTab,
7580
- classify: classify3
7967
+ classify: classify3,
7968
+ pageSize: railPageSize
7581
7969
  });
7582
7970
  const {
7583
7971
  search,
@@ -7658,7 +8046,8 @@ function RecordsAdminShellInner(props) {
7658
8046
  // host-supplied lifecycle grouping has the full picture.
7659
8047
  includeAll: isCollection && activeScope === "all",
7660
8048
  enabled: isCollection,
7661
- toSummary: itemToSummary
8049
+ toSummary: itemToSummary,
8050
+ pageSize: itemsPageSize
7662
8051
  });
7663
8052
  useEffect(() => {
7664
8053
  if (skipNextItemResetRef.current) {
@@ -7667,6 +8056,36 @@ function RecordsAdminShellInner(props) {
7667
8056
  }
7668
8057
  setSelectedItemId(null);
7669
8058
  }, [editingScope?.raw]);
8059
+ const isLifecycleRailEarly = (activeScope === "all" || activeScope === "collection") && isCollection && !!groupBy;
8060
+ const lifecycleBucketLabel = useMemo(() => {
8061
+ if (!isLifecycleRailEarly || !selectedLifecycleKey || !groupBy) return null;
8062
+ for (const it of collectionItems.items) {
8063
+ const g = groupBy(it);
8064
+ if (g && g.key === selectedLifecycleKey) return g.label ?? null;
8065
+ }
8066
+ return null;
8067
+ }, [isLifecycleRailEarly, selectedLifecycleKey, groupBy, collectionItems.items]);
8068
+ const scopedCollectionItemsList = useMemo(() => {
8069
+ if (!isLifecycleRailEarly || !selectedLifecycleKey || !groupBy) return collectionItems.items;
8070
+ return collectionItems.items.filter((it) => {
8071
+ const g = groupBy(it);
8072
+ return g?.key === selectedLifecycleKey;
8073
+ });
8074
+ }, [isLifecycleRailEarly, selectedLifecycleKey, groupBy, collectionItems.items]);
8075
+ useEffect(() => {
8076
+ if (!isLifecycleRailEarly || !groupBy) return;
8077
+ if (selectedLifecycleKey || !selectedItemId) return;
8078
+ const row = collectionItems.items.find(
8079
+ (it) => it.itemId === selectedItemId || it.id === selectedItemId
8080
+ );
8081
+ if (!row) return;
8082
+ const g = groupBy(row);
8083
+ if (g?.key) setSelectedLifecycleKey(g.key);
8084
+ }, [isLifecycleRailEarly, groupBy, selectedItemId, selectedLifecycleKey, collectionItems.items, setSelectedLifecycleKey]);
8085
+ const scopedCollectionItems = useMemo(() => ({
8086
+ ...collectionItems,
8087
+ items: scopedCollectionItemsList
8088
+ }), [collectionItems, scopedCollectionItemsList]);
7670
8089
  const { lastAppliedDLRef } = useShellDeepLink({
7671
8090
  deepLinkState,
7672
8091
  editingScope,
@@ -7769,7 +8188,6 @@ function RecordsAdminShellInner(props) {
7769
8188
  if (isCreate && isCollection && savedRecordId && isDraftId3(selectedItemId)) {
7770
8189
  setSelectedItemId(savedRecordId);
7771
8190
  }
7772
- await refetchAll();
7773
8191
  if (!isCollection && isCreate && activeScope === "collection") {
7774
8192
  setSelectedRecordId(savedRecordId ?? null);
7775
8193
  }
@@ -7788,7 +8206,6 @@ function RecordsAdminShellInner(props) {
7788
8206
  setSelectedRecordId(null);
7789
8207
  setDraftKind(null);
7790
8208
  }
7791
- await refetchAll();
7792
8209
  setIsReconcilingRecordSelection(false);
7793
8210
  }
7794
8211
  });
@@ -7954,7 +8371,7 @@ function RecordsAdminShellInner(props) {
7954
8371
  setSelectedItemId,
7955
8372
  editingScope,
7956
8373
  baseScopeRef,
7957
- collectionItems,
8374
+ collectionItems: scopedCollectionItems,
7958
8375
  queryClient,
7959
8376
  ctx,
7960
8377
  collectionId,
@@ -8670,7 +9087,7 @@ function RecordsAdminShellInner(props) {
8670
9087
  !railHidden && /* @__PURE__ */ jsx("aside", { className: "border-r overflow-hidden flex flex-col", style: { borderColor: "hsl(var(--ra-border))", background: "hsl(var(--ra-surface))" }, children: isCollection && selectedItemId && collectionRailMode === "siblings" && ruleWizardStep === null ? /* @__PURE__ */ jsx(
8671
9088
  SiblingRail,
8672
9089
  {
8673
- items: collectionItems.items,
9090
+ items: scopedCollectionItemsList,
8674
9091
  selectedItemId,
8675
9092
  isLoading: collectionItems.isLoading,
8676
9093
  error: collectionItems.error,
@@ -8680,8 +9097,13 @@ function RecordsAdminShellInner(props) {
8680
9097
  itemNoun: itemNounLabel,
8681
9098
  dirtyKeys,
8682
9099
  errorKeys,
8683
- contextKind: activeScope === "rule" ? "Rule" : activeScope === "product" ? "Product" : activeScope === "collection" ? "Global" : activeScope === "all" ? "All records" : activeScope === "variant" ? "Variant" : activeScope === "batch" ? "Batch" : activeScope === "facet" ? "Facet" : void 0,
8684
- contextSummary: activeScope === "rule" ? activeRuleSummary : activeScope === "product" ? editorHeaderLabel ?? null : null,
9100
+ hasNextPage: !!collectionItems.hasNextPage,
9101
+ isFetchingNextPage: !!collectionItems.isFetchingNextPage,
9102
+ onLoadMore: () => {
9103
+ void collectionItems.fetchNextPage();
9104
+ },
9105
+ 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,
9106
+ contextSummary: isLifecycleRailEarly && lifecycleBucketLabel ? `${scopedCollectionItemsList.length} ${itemNounLabel}${scopedCollectionItemsList.length === 1 ? "" : "s"}` : activeScope === "rule" ? activeRuleSummary : activeScope === "product" ? editorHeaderLabel ?? null : null,
8685
9107
  i18n
8686
9108
  }
8687
9109
  ) : /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -8859,19 +9281,29 @@ function RecordsAdminShellInner(props) {
8859
9281
  i18n
8860
9282
  }
8861
9283
  ),
8862
- isProductTab && !productPinned && productBrowse.hasNextPage && /* @__PURE__ */ jsx("div", { className: "p-2", children: /* @__PURE__ */ jsx(
8863
- "button",
9284
+ isProductTab && !productPinned && /* @__PURE__ */ jsx(
9285
+ LoadMoreFooter,
8864
9286
  {
8865
- type: "button",
8866
- onClick: () => {
9287
+ shown: leftItems.length,
9288
+ hasNextPage: !!productBrowse.hasNextPage,
9289
+ isFetchingNextPage: !!productBrowse.isFetchingNextPage,
9290
+ onLoadMore: () => {
8867
9291
  void productBrowse.fetchNextPage();
8868
- },
8869
- disabled: productBrowse.isFetchingNextPage,
8870
- className: "w-full text-xs py-2 rounded-md border transition-opacity disabled:opacity-50 hover:bg-[hsl(var(--ra-muted))]",
8871
- style: { borderColor: "hsl(var(--ra-border))", color: "hsl(var(--ra-text))" },
8872
- children: productBrowse.isFetchingNextPage ? "Loading\u2026" : `Load more (${leftItems.length} shown)`
9292
+ }
8873
9293
  }
8874
- ) })
9294
+ ),
9295
+ isRecordsTab && (!isCollection || !(isAllTab || isGlobalTab)) && /* @__PURE__ */ jsx(
9296
+ LoadMoreFooter,
9297
+ {
9298
+ shown: recordList.items.length,
9299
+ total: recordList.total,
9300
+ hasNextPage: !!recordList.hasNextPage,
9301
+ isFetchingNextPage: !!recordList.isFetchingNextPage,
9302
+ onLoadMore: () => {
9303
+ void recordList.fetchNextPage();
9304
+ }
9305
+ }
9306
+ )
8875
9307
  ] })
8876
9308
  ] }) })
8877
9309
  ] }) }),
@@ -8956,6 +9388,14 @@ function RecordsAdminShellInner(props) {
8956
9388
  ruleSummary: activeRuleSummary,
8957
9389
  rowActions: wrappedRecordActions,
8958
9390
  rowClipboard,
9391
+ searchableFields: itemsSearchableFields,
9392
+ searchable: itemsSearchable,
9393
+ total: collectionItems.total,
9394
+ hasNextPage: !!collectionItems.hasNextPage,
9395
+ isFetchingNextPage: !!collectionItems.isFetchingNextPage,
9396
+ onLoadMore: () => {
9397
+ void collectionItems.fetchNextPage();
9398
+ },
8959
9399
  i18n
8960
9400
  }
8961
9401
  ),
@@ -10045,6 +10485,6 @@ function useMergedRecord(args) {
10045
10485
  // src/components/RecordsAdmin/index.ts
10046
10486
  assertComponentStylesLoaded("records-admin");
10047
10487
 
10048
- export { ALL_ITEM_VIEWS, ALL_PRESENTATIONS, BatchList, BulkActionsMenu, DEFAULT_DEEP_LINK_PARAM_NAMES, DEFAULT_I18N, DEFAULT_ICONS, DefaultItemCards, DefaultItemTable, DefaultRecordCard, DefaultRecordRow, DeleteButton, DirtyDraftProvider, DrawerPreview, EditorItemNav, EmptyState, ErrorState, FacetList, InheritanceMarker, InheritanceProvider, InlinePreview, IntroCard, ItemListView, ItemViewSwitcher, LoadingState, PresentationSwitcher, PreviewScopePicker, PreviewToggleButton, ProductDrillDown, ProductList, RecordBrowser, RecordEditor, RecordList, RecordsAdminShell, ResolvedPreview, ScopeBreadcrumb, ScopeTabs, SiblingRail, SidePreview, StatusDot, StatusFilterPills, StatusIcon, TabbedPreview, UtilityRow, VariantList, buildDraftKey, buildRef, checkPasteCompatibility, cloneValue, createDefaultDeepLinkAdapter, createPostMessageDeepLinkAdapter, createRouterDeepLinkAdapter, downloadBlob, exportCsv, importCsv, isInSmartLinksIframe, mergeIcons, normaliseRule, parseRef, pickHeaderIcon, resolutionChain, resolveRecord, ruleHash, rulesEqual, scopeCountsQueryKey, statusToneLabel, summariseRule, useCollectedRecords, useCollectionItems, useDeepLinkState, useDirtyDraft, useDirtyDraftActions, useDirtyDraftStore, useDirtyDrafts, useDirtyNavigation, useFacetBrowse, useIntroDismissed, useItemViewPref, useMergedRecord, usePresentationPref, useProductBrowse, useProductChildren, useRecordClipboard, useRecordEditor, useRecordList, useResolveAllRecords, useResolvedRecord, useRulePreview, useScopeCounts, useScopeProbe, useUnsavedGuard };
10488
+ export { ALL_ITEM_VIEWS, ALL_PRESENTATIONS, BatchList, BulkActionsMenu, DEFAULT_DEEP_LINK_PARAM_NAMES, DEFAULT_I18N, DEFAULT_ICONS, DefaultItemCards, DefaultItemTable, DefaultRecordCard, DefaultRecordRow, DeleteButton, DirtyDraftProvider, DrawerPreview, EditorItemNav, EmptyState, ErrorState, FacetList, InheritanceMarker, InheritanceProvider, InlinePreview, IntroCard, ItemListView, ItemViewSwitcher, LoadingState, PresentationSwitcher, PreviewReopenPill, PreviewScopePicker, PreviewToggleButton, ProductDrillDown, ProductList, RecordBrowser, RecordEditor, RecordList, RecordsAdminShell, ResolvedPreview, ScopeBreadcrumb, ScopeTabs, SiblingRail, SidePreview, StatusDot, StatusFilterPills, StatusIcon, TabbedPreview, UtilityRow, VariantList, buildDraftKey, buildRef, checkPasteCompatibility, cloneValue, createDefaultDeepLinkAdapter, createPostMessageDeepLinkAdapter, createRouterDeepLinkAdapter, downloadBlob, exportCsv, importCsv, isInSmartLinksIframe, mergeIcons, normaliseRule, parseRef, pickHeaderIcon, resolutionChain, resolveRecord, ruleHash, rulesEqual, scopeCountsQueryKey, statusToneLabel, summariseRule, useCollectedRecords, useCollectionItems, useDeepLinkState, useDirtyDraft, useDirtyDraftActions, useDirtyDraftStore, useDirtyDrafts, useDirtyNavigation, useFacetBrowse, useIntroDismissed, useItemViewPref, useMergedRecord, usePresentationPref, useProductBrowse, useProductChildren, useRecordClipboard, useRecordEditor, useRecordList, useResolveAllRecords, useResolvedRecord, useRulePreview, useScopeCounts, useScopeProbe, useUnsavedGuard };
10049
10489
  //# sourceMappingURL=index.js.map
10050
10490
  //# sourceMappingURL=index.js.map