@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 CHANGED
@@ -10,5 +10,5 @@ custom/package-lock.json
10
10
  custom/package.json
11
11
  custom/tsconfig.json
12
12
 
13
- sent 16,779 bytes received 115 bytes 33,788.00 bytes/sec
14
- total size is 16,359 speedup is 0.97
13
+ sent 16,704 bytes received 115 bytes 33,638.00 bytes/sec
14
+ total size is 16,284 speedup is 0.97
@@ -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(parsedData, {
62
- quotes: true, // Force quotes around all fields
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
- function handleImportClick() {
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(parsedData, {
62
- quotes: true, // Force quotes around all fields
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
- function handleImportClick() {
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
- // csv export
67
+ // prepare data for PapaParse unparse
68
68
  const columns = this.resourceConfig.columns.filter((col) => !col.virtual);
69
- const escapeCSV = (value, column) => {
70
- if (value === null || value === undefined) {
71
- return '""';
72
- }
73
- if ((column === null || column === void 0 ? void 0 : column.type) === AdminForthDataTypes.FLOAT
74
- || (column === null || column === void 0 ? void 0 : column.type) === AdminForthDataTypes.INTEGER) {
75
- // no quotes for numbers
76
- return String(value);
77
- }
78
- if ((column === null || column === void 0 ? void 0 : column.type) === AdminForthDataTypes.BOOLEAN) {
79
- // no quotes for boolean values
80
- if (value === true) {
81
- return 'true';
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
- row[columns[j]] = columnValues[j][i];
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
- row[columns[j]] = columnValues[j][i];
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
- // csv export
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
- let csv = data.data.map((row) => {
97
- return columns.map((col) => escapeCSV(row[col.name], col)).join(',');
98
- }).join('\n');
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
- // add headers
101
- const headers = columns.map((col) => escapeCSV(col.name)).join(',');
102
- csv = `${headers}\n${csv}`;
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 { data: csv, exportedCount: data.total, ok: true };
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
- row[columns[j]] = columnValues[j][i];
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
- row[columns[j]] = columnValues[j][i];
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
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adminforth/import-export",
3
- "version": "1.4.8",
3
+ "version": "1.4.9",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "type": "module",