@wakastellar/ui 0.2.0 → 0.4.0
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/dist/blocks/activity-timeline/index.d.ts +73 -0
- package/dist/blocks/calendar-view/index.d.ts +56 -0
- package/dist/blocks/chat/index.d.ts +87 -0
- package/dist/blocks/dashboard/index.d.ts +92 -0
- package/dist/blocks/empty-states/index.d.ts +44 -0
- package/dist/blocks/error-pages/index.d.ts +52 -0
- package/dist/blocks/faq/index.d.ts +54 -0
- package/dist/blocks/file-manager/index.d.ts +81 -0
- package/dist/blocks/header/index.d.ts +86 -0
- package/dist/blocks/i18n-editor/index.d.ts +63 -0
- package/dist/blocks/index.d.ts +36 -0
- package/dist/blocks/kanban-board/index.d.ts +77 -0
- package/dist/blocks/landing/index.d.ts +101 -0
- package/dist/blocks/pricing/index.d.ts +60 -0
- package/dist/blocks/profile/index.d.ts +98 -0
- package/dist/blocks/settings/index.d.ts +62 -0
- package/dist/blocks/theme-creator-block/index.d.ts +86 -0
- package/dist/blocks/user-management/index.d.ts +95 -0
- package/dist/blocks/wizard/index.d.ts +88 -0
- package/dist/charts.cjs.js +1 -0
- package/dist/charts.d.ts +17 -0
- package/dist/charts.es.js +16 -0
- package/dist/cn-CAc3sAGM.js +21 -0
- package/dist/cn-zrNBeCrC.js +1 -0
- package/dist/components/DataTable/DataTableBody.d.ts +3 -1
- package/dist/components/DataTable/DataTableHeader.d.ts +3 -1
- package/dist/components/command/index.d.ts +5 -1
- package/dist/components/index.d.ts +19 -0
- package/dist/components/language-selector/index.d.ts +19 -1
- package/dist/components/theme-selector/index.d.ts +10 -0
- package/dist/components/waka-barcode/index.d.ts +27 -0
- package/dist/components/waka-breadcrumb/index.d.ts +43 -0
- package/dist/components/waka-combobox/index.d.ts +81 -0
- package/dist/components/waka-date-range-picker/index.d.ts +68 -0
- package/dist/components/waka-drawer/index.d.ts +59 -0
- package/dist/components/waka-image/index.d.ts +57 -0
- package/dist/components/waka-kanban/index.d.ts +68 -0
- package/dist/components/waka-modal/index.d.ts +82 -0
- package/dist/components/waka-number-input/index.d.ts +60 -0
- package/dist/components/waka-pagination/index.d.ts +67 -0
- package/dist/components/waka-qrcode/index.d.ts +32 -0
- package/dist/components/waka-segmented-control/index.d.ts +42 -0
- package/dist/components/waka-spinner/index.d.ts +57 -21
- package/dist/components/waka-stat/index.d.ts +57 -0
- package/dist/components/waka-stepper/index.d.ts +76 -0
- package/dist/components/waka-theme-creator/index.d.ts +73 -22
- package/dist/components/waka-time-picker/index.d.ts +51 -0
- package/dist/components/waka-timeline/index.d.ts +46 -0
- package/dist/components/waka-tree/index.d.ts +67 -0
- package/dist/components/waka-video/index.d.ts +66 -0
- package/dist/components/waka-virtual-list/index.d.ts +54 -0
- package/dist/export.cjs.js +1 -0
- package/dist/export.d.ts +28 -0
- package/dist/export.es.js +5 -0
- package/dist/index-CENPre_9.js +466 -0
- package/dist/index-CHLjUBPo.js +1 -0
- package/dist/index.cjs.js +54 -155
- package/dist/index.es.js +21942 -12131
- package/dist/rich-text.cjs.js +1 -0
- package/dist/rich-text.d.ts +21 -0
- package/dist/rich-text.es.js +4 -0
- package/dist/types-Bjy1Hy76.js +1111 -0
- package/dist/types-CHv7a1SP.js +1 -0
- package/dist/useDataTableImport-DqeEL4GC.js +124 -0
- package/dist/useDataTableImport-sQwBFAJ_.js +775 -0
- package/package.json +54 -5
|
@@ -0,0 +1,775 @@
|
|
|
1
|
+
import { useState as H, useRef as Z, useEffect as Q, useMemo as q, useCallback as d } from "react";
|
|
2
|
+
class ee {
|
|
3
|
+
constructor(e) {
|
|
4
|
+
this.config = {
|
|
5
|
+
debug: !1,
|
|
6
|
+
minLevel: "debug",
|
|
7
|
+
prefix: "[WakaUI]"
|
|
8
|
+
}, e && (this.config = { ...this.config, ...e });
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Configure the logger
|
|
12
|
+
*/
|
|
13
|
+
configure(e) {
|
|
14
|
+
this.config = { ...this.config, ...e };
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Check if logging is enabled for the given level
|
|
18
|
+
*/
|
|
19
|
+
shouldLog(e) {
|
|
20
|
+
if (e === "error" || e === "warn")
|
|
21
|
+
return !0;
|
|
22
|
+
if (process.env.NODE_ENV === "production" && !this.config.debug)
|
|
23
|
+
return !1;
|
|
24
|
+
const s = ["debug", "info", "warn", "error"], x = s.indexOf(e), T = s.indexOf(this.config.minLevel || "debug");
|
|
25
|
+
return x >= T;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Format log message with prefix
|
|
29
|
+
*/
|
|
30
|
+
format(e) {
|
|
31
|
+
return this.config.prefix ? `${this.config.prefix} ${e}` : e;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Debug level logging (development only by default)
|
|
35
|
+
*/
|
|
36
|
+
debug(e, ...s) {
|
|
37
|
+
this.shouldLog("debug") && console.log(this.format(e), ...s);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Info level logging
|
|
41
|
+
*/
|
|
42
|
+
info(e, ...s) {
|
|
43
|
+
this.shouldLog("info") && console.log(this.format(e), ...s);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Warning level logging (always shown)
|
|
47
|
+
*/
|
|
48
|
+
warn(e, ...s) {
|
|
49
|
+
this.shouldLog("warn") && console.warn(this.format(e), ...s);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Error level logging (always shown)
|
|
53
|
+
*/
|
|
54
|
+
error(e, ...s) {
|
|
55
|
+
this.shouldLog("error") && console.error(this.format(e), ...s);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
const z = new ee(), F = {
|
|
59
|
+
// Generic errors
|
|
60
|
+
UNKNOWN: "WAKA_UNKNOWN",
|
|
61
|
+
VALIDATION: "WAKA_VALIDATION",
|
|
62
|
+
NETWORK: "WAKA_NETWORK",
|
|
63
|
+
TIMEOUT: "WAKA_TIMEOUT",
|
|
64
|
+
// Theme errors
|
|
65
|
+
THEME_LOAD_FAILED: "WAKA_THEME_LOAD_FAILED",
|
|
66
|
+
THEME_PARSE_FAILED: "WAKA_THEME_PARSE_FAILED",
|
|
67
|
+
THEME_APPLY_FAILED: "WAKA_THEME_APPLY_FAILED",
|
|
68
|
+
// Language errors
|
|
69
|
+
LANG_LOAD_FAILED: "WAKA_LANG_LOAD_FAILED",
|
|
70
|
+
LANG_PARSE_FAILED: "WAKA_LANG_PARSE_FAILED",
|
|
71
|
+
TRANSLATION_MISSING: "WAKA_TRANSLATION_MISSING",
|
|
72
|
+
// DataTable errors
|
|
73
|
+
DATATABLE_EXPORT_FAILED: "WAKA_DATATABLE_EXPORT_FAILED",
|
|
74
|
+
DATATABLE_IMPORT_FAILED: "WAKA_DATATABLE_IMPORT_FAILED",
|
|
75
|
+
DATATABLE_PARSE_FAILED: "WAKA_DATATABLE_PARSE_FAILED",
|
|
76
|
+
// Component errors
|
|
77
|
+
COMPONENT_RENDER_FAILED: "WAKA_COMPONENT_RENDER_FAILED",
|
|
78
|
+
COMPONENT_INIT_FAILED: "WAKA_COMPONENT_INIT_FAILED",
|
|
79
|
+
// Provider errors
|
|
80
|
+
PROVIDER_MISSING: "WAKA_PROVIDER_MISSING",
|
|
81
|
+
PROVIDER_CONFIG_INVALID: "WAKA_PROVIDER_CONFIG_INVALID"
|
|
82
|
+
};
|
|
83
|
+
class _ extends Error {
|
|
84
|
+
constructor(e, s = {}) {
|
|
85
|
+
super(e), this.name = "WakaError", this.code = s.code || F.UNKNOWN, this.context = s.context, this.cause = s.cause, this.metadata = s.metadata, this.timestamp = /* @__PURE__ */ new Date(), Error.captureStackTrace && Error.captureStackTrace(this, _);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Create a WakaError from any error type
|
|
89
|
+
*/
|
|
90
|
+
static from(e, s = {}) {
|
|
91
|
+
return e instanceof _ ? e : e instanceof Error ? new _(e.message, {
|
|
92
|
+
...s,
|
|
93
|
+
cause: e
|
|
94
|
+
}) : new _(String(e), s);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Serialize error for logging or transmission
|
|
98
|
+
*/
|
|
99
|
+
toJSON() {
|
|
100
|
+
return {
|
|
101
|
+
name: this.name,
|
|
102
|
+
message: this.message,
|
|
103
|
+
code: this.code,
|
|
104
|
+
context: this.context,
|
|
105
|
+
metadata: this.metadata,
|
|
106
|
+
timestamp: this.timestamp.toISOString(),
|
|
107
|
+
stack: this.stack,
|
|
108
|
+
cause: this.cause?.message
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
function M(h, e = {}) {
|
|
113
|
+
const s = _.from(h, {
|
|
114
|
+
code: e.code,
|
|
115
|
+
context: e.context,
|
|
116
|
+
metadata: e.metadata
|
|
117
|
+
});
|
|
118
|
+
if (e.silent || z.error(
|
|
119
|
+
`${e.context || "Error"}: ${s.message}`,
|
|
120
|
+
s.toJSON()
|
|
121
|
+
), e.onError?.(s), e.rethrow)
|
|
122
|
+
throw s;
|
|
123
|
+
return s;
|
|
124
|
+
}
|
|
125
|
+
function oe(h, e = {}) {
|
|
126
|
+
try {
|
|
127
|
+
return h();
|
|
128
|
+
} catch (s) {
|
|
129
|
+
return M(s, e), e.fallback;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
async function ae(h, e = {}) {
|
|
133
|
+
try {
|
|
134
|
+
return await h();
|
|
135
|
+
} catch (s) {
|
|
136
|
+
return M(s, e), e.fallback;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
function se(h, e = {}) {
|
|
140
|
+
return async (...s) => {
|
|
141
|
+
try {
|
|
142
|
+
return await h(...s);
|
|
143
|
+
} catch (x) {
|
|
144
|
+
throw M(x, e);
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
function ce(h, e, s = {}) {
|
|
149
|
+
if (!h)
|
|
150
|
+
throw new _(e, {
|
|
151
|
+
code: s.code || F.VALIDATION,
|
|
152
|
+
context: s.context,
|
|
153
|
+
metadata: s.metadata
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
function te(h) {
|
|
157
|
+
return h instanceof _;
|
|
158
|
+
}
|
|
159
|
+
function ie(h, e) {
|
|
160
|
+
return te(h) && h.code === e;
|
|
161
|
+
}
|
|
162
|
+
function le(h) {
|
|
163
|
+
return (e, s = F.UNKNOWN, x) => new _(e, { code: s, context: h, metadata: x });
|
|
164
|
+
}
|
|
165
|
+
async function ue(h, e = {}) {
|
|
166
|
+
const {
|
|
167
|
+
maxRetries: s = 3,
|
|
168
|
+
baseDelay: x = 1e3,
|
|
169
|
+
maxDelay: T = 1e4,
|
|
170
|
+
context: y,
|
|
171
|
+
onRetry: b
|
|
172
|
+
} = e;
|
|
173
|
+
let m;
|
|
174
|
+
for (let E = 0; E <= s; E++)
|
|
175
|
+
try {
|
|
176
|
+
return await h();
|
|
177
|
+
} catch (w) {
|
|
178
|
+
if (m = _.from(w, { context: y }), E < s) {
|
|
179
|
+
const g = Math.min(x * Math.pow(2, E), T);
|
|
180
|
+
b?.(E + 1, m), z.warn(
|
|
181
|
+
`${y || "Operation"} failed (attempt ${E + 1}/${s + 1}), retrying in ${g}ms...`
|
|
182
|
+
), await new Promise((k) => setTimeout(k, g));
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
throw m;
|
|
186
|
+
}
|
|
187
|
+
const re = 1e3;
|
|
188
|
+
function pe({
|
|
189
|
+
data: h,
|
|
190
|
+
columns: e,
|
|
191
|
+
exportConfig: s,
|
|
192
|
+
onError: x
|
|
193
|
+
}) {
|
|
194
|
+
const [T, y] = H(0), [b, m] = H(!1), E = Z(null);
|
|
195
|
+
Q(() => () => {
|
|
196
|
+
E.current && (E.current.terminate(), E.current = null);
|
|
197
|
+
}, []);
|
|
198
|
+
const w = q(() => ({
|
|
199
|
+
formats: ["csv", "xlsx", "json"],
|
|
200
|
+
filename: "export",
|
|
201
|
+
includeHeaders: !0,
|
|
202
|
+
useWorker: !0,
|
|
203
|
+
// Utiliser le worker par défaut pour les grandes tables
|
|
204
|
+
workerThreshold: re,
|
|
205
|
+
...s
|
|
206
|
+
}), [s]), g = d((t) => {
|
|
207
|
+
const n = t;
|
|
208
|
+
return n.accessorKey || n.id;
|
|
209
|
+
}, []), k = d((t) => {
|
|
210
|
+
const n = t;
|
|
211
|
+
return typeof t.header == "string" ? t.header : (typeof t.header == "function", n.accessorKey || n.id || "");
|
|
212
|
+
}, []), v = d((t, n) => {
|
|
213
|
+
const o = g(n);
|
|
214
|
+
if (o)
|
|
215
|
+
return t[o];
|
|
216
|
+
}, [g]), S = d(() => e.filter((t) => g(t)).map((t) => ({
|
|
217
|
+
key: g(t),
|
|
218
|
+
header: k(t)
|
|
219
|
+
})), [e, g, k]), O = d(async (t, n, o) => new Promise((r, a) => {
|
|
220
|
+
m(!0), y(0);
|
|
221
|
+
try {
|
|
222
|
+
const p = `
|
|
223
|
+
// Fonction pour convertir en CSV
|
|
224
|
+
function convertToCSV(data, columns) {
|
|
225
|
+
const headers = columns.map(col => col.header).join(',');
|
|
226
|
+
const rows = data.map(row => {
|
|
227
|
+
return columns
|
|
228
|
+
.map(col => {
|
|
229
|
+
const value = row[col.key];
|
|
230
|
+
const stringValue = String(value ?? '');
|
|
231
|
+
if (stringValue.includes(',') || stringValue.includes('"') || stringValue.includes('\\n')) {
|
|
232
|
+
return '"' + stringValue.replace(/"/g, '""') + '"';
|
|
233
|
+
}
|
|
234
|
+
return stringValue;
|
|
235
|
+
})
|
|
236
|
+
.join(',');
|
|
237
|
+
});
|
|
238
|
+
return [headers, ...rows].join('\\n');
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// Fonction pour convertir en JSON
|
|
242
|
+
function convertToJSON(data) {
|
|
243
|
+
return JSON.stringify(data, null, 2);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// Fonction pour convertir en XML
|
|
247
|
+
function convertToXML(data, columns) {
|
|
248
|
+
let xmlContent = '<?xml version="1.0" encoding="UTF-8"?>\\n<data>\\n';
|
|
249
|
+
data.forEach((row, index) => {
|
|
250
|
+
xmlContent += ' <row id="' + index + '">\\n';
|
|
251
|
+
columns.forEach(col => {
|
|
252
|
+
const value = row[col.key];
|
|
253
|
+
const stringValue = String(value ?? '')
|
|
254
|
+
.replace(/&/g, '&')
|
|
255
|
+
.replace(/</g, '<')
|
|
256
|
+
.replace(/>/g, '>');
|
|
257
|
+
xmlContent += ' <' + col.key + '>' + stringValue + '</' + col.key + '>\\n';
|
|
258
|
+
});
|
|
259
|
+
xmlContent += ' </row>\\n';
|
|
260
|
+
});
|
|
261
|
+
xmlContent += '</data>';
|
|
262
|
+
return xmlContent;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// Traitement par chunks avec progression
|
|
266
|
+
function processWithProgress(data, columns, format) {
|
|
267
|
+
const CHUNK_SIZE = 500;
|
|
268
|
+
const totalRows = data.length;
|
|
269
|
+
|
|
270
|
+
if (format === 'json') {
|
|
271
|
+
self.postMessage({ type: 'progress', progress: 50 });
|
|
272
|
+
const result = convertToJSON(data);
|
|
273
|
+
self.postMessage({ type: 'progress', progress: 100 });
|
|
274
|
+
return result;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
let result = '';
|
|
278
|
+
|
|
279
|
+
if (format === 'csv') {
|
|
280
|
+
result = columns.map(col => col.header).join(',') + '\\n';
|
|
281
|
+
for (let i = 0; i < totalRows; i += CHUNK_SIZE) {
|
|
282
|
+
const chunk = data.slice(i, Math.min(i + CHUNK_SIZE, totalRows));
|
|
283
|
+
const chunkRows = chunk.map(row => {
|
|
284
|
+
return columns
|
|
285
|
+
.map(col => {
|
|
286
|
+
const value = row[col.key];
|
|
287
|
+
const stringValue = String(value ?? '');
|
|
288
|
+
if (stringValue.includes(',') || stringValue.includes('"') || stringValue.includes('\\n')) {
|
|
289
|
+
return '"' + stringValue.replace(/"/g, '""') + '"';
|
|
290
|
+
}
|
|
291
|
+
return stringValue;
|
|
292
|
+
})
|
|
293
|
+
.join(',');
|
|
294
|
+
});
|
|
295
|
+
result += chunkRows.join('\\n') + (i + CHUNK_SIZE < totalRows ? '\\n' : '');
|
|
296
|
+
self.postMessage({ type: 'progress', progress: Math.round(((i + CHUNK_SIZE) / totalRows) * 100) });
|
|
297
|
+
}
|
|
298
|
+
return result;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
if (format === 'xml') {
|
|
302
|
+
result = '<?xml version="1.0" encoding="UTF-8"?>\\n<data>\\n';
|
|
303
|
+
for (let i = 0; i < totalRows; i += CHUNK_SIZE) {
|
|
304
|
+
const chunk = data.slice(i, Math.min(i + CHUNK_SIZE, totalRows));
|
|
305
|
+
chunk.forEach((row, idx) => {
|
|
306
|
+
result += ' <row id="' + (i + idx) + '">\\n';
|
|
307
|
+
columns.forEach(col => {
|
|
308
|
+
const value = row[col.key];
|
|
309
|
+
const stringValue = String(value ?? '')
|
|
310
|
+
.replace(/&/g, '&')
|
|
311
|
+
.replace(/</g, '<')
|
|
312
|
+
.replace(/>/g, '>');
|
|
313
|
+
result += ' <' + col.key + '>' + stringValue + '</' + col.key + '>\\n';
|
|
314
|
+
});
|
|
315
|
+
result += ' </row>\\n';
|
|
316
|
+
});
|
|
317
|
+
self.postMessage({ type: 'progress', progress: Math.round(((i + CHUNK_SIZE) / totalRows) * 100) });
|
|
318
|
+
}
|
|
319
|
+
result += '</data>';
|
|
320
|
+
return result;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
return result;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
self.onmessage = function(e) {
|
|
327
|
+
const { format, data, columns } = e.data;
|
|
328
|
+
try {
|
|
329
|
+
const content = processWithProgress(data, columns, format);
|
|
330
|
+
self.postMessage({ type: 'success', content });
|
|
331
|
+
} catch (error) {
|
|
332
|
+
self.postMessage({ type: 'error', error: error.message || 'Unknown error' });
|
|
333
|
+
}
|
|
334
|
+
};
|
|
335
|
+
`, f = new Blob([p], { type: "application/javascript" }), c = URL.createObjectURL(f), u = new Worker(c);
|
|
336
|
+
E.current = u, u.onmessage = (I) => {
|
|
337
|
+
const { type: A, content: J, progress: $, error: K } = I.data;
|
|
338
|
+
if (A === "progress")
|
|
339
|
+
y($);
|
|
340
|
+
else if (A === "success") {
|
|
341
|
+
let C, W;
|
|
342
|
+
switch (n) {
|
|
343
|
+
case "csv":
|
|
344
|
+
C = "text/csv;charset=utf-8;", W = "csv";
|
|
345
|
+
break;
|
|
346
|
+
case "json":
|
|
347
|
+
C = "application/json", W = "json";
|
|
348
|
+
break;
|
|
349
|
+
case "xml":
|
|
350
|
+
C = "application/xml", W = "xml";
|
|
351
|
+
break;
|
|
352
|
+
default:
|
|
353
|
+
C = "text/plain", W = "txt";
|
|
354
|
+
}
|
|
355
|
+
const Y = new Blob([J], { type: C }), X = document.createElement("a");
|
|
356
|
+
X.href = URL.createObjectURL(Y), X.download = `${o}.${W}`, X.click(), URL.revokeObjectURL(X.href), u.terminate(), URL.revokeObjectURL(c), E.current = null, m(!1), y(0), r();
|
|
357
|
+
} else A === "error" && (u.terminate(), URL.revokeObjectURL(c), E.current = null, m(!1), y(0), a(new Error(K)));
|
|
358
|
+
}, u.onerror = (I) => {
|
|
359
|
+
u.terminate(), URL.revokeObjectURL(c), E.current = null, m(!1), y(0), a(new Error(I.message));
|
|
360
|
+
};
|
|
361
|
+
const L = S();
|
|
362
|
+
u.postMessage({
|
|
363
|
+
format: n,
|
|
364
|
+
data: t,
|
|
365
|
+
columns: L
|
|
366
|
+
});
|
|
367
|
+
} catch (p) {
|
|
368
|
+
m(!1), y(0), a(p);
|
|
369
|
+
}
|
|
370
|
+
}), [S]), D = d((t, n) => {
|
|
371
|
+
if (!t.length) return;
|
|
372
|
+
const o = e.filter((u) => g(u)), r = o.map((u) => k(u)).join(","), a = t.map((u) => o.map((L) => {
|
|
373
|
+
const I = v(u, L), A = String(I ?? "");
|
|
374
|
+
return A.includes(",") || A.includes('"') || A.includes(`
|
|
375
|
+
`) ? `"${A.replace(/"/g, '""')}"` : A;
|
|
376
|
+
}).join(",")), p = [r, ...a].join(`
|
|
377
|
+
`), f = new Blob([p], { type: "text/csv;charset=utf-8;" }), c = document.createElement("a");
|
|
378
|
+
c.href = URL.createObjectURL(f), c.download = `${n || w.filename}.csv`, c.click(), URL.revokeObjectURL(c.href);
|
|
379
|
+
}, [e, w.filename, g, k, v]), U = d((t, n) => {
|
|
380
|
+
const o = JSON.stringify(t, null, 2), r = new Blob([o], { type: "application/json" }), a = document.createElement("a");
|
|
381
|
+
a.href = URL.createObjectURL(r), a.download = `${n || w.filename}.json`, a.click(), URL.revokeObjectURL(a.href);
|
|
382
|
+
}, [w.filename]), R = d(async (t, n) => {
|
|
383
|
+
try {
|
|
384
|
+
if (typeof window > "u")
|
|
385
|
+
throw new Error("XLSX export not available in server environment");
|
|
386
|
+
let o;
|
|
387
|
+
try {
|
|
388
|
+
o = await import("xlsx");
|
|
389
|
+
} catch {
|
|
390
|
+
throw new Error(
|
|
391
|
+
"La dépendance 'xlsx' est requise pour l'export Excel. Installez-la avec: pnpm add xlsx (version >=0.18.0)"
|
|
392
|
+
);
|
|
393
|
+
}
|
|
394
|
+
const r = e.filter((u) => g(u)), p = [
|
|
395
|
+
r.map((u) => k(u)),
|
|
396
|
+
...t.map(
|
|
397
|
+
(u) => r.map((L) => v(u, L))
|
|
398
|
+
)
|
|
399
|
+
], f = o.utils.aoa_to_sheet(p), c = o.utils.book_new();
|
|
400
|
+
o.utils.book_append_sheet(c, f, "Sheet1"), o.writeFile(c, `${n || w.filename}.xlsx`);
|
|
401
|
+
} catch (o) {
|
|
402
|
+
throw M(o, {
|
|
403
|
+
code: F.DATATABLE_EXPORT_FAILED,
|
|
404
|
+
context: "DataTable.exportToXLSX",
|
|
405
|
+
onError: x
|
|
406
|
+
});
|
|
407
|
+
}
|
|
408
|
+
}, [e, w.filename, g, k, v, x]), V = d(async (t, n) => {
|
|
409
|
+
try {
|
|
410
|
+
if (typeof window > "u")
|
|
411
|
+
throw new Error("PDF export not available in server environment");
|
|
412
|
+
let o;
|
|
413
|
+
try {
|
|
414
|
+
o = await import("jspdf");
|
|
415
|
+
} catch {
|
|
416
|
+
throw new Error(
|
|
417
|
+
"La dépendance 'jspdf' est requise pour l'export PDF. Installez-la avec: pnpm add jspdf (version >=2.5.0)"
|
|
418
|
+
);
|
|
419
|
+
}
|
|
420
|
+
try {
|
|
421
|
+
await import("jspdf-autotable");
|
|
422
|
+
} catch {
|
|
423
|
+
throw new Error(
|
|
424
|
+
"La dépendance 'jspdf-autotable' est requise pour l'export PDF. Installez-la avec: pnpm add jspdf-autotable (version >=3.5.0)"
|
|
425
|
+
);
|
|
426
|
+
}
|
|
427
|
+
const r = new o.default(), a = e.filter((c) => g(c)), p = a.map((c) => k(c)), f = t.map(
|
|
428
|
+
(c) => a.map((u) => v(c, u))
|
|
429
|
+
);
|
|
430
|
+
r.autoTable({
|
|
431
|
+
head: [p],
|
|
432
|
+
body: f,
|
|
433
|
+
startY: 20,
|
|
434
|
+
styles: { fontSize: 8 },
|
|
435
|
+
headStyles: { fillColor: [66, 139, 202] }
|
|
436
|
+
}), r.save(`${n || w.filename}.pdf`);
|
|
437
|
+
} catch (o) {
|
|
438
|
+
throw M(o, {
|
|
439
|
+
code: F.DATATABLE_EXPORT_FAILED,
|
|
440
|
+
context: "DataTable.exportToPDF",
|
|
441
|
+
onError: x
|
|
442
|
+
});
|
|
443
|
+
}
|
|
444
|
+
}, [e, w.filename, g, k, v, x]), P = d((t, n) => {
|
|
445
|
+
const o = e.filter((f) => g(f));
|
|
446
|
+
let r = `<?xml version="1.0" encoding="UTF-8"?>
|
|
447
|
+
<data>
|
|
448
|
+
`;
|
|
449
|
+
t.forEach((f, c) => {
|
|
450
|
+
r += ` <row id="${c}">
|
|
451
|
+
`, o.forEach((u) => {
|
|
452
|
+
const L = g(u);
|
|
453
|
+
if (L) {
|
|
454
|
+
const I = v(f, u), A = String(I ?? "").replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
455
|
+
r += ` <${L}>${A}</${L}>
|
|
456
|
+
`;
|
|
457
|
+
}
|
|
458
|
+
}), r += ` </row>
|
|
459
|
+
`;
|
|
460
|
+
}), r += "</data>";
|
|
461
|
+
const a = new Blob([r], { type: "application/xml" }), p = document.createElement("a");
|
|
462
|
+
p.href = URL.createObjectURL(a), p.download = `${n || w.filename}.xml`, p.click(), URL.revokeObjectURL(p.href);
|
|
463
|
+
}, [e, w.filename, g, v]), N = d(async (t, n, o) => {
|
|
464
|
+
const r = n || h, a = o || w.filename;
|
|
465
|
+
if (w.onExport) {
|
|
466
|
+
w.onExport(r, t);
|
|
467
|
+
return;
|
|
468
|
+
}
|
|
469
|
+
const p = ["csv", "json", "xml"];
|
|
470
|
+
if (w.useWorker && r.length >= w.workerThreshold && p.includes(t.toLowerCase()) && typeof Worker < "u") {
|
|
471
|
+
await O(
|
|
472
|
+
r,
|
|
473
|
+
t.toLowerCase(),
|
|
474
|
+
a
|
|
475
|
+
);
|
|
476
|
+
return;
|
|
477
|
+
}
|
|
478
|
+
switch (t.toLowerCase()) {
|
|
479
|
+
case "csv":
|
|
480
|
+
D(r, a);
|
|
481
|
+
break;
|
|
482
|
+
case "json":
|
|
483
|
+
U(r, a);
|
|
484
|
+
break;
|
|
485
|
+
case "xlsx":
|
|
486
|
+
await R(r, a);
|
|
487
|
+
break;
|
|
488
|
+
case "pdf":
|
|
489
|
+
await V(r, a);
|
|
490
|
+
break;
|
|
491
|
+
case "xml":
|
|
492
|
+
P(r, a);
|
|
493
|
+
break;
|
|
494
|
+
default:
|
|
495
|
+
throw new Error(`Format d'export non supporté: ${t}`);
|
|
496
|
+
}
|
|
497
|
+
}, [h, w, O, D, U, R, V, P]), B = d(async (t) => N(t), [N]), i = d(async (t, n) => N(t, n), [N]), l = d(() => {
|
|
498
|
+
E.current && (E.current.terminate(), E.current = null, m(!1), y(0));
|
|
499
|
+
}, []);
|
|
500
|
+
return {
|
|
501
|
+
exportData: N,
|
|
502
|
+
exportAll: B,
|
|
503
|
+
exportSelected: i,
|
|
504
|
+
cancelExport: l,
|
|
505
|
+
exportProgress: T,
|
|
506
|
+
isExporting: b,
|
|
507
|
+
supportedFormats: w.formats,
|
|
508
|
+
isExportSupported: (t) => w.formats.includes(t)
|
|
509
|
+
};
|
|
510
|
+
}
|
|
511
|
+
const G = 5e3, j = 1e3;
|
|
512
|
+
function me({
|
|
513
|
+
importConfig: h,
|
|
514
|
+
onError: e
|
|
515
|
+
}) {
|
|
516
|
+
const [s, x] = H(0), [T, y] = H(!1), b = Z(null), m = q(() => ({
|
|
517
|
+
accept: ".csv,.xlsx,.json,.xml",
|
|
518
|
+
...h
|
|
519
|
+
}), [h]), E = d((i, l = ",") => {
|
|
520
|
+
const t = i.split(`
|
|
521
|
+
`).filter((r) => r.trim());
|
|
522
|
+
if (t.length === 0) return [];
|
|
523
|
+
const n = t[0].split(l).map((r) => r.trim().replace(/"/g, ""));
|
|
524
|
+
return t.slice(1).map((r) => {
|
|
525
|
+
const a = r.split(l).map((f) => f.trim().replace(/"/g, "")), p = {};
|
|
526
|
+
return n.forEach((f, c) => {
|
|
527
|
+
p[f] = a[c] || "";
|
|
528
|
+
}), p;
|
|
529
|
+
});
|
|
530
|
+
}, []), w = d(async (i, l = ",", t, n) => {
|
|
531
|
+
const o = i.split(`
|
|
532
|
+
`).filter((c) => c.trim());
|
|
533
|
+
if (o.length === 0) return [];
|
|
534
|
+
const r = o[0].split(l).map((c) => c.trim().replace(/"/g, "")), a = o.slice(1), p = a.length, f = [];
|
|
535
|
+
for (let c = 0; c < p; c += j) {
|
|
536
|
+
if (n?.aborted)
|
|
537
|
+
throw new Error("Import annulé");
|
|
538
|
+
const u = a.slice(c, c + j), L = u.map((A) => {
|
|
539
|
+
const J = A.split(l).map((K) => K.trim().replace(/"/g, "")), $ = {};
|
|
540
|
+
return r.forEach((K, C) => {
|
|
541
|
+
$[K] = J[C] || "";
|
|
542
|
+
}), $;
|
|
543
|
+
});
|
|
544
|
+
f.push(...L);
|
|
545
|
+
const I = Math.min(100, Math.round((c + u.length) / p * 100));
|
|
546
|
+
t?.(I), await new Promise((A) => setTimeout(A, 0));
|
|
547
|
+
}
|
|
548
|
+
return f;
|
|
549
|
+
}, []), g = d(async (i, l, t) => {
|
|
550
|
+
const n = JSON.parse(i), o = Array.isArray(n) ? n : [n];
|
|
551
|
+
if (o.length < G)
|
|
552
|
+
return l?.(100), o;
|
|
553
|
+
const r = [], a = o.length;
|
|
554
|
+
for (let p = 0; p < a; p += j) {
|
|
555
|
+
if (t?.aborted)
|
|
556
|
+
throw new Error("Import annulé");
|
|
557
|
+
const f = o.slice(p, p + j);
|
|
558
|
+
r.push(...f);
|
|
559
|
+
const c = Math.min(100, Math.round((p + f.length) / a * 100));
|
|
560
|
+
l?.(c), await new Promise((u) => setTimeout(u, 0));
|
|
561
|
+
}
|
|
562
|
+
return r;
|
|
563
|
+
}, []), k = d((i) => {
|
|
564
|
+
try {
|
|
565
|
+
const l = JSON.parse(i);
|
|
566
|
+
return Array.isArray(l) ? l : [l];
|
|
567
|
+
} catch {
|
|
568
|
+
throw new Error("Format JSON invalide");
|
|
569
|
+
}
|
|
570
|
+
}, []), v = d((i) => {
|
|
571
|
+
try {
|
|
572
|
+
const n = new DOMParser().parseFromString(i, "text/xml").querySelectorAll("row");
|
|
573
|
+
return Array.from(n).map((o) => {
|
|
574
|
+
const r = {};
|
|
575
|
+
return Array.from(o.children).forEach((a) => {
|
|
576
|
+
r[a.tagName] = a.textContent || "";
|
|
577
|
+
}), r;
|
|
578
|
+
});
|
|
579
|
+
} catch {
|
|
580
|
+
throw new Error("Format XML invalide");
|
|
581
|
+
}
|
|
582
|
+
}, []), S = d(async (i) => {
|
|
583
|
+
try {
|
|
584
|
+
if (typeof window > "u")
|
|
585
|
+
throw new Error("XLSX parsing not available in server environment");
|
|
586
|
+
let l;
|
|
587
|
+
try {
|
|
588
|
+
l = await import("xlsx");
|
|
589
|
+
} catch {
|
|
590
|
+
throw new Error(
|
|
591
|
+
"La dépendance 'xlsx' est requise pour l'import Excel. Installez-la avec: pnpm add xlsx (version >=0.18.0)"
|
|
592
|
+
);
|
|
593
|
+
}
|
|
594
|
+
const t = await i.arrayBuffer(), n = l.read(t, { type: "array" }), o = n.SheetNames[0], r = n.Sheets[o], a = l.utils.sheet_to_json(r, { header: 1 });
|
|
595
|
+
if (a.length === 0) return [];
|
|
596
|
+
const p = a[0];
|
|
597
|
+
return a.slice(1).map((f) => {
|
|
598
|
+
const c = f, u = {};
|
|
599
|
+
return p.forEach((L, I) => {
|
|
600
|
+
u[L] = c[I] ?? "";
|
|
601
|
+
}), u;
|
|
602
|
+
});
|
|
603
|
+
} catch {
|
|
604
|
+
throw new Error("Erreur lors du parsing du fichier XLSX");
|
|
605
|
+
}
|
|
606
|
+
}, []), O = d((i) => m.validate ? m.validate(i) : Array.isArray(i) ? i.length === 0 ? { valid: !1, errors: ["Aucune donnée trouvée"] } : { valid: !0, errors: [] } : { valid: !1, errors: ["Les données doivent être un tableau"] }, [m.validate]), D = d((i) => m.columnMapping ? i.map((l) => {
|
|
607
|
+
const t = {};
|
|
608
|
+
return Object.entries(m.columnMapping).forEach(([n, o]) => {
|
|
609
|
+
l[n] !== void 0 && (t[o] = l[n]);
|
|
610
|
+
}), t;
|
|
611
|
+
}) : i, [m.columnMapping]), U = d(async (i) => {
|
|
612
|
+
const l = i.name.split(".").pop()?.toLowerCase();
|
|
613
|
+
let t = [];
|
|
614
|
+
try {
|
|
615
|
+
const n = await i.text();
|
|
616
|
+
switch (l) {
|
|
617
|
+
case "csv":
|
|
618
|
+
t = E(n, m.parseOptions?.csv?.delimiter);
|
|
619
|
+
break;
|
|
620
|
+
case "json":
|
|
621
|
+
t = k(n);
|
|
622
|
+
break;
|
|
623
|
+
case "xml":
|
|
624
|
+
t = v(n);
|
|
625
|
+
break;
|
|
626
|
+
case "xlsx":
|
|
627
|
+
t = await S(i);
|
|
628
|
+
break;
|
|
629
|
+
default:
|
|
630
|
+
throw new Error(`Format de fichier non supporté: ${l}`);
|
|
631
|
+
}
|
|
632
|
+
const o = O(t);
|
|
633
|
+
if (!o.valid)
|
|
634
|
+
throw new Error(`Données invalides: ${o.errors.join(", ")}`);
|
|
635
|
+
const r = D(t);
|
|
636
|
+
return m.onImport && m.onImport(r), r;
|
|
637
|
+
} catch (n) {
|
|
638
|
+
throw M(n, {
|
|
639
|
+
code: F.DATATABLE_IMPORT_FAILED,
|
|
640
|
+
context: `DataTable.importData(${i.name})`,
|
|
641
|
+
onError: e
|
|
642
|
+
});
|
|
643
|
+
}
|
|
644
|
+
}, [m, E, k, v, S, O, D, e]), R = d(() => {
|
|
645
|
+
const i = document.createElement("input");
|
|
646
|
+
return i.type = "file", i.accept = m.accept, i.multiple = !1, i;
|
|
647
|
+
}, [m.accept]), V = d(() => new Promise((i, l) => {
|
|
648
|
+
const t = R();
|
|
649
|
+
t.onchange = async (n) => {
|
|
650
|
+
const o = n.target.files?.[0];
|
|
651
|
+
if (!o) {
|
|
652
|
+
l(new Error("Aucun fichier sélectionné"));
|
|
653
|
+
return;
|
|
654
|
+
}
|
|
655
|
+
try {
|
|
656
|
+
const r = await U(o);
|
|
657
|
+
i(r);
|
|
658
|
+
} catch (r) {
|
|
659
|
+
l(r);
|
|
660
|
+
}
|
|
661
|
+
}, t.click();
|
|
662
|
+
}), [R, U]), P = d(async (i, l) => {
|
|
663
|
+
const t = i.name.split(".").pop()?.toLowerCase();
|
|
664
|
+
b.current = new AbortController();
|
|
665
|
+
const n = b.current.signal;
|
|
666
|
+
y(!0), x(0);
|
|
667
|
+
const o = (r) => {
|
|
668
|
+
x(r), l?.onProgress?.(r);
|
|
669
|
+
};
|
|
670
|
+
try {
|
|
671
|
+
const r = await i.text();
|
|
672
|
+
let a = [];
|
|
673
|
+
const p = r.split(`
|
|
674
|
+
`).length;
|
|
675
|
+
switch (t) {
|
|
676
|
+
case "csv":
|
|
677
|
+
p > G ? a = await w(
|
|
678
|
+
r,
|
|
679
|
+
m.parseOptions?.csv?.delimiter,
|
|
680
|
+
o,
|
|
681
|
+
n
|
|
682
|
+
) : (a = E(r, m.parseOptions?.csv?.delimiter), o(100));
|
|
683
|
+
break;
|
|
684
|
+
case "json":
|
|
685
|
+
a = await g(r, o, n);
|
|
686
|
+
break;
|
|
687
|
+
case "xml":
|
|
688
|
+
a = v(r), o(100);
|
|
689
|
+
break;
|
|
690
|
+
case "xlsx":
|
|
691
|
+
a = await S(i), o(100);
|
|
692
|
+
break;
|
|
693
|
+
default:
|
|
694
|
+
throw new Error(`Format de fichier non supporté: ${t}`);
|
|
695
|
+
}
|
|
696
|
+
if (n.aborted)
|
|
697
|
+
throw new Error("Import annulé");
|
|
698
|
+
const f = O(a);
|
|
699
|
+
if (!f.valid)
|
|
700
|
+
throw new Error(`Données invalides: ${f.errors.join(", ")}`);
|
|
701
|
+
let c;
|
|
702
|
+
if (a.length > G && m.columnMapping) {
|
|
703
|
+
c = [];
|
|
704
|
+
for (let u = 0; u < a.length; u += j) {
|
|
705
|
+
if (n.aborted)
|
|
706
|
+
throw new Error("Import annulé");
|
|
707
|
+
const L = a.slice(u, u + j), I = D(L);
|
|
708
|
+
c.push(...I), l?.onChunk?.(I, c.length), await new Promise((A) => setTimeout(A, 0));
|
|
709
|
+
}
|
|
710
|
+
} else
|
|
711
|
+
c = D(a);
|
|
712
|
+
return m.onImport && m.onImport(c), c;
|
|
713
|
+
} catch (r) {
|
|
714
|
+
throw M(r, {
|
|
715
|
+
code: F.DATATABLE_IMPORT_FAILED,
|
|
716
|
+
context: `DataTable.importDataStreaming(${i.name})`,
|
|
717
|
+
onError: e
|
|
718
|
+
});
|
|
719
|
+
} finally {
|
|
720
|
+
y(!1), b.current = null;
|
|
721
|
+
}
|
|
722
|
+
}, [m, E, w, k, g, v, S, O, D, e]), N = d(() => {
|
|
723
|
+
b.current && (b.current.abort(), y(!1), x(0));
|
|
724
|
+
}, []), B = d((i) => new Promise((l, t) => {
|
|
725
|
+
const n = R();
|
|
726
|
+
n.onchange = async (o) => {
|
|
727
|
+
const r = o.target.files?.[0];
|
|
728
|
+
if (!r) {
|
|
729
|
+
t(new Error("Aucun fichier sélectionné"));
|
|
730
|
+
return;
|
|
731
|
+
}
|
|
732
|
+
try {
|
|
733
|
+
const a = await P(r, i);
|
|
734
|
+
l(a);
|
|
735
|
+
} catch (a) {
|
|
736
|
+
t(a);
|
|
737
|
+
}
|
|
738
|
+
}, n.click();
|
|
739
|
+
}), [R, P]);
|
|
740
|
+
return {
|
|
741
|
+
// Import standard (synchrone)
|
|
742
|
+
importData: U,
|
|
743
|
+
importWithUI: V,
|
|
744
|
+
// Import streaming (pour fichiers volumineux)
|
|
745
|
+
importDataStreaming: P,
|
|
746
|
+
importWithUIStreaming: B,
|
|
747
|
+
cancelImport: N,
|
|
748
|
+
// État du streaming
|
|
749
|
+
importProgress: s,
|
|
750
|
+
isImporting: T,
|
|
751
|
+
// Utilitaires
|
|
752
|
+
supportedFormats: m.accept?.split(",") || [],
|
|
753
|
+
isFormatSupported: (i) => {
|
|
754
|
+
const l = i.split(".").pop()?.toLowerCase();
|
|
755
|
+
return m.accept?.includes(l || "") || !1;
|
|
756
|
+
}
|
|
757
|
+
};
|
|
758
|
+
}
|
|
759
|
+
export {
|
|
760
|
+
F as E,
|
|
761
|
+
ee as L,
|
|
762
|
+
_ as W,
|
|
763
|
+
me as a,
|
|
764
|
+
ae as b,
|
|
765
|
+
ce as c,
|
|
766
|
+
ie as d,
|
|
767
|
+
le as e,
|
|
768
|
+
M as h,
|
|
769
|
+
te as i,
|
|
770
|
+
z as l,
|
|
771
|
+
ue as r,
|
|
772
|
+
oe as t,
|
|
773
|
+
pe as u,
|
|
774
|
+
se as w
|
|
775
|
+
};
|