@cristianmpx/react-import-sheet-ui-raw 1.0.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/README.md +67 -0
- package/dist/index.d.mts +750 -0
- package/dist/index.d.ts +750 -0
- package/dist/index.js +1766 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1696 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +114 -0
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,1696 @@
|
|
|
1
|
+
// src/hooks/useRawImporterRoot/useRawImporterRoot.ts
|
|
2
|
+
import { useMemo } from "react";
|
|
3
|
+
var defaultStages = {};
|
|
4
|
+
function useRawImporterRoot(options = {}) {
|
|
5
|
+
const {
|
|
6
|
+
layout,
|
|
7
|
+
engine,
|
|
8
|
+
persist,
|
|
9
|
+
persistKey,
|
|
10
|
+
fuzzyMatch = true,
|
|
11
|
+
editingEnabled = true,
|
|
12
|
+
stages = defaultStages,
|
|
13
|
+
autoApplyMappingWhenMismatchesAtMost = "never",
|
|
14
|
+
showErrorWhenMismatchesAbove,
|
|
15
|
+
onSubmit,
|
|
16
|
+
submitKeyMap
|
|
17
|
+
} = options;
|
|
18
|
+
const providerProps = useMemo(
|
|
19
|
+
() => ({
|
|
20
|
+
layout,
|
|
21
|
+
engine,
|
|
22
|
+
persist,
|
|
23
|
+
persistKey,
|
|
24
|
+
onSubmit,
|
|
25
|
+
submitKeyMap
|
|
26
|
+
}),
|
|
27
|
+
[layout, engine, persist, persistKey, onSubmit, submitKeyMap]
|
|
28
|
+
);
|
|
29
|
+
const rootConfig = useMemo(
|
|
30
|
+
() => ({
|
|
31
|
+
fuzzyMatch,
|
|
32
|
+
editingEnabled,
|
|
33
|
+
stages: { ...defaultStages, ...stages },
|
|
34
|
+
autoApplyMappingWhenMismatchesAtMost,
|
|
35
|
+
showErrorWhenMismatchesAbove
|
|
36
|
+
}),
|
|
37
|
+
[
|
|
38
|
+
fuzzyMatch,
|
|
39
|
+
editingEnabled,
|
|
40
|
+
stages,
|
|
41
|
+
autoApplyMappingWhenMismatchesAtMost,
|
|
42
|
+
showErrorWhenMismatchesAbove
|
|
43
|
+
]
|
|
44
|
+
);
|
|
45
|
+
return { providerProps, rootConfig };
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// src/hooks/useRawImporterRoot/RootConfigContext.tsx
|
|
49
|
+
import { createContext } from "react";
|
|
50
|
+
import { jsx } from "react/jsx-runtime";
|
|
51
|
+
var defaultConfig = {
|
|
52
|
+
fuzzyMatch: true,
|
|
53
|
+
editingEnabled: true,
|
|
54
|
+
stages: {},
|
|
55
|
+
autoApplyMappingWhenMismatchesAtMost: "never",
|
|
56
|
+
showErrorWhenMismatchesAbove: void 0
|
|
57
|
+
};
|
|
58
|
+
var RootConfigContext = createContext(defaultConfig);
|
|
59
|
+
var LayoutContext = createContext(null);
|
|
60
|
+
function RootConfigProvider({ rootConfig, children }) {
|
|
61
|
+
return /* @__PURE__ */ jsx(RootConfigContext.Provider, { value: rootConfig, children });
|
|
62
|
+
}
|
|
63
|
+
function LayoutProvider({ layout, children }) {
|
|
64
|
+
return /* @__PURE__ */ jsx(LayoutContext.Provider, { value: layout, children });
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// src/hooks/useStatusView/useStatusView.ts
|
|
68
|
+
import { useContext, useEffect, useMemo as useMemo2, useRef } from "react";
|
|
69
|
+
import { useConvert, useImporterStatus } from "@cristianmpx/react-import-sheet-headless";
|
|
70
|
+
|
|
71
|
+
// src/shared/types/status-views.ts
|
|
72
|
+
function getViewFromState(status, convertResult) {
|
|
73
|
+
if (convertResult !== null && convertResult !== void 0) {
|
|
74
|
+
return "mapping";
|
|
75
|
+
}
|
|
76
|
+
switch (status) {
|
|
77
|
+
case "idle":
|
|
78
|
+
case "loading":
|
|
79
|
+
case "parsing":
|
|
80
|
+
return "idle";
|
|
81
|
+
case "validating":
|
|
82
|
+
case "transforming":
|
|
83
|
+
return "process";
|
|
84
|
+
case "success":
|
|
85
|
+
return "result";
|
|
86
|
+
case "error":
|
|
87
|
+
case "cancelled":
|
|
88
|
+
return "error";
|
|
89
|
+
default:
|
|
90
|
+
return "idle";
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// src/hooks/useStatusView/useStatusView.ts
|
|
95
|
+
function applyStages(view, stages) {
|
|
96
|
+
if (view === "mapping" && stages.mapping === false) return "idle";
|
|
97
|
+
if (view === "process" && stages.process === false) return "idle";
|
|
98
|
+
if (view === "result" && stages.result === false) return "idle";
|
|
99
|
+
return view;
|
|
100
|
+
}
|
|
101
|
+
function resolveMappingView(rawView, mismatchCount, autoApply, showErrorAbove) {
|
|
102
|
+
if (rawView !== "mapping") {
|
|
103
|
+
return { view: rawView, mappingErrorDetail: null };
|
|
104
|
+
}
|
|
105
|
+
if (showErrorAbove != null && mismatchCount > showErrorAbove) {
|
|
106
|
+
return {
|
|
107
|
+
view: "error",
|
|
108
|
+
mappingErrorDetail: {
|
|
109
|
+
code: "TOO_MANY_MISMATCHES",
|
|
110
|
+
mismatchCount,
|
|
111
|
+
maxAllowed: showErrorAbove
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
if (autoApply !== "never" && typeof autoApply === "number" && mismatchCount <= autoApply) {
|
|
116
|
+
return { view: "process", mappingErrorDetail: null };
|
|
117
|
+
}
|
|
118
|
+
return { view: "mapping", mappingErrorDetail: null };
|
|
119
|
+
}
|
|
120
|
+
function useStatusView() {
|
|
121
|
+
const rootConfig = useContext(RootConfigContext);
|
|
122
|
+
const { status, progressEventTarget } = useImporterStatus();
|
|
123
|
+
const { convertResult } = useConvert();
|
|
124
|
+
const mismatchCount = useMemo2(
|
|
125
|
+
() => convertResult?.mismatches?.length ?? 0,
|
|
126
|
+
[convertResult]
|
|
127
|
+
);
|
|
128
|
+
const { view, mappingErrorDetail } = useMemo2(() => {
|
|
129
|
+
const raw = getViewFromState(status, convertResult);
|
|
130
|
+
const afterStages = applyStages(raw, rootConfig.stages);
|
|
131
|
+
return resolveMappingView(
|
|
132
|
+
afterStages,
|
|
133
|
+
mismatchCount,
|
|
134
|
+
rootConfig.autoApplyMappingWhenMismatchesAtMost,
|
|
135
|
+
rootConfig.showErrorWhenMismatchesAbove
|
|
136
|
+
);
|
|
137
|
+
}, [
|
|
138
|
+
status,
|
|
139
|
+
convertResult,
|
|
140
|
+
rootConfig.stages,
|
|
141
|
+
mismatchCount,
|
|
142
|
+
rootConfig.autoApplyMappingWhenMismatchesAtMost,
|
|
143
|
+
rootConfig.showErrorWhenMismatchesAbove
|
|
144
|
+
]);
|
|
145
|
+
const appliedRef = useRef(null);
|
|
146
|
+
useEffect(() => {
|
|
147
|
+
const autoApply = rootConfig.autoApplyMappingWhenMismatchesAtMost;
|
|
148
|
+
if (convertResult != null && autoApply !== "never" && typeof autoApply === "number" && mismatchCount <= autoApply && appliedRef.current !== convertResult) {
|
|
149
|
+
appliedRef.current = convertResult;
|
|
150
|
+
convertResult.applyMapping();
|
|
151
|
+
}
|
|
152
|
+
if (convertResult == null) {
|
|
153
|
+
appliedRef.current = null;
|
|
154
|
+
}
|
|
155
|
+
}, [convertResult, mismatchCount, rootConfig.autoApplyMappingWhenMismatchesAtMost]);
|
|
156
|
+
return useMemo2(
|
|
157
|
+
() => ({
|
|
158
|
+
view,
|
|
159
|
+
status,
|
|
160
|
+
progressEventTarget,
|
|
161
|
+
convertResult,
|
|
162
|
+
mappingErrorDetail
|
|
163
|
+
}),
|
|
164
|
+
[view, status, progressEventTarget, convertResult, mappingErrorDetail]
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// src/hooks/useRawFilePicker/useRawFilePicker.ts
|
|
169
|
+
import { useCallback, useRef as useRef2, useState } from "react";
|
|
170
|
+
import { useImporter } from "@cristianmpx/react-import-sheet-headless";
|
|
171
|
+
function useRawFilePicker(options = {}) {
|
|
172
|
+
const { accept } = options;
|
|
173
|
+
const { processFile } = useImporter();
|
|
174
|
+
const [isDragging, setIsDragging] = useState(false);
|
|
175
|
+
const rootRef = useRef2(null);
|
|
176
|
+
const inputRef = useRef2(null);
|
|
177
|
+
const setRootRef = useCallback((el) => {
|
|
178
|
+
rootRef.current = el;
|
|
179
|
+
}, []);
|
|
180
|
+
const setInputRef = useCallback((el) => {
|
|
181
|
+
inputRef.current = el;
|
|
182
|
+
}, []);
|
|
183
|
+
const handleDrop = useCallback(
|
|
184
|
+
(e) => {
|
|
185
|
+
e.preventDefault();
|
|
186
|
+
e.stopPropagation();
|
|
187
|
+
setIsDragging(false);
|
|
188
|
+
const file = e.dataTransfer?.files?.[0];
|
|
189
|
+
if (file) processFile(file);
|
|
190
|
+
},
|
|
191
|
+
[processFile]
|
|
192
|
+
);
|
|
193
|
+
const handleDragOver = useCallback((e) => {
|
|
194
|
+
e.preventDefault();
|
|
195
|
+
e.stopPropagation();
|
|
196
|
+
e.dataTransfer.dropEffect = "copy";
|
|
197
|
+
setIsDragging(true);
|
|
198
|
+
}, []);
|
|
199
|
+
const handleDragLeave = useCallback((e) => {
|
|
200
|
+
e.preventDefault();
|
|
201
|
+
e.stopPropagation();
|
|
202
|
+
if (!rootRef.current?.contains(e.relatedTarget)) {
|
|
203
|
+
setIsDragging(false);
|
|
204
|
+
}
|
|
205
|
+
}, []);
|
|
206
|
+
const handleChange = useCallback(
|
|
207
|
+
(e) => {
|
|
208
|
+
const file = e.target.files?.[0];
|
|
209
|
+
if (file) processFile(file);
|
|
210
|
+
e.target.value = "";
|
|
211
|
+
},
|
|
212
|
+
[processFile]
|
|
213
|
+
);
|
|
214
|
+
const handleRootClick = useCallback((e) => {
|
|
215
|
+
if (e.target !== inputRef.current) {
|
|
216
|
+
inputRef.current?.click();
|
|
217
|
+
}
|
|
218
|
+
}, []);
|
|
219
|
+
const getRootProps = useCallback(
|
|
220
|
+
(opts) => ({
|
|
221
|
+
ref: setRootRef,
|
|
222
|
+
onClick: handleRootClick,
|
|
223
|
+
onDragOver: handleDragOver,
|
|
224
|
+
onDragLeave: handleDragLeave,
|
|
225
|
+
onDrop: handleDrop,
|
|
226
|
+
role: "button",
|
|
227
|
+
"aria-label": "Drop zone for file import",
|
|
228
|
+
"data-dropzone": "true",
|
|
229
|
+
className: opts?.className,
|
|
230
|
+
style: opts?.style
|
|
231
|
+
}),
|
|
232
|
+
[handleRootClick, handleDragOver, handleDragLeave, handleDrop, setRootRef]
|
|
233
|
+
);
|
|
234
|
+
const getInputProps = useCallback(
|
|
235
|
+
() => ({
|
|
236
|
+
ref: setInputRef,
|
|
237
|
+
type: "file",
|
|
238
|
+
onChange: handleChange,
|
|
239
|
+
accept: accept ?? ".xlsx,.xls,.csv",
|
|
240
|
+
tabIndex: -1,
|
|
241
|
+
"aria-label": "Select file to import"
|
|
242
|
+
}),
|
|
243
|
+
[handleChange, setInputRef, accept]
|
|
244
|
+
);
|
|
245
|
+
return {
|
|
246
|
+
isDragging,
|
|
247
|
+
getRootProps,
|
|
248
|
+
getInputProps
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// src/hooks/useRawMappingTable/useRawMappingTable.ts
|
|
253
|
+
import { useMemo as useMemo3 } from "react";
|
|
254
|
+
import { useConvert as useConvert2 } from "@cristianmpx/react-import-sheet-headless";
|
|
255
|
+
function useRawMappingTable() {
|
|
256
|
+
const { convertResult } = useConvert2();
|
|
257
|
+
const rows = useMemo3(() => {
|
|
258
|
+
if (!convertResult?.headersFound?.length) return [];
|
|
259
|
+
return convertResult.headersFound.map((headerOriginal, columnIndex) => ({
|
|
260
|
+
headerOriginal,
|
|
261
|
+
columnIndex
|
|
262
|
+
}));
|
|
263
|
+
}, [convertResult]);
|
|
264
|
+
const hasMappingData = convertResult != null && rows.length > 0;
|
|
265
|
+
return useMemo3(
|
|
266
|
+
() => ({
|
|
267
|
+
rows,
|
|
268
|
+
hasMappingData
|
|
269
|
+
}),
|
|
270
|
+
[rows, hasMappingData]
|
|
271
|
+
);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// src/hooks/useRawMappingRow/useRawMappingRow.ts
|
|
275
|
+
import { useContext as useContext2, useCallback as useCallback2, useMemo as useMemo4 } from "react";
|
|
276
|
+
import { useConvert as useConvert3 } from "@cristianmpx/react-import-sheet-headless";
|
|
277
|
+
|
|
278
|
+
// src/shared/types/input-phase.ts
|
|
279
|
+
function getLayoutFieldOptions(layout) {
|
|
280
|
+
if (!layout?.fields) return [];
|
|
281
|
+
return Object.entries(layout.fields).map(([id, field]) => ({
|
|
282
|
+
id,
|
|
283
|
+
label: field.name ?? id
|
|
284
|
+
}));
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// src/hooks/useRawMappingRow/useRawMappingRow.ts
|
|
288
|
+
function useRawMappingRow(options) {
|
|
289
|
+
const { rowContext } = options;
|
|
290
|
+
const { headerOriginal, columnIndex } = rowContext;
|
|
291
|
+
const layout = useContext2(LayoutContext);
|
|
292
|
+
const { convertResult } = useConvert3();
|
|
293
|
+
const optionsList = useMemo4(() => getLayoutFieldOptions(layout), [layout]);
|
|
294
|
+
const usedByOtherColumns = useMemo4(() => {
|
|
295
|
+
if (!convertResult?.headerToFieldMap) return /* @__PURE__ */ new Set();
|
|
296
|
+
return new Set(
|
|
297
|
+
Object.entries(convertResult.headerToFieldMap).filter(([header]) => header !== headerOriginal).map(([, fieldId]) => fieldId).filter(Boolean)
|
|
298
|
+
);
|
|
299
|
+
}, [convertResult?.headerToFieldMap, headerOriginal]);
|
|
300
|
+
const mappingOptions = useMemo4(
|
|
301
|
+
() => optionsList.map((opt) => ({
|
|
302
|
+
...opt,
|
|
303
|
+
disabled: usedByOtherColumns.has(opt.id)
|
|
304
|
+
})),
|
|
305
|
+
[optionsList, usedByOtherColumns]
|
|
306
|
+
);
|
|
307
|
+
const value = useMemo4(() => {
|
|
308
|
+
if (!convertResult?.headerToFieldMap) return null;
|
|
309
|
+
return convertResult.headerToFieldMap[headerOriginal] ?? null;
|
|
310
|
+
}, [convertResult, headerOriginal]);
|
|
311
|
+
const onChange = useCallback2(
|
|
312
|
+
(fieldId) => {
|
|
313
|
+
convertResult?.renameColumn(headerOriginal, fieldId);
|
|
314
|
+
},
|
|
315
|
+
[convertResult, headerOriginal]
|
|
316
|
+
);
|
|
317
|
+
const mappingStatus = useMemo4(() => {
|
|
318
|
+
if (value == null || value === "") return "unmapped";
|
|
319
|
+
const mismatches = convertResult?.mismatches ?? [];
|
|
320
|
+
const stillMismatch = mismatches.some((m) => m.expected === value);
|
|
321
|
+
return stillMismatch ? "invalid" : "valid";
|
|
322
|
+
}, [value, convertResult?.mismatches]);
|
|
323
|
+
return useMemo4(
|
|
324
|
+
() => ({
|
|
325
|
+
headerOriginal,
|
|
326
|
+
columnIndex,
|
|
327
|
+
options: mappingOptions,
|
|
328
|
+
value,
|
|
329
|
+
onChange,
|
|
330
|
+
mappingStatus
|
|
331
|
+
}),
|
|
332
|
+
[headerOriginal, columnIndex, mappingOptions, value, onChange, mappingStatus]
|
|
333
|
+
);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
// src/hooks/useRawMappingSuggest/useRawMappingSuggest.ts
|
|
337
|
+
import { useContext as useContext3, useMemo as useMemo5 } from "react";
|
|
338
|
+
|
|
339
|
+
// src/shared/utils/fuzzy-similarity.ts
|
|
340
|
+
function normalize(s) {
|
|
341
|
+
return s.trim().toLowerCase().normalize("NFD").replace(/\p{Diacritic}/gu, "");
|
|
342
|
+
}
|
|
343
|
+
function levenshtein(a, b) {
|
|
344
|
+
if (a.length === 0) return b.length;
|
|
345
|
+
if (b.length === 0) return a.length;
|
|
346
|
+
let prev = Array.from({ length: b.length + 1 }, (_, i) => i);
|
|
347
|
+
for (let i = 1; i <= a.length; i++) {
|
|
348
|
+
const curr = [i];
|
|
349
|
+
for (let j = 1; j <= b.length; j++) {
|
|
350
|
+
const cost = a[i - 1] === b[j - 1] ? 0 : 1;
|
|
351
|
+
curr[j] = Math.min(curr[j - 1] + 1, prev[j] + 1, prev[j - 1] + cost);
|
|
352
|
+
}
|
|
353
|
+
prev = curr;
|
|
354
|
+
}
|
|
355
|
+
return prev[b.length];
|
|
356
|
+
}
|
|
357
|
+
function getSimilarity(s1, s2) {
|
|
358
|
+
const a = normalize(s1);
|
|
359
|
+
const b = normalize(s2);
|
|
360
|
+
if (a.length === 0 && b.length === 0) return 1;
|
|
361
|
+
const longer = a.length >= b.length ? a : b;
|
|
362
|
+
const shorter = a.length < b.length ? a : b;
|
|
363
|
+
if (longer.length === 0) return 1;
|
|
364
|
+
const distance = levenshtein(longer, shorter);
|
|
365
|
+
return (longer.length - distance) / longer.length;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
// src/hooks/useRawMappingSuggest/useRawMappingSuggest.ts
|
|
369
|
+
var DEFAULT_FUZZY_THRESHOLD = 0.8;
|
|
370
|
+
function useRawMappingSuggest(options) {
|
|
371
|
+
const { columnContext } = options;
|
|
372
|
+
const { fileHeader } = columnContext;
|
|
373
|
+
const rootConfig = useContext3(RootConfigContext);
|
|
374
|
+
const layout = useContext3(LayoutContext);
|
|
375
|
+
return useMemo5(() => {
|
|
376
|
+
if (rootConfig.fuzzyMatch === false) {
|
|
377
|
+
return { matchScore: 0, suggestedFieldId: null, suggestedFieldLabel: null };
|
|
378
|
+
}
|
|
379
|
+
const optionsList = getLayoutFieldOptions(layout);
|
|
380
|
+
let bestScore = 0;
|
|
381
|
+
let bestId = null;
|
|
382
|
+
let bestLabel = null;
|
|
383
|
+
for (const opt of optionsList) {
|
|
384
|
+
const score = getSimilarity(fileHeader, opt.label);
|
|
385
|
+
if (score >= DEFAULT_FUZZY_THRESHOLD && score > bestScore) {
|
|
386
|
+
bestScore = score;
|
|
387
|
+
bestId = opt.id;
|
|
388
|
+
bestLabel = opt.label;
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
const matchScore = Math.round(bestScore * 100);
|
|
392
|
+
return {
|
|
393
|
+
matchScore: bestId != null ? matchScore : 0,
|
|
394
|
+
suggestedFieldId: bestId,
|
|
395
|
+
suggestedFieldLabel: bestLabel
|
|
396
|
+
};
|
|
397
|
+
}, [rootConfig.fuzzyMatch, layout, fileHeader]);
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
// src/hooks/useRawImportAction/useRawImportAction.ts
|
|
401
|
+
import { useCallback as useCallback3, useMemo as useMemo6 } from "react";
|
|
402
|
+
import { useConvert as useConvert4, useImporterStatus as useImporterStatus2 } from "@cristianmpx/react-import-sheet-headless";
|
|
403
|
+
function useRawImportAction() {
|
|
404
|
+
const { convertResult } = useConvert4();
|
|
405
|
+
const { status } = useImporterStatus2();
|
|
406
|
+
const isProcessing = status === "loading" || status === "parsing" || status === "validating" || status === "transforming";
|
|
407
|
+
const disabled = useMemo6(() => {
|
|
408
|
+
if (isProcessing) return true;
|
|
409
|
+
if (!convertResult) return true;
|
|
410
|
+
if (typeof convertResult.layoutError === "boolean") {
|
|
411
|
+
return convertResult.layoutError === true;
|
|
412
|
+
}
|
|
413
|
+
return convertResult.mismatches.length > 0;
|
|
414
|
+
}, [isProcessing, convertResult]);
|
|
415
|
+
const runImport = useCallback3(() => {
|
|
416
|
+
if (convertResult && !disabled) {
|
|
417
|
+
convertResult.applyMapping();
|
|
418
|
+
}
|
|
419
|
+
}, [convertResult, disabled]);
|
|
420
|
+
return useMemo6(
|
|
421
|
+
() => ({
|
|
422
|
+
disabled,
|
|
423
|
+
runImport
|
|
424
|
+
}),
|
|
425
|
+
[disabled, runImport]
|
|
426
|
+
);
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
// src/hooks/useRawProgress/useRawProgress.ts
|
|
430
|
+
import { useEffect as useEffect2, useRef as useRef3 } from "react";
|
|
431
|
+
import {
|
|
432
|
+
useImporterStatus as useImporterStatus3,
|
|
433
|
+
IMPORTER_PROGRESS_EVENT,
|
|
434
|
+
IMPORTER_ABORTED_EVENT
|
|
435
|
+
} from "@cristianmpx/react-import-sheet-headless";
|
|
436
|
+
function useRawProgress(options = {}) {
|
|
437
|
+
const { onProgress } = options;
|
|
438
|
+
const { progressEventTarget } = useImporterStatus3();
|
|
439
|
+
const progressRef = useRef3(null);
|
|
440
|
+
useEffect2(() => {
|
|
441
|
+
const target = progressEventTarget;
|
|
442
|
+
const handleProgress = (e) => {
|
|
443
|
+
const detail = e.detail;
|
|
444
|
+
progressRef.current = detail ?? null;
|
|
445
|
+
onProgress?.(detail);
|
|
446
|
+
};
|
|
447
|
+
const handleAborted = () => {
|
|
448
|
+
progressRef.current = null;
|
|
449
|
+
};
|
|
450
|
+
target.addEventListener(IMPORTER_PROGRESS_EVENT, handleProgress);
|
|
451
|
+
target.addEventListener(IMPORTER_ABORTED_EVENT, handleAborted);
|
|
452
|
+
return () => {
|
|
453
|
+
target.removeEventListener(IMPORTER_PROGRESS_EVENT, handleProgress);
|
|
454
|
+
target.removeEventListener(IMPORTER_ABORTED_EVENT, handleAborted);
|
|
455
|
+
};
|
|
456
|
+
}, [progressEventTarget, onProgress]);
|
|
457
|
+
return {
|
|
458
|
+
progressRef,
|
|
459
|
+
...onProgress ? { onProgress } : {}
|
|
460
|
+
};
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
// src/hooks/useRawStatus/useRawStatus.ts
|
|
464
|
+
import { useMemo as useMemo7 } from "react";
|
|
465
|
+
import { useImporterStatus as useImporterStatus4 } from "@cristianmpx/react-import-sheet-headless";
|
|
466
|
+
function useRawStatus() {
|
|
467
|
+
const { status } = useImporterStatus4();
|
|
468
|
+
return useMemo7(
|
|
469
|
+
() => ({
|
|
470
|
+
status,
|
|
471
|
+
// When headless exposes lastError / errorDetail, wire it here for status === 'error'
|
|
472
|
+
errorDetail: void 0
|
|
473
|
+
}),
|
|
474
|
+
[status]
|
|
475
|
+
);
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
// src/hooks/useRawAbort/useRawAbort.ts
|
|
479
|
+
import { useImporter as useImporter2 } from "@cristianmpx/react-import-sheet-headless";
|
|
480
|
+
function useRawAbort() {
|
|
481
|
+
const { abort } = useImporter2();
|
|
482
|
+
return { abort };
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
// src/hooks/useRawDataTable/useRawDataTable.ts
|
|
486
|
+
import { useContext as useContext4, useCallback as useCallback4, useMemo as useMemo8, useState as useState2 } from "react";
|
|
487
|
+
import { useSheetData } from "@cristianmpx/react-import-sheet-headless";
|
|
488
|
+
function useRawDataTable(options = {}) {
|
|
489
|
+
const { onNavigateToIndex } = options;
|
|
490
|
+
const layout = useContext4(LayoutContext);
|
|
491
|
+
const rootConfig = useContext4(RootConfigContext);
|
|
492
|
+
const { sheet } = useSheetData();
|
|
493
|
+
const [focusedRowIndex, setFocusedRowIndex] = useState2(null);
|
|
494
|
+
const [focusedCellKey, setFocusedCellKey] = useState2(null);
|
|
495
|
+
const [pendingCell, setPendingCell] = useState2(
|
|
496
|
+
null
|
|
497
|
+
);
|
|
498
|
+
const headerIds = useMemo8(() => {
|
|
499
|
+
if (!layout?.fields) return [];
|
|
500
|
+
return Object.keys(layout.fields);
|
|
501
|
+
}, [layout?.fields]);
|
|
502
|
+
const totalRowCount = sheet?.rows?.length ?? 0;
|
|
503
|
+
const editingEnabled = rootConfig.editingEnabled ?? true;
|
|
504
|
+
const headers = useMemo8(
|
|
505
|
+
() => getLayoutFieldOptions(layout).map((o) => ({ id: o.id, label: o.label })),
|
|
506
|
+
[layout]
|
|
507
|
+
);
|
|
508
|
+
const setFocused = useCallback4((rowIndex, cellKey) => {
|
|
509
|
+
setFocusedRowIndex(rowIndex);
|
|
510
|
+
setFocusedCellKey(cellKey);
|
|
511
|
+
}, []);
|
|
512
|
+
const getKeyDownHandler = useCallback4(
|
|
513
|
+
(rowIndex, cellKey) => {
|
|
514
|
+
return (e) => {
|
|
515
|
+
const key = e.key;
|
|
516
|
+
if (key !== "ArrowLeft" && key !== "ArrowRight" && key !== "ArrowUp" && key !== "ArrowDown") {
|
|
517
|
+
return;
|
|
518
|
+
}
|
|
519
|
+
e.preventDefault();
|
|
520
|
+
const colIdx = headerIds.indexOf(cellKey);
|
|
521
|
+
if (colIdx === -1) return;
|
|
522
|
+
if (key === "ArrowLeft" && colIdx > 0) {
|
|
523
|
+
setFocused(rowIndex, headerIds[colIdx - 1] ?? null);
|
|
524
|
+
return;
|
|
525
|
+
}
|
|
526
|
+
if (key === "ArrowRight" && colIdx < headerIds.length - 1) {
|
|
527
|
+
setFocused(rowIndex, headerIds[colIdx + 1] ?? null);
|
|
528
|
+
return;
|
|
529
|
+
}
|
|
530
|
+
if (key === "ArrowUp" && rowIndex > 0) {
|
|
531
|
+
const nextIndex = rowIndex - 1;
|
|
532
|
+
setFocused(nextIndex, cellKey);
|
|
533
|
+
onNavigateToIndex?.(nextIndex);
|
|
534
|
+
return;
|
|
535
|
+
}
|
|
536
|
+
if (key === "ArrowDown" && rowIndex < totalRowCount - 1) {
|
|
537
|
+
const nextIndex = rowIndex + 1;
|
|
538
|
+
setFocused(nextIndex, cellKey);
|
|
539
|
+
onNavigateToIndex?.(nextIndex);
|
|
540
|
+
return;
|
|
541
|
+
}
|
|
542
|
+
};
|
|
543
|
+
},
|
|
544
|
+
[headerIds, totalRowCount, setFocused, onNavigateToIndex]
|
|
545
|
+
);
|
|
546
|
+
const value = useMemo8(
|
|
547
|
+
() => ({
|
|
548
|
+
editingEnabled,
|
|
549
|
+
headerIds,
|
|
550
|
+
totalRowCount,
|
|
551
|
+
focusedRowIndex,
|
|
552
|
+
focusedCellKey,
|
|
553
|
+
setFocused,
|
|
554
|
+
pendingCell,
|
|
555
|
+
setPendingCell,
|
|
556
|
+
getKeyDownHandler,
|
|
557
|
+
onNavigateToIndex
|
|
558
|
+
}),
|
|
559
|
+
[
|
|
560
|
+
editingEnabled,
|
|
561
|
+
headerIds,
|
|
562
|
+
totalRowCount,
|
|
563
|
+
focusedRowIndex,
|
|
564
|
+
focusedCellKey,
|
|
565
|
+
setFocused,
|
|
566
|
+
pendingCell,
|
|
567
|
+
getKeyDownHandler,
|
|
568
|
+
onNavigateToIndex
|
|
569
|
+
]
|
|
570
|
+
);
|
|
571
|
+
return useMemo8(
|
|
572
|
+
() => ({
|
|
573
|
+
...value,
|
|
574
|
+
headers
|
|
575
|
+
}),
|
|
576
|
+
[value, headers]
|
|
577
|
+
);
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
// src/hooks/useRawDataTable/DataTableContext.tsx
|
|
581
|
+
import { createContext as createContext2 } from "react";
|
|
582
|
+
var defaultContext = {
|
|
583
|
+
editingEnabled: true,
|
|
584
|
+
headerIds: [],
|
|
585
|
+
totalRowCount: 0,
|
|
586
|
+
focusedRowIndex: null,
|
|
587
|
+
focusedCellKey: null,
|
|
588
|
+
setFocused: () => {
|
|
589
|
+
},
|
|
590
|
+
pendingCell: null,
|
|
591
|
+
setPendingCell: () => {
|
|
592
|
+
},
|
|
593
|
+
getKeyDownHandler: () => () => {
|
|
594
|
+
}
|
|
595
|
+
};
|
|
596
|
+
var DataTableContext = createContext2(defaultContext);
|
|
597
|
+
|
|
598
|
+
// src/hooks/useRawDataTable/RawDataTableProvider.tsx
|
|
599
|
+
import { useMemo as useMemo9 } from "react";
|
|
600
|
+
import { useSheetEditor } from "@cristianmpx/react-import-sheet-headless";
|
|
601
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
602
|
+
function RawDataTableProvider({ children, onNavigateToIndex }) {
|
|
603
|
+
const editor = useSheetEditor();
|
|
604
|
+
const tableValue = useRawDataTable({ onNavigateToIndex });
|
|
605
|
+
const canEdit = editor.canEdit !== false;
|
|
606
|
+
const effectiveEditing = tableValue.editingEnabled && canEdit;
|
|
607
|
+
const value = useMemo9(
|
|
608
|
+
() => ({ ...tableValue, editingEnabled: effectiveEditing }),
|
|
609
|
+
[tableValue, effectiveEditing]
|
|
610
|
+
);
|
|
611
|
+
return /* @__PURE__ */ jsx2(DataTableContext.Provider, { value, children });
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
// src/hooks/useRawTableHead/useRawTableHead.ts
|
|
615
|
+
import { useContext as useContext5, useMemo as useMemo10 } from "react";
|
|
616
|
+
function useRawTableHead() {
|
|
617
|
+
const layout = useContext5(LayoutContext);
|
|
618
|
+
const headers = useMemo10(
|
|
619
|
+
() => getLayoutFieldOptions(layout).map((o) => ({ id: o.id, label: o.label })),
|
|
620
|
+
[layout]
|
|
621
|
+
);
|
|
622
|
+
return useMemo10(() => ({ headers }), [headers]);
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
// src/hooks/useRawTableBody/useRawTableBody.ts
|
|
626
|
+
import { useCallback as useCallback5, useMemo as useMemo11 } from "react";
|
|
627
|
+
import { useSheetData as useSheetData2 } from "@cristianmpx/react-import-sheet-headless";
|
|
628
|
+
function useRawTableBody() {
|
|
629
|
+
const { sheet } = useSheetData2();
|
|
630
|
+
const totalRowCount = sheet?.rows?.length ?? 0;
|
|
631
|
+
const isPlaceholder = useCallback5(
|
|
632
|
+
(index) => index < 0 || index >= totalRowCount,
|
|
633
|
+
[totalRowCount]
|
|
634
|
+
);
|
|
635
|
+
const getRowProps = useCallback5(
|
|
636
|
+
(options) => {
|
|
637
|
+
const { index, style } = options;
|
|
638
|
+
const row = sheet?.rows?.[index];
|
|
639
|
+
const hasErrors = (row?.errors?.length ?? 0) > 0;
|
|
640
|
+
const placeholder = isPlaceholder(index);
|
|
641
|
+
return {
|
|
642
|
+
"data-row-index": index,
|
|
643
|
+
"data-has-errors": hasErrors || void 0,
|
|
644
|
+
"data-placeholder": placeholder || void 0,
|
|
645
|
+
style,
|
|
646
|
+
role: "row",
|
|
647
|
+
"aria-rowindex": index + 1
|
|
648
|
+
};
|
|
649
|
+
},
|
|
650
|
+
[sheet?.rows, isPlaceholder]
|
|
651
|
+
);
|
|
652
|
+
return useMemo11(
|
|
653
|
+
() => ({
|
|
654
|
+
totalRowCount,
|
|
655
|
+
getRowProps,
|
|
656
|
+
isPlaceholder
|
|
657
|
+
}),
|
|
658
|
+
[totalRowCount, getRowProps, isPlaceholder]
|
|
659
|
+
);
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
// src/hooks/useRawTableRow/useRawTableRow.ts
|
|
663
|
+
import { useCallback as useCallback6, useMemo as useMemo12 } from "react";
|
|
664
|
+
import { useSheetData as useSheetData3 } from "@cristianmpx/react-import-sheet-headless";
|
|
665
|
+
function useRawTableRow(options) {
|
|
666
|
+
const { index, style } = options;
|
|
667
|
+
const { sheet } = useSheetData3();
|
|
668
|
+
const { getRowProps: bodyGetRowProps, isPlaceholder } = useRawTableBody();
|
|
669
|
+
const row = useMemo12(() => {
|
|
670
|
+
if (options.row !== void 0) return options.row;
|
|
671
|
+
if (!sheet?.rows) return null;
|
|
672
|
+
if (isPlaceholder(index)) return null;
|
|
673
|
+
return sheet.rows[index] ?? null;
|
|
674
|
+
}, [options.row, sheet?.rows, index, isPlaceholder]);
|
|
675
|
+
const getRowProps = useCallback6(
|
|
676
|
+
(merge) => {
|
|
677
|
+
const base = bodyGetRowProps({ index, style });
|
|
678
|
+
return {
|
|
679
|
+
...base,
|
|
680
|
+
...merge?.className != null && { className: merge.className },
|
|
681
|
+
...merge?.style != null && { style: { ...base.style, ...merge.style } }
|
|
682
|
+
};
|
|
683
|
+
},
|
|
684
|
+
[bodyGetRowProps, index, style]
|
|
685
|
+
);
|
|
686
|
+
const rowErrors = row?.errors ?? [];
|
|
687
|
+
return useMemo12(
|
|
688
|
+
() => ({
|
|
689
|
+
getRowProps,
|
|
690
|
+
row: row ?? void 0,
|
|
691
|
+
rowErrors
|
|
692
|
+
}),
|
|
693
|
+
[getRowProps, row, rowErrors]
|
|
694
|
+
);
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
// src/hooks/useRawCell/useRawCell.ts
|
|
698
|
+
import { useContext as useContext6, useCallback as useCallback7, useMemo as useMemo13, useRef as useRef4 } from "react";
|
|
699
|
+
import { useSheetData as useSheetData4, useSheetEditor as useSheetEditor2 } from "@cristianmpx/react-import-sheet-headless";
|
|
700
|
+
function useRawCell(options) {
|
|
701
|
+
const { rowIndex, fieldId } = options;
|
|
702
|
+
const { sheet } = useSheetData4();
|
|
703
|
+
const { editCell: editorEditCell } = useSheetEditor2();
|
|
704
|
+
const ctx = useContext6(DataTableContext);
|
|
705
|
+
const row = sheet?.rows?.[rowIndex];
|
|
706
|
+
const cell = useMemo13(() => row?.cells?.find((c) => c.key === fieldId), [row?.cells, fieldId]);
|
|
707
|
+
const value = cell?.value;
|
|
708
|
+
const errors = cell?.errors ?? [];
|
|
709
|
+
const isPending = ctx.pendingCell?.rowIndex === rowIndex && ctx.pendingCell?.fieldId === fieldId;
|
|
710
|
+
const isFocused = ctx.focusedRowIndex === rowIndex && ctx.focusedCellKey === fieldId;
|
|
711
|
+
const isEditing = (ctx.editingEnabled ?? true) && isFocused;
|
|
712
|
+
const editCell = useCallback7(
|
|
713
|
+
(newValue) => {
|
|
714
|
+
if (!(ctx.editingEnabled ?? true)) return;
|
|
715
|
+
ctx.setPendingCell({ rowIndex, fieldId });
|
|
716
|
+
const p = editorEditCell({
|
|
717
|
+
rowIndex,
|
|
718
|
+
cellKey: fieldId,
|
|
719
|
+
value: newValue
|
|
720
|
+
});
|
|
721
|
+
if (p && typeof p.then === "function") {
|
|
722
|
+
p.then(
|
|
723
|
+
() => ctx.setPendingCell(null),
|
|
724
|
+
() => ctx.setPendingCell(null)
|
|
725
|
+
);
|
|
726
|
+
} else {
|
|
727
|
+
ctx.setPendingCell(null);
|
|
728
|
+
}
|
|
729
|
+
},
|
|
730
|
+
[ctx.editingEnabled, ctx.setPendingCell, editorEditCell, rowIndex, fieldId]
|
|
731
|
+
);
|
|
732
|
+
const localValueRef = useRef4(value);
|
|
733
|
+
const displayValue = isPending ? localValueRef.current : value;
|
|
734
|
+
if (!isPending) localValueRef.current = value;
|
|
735
|
+
const getCellProps = useCallback7(
|
|
736
|
+
(opts) => {
|
|
737
|
+
const base = {
|
|
738
|
+
role: "gridcell",
|
|
739
|
+
tabIndex: isFocused ? 0 : -1,
|
|
740
|
+
"data-pending": isPending ? "true" : "false",
|
|
741
|
+
"data-has-error": errors.length > 0 ? "true" : void 0,
|
|
742
|
+
"aria-invalid": errors.length > 0 ? "true" : void 0,
|
|
743
|
+
"data-cell-key": fieldId,
|
|
744
|
+
"data-row-index": rowIndex,
|
|
745
|
+
onKeyDown: ctx.getKeyDownHandler(rowIndex, fieldId),
|
|
746
|
+
onFocus: () => ctx.setFocused(rowIndex, fieldId),
|
|
747
|
+
...opts?.className != null && { className: opts.className },
|
|
748
|
+
...opts?.style != null && { style: opts.style }
|
|
749
|
+
};
|
|
750
|
+
return base;
|
|
751
|
+
},
|
|
752
|
+
[isFocused, isPending, errors.length, fieldId, rowIndex, ctx.getKeyDownHandler, ctx.setFocused]
|
|
753
|
+
);
|
|
754
|
+
const getEditInputProps = useCallback7(() => {
|
|
755
|
+
return {
|
|
756
|
+
value: displayValue ?? "",
|
|
757
|
+
onChange: (e) => {
|
|
758
|
+
const v = e.target.value;
|
|
759
|
+
localValueRef.current = v;
|
|
760
|
+
editCell(v);
|
|
761
|
+
},
|
|
762
|
+
onBlur: () => {
|
|
763
|
+
},
|
|
764
|
+
"aria-label": fieldId
|
|
765
|
+
};
|
|
766
|
+
}, [displayValue, fieldId, editCell]);
|
|
767
|
+
const getErrorProps = useCallback7(
|
|
768
|
+
() => ({
|
|
769
|
+
role: "alert",
|
|
770
|
+
"aria-live": "polite",
|
|
771
|
+
"aria-atomic": true,
|
|
772
|
+
"data-ris-ui": "raw-cell-error-message"
|
|
773
|
+
}),
|
|
774
|
+
[]
|
|
775
|
+
);
|
|
776
|
+
return useMemo13(
|
|
777
|
+
() => ({
|
|
778
|
+
value: displayValue,
|
|
779
|
+
errors,
|
|
780
|
+
isPending,
|
|
781
|
+
isEditing,
|
|
782
|
+
getCellProps,
|
|
783
|
+
getEditInputProps,
|
|
784
|
+
getErrorProps,
|
|
785
|
+
editCell
|
|
786
|
+
}),
|
|
787
|
+
[
|
|
788
|
+
displayValue,
|
|
789
|
+
errors,
|
|
790
|
+
isPending,
|
|
791
|
+
isEditing,
|
|
792
|
+
getCellProps,
|
|
793
|
+
getEditInputProps,
|
|
794
|
+
getErrorProps,
|
|
795
|
+
editCell
|
|
796
|
+
]
|
|
797
|
+
);
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
// src/hooks/useRawErrorBadge/useRawErrorBadge.ts
|
|
801
|
+
import { useMemo as useMemo14 } from "react";
|
|
802
|
+
function useRawErrorBadge(options) {
|
|
803
|
+
const { error, translateError } = options;
|
|
804
|
+
const message = useMemo14(() => {
|
|
805
|
+
if (!error) return "";
|
|
806
|
+
if (translateError) return translateError(error.code, error.params);
|
|
807
|
+
return error.message ?? error.code;
|
|
808
|
+
}, [error, translateError]);
|
|
809
|
+
return useMemo14(
|
|
810
|
+
() => ({
|
|
811
|
+
error,
|
|
812
|
+
message,
|
|
813
|
+
translateError
|
|
814
|
+
}),
|
|
815
|
+
[error, message, translateError]
|
|
816
|
+
);
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
// src/hooks/useRawPagination/useRawPagination.ts
|
|
820
|
+
import { useContext as useContext7 } from "react";
|
|
821
|
+
|
|
822
|
+
// src/hooks/useRawPagination/ViewPhaseContext.tsx
|
|
823
|
+
import { createContext as createContext3 } from "react";
|
|
824
|
+
var ViewPhaseContext = createContext3(null);
|
|
825
|
+
|
|
826
|
+
// src/hooks/useRawPagination/useRawPagination.ts
|
|
827
|
+
var VIEW_PHASE_ERROR = "useRawPagination must be used within RawViewPhaseProvider (e.g. in RESULT view).";
|
|
828
|
+
function useRawPagination() {
|
|
829
|
+
const ctx = useContext7(ViewPhaseContext);
|
|
830
|
+
if (!ctx) throw new Error(VIEW_PHASE_ERROR);
|
|
831
|
+
return {
|
|
832
|
+
page: ctx.page,
|
|
833
|
+
pageSize: ctx.pageSize,
|
|
834
|
+
totalRows: ctx.totalRows,
|
|
835
|
+
visibleSheetIndices: ctx.visibleSheetIndices,
|
|
836
|
+
setPage: ctx.setPage,
|
|
837
|
+
setPageSize: ctx.setPageSize
|
|
838
|
+
};
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
// src/hooks/useRawPagination/useRawSubmitStatus.ts
|
|
842
|
+
import { useContext as useContext8 } from "react";
|
|
843
|
+
var VIEW_PHASE_ERROR2 = "useRawSubmitStatus must be used within RawViewPhaseProvider (e.g. in RESULT view).";
|
|
844
|
+
function useRawSubmitStatus() {
|
|
845
|
+
const ctx = useContext8(ViewPhaseContext);
|
|
846
|
+
if (!ctx) throw new Error(VIEW_PHASE_ERROR2);
|
|
847
|
+
return {
|
|
848
|
+
isSubmitted: ctx.isSubmitted,
|
|
849
|
+
markSubmitted: ctx.markSubmitted,
|
|
850
|
+
canSubmit: ctx.canSubmit
|
|
851
|
+
};
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
// src/hooks/useRawPagination/RawViewPhaseProvider.tsx
|
|
855
|
+
import { useCallback as useCallback8, useContext as useContext9, useMemo as useMemo15, useState as useState3 } from "react";
|
|
856
|
+
import { useSheetView, useSheetData as useSheetData5, useImporter as useImporter3 } from "@cristianmpx/react-import-sheet-headless";
|
|
857
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
858
|
+
function hasRowErrors(row) {
|
|
859
|
+
if (!row) return false;
|
|
860
|
+
if ((row.errors?.length ?? 0) > 0) return true;
|
|
861
|
+
return row.cells?.some((c) => (c?.errors?.length ?? 0) > 0) ?? false;
|
|
862
|
+
}
|
|
863
|
+
function escapeCsvCell(value) {
|
|
864
|
+
const s = value == null ? "" : String(value);
|
|
865
|
+
if (/[",\r\n]/.test(s)) return `"${s.replace(/"/g, '""')}"`;
|
|
866
|
+
return s;
|
|
867
|
+
}
|
|
868
|
+
function buildErrorsOnlyCSV(options, rowsWithErrors) {
|
|
869
|
+
const headerLine = options.map((o) => o.label).map(escapeCsvCell).join(",");
|
|
870
|
+
const dataLines = rowsWithErrors.map(
|
|
871
|
+
(row) => options.map((o) => row.cells?.find((c) => c.key === o.id)).map((c) => escapeCsvCell(c?.value)).join(",")
|
|
872
|
+
);
|
|
873
|
+
return [headerLine, ...dataLines].join("\r\n");
|
|
874
|
+
}
|
|
875
|
+
function buildErrorsOnlyJSON(rowsWithErrors) {
|
|
876
|
+
const arr = rowsWithErrors.map((row) => {
|
|
877
|
+
const obj = {};
|
|
878
|
+
(row.cells ?? []).forEach((c) => {
|
|
879
|
+
obj[c.key] = c.value;
|
|
880
|
+
});
|
|
881
|
+
return obj;
|
|
882
|
+
});
|
|
883
|
+
return JSON.stringify(arr, null, 2);
|
|
884
|
+
}
|
|
885
|
+
function downloadBlob(blob, filename) {
|
|
886
|
+
const url = URL.createObjectURL(blob);
|
|
887
|
+
const a = document.createElement("a");
|
|
888
|
+
a.href = url;
|
|
889
|
+
a.download = filename;
|
|
890
|
+
a.click();
|
|
891
|
+
URL.revokeObjectURL(url);
|
|
892
|
+
}
|
|
893
|
+
function RawViewPhaseProvider({
|
|
894
|
+
children,
|
|
895
|
+
initialPage = 1,
|
|
896
|
+
defaultPageSize = 25,
|
|
897
|
+
defaultFilterMode = "all"
|
|
898
|
+
}) {
|
|
899
|
+
const [filterMode, setFilterMode] = useState3(defaultFilterMode);
|
|
900
|
+
const [pageSize, setPageSize] = useState3(defaultPageSize);
|
|
901
|
+
const layout = useContext9(LayoutContext);
|
|
902
|
+
const { sheet } = useSheetData5();
|
|
903
|
+
const { submitDone, submit, canSubmit } = useImporter3();
|
|
904
|
+
const view = useSheetView({
|
|
905
|
+
page: initialPage,
|
|
906
|
+
defaultPageSize: pageSize,
|
|
907
|
+
filterMode
|
|
908
|
+
});
|
|
909
|
+
const layoutOptions = useMemo15(() => getLayoutFieldOptions(layout), [layout]);
|
|
910
|
+
const rowsWithErrors = useMemo15(
|
|
911
|
+
() => (sheet?.rows ?? []).filter((row) => hasRowErrors(row)),
|
|
912
|
+
[sheet?.rows]
|
|
913
|
+
);
|
|
914
|
+
const downloadCSVErrorsOnly = useCallback8(
|
|
915
|
+
(opts) => {
|
|
916
|
+
if (rowsWithErrors.length === 0) return;
|
|
917
|
+
const csv = buildErrorsOnlyCSV(layoutOptions, rowsWithErrors);
|
|
918
|
+
const blob = new Blob([csv], { type: "text/csv;charset=utf-8" });
|
|
919
|
+
downloadBlob(blob, opts?.filename ?? "errors-only.csv");
|
|
920
|
+
},
|
|
921
|
+
[layoutOptions, rowsWithErrors]
|
|
922
|
+
);
|
|
923
|
+
const downloadJSONErrorsOnly = useCallback8(
|
|
924
|
+
(opts) => {
|
|
925
|
+
if (rowsWithErrors.length === 0) return;
|
|
926
|
+
const json = buildErrorsOnlyJSON(rowsWithErrors);
|
|
927
|
+
const blob = new Blob([json], { type: "application/json;charset=utf-8" });
|
|
928
|
+
downloadBlob(blob, opts?.filename ?? "errors-only.json");
|
|
929
|
+
},
|
|
930
|
+
[rowsWithErrors]
|
|
931
|
+
);
|
|
932
|
+
const visibleSheetIndices = useMemo15(() => {
|
|
933
|
+
const rows = sheet?.rows ?? [];
|
|
934
|
+
return view.paginatedRows.map((row) => rows.indexOf(row)).filter((i) => i >= 0);
|
|
935
|
+
}, [sheet?.rows, view.paginatedRows]);
|
|
936
|
+
const value = useMemo15(
|
|
937
|
+
() => ({
|
|
938
|
+
page: view.page,
|
|
939
|
+
setPage: view.setPage,
|
|
940
|
+
pageSize: view.pageSize,
|
|
941
|
+
setPageSize,
|
|
942
|
+
totalRows: view.totalRows,
|
|
943
|
+
visibleSheetIndices,
|
|
944
|
+
filterMode,
|
|
945
|
+
setFilterMode,
|
|
946
|
+
downloadCSV: view.downloadCSV,
|
|
947
|
+
downloadJSON: view.downloadJSON,
|
|
948
|
+
downloadCSVErrorsOnly,
|
|
949
|
+
downloadJSONErrorsOnly,
|
|
950
|
+
hasRowsWithErrors: rowsWithErrors.length > 0,
|
|
951
|
+
hasRecoverableSession: view.hasRecoverableSession,
|
|
952
|
+
recoverSession: view.recoverSession,
|
|
953
|
+
clearSession: view.clearPersistedState,
|
|
954
|
+
isSubmitted: submitDone ?? false,
|
|
955
|
+
markSubmitted: submit ?? (() => {
|
|
956
|
+
}),
|
|
957
|
+
canSubmit: canSubmit ?? false
|
|
958
|
+
}),
|
|
959
|
+
[
|
|
960
|
+
view.page,
|
|
961
|
+
view.setPage,
|
|
962
|
+
view.pageSize,
|
|
963
|
+
view.totalRows,
|
|
964
|
+
visibleSheetIndices,
|
|
965
|
+
view.downloadCSV,
|
|
966
|
+
view.downloadJSON,
|
|
967
|
+
view.hasRecoverableSession,
|
|
968
|
+
view.recoverSession,
|
|
969
|
+
view.clearPersistedState,
|
|
970
|
+
filterMode,
|
|
971
|
+
pageSize,
|
|
972
|
+
downloadCSVErrorsOnly,
|
|
973
|
+
downloadJSONErrorsOnly,
|
|
974
|
+
rowsWithErrors.length,
|
|
975
|
+
submitDone,
|
|
976
|
+
submit,
|
|
977
|
+
canSubmit
|
|
978
|
+
]
|
|
979
|
+
);
|
|
980
|
+
return /* @__PURE__ */ jsx3(ViewPhaseContext.Provider, { value, children });
|
|
981
|
+
}
|
|
982
|
+
|
|
983
|
+
// src/hooks/useRawRemoveRow/useRawRemoveRow.ts
|
|
984
|
+
import { useCallback as useCallback9 } from "react";
|
|
985
|
+
import { useSheetEditor as useSheetEditor3 } from "@cristianmpx/react-import-sheet-headless";
|
|
986
|
+
function useRawRemoveRow() {
|
|
987
|
+
const editor = useSheetEditor3();
|
|
988
|
+
const removeRowFn = editor.removeRow;
|
|
989
|
+
const canRemoveRow = typeof removeRowFn === "function";
|
|
990
|
+
const removeRow = useCallback9(
|
|
991
|
+
(rowIndex) => {
|
|
992
|
+
if (typeof removeRowFn === "function") {
|
|
993
|
+
removeRowFn(rowIndex);
|
|
994
|
+
}
|
|
995
|
+
},
|
|
996
|
+
[removeRowFn]
|
|
997
|
+
);
|
|
998
|
+
return { removeRow, canRemoveRow };
|
|
999
|
+
}
|
|
1000
|
+
|
|
1001
|
+
// src/hooks/useRawEditLog/useRawEditLog.ts
|
|
1002
|
+
import { useSheetEditor as useSheetEditor4 } from "@cristianmpx/react-import-sheet-headless";
|
|
1003
|
+
function useRawEditLog() {
|
|
1004
|
+
const editor = useSheetEditor4();
|
|
1005
|
+
const entries = editor.changeLog ?? [];
|
|
1006
|
+
const changeLogAsText = editor.changeLogAsText ?? "";
|
|
1007
|
+
return {
|
|
1008
|
+
entries,
|
|
1009
|
+
changeLogAsText,
|
|
1010
|
+
clearLog: () => {
|
|
1011
|
+
}
|
|
1012
|
+
};
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
// src/hooks/useRawEditLog/EditLogContext.tsx
|
|
1016
|
+
import { createContext as createContext4 } from "react";
|
|
1017
|
+
var EditLogContext = createContext4(null);
|
|
1018
|
+
|
|
1019
|
+
// src/hooks/useRawEditLog/RawEditLogProvider.tsx
|
|
1020
|
+
import { useCallback as useCallback10, useMemo as useMemo16, useState as useState4 } from "react";
|
|
1021
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
1022
|
+
function RawEditLogProvider({ children }) {
|
|
1023
|
+
const [entries, setEntries] = useState4([]);
|
|
1024
|
+
const appendCellUpdate = useCallback10(
|
|
1025
|
+
(params) => {
|
|
1026
|
+
setEntries((prev) => [
|
|
1027
|
+
...prev,
|
|
1028
|
+
{
|
|
1029
|
+
type: "cell_update",
|
|
1030
|
+
...params,
|
|
1031
|
+
timestamp: Date.now()
|
|
1032
|
+
}
|
|
1033
|
+
]);
|
|
1034
|
+
},
|
|
1035
|
+
[]
|
|
1036
|
+
);
|
|
1037
|
+
const appendRowRemoved = useCallback10((params) => {
|
|
1038
|
+
setEntries((prev) => [
|
|
1039
|
+
...prev,
|
|
1040
|
+
{
|
|
1041
|
+
type: "row_removed",
|
|
1042
|
+
...params,
|
|
1043
|
+
timestamp: Date.now()
|
|
1044
|
+
}
|
|
1045
|
+
]);
|
|
1046
|
+
}, []);
|
|
1047
|
+
const clearLog = useCallback10(() => setEntries([]), []);
|
|
1048
|
+
const value = useMemo16(
|
|
1049
|
+
() => ({ entries, appendCellUpdate, appendRowRemoved, clearLog }),
|
|
1050
|
+
[entries, appendCellUpdate, appendRowRemoved, clearLog]
|
|
1051
|
+
);
|
|
1052
|
+
return /* @__PURE__ */ jsx4(EditLogContext.Provider, { value, children });
|
|
1053
|
+
}
|
|
1054
|
+
|
|
1055
|
+
// src/hooks/useRawFilterToggle/useRawFilterToggle.ts
|
|
1056
|
+
import { useContext as useContext10 } from "react";
|
|
1057
|
+
var VIEW_PHASE_ERROR3 = "useRawFilterToggle must be used within RawViewPhaseProvider (e.g. in RESULT view).";
|
|
1058
|
+
function useRawFilterToggle() {
|
|
1059
|
+
const ctx = useContext10(ViewPhaseContext);
|
|
1060
|
+
if (!ctx) throw new Error(VIEW_PHASE_ERROR3);
|
|
1061
|
+
return {
|
|
1062
|
+
filterMode: ctx.filterMode,
|
|
1063
|
+
setFilterMode: ctx.setFilterMode
|
|
1064
|
+
};
|
|
1065
|
+
}
|
|
1066
|
+
|
|
1067
|
+
// src/hooks/useRawExport/useRawExport.ts
|
|
1068
|
+
import { useContext as useContext11 } from "react";
|
|
1069
|
+
var VIEW_PHASE_ERROR4 = "useRawExport must be used within RawViewPhaseProvider (e.g. in RESULT view).";
|
|
1070
|
+
function useRawExport() {
|
|
1071
|
+
const ctx = useContext11(ViewPhaseContext);
|
|
1072
|
+
if (!ctx) throw new Error(VIEW_PHASE_ERROR4);
|
|
1073
|
+
return {
|
|
1074
|
+
downloadCSV: ctx.downloadCSV,
|
|
1075
|
+
downloadJSON: ctx.downloadJSON,
|
|
1076
|
+
downloadCSVErrorsOnly: ctx.downloadCSVErrorsOnly,
|
|
1077
|
+
downloadJSONErrorsOnly: ctx.downloadJSONErrorsOnly,
|
|
1078
|
+
hasRowsWithErrors: ctx.hasRowsWithErrors
|
|
1079
|
+
};
|
|
1080
|
+
}
|
|
1081
|
+
|
|
1082
|
+
// src/hooks/useRawPersistence/useRawPersistence.ts
|
|
1083
|
+
import { useContext as useContext12 } from "react";
|
|
1084
|
+
var VIEW_PHASE_ERROR5 = "useRawPersistence must be used within RawViewPhaseProvider (e.g. in RESULT view).";
|
|
1085
|
+
function useRawPersistence() {
|
|
1086
|
+
const ctx = useContext12(ViewPhaseContext);
|
|
1087
|
+
if (!ctx) throw new Error(VIEW_PHASE_ERROR5);
|
|
1088
|
+
return {
|
|
1089
|
+
hasRecoverableSession: ctx.hasRecoverableSession,
|
|
1090
|
+
recoverSession: ctx.recoverSession,
|
|
1091
|
+
clearSession: ctx.clearSession
|
|
1092
|
+
};
|
|
1093
|
+
}
|
|
1094
|
+
|
|
1095
|
+
// src/hooks/useImporterMetrics/useImporterMetrics.ts
|
|
1096
|
+
import { useImporter as useImporter4 } from "@cristianmpx/react-import-sheet-headless";
|
|
1097
|
+
function useImporterMetrics() {
|
|
1098
|
+
const { metrics } = useImporter4();
|
|
1099
|
+
return metrics;
|
|
1100
|
+
}
|
|
1101
|
+
|
|
1102
|
+
// src/components/RawImporterRoot/RawImporterRoot.tsx
|
|
1103
|
+
import { forwardRef } from "react";
|
|
1104
|
+
import { ImporterProvider } from "@cristianmpx/react-import-sheet-headless";
|
|
1105
|
+
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
1106
|
+
var RawImporterRoot = forwardRef(
|
|
1107
|
+
function RawImporterRoot2({ children, className, style, ...options }, ref) {
|
|
1108
|
+
const { providerProps, rootConfig } = useRawImporterRoot(options);
|
|
1109
|
+
return /* @__PURE__ */ jsx5(ImporterProvider, { ...providerProps, children: /* @__PURE__ */ jsx5(LayoutProvider, { layout: providerProps.layout ?? null, children: /* @__PURE__ */ jsx5(RootConfigProvider, { rootConfig, children: /* @__PURE__ */ jsx5("div", { ref, className, style, "data-ris-ui": "raw-importer-root", children }) }) }) });
|
|
1110
|
+
}
|
|
1111
|
+
);
|
|
1112
|
+
|
|
1113
|
+
// src/components/RawStatusGuard/RawStatusGuard.tsx
|
|
1114
|
+
import { forwardRef as forwardRef2 } from "react";
|
|
1115
|
+
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
1116
|
+
var RawStatusGuard = forwardRef2(
|
|
1117
|
+
function RawStatusGuard2({ renderIdle, renderMapping, renderProcess, renderResult, renderError, className, style }, ref) {
|
|
1118
|
+
const data = useStatusView();
|
|
1119
|
+
const { view } = data;
|
|
1120
|
+
let content = null;
|
|
1121
|
+
if (view === "idle" && renderIdle) content = renderIdle(data);
|
|
1122
|
+
else if (view === "mapping" && renderMapping) content = renderMapping(data);
|
|
1123
|
+
else if (view === "process" && renderProcess) content = renderProcess(data);
|
|
1124
|
+
else if (view === "result" && renderResult) content = renderResult(data);
|
|
1125
|
+
else if (view === "error" && renderError) content = renderError(data);
|
|
1126
|
+
return /* @__PURE__ */ jsx6("div", { ref, className, style, "data-ris-ui": "raw-status-guard", children: content });
|
|
1127
|
+
}
|
|
1128
|
+
);
|
|
1129
|
+
|
|
1130
|
+
// src/components/RawFilePicker/RawFilePicker.tsx
|
|
1131
|
+
import { forwardRef as forwardRef3, useCallback as useCallback11 } from "react";
|
|
1132
|
+
import { jsx as jsx7, jsxs } from "react/jsx-runtime";
|
|
1133
|
+
var RawFilePicker = forwardRef3(function RawFilePicker2({ children, className, style }, ref) {
|
|
1134
|
+
const state = useRawFilePicker();
|
|
1135
|
+
const rootProps = state.getRootProps({ className, style });
|
|
1136
|
+
const { ref: rootRef, ...restRootProps } = rootProps;
|
|
1137
|
+
const setRef = useCallback11(
|
|
1138
|
+
(el) => {
|
|
1139
|
+
rootRef(el);
|
|
1140
|
+
if (typeof ref === "function") ref(el);
|
|
1141
|
+
else if (ref) ref.current = el;
|
|
1142
|
+
},
|
|
1143
|
+
[rootRef, ref]
|
|
1144
|
+
);
|
|
1145
|
+
return /* @__PURE__ */ jsxs("div", { ref: setRef, ...restRootProps, "data-ris-ui": "raw-file-picker", children: [
|
|
1146
|
+
/* @__PURE__ */ jsx7("input", { ...state.getInputProps() }),
|
|
1147
|
+
children(state)
|
|
1148
|
+
] });
|
|
1149
|
+
});
|
|
1150
|
+
|
|
1151
|
+
// src/components/RawMappingTable/RawMappingTable.tsx
|
|
1152
|
+
import { forwardRef as forwardRef4 } from "react";
|
|
1153
|
+
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
1154
|
+
var RawMappingTable = forwardRef4(
|
|
1155
|
+
function RawMappingTable2({ children, className, style }, ref) {
|
|
1156
|
+
const state = useRawMappingTable();
|
|
1157
|
+
return /* @__PURE__ */ jsx8("div", { ref, className, style, "data-ris-ui": "raw-mapping-table", children: children(state) });
|
|
1158
|
+
}
|
|
1159
|
+
);
|
|
1160
|
+
|
|
1161
|
+
// src/components/RawMappingRow/RawMappingRow.tsx
|
|
1162
|
+
import { forwardRef as forwardRef5 } from "react";
|
|
1163
|
+
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
1164
|
+
var RawMappingRow = forwardRef5(function RawMappingRow2({ rowContext, children, className, style }, ref) {
|
|
1165
|
+
const state = useRawMappingRow({ rowContext });
|
|
1166
|
+
return /* @__PURE__ */ jsx9("div", { ref, className, style, "data-ris-ui": "raw-mapping-row", children: children(state) });
|
|
1167
|
+
});
|
|
1168
|
+
|
|
1169
|
+
// src/components/RawMappingSuggest/RawMappingSuggest.tsx
|
|
1170
|
+
import { forwardRef as forwardRef6 } from "react";
|
|
1171
|
+
import { jsx as jsx10 } from "react/jsx-runtime";
|
|
1172
|
+
var RawMappingSuggest = forwardRef6(
|
|
1173
|
+
function RawMappingSuggest2({ columnContext, children, className, style }, ref) {
|
|
1174
|
+
const state = useRawMappingSuggest({ columnContext });
|
|
1175
|
+
return /* @__PURE__ */ jsx10("div", { ref, className, style, "data-ris-ui": "raw-mapping-suggest", children: children(state) });
|
|
1176
|
+
}
|
|
1177
|
+
);
|
|
1178
|
+
|
|
1179
|
+
// src/components/RawImportAction/RawImportAction.tsx
|
|
1180
|
+
import { forwardRef as forwardRef7 } from "react";
|
|
1181
|
+
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
1182
|
+
var RawImportAction = forwardRef7(
|
|
1183
|
+
function RawImportAction2({ children, className, style }, ref) {
|
|
1184
|
+
const state = useRawImportAction();
|
|
1185
|
+
return /* @__PURE__ */ jsx11("div", { ref, className, style, "data-ris-ui": "raw-import-action", children: children(state) });
|
|
1186
|
+
}
|
|
1187
|
+
);
|
|
1188
|
+
|
|
1189
|
+
// src/components/RawErrorBoundary/RawErrorBoundary.tsx
|
|
1190
|
+
import { Component } from "react";
|
|
1191
|
+
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
1192
|
+
var RawErrorBoundary = class extends Component {
|
|
1193
|
+
constructor(props) {
|
|
1194
|
+
super(props);
|
|
1195
|
+
this.state = { error: null, errorInfo: null };
|
|
1196
|
+
}
|
|
1197
|
+
static getDerivedStateFromError(error) {
|
|
1198
|
+
return { error, errorInfo: null };
|
|
1199
|
+
}
|
|
1200
|
+
componentDidCatch(error, errorInfo) {
|
|
1201
|
+
this.setState((s) => ({ ...s, errorInfo }));
|
|
1202
|
+
this.props.onError?.(error, errorInfo);
|
|
1203
|
+
}
|
|
1204
|
+
render() {
|
|
1205
|
+
const { error, errorInfo } = this.state;
|
|
1206
|
+
const { children, fallback } = this.props;
|
|
1207
|
+
if (error) {
|
|
1208
|
+
const content = typeof fallback === "function" ? fallback(error, errorInfo ?? { componentStack: "" }) : fallback;
|
|
1209
|
+
return /* @__PURE__ */ jsx12("div", { "data-ris-ui": "raw-error-boundary", children: content });
|
|
1210
|
+
}
|
|
1211
|
+
return children;
|
|
1212
|
+
}
|
|
1213
|
+
};
|
|
1214
|
+
|
|
1215
|
+
// src/components/RawProgressDisplay/RawProgressDisplay.tsx
|
|
1216
|
+
import { forwardRef as forwardRef8 } from "react";
|
|
1217
|
+
import { jsx as jsx13 } from "react/jsx-runtime";
|
|
1218
|
+
var RawProgressDisplay = forwardRef8(
|
|
1219
|
+
function RawProgressDisplay2({ children, className, style, onProgress }, ref) {
|
|
1220
|
+
const state = useRawProgress({ onProgress });
|
|
1221
|
+
return /* @__PURE__ */ jsx13("div", { ref, className, style, "data-ris-ui": "raw-progress-display", children: children(state) });
|
|
1222
|
+
}
|
|
1223
|
+
);
|
|
1224
|
+
|
|
1225
|
+
// src/components/RawStatusIndicator/RawStatusIndicator.tsx
|
|
1226
|
+
import { forwardRef as forwardRef9 } from "react";
|
|
1227
|
+
import { jsx as jsx14 } from "react/jsx-runtime";
|
|
1228
|
+
var RawStatusIndicator = forwardRef9(
|
|
1229
|
+
function RawStatusIndicator2({ children, className, style }, ref) {
|
|
1230
|
+
const state = useRawStatus();
|
|
1231
|
+
return /* @__PURE__ */ jsx14("div", { ref, className, style, "data-ris-ui": "raw-status-indicator", children: children(state) });
|
|
1232
|
+
}
|
|
1233
|
+
);
|
|
1234
|
+
|
|
1235
|
+
// src/components/RawAbortButton/RawAbortButton.tsx
|
|
1236
|
+
import { forwardRef as forwardRef10, useMemo as useMemo17 } from "react";
|
|
1237
|
+
import { jsx as jsx15 } from "react/jsx-runtime";
|
|
1238
|
+
var PROCESSING_STATUSES = ["loading", "parsing", "validating", "transforming"];
|
|
1239
|
+
var RawAbortButton = forwardRef10(
|
|
1240
|
+
function RawAbortButton2({ children, className, style, disabled: disabledProp, "aria-label": ariaLabel }, ref) {
|
|
1241
|
+
const { abort } = useRawAbort();
|
|
1242
|
+
const { status } = useRawStatus();
|
|
1243
|
+
const isProcessing = PROCESSING_STATUSES.includes(
|
|
1244
|
+
status
|
|
1245
|
+
);
|
|
1246
|
+
const disabled = disabledProp ?? !isProcessing;
|
|
1247
|
+
const buttonProps = useMemo17(
|
|
1248
|
+
() => ({
|
|
1249
|
+
type: "button",
|
|
1250
|
+
onClick: abort,
|
|
1251
|
+
disabled,
|
|
1252
|
+
className,
|
|
1253
|
+
style,
|
|
1254
|
+
"aria-label": ariaLabel ?? "Cancel import"
|
|
1255
|
+
}),
|
|
1256
|
+
[abort, disabled, className, style, ariaLabel]
|
|
1257
|
+
);
|
|
1258
|
+
return /* @__PURE__ */ jsx15("button", { ref, ...buttonProps, "data-ris-ui": "raw-abort-button", children: children ?? "Cancel" });
|
|
1259
|
+
}
|
|
1260
|
+
);
|
|
1261
|
+
|
|
1262
|
+
// src/components/RawImporterWorkflow/RawImporterWorkflow.tsx
|
|
1263
|
+
import { forwardRef as forwardRef12 } from "react";
|
|
1264
|
+
|
|
1265
|
+
// src/components/RawEditLogPanel/RawEditLogPanel.tsx
|
|
1266
|
+
import { forwardRef as forwardRef11 } from "react";
|
|
1267
|
+
import { jsx as jsx16, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
1268
|
+
var RawEditLogPanel = forwardRef11(
|
|
1269
|
+
function RawEditLogPanel2({ className, style, children }, ref) {
|
|
1270
|
+
const { entries, changeLogAsText } = useRawEditLog();
|
|
1271
|
+
if (children) {
|
|
1272
|
+
return /* @__PURE__ */ jsx16(
|
|
1273
|
+
"div",
|
|
1274
|
+
{
|
|
1275
|
+
ref,
|
|
1276
|
+
className,
|
|
1277
|
+
style,
|
|
1278
|
+
"data-ris-ui": "raw-edit-log-panel",
|
|
1279
|
+
role: "log",
|
|
1280
|
+
"aria-label": "Edit log",
|
|
1281
|
+
children: children({ entries, changeLogAsText, clearLog: () => {
|
|
1282
|
+
} })
|
|
1283
|
+
}
|
|
1284
|
+
);
|
|
1285
|
+
}
|
|
1286
|
+
return /* @__PURE__ */ jsxs2(
|
|
1287
|
+
"div",
|
|
1288
|
+
{
|
|
1289
|
+
ref,
|
|
1290
|
+
className,
|
|
1291
|
+
style,
|
|
1292
|
+
"data-ris-ui": "raw-edit-log-panel",
|
|
1293
|
+
role: "log",
|
|
1294
|
+
"aria-label": "Edit log",
|
|
1295
|
+
children: [
|
|
1296
|
+
/* @__PURE__ */ jsx16("div", { "data-ris-ui": "raw-edit-log-header", children: /* @__PURE__ */ jsxs2("span", { children: [
|
|
1297
|
+
"Edit log (",
|
|
1298
|
+
entries.length,
|
|
1299
|
+
" changes)"
|
|
1300
|
+
] }) }),
|
|
1301
|
+
changeLogAsText ? /* @__PURE__ */ jsx16("pre", { "data-ris-ui": "raw-edit-log-list", children: changeLogAsText }) : /* @__PURE__ */ jsx16("ul", { "data-ris-ui": "raw-edit-log-list", children: entries.length === 0 ? /* @__PURE__ */ jsx16("li", { "data-ris-ui": "raw-edit-log-entry", children: "No changes yet." }) : null })
|
|
1302
|
+
]
|
|
1303
|
+
}
|
|
1304
|
+
);
|
|
1305
|
+
}
|
|
1306
|
+
);
|
|
1307
|
+
|
|
1308
|
+
// src/components/RawImporterWorkflow/RawImporterWorkflow.tsx
|
|
1309
|
+
import { Fragment, jsx as jsx17, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
1310
|
+
function BackToFileButton({
|
|
1311
|
+
children = "Choose another file",
|
|
1312
|
+
"aria-label": ariaLabel = "Cancel and choose another file"
|
|
1313
|
+
}) {
|
|
1314
|
+
const { abort } = useRawAbort();
|
|
1315
|
+
return /* @__PURE__ */ jsx17(
|
|
1316
|
+
"button",
|
|
1317
|
+
{
|
|
1318
|
+
type: "button",
|
|
1319
|
+
onClick: abort,
|
|
1320
|
+
"aria-label": ariaLabel,
|
|
1321
|
+
"data-ris-ui": "raw-workflow-back-button",
|
|
1322
|
+
children
|
|
1323
|
+
}
|
|
1324
|
+
);
|
|
1325
|
+
}
|
|
1326
|
+
function DefaultIdle() {
|
|
1327
|
+
return /* @__PURE__ */ jsx17(RawFilePicker, { children: (state) => /* @__PURE__ */ jsx17("span", { "data-ris-ui": "raw-file-picker-prompt", children: state.isDragging ? "Drop file here" : "Click or drop file here" }) });
|
|
1328
|
+
}
|
|
1329
|
+
function DefaultMapping() {
|
|
1330
|
+
return /* @__PURE__ */ jsx17(RawMappingTable, { children: (state) => state.rows.map((rowContext) => /* @__PURE__ */ jsx17(RawMappingRow, { rowContext, children: (rowState) => /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
1331
|
+
/* @__PURE__ */ jsx17("span", { children: rowState.headerOriginal }),
|
|
1332
|
+
/* @__PURE__ */ jsx17(
|
|
1333
|
+
RawMappingSuggest,
|
|
1334
|
+
{
|
|
1335
|
+
columnContext: {
|
|
1336
|
+
fileHeader: rowContext.headerOriginal,
|
|
1337
|
+
columnIndex: rowContext.columnIndex
|
|
1338
|
+
},
|
|
1339
|
+
children: (suggestState) => suggestState.suggestedFieldId != null ? /* @__PURE__ */ jsxs3("span", { "data-ris-ui": "raw-mapping-suggest-badge", children: [
|
|
1340
|
+
suggestState.suggestedFieldLabel,
|
|
1341
|
+
" (",
|
|
1342
|
+
suggestState.matchScore,
|
|
1343
|
+
"%)"
|
|
1344
|
+
] }) : null
|
|
1345
|
+
}
|
|
1346
|
+
),
|
|
1347
|
+
/* @__PURE__ */ jsxs3(
|
|
1348
|
+
"select",
|
|
1349
|
+
{
|
|
1350
|
+
value: rowState.value ?? "",
|
|
1351
|
+
onChange: (e) => rowState.onChange(e.target.value),
|
|
1352
|
+
"aria-label": `Map ${rowState.headerOriginal}`,
|
|
1353
|
+
children: [
|
|
1354
|
+
/* @__PURE__ */ jsx17("option", { value: "", children: "\u2014" }),
|
|
1355
|
+
rowState.options.map((opt) => /* @__PURE__ */ jsx17("option", { value: opt.id, disabled: opt.disabled, children: opt.label }, opt.id))
|
|
1356
|
+
]
|
|
1357
|
+
}
|
|
1358
|
+
)
|
|
1359
|
+
] }) }, rowContext.columnIndex)) });
|
|
1360
|
+
}
|
|
1361
|
+
function DefaultMappingWithAction() {
|
|
1362
|
+
return /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
1363
|
+
/* @__PURE__ */ jsx17(DefaultMapping, {}),
|
|
1364
|
+
/* @__PURE__ */ jsxs3("div", { "data-ris-ui": "raw-workflow-mapping-actions", role: "group", children: [
|
|
1365
|
+
/* @__PURE__ */ jsx17(RawImportAction, { children: (state) => /* @__PURE__ */ jsx17(
|
|
1366
|
+
"button",
|
|
1367
|
+
{
|
|
1368
|
+
type: "button",
|
|
1369
|
+
disabled: state.disabled,
|
|
1370
|
+
onClick: state.runImport,
|
|
1371
|
+
"aria-label": "Run import",
|
|
1372
|
+
children: "Import"
|
|
1373
|
+
}
|
|
1374
|
+
) }),
|
|
1375
|
+
/* @__PURE__ */ jsx17(BackToFileButton, { children: "Choose another file" })
|
|
1376
|
+
] })
|
|
1377
|
+
] });
|
|
1378
|
+
}
|
|
1379
|
+
function DefaultProcess() {
|
|
1380
|
+
return /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
1381
|
+
/* @__PURE__ */ jsx17(RawProgressDisplay, { children: (state) => /* @__PURE__ */ jsx17("div", { "data-ris-ui": "raw-progress", children: String(state.progressRef?.current ?? 0) }) }),
|
|
1382
|
+
/* @__PURE__ */ jsx17(RawStatusIndicator, { children: (state) => /* @__PURE__ */ jsx17("div", { "data-ris-ui": "raw-status", children: state.status }) }),
|
|
1383
|
+
/* @__PURE__ */ jsx17(RawAbortButton, {})
|
|
1384
|
+
] });
|
|
1385
|
+
}
|
|
1386
|
+
function ResultToolbar({
|
|
1387
|
+
submitLabel = "Submit"
|
|
1388
|
+
} = {}) {
|
|
1389
|
+
const filter = useRawFilterToggle();
|
|
1390
|
+
const exportApi = useRawExport();
|
|
1391
|
+
const { isSubmitted, markSubmitted, canSubmit } = useRawSubmitStatus();
|
|
1392
|
+
return /* @__PURE__ */ jsxs3("div", { "data-ris-ui": "raw-workflow-toolbar", role: "toolbar", children: [
|
|
1393
|
+
isSubmitted ? /* @__PURE__ */ jsx17("span", { "data-ris-ui": "raw-workflow-submitted-message", role: "status", children: "Submitted. You can download the file below." }) : null,
|
|
1394
|
+
/* @__PURE__ */ jsx17(BackToFileButton, { "aria-label": "Import another file", children: "New file" }),
|
|
1395
|
+
/* @__PURE__ */ jsx17(
|
|
1396
|
+
"button",
|
|
1397
|
+
{
|
|
1398
|
+
type: "button",
|
|
1399
|
+
onClick: () => filter.setFilterMode(filter.filterMode === "all" ? "errors-only" : "all"),
|
|
1400
|
+
"aria-pressed": filter.filterMode === "errors-only",
|
|
1401
|
+
children: filter.filterMode === "all" ? "All" : "Errors only"
|
|
1402
|
+
}
|
|
1403
|
+
),
|
|
1404
|
+
/* @__PURE__ */ jsx17("button", { type: "button", onClick: () => exportApi.downloadCSV?.(), children: "Export CSV" }),
|
|
1405
|
+
/* @__PURE__ */ jsx17("button", { type: "button", onClick: () => exportApi.downloadJSON?.(), children: "Export JSON" }),
|
|
1406
|
+
exportApi.downloadCSVErrorsOnly != null ? /* @__PURE__ */ jsx17(
|
|
1407
|
+
"button",
|
|
1408
|
+
{
|
|
1409
|
+
type: "button",
|
|
1410
|
+
disabled: !exportApi.hasRowsWithErrors || isSubmitted,
|
|
1411
|
+
onClick: () => exportApi.downloadCSVErrorsOnly?.(),
|
|
1412
|
+
title: exportApi.hasRowsWithErrors ? void 0 : "No hay filas con errores",
|
|
1413
|
+
children: "Export CSV (errors only)"
|
|
1414
|
+
}
|
|
1415
|
+
) : null,
|
|
1416
|
+
exportApi.downloadJSONErrorsOnly != null ? /* @__PURE__ */ jsx17(
|
|
1417
|
+
"button",
|
|
1418
|
+
{
|
|
1419
|
+
type: "button",
|
|
1420
|
+
disabled: !exportApi.hasRowsWithErrors || isSubmitted,
|
|
1421
|
+
onClick: () => exportApi.downloadJSONErrorsOnly?.(),
|
|
1422
|
+
title: exportApi.hasRowsWithErrors ? void 0 : "No hay filas con errores",
|
|
1423
|
+
children: "Export JSON (errors only)"
|
|
1424
|
+
}
|
|
1425
|
+
) : null,
|
|
1426
|
+
!isSubmitted ? /* @__PURE__ */ jsx17(
|
|
1427
|
+
"button",
|
|
1428
|
+
{
|
|
1429
|
+
type: "button",
|
|
1430
|
+
disabled: !canSubmit,
|
|
1431
|
+
onClick: () => markSubmitted(),
|
|
1432
|
+
"data-ris-ui": "raw-workflow-submit",
|
|
1433
|
+
"aria-label": typeof submitLabel === "string" ? submitLabel : "Submit",
|
|
1434
|
+
children: submitLabel
|
|
1435
|
+
}
|
|
1436
|
+
) : null
|
|
1437
|
+
] });
|
|
1438
|
+
}
|
|
1439
|
+
function ResultGrid({
|
|
1440
|
+
cellErrorPlacement = "inline"
|
|
1441
|
+
}) {
|
|
1442
|
+
const { headers } = useRawTableHead();
|
|
1443
|
+
const { visibleSheetIndices } = useRawPagination();
|
|
1444
|
+
const { canRemoveRow } = useRawRemoveRow();
|
|
1445
|
+
return /* @__PURE__ */ jsxs3("table", { "data-ris-ui": "raw-workflow-grid", role: "grid", children: [
|
|
1446
|
+
/* @__PURE__ */ jsx17("thead", { children: /* @__PURE__ */ jsxs3("tr", { role: "row", children: [
|
|
1447
|
+
headers.map((h) => /* @__PURE__ */ jsx17("th", { scope: "col", role: "columnheader", children: h.label }, h.id)),
|
|
1448
|
+
canRemoveRow ? /* @__PURE__ */ jsx17("th", { scope: "col", role: "columnheader", "data-ris-ui": "raw-workflow-row-actions-header", children: "Actions" }) : null
|
|
1449
|
+
] }) }),
|
|
1450
|
+
/* @__PURE__ */ jsx17("tbody", { children: visibleSheetIndices.map((sheetIndex) => /* @__PURE__ */ jsx17(
|
|
1451
|
+
ResultRow,
|
|
1452
|
+
{
|
|
1453
|
+
index: sheetIndex,
|
|
1454
|
+
headerIds: headers.map((h) => h.id),
|
|
1455
|
+
showRemoveAction: canRemoveRow,
|
|
1456
|
+
cellErrorPlacement
|
|
1457
|
+
},
|
|
1458
|
+
sheetIndex
|
|
1459
|
+
)) })
|
|
1460
|
+
] });
|
|
1461
|
+
}
|
|
1462
|
+
function ResultRow({
|
|
1463
|
+
index,
|
|
1464
|
+
headerIds,
|
|
1465
|
+
showRemoveAction,
|
|
1466
|
+
cellErrorPlacement = "inline"
|
|
1467
|
+
}) {
|
|
1468
|
+
const row = useRawTableRow({ index });
|
|
1469
|
+
const { removeRow, canRemoveRow } = useRawRemoveRow();
|
|
1470
|
+
const { isSubmitted } = useRawSubmitStatus();
|
|
1471
|
+
const showDelete = showRemoveAction && canRemoveRow && !isSubmitted;
|
|
1472
|
+
return /* @__PURE__ */ jsxs3("tr", { ...row.getRowProps(), children: [
|
|
1473
|
+
headerIds.map((fieldId) => /* @__PURE__ */ jsx17(
|
|
1474
|
+
ResultCell,
|
|
1475
|
+
{
|
|
1476
|
+
rowIndex: index,
|
|
1477
|
+
fieldId,
|
|
1478
|
+
cellErrorPlacement
|
|
1479
|
+
},
|
|
1480
|
+
fieldId
|
|
1481
|
+
)),
|
|
1482
|
+
showDelete ? /* @__PURE__ */ jsx17("td", { role: "gridcell", "data-ris-ui": "raw-workflow-row-remove-cell", children: /* @__PURE__ */ jsx17(
|
|
1483
|
+
"button",
|
|
1484
|
+
{
|
|
1485
|
+
type: "button",
|
|
1486
|
+
onClick: () => removeRow(index),
|
|
1487
|
+
"aria-label": `Remove row ${index + 1}`,
|
|
1488
|
+
"data-ris-ui": "raw-workflow-remove-row",
|
|
1489
|
+
children: "Remove row"
|
|
1490
|
+
}
|
|
1491
|
+
) }) : null
|
|
1492
|
+
] }, index);
|
|
1493
|
+
}
|
|
1494
|
+
function ResultCell({
|
|
1495
|
+
rowIndex,
|
|
1496
|
+
fieldId,
|
|
1497
|
+
cellErrorPlacement = "inline"
|
|
1498
|
+
}) {
|
|
1499
|
+
const cell = useRawCell({ rowIndex, fieldId });
|
|
1500
|
+
const error = cell.errors?.[0];
|
|
1501
|
+
const badge = useRawErrorBadge({
|
|
1502
|
+
error: error ?? null,
|
|
1503
|
+
translateError: void 0
|
|
1504
|
+
});
|
|
1505
|
+
const showError = cellErrorPlacement !== "none" && badge.message;
|
|
1506
|
+
const errorSlot = showError && /* @__PURE__ */ jsx17("span", { ...cell.getErrorProps(), children: badge.message });
|
|
1507
|
+
return /* @__PURE__ */ jsx17("td", { ...cell.getCellProps(), children: cellErrorPlacement === "below" ? /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
1508
|
+
/* @__PURE__ */ jsx17("div", { "data-ris-ui": "raw-cell-value-line", children: cell.isEditing ? /* @__PURE__ */ jsx17("input", { ...cell.getEditInputProps() }) : /* @__PURE__ */ jsx17("span", { children: String(cell.value ?? "") }) }),
|
|
1509
|
+
showError ? /* @__PURE__ */ jsx17("div", { "data-ris-ui": "raw-cell-error-line", children: errorSlot }) : null
|
|
1510
|
+
] }) : /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
1511
|
+
cell.isEditing ? /* @__PURE__ */ jsx17("input", { ...cell.getEditInputProps() }) : /* @__PURE__ */ jsx17("span", { children: String(cell.value ?? "") }),
|
|
1512
|
+
cellErrorPlacement === "inline" && errorSlot
|
|
1513
|
+
] }) });
|
|
1514
|
+
}
|
|
1515
|
+
function ResultFooter() {
|
|
1516
|
+
const pagination = useRawPagination();
|
|
1517
|
+
const persistence = useRawPersistence();
|
|
1518
|
+
return /* @__PURE__ */ jsxs3("div", { "data-ris-ui": "raw-workflow-footer", role: "contentinfo", children: [
|
|
1519
|
+
/* @__PURE__ */ jsxs3("div", { "data-ris-ui": "raw-workflow-pagination", children: [
|
|
1520
|
+
/* @__PURE__ */ jsx17(
|
|
1521
|
+
"button",
|
|
1522
|
+
{
|
|
1523
|
+
type: "button",
|
|
1524
|
+
disabled: pagination.page <= 1,
|
|
1525
|
+
onClick: () => pagination.setPage(pagination.page - 1),
|
|
1526
|
+
"aria-label": "Previous page",
|
|
1527
|
+
children: "Previous"
|
|
1528
|
+
}
|
|
1529
|
+
),
|
|
1530
|
+
/* @__PURE__ */ jsxs3("span", { children: [
|
|
1531
|
+
"Page ",
|
|
1532
|
+
pagination.page,
|
|
1533
|
+
" of",
|
|
1534
|
+
" ",
|
|
1535
|
+
Math.max(1, Math.ceil(pagination.totalRows / pagination.pageSize))
|
|
1536
|
+
] }),
|
|
1537
|
+
/* @__PURE__ */ jsx17(
|
|
1538
|
+
"button",
|
|
1539
|
+
{
|
|
1540
|
+
type: "button",
|
|
1541
|
+
disabled: pagination.page >= Math.ceil(pagination.totalRows / pagination.pageSize),
|
|
1542
|
+
onClick: () => pagination.setPage(pagination.page + 1),
|
|
1543
|
+
"aria-label": "Next page",
|
|
1544
|
+
children: "Next"
|
|
1545
|
+
}
|
|
1546
|
+
)
|
|
1547
|
+
] }),
|
|
1548
|
+
persistence.hasRecoverableSession ? /* @__PURE__ */ jsxs3("div", { "data-ris-ui": "raw-workflow-persistence", children: [
|
|
1549
|
+
/* @__PURE__ */ jsx17("button", { type: "button", onClick: persistence.recoverSession, children: "Recover session" }),
|
|
1550
|
+
/* @__PURE__ */ jsx17("button", { type: "button", onClick: persistence.clearSession, children: "Clear" })
|
|
1551
|
+
] }) : null
|
|
1552
|
+
] });
|
|
1553
|
+
}
|
|
1554
|
+
function DefaultResult({
|
|
1555
|
+
submitLabel,
|
|
1556
|
+
cellErrorPlacement = "inline"
|
|
1557
|
+
} = {}) {
|
|
1558
|
+
return /* @__PURE__ */ jsxs3(RawViewPhaseProvider, { children: [
|
|
1559
|
+
/* @__PURE__ */ jsx17(ResultToolbar, { submitLabel }),
|
|
1560
|
+
/* @__PURE__ */ jsx17(RawEditLogPanel, {}),
|
|
1561
|
+
/* @__PURE__ */ jsx17(RawDataTableProvider, { children: /* @__PURE__ */ jsx17(ResultGrid, { cellErrorPlacement }) }),
|
|
1562
|
+
/* @__PURE__ */ jsx17(ResultFooter, {})
|
|
1563
|
+
] });
|
|
1564
|
+
}
|
|
1565
|
+
function DefaultError({ mappingErrorDetail }) {
|
|
1566
|
+
if (mappingErrorDetail?.code === "TOO_MANY_MISMATCHES") {
|
|
1567
|
+
return /* @__PURE__ */ jsxs3("div", { "data-ris-ui": "raw-workflow-mapping-error", role: "alert", children: [
|
|
1568
|
+
/* @__PURE__ */ jsxs3("p", { children: [
|
|
1569
|
+
"Too many column mismatches (",
|
|
1570
|
+
mappingErrorDetail.mismatchCount,
|
|
1571
|
+
"). Maximum allowed:",
|
|
1572
|
+
" ",
|
|
1573
|
+
mappingErrorDetail.maxAllowed,
|
|
1574
|
+
"."
|
|
1575
|
+
] }),
|
|
1576
|
+
/* @__PURE__ */ jsx17(BackToFileButton, { children: "Choose another file" })
|
|
1577
|
+
] });
|
|
1578
|
+
}
|
|
1579
|
+
return /* @__PURE__ */ jsx17(DefaultIdle, {});
|
|
1580
|
+
}
|
|
1581
|
+
var RawImporterWorkflow = forwardRef12(
|
|
1582
|
+
function RawImporterWorkflow2({
|
|
1583
|
+
className,
|
|
1584
|
+
style,
|
|
1585
|
+
renderIdle,
|
|
1586
|
+
renderMapping,
|
|
1587
|
+
renderProcess,
|
|
1588
|
+
renderResult,
|
|
1589
|
+
renderError,
|
|
1590
|
+
submitLabel,
|
|
1591
|
+
cellErrorPlacement = "inline"
|
|
1592
|
+
}, ref) {
|
|
1593
|
+
const { view, mappingErrorDetail } = useStatusView();
|
|
1594
|
+
let content;
|
|
1595
|
+
switch (view) {
|
|
1596
|
+
case "idle":
|
|
1597
|
+
content = renderIdle ? renderIdle() : /* @__PURE__ */ jsx17(DefaultIdle, {});
|
|
1598
|
+
break;
|
|
1599
|
+
case "mapping":
|
|
1600
|
+
content = renderMapping ? renderMapping() : /* @__PURE__ */ jsx17(DefaultMappingWithAction, {});
|
|
1601
|
+
break;
|
|
1602
|
+
case "process":
|
|
1603
|
+
content = renderProcess ? renderProcess() : /* @__PURE__ */ jsx17(DefaultProcess, {});
|
|
1604
|
+
break;
|
|
1605
|
+
case "result":
|
|
1606
|
+
content = renderResult ? renderResult() : /* @__PURE__ */ jsx17(DefaultResult, { submitLabel, cellErrorPlacement });
|
|
1607
|
+
break;
|
|
1608
|
+
case "error":
|
|
1609
|
+
content = renderError ? renderError({ mappingErrorDetail }) : /* @__PURE__ */ jsx17(DefaultError, { mappingErrorDetail });
|
|
1610
|
+
break;
|
|
1611
|
+
default:
|
|
1612
|
+
content = renderIdle ? renderIdle() : /* @__PURE__ */ jsx17(DefaultIdle, {});
|
|
1613
|
+
}
|
|
1614
|
+
return /* @__PURE__ */ jsx17("div", { ref, className, style, "data-ris-ui": "raw-importer-workflow", children: content });
|
|
1615
|
+
}
|
|
1616
|
+
);
|
|
1617
|
+
|
|
1618
|
+
// src/index.ts
|
|
1619
|
+
import {
|
|
1620
|
+
ImporterProvider as ImporterProvider2,
|
|
1621
|
+
useImporter as useImporter5,
|
|
1622
|
+
useImportSheet,
|
|
1623
|
+
useConvert as useConvert5,
|
|
1624
|
+
useImporterStatus as useImporterStatus5,
|
|
1625
|
+
useSheetData as useSheetData6,
|
|
1626
|
+
useSheetEditor as useSheetEditor5,
|
|
1627
|
+
useSheetView as useSheetView2,
|
|
1628
|
+
useImporterEventTarget,
|
|
1629
|
+
useImporterProgressSubscription,
|
|
1630
|
+
IMPORTER_ABORTED_EVENT as IMPORTER_ABORTED_EVENT2,
|
|
1631
|
+
IMPORTER_PROGRESS_EVENT as IMPORTER_PROGRESS_EVENT2
|
|
1632
|
+
} from "@cristianmpx/react-import-sheet-headless";
|
|
1633
|
+
export {
|
|
1634
|
+
DataTableContext,
|
|
1635
|
+
EditLogContext,
|
|
1636
|
+
IMPORTER_ABORTED_EVENT2 as IMPORTER_ABORTED_EVENT,
|
|
1637
|
+
IMPORTER_PROGRESS_EVENT2 as IMPORTER_PROGRESS_EVENT,
|
|
1638
|
+
ImporterProvider2 as ImporterProvider,
|
|
1639
|
+
LayoutContext,
|
|
1640
|
+
LayoutProvider,
|
|
1641
|
+
RawAbortButton,
|
|
1642
|
+
RawDataTableProvider,
|
|
1643
|
+
RawEditLogPanel,
|
|
1644
|
+
RawEditLogProvider,
|
|
1645
|
+
RawErrorBoundary,
|
|
1646
|
+
RawFilePicker,
|
|
1647
|
+
RawImportAction,
|
|
1648
|
+
RawImporterRoot,
|
|
1649
|
+
RawImporterWorkflow,
|
|
1650
|
+
RawMappingRow,
|
|
1651
|
+
RawMappingSuggest,
|
|
1652
|
+
RawMappingTable,
|
|
1653
|
+
RawProgressDisplay,
|
|
1654
|
+
RawStatusGuard,
|
|
1655
|
+
RawStatusIndicator,
|
|
1656
|
+
RawViewPhaseProvider,
|
|
1657
|
+
RootConfigContext,
|
|
1658
|
+
RootConfigProvider,
|
|
1659
|
+
ViewPhaseContext,
|
|
1660
|
+
getLayoutFieldOptions,
|
|
1661
|
+
getViewFromState,
|
|
1662
|
+
useConvert5 as useConvert,
|
|
1663
|
+
useImportSheet,
|
|
1664
|
+
useImporter5 as useImporter,
|
|
1665
|
+
useImporterEventTarget,
|
|
1666
|
+
useImporterMetrics,
|
|
1667
|
+
useImporterProgressSubscription,
|
|
1668
|
+
useImporterStatus5 as useImporterStatus,
|
|
1669
|
+
useRawAbort,
|
|
1670
|
+
useRawCell,
|
|
1671
|
+
useRawDataTable,
|
|
1672
|
+
useRawEditLog,
|
|
1673
|
+
useRawErrorBadge,
|
|
1674
|
+
useRawExport,
|
|
1675
|
+
useRawFilePicker,
|
|
1676
|
+
useRawFilterToggle,
|
|
1677
|
+
useRawImportAction,
|
|
1678
|
+
useRawImporterRoot,
|
|
1679
|
+
useRawMappingRow,
|
|
1680
|
+
useRawMappingSuggest,
|
|
1681
|
+
useRawMappingTable,
|
|
1682
|
+
useRawPagination,
|
|
1683
|
+
useRawPersistence,
|
|
1684
|
+
useRawProgress,
|
|
1685
|
+
useRawRemoveRow,
|
|
1686
|
+
useRawStatus,
|
|
1687
|
+
useRawSubmitStatus,
|
|
1688
|
+
useRawTableBody,
|
|
1689
|
+
useRawTableHead,
|
|
1690
|
+
useRawTableRow,
|
|
1691
|
+
useSheetData6 as useSheetData,
|
|
1692
|
+
useSheetEditor5 as useSheetEditor,
|
|
1693
|
+
useSheetView2 as useSheetView,
|
|
1694
|
+
useStatusView
|
|
1695
|
+
};
|
|
1696
|
+
//# sourceMappingURL=index.mjs.map
|