@nkhang1902/strapi-plugin-export-import-clsx 1.1.1 → 1.1.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.
@@ -175,8 +175,9 @@ const ExportImportButtons = (props) => {
175
175
  formData.append("file", file);
176
176
  formData.append("contentType", contentType);
177
177
 
178
+ const eventFilter = getEventFilter();
178
179
  try {
179
- const response = await fetch("/export-import-clsx/import", {
180
+ const response = await fetch(`/export-import-clsx/import?eventId=${eventFilter.eventId}`, {
180
181
  method: "POST",
181
182
  body: formData,
182
183
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nkhang1902/strapi-plugin-export-import-clsx",
3
- "version": "1.1.1",
3
+ "version": "1.1.13",
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": {
@@ -14,7 +14,9 @@ module.exports = ({ strapi }) => ({
14
14
  .plugin("export-import-clsx")
15
15
  .service("import-service");
16
16
 
17
- const result = await importService.importData(file, targetContentType);
17
+ const { eventId } = ctx.request.query;
18
+
19
+ const result = await importService.importData(file, targetContentType, eventId);
18
20
 
19
21
  // Create appropriate message based on results
20
22
  let message = "Import completed successfully";
@@ -349,6 +349,13 @@ module.exports = ({ strapi }) => ({
349
349
  }
350
350
  return result;
351
351
  }
352
+
353
+ if (["corporate", "investor", "vip-guest"].includes(contentType.split(".")[1])) {
354
+ cleanedEntries.forEach((entry) => {
355
+ entry["liveLink"] = `${process.env.PREVIEW_URL}/download/live-link?participantId=${entry["documentId"]}`;
356
+ });
357
+ }
358
+
352
359
  const cleanedFlat = cleanedEntries.map((entry) =>
353
360
  flattenForXLSX(entry)
354
361
  );
@@ -13,7 +13,7 @@ const SHORTCUT_FIELDS = [
13
13
  "tickerCode",
14
14
  ];
15
15
  module.exports = ({ strapi }) => ({
16
- async importData(file, targetContentType = null) {
16
+ async importData(file, targetContentType = null, eventId = null) {
17
17
  let result;
18
18
  try {
19
19
  let importData;
@@ -32,7 +32,7 @@ module.exports = ({ strapi }) => ({
32
32
  } else if (fileExtension === "xlsx" || fileExtension === "xls") {
33
33
  importData = this.transformExcelData(filePath, targetContentType);
34
34
  }
35
- result = await this.bulkInsertData(importData);
35
+ result = await this.bulkInsertData(importData, eventId);
36
36
  return result;
37
37
  } catch (error) {
38
38
  // Clean up uploaded file on error
@@ -147,7 +147,7 @@ module.exports = ({ strapi }) => ({
147
147
  .map(([fieldName, attr]) => toCamel(fieldName));
148
148
  },
149
149
 
150
- async handleRelations(entry, contentType) {
150
+ async handleRelations(entry, contentType, eventId) {
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`);
159
+ throw new Error(`Data with ${field} ${value} not found. Cannot map to ${contentType}`);
160
160
  }
161
161
  return null;
162
162
  };
@@ -170,11 +170,22 @@ module.exports = ({ strapi }) => ({
170
170
  const { field, target, relation } = rel;
171
171
 
172
172
  let value = entry[field];
173
- if (!value || value === "") {
173
+
174
+ // Excel column NOT PROVIDED → do not touch relation
175
+ if (value === undefined) {
176
+ continue;
177
+ }
178
+
179
+ // Excel explicitly empty → unlink
180
+ if (value === "") {
174
181
  if (relation === "manyToMany" || relation === "oneToMany") {
175
182
  updatedEntry[field] = [];
176
183
  } else {
177
- updatedEntry[field] = null;
184
+ if (field === 'event') {
185
+ updatedEntry[field] = { documentId: eventId };
186
+ } else {
187
+ updatedEntry[field] = null;
188
+ }
178
189
  }
179
190
  continue;
180
191
  }
@@ -268,11 +279,11 @@ module.exports = ({ strapi }) => ({
268
279
  if (attr.type === 'component') {
269
280
  cleaned[key] = attr.repeatable
270
281
  ? (value || []).map((v, i) =>
271
- sanitizeComponent(v, attr.component, rowIndex, errors, `${fieldPath}[${i}]`)
282
+ this.sanitizeComponent(v, attr.component, rowIndex, errors, `${fieldPath}[${i}]`)
272
283
  )
273
- : sanitizeComponent(value, attr.component, rowIndex, errors, fieldPath);
284
+ : this.sanitizeComponent(value, attr.component, rowIndex, errors, fieldPath);
274
285
  } else {
275
- cleaned[key] = sanitizePrimitive(value, attr, rowIndex, errors, fieldPath);
286
+ cleaned[key] = this.sanitizePrimitive(value, attr, rowIndex, errors, fieldPath);
276
287
  }
277
288
  }
278
289
 
@@ -297,13 +308,13 @@ module.exports = ({ strapi }) => ({
297
308
 
298
309
  cleaned[key] = attr.repeatable
299
310
  ? value.map((v, i) =>
300
- sanitizeComponent(v, attr.component, rowIndex, errors, `${fieldPath}[${i}]`)
311
+ this.sanitizeComponent(v, attr.component, rowIndex, errors, `${fieldPath}[${i}]`)
301
312
  )
302
- : sanitizeComponent(value, attr.component, rowIndex, errors, fieldPath);
313
+ : this.sanitizeComponent(value, attr.component, rowIndex, errors, fieldPath);
303
314
  continue;
304
315
  }
305
316
 
306
- cleaned[key] = sanitizePrimitive(value, attr, rowIndex, errors, fieldPath);
317
+ cleaned[key] = this.sanitizePrimitive(value, attr, rowIndex, errors, fieldPath);
307
318
  }
308
319
 
309
320
  return cleaned;
@@ -341,37 +352,7 @@ module.exports = ({ strapi }) => ({
341
352
  }
342
353
  },
343
354
 
344
- sanitizeEntryBeforeWrite(data, uid, rowIndex, errors, path = '') {
345
- const schema = strapi.contentTypes[uid];
346
- const cleaned = {};
347
-
348
- for (const [key, attr] of Object.entries(schema.attributes)) {
349
- const value = data[key];
350
- const fieldPath = path ? `${path}.${key}` : key;
351
-
352
- if (value === undefined) continue;
353
-
354
- if (attr.type === 'component') {
355
- if (!value) {
356
- cleaned[key] = attr.repeatable ? [] : null;
357
- continue;
358
- }
359
-
360
- cleaned[key] = attr.repeatable
361
- ? value.map((v, i) =>
362
- sanitizeComponent(v, attr.component, rowIndex, errors, `${fieldPath}[${i}]`)
363
- )
364
- : sanitizeComponent(value, attr.component, rowIndex, errors, fieldPath);
365
- continue;
366
- }
367
-
368
- cleaned[key] = sanitizePrimitive(value, attr, rowIndex, errors, fieldPath);
369
- }
370
-
371
- return cleaned;
372
- },
373
-
374
- async bulkInsertData(importData) {
355
+ async bulkInsertData(importData, eventId) {
375
356
  const results = {
376
357
  created: 0,
377
358
  updated: 0,
@@ -392,7 +373,8 @@ module.exports = ({ strapi }) => ({
392
373
  try {
393
374
  const { created, updated, errors } = await this.importEntries(
394
375
  entries,
395
- contentType
376
+ contentType,
377
+ eventId,
396
378
  );
397
379
  results.created += created;
398
380
  results.updated += updated;
@@ -405,7 +387,7 @@ module.exports = ({ strapi }) => ({
405
387
  return results;
406
388
  },
407
389
 
408
- async importEntries(entries, contentType) {
390
+ async importEntries(entries, contentType, eventId) {
409
391
  const results = { created: 0, updated: 0, errors: [] };
410
392
 
411
393
  await strapi.db.transaction(async ({ trx, rollback, onRollback }) => {
@@ -430,13 +412,16 @@ module.exports = ({ strapi }) => ({
430
412
  },
431
413
  { transaction: trx }
432
414
  );
415
+ if (!existing) {
416
+ throw new Error(`Document with id ${id} not found`);
417
+ }
433
418
  }
434
419
 
435
420
  // Handle relations & components
436
- data = await this.handleRelations(data, contentType, trx);
421
+ data = await this.handleRelations(data, contentType, eventId);
437
422
  data = await this.handleComponents(data, existing, contentType);
438
423
  const sanitizeErrors = [];
439
- data = sanitizeEntryBeforeWrite(data, contentType, '', sanitizeErrors);
424
+ data = this.sanitizeEntryBeforeWrite(data, contentType, '', sanitizeErrors);
440
425
 
441
426
  if (sanitizeErrors.length) {
442
427
  throw new Error(`Data validation failed:\n${sanitizeErrors.join('\n')}`);
@@ -452,10 +437,8 @@ module.exports = ({ strapi }) => ({
452
437
  { transaction: trx }
453
438
  );
454
439
  results.updated++;
455
- }
456
-
440
+ } else {
457
441
  // Create
458
- else {
459
442
  await strapi
460
443
  .documents(contentType)
461
444
  .create({ data }, { transaction: trx });