@nkhang1902/strapi-plugin-export-import-clsx 1.1.14 → 1.1.16

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.
@@ -1,5 +1,7 @@
1
1
  import { useState, useRef } from "react";
2
- import { Button } from "@strapi/design-system";
2
+ import {
3
+ Button,
4
+ } from "@strapi/design-system";
3
5
  import { Download, Upload } from "@strapi/icons";
4
6
  import { useNotification } from "@strapi/strapi/admin";
5
7
 
@@ -177,40 +179,32 @@ const ExportImportButtons = (props) => {
177
179
 
178
180
  const eventFilter = getEventFilter();
179
181
  try {
180
- const response = await fetch(`/export-import-clsx/import?eventId=${eventFilter.eventId}`, {
182
+ const response = await fetch(`/export-import-clsx/import?eventId=${eventFilter?.eventId || ""}`, {
181
183
  method: "POST",
182
184
  body: formData,
183
185
  });
184
186
 
185
187
  if (response.ok) {
186
188
  const result = await response.json();
189
+ const created = result.summary?.created || result.result.created || 0;
190
+ const updated = result.summary?.updated || result.result.updated || 0;
187
191
 
188
- // Create appropriate notification based on results
189
- const created = result.summary?.created || result.result.created;
190
- const updated = result.summary?.updated || result.result.updated;
191
- const errors = result.result.errors?.length || 0;
192
-
192
+ const errorList = result.result?.errors || [];
193
193
  const total = created + updated;
194
194
 
195
- if (errors > 0) {
196
- toggleNotification({
197
- type: "warning",
198
- message: `Import completed with ${errors} error(s). Processed ${total} entries (${created} created, ${updated} updated)`,
199
- });
195
+ if (errorList.length > 0) {
196
+ showLongNotification(toggleNotification, {
197
+ title: "Import errors",
198
+ message: errorList.join("\n"),
199
+ type: "danger",
200
+ })
200
201
  } else if (total > 0) {
201
202
  toggleNotification({
202
203
  type: "success",
203
204
  message: `Import completed successfully! Processed ${total} entries (${created} created, ${updated} updated)`,
204
205
  });
205
- } else {
206
- toggleNotification({
207
- type: "info",
208
- message: "Import completed - no changes were made",
209
- });
206
+ window.location.reload();
210
207
  }
211
-
212
- // Reload the page to show new data
213
- window.location.reload();
214
208
  } else {
215
209
  const error = await response.json();
216
210
  throw new Error(error.error || "Import failed");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nkhang1902/strapi-plugin-export-import-clsx",
3
- "version": "1.1.14",
3
+ "version": "1.1.16",
4
4
  "description": "A powerful Strapi plugin for exporting and importing data with Excel support and advanced filtering",
5
5
  "main": "./strapi-server.js",
6
6
  "scripts": {
@@ -15,6 +15,9 @@ module.exports = ({ strapi }) => ({
15
15
  .service("import-service");
16
16
 
17
17
  const { eventId } = ctx.request.query;
18
+ if (eventId == "") {
19
+ eventId = null;
20
+ }
18
21
 
19
22
  const result = await importService.importData(file, targetContentType, eventId);
20
23
 
@@ -352,13 +352,6 @@ module.exports = ({ strapi }) => ({
352
352
  }
353
353
  return result;
354
354
  }
355
-
356
- if (["corporate", "investor", "vip-guest"].includes(contentType.split(".")[1])) {
357
- cleanedEntries.forEach((entry) => {
358
- entry["liveLink"] = `${process.env.PREVIEW_URL}/download/live-link?participantId=${entry["documentId"]}`;
359
- });
360
- }
361
-
362
355
  const cleanedFlat = cleanedEntries.map((entry) =>
363
356
  flattenForXLSX(entry)
364
357
  );
@@ -147,7 +147,7 @@ module.exports = ({ strapi }) => ({
147
147
  .map(([fieldName, attr]) => toCamel(fieldName));
148
148
  },
149
149
 
150
- async handleRelations(entry, contentType, eventId) {
150
+ async handleRelations(entry, contentType, row) {
151
151
  const resolveRelationValue = async (field, value, target) => {
152
152
  const targetAttr = strapi.contentTypes[target].attributes;
153
153
  for (const field of SHORTCUT_FIELDS) {
@@ -156,7 +156,7 @@ module.exports = ({ strapi }) => ({
156
156
  filters: { [field]: { $eq: value } },
157
157
  });
158
158
  if (existing) return { id: existing.id };
159
- throw new Error(`Data with ${field} ${value} not found. Cannot map to ${contentType}`);
159
+ throw new Error(`Not found.`);
160
160
  }
161
161
  return null;
162
162
  };
@@ -181,11 +181,7 @@ module.exports = ({ strapi }) => ({
181
181
  if (relation === "manyToMany" || relation === "oneToMany") {
182
182
  updatedEntry[field] = [];
183
183
  } else {
184
- if (field === 'event') {
185
- updatedEntry[field] = { documentId: eventId };
186
- } else {
187
- updatedEntry[field] = null;
188
- }
184
+ updatedEntry[field] = null;
189
185
  }
190
186
  continue;
191
187
  }
@@ -215,7 +211,7 @@ module.exports = ({ strapi }) => ({
215
211
  updatedEntry[field] = Array.isArray(value) ? processed : processed[0];
216
212
  } catch (err) {
217
213
  throw new Error(
218
- `Failed processing field ${field} with value ${JSON.stringify(value)}: ${err.message}`
214
+ `Error resolving field '${field}' with value '${JSON.stringify(value)}': ${err.message}`
219
215
  );
220
216
  }
221
217
  }
@@ -342,10 +338,15 @@ module.exports = ({ strapi }) => ({
342
338
  const f = parseFloat(value);
343
339
  return Number.isNaN(f) ? 0 : f;
344
340
  }
345
- case 'date':
341
+ case 'date': {
342
+ const d = new Date(value);
343
+ if (isNaN(d.getTime())) return null;
344
+ return d.toISOString().slice(0, 10); // YYYY-MM-DD ONLY
345
+ }
346
346
  case 'datetime': {
347
347
  const d = new Date(value);
348
- return isNaN(d.getTime()) ? null : d.toISOString();
348
+ if (isNaN(d.getTime())) return null;
349
+ return d.toISOString(); // full ISO is valid here
349
350
  }
350
351
  default:
351
352
  return value;
@@ -389,6 +390,9 @@ module.exports = ({ strapi }) => ({
389
390
 
390
391
  async importEntries(entries, contentType, eventId) {
391
392
  const results = { created: 0, updated: 0, errors: [] };
393
+ const event = eventId ? strapi.documents("api::event.event").findFirst({
394
+ filters: { documentId: eventId },
395
+ }) : null;
392
396
 
393
397
  await strapi.db.transaction(async ({ trx, rollback, onRollback }) => {
394
398
  onRollback(() => {
@@ -416,9 +420,10 @@ module.exports = ({ strapi }) => ({
416
420
  throw new Error(`Document with id ${id} not found`);
417
421
  }
418
422
  }
423
+ data["event"] = event ? event.name : "";
419
424
 
420
425
  // Handle relations & components
421
- data = await this.handleRelations(data, contentType, eventId);
426
+ data = await this.handleRelations(data, contentType, row, eventName);
422
427
  data = await this.handleComponents(data, existing, contentType);
423
428
  const sanitizeErrors = [];
424
429
  data = this.sanitizeEntryBeforeWrite(data, contentType, '', sanitizeErrors);
@@ -446,9 +451,7 @@ module.exports = ({ strapi }) => ({
446
451
  }
447
452
  } catch (err) {
448
453
  results.errors.push(
449
- `Failed ${existing ? "updating" : "creating"} on row ${
450
- i + 2
451
- }: ${err.message}`
454
+ `Row ${i + 2}: ${err.message || err.toString()}`
452
455
  );
453
456
  results.created = 0;
454
457
  results.updated = 0;