@nkhang1902/strapi-plugin-export-import-clsx 1.1.12 → 1.1.14
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(
|
|
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.
|
|
3
|
+
"version": "1.1.14",
|
|
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
|
|
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";
|
|
@@ -287,7 +287,10 @@ module.exports = ({ strapi }) => ({
|
|
|
287
287
|
for (const key in obj) {
|
|
288
288
|
const value = obj[key];
|
|
289
289
|
|
|
290
|
-
|
|
290
|
+
if (key === "documentId" && ["corporate", "investor", "vip-guest"].includes(contentType.split(".")[1])) {
|
|
291
|
+
result["liveLink"] = `${process.env.PREVIEW_URL}/download/live-link?participantId=${value}`;
|
|
292
|
+
continue
|
|
293
|
+
}
|
|
291
294
|
if (SYSTEM_KEYS.includes(key)) continue;
|
|
292
295
|
if (customFields.includes(key)) continue;
|
|
293
296
|
if ([...skipFields, "wishlist", "availableSlot"].includes(key))
|
|
@@ -295,7 +298,7 @@ module.exports = ({ strapi }) => ({
|
|
|
295
298
|
|
|
296
299
|
if (componentFields.includes(key)) {
|
|
297
300
|
for (const subKey in value) {
|
|
298
|
-
if (
|
|
301
|
+
if (["id", "createdAt", "updatedAt", "lastUpdate", "passcode"]) continue;
|
|
299
302
|
result[`${key}_${subKey}`] = value[subKey];
|
|
300
303
|
}
|
|
301
304
|
continue;
|
|
@@ -349,6 +352,13 @@ module.exports = ({ strapi }) => ({
|
|
|
349
352
|
}
|
|
350
353
|
return result;
|
|
351
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
|
+
|
|
352
362
|
const cleanedFlat = cleanedEntries.map((entry) =>
|
|
353
363
|
flattenForXLSX(entry)
|
|
354
364
|
);
|
|
@@ -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
|
-
|
|
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
|
-
|
|
184
|
+
if (field === 'event') {
|
|
185
|
+
updatedEntry[field] = { documentId: eventId };
|
|
186
|
+
} else {
|
|
187
|
+
updatedEntry[field] = null;
|
|
188
|
+
}
|
|
178
189
|
}
|
|
179
190
|
continue;
|
|
180
191
|
}
|
|
@@ -341,7 +352,7 @@ module.exports = ({ strapi }) => ({
|
|
|
341
352
|
}
|
|
342
353
|
},
|
|
343
354
|
|
|
344
|
-
async bulkInsertData(importData) {
|
|
355
|
+
async bulkInsertData(importData, eventId) {
|
|
345
356
|
const results = {
|
|
346
357
|
created: 0,
|
|
347
358
|
updated: 0,
|
|
@@ -362,7 +373,8 @@ module.exports = ({ strapi }) => ({
|
|
|
362
373
|
try {
|
|
363
374
|
const { created, updated, errors } = await this.importEntries(
|
|
364
375
|
entries,
|
|
365
|
-
contentType
|
|
376
|
+
contentType,
|
|
377
|
+
eventId,
|
|
366
378
|
);
|
|
367
379
|
results.created += created;
|
|
368
380
|
results.updated += updated;
|
|
@@ -375,7 +387,7 @@ module.exports = ({ strapi }) => ({
|
|
|
375
387
|
return results;
|
|
376
388
|
},
|
|
377
389
|
|
|
378
|
-
async importEntries(entries, contentType) {
|
|
390
|
+
async importEntries(entries, contentType, eventId) {
|
|
379
391
|
const results = { created: 0, updated: 0, errors: [] };
|
|
380
392
|
|
|
381
393
|
await strapi.db.transaction(async ({ trx, rollback, onRollback }) => {
|
|
@@ -400,10 +412,13 @@ module.exports = ({ strapi }) => ({
|
|
|
400
412
|
},
|
|
401
413
|
{ transaction: trx }
|
|
402
414
|
);
|
|
415
|
+
if (!existing) {
|
|
416
|
+
throw new Error(`Document with id ${id} not found`);
|
|
417
|
+
}
|
|
403
418
|
}
|
|
404
419
|
|
|
405
420
|
// Handle relations & components
|
|
406
|
-
data = await this.handleRelations(data, contentType,
|
|
421
|
+
data = await this.handleRelations(data, contentType, eventId);
|
|
407
422
|
data = await this.handleComponents(data, existing, contentType);
|
|
408
423
|
const sanitizeErrors = [];
|
|
409
424
|
data = this.sanitizeEntryBeforeWrite(data, contentType, '', sanitizeErrors);
|
|
@@ -422,10 +437,8 @@ module.exports = ({ strapi }) => ({
|
|
|
422
437
|
{ transaction: trx }
|
|
423
438
|
);
|
|
424
439
|
results.updated++;
|
|
425
|
-
}
|
|
426
|
-
|
|
440
|
+
} else {
|
|
427
441
|
// Create
|
|
428
|
-
else {
|
|
429
442
|
await strapi
|
|
430
443
|
.documents(contentType)
|
|
431
444
|
.create({ data }, { transaction: trx });
|