strapi-plugin-bulk-updater 1.1.0 → 1.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -6
- package/dist/_chunks/{BulkUpdater-BSZP0U18.mjs → BulkUpdater-BYtO2SHc.mjs} +199 -127
- package/dist/_chunks/BulkUpdater-BYtO2SHc.mjs.map +1 -0
- package/dist/_chunks/{BulkUpdater-BRcMQGP3.js → BulkUpdater-BdRJhVFh.js} +196 -124
- package/dist/_chunks/BulkUpdater-BdRJhVFh.js.map +1 -0
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +1 -1
- package/dist/server/index.js +524 -88
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +524 -88
- package/dist/server/index.mjs.map +1 -1
- package/package.json +1 -1
- package/dist/_chunks/BulkUpdater-BRcMQGP3.js.map +0 -1
- package/dist/_chunks/BulkUpdater-BSZP0U18.mjs.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
|
2
|
-
import React__default, { useState, useEffect } from "react";
|
|
2
|
+
import React__default, { useState, useEffect, useRef } from "react";
|
|
3
3
|
import { useFetchClient, useNotification } from "@strapi/strapi/admin";
|
|
4
|
-
import { Box, Flex, Typography, Button, SingleSelect, SingleSelectOption, Checkbox, Badge, Table, Thead, Tr, Th, Tbody, Td, Alert, TextInput } from "@strapi/design-system";
|
|
4
|
+
import { Box, Flex, Typography, Button, SingleSelect, SingleSelectOption, Checkbox, Badge, Table, Thead, Tr, Th, Tbody, Td, Alert, Field, Combobox, ComboboxOption, TextInput } from "@strapi/design-system";
|
|
5
5
|
import { ArrowClockwise, Download, Upload, Check, Play } from "@strapi/icons";
|
|
6
6
|
import { V as ValidationRulesTab } from "./ValidationRulesTab-BGcqM9cN.mjs";
|
|
7
7
|
function CsvManagerTab() {
|
|
@@ -418,6 +418,11 @@ function CsvManagerTab() {
|
|
|
418
418
|
] })
|
|
419
419
|
] }) });
|
|
420
420
|
}
|
|
421
|
+
function getNestedValue(obj, path) {
|
|
422
|
+
if (!obj || !path) return void 0;
|
|
423
|
+
if (!path.includes(".")) return obj[path];
|
|
424
|
+
return path.split(".").reduce((acc, part) => acc && typeof acc === "object" ? acc[part] : void 0, obj);
|
|
425
|
+
}
|
|
421
426
|
function getAvailableColumnsForCollection(col, selectedAttribute) {
|
|
422
427
|
const cols = [
|
|
423
428
|
{
|
|
@@ -438,7 +443,7 @@ function getAvailableColumnsForCollection(col, selectedAttribute) {
|
|
|
438
443
|
if (attr === "name" || attr === "title" || attr === selectedAttribute) {
|
|
439
444
|
return;
|
|
440
445
|
}
|
|
441
|
-
const formattedLabel = attr.charAt(0).toUpperCase() + attr.slice(1);
|
|
446
|
+
const formattedLabel = attr.includes(".") ? attr.split(".").map((s) => s.charAt(0).toUpperCase() + s.slice(1)).join(" > ") : attr.charAt(0).toUpperCase() + attr.slice(1);
|
|
442
447
|
cols.push({
|
|
443
448
|
key: `attr_${attr}`,
|
|
444
449
|
label: formattedLabel,
|
|
@@ -524,7 +529,7 @@ function renderCellContent(colDef, entry, col, selectedAttribute, isMatch, hasAt
|
|
|
524
529
|
] });
|
|
525
530
|
}
|
|
526
531
|
case "target_attr": {
|
|
527
|
-
const val = entry
|
|
532
|
+
const val = getNestedValue(entry, selectedAttribute);
|
|
528
533
|
const displayStr = formatDisplayValue(val);
|
|
529
534
|
const isUnset = displayStr === "(empty / not set)" || displayStr === "(empty / unlinked)";
|
|
530
535
|
return /* @__PURE__ */ jsx(
|
|
@@ -554,7 +559,7 @@ function renderCellContent(colDef, entry, col, selectedAttribute, isMatch, hasAt
|
|
|
554
559
|
}
|
|
555
560
|
default: {
|
|
556
561
|
const attrName = colDef.key.replace("attr_", "");
|
|
557
|
-
const rawVal = entry
|
|
562
|
+
const rawVal = getNestedValue(entry, attrName);
|
|
558
563
|
const displayStr = formatDisplayValue(rawVal);
|
|
559
564
|
return /* @__PURE__ */ jsx(
|
|
560
565
|
Typography,
|
|
@@ -628,7 +633,8 @@ const BulkUpdater = () => {
|
|
|
628
633
|
const [regexPattern, setRegexPattern] = useState("");
|
|
629
634
|
const [filterOperator, setFilterOperator] = useState("none");
|
|
630
635
|
const [filterQuery, setFilterQuery] = useState("");
|
|
631
|
-
const [
|
|
636
|
+
const [entrySearch, setEntrySearch] = useState("");
|
|
637
|
+
const isFilterActive = filterOperator !== "none" && (["empty", "not_empty"].includes(filterOperator) || Boolean(filterQuery.trim())) || Boolean(entrySearch.trim());
|
|
632
638
|
const [lastResults, setLastResults] = useState(null);
|
|
633
639
|
const [updateSummary, setUpdateSummary] = useState(null);
|
|
634
640
|
const [collectionPages, setCollectionPages] = useState({});
|
|
@@ -724,12 +730,15 @@ const BulkUpdater = () => {
|
|
|
724
730
|
setLoading(false);
|
|
725
731
|
}
|
|
726
732
|
};
|
|
727
|
-
const loadCollectionPage = async (colUid, targetPage, customPageSize, customSortField, customSortOrder) => {
|
|
733
|
+
const loadCollectionPage = async (colUid, targetPage, customPageSize, customSortField, customSortOrder, overrideFilterOp, overrideFilterQuery, overrideEntrySearch, autoSelectReturned = true) => {
|
|
728
734
|
const currentPageState = collectionPages[colUid];
|
|
729
735
|
const size = customPageSize || currentPageState?.pageSize || defaultPageSize;
|
|
730
736
|
const currentSort = collectionSorts[colUid] || { field: "createdAt", order: "desc" };
|
|
731
737
|
const sortField = customSortField !== void 0 ? customSortField : currentSort.field;
|
|
732
738
|
const sortOrder = customSortOrder !== void 0 ? customSortOrder : currentSort.order;
|
|
739
|
+
const op = overrideFilterOp !== void 0 ? overrideFilterOp : filterOperator;
|
|
740
|
+
const q = overrideFilterQuery !== void 0 ? overrideFilterQuery : filterQuery;
|
|
741
|
+
const s = overrideEntrySearch !== void 0 ? overrideEntrySearch : entrySearch;
|
|
733
742
|
setCollectionPages((prev) => ({
|
|
734
743
|
...prev,
|
|
735
744
|
[colUid]: {
|
|
@@ -743,16 +752,20 @@ const BulkUpdater = () => {
|
|
|
743
752
|
pageSize: String(size)
|
|
744
753
|
});
|
|
745
754
|
if (selectedAttribute) params.set("attribute", selectedAttribute);
|
|
746
|
-
if (
|
|
747
|
-
params.set("filterOperator",
|
|
748
|
-
if (
|
|
755
|
+
if (op && op !== "none") {
|
|
756
|
+
params.set("filterOperator", op);
|
|
757
|
+
if (q) params.set("filterQuery", q);
|
|
758
|
+
}
|
|
759
|
+
if (s && s.trim()) {
|
|
760
|
+
params.set("search", s.trim());
|
|
749
761
|
}
|
|
750
762
|
if (sortField) {
|
|
751
763
|
params.set("sortField", sortField);
|
|
752
764
|
params.set("sortOrder", sortOrder);
|
|
753
765
|
}
|
|
754
766
|
const res = await get(`/bulk-updater/collections/${colUid}/entries?${params.toString()}`);
|
|
755
|
-
if (res.data && res.data.success) {
|
|
767
|
+
if (res.data && (res.data.success || res.data.entries !== void 0)) {
|
|
768
|
+
const fetchedEntries = res.data.entries || [];
|
|
756
769
|
setCollectionPages((prev) => ({
|
|
757
770
|
...prev,
|
|
758
771
|
[colUid]: {
|
|
@@ -760,10 +773,20 @@ const BulkUpdater = () => {
|
|
|
760
773
|
pageSize: res.data.pagination.pageSize,
|
|
761
774
|
total: res.data.pagination.total,
|
|
762
775
|
pageCount: res.data.pagination.pageCount,
|
|
763
|
-
entries:
|
|
776
|
+
entries: fetchedEntries,
|
|
764
777
|
loading: false
|
|
765
778
|
}
|
|
766
779
|
}));
|
|
780
|
+
const isFilterActiveNow = op !== "none" && (["empty", "not_empty"].includes(op) || Boolean(q.trim())) || Boolean(s.trim());
|
|
781
|
+
if (isFilterActiveNow && autoSelectReturned) {
|
|
782
|
+
setSelectedEntries((prev) => {
|
|
783
|
+
const next = { ...prev };
|
|
784
|
+
fetchedEntries.forEach((e) => {
|
|
785
|
+
next[`${colUid}${KEY_SEP}${e.documentId}`] = true;
|
|
786
|
+
});
|
|
787
|
+
return next;
|
|
788
|
+
});
|
|
789
|
+
}
|
|
767
790
|
}
|
|
768
791
|
} catch (err) {
|
|
769
792
|
toggleNotification({
|
|
@@ -827,6 +850,35 @@ const BulkUpdater = () => {
|
|
|
827
850
|
fetchPendingBatches();
|
|
828
851
|
}
|
|
829
852
|
}, [activeTab]);
|
|
853
|
+
const isInitialFilterMount = useRef(true);
|
|
854
|
+
useEffect(() => {
|
|
855
|
+
if (isInitialFilterMount.current) {
|
|
856
|
+
isInitialFilterMount.current = false;
|
|
857
|
+
return;
|
|
858
|
+
}
|
|
859
|
+
const timer = setTimeout(() => {
|
|
860
|
+
if (collections.length > 0) {
|
|
861
|
+
const isFilterActiveNow = filterOperator !== "none" && (["empty", "not_empty"].includes(filterOperator) || Boolean(filterQuery.trim())) || Boolean(entrySearch.trim());
|
|
862
|
+
if (isFilterActiveNow) {
|
|
863
|
+
setSelectedEntries({});
|
|
864
|
+
}
|
|
865
|
+
collections.forEach((col) => {
|
|
866
|
+
loadCollectionPage(
|
|
867
|
+
col.uid,
|
|
868
|
+
1,
|
|
869
|
+
void 0,
|
|
870
|
+
void 0,
|
|
871
|
+
void 0,
|
|
872
|
+
filterOperator,
|
|
873
|
+
filterQuery,
|
|
874
|
+
entrySearch,
|
|
875
|
+
true
|
|
876
|
+
);
|
|
877
|
+
});
|
|
878
|
+
}
|
|
879
|
+
}, 350);
|
|
880
|
+
return () => clearTimeout(timer);
|
|
881
|
+
}, [filterOperator, filterQuery, entrySearch]);
|
|
830
882
|
const KEY_SEP = "@@@";
|
|
831
883
|
const handleAttributeChange = (newAttr) => {
|
|
832
884
|
if (newAttr !== selectedAttribute) {
|
|
@@ -834,7 +886,7 @@ const BulkUpdater = () => {
|
|
|
834
886
|
setSelectedEntries({});
|
|
835
887
|
setFilterOperator("none");
|
|
836
888
|
setFilterQuery("");
|
|
837
|
-
|
|
889
|
+
setEntrySearch("");
|
|
838
890
|
setSelectedRelationDocId("");
|
|
839
891
|
setAttributeValue("");
|
|
840
892
|
if (relationsMeta[newAttr]) {
|
|
@@ -851,7 +903,7 @@ const BulkUpdater = () => {
|
|
|
851
903
|
(c) => visibleTypeUids[c.uid] !== false && (!collectionSearch.trim() || c.displayName.toLowerCase().includes(collectionSearch.toLowerCase().trim()) || c.uid.toLowerCase().includes(collectionSearch.toLowerCase().trim()))
|
|
852
904
|
);
|
|
853
905
|
const handleGlobalPageSizeChange = (newSize) => {
|
|
854
|
-
const capped = Math.min(
|
|
906
|
+
const capped = Math.min(500, Math.max(1, newSize));
|
|
855
907
|
setDefaultPageSize(capped);
|
|
856
908
|
collections.forEach((col) => {
|
|
857
909
|
if (!col.isSingleType) {
|
|
@@ -860,7 +912,7 @@ const BulkUpdater = () => {
|
|
|
860
912
|
});
|
|
861
913
|
};
|
|
862
914
|
const handleCollectionPageSizeChange = (colUid, newSize) => {
|
|
863
|
-
const capped = Math.min(
|
|
915
|
+
const capped = Math.min(500, Math.max(1, newSize));
|
|
864
916
|
loadCollectionPage(colUid, 1, capped);
|
|
865
917
|
};
|
|
866
918
|
const handleCollectionSortChange = (colUid, field, order) => {
|
|
@@ -884,7 +936,7 @@ const BulkUpdater = () => {
|
|
|
884
936
|
};
|
|
885
937
|
const entryMatchesFilter = (entry, attr) => {
|
|
886
938
|
if (filterOperator === "none") return true;
|
|
887
|
-
const val = entry
|
|
939
|
+
const val = getNestedValue(entry, attr);
|
|
888
940
|
const displayStr = formatDisplayValue(val);
|
|
889
941
|
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)";
|
|
890
942
|
switch (filterOperator) {
|
|
@@ -904,64 +956,48 @@ const BulkUpdater = () => {
|
|
|
904
956
|
};
|
|
905
957
|
const getVisibleEntries = (col) => {
|
|
906
958
|
const pageState = collectionPages[col.uid];
|
|
907
|
-
|
|
908
|
-
if (!hideNonMatching || filterOperator === "none") {
|
|
909
|
-
return entries;
|
|
910
|
-
}
|
|
911
|
-
return entries.filter((e) => entryMatchesFilter(e, selectedAttribute));
|
|
959
|
+
return pageState ? pageState.entries : col.entries || [];
|
|
912
960
|
};
|
|
913
961
|
const matchingEntriesCount = React__default.useMemo(() => {
|
|
914
|
-
if (
|
|
962
|
+
if (!isFilterActive) return 0;
|
|
915
963
|
let count = 0;
|
|
916
964
|
filteredCollections.forEach((col) => {
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
entries.forEach((entry) => {
|
|
921
|
-
if (entryMatchesFilter(entry, selectedAttribute)) {
|
|
922
|
-
count++;
|
|
923
|
-
}
|
|
924
|
-
});
|
|
965
|
+
const pageState = collectionPages[col.uid];
|
|
966
|
+
if (pageState) {
|
|
967
|
+
count += pageState.total;
|
|
925
968
|
}
|
|
926
969
|
});
|
|
927
970
|
return count;
|
|
928
|
-
}, [filteredCollections, collectionPages,
|
|
971
|
+
}, [filteredCollections, collectionPages, isFilterActive]);
|
|
929
972
|
const selectAllMatching = () => {
|
|
930
973
|
const updated = { ...selectedEntries };
|
|
931
974
|
filteredCollections.forEach((col) => {
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
updated[`${col.uid}${KEY_SEP}${e.documentId}`] = true;
|
|
938
|
-
}
|
|
939
|
-
});
|
|
940
|
-
}
|
|
975
|
+
const pageState = collectionPages[col.uid];
|
|
976
|
+
const entries = pageState ? pageState.entries : col.entries || [];
|
|
977
|
+
entries.forEach((e) => {
|
|
978
|
+
updated[`${col.uid}${KEY_SEP}${e.documentId}`] = true;
|
|
979
|
+
});
|
|
941
980
|
});
|
|
942
981
|
setSelectedEntries(updated);
|
|
943
982
|
};
|
|
944
983
|
const deselectAllMatching = () => {
|
|
945
984
|
const updated = { ...selectedEntries };
|
|
946
985
|
filteredCollections.forEach((col) => {
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
delete updated[`${col.uid}${KEY_SEP}${e.documentId}`];
|
|
953
|
-
}
|
|
954
|
-
});
|
|
955
|
-
}
|
|
986
|
+
const pageState = collectionPages[col.uid];
|
|
987
|
+
const entries = pageState ? pageState.entries : col.entries || [];
|
|
988
|
+
entries.forEach((e) => {
|
|
989
|
+
delete updated[`${col.uid}${KEY_SEP}${e.documentId}`];
|
|
990
|
+
});
|
|
956
991
|
});
|
|
957
992
|
setSelectedEntries(updated);
|
|
958
993
|
};
|
|
959
994
|
const clearFilter = () => {
|
|
960
995
|
setFilterOperator("none");
|
|
961
996
|
setFilterQuery("");
|
|
962
|
-
|
|
997
|
+
setEntrySearch("");
|
|
998
|
+
setSelectedEntries({});
|
|
963
999
|
collections.forEach((col) => {
|
|
964
|
-
loadCollectionPage(col.uid, 1);
|
|
1000
|
+
loadCollectionPage(col.uid, 1, void 0, void 0, void 0, "none", "", "", false);
|
|
965
1001
|
});
|
|
966
1002
|
};
|
|
967
1003
|
const isCollectionFullySelected = (col) => {
|
|
@@ -1083,6 +1119,7 @@ const BulkUpdater = () => {
|
|
|
1083
1119
|
message: `Bulk update complete! Batch ID: ${res.data.batchId}. Updated: ${res.data.updatedCount}, Skipped: ${res.data.skippedCount}`
|
|
1084
1120
|
});
|
|
1085
1121
|
await fetchModels();
|
|
1122
|
+
await fetchAuditHistory();
|
|
1086
1123
|
}
|
|
1087
1124
|
} else {
|
|
1088
1125
|
toggleNotification({
|
|
@@ -1369,7 +1406,7 @@ const BulkUpdater = () => {
|
|
|
1369
1406
|
/* @__PURE__ */ jsxs(Typography, { variant: "pi", textColor: "neutral700", children: [
|
|
1370
1407
|
/* @__PURE__ */ jsx("code", { children: latestActiveBatch.batchId }),
|
|
1371
1408
|
" (",
|
|
1372
|
-
latestActiveBatch.
|
|
1409
|
+
latestActiveBatch.updatedCount,
|
|
1373
1410
|
" entries updated by ",
|
|
1374
1411
|
latestActiveBatch.userEmail,
|
|
1375
1412
|
")"
|
|
@@ -1413,23 +1450,34 @@ const BulkUpdater = () => {
|
|
|
1413
1450
|
children: [
|
|
1414
1451
|
/* @__PURE__ */ jsx(Typography, { variant: "delta", tag: "h2", marginBottom: 4, fontWeight: "semiBold", children: "1. Configure Attribute Update" }),
|
|
1415
1452
|
/* @__PURE__ */ jsxs(Flex, { gap: 4, alignItems: "flex-end", wrap: "wrap", children: [
|
|
1416
|
-
/* @__PURE__ */ jsx(Box, { style: { minWidth:
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1453
|
+
/* @__PURE__ */ jsx(Box, { style: { minWidth: 280, flex: 1, maxWidth: 440 }, children: /* @__PURE__ */ jsxs(Field.Root, { children: [
|
|
1454
|
+
/* @__PURE__ */ jsx(Field.Label, { children: "Attribute to Update" }),
|
|
1455
|
+
/* @__PURE__ */ jsx(
|
|
1456
|
+
Combobox,
|
|
1457
|
+
{
|
|
1458
|
+
autocomplete: { type: "list", filter: "contains" },
|
|
1459
|
+
placeholder: "Search attribute by name or relation...",
|
|
1460
|
+
value: selectedAttribute,
|
|
1461
|
+
onChange: (val) => {
|
|
1462
|
+
if (val && typeof val === "string") {
|
|
1463
|
+
handleAttributeChange(val);
|
|
1464
|
+
}
|
|
1465
|
+
},
|
|
1466
|
+
children: attributes.map((attr) => {
|
|
1467
|
+
const rel = relationsMeta[attr];
|
|
1468
|
+
const cleanParts = attr.includes(".") ? attr.split(".").join(" ") : "";
|
|
1469
|
+
const labelText = `${attr} ${cleanParts} ${rel ? `relation ${rel.targetDisplayName}` : ""}`.trim();
|
|
1470
|
+
return /* @__PURE__ */ jsx(ComboboxOption, { value: attr, textValue: labelText, children: /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", alignItems: "center", width: "100%", gap: 2, children: [
|
|
1471
|
+
/* @__PURE__ */ jsx(Typography, { variant: "omega", fontWeight: attr === selectedAttribute ? "bold" : "regular", children: attr }),
|
|
1472
|
+
rel ? /* @__PURE__ */ jsxs(Badge, { backgroundColor: "secondary100", textColor: "secondary700", size: "S", children: [
|
|
1473
|
+
"relation ➔ ",
|
|
1474
|
+
rel.targetDisplayName
|
|
1475
|
+
] }) : attr.includes(".") ? /* @__PURE__ */ jsx(Badge, { backgroundColor: "neutral150", textColor: "neutral700", size: "S", children: "component" }) : null
|
|
1476
|
+
] }) }, attr);
|
|
1477
|
+
})
|
|
1478
|
+
}
|
|
1479
|
+
)
|
|
1480
|
+
] }) }),
|
|
1433
1481
|
/* @__PURE__ */ jsx(Box, { style: { flex: 1, minWidth: 340 }, children: relationsMeta[selectedAttribute] ? /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 1, style: { width: "100%" }, children: [
|
|
1434
1482
|
/* @__PURE__ */ jsxs(Flex, { gap: 2, alignItems: "center", wrap: "wrap", children: [
|
|
1435
1483
|
/* @__PURE__ */ jsxs(Typography, { variant: "pi", fontWeight: "bold", textColor: "neutral700", children: [
|
|
@@ -1445,28 +1493,31 @@ const BulkUpdater = () => {
|
|
|
1445
1493
|
relationsMeta[selectedAttribute].isMulti && /* @__PURE__ */ jsx(Badge, { backgroundColor: "primary100", textColor: "primary700", children: "Multi-Relation" })
|
|
1446
1494
|
] }),
|
|
1447
1495
|
/* @__PURE__ */ jsxs(Flex, { gap: 2, alignItems: "center", style: { width: "100%" }, children: [
|
|
1448
|
-
/* @__PURE__ */ jsx(Box, { style: { flex: 1, minWidth: 200 }, children: /* @__PURE__ */ jsxs(
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1496
|
+
/* @__PURE__ */ jsx(Box, { style: { flex: 1, minWidth: 200 }, children: /* @__PURE__ */ jsxs(Field.Root, { children: [
|
|
1497
|
+
/* @__PURE__ */ jsx(Field.Label, { children: `Choose ${relationsMeta[selectedAttribute].targetDisplayName}` }),
|
|
1498
|
+
/* @__PURE__ */ jsxs(
|
|
1499
|
+
Combobox,
|
|
1500
|
+
{
|
|
1501
|
+
autocomplete: { type: "list", filter: "contains" },
|
|
1502
|
+
placeholder: relationOptionsLoading ? "Loading entities..." : `Search & pick ${relationsMeta[selectedAttribute].targetDisplayName}...`,
|
|
1503
|
+
value: selectedRelationDocId,
|
|
1504
|
+
onChange: (val) => {
|
|
1505
|
+
const docId = val ? String(val) : "";
|
|
1506
|
+
setSelectedRelationDocId(docId);
|
|
1507
|
+
if (docId === "__clear__") {
|
|
1508
|
+
setAttributeValue(JSON.stringify({ mode: "clear", label: "(clear relation)" }));
|
|
1509
|
+
} else {
|
|
1510
|
+
const opt = relationOptions.find((o) => o.documentId === docId);
|
|
1511
|
+
setAttributeValue(JSON.stringify({ mode: relationMode, documentIds: [docId], label: opt?.label || docId }));
|
|
1512
|
+
}
|
|
1513
|
+
},
|
|
1514
|
+
children: [
|
|
1515
|
+
/* @__PURE__ */ jsx(ComboboxOption, { value: "__clear__", textValue: "Clear / Unlink Relation", children: "-- Clear / Unlink Relation --" }),
|
|
1516
|
+
relationOptions.map((opt) => /* @__PURE__ */ jsx(ComboboxOption, { value: opt.documentId, textValue: opt.label, children: opt.label }, opt.documentId))
|
|
1517
|
+
]
|
|
1518
|
+
}
|
|
1519
|
+
)
|
|
1520
|
+
] }) }),
|
|
1470
1521
|
relationsMeta[selectedAttribute].isMulti && /* @__PURE__ */ jsx(Box, { style: { width: 170 }, children: /* @__PURE__ */ jsxs(
|
|
1471
1522
|
SingleSelect,
|
|
1472
1523
|
{
|
|
@@ -1596,24 +1647,25 @@ const BulkUpdater = () => {
|
|
|
1596
1647
|
children: /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 3, children: [
|
|
1597
1648
|
/* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", alignItems: "center", wrap: "wrap", gap: 2, children: [
|
|
1598
1649
|
/* @__PURE__ */ jsxs(Flex, { gap: 2, alignItems: "center", children: [
|
|
1599
|
-
/* @__PURE__ */ jsx(Typography, { variant: "omega", fontWeight: "bold", children: "
|
|
1600
|
-
|
|
1650
|
+
/* @__PURE__ */ jsx(Typography, { variant: "omega", fontWeight: "bold", children: "Search & Filter Targets:" }),
|
|
1651
|
+
isFilterActive && /* @__PURE__ */ jsxs(Badge, { backgroundColor: "primary100", textColor: "primary700", children: [
|
|
1601
1652
|
matchingEntriesCount,
|
|
1602
1653
|
" matching ",
|
|
1603
|
-
matchingEntriesCount === 1 ? "entry" : "entries"
|
|
1654
|
+
matchingEntriesCount === 1 ? "entry" : "entries",
|
|
1655
|
+
" found in database"
|
|
1604
1656
|
] })
|
|
1605
1657
|
] }),
|
|
1606
|
-
|
|
1658
|
+
isFilterActive && /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "S", onClick: clearFilter, children: "Clear Search & Filter" })
|
|
1607
1659
|
] }),
|
|
1608
1660
|
/* @__PURE__ */ jsxs(Flex, { gap: 3, alignItems: "flex-end", wrap: "wrap", children: [
|
|
1609
|
-
/* @__PURE__ */ jsx(Box, { style: { width:
|
|
1661
|
+
/* @__PURE__ */ jsx(Box, { style: { width: 220, minWidth: 180 }, children: /* @__PURE__ */ jsxs(
|
|
1610
1662
|
SingleSelect,
|
|
1611
1663
|
{
|
|
1612
1664
|
label: `Filter condition for "${selectedAttribute}"`,
|
|
1613
1665
|
value: filterOperator,
|
|
1614
1666
|
onChange: (val) => setFilterOperator(String(val)),
|
|
1615
1667
|
children: [
|
|
1616
|
-
/* @__PURE__ */ jsx(SingleSelectOption, { value: "none", children: "Show All (No Filter)" }),
|
|
1668
|
+
/* @__PURE__ */ jsx(SingleSelectOption, { value: "none", children: "Show All (No Attribute Filter)" }),
|
|
1617
1669
|
/* @__PURE__ */ jsx(SingleSelectOption, { value: "empty", children: "Is Empty or Null" }),
|
|
1618
1670
|
/* @__PURE__ */ jsx(SingleSelectOption, { value: "not_empty", children: "Is Not Empty" }),
|
|
1619
1671
|
/* @__PURE__ */ jsx(SingleSelectOption, { value: "equals", children: "Equals Exact Text" }),
|
|
@@ -1622,28 +1674,33 @@ const BulkUpdater = () => {
|
|
|
1622
1674
|
]
|
|
1623
1675
|
}
|
|
1624
1676
|
) }),
|
|
1625
|
-
(filterOperator === "equals" || filterOperator === "contains" || filterOperator === "starts_with") && /* @__PURE__ */ jsx(Box, { style: { flex: 1, minWidth:
|
|
1677
|
+
(filterOperator === "equals" || filterOperator === "contains" || filterOperator === "starts_with") && /* @__PURE__ */ jsx(Box, { style: { flex: 1, minWidth: 200 }, children: /* @__PURE__ */ jsx(
|
|
1626
1678
|
TextInput,
|
|
1627
1679
|
{
|
|
1628
|
-
label:
|
|
1680
|
+
label: `Value for "${selectedAttribute}"`,
|
|
1629
1681
|
placeholder: "Type value to match...",
|
|
1630
1682
|
value: filterQuery,
|
|
1631
1683
|
onChange: (e) => setFilterQuery(e.target.value)
|
|
1632
1684
|
}
|
|
1633
1685
|
) }),
|
|
1634
|
-
|
|
1635
|
-
|
|
1686
|
+
/* @__PURE__ */ jsx(Box, { style: { flex: 1, minWidth: 200 }, children: /* @__PURE__ */ jsx(
|
|
1687
|
+
TextInput,
|
|
1688
|
+
{
|
|
1689
|
+
label: "Full-text Entry Search",
|
|
1690
|
+
placeholder: "Search title, name, or text across records...",
|
|
1691
|
+
value: entrySearch,
|
|
1692
|
+
onChange: (e) => setEntrySearch(e.target.value)
|
|
1693
|
+
}
|
|
1694
|
+
) }),
|
|
1695
|
+
isFilterActive && /* @__PURE__ */ jsxs(Flex, { gap: 2, alignItems: "center", children: [
|
|
1696
|
+
/* @__PURE__ */ jsx(
|
|
1636
1697
|
Button,
|
|
1637
1698
|
{
|
|
1638
1699
|
variant: "default",
|
|
1639
1700
|
size: "S",
|
|
1640
1701
|
onClick: selectAllMatching,
|
|
1641
1702
|
disabled: matchingEntriesCount === 0,
|
|
1642
|
-
children:
|
|
1643
|
-
"Select Matching (",
|
|
1644
|
-
matchingEntriesCount,
|
|
1645
|
-
")"
|
|
1646
|
-
]
|
|
1703
|
+
children: "Select All Loaded"
|
|
1647
1704
|
}
|
|
1648
1705
|
),
|
|
1649
1706
|
/* @__PURE__ */ jsx(
|
|
@@ -1653,19 +1710,12 @@ const BulkUpdater = () => {
|
|
|
1653
1710
|
size: "S",
|
|
1654
1711
|
onClick: deselectAllMatching,
|
|
1655
1712
|
disabled: matchingEntriesCount === 0,
|
|
1656
|
-
children: "Deselect
|
|
1713
|
+
children: "Deselect All Loaded"
|
|
1657
1714
|
}
|
|
1658
1715
|
)
|
|
1659
1716
|
] })
|
|
1660
1717
|
] }),
|
|
1661
|
-
|
|
1662
|
-
Checkbox,
|
|
1663
|
-
{
|
|
1664
|
-
checked: hideNonMatching,
|
|
1665
|
-
onCheckedChange: (checked) => setHideNonMatching(Boolean(checked)),
|
|
1666
|
-
children: /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral700", children: "Only display matching entries in tables (hide non-matching)" })
|
|
1667
|
-
}
|
|
1668
|
-
) })
|
|
1718
|
+
isFilterActive && /* @__PURE__ */ jsx(Flex, { gap: 2, alignItems: "center", marginTop: 1, children: /* @__PURE__ */ jsx(Badge, { backgroundColor: "success100", textColor: "success700", size: "S", children: "✓ Filter active: Showing only matching entries. All returned matching records are pre-selected." }) })
|
|
1669
1719
|
] })
|
|
1670
1720
|
}
|
|
1671
1721
|
),
|
|
@@ -1759,8 +1809,8 @@ const BulkUpdater = () => {
|
|
|
1759
1809
|
}
|
|
1760
1810
|
) }),
|
|
1761
1811
|
/* @__PURE__ */ jsxs(Flex, { gap: 2, alignItems: "center", style: { marginLeft: "auto" }, children: [
|
|
1762
|
-
/* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", children: "Default page size (max
|
|
1763
|
-
/* @__PURE__ */ jsx(Box, { style: { width:
|
|
1812
|
+
/* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", children: "Default page size (max 500):" }),
|
|
1813
|
+
/* @__PURE__ */ jsx(Box, { style: { width: 130 }, children: /* @__PURE__ */ jsxs(
|
|
1764
1814
|
SingleSelect,
|
|
1765
1815
|
{
|
|
1766
1816
|
size: "S",
|
|
@@ -1771,7 +1821,9 @@ const BulkUpdater = () => {
|
|
|
1771
1821
|
/* @__PURE__ */ jsx(SingleSelectOption, { value: "10", children: "10 / page" }),
|
|
1772
1822
|
/* @__PURE__ */ jsx(SingleSelectOption, { value: "25", children: "25 / page" }),
|
|
1773
1823
|
/* @__PURE__ */ jsx(SingleSelectOption, { value: "50", children: "50 / page" }),
|
|
1774
|
-
/* @__PURE__ */ jsx(SingleSelectOption, { value: "100", children: "100 / page" })
|
|
1824
|
+
/* @__PURE__ */ jsx(SingleSelectOption, { value: "100", children: "100 / page" }),
|
|
1825
|
+
/* @__PURE__ */ jsx(SingleSelectOption, { value: "250", children: "250 / page" }),
|
|
1826
|
+
/* @__PURE__ */ jsx(SingleSelectOption, { value: "500", children: "500 / page" })
|
|
1775
1827
|
]
|
|
1776
1828
|
}
|
|
1777
1829
|
) })
|
|
@@ -1786,7 +1838,7 @@ const BulkUpdater = () => {
|
|
|
1786
1838
|
const pageSize = pageState ? pageState.pageSize : defaultPageSize;
|
|
1787
1839
|
const hasAttr = col.attributes.includes(selectedAttribute);
|
|
1788
1840
|
const visibleEntries = getVisibleEntries(col);
|
|
1789
|
-
|
|
1841
|
+
entries.filter((e) => entryMatchesFilter(e, selectedAttribute)).length;
|
|
1790
1842
|
const isFullySelected = isCollectionFullySelected(col);
|
|
1791
1843
|
const isPartiallySelected = isCollectionPartiallySelected(col);
|
|
1792
1844
|
const currentSort = collectionSorts[col.uid] || { field: "createdAt", order: "desc" };
|
|
@@ -1895,6 +1947,9 @@ const BulkUpdater = () => {
|
|
|
1895
1947
|
params.set("filterOperator", filterOperator);
|
|
1896
1948
|
if (filterQuery) params.set("filterQuery", filterQuery);
|
|
1897
1949
|
}
|
|
1950
|
+
if (entrySearch && entrySearch.trim()) {
|
|
1951
|
+
params.set("search", entrySearch.trim());
|
|
1952
|
+
}
|
|
1898
1953
|
const res = await get(`/bulk-updater/csv/export/${col.uid}?${params.toString()}`);
|
|
1899
1954
|
const csvStr = res.data?.csvContent || (typeof res.data === "string" ? res.data : "");
|
|
1900
1955
|
if (!csvStr) {
|
|
@@ -1927,7 +1982,7 @@ const BulkUpdater = () => {
|
|
|
1927
1982
|
children: "Export CSV"
|
|
1928
1983
|
}
|
|
1929
1984
|
),
|
|
1930
|
-
/* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral500", children: col.isSingleType ? "1 single entry" :
|
|
1985
|
+
/* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral500", children: col.isSingleType ? "1 single entry" : isFilterActive ? `${totalEntries} matching entries in DB` : `${totalEntries} entries` })
|
|
1931
1986
|
] })
|
|
1932
1987
|
] }),
|
|
1933
1988
|
openColumnPickerUid === col.uid && /* @__PURE__ */ jsx(
|
|
@@ -1997,7 +2052,7 @@ const BulkUpdater = () => {
|
|
|
1997
2052
|
/* @__PURE__ */ jsx(Tbody, { children: visibleEntries.length === 0 ? /* @__PURE__ */ jsx(Tr, { children: /* @__PURE__ */ jsx(Td, { colSpan: activeColumns.length, children: /* @__PURE__ */ jsx(Box, { padding: 4, style: { textAlign: "center" }, children: /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral500", children: "No entries in this content type match the active filter criteria." }) }) }) }) : visibleEntries.map((entry) => {
|
|
1998
2053
|
const key = `${col.uid}${KEY_SEP}${entry.documentId}`;
|
|
1999
2054
|
const isSelected = Boolean(selectedEntries[key]);
|
|
2000
|
-
const isMatch =
|
|
2055
|
+
const isMatch = isFilterActive;
|
|
2001
2056
|
return /* @__PURE__ */ jsx(
|
|
2002
2057
|
Tr,
|
|
2003
2058
|
{
|
|
@@ -2029,11 +2084,12 @@ const BulkUpdater = () => {
|
|
|
2029
2084
|
Math.min(page * pageSize, totalEntries),
|
|
2030
2085
|
" of ",
|
|
2031
2086
|
totalEntries,
|
|
2032
|
-
"
|
|
2087
|
+
" ",
|
|
2088
|
+
isFilterActive ? "matching entries" : "entries"
|
|
2033
2089
|
] }),
|
|
2034
2090
|
/* @__PURE__ */ jsxs(Flex, { gap: 1, alignItems: "center", children: [
|
|
2035
2091
|
/* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", children: "Show:" }),
|
|
2036
|
-
/* @__PURE__ */ jsx(Box, { style: { width:
|
|
2092
|
+
/* @__PURE__ */ jsx(Box, { style: { width: 85 }, children: /* @__PURE__ */ jsxs(
|
|
2037
2093
|
SingleSelect,
|
|
2038
2094
|
{
|
|
2039
2095
|
size: "S",
|
|
@@ -2044,12 +2100,27 @@ const BulkUpdater = () => {
|
|
|
2044
2100
|
/* @__PURE__ */ jsx(SingleSelectOption, { value: "10", children: "10" }),
|
|
2045
2101
|
/* @__PURE__ */ jsx(SingleSelectOption, { value: "25", children: "25" }),
|
|
2046
2102
|
/* @__PURE__ */ jsx(SingleSelectOption, { value: "50", children: "50" }),
|
|
2047
|
-
/* @__PURE__ */ jsx(SingleSelectOption, { value: "100", children: "100" })
|
|
2103
|
+
/* @__PURE__ */ jsx(SingleSelectOption, { value: "100", children: "100" }),
|
|
2104
|
+
/* @__PURE__ */ jsx(SingleSelectOption, { value: "250", children: "250" }),
|
|
2105
|
+
/* @__PURE__ */ jsx(SingleSelectOption, { value: "500", children: "500" })
|
|
2048
2106
|
]
|
|
2049
2107
|
}
|
|
2050
2108
|
) }),
|
|
2051
2109
|
/* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral500", children: "per page" })
|
|
2052
|
-
] })
|
|
2110
|
+
] }),
|
|
2111
|
+
totalEntries > visibleEntries.length && /* @__PURE__ */ jsxs(
|
|
2112
|
+
Button,
|
|
2113
|
+
{
|
|
2114
|
+
variant: "tertiary",
|
|
2115
|
+
size: "S",
|
|
2116
|
+
onClick: () => handleCollectionPageSizeChange(col.uid, Math.min(totalEntries, 500)),
|
|
2117
|
+
children: [
|
|
2118
|
+
"Load all ",
|
|
2119
|
+
totalEntries,
|
|
2120
|
+
" entries"
|
|
2121
|
+
]
|
|
2122
|
+
}
|
|
2123
|
+
)
|
|
2053
2124
|
] }),
|
|
2054
2125
|
pageCount > 1 && /* @__PURE__ */ jsxs(Flex, { gap: 2, alignItems: "center", children: [
|
|
2055
2126
|
/* @__PURE__ */ jsx(
|
|
@@ -2707,6 +2778,7 @@ const BulkUpdater = () => {
|
|
|
2707
2778
|
export {
|
|
2708
2779
|
BulkUpdater as default,
|
|
2709
2780
|
formatDisplayValue,
|
|
2710
|
-
getAvailableColumnsForCollection
|
|
2781
|
+
getAvailableColumnsForCollection,
|
|
2782
|
+
getNestedValue
|
|
2711
2783
|
};
|
|
2712
|
-
//# sourceMappingURL=BulkUpdater-
|
|
2784
|
+
//# sourceMappingURL=BulkUpdater-BYtO2SHc.mjs.map
|