@adminforth/import-export 1.4.8 → 1.4.9
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.
- package/build.log +2 -2
- package/custom/ExportCsv.vue +2 -5
- package/custom/ImportCsv.vue +2 -6
- package/dist/custom/ExportCsv.vue +2 -5
- package/dist/custom/ImportCsv.vue +2 -6
- package/dist/index.js +44 -33
- package/index.ts +48 -34
- package/package.json +1 -1
package/build.log
CHANGED
|
@@ -10,5 +10,5 @@ custom/package-lock.json
|
|
|
10
10
|
custom/package.json
|
|
11
11
|
custom/tsconfig.json
|
|
12
12
|
|
|
13
|
-
sent 16,
|
|
14
|
-
total size is 16,
|
|
13
|
+
sent 16,704 bytes received 115 bytes 33,638.00 bytes/sec
|
|
14
|
+
total size is 16,284 speedup is 0.97
|
package/custom/ExportCsv.vue
CHANGED
|
@@ -54,12 +54,9 @@ async function exportCsv() {
|
|
|
54
54
|
throw new Error(resp.error);
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
// Parse the CSV data to ensure proper formatting
|
|
58
|
-
const parsedData = Papa.parse(resp.data).data;
|
|
59
|
-
|
|
60
57
|
// Generate properly formatted CSV
|
|
61
|
-
const csvContent = '\ufeff' + Papa.unparse(
|
|
62
|
-
quotes:
|
|
58
|
+
const csvContent = '\ufeff' + Papa.unparse(resp.data, {
|
|
59
|
+
quotes: resp.columnsToForceQuote, // Force quotes only certain columns (!!!not all this breaks BI/Excel tasks)
|
|
63
60
|
quoteChar: '"',
|
|
64
61
|
escapeChar: '"',
|
|
65
62
|
});
|
package/custom/ImportCsv.vue
CHANGED
|
@@ -165,6 +165,7 @@ async function importCsv() {
|
|
|
165
165
|
Papa.parse(text, {
|
|
166
166
|
header: true,
|
|
167
167
|
skipEmptyLines: true,
|
|
168
|
+
// dynamicTyping: true, - bad option becaue it tries to parse "1" -> int even if the column is string
|
|
168
169
|
|
|
169
170
|
complete: async (results) => {
|
|
170
171
|
if (results.errors.length > 0) {
|
|
@@ -214,12 +215,7 @@ async function importCsv() {
|
|
|
214
215
|
reader.readAsText(file);
|
|
215
216
|
};
|
|
216
217
|
}
|
|
217
|
-
|
|
218
|
-
console.log('handleImportClick', checkProgress.value);
|
|
219
|
-
if (!checkProgress.value) {
|
|
220
|
-
importCsv();
|
|
221
|
-
}
|
|
222
|
-
}
|
|
218
|
+
|
|
223
219
|
|
|
224
220
|
function click() {
|
|
225
221
|
importCsv();
|
|
@@ -54,12 +54,9 @@ async function exportCsv() {
|
|
|
54
54
|
throw new Error(resp.error);
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
// Parse the CSV data to ensure proper formatting
|
|
58
|
-
const parsedData = Papa.parse(resp.data).data;
|
|
59
|
-
|
|
60
57
|
// Generate properly formatted CSV
|
|
61
|
-
const csvContent = '\ufeff' + Papa.unparse(
|
|
62
|
-
quotes:
|
|
58
|
+
const csvContent = '\ufeff' + Papa.unparse(resp.data, {
|
|
59
|
+
quotes: resp.columnsToForceQuote, // Force quotes only certain columns (!!!not all this breaks BI/Excel tasks)
|
|
63
60
|
quoteChar: '"',
|
|
64
61
|
escapeChar: '"',
|
|
65
62
|
});
|
|
@@ -165,6 +165,7 @@ async function importCsv() {
|
|
|
165
165
|
Papa.parse(text, {
|
|
166
166
|
header: true,
|
|
167
167
|
skipEmptyLines: true,
|
|
168
|
+
// dynamicTyping: true, - bad option becaue it tries to parse "1" -> int even if the column is string
|
|
168
169
|
|
|
169
170
|
complete: async (results) => {
|
|
170
171
|
if (results.errors.length > 0) {
|
|
@@ -214,12 +215,7 @@ async function importCsv() {
|
|
|
214
215
|
reader.readAsText(file);
|
|
215
216
|
};
|
|
216
217
|
}
|
|
217
|
-
|
|
218
|
-
console.log('handleImportClick', checkProgress.value);
|
|
219
|
-
if (!checkProgress.value) {
|
|
220
|
-
importCsv();
|
|
221
|
-
}
|
|
222
|
-
}
|
|
218
|
+
|
|
223
219
|
|
|
224
220
|
function click() {
|
|
225
221
|
importCsv();
|
package/dist/index.js
CHANGED
|
@@ -64,39 +64,23 @@ export default class ImportExport extends AdminForthPlugin {
|
|
|
64
64
|
sort,
|
|
65
65
|
getTotals: true,
|
|
66
66
|
});
|
|
67
|
-
//
|
|
67
|
+
// prepare data for PapaParse unparse
|
|
68
68
|
const columns = this.resourceConfig.columns.filter((col) => !col.virtual);
|
|
69
|
-
const
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
else if (value === false) {
|
|
84
|
-
return 'false';
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
const str = String(value);
|
|
88
|
-
if (str.includes(',') || str.includes('"') || str.includes('\n')) {
|
|
89
|
-
return `"${str.replace(/"/g, '""')}"`;
|
|
90
|
-
}
|
|
91
|
-
return `"${str}"`;
|
|
69
|
+
const columnsToForceQuote = columns.map(col => {
|
|
70
|
+
return col.type !== AdminForthDataTypes.FLOAT
|
|
71
|
+
&& col.type !== AdminForthDataTypes.INTEGER
|
|
72
|
+
&& col.type !== AdminForthDataTypes.BOOLEAN;
|
|
73
|
+
});
|
|
74
|
+
const fields = columns.map((col) => col.name);
|
|
75
|
+
const rows = data.data.map((row) => {
|
|
76
|
+
return columns.map((col) => row[col.name]);
|
|
77
|
+
});
|
|
78
|
+
return {
|
|
79
|
+
data: { fields, data: rows },
|
|
80
|
+
columnsToForceQuote,
|
|
81
|
+
exportedCount: data.total,
|
|
82
|
+
ok: true
|
|
92
83
|
};
|
|
93
|
-
let csv = data.data.map((row) => {
|
|
94
|
-
return columns.map((col) => escapeCSV(row[col.name], col)).join(',');
|
|
95
|
-
}).join('\n');
|
|
96
|
-
// add headers
|
|
97
|
-
const headers = columns.map((col) => escapeCSV(col.name)).join(',');
|
|
98
|
-
csv = `${headers}\n${csv}`;
|
|
99
|
-
return { data: csv, exportedCount: data.total, ok: true };
|
|
100
84
|
})
|
|
101
85
|
});
|
|
102
86
|
server.endpoint({
|
|
@@ -119,14 +103,28 @@ export default class ImportExport extends AdminForthPlugin {
|
|
|
119
103
|
return { ok: false, errors };
|
|
120
104
|
}
|
|
121
105
|
const primaryKeyColumn = this.resourceConfig.columns.find(col => col.primaryKey);
|
|
106
|
+
const resourceColumns = columns.map(colName => this.resourceConfig.columns.find(c => c.name === colName));
|
|
122
107
|
const columnValues = Object.values(data);
|
|
123
108
|
for (let i = 0; i < columnValues[0].length; i++) {
|
|
124
109
|
const row = {};
|
|
125
110
|
for (let j = 0; j < columns.length; j++) {
|
|
126
|
-
|
|
111
|
+
const val = columnValues[j][i];
|
|
112
|
+
const resourceCol = resourceColumns[j];
|
|
113
|
+
if ((resourceCol.type === AdminForthDataTypes.INTEGER
|
|
114
|
+
|| resourceCol.type === AdminForthDataTypes.FLOAT) && val !== '') {
|
|
115
|
+
// convert empty strings to null for numeric fields
|
|
116
|
+
row[columns[j]] = +val;
|
|
117
|
+
}
|
|
118
|
+
else if (resourceCol.type === AdminForthDataTypes.BOOLEAN && val !== '') {
|
|
119
|
+
row[columns[j]] = (val.toLowerCase() === 'true' || val === '1' || val === 1);
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
row[columns[j]] = val;
|
|
123
|
+
}
|
|
127
124
|
}
|
|
128
125
|
rows.push(row);
|
|
129
126
|
}
|
|
127
|
+
console.log('Prepared rows for import:', rows);
|
|
130
128
|
let importedCount = 0;
|
|
131
129
|
let updatedCount = 0;
|
|
132
130
|
yield Promise.all(rows.map((row) => __awaiter(this, void 0, void 0, function* () {
|
|
@@ -171,11 +169,24 @@ export default class ImportExport extends AdminForthPlugin {
|
|
|
171
169
|
return { ok: false, errors };
|
|
172
170
|
}
|
|
173
171
|
const primaryKeyColumn = this.resourceConfig.columns.find(col => col.primaryKey);
|
|
172
|
+
const resourceColumns = columns.map(colName => this.resourceConfig.columns.find(c => c.name === colName));
|
|
174
173
|
const columnValues = Object.values(data);
|
|
175
174
|
for (let i = 0; i < columnValues[0].length; i++) {
|
|
176
175
|
const row = {};
|
|
177
176
|
for (let j = 0; j < columns.length; j++) {
|
|
178
|
-
|
|
177
|
+
const val = columnValues[j][i];
|
|
178
|
+
const resourceCol = resourceColumns[j];
|
|
179
|
+
if ((resourceCol.type === AdminForthDataTypes.INTEGER
|
|
180
|
+
|| resourceCol.type === AdminForthDataTypes.FLOAT) && val !== '') {
|
|
181
|
+
// convert empty strings to null for numeric fields
|
|
182
|
+
row[columns[j]] = +val;
|
|
183
|
+
}
|
|
184
|
+
else if (resourceCol.type === AdminForthDataTypes.BOOLEAN && val !== '') {
|
|
185
|
+
row[columns[j]] = (val.toLowerCase() === 'true' || val === '1' || val === 1);
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
row[columns[j]] = val;
|
|
189
|
+
}
|
|
179
190
|
}
|
|
180
191
|
rows.push(row);
|
|
181
192
|
}
|
package/index.ts
CHANGED
|
@@ -66,42 +66,27 @@ export default class ImportExport extends AdminForthPlugin {
|
|
|
66
66
|
getTotals: true,
|
|
67
67
|
});
|
|
68
68
|
|
|
69
|
-
//
|
|
69
|
+
// prepare data for PapaParse unparse
|
|
70
70
|
const columns = this.resourceConfig.columns.filter((col) => !col.virtual);
|
|
71
|
-
|
|
72
|
-
const escapeCSV = (value: any, column?: AdminForthResourceColumn) => {
|
|
73
|
-
if (value === null || value === undefined) {
|
|
74
|
-
return '""';
|
|
75
|
-
}
|
|
76
|
-
if (column?.type === AdminForthDataTypes.FLOAT
|
|
77
|
-
|| column?.type === AdminForthDataTypes.INTEGER) {
|
|
78
|
-
// no quotes for numbers
|
|
79
|
-
return String(value);
|
|
80
|
-
}
|
|
81
|
-
if (column?.type === AdminForthDataTypes.BOOLEAN) {
|
|
82
|
-
// no quotes for boolean values
|
|
83
|
-
if (value === true) {
|
|
84
|
-
return 'true';
|
|
85
|
-
} else if (value === false) {
|
|
86
|
-
return 'false';
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
const str = String(value);
|
|
90
|
-
if (str.includes(',') || str.includes('"') || str.includes('\n')) {
|
|
91
|
-
return `"${str.replace(/"/g, '""')}"`;
|
|
92
|
-
}
|
|
93
|
-
return `"${str}"`;
|
|
94
|
-
};
|
|
95
71
|
|
|
96
|
-
|
|
97
|
-
return
|
|
98
|
-
|
|
72
|
+
const columnsToForceQuote = columns.map(col => {
|
|
73
|
+
return col.type !== AdminForthDataTypes.FLOAT
|
|
74
|
+
&& col.type !== AdminForthDataTypes.INTEGER
|
|
75
|
+
&& col.type !== AdminForthDataTypes.BOOLEAN;
|
|
76
|
+
})
|
|
99
77
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
78
|
+
const fields = columns.map((col) => col.name);
|
|
79
|
+
|
|
80
|
+
const rows = data.data.map((row) => {
|
|
81
|
+
return columns.map((col) => row[col.name]);
|
|
82
|
+
});
|
|
103
83
|
|
|
104
|
-
return {
|
|
84
|
+
return {
|
|
85
|
+
data: { fields, data: rows },
|
|
86
|
+
columnsToForceQuote,
|
|
87
|
+
exportedCount: data.total,
|
|
88
|
+
ok: true
|
|
89
|
+
};
|
|
105
90
|
}
|
|
106
91
|
});
|
|
107
92
|
|
|
@@ -130,15 +115,31 @@ export default class ImportExport extends AdminForthPlugin {
|
|
|
130
115
|
|
|
131
116
|
const primaryKeyColumn = this.resourceConfig.columns.find(col => col.primaryKey);
|
|
132
117
|
|
|
118
|
+
const resourceColumns = columns.map(colName => this.resourceConfig.columns.find(c => c.name === colName));
|
|
119
|
+
|
|
133
120
|
const columnValues: any[] = Object.values(data);
|
|
134
121
|
for (let i = 0; i < columnValues[0].length; i++) {
|
|
135
122
|
const row = {};
|
|
136
123
|
for (let j = 0; j < columns.length; j++) {
|
|
137
|
-
|
|
124
|
+
const val = columnValues[j][i];
|
|
125
|
+
const resourceCol = resourceColumns[j];
|
|
126
|
+
|
|
127
|
+
if ( (resourceCol.type === AdminForthDataTypes.INTEGER
|
|
128
|
+
|| resourceCol.type === AdminForthDataTypes.FLOAT) && val !== ''
|
|
129
|
+
) {
|
|
130
|
+
// convert empty strings to null for numeric fields
|
|
131
|
+
row[columns[j]] = +val;
|
|
132
|
+
} else if (resourceCol.type === AdminForthDataTypes.BOOLEAN && val !== '') {
|
|
133
|
+
row[columns[j]] = (val.toLowerCase() === 'true' || val === '1' || val === 1);
|
|
134
|
+
} else {
|
|
135
|
+
row[columns[j]] = val;
|
|
136
|
+
}
|
|
138
137
|
}
|
|
139
138
|
rows.push(row);
|
|
140
139
|
}
|
|
141
140
|
|
|
141
|
+
console.log('Prepared rows for import:', rows);
|
|
142
|
+
|
|
142
143
|
let importedCount = 0;
|
|
143
144
|
let updatedCount = 0;
|
|
144
145
|
|
|
@@ -190,11 +191,24 @@ export default class ImportExport extends AdminForthPlugin {
|
|
|
190
191
|
}
|
|
191
192
|
|
|
192
193
|
const primaryKeyColumn = this.resourceConfig.columns.find(col => col.primaryKey);
|
|
194
|
+
const resourceColumns = columns.map(colName => this.resourceConfig.columns.find(c => c.name === colName));
|
|
193
195
|
const columnValues: any[] = Object.values(data);
|
|
194
196
|
for (let i = 0; i < columnValues[0].length; i++) {
|
|
195
197
|
const row = {};
|
|
196
198
|
for (let j = 0; j < columns.length; j++) {
|
|
197
|
-
|
|
199
|
+
const val = columnValues[j][i];
|
|
200
|
+
const resourceCol = resourceColumns[j];
|
|
201
|
+
|
|
202
|
+
if ( (resourceCol.type === AdminForthDataTypes.INTEGER
|
|
203
|
+
|| resourceCol.type === AdminForthDataTypes.FLOAT) && val !== ''
|
|
204
|
+
) {
|
|
205
|
+
// convert empty strings to null for numeric fields
|
|
206
|
+
row[columns[j]] = +val;
|
|
207
|
+
} else if (resourceCol.type === AdminForthDataTypes.BOOLEAN && val !== '') {
|
|
208
|
+
row[columns[j]] = (val.toLowerCase() === 'true' || val === '1' || val === 1);
|
|
209
|
+
} else {
|
|
210
|
+
row[columns[j]] = val;
|
|
211
|
+
}
|
|
198
212
|
}
|
|
199
213
|
rows.push(row);
|
|
200
214
|
}
|