strapi-plugin-bulk-updater 1.2.7 → 1.2.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.
@@ -1432,7 +1432,7 @@ const BulkUpdater = () => {
1432
1432
  storedAttr = localStorage.getItem(LAST_ATTR_KEY);
1433
1433
  } catch {
1434
1434
  }
1435
- const resolvedAttr = storedAttr && attrs.includes(storedAttr) ? storedAttr : attrs.includes(selectedAttribute) ? selectedAttribute : attrs[0] || "metaDescription";
1435
+ const resolvedAttr = storedAttr && attrs.includes(storedAttr) ? storedAttr : selectedAttribute && attrs.includes(selectedAttribute) ? selectedAttribute : "";
1436
1436
  setSelectedAttribute(resolvedAttr);
1437
1437
  if (resolvedAttr && data.relationsMeta && data.relationsMeta[resolvedAttr]) {
1438
1438
  fetchRelationOptions(data.relationsMeta[resolvedAttr].targetUid);
@@ -1630,7 +1630,11 @@ const BulkUpdater = () => {
1630
1630
  if (newAttr !== selectedAttribute) {
1631
1631
  setSelectedAttribute(newAttr);
1632
1632
  try {
1633
- localStorage.setItem(LAST_ATTR_KEY, newAttr);
1633
+ if (newAttr) {
1634
+ localStorage.setItem(LAST_ATTR_KEY, newAttr);
1635
+ } else {
1636
+ localStorage.removeItem(LAST_ATTR_KEY);
1637
+ }
1634
1638
  } catch {
1635
1639
  }
1636
1640
  setSelectedEntries({});
@@ -1639,17 +1643,19 @@ const BulkUpdater = () => {
1639
1643
  setEntrySearch("");
1640
1644
  setSelectedRelationDocId("");
1641
1645
  setAttributeValue("");
1642
- if (relationsMeta[newAttr]) {
1646
+ if (newAttr && relationsMeta[newAttr]) {
1643
1647
  fetchRelationOptions(relationsMeta[newAttr].targetUid);
1644
1648
  } else {
1645
1649
  setRelationOptions([]);
1646
1650
  }
1647
- const collectionsToLoad = collections.filter(
1648
- (col) => visibleTypeUids[col.uid] !== false && col.attributes.includes(newAttr) && (!collectionPages[col.uid]?.entries || collectionPages[col.uid].entries.length === 0)
1649
- );
1650
- collectionsToLoad.forEach((col) => {
1651
- loadCollectionPage(col.uid, 1);
1652
- });
1651
+ if (newAttr) {
1652
+ const collectionsToLoad = collections.filter(
1653
+ (col) => visibleTypeUids[col.uid] !== false && col.attributes.includes(newAttr) && (!collectionPages[col.uid]?.entries || collectionPages[col.uid].entries.length === 0)
1654
+ );
1655
+ collectionsToLoad.forEach((col) => {
1656
+ loadCollectionPage(col.uid, 1);
1657
+ });
1658
+ }
1653
1659
  }
1654
1660
  };
1655
1661
  const filteredCollections = collections.filter(
@@ -1686,8 +1692,30 @@ const BulkUpdater = () => {
1686
1692
  });
1687
1693
  setVisibleTypeUids(newVis);
1688
1694
  };
1695
+ const [attributeSearch, setAttributeSearch] = React.useState("");
1696
+ const filteredAttributes = React.useMemo(() => {
1697
+ if (!attributeSearch.trim()) {
1698
+ return attributes;
1699
+ }
1700
+ const q = attributeSearch.toLowerCase().trim();
1701
+ const cleanQ = q.replace(/[^a-z0-9]/g, "");
1702
+ return attributes.filter((attr) => {
1703
+ const lower = attr.toLowerCase();
1704
+ const cleanLower = lower.replace(/[^a-z0-9]/g, "");
1705
+ const rel = relationsMeta[attr];
1706
+ const relTarget = (rel?.targetDisplayName || "").toLowerCase();
1707
+ return lower.includes(q) || cleanLower.includes(cleanQ) || relTarget.includes(q);
1708
+ });
1709
+ }, [attributes, attributeSearch, relationsMeta]);
1689
1710
  const memoizedComboboxOptions = React.useMemo(() => {
1690
- return attributes.map((attr) => {
1711
+ if (filteredAttributes.length === 0) {
1712
+ return /* @__PURE__ */ jsxRuntime.jsx(designSystem.ComboboxOption, { value: "__none__", disabled: true, textValue: "No matching attributes found", children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: [
1713
+ 'No matching attributes found for "',
1714
+ attributeSearch,
1715
+ '"'
1716
+ ] }) });
1717
+ }
1718
+ return filteredAttributes.map((attr) => {
1691
1719
  const rel = relationsMeta[attr];
1692
1720
  return /* @__PURE__ */ jsxRuntime.jsx(designSystem.ComboboxOption, { value: attr, textValue: attr, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", alignItems: "center", width: "100%", gap: 2, children: [
1693
1721
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", fontWeight: attr === selectedAttribute ? "bold" : "regular", children: attr }),
@@ -1697,7 +1725,7 @@ const BulkUpdater = () => {
1697
1725
  ] }) : attr.includes(".") ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Badge, { backgroundColor: "neutral150", textColor: "neutral700", size: "S", children: "component" }) : null
1698
1726
  ] }) }, attr);
1699
1727
  });
1700
- }, [attributes, relationsMeta, selectedAttribute]);
1728
+ }, [filteredAttributes, relationsMeta, selectedAttribute, attributeSearch]);
1701
1729
  const handleGlobalPageSizeChange = (newSize) => {
1702
1730
  const capped = Math.min(500, Math.max(1, newSize));
1703
1731
  setDefaultPageSize(capped);
@@ -2353,15 +2381,28 @@ const BulkUpdater = () => {
2353
2381
  /* @__PURE__ */ jsxRuntime.jsx(
2354
2382
  designSystem.Combobox,
2355
2383
  {
2356
- autocomplete: { type: "list", filter: "contains" },
2384
+ autocomplete: "none",
2357
2385
  placeholder: "Search attribute by name or relation...",
2358
- value: selectedAttribute,
2359
- textValue: selectedAttribute,
2386
+ value: selectedAttribute || void 0,
2387
+ clearLabel: "Clear attribute selection",
2388
+ onClear: () => {
2389
+ handleAttributeChange("");
2390
+ setAttributeSearch("");
2391
+ },
2392
+ onInputChange: (e) => {
2393
+ setAttributeSearch(e.target.value);
2394
+ },
2395
+ onOpenChange: (isOpen) => {
2396
+ if (!isOpen) {
2397
+ setAttributeSearch("");
2398
+ }
2399
+ },
2360
2400
  loading: loading && attributes.length === 0,
2361
2401
  loadingMessage: "Discovering schema attributes...",
2362
2402
  onChange: (val) => {
2363
- if (val && typeof val === "string") {
2403
+ if (val && typeof val === "string" && val !== "__none__") {
2364
2404
  handleAttributeChange(val);
2405
+ setAttributeSearch("");
2365
2406
  }
2366
2407
  },
2367
2408
  children: memoizedComboboxOptions
@@ -2606,7 +2647,7 @@ const BulkUpdater = () => {
2606
2647
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { style: { width: 220, minWidth: 180 }, children: /* @__PURE__ */ jsxRuntime.jsxs(
2607
2648
  designSystem.SingleSelect,
2608
2649
  {
2609
- label: `Filter condition for "${selectedAttribute}"`,
2650
+ label: selectedAttribute ? `Filter condition for "${selectedAttribute}"` : "Filter condition",
2610
2651
  value: filterOperator,
2611
2652
  onChange: (val) => setFilterOperator(String(val)),
2612
2653
  children: [
@@ -2622,7 +2663,7 @@ const BulkUpdater = () => {
2622
2663
  (filterOperator === "equals" || filterOperator === "contains" || filterOperator === "starts_with") && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { style: { flex: 1, minWidth: 200 }, children: /* @__PURE__ */ jsxRuntime.jsx(
2623
2664
  designSystem.TextInput,
2624
2665
  {
2625
- label: `Value for "${selectedAttribute}"`,
2666
+ label: selectedAttribute ? `Value for "${selectedAttribute}"` : "Value to match",
2626
2667
  placeholder: "Type value to match...",
2627
2668
  value: filterQuery,
2628
2669
  onChange: (e) => setFilterQuery(e.target.value)
@@ -2750,7 +2791,7 @@ const BulkUpdater = () => {
2750
2791
  (col) => !typeVisibilitySearch.trim() || col.displayName.toLowerCase().includes(typeVisibilitySearch.toLowerCase().trim()) || col.uid.toLowerCase().includes(typeVisibilitySearch.toLowerCase().trim())
2751
2792
  ).map((col) => {
2752
2793
  const isVisible = visibleTypeUids[col.uid] !== false;
2753
- const hasAttr = col.attributes.includes(selectedAttribute);
2794
+ const hasAttr = selectedAttribute ? col.attributes.includes(selectedAttribute) : false;
2754
2795
  return /* @__PURE__ */ jsxRuntime.jsx(
2755
2796
  designSystem.Box,
2756
2797
  {
@@ -2824,9 +2865,9 @@ const BulkUpdater = () => {
2824
2865
  const page = pageState ? pageState.page : 1;
2825
2866
  const pageCount = pageState ? pageState.pageCount : 1;
2826
2867
  const pageSize = pageState ? pageState.pageSize : defaultPageSize;
2827
- const hasAttr = col.attributes.includes(selectedAttribute);
2868
+ const hasAttr = selectedAttribute ? col.attributes.includes(selectedAttribute) : false;
2828
2869
  const visibleEntries = getVisibleEntries(col);
2829
- entries.filter((e) => entryMatchesFilter(e, selectedAttribute)).length;
2870
+ selectedAttribute ? entries.filter((e) => entryMatchesFilter(e, selectedAttribute)).length : 0;
2830
2871
  const isFullySelected = isCollectionFullySelected(col);
2831
2872
  const isPartiallySelected = isCollectionPartiallySelected(col);
2832
2873
  const currentSort = collectionSorts[col.uid] || { field: "createdAt", order: "desc" };
@@ -2860,14 +2901,14 @@ const BulkUpdater = () => {
2860
2901
  ] })
2861
2902
  }
2862
2903
  ),
2863
- col.isSingleType ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Badge, { backgroundColor: "secondary100", textColor: "secondary700", children: "Single Type" }) : /* @__PURE__ */ jsxRuntime.jsx(
2904
+ col.isSingleType ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Badge, { backgroundColor: "secondary100", textColor: "secondary700", children: "Single Type" }) : selectedAttribute ? /* @__PURE__ */ jsxRuntime.jsx(
2864
2905
  designSystem.Badge,
2865
2906
  {
2866
2907
  backgroundColor: hasAttr ? "success100" : "warning100",
2867
2908
  textColor: hasAttr ? "success700" : "warning700",
2868
2909
  children: hasAttr ? `Schema has "${selectedAttribute}"` : `Schema lacks "${selectedAttribute}" (will skip)`
2869
2910
  }
2870
- )
2911
+ ) : null
2871
2912
  ] }),
2872
2913
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 3, alignItems: "center", wrap: "wrap", children: [
2873
2914
  !col.isSingleType && /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, alignItems: "center", children: [
@@ -3790,4 +3831,4 @@ exports.default = BulkUpdater;
3790
3831
  exports.formatDisplayValue = formatDisplayValue;
3791
3832
  exports.getAvailableColumnsForCollection = getAvailableColumnsForCollection;
3792
3833
  exports.getNestedValue = getNestedValue;
3793
- //# sourceMappingURL=BulkUpdater-2TTEWMXI.js.map
3834
+ //# sourceMappingURL=BulkUpdater-Q4rX3L5w.js.map