strapi-plugin-bulk-updater 1.1.0 → 1.2.0

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.
@@ -422,6 +422,11 @@ function CsvManagerTab() {
422
422
  ] })
423
423
  ] }) });
424
424
  }
425
+ function getNestedValue(obj, path) {
426
+ if (!obj || !path) return void 0;
427
+ if (!path.includes(".")) return obj[path];
428
+ return path.split(".").reduce((acc, part) => acc && typeof acc === "object" ? acc[part] : void 0, obj);
429
+ }
425
430
  function getAvailableColumnsForCollection(col, selectedAttribute) {
426
431
  const cols = [
427
432
  {
@@ -442,7 +447,7 @@ function getAvailableColumnsForCollection(col, selectedAttribute) {
442
447
  if (attr === "name" || attr === "title" || attr === selectedAttribute) {
443
448
  return;
444
449
  }
445
- const formattedLabel = attr.charAt(0).toUpperCase() + attr.slice(1);
450
+ const formattedLabel = attr.includes(".") ? attr.split(".").map((s) => s.charAt(0).toUpperCase() + s.slice(1)).join(" > ") : attr.charAt(0).toUpperCase() + attr.slice(1);
446
451
  cols.push({
447
452
  key: `attr_${attr}`,
448
453
  label: formattedLabel,
@@ -528,7 +533,7 @@ function renderCellContent(colDef, entry, col, selectedAttribute, isMatch, hasAt
528
533
  ] });
529
534
  }
530
535
  case "target_attr": {
531
- const val = entry[selectedAttribute];
536
+ const val = getNestedValue(entry, selectedAttribute);
532
537
  const displayStr = formatDisplayValue(val);
533
538
  const isUnset = displayStr === "(empty / not set)" || displayStr === "(empty / unlinked)";
534
539
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -558,7 +563,7 @@ function renderCellContent(colDef, entry, col, selectedAttribute, isMatch, hasAt
558
563
  }
559
564
  default: {
560
565
  const attrName = colDef.key.replace("attr_", "");
561
- const rawVal = entry[attrName];
566
+ const rawVal = getNestedValue(entry, attrName);
562
567
  const displayStr = formatDisplayValue(rawVal);
563
568
  return /* @__PURE__ */ jsxRuntime.jsx(
564
569
  designSystem.Typography,
@@ -632,7 +637,8 @@ const BulkUpdater = () => {
632
637
  const [regexPattern, setRegexPattern] = React.useState("");
633
638
  const [filterOperator, setFilterOperator] = React.useState("none");
634
639
  const [filterQuery, setFilterQuery] = React.useState("");
635
- const [hideNonMatching, setHideNonMatching] = React.useState(false);
640
+ const [entrySearch, setEntrySearch] = React.useState("");
641
+ const isFilterActive = filterOperator !== "none" && (["empty", "not_empty"].includes(filterOperator) || Boolean(filterQuery.trim())) || Boolean(entrySearch.trim());
636
642
  const [lastResults, setLastResults] = React.useState(null);
637
643
  const [updateSummary, setUpdateSummary] = React.useState(null);
638
644
  const [collectionPages, setCollectionPages] = React.useState({});
@@ -728,12 +734,15 @@ const BulkUpdater = () => {
728
734
  setLoading(false);
729
735
  }
730
736
  };
731
- const loadCollectionPage = async (colUid, targetPage, customPageSize, customSortField, customSortOrder) => {
737
+ const loadCollectionPage = async (colUid, targetPage, customPageSize, customSortField, customSortOrder, overrideFilterOp, overrideFilterQuery, overrideEntrySearch, autoSelectReturned = true) => {
732
738
  const currentPageState = collectionPages[colUid];
733
739
  const size = customPageSize || currentPageState?.pageSize || defaultPageSize;
734
740
  const currentSort = collectionSorts[colUid] || { field: "createdAt", order: "desc" };
735
741
  const sortField = customSortField !== void 0 ? customSortField : currentSort.field;
736
742
  const sortOrder = customSortOrder !== void 0 ? customSortOrder : currentSort.order;
743
+ const op = overrideFilterOp !== void 0 ? overrideFilterOp : filterOperator;
744
+ const q = overrideFilterQuery !== void 0 ? overrideFilterQuery : filterQuery;
745
+ const s = overrideEntrySearch !== void 0 ? overrideEntrySearch : entrySearch;
737
746
  setCollectionPages((prev) => ({
738
747
  ...prev,
739
748
  [colUid]: {
@@ -747,16 +756,20 @@ const BulkUpdater = () => {
747
756
  pageSize: String(size)
748
757
  });
749
758
  if (selectedAttribute) params.set("attribute", selectedAttribute);
750
- if (filterOperator && filterOperator !== "none") {
751
- params.set("filterOperator", filterOperator);
752
- if (filterQuery) params.set("filterQuery", filterQuery);
759
+ if (op && op !== "none") {
760
+ params.set("filterOperator", op);
761
+ if (q) params.set("filterQuery", q);
762
+ }
763
+ if (s && s.trim()) {
764
+ params.set("search", s.trim());
753
765
  }
754
766
  if (sortField) {
755
767
  params.set("sortField", sortField);
756
768
  params.set("sortOrder", sortOrder);
757
769
  }
758
770
  const res = await get(`/bulk-updater/collections/${colUid}/entries?${params.toString()}`);
759
- if (res.data && res.data.success) {
771
+ if (res.data && (res.data.success || res.data.entries !== void 0)) {
772
+ const fetchedEntries = res.data.entries || [];
760
773
  setCollectionPages((prev) => ({
761
774
  ...prev,
762
775
  [colUid]: {
@@ -764,10 +777,20 @@ const BulkUpdater = () => {
764
777
  pageSize: res.data.pagination.pageSize,
765
778
  total: res.data.pagination.total,
766
779
  pageCount: res.data.pagination.pageCount,
767
- entries: res.data.entries || [],
780
+ entries: fetchedEntries,
768
781
  loading: false
769
782
  }
770
783
  }));
784
+ const isFilterActiveNow = op !== "none" && (["empty", "not_empty"].includes(op) || Boolean(q.trim())) || Boolean(s.trim());
785
+ if (isFilterActiveNow && autoSelectReturned) {
786
+ setSelectedEntries((prev) => {
787
+ const next = { ...prev };
788
+ fetchedEntries.forEach((e) => {
789
+ next[`${colUid}${KEY_SEP}${e.documentId}`] = true;
790
+ });
791
+ return next;
792
+ });
793
+ }
771
794
  }
772
795
  } catch (err) {
773
796
  toggleNotification({
@@ -831,6 +854,35 @@ const BulkUpdater = () => {
831
854
  fetchPendingBatches();
832
855
  }
833
856
  }, [activeTab]);
857
+ const isInitialFilterMount = React.useRef(true);
858
+ React.useEffect(() => {
859
+ if (isInitialFilterMount.current) {
860
+ isInitialFilterMount.current = false;
861
+ return;
862
+ }
863
+ const timer = setTimeout(() => {
864
+ if (collections.length > 0) {
865
+ const isFilterActiveNow = filterOperator !== "none" && (["empty", "not_empty"].includes(filterOperator) || Boolean(filterQuery.trim())) || Boolean(entrySearch.trim());
866
+ if (isFilterActiveNow) {
867
+ setSelectedEntries({});
868
+ }
869
+ collections.forEach((col) => {
870
+ loadCollectionPage(
871
+ col.uid,
872
+ 1,
873
+ void 0,
874
+ void 0,
875
+ void 0,
876
+ filterOperator,
877
+ filterQuery,
878
+ entrySearch,
879
+ true
880
+ );
881
+ });
882
+ }
883
+ }, 350);
884
+ return () => clearTimeout(timer);
885
+ }, [filterOperator, filterQuery, entrySearch]);
834
886
  const KEY_SEP = "@@@";
835
887
  const handleAttributeChange = (newAttr) => {
836
888
  if (newAttr !== selectedAttribute) {
@@ -838,7 +890,7 @@ const BulkUpdater = () => {
838
890
  setSelectedEntries({});
839
891
  setFilterOperator("none");
840
892
  setFilterQuery("");
841
- setHideNonMatching(false);
893
+ setEntrySearch("");
842
894
  setSelectedRelationDocId("");
843
895
  setAttributeValue("");
844
896
  if (relationsMeta[newAttr]) {
@@ -855,7 +907,7 @@ const BulkUpdater = () => {
855
907
  (c) => visibleTypeUids[c.uid] !== false && (!collectionSearch.trim() || c.displayName.toLowerCase().includes(collectionSearch.toLowerCase().trim()) || c.uid.toLowerCase().includes(collectionSearch.toLowerCase().trim()))
856
908
  );
857
909
  const handleGlobalPageSizeChange = (newSize) => {
858
- const capped = Math.min(100, Math.max(1, newSize));
910
+ const capped = Math.min(500, Math.max(1, newSize));
859
911
  setDefaultPageSize(capped);
860
912
  collections.forEach((col) => {
861
913
  if (!col.isSingleType) {
@@ -864,7 +916,7 @@ const BulkUpdater = () => {
864
916
  });
865
917
  };
866
918
  const handleCollectionPageSizeChange = (colUid, newSize) => {
867
- const capped = Math.min(100, Math.max(1, newSize));
919
+ const capped = Math.min(500, Math.max(1, newSize));
868
920
  loadCollectionPage(colUid, 1, capped);
869
921
  };
870
922
  const handleCollectionSortChange = (colUid, field, order) => {
@@ -888,7 +940,7 @@ const BulkUpdater = () => {
888
940
  };
889
941
  const entryMatchesFilter = (entry, attr) => {
890
942
  if (filterOperator === "none") return true;
891
- const val = entry[attr];
943
+ const val = getNestedValue(entry, attr);
892
944
  const displayStr = formatDisplayValue(val);
893
945
  const isValEmpty = val === void 0 || val === null || displayStr.trim() === "" || displayStr.trim().toLowerCase() === "(not set)" || displayStr.trim().toLowerCase() === "(empty / not set)" || displayStr.trim().toLowerCase() === "(empty / unlinked)";
894
946
  switch (filterOperator) {
@@ -908,64 +960,48 @@ const BulkUpdater = () => {
908
960
  };
909
961
  const getVisibleEntries = (col) => {
910
962
  const pageState = collectionPages[col.uid];
911
- const entries = pageState ? pageState.entries : col.entries || [];
912
- if (!hideNonMatching || filterOperator === "none") {
913
- return entries;
914
- }
915
- return entries.filter((e) => entryMatchesFilter(e, selectedAttribute));
963
+ return pageState ? pageState.entries : col.entries || [];
916
964
  };
917
965
  const matchingEntriesCount = React__default.default.useMemo(() => {
918
- if (filterOperator === "none") return 0;
966
+ if (!isFilterActive) return 0;
919
967
  let count = 0;
920
968
  filteredCollections.forEach((col) => {
921
- if (col.attributes.includes(selectedAttribute)) {
922
- const pageState = collectionPages[col.uid];
923
- const entries = pageState ? pageState.entries : col.entries || [];
924
- entries.forEach((entry) => {
925
- if (entryMatchesFilter(entry, selectedAttribute)) {
926
- count++;
927
- }
928
- });
969
+ const pageState = collectionPages[col.uid];
970
+ if (pageState) {
971
+ count += pageState.total;
929
972
  }
930
973
  });
931
974
  return count;
932
- }, [filteredCollections, collectionPages, selectedAttribute, filterOperator, filterQuery]);
975
+ }, [filteredCollections, collectionPages, isFilterActive]);
933
976
  const selectAllMatching = () => {
934
977
  const updated = { ...selectedEntries };
935
978
  filteredCollections.forEach((col) => {
936
- if (col.attributes.includes(selectedAttribute)) {
937
- const pageState = collectionPages[col.uid];
938
- const entries = pageState ? pageState.entries : col.entries || [];
939
- entries.forEach((e) => {
940
- if (entryMatchesFilter(e, selectedAttribute)) {
941
- updated[`${col.uid}${KEY_SEP}${e.documentId}`] = true;
942
- }
943
- });
944
- }
979
+ const pageState = collectionPages[col.uid];
980
+ const entries = pageState ? pageState.entries : col.entries || [];
981
+ entries.forEach((e) => {
982
+ updated[`${col.uid}${KEY_SEP}${e.documentId}`] = true;
983
+ });
945
984
  });
946
985
  setSelectedEntries(updated);
947
986
  };
948
987
  const deselectAllMatching = () => {
949
988
  const updated = { ...selectedEntries };
950
989
  filteredCollections.forEach((col) => {
951
- if (col.attributes.includes(selectedAttribute)) {
952
- const pageState = collectionPages[col.uid];
953
- const entries = pageState ? pageState.entries : col.entries || [];
954
- entries.forEach((e) => {
955
- if (entryMatchesFilter(e, selectedAttribute)) {
956
- delete updated[`${col.uid}${KEY_SEP}${e.documentId}`];
957
- }
958
- });
959
- }
990
+ const pageState = collectionPages[col.uid];
991
+ const entries = pageState ? pageState.entries : col.entries || [];
992
+ entries.forEach((e) => {
993
+ delete updated[`${col.uid}${KEY_SEP}${e.documentId}`];
994
+ });
960
995
  });
961
996
  setSelectedEntries(updated);
962
997
  };
963
998
  const clearFilter = () => {
964
999
  setFilterOperator("none");
965
1000
  setFilterQuery("");
966
- setHideNonMatching(false);
1001
+ setEntrySearch("");
1002
+ setSelectedEntries({});
967
1003
  collections.forEach((col) => {
968
- loadCollectionPage(col.uid, 1);
1004
+ loadCollectionPage(col.uid, 1, void 0, void 0, void 0, "none", "", "", false);
969
1005
  });
970
1006
  };
971
1007
  const isCollectionFullySelected = (col) => {
@@ -1087,6 +1123,7 @@ const BulkUpdater = () => {
1087
1123
  message: `Bulk update complete! Batch ID: ${res.data.batchId}. Updated: ${res.data.updatedCount}, Skipped: ${res.data.skippedCount}`
1088
1124
  });
1089
1125
  await fetchModels();
1126
+ await fetchAuditHistory();
1090
1127
  }
1091
1128
  } else {
1092
1129
  toggleNotification({
@@ -1373,7 +1410,7 @@ const BulkUpdater = () => {
1373
1410
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { variant: "pi", textColor: "neutral700", children: [
1374
1411
  /* @__PURE__ */ jsxRuntime.jsx("code", { children: latestActiveBatch.batchId }),
1375
1412
  " (",
1376
- latestActiveBatch.recordCount,
1413
+ latestActiveBatch.updatedCount,
1377
1414
  " entries updated by ",
1378
1415
  latestActiveBatch.userEmail,
1379
1416
  ")"
@@ -1600,24 +1637,25 @@ const BulkUpdater = () => {
1600
1637
  children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 3, children: [
1601
1638
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", alignItems: "center", wrap: "wrap", gap: 2, children: [
1602
1639
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, alignItems: "center", children: [
1603
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", fontWeight: "bold", children: "Find Targets by Current Value:" }),
1604
- filterOperator !== "none" && /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Badge, { backgroundColor: "primary100", textColor: "primary700", children: [
1640
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", fontWeight: "bold", children: "Search & Filter Targets:" }),
1641
+ isFilterActive && /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Badge, { backgroundColor: "primary100", textColor: "primary700", children: [
1605
1642
  matchingEntriesCount,
1606
1643
  " matching ",
1607
- matchingEntriesCount === 1 ? "entry" : "entries"
1644
+ matchingEntriesCount === 1 ? "entry" : "entries",
1645
+ " found in database"
1608
1646
  ] })
1609
1647
  ] }),
1610
- filterOperator !== "none" && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "ghost", size: "S", onClick: clearFilter, children: "Clear Filter" })
1648
+ isFilterActive && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "ghost", size: "S", onClick: clearFilter, children: "Clear Search & Filter" })
1611
1649
  ] }),
1612
1650
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 3, alignItems: "flex-end", wrap: "wrap", children: [
1613
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { style: { width: 240, minWidth: 200 }, children: /* @__PURE__ */ jsxRuntime.jsxs(
1651
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { style: { width: 220, minWidth: 180 }, children: /* @__PURE__ */ jsxRuntime.jsxs(
1614
1652
  designSystem.SingleSelect,
1615
1653
  {
1616
1654
  label: `Filter condition for "${selectedAttribute}"`,
1617
1655
  value: filterOperator,
1618
1656
  onChange: (val) => setFilterOperator(String(val)),
1619
1657
  children: [
1620
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "none", children: "Show All (No Filter)" }),
1658
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "none", children: "Show All (No Attribute Filter)" }),
1621
1659
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "empty", children: "Is Empty or Null" }),
1622
1660
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "not_empty", children: "Is Not Empty" }),
1623
1661
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "equals", children: "Equals Exact Text" }),
@@ -1626,28 +1664,33 @@ const BulkUpdater = () => {
1626
1664
  ]
1627
1665
  }
1628
1666
  ) }),
1629
- (filterOperator === "equals" || filterOperator === "contains" || filterOperator === "starts_with") && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { style: { flex: 1, minWidth: 220 }, children: /* @__PURE__ */ jsxRuntime.jsx(
1667
+ (filterOperator === "equals" || filterOperator === "contains" || filterOperator === "starts_with") && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { style: { flex: 1, minWidth: 200 }, children: /* @__PURE__ */ jsxRuntime.jsx(
1630
1668
  designSystem.TextInput,
1631
1669
  {
1632
- label: "Value to Search",
1670
+ label: `Value for "${selectedAttribute}"`,
1633
1671
  placeholder: "Type value to match...",
1634
1672
  value: filterQuery,
1635
1673
  onChange: (e) => setFilterQuery(e.target.value)
1636
1674
  }
1637
1675
  ) }),
1638
- filterOperator !== "none" && /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, alignItems: "center", children: [
1639
- /* @__PURE__ */ jsxRuntime.jsxs(
1676
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { style: { flex: 1, minWidth: 200 }, children: /* @__PURE__ */ jsxRuntime.jsx(
1677
+ designSystem.TextInput,
1678
+ {
1679
+ label: "Full-text Entry Search",
1680
+ placeholder: "Search title, name, or text across records...",
1681
+ value: entrySearch,
1682
+ onChange: (e) => setEntrySearch(e.target.value)
1683
+ }
1684
+ ) }),
1685
+ isFilterActive && /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, alignItems: "center", children: [
1686
+ /* @__PURE__ */ jsxRuntime.jsx(
1640
1687
  designSystem.Button,
1641
1688
  {
1642
1689
  variant: "default",
1643
1690
  size: "S",
1644
1691
  onClick: selectAllMatching,
1645
1692
  disabled: matchingEntriesCount === 0,
1646
- children: [
1647
- "Select Matching (",
1648
- matchingEntriesCount,
1649
- ")"
1650
- ]
1693
+ children: "Select All Loaded"
1651
1694
  }
1652
1695
  ),
1653
1696
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -1657,19 +1700,12 @@ const BulkUpdater = () => {
1657
1700
  size: "S",
1658
1701
  onClick: deselectAllMatching,
1659
1702
  disabled: matchingEntriesCount === 0,
1660
- children: "Deselect Matching"
1703
+ children: "Deselect All Loaded"
1661
1704
  }
1662
1705
  )
1663
1706
  ] })
1664
1707
  ] }),
1665
- filterOperator !== "none" && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { gap: 2, alignItems: "center", marginTop: 1, children: /* @__PURE__ */ jsxRuntime.jsx(
1666
- designSystem.Checkbox,
1667
- {
1668
- checked: hideNonMatching,
1669
- onCheckedChange: (checked) => setHideNonMatching(Boolean(checked)),
1670
- children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral700", children: "Only display matching entries in tables (hide non-matching)" })
1671
- }
1672
- ) })
1708
+ isFilterActive && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { gap: 2, alignItems: "center", marginTop: 1, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Badge, { backgroundColor: "success100", textColor: "success700", size: "S", children: "✓ Filter active: Showing only matching entries. All returned matching records are pre-selected." }) })
1673
1709
  ] })
1674
1710
  }
1675
1711
  ),
@@ -1763,8 +1799,8 @@ const BulkUpdater = () => {
1763
1799
  }
1764
1800
  ) }),
1765
1801
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, alignItems: "center", style: { marginLeft: "auto" }, children: [
1766
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: "Default page size (max 100):" }),
1767
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { style: { width: 120 }, children: /* @__PURE__ */ jsxRuntime.jsxs(
1802
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: "Default page size (max 500):" }),
1803
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { style: { width: 130 }, children: /* @__PURE__ */ jsxRuntime.jsxs(
1768
1804
  designSystem.SingleSelect,
1769
1805
  {
1770
1806
  size: "S",
@@ -1775,7 +1811,9 @@ const BulkUpdater = () => {
1775
1811
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "10", children: "10 / page" }),
1776
1812
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "25", children: "25 / page" }),
1777
1813
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "50", children: "50 / page" }),
1778
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "100", children: "100 / page" })
1814
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "100", children: "100 / page" }),
1815
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "250", children: "250 / page" }),
1816
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "500", children: "500 / page" })
1779
1817
  ]
1780
1818
  }
1781
1819
  ) })
@@ -1790,7 +1828,7 @@ const BulkUpdater = () => {
1790
1828
  const pageSize = pageState ? pageState.pageSize : defaultPageSize;
1791
1829
  const hasAttr = col.attributes.includes(selectedAttribute);
1792
1830
  const visibleEntries = getVisibleEntries(col);
1793
- const matchingColCount = entries.filter((e) => entryMatchesFilter(e, selectedAttribute)).length;
1831
+ entries.filter((e) => entryMatchesFilter(e, selectedAttribute)).length;
1794
1832
  const isFullySelected = isCollectionFullySelected(col);
1795
1833
  const isPartiallySelected = isCollectionPartiallySelected(col);
1796
1834
  const currentSort = collectionSorts[col.uid] || { field: "createdAt", order: "desc" };
@@ -1899,6 +1937,9 @@ const BulkUpdater = () => {
1899
1937
  params.set("filterOperator", filterOperator);
1900
1938
  if (filterQuery) params.set("filterQuery", filterQuery);
1901
1939
  }
1940
+ if (entrySearch && entrySearch.trim()) {
1941
+ params.set("search", entrySearch.trim());
1942
+ }
1902
1943
  const res = await get(`/bulk-updater/csv/export/${col.uid}?${params.toString()}`);
1903
1944
  const csvStr = res.data?.csvContent || (typeof res.data === "string" ? res.data : "");
1904
1945
  if (!csvStr) {
@@ -1931,7 +1972,7 @@ const BulkUpdater = () => {
1931
1972
  children: "Export CSV"
1932
1973
  }
1933
1974
  ),
1934
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral500", children: col.isSingleType ? "1 single entry" : filterOperator !== "none" ? `${matchingColCount} matching of ${totalEntries} entries` : `${totalEntries} entries` })
1975
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral500", children: col.isSingleType ? "1 single entry" : isFilterActive ? `${totalEntries} matching entries in DB` : `${totalEntries} entries` })
1935
1976
  ] })
1936
1977
  ] }),
1937
1978
  openColumnPickerUid === col.uid && /* @__PURE__ */ jsxRuntime.jsx(
@@ -2001,7 +2042,7 @@ const BulkUpdater = () => {
2001
2042
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tbody, { children: visibleEntries.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tr, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { colSpan: activeColumns.length, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: 4, style: { textAlign: "center" }, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral500", children: "No entries in this content type match the active filter criteria." }) }) }) }) : visibleEntries.map((entry) => {
2002
2043
  const key = `${col.uid}${KEY_SEP}${entry.documentId}`;
2003
2044
  const isSelected = Boolean(selectedEntries[key]);
2004
- const isMatch = filterOperator !== "none" && entryMatchesFilter(entry, selectedAttribute);
2045
+ const isMatch = isFilterActive;
2005
2046
  return /* @__PURE__ */ jsxRuntime.jsx(
2006
2047
  designSystem.Tr,
2007
2048
  {
@@ -2033,11 +2074,12 @@ const BulkUpdater = () => {
2033
2074
  Math.min(page * pageSize, totalEntries),
2034
2075
  " of ",
2035
2076
  totalEntries,
2036
- " entries"
2077
+ " ",
2078
+ isFilterActive ? "matching entries" : "entries"
2037
2079
  ] }),
2038
2080
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 1, alignItems: "center", children: [
2039
2081
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: "Show:" }),
2040
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { style: { width: 80 }, children: /* @__PURE__ */ jsxRuntime.jsxs(
2082
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { style: { width: 85 }, children: /* @__PURE__ */ jsxRuntime.jsxs(
2041
2083
  designSystem.SingleSelect,
2042
2084
  {
2043
2085
  size: "S",
@@ -2048,12 +2090,27 @@ const BulkUpdater = () => {
2048
2090
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "10", children: "10" }),
2049
2091
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "25", children: "25" }),
2050
2092
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "50", children: "50" }),
2051
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "100", children: "100" })
2093
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "100", children: "100" }),
2094
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "250", children: "250" }),
2095
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "500", children: "500" })
2052
2096
  ]
2053
2097
  }
2054
2098
  ) }),
2055
2099
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral500", children: "per page" })
2056
- ] })
2100
+ ] }),
2101
+ totalEntries > visibleEntries.length && /* @__PURE__ */ jsxRuntime.jsxs(
2102
+ designSystem.Button,
2103
+ {
2104
+ variant: "tertiary",
2105
+ size: "S",
2106
+ onClick: () => handleCollectionPageSizeChange(col.uid, Math.min(totalEntries, 500)),
2107
+ children: [
2108
+ "Load all ",
2109
+ totalEntries,
2110
+ " entries"
2111
+ ]
2112
+ }
2113
+ )
2057
2114
  ] }),
2058
2115
  pageCount > 1 && /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, alignItems: "center", children: [
2059
2116
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -2711,4 +2768,5 @@ const BulkUpdater = () => {
2711
2768
  exports.default = BulkUpdater;
2712
2769
  exports.formatDisplayValue = formatDisplayValue;
2713
2770
  exports.getAvailableColumnsForCollection = getAvailableColumnsForCollection;
2714
- //# sourceMappingURL=BulkUpdater-BRcMQGP3.js.map
2771
+ exports.getNestedValue = getNestedValue;
2772
+ //# sourceMappingURL=BulkUpdater-DCrCPKSe.js.map