@jmruthers/pace-core 0.5.98 → 0.5.100
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{DataTable-YK5UZGRI.js → DataTable-MHN7PNH3.js} +2 -2
- package/dist/{chunk-UWBDIT5N.js → chunk-OLZSC5EH.js} +102 -14
- package/dist/{chunk-UWBDIT5N.js.map → chunk-OLZSC5EH.js.map} +1 -1
- package/dist/{chunk-DIKQ7AB6.js → chunk-Z4HVIZSK.js} +2 -2
- package/dist/components.js +2 -2
- package/dist/index.js +2 -2
- package/dist/utils.js +1 -1
- package/docs/api/classes/ColumnFactory.md +1 -1
- package/docs/api/classes/ErrorBoundary.md +1 -1
- package/docs/api/classes/InvalidScopeError.md +1 -1
- package/docs/api/classes/MissingUserContextError.md +1 -1
- package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
- package/docs/api/classes/PermissionDeniedError.md +1 -1
- package/docs/api/classes/PublicErrorBoundary.md +1 -1
- package/docs/api/classes/RBACAuditManager.md +1 -1
- package/docs/api/classes/RBACCache.md +1 -1
- package/docs/api/classes/RBACEngine.md +1 -1
- package/docs/api/classes/RBACError.md +1 -1
- package/docs/api/classes/RBACNotInitializedError.md +1 -1
- package/docs/api/classes/SecureSupabaseClient.md +1 -1
- package/docs/api/classes/StorageUtils.md +1 -1
- package/docs/api/enums/FileCategory.md +1 -1
- package/docs/api/interfaces/AggregateConfig.md +1 -1
- package/docs/api/interfaces/ButtonProps.md +1 -1
- package/docs/api/interfaces/CardProps.md +1 -1
- package/docs/api/interfaces/ColorPalette.md +1 -1
- package/docs/api/interfaces/ColorShade.md +1 -1
- package/docs/api/interfaces/DataAccessRecord.md +1 -1
- package/docs/api/interfaces/DataRecord.md +1 -1
- package/docs/api/interfaces/DataTableAction.md +1 -1
- package/docs/api/interfaces/DataTableColumn.md +1 -1
- package/docs/api/interfaces/DataTableProps.md +1 -1
- package/docs/api/interfaces/DataTableToolbarButton.md +1 -1
- package/docs/api/interfaces/EmptyStateConfig.md +1 -1
- package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
- package/docs/api/interfaces/EventLogoProps.md +1 -1
- package/docs/api/interfaces/FileDisplayProps.md +1 -1
- package/docs/api/interfaces/FileMetadata.md +1 -1
- package/docs/api/interfaces/FileReference.md +1 -1
- package/docs/api/interfaces/FileSizeLimits.md +1 -1
- package/docs/api/interfaces/FileUploadOptions.md +1 -1
- package/docs/api/interfaces/FileUploadProps.md +1 -1
- package/docs/api/interfaces/FooterProps.md +1 -1
- package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
- package/docs/api/interfaces/InputProps.md +1 -1
- package/docs/api/interfaces/LabelProps.md +1 -1
- package/docs/api/interfaces/LoginFormProps.md +1 -1
- package/docs/api/interfaces/NavigationAccessRecord.md +1 -1
- package/docs/api/interfaces/NavigationContextType.md +1 -1
- package/docs/api/interfaces/NavigationGuardProps.md +1 -1
- package/docs/api/interfaces/NavigationItem.md +1 -1
- package/docs/api/interfaces/NavigationMenuProps.md +1 -1
- package/docs/api/interfaces/NavigationProviderProps.md +1 -1
- package/docs/api/interfaces/Organisation.md +1 -1
- package/docs/api/interfaces/OrganisationContextType.md +1 -1
- package/docs/api/interfaces/OrganisationMembership.md +1 -1
- package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
- package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
- package/docs/api/interfaces/PaceAppLayoutProps.md +1 -1
- package/docs/api/interfaces/PaceLoginPageProps.md +1 -1
- package/docs/api/interfaces/PageAccessRecord.md +1 -1
- package/docs/api/interfaces/PagePermissionContextType.md +1 -1
- package/docs/api/interfaces/PagePermissionGuardProps.md +1 -1
- package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
- package/docs/api/interfaces/PaletteData.md +1 -1
- package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
- package/docs/api/interfaces/ProtectedRouteProps.md +1 -1
- package/docs/api/interfaces/PublicErrorBoundaryProps.md +1 -1
- package/docs/api/interfaces/PublicErrorBoundaryState.md +1 -1
- package/docs/api/interfaces/PublicLoadingSpinnerProps.md +1 -1
- package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
- package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
- package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
- package/docs/api/interfaces/RBACConfig.md +1 -1
- package/docs/api/interfaces/RBACLogger.md +1 -1
- package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
- package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
- package/docs/api/interfaces/RouteAccessRecord.md +1 -1
- package/docs/api/interfaces/RouteConfig.md +1 -1
- package/docs/api/interfaces/SecureDataContextType.md +1 -1
- package/docs/api/interfaces/SecureDataProviderProps.md +1 -1
- package/docs/api/interfaces/StorageConfig.md +1 -1
- package/docs/api/interfaces/StorageFileInfo.md +1 -1
- package/docs/api/interfaces/StorageFileMetadata.md +1 -1
- package/docs/api/interfaces/StorageListOptions.md +1 -1
- package/docs/api/interfaces/StorageListResult.md +1 -1
- package/docs/api/interfaces/StorageUploadOptions.md +1 -1
- package/docs/api/interfaces/StorageUploadResult.md +1 -1
- package/docs/api/interfaces/StorageUrlOptions.md +1 -1
- package/docs/api/interfaces/StyleImport.md +1 -1
- package/docs/api/interfaces/SwitchProps.md +1 -1
- package/docs/api/interfaces/ToastActionElement.md +1 -1
- package/docs/api/interfaces/ToastProps.md +1 -1
- package/docs/api/interfaces/UnifiedAuthContextType.md +1 -1
- package/docs/api/interfaces/UnifiedAuthProviderProps.md +1 -1
- package/docs/api/interfaces/UseEventLogoOptions.md +1 -1
- package/docs/api/interfaces/UseEventLogoReturn.md +1 -1
- package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
- package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
- package/docs/api/interfaces/UsePublicEventLogoOptions.md +1 -1
- package/docs/api/interfaces/UsePublicEventLogoReturn.md +1 -1
- package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
- package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
- package/docs/api/interfaces/UsePublicFileDisplayOptions.md +1 -1
- package/docs/api/interfaces/UsePublicFileDisplayReturn.md +1 -1
- package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
- package/docs/api/interfaces/UseResolvedScopeOptions.md +1 -1
- package/docs/api/interfaces/UseResolvedScopeReturn.md +1 -1
- package/docs/api/interfaces/UserEventAccess.md +1 -1
- package/docs/api/interfaces/UserMenuProps.md +1 -1
- package/docs/api/interfaces/UserProfile.md +1 -1
- package/docs/api/modules.md +2 -2
- package/package.json +1 -1
- package/src/components/DataTable/components/DataTableCore.tsx +32 -3
- package/src/components/DataTable/components/DataTableModals.tsx +92 -11
- /package/dist/{DataTable-YK5UZGRI.js.map → DataTable-MHN7PNH3.js.map} +0 -0
- /package/dist/{chunk-DIKQ7AB6.js.map → chunk-Z4HVIZSK.js.map} +0 -0
package/docs/api/modules.md
CHANGED
package/package.json
CHANGED
|
@@ -1293,10 +1293,39 @@ function DataTableInternal<TData extends DataRecord>({
|
|
|
1293
1293
|
onCloseImportModal={() => stateActions.setImportModal(false)}
|
|
1294
1294
|
onImport={async (data: TData[]) => {
|
|
1295
1295
|
if (onImport) {
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1296
|
+
try {
|
|
1297
|
+
console.log('[DataTableCore] onImport called with', data.length, 'rows');
|
|
1298
|
+
const result = onImport(data);
|
|
1299
|
+
if (result && typeof result.then === 'function') {
|
|
1300
|
+
await result;
|
|
1301
|
+
}
|
|
1302
|
+
console.log('[DataTableCore] onImport completed successfully');
|
|
1303
|
+
|
|
1304
|
+
// Show success toast
|
|
1305
|
+
toast({
|
|
1306
|
+
title: "Import Successful",
|
|
1307
|
+
description: `Successfully imported ${data.length} ${data.length === 1 ? 'row' : 'rows'}`,
|
|
1308
|
+
variant: "default"
|
|
1309
|
+
});
|
|
1310
|
+
} catch (error) {
|
|
1311
|
+
console.error('[DataTableCore] Import error:', error);
|
|
1312
|
+
toast({
|
|
1313
|
+
title: "Import Failed",
|
|
1314
|
+
description: error instanceof Error ? error.message : 'Failed to import data',
|
|
1315
|
+
variant: "destructive"
|
|
1316
|
+
});
|
|
1317
|
+
// Don't close modal on error so user can see the error
|
|
1318
|
+
return;
|
|
1299
1319
|
}
|
|
1320
|
+
} else {
|
|
1321
|
+
console.error('[DataTableCore] onImport handler not provided');
|
|
1322
|
+
toast({
|
|
1323
|
+
title: "Import Not Configured",
|
|
1324
|
+
description: "Import functionality requires an onImport handler to be provided.",
|
|
1325
|
+
variant: "destructive"
|
|
1326
|
+
});
|
|
1327
|
+
// Don't close modal so user can see the error
|
|
1328
|
+
return;
|
|
1300
1329
|
}
|
|
1301
1330
|
stateActions.setImportModal(false);
|
|
1302
1331
|
}}
|
|
@@ -41,43 +41,102 @@ function mapCSVToTableColumns<TData extends Record<string, unknown> = Record<str
|
|
|
41
41
|
// Priority: editAccessorKey > accessorKey > id
|
|
42
42
|
const columnMap = new Map<string, string>();
|
|
43
43
|
|
|
44
|
+
console.log('[mapCSVToTableColumns] Building column map from', columns.length, 'column definitions');
|
|
45
|
+
|
|
44
46
|
columns.forEach(col => {
|
|
45
47
|
const fieldName = col.editAccessorKey || col.accessorKey || col.id;
|
|
46
48
|
const header = typeof col.header === 'string' ? col.header : '';
|
|
47
49
|
|
|
48
50
|
if (fieldName && header) {
|
|
51
|
+
const headerLower = header.toLowerCase();
|
|
49
52
|
// Map header to field name (case-insensitive)
|
|
50
|
-
columnMap.set(
|
|
53
|
+
columnMap.set(headerLower, fieldName);
|
|
54
|
+
console.log(`[mapCSVToTableColumns] Mapped "${header}" -> "${fieldName}"`);
|
|
55
|
+
|
|
51
56
|
// Also map id/accessorKey if different from header
|
|
52
57
|
const colId = col.id || col.accessorKey;
|
|
53
58
|
if (colId && colId !== header && colId !== fieldName) {
|
|
54
59
|
columnMap.set(colId.toLowerCase(), fieldName);
|
|
60
|
+
console.log(`[mapCSVToTableColumns] Also mapped "${colId}" -> "${fieldName}"`);
|
|
55
61
|
}
|
|
56
62
|
|
|
57
63
|
// For reference fields with editAccessorKey, also map the ID column header
|
|
58
64
|
// This handles exports that include both "Type" and "Type (ID)" columns
|
|
59
65
|
if (col.editAccessorKey && header) {
|
|
66
|
+
const editAccessorKey = col.editAccessorKey; // Store in const for proper type narrowing
|
|
60
67
|
const idColumnHeader = `${header} (ID)`;
|
|
61
|
-
columnMap.set(idColumnHeader.toLowerCase(),
|
|
68
|
+
columnMap.set(idColumnHeader.toLowerCase(), editAccessorKey);
|
|
69
|
+
console.log(`[mapCSVToTableColumns] Mapped ID column "${idColumnHeader}" -> "${editAccessorKey}"`);
|
|
62
70
|
// Also map the editAccessorKey directly (in case CSV uses the field name)
|
|
63
|
-
columnMap.set(
|
|
71
|
+
columnMap.set(editAccessorKey.toLowerCase(), editAccessorKey);
|
|
72
|
+
console.log(`[mapCSVToTableColumns] Also mapped "${editAccessorKey}" -> "${editAccessorKey}"`);
|
|
64
73
|
}
|
|
74
|
+
} else {
|
|
75
|
+
console.warn('[mapCSVToTableColumns] Skipping column with missing fieldName or header:', col);
|
|
65
76
|
}
|
|
66
77
|
});
|
|
67
78
|
|
|
79
|
+
if (csvData.length === 0) {
|
|
80
|
+
console.warn('[mapCSVToTableColumns] No CSV data to map');
|
|
81
|
+
return [];
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const csvHeaders = Object.keys(csvData[0]);
|
|
85
|
+
console.log('[mapCSVToTableColumns] CSV headers found:', csvHeaders);
|
|
86
|
+
console.log('[mapCSVToTableColumns] Column map size:', columnMap.size);
|
|
87
|
+
|
|
68
88
|
// Transform CSV data using the mapping
|
|
69
|
-
|
|
89
|
+
const mappedData = csvData.map((row, index) => {
|
|
70
90
|
const mappedRow: Record<string, unknown> = {};
|
|
71
91
|
|
|
72
92
|
// For each CSV column, find the corresponding table field
|
|
73
93
|
Object.keys(row).forEach(csvHeader => {
|
|
74
94
|
const csvHeaderLower = csvHeader.toLowerCase();
|
|
75
|
-
|
|
76
|
-
|
|
95
|
+
|
|
96
|
+
// Try exact match first
|
|
97
|
+
let fieldName = columnMap.get(csvHeaderLower);
|
|
98
|
+
|
|
99
|
+
// If no exact match, try flexible suffix matching:
|
|
100
|
+
// If CSV header ends with " [space] ColumnHeader", match it
|
|
101
|
+
// This handles cases like "Meal Type" → "Type", "User Name" → "Name", etc.
|
|
102
|
+
// Also handles "Meal Type (ID)" → matches the column with header "Type (ID)"
|
|
103
|
+
if (!fieldName) {
|
|
104
|
+
for (const [mapKey, mapValue] of columnMap.entries()) {
|
|
105
|
+
// Check if CSV header ends with the mapped key (with a space before it, or exact match)
|
|
106
|
+
const keyWithSpace = ` ${mapKey}`;
|
|
107
|
+
if (csvHeaderLower === mapKey || csvHeaderLower.endsWith(keyWithSpace)) {
|
|
108
|
+
fieldName = mapValue;
|
|
109
|
+
if (index === 0) {
|
|
110
|
+
console.log(`[mapCSVToTableColumns] Flexible match: "${csvHeader}" -> "${mapValue}" (matched "${mapKey}")`);
|
|
111
|
+
}
|
|
112
|
+
break; // Found a match, stop searching
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (fieldName) {
|
|
118
|
+
mappedRow[fieldName] = row[csvHeader];
|
|
119
|
+
if (index === 0) {
|
|
120
|
+
console.log(`[mapCSVToTableColumns] Row 0: "${csvHeader}" -> "${fieldName}"`);
|
|
121
|
+
}
|
|
122
|
+
} else {
|
|
123
|
+
// If no mapping found, use the CSV header as-is (lowercase)
|
|
124
|
+
mappedRow[csvHeaderLower] = row[csvHeader];
|
|
125
|
+
if (index === 0) {
|
|
126
|
+
console.warn(`[mapCSVToTableColumns] No mapping found for "${csvHeader}", using as-is`);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
77
129
|
});
|
|
78
130
|
|
|
79
131
|
return mappedRow as TData;
|
|
80
132
|
});
|
|
133
|
+
|
|
134
|
+
console.log('[mapCSVToTableColumns] Mapped', mappedData.length, 'rows');
|
|
135
|
+
if (mappedData.length > 0) {
|
|
136
|
+
console.log('[mapCSVToTableColumns] First mapped row keys:', Object.keys(mappedData[0]));
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return mappedData;
|
|
81
140
|
}
|
|
82
141
|
|
|
83
142
|
/**
|
|
@@ -164,11 +223,33 @@ export function DataTableModals<TData extends Record<string, unknown> = Record<s
|
|
|
164
223
|
isOpen={showImportModal}
|
|
165
224
|
onClose={onCloseImportModal}
|
|
166
225
|
onImport={async (rawData: Array<Record<string, unknown>>) => {
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
226
|
+
try {
|
|
227
|
+
// Automatically map CSV columns to table columns based on column definitions
|
|
228
|
+
let mappedData: TData[];
|
|
229
|
+
if (columns && columns.length > 0) {
|
|
230
|
+
console.log('[DataTableModals] Mapping CSV data with', columns.length, 'column definitions');
|
|
231
|
+
console.log('[DataTableModals] Raw CSV headers:', rawData.length > 0 ? Object.keys(rawData[0]) : []);
|
|
232
|
+
mappedData = mapCSVToTableColumns<TData>(rawData, columns);
|
|
233
|
+
console.log('[DataTableModals] Mapped data sample:', mappedData.length > 0 ? mappedData[0] : null);
|
|
234
|
+
} else {
|
|
235
|
+
console.warn('[DataTableModals] No columns provided for mapping, using raw data');
|
|
236
|
+
mappedData = rawData as TData[];
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
if (!onImport) {
|
|
240
|
+
console.error('[DataTableModals] onImport callback is not provided');
|
|
241
|
+
throw new Error('Import handler is not configured. Please provide an onImport callback.');
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
console.log('[DataTableModals] Calling onImport with', mappedData.length, 'rows');
|
|
245
|
+
const result = onImport(mappedData);
|
|
246
|
+
if (result && typeof result.then === 'function') {
|
|
247
|
+
await result;
|
|
248
|
+
}
|
|
249
|
+
console.log('[DataTableModals] Import completed successfully');
|
|
250
|
+
} catch (error) {
|
|
251
|
+
console.error('[DataTableModals] Import error:', error);
|
|
252
|
+
throw error; // Re-throw to let ImportModal handle it
|
|
172
253
|
}
|
|
173
254
|
}}
|
|
174
255
|
config={importModalConfig}
|
|
File without changes
|
|
File without changes
|