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