strapi-plugin-bulk-updater 1.5.9 → 1.5.10

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.
@@ -234,6 +234,10 @@ function CsvManagerTab() {
234
234
  const [collectionEntries, setCollectionEntries] = React.useState([]);
235
235
  const [pendingBatches, setPendingBatches] = React.useState([]);
236
236
  const [exportLimit, setExportLimit] = React.useState(0);
237
+ const [exportLimitInput, setExportLimitInput] = React.useState("");
238
+ const [exportingCollection, setExportingCollection] = React.useState(false);
239
+ const [downloadingTemplate, setDownloadingTemplate] = React.useState(false);
240
+ const [exportingViolations, setExportingViolations] = React.useState(false);
237
241
  const [exportOnlyViolations, setExportOnlyViolations] = React.useState(false);
238
242
  const [rules, setRules] = React.useState([]);
239
243
  const [selectedRuleId, setSelectedRuleId] = React.useState("");
@@ -279,7 +283,6 @@ function CsvManagerTab() {
279
283
  if (loadedCollections.length > 0) {
280
284
  const firstUid = loadedCollections[0].uid;
281
285
  setSelectedUid(firstUid);
282
- fetchAndEnrichEntries(firstUid, loadedCollections, batchesRes.data?.batches || []);
283
286
  }
284
287
  }
285
288
  if (rulesRes.data?.rules) {
@@ -354,14 +357,10 @@ function CsvManagerTab() {
354
357
  return row;
355
358
  });
356
359
  };
357
- React.useEffect(() => {
358
- if (selectedUid) {
359
- fetchAndEnrichEntries(selectedUid);
360
- }
361
- }, [selectedUid]);
362
360
  const handleDownloadTemplate = async () => {
363
- if (!selectedUid) return;
361
+ if (!selectedUid || downloadingTemplate) return;
364
362
  try {
363
+ setDownloadingTemplate(true);
365
364
  const res = await get(`/bulk-updater/csv/template/${selectedUid}`);
366
365
  const csvStr = res.data?.csvContent || (typeof res.data === "string" ? res.data : "");
367
366
  const filename = res.data?.filename || `${selectedUid.split(".").pop()}_template.csv`;
@@ -376,12 +375,14 @@ function CsvManagerTab() {
376
375
  type: "danger",
377
376
  message: err.message || "Failed downloading CSV template"
378
377
  });
378
+ } finally {
379
+ setDownloadingTemplate(false);
379
380
  }
380
381
  };
381
382
  const handleExportCollection = async () => {
382
- if (!selectedUid) return;
383
+ if (!selectedUid || exportingCollection) return;
383
384
  try {
384
- await fetchAndEnrichEntries(selectedUid);
385
+ setExportingCollection(true);
385
386
  const res = await get(`/bulk-updater/csv/export/${selectedUid}?limit=${exportLimit}`);
386
387
  const csvStr = res.data?.csvContent || (typeof res.data === "string" ? res.data : "");
387
388
  const filename = res.data?.filename || `${selectedUid.split(".").pop()}_export.csv`;
@@ -396,11 +397,14 @@ function CsvManagerTab() {
396
397
  type: "danger",
397
398
  message: err.message || "Failed exporting collection to CSV"
398
399
  });
400
+ } finally {
401
+ setExportingCollection(false);
399
402
  }
400
403
  };
401
404
  const handleExportViolations = async () => {
402
- if (!selectedRuleId) return;
405
+ if (!selectedRuleId || exportingViolations) return;
403
406
  try {
407
+ setExportingViolations(true);
404
408
  const res = await get(`/bulk-updater/csv/export-violations/${selectedRuleId}`);
405
409
  const csvStr = res.data?.csvContent || (typeof res.data === "string" ? res.data : "");
406
410
  const filename = res.data?.filename || `violations_${selectedRuleId}.csv`;
@@ -415,6 +419,8 @@ function CsvManagerTab() {
415
419
  type: "danger",
416
420
  message: err.message || "Failed exporting violations to CSV"
417
421
  });
422
+ } finally {
423
+ setExportingViolations(false);
418
424
  }
419
425
  };
420
426
  const downloadCsvFile = (content, fallbackName) => {
@@ -695,7 +701,8 @@ function CsvManagerTab() {
695
701
  variant: "tertiary",
696
702
  startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.Download, {}),
697
703
  onClick: handleDownloadTemplate,
698
- disabled: !selectedUid,
704
+ disabled: !selectedUid || downloadingTemplate,
705
+ loading: downloadingTemplate,
699
706
  children: "Download Sample CSV Template"
700
707
  }
701
708
  )
@@ -703,35 +710,61 @@ function CsvManagerTab() {
703
710
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { padding: 5, background: "neutral100", hasRadius: true, children: [
704
711
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "delta", tag: "h3", fontWeight: "bold", marginBottom: 2, children: "1. Export Data to CSV" }),
705
712
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", marginBottom: 4, children: "Extract entire collections without artificial limits (streams 10,000+ records in paged chunks) or pinpoint records violating validation quotas." }),
706
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 4, wrap: "wrap", alignItems: "center", marginTop: 3, children: [
707
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { style: { width: 220 }, children: /* @__PURE__ */ jsxRuntime.jsxs(
708
- designSystem.SingleSelect,
709
- {
710
- value: String(exportLimit),
711
- onChange: (val) => setExportLimit(Number(val)),
712
- placeholder: "Export Limit",
713
- children: [
714
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "0", children: "All Records (No Limit)" }),
715
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "10000", children: "Up to 10,000 Records" }),
716
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "5000", children: "Up to 5,000 Records" }),
717
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "1000", children: "Up to 1,000 Records" })
718
- ]
719
- }
720
- ) }),
721
- /* @__PURE__ */ jsxRuntime.jsxs(
713
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 4, wrap: "wrap", alignItems: "flex-end", marginTop: 3, children: [
714
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { style: { width: 220 }, children: [
715
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", fontWeight: "bold", textColor: "neutral800", marginBottom: 1, display: "block", children: "Records to Download" }),
716
+ /* @__PURE__ */ jsxRuntime.jsx(
717
+ designSystem.TextInput,
718
+ {
719
+ type: "number",
720
+ min: 0,
721
+ placeholder: "All records (or enter count)",
722
+ value: exportLimitInput,
723
+ onChange: (e) => {
724
+ const raw = e.target.value;
725
+ setExportLimitInput(raw);
726
+ const parsed = parseInt(raw, 10);
727
+ setExportLimit(!raw || isNaN(parsed) || parsed <= 0 ? 0 : parsed);
728
+ },
729
+ hint: exportLimit === 0 ? "Exporting all records (no limit)" : `Exporting first ${exportLimit.toLocaleString()} records`
730
+ }
731
+ )
732
+ ] }),
733
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { children: [
734
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", marginBottom: 1, display: "block", children: "Quick Presets:" }),
735
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { gap: 1, wrap: "wrap", children: [
736
+ { label: "All", value: 0 },
737
+ { label: "100", value: 100 },
738
+ { label: "500", value: 500 },
739
+ { label: "1,000", value: 1e3 },
740
+ { label: "5,000", value: 5e3 },
741
+ { label: "10,000", value: 1e4 }
742
+ ].map((preset) => {
743
+ const isSelected = preset.value === 0 ? exportLimit === 0 && (!exportLimitInput || exportLimitInput === "0") : exportLimit === preset.value && exportLimitInput === String(preset.value);
744
+ return /* @__PURE__ */ jsxRuntime.jsx(
745
+ designSystem.Button,
746
+ {
747
+ variant: isSelected ? "secondary" : "tertiary",
748
+ size: "S",
749
+ onClick: () => {
750
+ setExportLimit(preset.value);
751
+ setExportLimitInput(preset.value === 0 ? "" : String(preset.value));
752
+ },
753
+ children: preset.label
754
+ },
755
+ preset.value
756
+ );
757
+ }) })
758
+ ] }),
759
+ /* @__PURE__ */ jsxRuntime.jsx(
722
760
  designSystem.Button,
723
761
  {
724
762
  variant: "default",
725
763
  startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.Download, {}),
726
764
  onClick: handleExportCollection,
727
- disabled: !selectedUid,
728
- children: [
729
- "Export ",
730
- exportLimit === 0 ? "All" : `${exportLimit}`,
731
- " ",
732
- selectedCol?.displayName || "Collection",
733
- " Records (.csv)"
734
- ]
765
+ disabled: !selectedUid || exportingCollection,
766
+ loading: exportingCollection,
767
+ children: exportingCollection ? "Preparing CSV download..." : `Export ${exportLimit === 0 ? "All" : exportLimit.toLocaleString()} ${selectedCol?.displayName || "Collection"} Records (.csv)`
735
768
  }
736
769
  ),
737
770
  rules.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, alignItems: "center", style: { marginLeft: "auto" }, children: [
@@ -753,7 +786,8 @@ function CsvManagerTab() {
753
786
  variant: "danger-light",
754
787
  startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.Download, {}),
755
788
  onClick: handleExportViolations,
756
- disabled: !selectedRuleId,
789
+ disabled: !selectedRuleId || exportingViolations,
790
+ loading: exportingViolations,
757
791
  children: "Export Violators CSV"
758
792
  }
759
793
  )
@@ -7623,4 +7657,4 @@ exports.getNestedValue = getNestedValue;
7623
7657
  exports.getPropertyValue = getPropertyValue;
7624
7658
  exports.getSortOptionsForCollection = getSortOptionsForCollection;
7625
7659
  exports.parseDynamicZonePath = parseDynamicZonePath;
7626
- //# sourceMappingURL=BulkUpdater-C0uR_ORS.js.map
7660
+ //# sourceMappingURL=BulkUpdater-BlSPmNFG.js.map