strapi-plugin-bulk-updater 1.2.12 → 1.2.13

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.
@@ -5,7 +5,7 @@ const React = require("react");
5
5
  const admin = require("@strapi/strapi/admin");
6
6
  const designSystem = require("@strapi/design-system");
7
7
  const icons = require("@strapi/icons");
8
- const ValidationRulesTab = require("./ValidationRulesTab-BoqhoTjo.js");
8
+ const ValidationRulesTab = require("./ValidationRulesTab-BLZWPGrZ.js");
9
9
  const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
10
10
  const React__default = /* @__PURE__ */ _interopDefault(React);
11
11
  function CsvManagerTab() {
@@ -118,7 +118,8 @@ function CsvManagerTab() {
118
118
  });
119
119
  return;
120
120
  }
121
- const blob = new Blob([content], { type: "text/csv;charset=utf-8;" });
121
+ const safeContent = content.startsWith("\uFEFF") ? content : "\uFEFF" + content;
122
+ const blob = new Blob([safeContent], { type: "text/csv;charset=utf-8;" });
122
123
  const url = URL.createObjectURL(blob);
123
124
  const link = document.createElement("a");
124
125
  link.href = url;
@@ -507,7 +508,9 @@ function formatVal(v) {
507
508
  return String(v);
508
509
  }
509
510
  function downloadFile(content, filename, mimeType = "text/csv;charset=utf-8;") {
510
- const blob = new Blob([content], { type: mimeType });
511
+ const isCsv = mimeType.includes("csv") || filename.endsWith(".csv");
512
+ const safeContent = isCsv && !content.startsWith("\uFEFF") ? "\uFEFF" + content : content;
513
+ const blob = new Blob([safeContent], { type: mimeType });
511
514
  const url = URL.createObjectURL(blob);
512
515
  const a = document.createElement("a");
513
516
  a.href = url;
@@ -629,7 +632,7 @@ function ProcessingDashboardModal({
629
632
  ].join(",")
630
633
  )
631
634
  ];
632
- downloadFile(csvRows.join("\n"), `bulk_update_report_${targetId}.csv`);
635
+ downloadFile(csvRows.join("\r\n") + "\r\n", `bulk_update_report_${targetId}.csv`);
633
636
  toggleNotification({
634
637
  type: "success",
635
638
  message: "Execution report downloaded successfully"
@@ -1650,6 +1653,7 @@ const BulkUpdater = () => {
1650
1653
  const [showPublishConfirmModal, setShowPublishConfirmModal] = React.useState(false);
1651
1654
  const [publishing, setPublishing] = React.useState(false);
1652
1655
  const [publishMakerNotesInput, setPublishMakerNotesInput] = React.useState("");
1656
+ const [bulkExporting, setBulkExporting] = React.useState(false);
1653
1657
  const MODELS_CACHE_KEY = "strapi_bulk_updater_models_cache";
1654
1658
  const LAST_ATTR_KEY = "strapi_bulk_updater_last_attr";
1655
1659
  const getInitialAttribute = () => {
@@ -2435,6 +2439,57 @@ const BulkUpdater = () => {
2435
2439
  setMakerNotesInput("");
2436
2440
  }
2437
2441
  };
2442
+ const handleBulkExportSelected = async () => {
2443
+ const targets = [];
2444
+ Object.keys(selectedEntries).forEach((key) => {
2445
+ if (selectedEntries[key]) {
2446
+ const parts = key.split(KEY_SEP);
2447
+ if (parts.length === 2) {
2448
+ targets.push({ uid: parts[0], documentId: parts[1] });
2449
+ }
2450
+ }
2451
+ });
2452
+ if (targets.length === 0) {
2453
+ toggleNotification({
2454
+ type: "warning",
2455
+ message: "Please select at least one entry to export"
2456
+ });
2457
+ return;
2458
+ }
2459
+ try {
2460
+ setBulkExporting(true);
2461
+ const res = await post("/bulk-updater/csv/export-bulk", { selectedEntries: targets });
2462
+ const csvStr = res.data?.csvContent || (typeof res.data === "string" ? res.data : "");
2463
+ if (!csvStr) {
2464
+ toggleNotification({
2465
+ type: "warning",
2466
+ message: "No CSV content returned for selected entries"
2467
+ });
2468
+ return;
2469
+ }
2470
+ const safeContent = csvStr.startsWith("\uFEFF") ? csvStr : "\uFEFF" + csvStr;
2471
+ const blob = new Blob([safeContent], { type: "text/csv;charset=utf-8;" });
2472
+ const url = URL.createObjectURL(blob);
2473
+ const link = document.createElement("a");
2474
+ link.href = url;
2475
+ link.setAttribute("download", res.data?.filename || `bulk_export_selected_${targets.length}.csv`);
2476
+ document.body.appendChild(link);
2477
+ link.click();
2478
+ document.body.removeChild(link);
2479
+ URL.revokeObjectURL(url);
2480
+ toggleNotification({
2481
+ type: "success",
2482
+ message: `Successfully exported ${res.data?.count || targets.length} selected records to Excel CSV`
2483
+ });
2484
+ } catch (e) {
2485
+ toggleNotification({
2486
+ type: "danger",
2487
+ message: e.message || "Failed exporting selected records to CSV"
2488
+ });
2489
+ } finally {
2490
+ setBulkExporting(false);
2491
+ }
2492
+ };
2438
2493
  const handleOpenPublishModal = () => {
2439
2494
  const totalSelected = Object.values(selectedEntries).filter(Boolean).length;
2440
2495
  if (totalSelected === 0) {
@@ -3078,6 +3133,23 @@ const BulkUpdater = () => {
3078
3133
  ")"
3079
3134
  ]
3080
3135
  }
3136
+ ),
3137
+ /* @__PURE__ */ jsxRuntime.jsxs(
3138
+ designSystem.Button,
3139
+ {
3140
+ startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.Download, {}),
3141
+ variant: "tertiary",
3142
+ size: "L",
3143
+ onClick: handleBulkExportSelected,
3144
+ loading: bulkExporting,
3145
+ disabled: loading || totalSelectedCount === 0,
3146
+ title: "Export selected entries to Excel-compatible CSV with full nested component support",
3147
+ children: [
3148
+ "Export Selected (",
3149
+ totalSelectedCount,
3150
+ ")"
3151
+ ]
3152
+ }
3081
3153
  )
3082
3154
  ] })
3083
3155
  ] }),
@@ -3579,6 +3651,10 @@ const BulkUpdater = () => {
3579
3651
  if (entrySearch && entrySearch.trim()) {
3580
3652
  params.set("search", entrySearch.trim());
3581
3653
  }
3654
+ const colSelectedDocIds = col.entries.filter((e) => selectedEntries[`${col.uid}${KEY_SEP}${e.documentId}`]).map((e) => e.documentId);
3655
+ if (colSelectedDocIds.length > 0) {
3656
+ params.set("documentIds", colSelectedDocIds.join(","));
3657
+ }
3582
3658
  const res = await get(`/bulk-updater/csv/export/${col.uid}?${params.toString()}`);
3583
3659
  const csvStr = res.data?.csvContent || (typeof res.data === "string" ? res.data : "");
3584
3660
  if (!csvStr) {
@@ -3588,7 +3664,8 @@ const BulkUpdater = () => {
3588
3664
  });
3589
3665
  return;
3590
3666
  }
3591
- const blob = new Blob([csvStr], { type: "text/csv;charset=utf-8;" });
3667
+ const safeContent = csvStr.startsWith("\uFEFF") ? csvStr : "\uFEFF" + csvStr;
3668
+ const blob = new Blob([safeContent], { type: "text/csv;charset=utf-8;" });
3592
3669
  const url = URL.createObjectURL(blob);
3593
3670
  const link = document.createElement("a");
3594
3671
  link.href = url;
@@ -3599,7 +3676,7 @@ const BulkUpdater = () => {
3599
3676
  URL.revokeObjectURL(url);
3600
3677
  toggleNotification({
3601
3678
  type: "success",
3602
- message: `Exported ${col.displayName} entries to CSV`
3679
+ message: `Exported ${res.data?.count ?? (colSelectedDocIds.length || col.entries.length)} ${col.displayName} entries to Excel CSV`
3603
3680
  });
3604
3681
  } catch (e) {
3605
3682
  toggleNotification({
@@ -4667,4 +4744,4 @@ exports.default = BulkUpdater;
4667
4744
  exports.formatDisplayValue = formatDisplayValue;
4668
4745
  exports.getAvailableColumnsForCollection = getAvailableColumnsForCollection;
4669
4746
  exports.getNestedValue = getNestedValue;
4670
- //# sourceMappingURL=BulkUpdater-CQ9zGdat.js.map
4747
+ //# sourceMappingURL=BulkUpdater-CWJYmuGU.js.map