@jmruthers/pace-core 0.6.8 → 0.6.10
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/CHANGELOG.md +3 -0
- package/audit-tool/audits/02-project-structure.cjs +97 -32
- package/audit-tool/audits/03-architecture.cjs +145 -19
- package/audit-tool/audits/04-code-quality.cjs +86 -1
- package/audit-tool/audits/06-security-rbac.cjs +109 -11
- package/cursor-rules/02-project-structure.mdc +2 -26
- package/cursor-rules/05-styling.mdc +84 -6
- package/cursor-rules/06-security-rbac.mdc +124 -1
- package/dist/{DataTable-6RMSCQJ6.js → DataTable-SAXFG4XI.js} +11 -13
- package/dist/{AuthService-DmfO5rGS.d.ts → InactivityServiceProvider-DHryoh6K.d.ts} +24 -249
- package/dist/UnifiedAuthProvider-BBD2PS3Q.js +7 -0
- package/dist/{UnifiedAuthProvider-CKvHP1MK.d.ts → UnifiedAuthProvider-CiBAl9-s.d.ts} +34 -22
- package/dist/{api-7P7DI652.js → api-F47QJ7FX.js} +3 -3
- package/dist/assets/app-icons/admin_favicon.svg +462 -0
- package/dist/assets/app-icons/base_favicon.svg +85 -0
- package/dist/assets/app-icons/cake_favicon.svg +68 -0
- package/dist/assets/app-icons/core_favicon.svg +256 -0
- package/dist/assets/app-icons/gear_favicon.svg +91 -0
- package/dist/assets/app-icons/medi_favicon.svg +92 -0
- package/dist/assets/app-icons/mint_favicon.svg +83 -0
- package/dist/assets/app-icons/pace_favicon.svg +49 -0
- package/dist/assets/app-icons/pump_favicon.svg +68 -0
- package/dist/assets/app-icons/seed_favicon.svg +91 -0
- package/dist/assets/app-icons/team_favicon.svg +67 -0
- package/dist/assets/app-icons/trac_favicon.svg +112 -0
- package/dist/assets/app-icons/trip_favicon.svg +102 -0
- package/dist/audit-Z6ZZBWLU.js +3 -0
- package/dist/chunk-3GWSPISD.js +61 -0
- package/dist/{chunk-4DDCYDQ3.js → chunk-66R6RLUZ.js} +12 -27
- package/dist/{chunk-FYHN4DD5.js → chunk-7YDC7LMU.js} +80 -8
- package/dist/{chunk-S7DKJPLT.js → chunk-BCTXBU6U.js} +22 -17
- package/dist/{chunk-TTRFSOKR.js → chunk-BTHN5MKC.js} +4 -4
- package/dist/{chunk-A3W6LW53.js → chunk-DDMPHZ3D.js} +6 -18
- package/dist/{chunk-MPBLMWVR.js → chunk-FBZ7U3ID.js} +140 -92
- package/dist/chunk-FN52B75D.js +246 -0
- package/dist/{chunk-5W2A3DRC.js → chunk-JJEYZ3DX.js} +5 -4
- package/dist/chunk-KPYQWGFQ.js +183 -0
- package/dist/{chunk-IUBRCBSY.js → chunk-KSNLMI7N.js} +14 -8
- package/dist/chunk-KYURMOQM.js +977 -0
- package/dist/{chunk-LX6U42O3.js → chunk-LNHFAF4X.js} +160 -58
- package/dist/{chunk-NKHKXPI4.js → chunk-MPY44PWB.js} +683 -627
- package/dist/{chunk-AHU7G2R5.js → chunk-NIU6DPQV.js} +10 -6
- package/dist/{chunk-HF6O3O37.js → chunk-RMLY6KB5.js} +1 -1
- package/dist/{chunk-6GLLNA6U.js → chunk-SACF5YSM.js} +1 -1
- package/dist/{chunk-EURB7QFZ.js → chunk-TFIPNIPE.js} +867 -534
- package/dist/{chunk-OJ4SKRSV.js → chunk-UZNAFKGW.js} +25 -5
- package/dist/chunk-W46INAVW.js +1216 -0
- package/dist/chunk-X5EAU5G7.js +793 -0
- package/dist/{chunk-T5CVK4R3.js → chunk-Y4PF6HIM.js} +110 -64
- package/dist/components.d.ts +8 -86
- package/dist/components.js +21 -55
- package/dist/{database.generated-CcnC_DRc.d.ts → database.generated-DT8JTZiP.d.ts} +12 -12
- package/dist/eslint-rules/rules/05-styling.cjs +507 -0
- package/dist/eslint-rules/rules/06-security-rbac.cjs +10 -0
- package/dist/{event-CW5YB_2p.d.ts → event-WTAQuGcq.d.ts} +1 -1
- package/dist/{functions-lBy5L2ry.d.ts → functions-DH45k8ec.d.ts} +1 -1
- package/dist/hooks.d.ts +12 -11
- package/dist/hooks.js +69 -44
- package/dist/index.d.ts +380 -32
- package/dist/index.js +46 -32
- package/dist/papaparseLoader-WG2UXQ22.js +7 -0
- package/dist/providers.d.ts +28 -14
- package/dist/providers.js +5 -5
- package/dist/rbac/eslint-rules.js +2 -2
- package/dist/rbac/index.d.ts +58 -214
- package/dist/rbac/index.js +11 -11
- package/dist/theming/runtime.d.ts +9 -3
- package/dist/theming/runtime.js +2 -2
- package/dist/{timezone-BZe_eUxx.d.ts → timezone-K-ptz3HO.d.ts} +22 -23
- package/dist/{types-t9H8qKRw.d.ts → types-BE2sEHKd.d.ts} +1 -1
- package/dist/{types-BeoeWV5I.d.ts → types-CvOPXWWZ.d.ts} +6 -5
- package/dist/{types-DXstZpNI.d.ts → types-D05dCGma.d.ts} +56 -149
- package/dist/types-Dr8sNhER.d.ts +50 -0
- package/dist/types.d.ts +5 -5
- package/dist/{PublicPageProvider-CIGSujI2.d.ts → usePublicPageContext-vxBlEHO9.d.ts} +294 -151
- package/dist/{usePublicRouteParams-MamNgwqe.d.ts → usePublicRouteParams-G3Ks53mk.d.ts} +8 -7
- package/dist/utils.d.ts +301 -137
- package/dist/utils.js +42 -41
- package/dist/{validation-643vUDZW.d.ts → validation-g5n0hDkh.d.ts} +2 -2
- package/docs/api/modules.md +542 -549
- package/docs/api-reference/components.md +5 -5
- package/docs/api-reference/rpc-functions.md +3 -3
- package/docs/implementation-guides/data-tables.md +256 -8
- package/docs/rbac/RBAC_CONTRACT.md +0 -12
- package/docs/standards/2-project-structure-standards.md +12 -74
- package/docs/standards/6-security-rbac-standards.md +222 -7
- package/docs/standards/7-api-tech-stack-standards.md +91 -3
- package/docs/testing/README.md +10 -0
- package/docs/testing/test-setup-for-consumers.md +914 -0
- package/eslint-config-pace-core.cjs +4 -0
- package/package.json +1 -1
- package/scripts/eslint-audit.cjs +110 -11
- package/src/__mocks__/lucide-react.ts +0 -2
- package/src/__tests__/helpers/__tests__/test-utils.test.tsx +0 -2
- package/src/__tests__/index.test.ts +532 -0
- package/src/__tests__/integration/UserProfile.test.tsx +1 -1
- package/src/__tests__/rbac/PagePermissionGuard.test.tsx +10 -8
- package/src/__tests__/rls-policies.test.ts +3 -2
- package/src/assets/app-icons/admin_favicon.svg +462 -0
- package/src/assets/app-icons/base_favicon.svg +85 -0
- package/src/assets/app-icons/cake_favicon.svg +68 -0
- package/src/assets/app-icons/core_favicon.svg +256 -0
- package/src/assets/app-icons/gear_favicon.svg +91 -0
- package/src/assets/app-icons/index.ts +83 -0
- package/src/assets/app-icons/medi_favicon.svg +92 -0
- package/src/assets/app-icons/mint_favicon.svg +83 -0
- package/src/assets/app-icons/pace_favicon.svg +49 -0
- package/src/assets/app-icons/pump_favicon.svg +68 -0
- package/src/assets/app-icons/seed_favicon.svg +91 -0
- package/src/assets/app-icons/team_favicon.svg +67 -0
- package/src/assets/app-icons/trac_favicon.svg +112 -0
- package/src/assets/app-icons/trip_favicon.svg +102 -0
- package/src/components/AddressField/AddressField.test.tsx +378 -3
- package/src/components/AddressField/AddressField.tsx +2 -2
- package/src/components/AddressField/types.ts +2 -2
- package/src/components/Alert/Alert.test.tsx +35 -25
- package/src/components/Alert/Alert.tsx +8 -8
- package/src/components/AppSwitcher/AppSwitcher.test.tsx +1250 -0
- package/src/components/AppSwitcher/AppSwitcher.tsx +315 -0
- package/src/components/Avatar/Avatar.test.tsx +11 -1
- package/src/components/Avatar/Avatar.tsx +3 -2
- package/src/components/Badge/Badge.test.tsx +11 -1
- package/src/components/Button/Button.test.tsx +13 -3
- package/src/components/Calendar/Calendar.test.tsx +523 -131
- package/src/components/Calendar/Calendar.tsx +107 -488
- package/src/components/Card/Card.test.tsx +220 -249
- package/src/components/Checkbox/Checkbox.test.tsx +58 -174
- package/src/components/ContextSelector/ContextSelector.tsx +3 -3
- package/src/components/ContextSelector/__tests__/ContextSelector.test.tsx +360 -0
- package/src/components/DataTable/DataTable.tsx +2 -2
- package/src/components/DataTable/__tests__/DataTable.comprehensive.test.tsx +1 -1
- package/src/components/DataTable/__tests__/DataTable.export.test.tsx +2 -2
- package/src/components/DataTable/__tests__/DataTable.grouping-aggregation.test.tsx +1 -1
- package/src/components/DataTable/__tests__/DataTable.select-label-display.test.tsx +485 -0
- package/src/components/DataTable/__tests__/DataTable.test.tsx +2 -2
- package/src/components/DataTable/__tests__/DataTableCore.test-setup.ts +1 -1
- package/src/components/DataTable/__tests__/DataTableCore.test.tsx +76 -580
- package/src/components/DataTable/__tests__/README.md +1 -1
- package/src/components/DataTable/__tests__/a11y.basic.test.tsx +1 -1
- package/src/components/DataTable/__tests__/keyboard.test.tsx +1 -1
- package/src/components/DataTable/__tests__/pagination.modes.test.tsx +1 -3
- package/src/components/DataTable/__tests__/ssr.strict-mode.test.tsx +0 -6
- package/src/components/DataTable/__tests__/test-utils/sharedTestUtils.tsx +14 -6
- package/src/components/DataTable/components/ActionButtons.tsx +9 -4
- package/src/components/DataTable/components/BulkOperationsDropdown.tsx +3 -3
- package/src/components/DataTable/components/ColumnFilter.tsx +2 -7
- package/src/components/DataTable/components/DataTableCore.tsx +44 -52
- package/src/components/DataTable/components/DataTableLayout.tsx +37 -26
- package/src/components/DataTable/components/DataTableModals.tsx +118 -30
- package/src/components/DataTable/components/DataTableToolbar.tsx +2 -2
- package/src/components/DataTable/components/EditFields.tsx +6 -47
- package/src/components/DataTable/components/EditableRow.tsx +8 -8
- package/src/components/DataTable/components/EmptyState.tsx +6 -3
- package/src/components/DataTable/components/FilterRow.tsx +18 -11
- package/src/components/DataTable/components/GroupingDropdown.tsx +0 -1
- package/src/components/DataTable/components/ImportModal.tsx +305 -133
- package/src/components/DataTable/components/LoadingState.tsx +2 -2
- package/src/components/DataTable/components/PaginationControls.tsx +0 -4
- package/src/components/DataTable/components/RowComponent.tsx +42 -22
- package/src/components/DataTable/components/UnifiedTableBody.tsx +52 -12
- package/src/components/DataTable/components/__tests__/AccessDeniedPage.test.tsx +51 -463
- package/src/components/DataTable/components/__tests__/ActionButtons.test.tsx +122 -116
- package/src/components/DataTable/components/__tests__/BulkOperationsDropdown.test.tsx +40 -68
- package/src/components/DataTable/components/__tests__/ColumnFilter.test.tsx +9 -137
- package/src/components/DataTable/components/__tests__/ColumnVisibilityDropdown.test.tsx +57 -17
- package/src/components/DataTable/components/__tests__/DataTableCore.test.tsx +792 -0
- package/src/components/DataTable/components/__tests__/DataTableErrorBoundary.test.tsx +24 -65
- package/src/components/DataTable/components/__tests__/DataTableLayout.test.tsx +467 -0
- package/src/components/DataTable/components/__tests__/DataTableModals.test.tsx +8 -125
- package/src/components/DataTable/components/__tests__/DataTableToolbar.test.tsx +528 -56
- package/src/components/DataTable/components/__tests__/EditFields.test.tsx +526 -0
- package/src/components/DataTable/components/__tests__/EditableRow.test.tsx +1 -68
- package/src/components/DataTable/components/__tests__/EmptyState.test.tsx +8 -25
- package/src/components/DataTable/components/__tests__/FilterRow.test.tsx +3 -62
- package/src/components/DataTable/components/__tests__/GroupingDropdown.test.tsx +9 -14
- package/src/components/DataTable/components/__tests__/ImportModal.test.tsx +50 -186
- package/src/components/DataTable/components/__tests__/LoadingState.test.tsx +39 -97
- package/src/components/DataTable/components/__tests__/PaginationControls.test.tsx +13 -103
- package/src/components/DataTable/components/__tests__/RowComponent.test.tsx +629 -0
- package/src/components/DataTable/components/__tests__/SortIndicator.test.tsx +135 -0
- package/src/components/DataTable/components/__tests__/UnifiedTableBody.test.tsx +31 -171
- package/src/components/DataTable/components/__tests__/cellValueUtils.test.ts +453 -0
- package/src/components/DataTable/components/hooks/useImportModalFocus.test.ts +184 -0
- package/src/components/DataTable/components/hooks/usePermissionTracking.test.ts +381 -0
- package/src/components/DataTable/context/DataTableContext.tsx +9 -10
- package/src/components/DataTable/context/__tests__/DataTableContext.test.tsx +12 -26
- package/src/components/DataTable/core/ColumnFactory.ts +3 -3
- package/src/components/DataTable/core/ColumnManager.ts +0 -1
- package/src/components/DataTable/core/DataManager.ts +4 -2
- package/src/components/DataTable/core/LocalDataAdapter.ts +1 -1
- package/src/components/DataTable/core/PluginRegistry.ts +2 -2
- package/src/components/DataTable/core/__tests__/ActionManager.test.ts +114 -2
- package/src/components/DataTable/core/__tests__/ColumnFactory.test.ts +103 -5
- package/src/components/DataTable/core/__tests__/ColumnManager.test.ts +57 -0
- package/src/components/DataTable/core/__tests__/DataManager.test.ts +63 -0
- package/src/components/DataTable/core/__tests__/LocalDataAdapter.test.ts +42 -9
- package/src/components/DataTable/core/__tests__/PluginRegistry.test.ts +29 -7
- package/src/components/DataTable/core/__tests__/StateManager.test.ts +58 -4
- package/src/components/DataTable/hooks/__tests__/useColumnOrderPersistence.test.ts +16 -21
- package/src/components/DataTable/hooks/__tests__/useColumnVisibilityPersistence.test.ts +93 -4
- package/src/components/DataTable/hooks/__tests__/useDataTableConfiguration.test.ts +227 -54
- package/src/components/DataTable/hooks/__tests__/useDataTableDataPipeline.test.ts +215 -62
- package/src/components/DataTable/hooks/__tests__/useDataTablePermissions.test.ts +217 -39
- package/src/components/DataTable/hooks/__tests__/useDataTableState.test.ts +101 -6
- package/src/components/DataTable/hooks/__tests__/useEffectiveColumnOrder.test.ts +157 -27
- package/src/components/DataTable/hooks/__tests__/useHierarchicalState.test.ts +80 -0
- package/src/components/DataTable/hooks/__tests__/useKeyboardNavigation.test.ts +787 -0
- package/src/components/DataTable/hooks/__tests__/useServerSideDataEffect.test.ts +258 -0
- package/src/components/DataTable/hooks/__tests__/useTableColumns.test.ts +298 -23
- package/src/components/DataTable/hooks/__tests__/useTableHandlers.test.ts +440 -0
- package/src/components/DataTable/hooks/useColumnOrderPersistence.ts +12 -9
- package/src/components/DataTable/hooks/useColumnVisibilityPersistence.ts +12 -9
- package/src/components/DataTable/hooks/useDataTableConfiguration.ts +1 -1
- package/src/components/DataTable/hooks/useDataTablePermissions.ts +11 -22
- package/src/components/DataTable/hooks/useDataTableState.ts +20 -24
- package/src/components/DataTable/hooks/useKeyboardNavigation.ts +5 -5
- package/src/components/DataTable/hooks/useServerSideDataEffect.ts +13 -1
- package/src/components/DataTable/hooks/useTableColumns.ts +36 -38
- package/src/components/DataTable/hooks/useTableHandlers.ts +8 -20
- package/src/components/DataTable/index.ts +24 -2
- package/src/components/DataTable/types.ts +6 -3
- package/src/components/DataTable/utils/__tests__/a11yUtils.test.ts +3 -67
- package/src/components/DataTable/utils/__tests__/aggregationUtils.test.ts +288 -0
- package/src/components/DataTable/utils/__tests__/errorHandling.test.ts +3 -60
- package/src/components/DataTable/utils/__tests__/flexibleImport.test.ts +1 -1
- package/src/components/DataTable/utils/__tests__/hierarchicalSorting.test.ts +9 -21
- package/src/components/DataTable/utils/__tests__/hierarchicalUtils.test.ts +102 -86
- package/src/components/DataTable/utils/__tests__/paginationUtils.test.ts +593 -0
- package/src/components/DataTable/utils/__tests__/rowUtils.test.ts +33 -49
- package/src/components/DataTable/utils/__tests__/selectFieldUtils.test.ts +208 -0
- package/src/components/DataTable/utils/a11yUtils.ts +1 -1
- package/src/components/DataTable/utils/aggregationUtils.ts +5 -5
- package/src/components/DataTable/utils/errorHandling.ts +3 -1
- package/src/components/DataTable/utils/exportUtils.ts +1 -1
- package/src/components/DataTable/utils/flexibleImport.ts +2 -2
- package/src/components/DataTable/utils/hierarchicalSorting.ts +3 -3
- package/src/components/DataTable/utils/paginationUtils.ts +1 -1
- package/src/components/DataTable/utils/performanceUtils.ts +1 -1
- package/src/components/DataTable/utils/selectFieldUtils.ts +127 -0
- package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.test.tsx +17 -24
- package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.tsx +1 -1
- package/src/components/DateTimeField/DateTimeField.test.tsx +2 -15
- package/src/components/DateTimeField/DateTimeField.tsx +1 -1
- package/src/components/Dialog/Dialog.test.tsx +2007 -407
- package/src/components/Dialog/Dialog.tsx +97 -192
- package/src/components/ErrorBoundary/ErrorBoundary.test.tsx +2 -62
- package/src/components/ErrorBoundary/ErrorBoundaryContext.context.ts +17 -0
- package/src/components/ErrorBoundary/ErrorBoundaryContext.tsx +2 -45
- package/src/components/ErrorBoundary/ErrorBoundaryContext.types.ts +41 -0
- package/src/components/ErrorBoundary/index.ts +3 -4
- package/src/components/ErrorBoundary/useErrorBoundaryContext.ts +20 -0
- package/src/components/FileDisplay/FileDisplay.test.tsx +454 -222
- package/src/components/FileDisplay/FileDisplay.tsx +14 -12
- package/src/components/FileDisplay/index.tsx +1 -1
- package/src/components/FileUpload/FileUpload.test.tsx +54 -18
- package/src/components/FileUpload/FileUpload.tsx +10 -7
- package/src/components/FileUpload/index.tsx +1 -1
- package/src/components/Footer/Footer.test.tsx +33 -114
- package/src/components/Form/Form.test.tsx +388 -68
- package/src/components/Form/Form.tsx +57 -42
- package/src/components/Header/Header.test.tsx +645 -154
- package/src/components/Header/Header.tsx +52 -43
- package/src/components/InactivityWarningModal/InactivityWarningModal.test.tsx +35 -76
- package/src/components/Input/Input.test.tsx +34 -120
- package/src/components/Label/Label.test.tsx +47 -46
- package/src/components/LoadingSpinner/LoadingSpinner.test.tsx +9 -12
- package/src/components/LoginForm/LoginForm.test.tsx +0 -1
- package/src/components/NavigationMenu/NavigationMenu.test.tsx +1399 -82
- package/src/components/NavigationMenu/NavigationMenu.tsx +2 -2
- package/src/components/NavigationMenu/__tests__/useNavigationFiltering.test.ts +1934 -0
- package/src/components/NavigationMenu/useNavigationFiltering.ts +5 -15
- package/src/components/PaceAppLayout/PaceAppLayout.edge-cases.test.tsx +1307 -0
- package/src/components/PaceAppLayout/PaceAppLayout.integration.test.tsx +47 -46
- package/src/components/PaceAppLayout/PaceAppLayout.performance.test.tsx +81 -38
- package/src/components/PaceAppLayout/PaceAppLayout.security.test.tsx +87 -66
- package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +245 -39
- package/src/components/PaceAppLayout/PaceAppLayout.tsx +14 -20
- package/src/components/PaceAppLayout/README.md +0 -9
- package/src/components/PaceAppLayout/test-setup.tsx +15 -9
- package/src/components/PaceLoginPage/PaceLoginPage.test.tsx +759 -3
- package/src/components/PaceLoginPage/PaceLoginPage.tsx +2 -3
- package/src/components/PasswordChange/PasswordChangeForm.test.tsx +1 -1
- package/src/components/Progress/Progress.test.tsx +127 -1
- package/src/components/ProtectedRoute/ProtectedRoute.test.tsx +1196 -4
- package/src/components/ProtectedRoute/ProtectedRoute.tsx +24 -6
- package/src/components/PublicLayout/PublicLayout.test.tsx +1435 -14
- package/src/components/PublicLayout/PublicPageContext.ts +28 -0
- package/src/components/PublicLayout/PublicPageLayout.tsx +6 -6
- package/src/components/PublicLayout/PublicPageProvider.tsx +2 -41
- package/src/components/PublicLayout/usePublicPageContext.ts +36 -0
- package/src/components/Select/Select.test.tsx +46 -9
- package/src/components/Select/Select.tsx +31 -24
- package/src/components/Select/__tests__/context.test.tsx +56 -0
- package/src/components/Select/hooks/__tests__/useSelectEvents.test.ts +279 -0
- package/src/components/Select/hooks/__tests__/useSelectSearch.test.tsx +295 -0
- package/src/components/Select/hooks/__tests__/useSelectState.test.ts +254 -0
- package/src/components/Select/hooks/useSelectState.ts +16 -16
- package/src/components/Select/types.ts +3 -0
- package/src/components/Select/utils/__tests__/text.test.tsx +104 -0
- package/src/components/SessionRestorationLoader/SessionRestorationLoader.test.tsx +28 -112
- package/src/components/Switch/Switch.test.tsx +57 -153
- package/src/components/Table/Table.test.tsx +47 -317
- package/src/components/Tabs/Tabs.tsx +3 -3
- package/src/components/Textarea/Textarea.test.tsx +11 -38
- package/src/components/Toast/Toast.test.tsx +78 -569
- package/src/components/Tooltip/Tooltip.test.tsx +4 -21
- package/src/components/UserMenu/UserMenu.test.tsx +1 -21
- package/src/components/UserMenu/UserMenu.tsx +3 -6
- package/src/components/__tests__/index.test.ts +346 -0
- package/src/components/index.ts +12 -1
- package/src/constants/__tests__/performance.test.ts +91 -0
- package/src/hooks/__tests__/ServiceHooks.test.tsx +239 -129
- package/src/hooks/__tests__/hooks.integration.test.tsx +4 -3
- package/src/hooks/__tests__/useApiFetch.unit.test.ts +1 -1
- package/src/hooks/__tests__/useAppConfig.unit.test.ts +88 -29
- package/src/hooks/__tests__/useComponentPerformance.unit.test.tsx +282 -98
- package/src/hooks/__tests__/useDataTablePerformance.unit.test.ts +53 -109
- package/src/hooks/__tests__/useDataTableState.test.ts +143 -49
- package/src/hooks/__tests__/useDebounce.unit.test.ts +94 -19
- package/src/hooks/__tests__/useEvents.unit.test.ts +100 -125
- package/src/hooks/__tests__/useFileDisplay.test.ts +540 -0
- package/src/hooks/__tests__/useFileDisplay.unit.test.ts +1 -4
- package/src/hooks/__tests__/useFileUrl.unit.test.ts +27 -247
- package/src/hooks/__tests__/useFileUrlCache.test.ts +246 -56
- package/src/hooks/__tests__/useFocusManagement.unit.test.ts +442 -68
- package/src/hooks/__tests__/useFocusTrap.unit.test.tsx +345 -560
- package/src/hooks/__tests__/useFormDialog.test.ts +51 -222
- package/src/hooks/__tests__/useInactivityTracker.unit.test.ts +1 -1
- package/src/hooks/__tests__/useKeyboardShortcuts.unit.test.ts +1 -4
- package/src/hooks/__tests__/useOrganisationPermissions.unit.test.tsx +0 -1
- package/src/hooks/__tests__/usePerformanceMonitor.unit.test.ts +1 -1
- package/src/hooks/__tests__/usePermissionCache.test.ts +506 -0
- package/src/hooks/__tests__/usePreventTabReload.test.ts +255 -36
- package/src/hooks/__tests__/usePublicEvent.simple.test.ts +17 -8
- package/src/hooks/__tests__/usePublicEvent.test.ts +16 -24
- package/src/hooks/__tests__/usePublicEvent.unit.test.ts +12 -4
- package/src/hooks/__tests__/usePublicFileDisplay.test.ts +3 -6
- package/src/hooks/__tests__/usePublicRouteParams.unit.test.ts +1 -2
- package/src/hooks/__tests__/useQueryCache.test.ts +313 -66
- package/src/hooks/__tests__/useSessionDraft.test.ts +496 -103
- package/src/hooks/__tests__/useSessionRestoration.unit.test.tsx +2 -2
- package/src/hooks/__tests__/useStorage.unit.test.ts +72 -102
- package/src/hooks/__tests__/useToast.test.ts +413 -0
- package/src/hooks/__tests__/useToast.unit.test.tsx +1 -1
- package/src/hooks/__tests__/useZodForm.unit.test.tsx +175 -21
- package/src/hooks/index.ts +13 -1
- package/src/hooks/public/usePublicEvent.test.ts +304 -0
- package/src/hooks/public/usePublicEvent.ts +11 -11
- package/src/hooks/public/usePublicEventLogo.test.ts +655 -120
- package/src/hooks/public/usePublicEventLogo.ts +2 -2
- package/src/hooks/public/usePublicFileDisplay.test.ts +723 -0
- package/src/hooks/public/usePublicFileDisplay.ts +79 -49
- package/src/hooks/public/usePublicRouteParams.test.ts +595 -0
- package/src/hooks/public/usePublicRouteParams.ts +2 -2
- package/src/hooks/services/useAuthService.ts +1 -1
- package/src/hooks/services/useEventService.ts +1 -1
- package/src/hooks/useAccessibleApps.test.ts +400 -0
- package/src/hooks/useAccessibleApps.ts +264 -0
- package/src/hooks/useAddressAutocomplete.test.ts +165 -42
- package/src/hooks/useAddressAutocomplete.ts +41 -28
- package/src/hooks/useAppConfig.ts +13 -3
- package/src/hooks/useDataTablePerformance.ts +13 -12
- package/src/hooks/useDataTableState.ts +5 -5
- package/src/hooks/useEventTheme.test.ts +66 -17
- package/src/hooks/useEventTheme.ts +1 -1
- package/src/hooks/useEvents.ts +8 -1
- package/src/hooks/useFileDisplay.ts +66 -33
- package/src/hooks/useFileReference.test.ts +365 -87
- package/src/hooks/useFileReference.ts +2 -6
- package/src/hooks/useFileUrlCache.ts +4 -1
- package/src/hooks/useFormDialog.ts +2 -2
- package/src/hooks/useInactivityTracker.ts +3 -3
- package/src/hooks/useOrganisationPermissions.test.ts +1 -2
- package/src/hooks/useOrganisationPermissions.ts +1 -4
- package/src/hooks/useOrganisationSecurity.test.ts +1 -30
- package/src/hooks/useOrganisationSecurity.ts +3 -3
- package/src/hooks/useOrganisations.ts +1 -1
- package/src/hooks/usePerformanceMonitor.ts +1 -1
- package/src/hooks/usePermissionCache.ts +2 -6
- package/src/hooks/useQueryCache.ts +7 -7
- package/src/hooks/useSessionDraft.ts +14 -11
- package/src/hooks/useSessionRestoration.ts +1 -1
- package/src/hooks/useStorage.ts +75 -40
- package/src/hooks/useToast.ts +2 -2
- package/src/hooks/useZodForm.ts +3 -3
- package/src/icons/__tests__/index.test.ts +133 -0
- package/src/icons/index.ts +1 -1
- package/src/index.ts +43 -4
- package/src/providers/OrganisationProvider.test.tsx +40 -0
- package/src/providers/OrganisationProvider.tsx +5 -5
- package/src/providers/UnifiedAuthProvider.smoke.test.tsx +7 -12
- package/src/providers/__tests__/AuthProvider.test.tsx +22 -91
- package/src/providers/__tests__/EventProvider.test.tsx +16 -80
- package/src/providers/__tests__/InactivityProvider.test.tsx +29 -173
- package/src/providers/__tests__/OrganisationProvider.test.tsx +4 -5
- package/src/providers/__tests__/OrganisationProvider.wrapper.test.tsx +591 -0
- package/src/providers/__tests__/ProviderLifecycle.test.tsx +80 -196
- package/src/providers/__tests__/UnifiedAuthProvider.test.tsx +40 -133
- package/src/providers/__tests__/index.test.ts +138 -0
- package/src/providers/services/AuthServiceContext.ts +27 -0
- package/src/providers/services/AuthServiceProvider.tsx +81 -20
- package/src/providers/services/EventServiceContext.ts +25 -0
- package/src/providers/services/EventServiceProvider.tsx +11 -20
- package/src/providers/services/InactivityServiceContext.ts +25 -0
- package/src/providers/services/InactivityServiceProvider.tsx +7 -17
- package/src/providers/services/OrganisationServiceContext.ts +25 -0
- package/src/providers/services/OrganisationServiceProvider.tsx +7 -17
- package/src/providers/services/UnifiedAuthContext.ts +99 -0
- package/src/providers/services/UnifiedAuthProvider.test.tsx +212 -0
- package/src/providers/services/UnifiedAuthProvider.tsx +38 -143
- package/src/providers/services/__tests__/AuthServiceProvider.integration.test.tsx +61 -95
- package/src/providers/services/__tests__/AuthServiceProvider.test.tsx +638 -0
- package/src/providers/services/__tests__/EventServiceProvider.test.tsx +839 -0
- package/src/providers/services/__tests__/InactivityServiceProvider.test.tsx +662 -0
- package/src/providers/services/__tests__/OrganisationServiceProvider.test.tsx +440 -0
- package/src/providers/services/__tests__/UnifiedAuthProvider.advanced.test.tsx +435 -0
- package/src/providers/services/__tests__/UnifiedAuthProvider.appId.test.tsx +408 -0
- package/src/providers/services/__tests__/UnifiedAuthProvider.integration.test.tsx +55 -48
- package/src/providers/services/__tests__/contexts.test.tsx +281 -0
- package/src/providers/services/__tests__/useUnifiedAuth.test.tsx +251 -0
- package/src/providers/services/useUnifiedAuth.ts +29 -0
- package/src/rbac/README.md +5 -5
- package/src/rbac/__tests__/adapters.comprehensive.test.tsx +9 -14
- package/src/rbac/__tests__/audit-batched.test.ts +550 -0
- package/src/rbac/__tests__/auth-rbac-security.integration.test.tsx +1 -14
- package/src/rbac/__tests__/auth-rbac.e2e.test.tsx +43 -12
- package/src/rbac/__tests__/cache-invalidation.test.ts +8 -14
- package/src/rbac/__tests__/engine.comprehensive.test.ts +2 -7
- package/src/rbac/__tests__/index.test.ts +107 -0
- package/src/rbac/__tests__/performance.test.ts +451 -0
- package/src/rbac/__tests__/rbac-core.test.tsx +2 -2
- package/src/rbac/__tests__/rbac-engine-core-logic.test.ts +0 -5
- package/src/rbac/__tests__/rbac-engine-simplified.test.ts +1 -7
- package/src/rbac/__tests__/rbac-functions.test.ts +0 -1
- package/src/rbac/__tests__/rbac-integration.test.ts +0 -1
- package/src/rbac/__tests__/scenarios.user-role.test.tsx +21 -32
- package/src/rbac/adapters.test.tsx +654 -0
- package/src/rbac/adapters.tsx +24 -9
- package/src/rbac/api.test.ts +13 -217
- package/src/rbac/api.ts +85 -16
- package/src/rbac/audit-batched.ts +5 -4
- package/src/rbac/audit.test.ts +225 -28
- package/src/rbac/audit.ts +22 -17
- package/src/rbac/cache-invalidation.ts +18 -15
- package/src/rbac/cache.test.ts +123 -63
- package/src/rbac/cache.ts +3 -4
- package/src/rbac/components/AccessDenied.tsx +20 -18
- package/src/rbac/components/NavigationGuard.tsx +10 -8
- package/src/rbac/components/PagePermissionGuard.tsx +27 -25
- package/src/rbac/components/__tests__/AccessDenied.test.tsx +324 -0
- package/src/rbac/components/__tests__/NavigationGuard.test.tsx +242 -71
- package/src/rbac/components/__tests__/PagePermissionGuard.performance.test.tsx +20 -37
- package/src/rbac/components/__tests__/PagePermissionGuard.race-condition.test.tsx +18 -17
- package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +452 -129
- package/src/rbac/components/__tests__/PagePermissionGuard.verification.test.tsx +14 -13
- package/src/rbac/config.test.ts +131 -48
- package/src/rbac/config.ts +11 -8
- package/src/rbac/docs/event-based-apps.md +26 -13
- package/src/rbac/engine.test.ts +496 -146
- package/src/rbac/engine.ts +53 -13
- package/src/rbac/errors.test.ts +99 -87
- package/src/rbac/eslint-rules.js +2 -2
- package/src/rbac/hooks/__tests__/usePermissions.integration.test.ts +0 -5
- package/src/rbac/hooks/__tests__/useSecureSupabase.test.ts +601 -1
- package/src/rbac/hooks/permissions/__tests__/useAccessLevel.test.ts +622 -0
- package/src/rbac/hooks/permissions/__tests__/useCan.test.ts +798 -0
- package/src/rbac/hooks/permissions/__tests__/useMultiplePermissions.test.ts +843 -0
- package/src/rbac/hooks/permissions/__tests__/usePermissions.test.ts +545 -0
- package/src/rbac/hooks/permissions/useAccessLevel.ts +7 -8
- package/src/rbac/hooks/permissions/useCan.ts +12 -10
- package/src/rbac/hooks/permissions/useMultiplePermissions.ts +57 -8
- package/src/rbac/hooks/permissions/usePermissions.ts +15 -14
- package/src/rbac/hooks/useCan.test.ts +319 -3
- package/src/rbac/hooks/usePermissions.test.ts +426 -0
- package/src/rbac/hooks/usePermissions.ts +5 -7
- package/src/rbac/hooks/useRBAC.test.ts +1669 -2
- package/src/rbac/hooks/useRBAC.ts +7 -11
- package/src/rbac/hooks/useResolvedScope.test.ts +442 -5
- package/src/rbac/hooks/useResolvedScope.ts +4 -1
- package/src/rbac/hooks/useResourcePermissions.test.ts +538 -1
- package/src/rbac/hooks/useResourcePermissions.ts +9 -7
- package/src/rbac/hooks/useRoleManagement.test.ts +659 -1
- package/src/rbac/hooks/useRoleManagement.ts +16 -12
- package/src/rbac/hooks/useSecureSupabase.ts +11 -12
- package/src/rbac/index.ts +32 -32
- package/src/rbac/permissions.test.ts +149 -68
- package/src/rbac/permissions.ts +0 -3
- package/src/rbac/request-deduplication.test.ts +347 -0
- package/src/rbac/secureClient.test.ts +112 -159
- package/src/rbac/secureClient.ts +46 -26
- package/src/rbac/security.test.ts +125 -44
- package/src/rbac/security.ts +7 -6
- package/src/rbac/types.test.ts +236 -0
- package/src/rbac/types.ts +7 -5
- package/src/rbac/utils/__tests__/clientSecurity.test.ts +192 -0
- package/src/rbac/utils/__tests__/contextValidator.test.ts +1 -3
- package/src/rbac/utils/__tests__/deep-equal.test.ts +23 -0
- package/src/rbac/utils/__tests__/eventContext.test.ts +10 -57
- package/src/rbac/utils/clientSecurity.ts +6 -4
- package/src/rbac/utils/contextValidator.ts +1 -2
- package/src/rbac/utils/eventContext.ts +2 -2
- package/src/services/AuthService.ts +13 -11
- package/src/services/EventService.ts +4 -5
- package/src/services/OrganisationService.ts +13 -30
- package/src/services/__tests__/AuthService.edge-cases.test.ts +746 -0
- package/src/services/__tests__/AuthService.restoreSession.test.ts +23 -3
- package/src/services/__tests__/AuthService.test.ts +4 -8
- package/src/services/__tests__/BaseService.edge-cases.test.ts +506 -0
- package/src/services/__tests__/BaseService.test.ts +49 -0
- package/src/services/__tests__/EventService.edge-cases.test.ts +633 -0
- package/src/services/__tests__/EventService.eventColours.test.ts +0 -12
- package/src/services/__tests__/EventService.test.ts +0 -7
- package/src/services/__tests__/InactivityService.edge-cases.test.ts +492 -0
- package/src/services/__tests__/InactivityService.lifecycle.test.ts +0 -5
- package/src/services/__tests__/OrganisationService.edge-cases.test.ts +633 -0
- package/src/services/base/BaseService.test.ts +214 -0
- package/src/services/interfaces/IOrganisationService.ts +0 -1
- package/src/services/interfaces/__tests__/IAuthService.test.ts +190 -0
- package/src/services/interfaces/__tests__/IEventService.test.ts +176 -0
- package/src/services/interfaces/__tests__/IInactivityService.test.ts +183 -0
- package/src/services/interfaces/__tests__/IOrganisationService.test.ts +207 -0
- package/src/styles/core.css +1 -0
- package/src/theming/__tests__/runtime.test.ts +29 -94
- package/src/theming/parseEventColours.ts +18 -9
- package/src/theming/runtime.ts +1 -5
- package/src/types/__tests__/core.test.ts +397 -0
- package/src/types/__tests__/database-generated.test.ts +78 -0
- package/src/types/__tests__/file-reference.test.ts +270 -366
- package/src/types/__tests__/guards.test.ts +26 -26
- package/src/types/__tests__/index.test.ts +265 -0
- package/src/types/__tests__/type-validation.test.ts +3 -3
- package/src/types/__tests__/validation.test.ts +0 -2
- package/src/types/auth.ts +0 -1
- package/src/types/database.generated.ts +9 -9
- package/src/types/event.ts +1 -1
- package/src/types/rpc-responses.ts +33 -0
- package/src/types/supabase.ts +1 -2
- package/src/types/vitest-globals.d.ts +1 -1
- package/src/utils/__tests__/bundleAnalysis.unit.test.ts +64 -77
- package/src/utils/__tests__/dynamicUtils.unit.test.ts +13 -0
- package/src/utils/__tests__/formatDate.unit.test.ts +1 -1
- package/src/utils/__tests__/lazyLoad.unit.test.tsx +0 -1
- package/src/utils/__tests__/logger.unit.test.ts +1 -1
- package/src/utils/__tests__/performanceBenchmark.test.ts +1 -2
- package/src/utils/__tests__/performanceBudgets.unit.test.ts +48 -13
- package/src/utils/__tests__/request-deduplication.test.ts +349 -0
- package/src/utils/__tests__/secureDataAccess.unit.test.ts +0 -1
- package/src/utils/__tests__/timezone.test.ts +1 -1
- package/src/utils/__tests__/validation.unit.test.ts +1 -2
- package/src/utils/__tests__/validationUtils.unit.test.ts +1 -1
- package/src/utils/app/appConfig.test.ts +235 -0
- package/src/utils/app/appIdResolver.test.ts +188 -20
- package/src/utils/app/appNameResolver.test.ts +18 -10
- package/src/utils/app/appNameResolver.ts +11 -9
- package/src/utils/app/appPortMap.test.ts +125 -0
- package/src/utils/app/appPortMap.ts +51 -0
- package/src/utils/app/buildAppUrl.test.ts +273 -0
- package/src/utils/app/buildAppUrl.ts +114 -0
- package/src/utils/audit/audit.test.ts +354 -39
- package/src/utils/context/organisationContext.test.ts +10 -4
- package/src/utils/context/organisationContext.ts +5 -5
- package/src/utils/context/sessionTracking.test.ts +354 -0
- package/src/utils/core/__tests__/cn.test.ts +66 -0
- package/src/utils/core/__tests__/debugLogger.test.ts +113 -0
- package/src/utils/core/__tests__/logger.test.ts +217 -0
- package/src/utils/core/debugLogger.ts +15 -8
- package/src/utils/core/logger.ts +20 -16
- package/src/utils/device/deviceFingerprint.test.ts +8 -5
- package/src/utils/device/deviceFingerprint.ts +3 -3
- package/src/utils/dynamic/__tests__/dynamicUtils.test.ts +185 -0
- package/src/utils/dynamic/__tests__/lazyLoad.test.tsx +156 -0
- package/src/utils/dynamic/createLazyComponent.tsx +38 -0
- package/src/utils/dynamic/dynamicUtils.ts +6 -6
- package/src/utils/dynamic/lazyLoad.tsx +8 -36
- package/src/utils/dynamic/papaparseLoader.ts +7 -0
- package/src/utils/file-reference/__tests__/file-reference.test.ts +583 -145
- package/src/utils/file-reference/index.ts +0 -1
- package/src/utils/formatting/formatDate.test.ts +22 -148
- package/src/utils/formatting/formatDateTime.test.ts +41 -119
- package/src/utils/formatting/formatDateTimeTimezone.test.ts +40 -84
- package/src/utils/formatting/formatNumber.test.ts +259 -0
- package/src/utils/formatting/formatTime.test.ts +36 -128
- package/src/utils/formatting/formatting.ts +1 -1
- package/src/utils/google-places/googlePlacesUtils.test.ts +72 -3
- package/src/utils/google-places/googlePlacesUtils.ts +15 -2
- package/src/utils/google-places/loadGoogleMapsScript.test.ts +58 -1
- package/src/utils/google-places/loadGoogleMapsScript.ts +2 -1
- package/src/utils/index.ts +52 -11
- package/src/utils/location/location.test.ts +18 -115
- package/src/utils/performance/__tests__/bundleAnalysis.test.ts +148 -0
- package/src/utils/performance/__tests__/performanceBenchmark.test.ts +251 -0
- package/src/utils/performance/__tests__/performanceBudgets.test.ts +241 -0
- package/src/utils/performance/bundleAnalysis.ts +16 -22
- package/src/utils/performance/performanceBenchmark.ts +12 -4
- package/src/utils/performance/performanceBudgets.ts +9 -6
- package/src/utils/permissions/__tests__/permissionTypes.test.ts +149 -0
- package/src/utils/permissions/permissionUtils.test.ts +20 -42
- package/src/utils/persistence/__tests__/keyDerivation.test.ts +180 -9
- package/src/utils/persistence/__tests__/sensitiveFieldDetection.test.ts +164 -16
- package/src/utils/persistence/sensitiveFieldDetection.ts +2 -2
- package/src/utils/request-deduplication.ts +6 -4
- package/src/utils/security/auth-utils.ts +7 -7
- package/src/utils/security/secureDataAccess.test.ts +22 -191
- package/src/utils/security/secureErrors.test.ts +163 -0
- package/src/utils/security/secureStorage.test.ts +156 -0
- package/src/utils/security/secureStorage.ts +1 -1
- package/src/utils/security/security.test.ts +204 -0
- package/src/utils/security/securityMonitor.test.ts +90 -0
- package/src/utils/security/securityMonitor.ts +1 -1
- package/src/utils/storage/__tests__/config.unit.test.ts +239 -0
- package/src/utils/storage/__tests__/index.unit.test.ts +64 -12
- package/src/utils/storage/helpers.test.ts +757 -430
- package/src/utils/storage/helpers.ts +1 -2
- package/src/utils/storage/{index.ts → storageUtils.ts} +1 -36
- package/src/utils/storage/types.ts +2 -2
- package/src/utils/supabase/createBaseClient.test.ts +201 -0
- package/src/utils/supabase/createBaseClient.ts +27 -8
- package/src/utils/timezone/timezone.test.ts +25 -43
- package/src/utils/validation/__tests__/common.test.ts +115 -0
- package/src/utils/validation/__tests__/csrf.test.ts +65 -0
- package/src/utils/validation/__tests__/htmlSanitization.unit.test.ts +27 -7
- package/src/utils/validation/__tests__/passwordSchema.test.ts +164 -0
- package/src/utils/validation/__tests__/schema.test.ts +127 -0
- package/src/utils/validation/__tests__/sqlInjectionProtection.test.ts +76 -3
- package/src/utils/validation/__tests__/user.test.ts +173 -0
- package/src/utils/validation/__tests__/validation.test.ts +197 -0
- package/src/utils/validation/__tests__/validationUtils.test.ts +265 -43
- package/src/utils/validation/htmlSanitization.ts +27 -31
- package/src/utils/validation/schema.ts +6 -3
- package/src/utils/validation/sqlInjectionProtection.ts +2 -2
- package/src/vite-env.d.ts +6 -0
- package/dist/DataTable-DRUIgtUH.d.ts +0 -166
- package/dist/UnifiedAuthProvider-7SNDOWYD.js +0 -7
- package/dist/audit-MYQXYZFU.js +0 -3
- package/dist/chunk-7ILTDCL2.js +0 -80
- package/dist/chunk-EF2UGZWY.js +0 -611
- package/dist/chunk-FEJLJNWA.js +0 -181
- package/dist/chunk-GS5672WG.js +0 -2003
- package/dist/chunk-S6ZQKDY6.js +0 -62
- package/dist/chunk-Z2FNRKF3.js +0 -994
- package/dist/useToast-AyaT-x7p.d.ts +0 -68
- package/src/components/DataTable/components/index.ts +0 -16
- package/src/components/DataTable/core/index.ts +0 -1
- package/src/components/DataTable/hooks/index.ts +0 -13
- package/src/components/DataTable/utils/index.ts +0 -9
- package/src/components/PublicLayout/index.ts +0 -32
- package/src/hooks/__tests__/usePermissionCache.simple.test.ts +0 -192
- package/src/hooks/__tests__/usePermissionCache.unit.test.ts +0 -741
- package/src/hooks/public/index.ts +0 -36
- package/src/hooks/usePermissionCache.test.ts +0 -536
- package/src/rbac/__tests__/isSuperAdmin.real.test.ts +0 -82
- package/src/rbac/audit-enhanced.ts +0 -384
- package/src/rbac/compliance/database-validator.ts +0 -165
- package/src/rbac/compliance/index.ts +0 -48
- package/src/rbac/compliance/pattern-detector.ts +0 -553
- package/src/rbac/compliance/quick-fix-suggestions.ts +0 -209
- package/src/rbac/compliance/runtime-compliance.ts +0 -99
- package/src/rbac/compliance/setup-validator.ts +0 -131
- package/src/rbac/components/index.ts +0 -26
- package/src/rbac/hooks/index.ts +0 -34
- package/src/rbac/hooks/permissions/index.ts +0 -4
- package/src/rbac/hooks/useRBAC.simple.test.ts +0 -95
- package/src/rbac/utils/__tests__/eventContext.unit.test.ts +0 -490
- package/src/utils/app/appNameResolver.simple.test.ts +0 -212
- package/src/utils/google-places/index.ts +0 -26
- package/src/utils/location/index.ts +0 -16
- package/src/utils/storage/__tests__/helpers.unit.test.ts +0 -332
- package/src/utils/timezone/index.ts +0 -17
- package/src/utils/validation/index.ts +0 -73
|
@@ -74,7 +74,7 @@ The `DataTable.regressionFixes.test.tsx` file documents specific fixes:
|
|
|
74
74
|
|
|
75
75
|
- **Action Button Icons and Behavior (4 tests)**
|
|
76
76
|
- Pencil icons for Edit buttons
|
|
77
|
-
-
|
|
77
|
+
- Trash2 icons for Delete buttons
|
|
78
78
|
- Correct edit mode entry behavior
|
|
79
79
|
- Immediate delete handler execution
|
|
80
80
|
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import React from 'react';
|
|
12
|
-
import { render, screen,
|
|
12
|
+
import { render, screen, waitFor, within } from '@testing-library/react';
|
|
13
13
|
import { axe, toHaveNoViolations } from 'jest-axe';
|
|
14
14
|
import userEvent from '@testing-library/user-event';
|
|
15
15
|
import { vi, beforeEach, afterEach } from 'vitest';
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import React from 'react';
|
|
12
|
-
import { render, screen,
|
|
12
|
+
import { render, screen, waitFor, within } from '@testing-library/react';
|
|
13
13
|
import userEvent from '@testing-library/user-event';
|
|
14
14
|
import { vi, beforeEach, afterEach } from 'vitest';
|
|
15
15
|
import { DataTable } from '../DataTable';
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import React from 'react';
|
|
12
|
-
import { render, screen,
|
|
12
|
+
import { render, screen, act, waitFor } from '@testing-library/react';
|
|
13
13
|
import userEvent from '@testing-library/user-event';
|
|
14
14
|
import { vi, describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
15
15
|
import { DataTable } from '../DataTable';
|
|
@@ -337,7 +337,6 @@ describe('getPaginationBinding', () => {
|
|
|
337
337
|
|
|
338
338
|
describe('DataTable Pagination Integration', () => {
|
|
339
339
|
const smallDataset = generateTestData(25);
|
|
340
|
-
const largeDataset = generateTestData(100);
|
|
341
340
|
|
|
342
341
|
describe('Client Mode Integration', () => {
|
|
343
342
|
it('should render pagination controls for client mode', async () => {
|
|
@@ -449,7 +448,6 @@ describe('DataTable Pagination Integration', () => {
|
|
|
449
448
|
|
|
450
449
|
describe('Server Mode Integration', () => {
|
|
451
450
|
it('should validate server mode configuration', () => {
|
|
452
|
-
const mockFetchData = vi.fn();
|
|
453
451
|
const mockOnPageChange = vi.fn();
|
|
454
452
|
const mockOnPageSizeChange = vi.fn();
|
|
455
453
|
|
|
@@ -197,14 +197,8 @@ describe('DataTable SSR and Strict Mode Compatibility', () => {
|
|
|
197
197
|
if (!window.location) {
|
|
198
198
|
(window as any).location = { reload: () => {} } as any;
|
|
199
199
|
}
|
|
200
|
-
const originalReload = window.location.reload?.bind(window.location);
|
|
201
200
|
const mockReload = vi.fn();
|
|
202
201
|
// Some environments have readonly location.reload; simulate guard by calling through a wrapper
|
|
203
|
-
const callReloadSafely = () => {
|
|
204
|
-
try {
|
|
205
|
-
window.location.reload();
|
|
206
|
-
} catch {}
|
|
207
|
-
};
|
|
208
202
|
|
|
209
203
|
// Render a minimal access denied UI that does not invoke reload
|
|
210
204
|
const AccessDeniedStub = () => <div>Access Denied</div>;
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* Shared utilities and helpers for DataTable tests to reduce duplication
|
|
9
9
|
* and provide consistent testing patterns across the test suite.
|
|
10
10
|
*/
|
|
11
|
-
import type {
|
|
11
|
+
import type { DataTableAction, DataTableFeatureConfig } from '../../types';
|
|
12
12
|
// AccessLevel removed - use AccessLevel type from rbac/types.ts if needed
|
|
13
13
|
import '@testing-library/jest-dom';
|
|
14
14
|
import React from 'react';
|
|
@@ -123,7 +123,7 @@ export const createTanStackTableModuleMock = (tableMock: any = {}) => ({
|
|
|
123
123
|
getPaginationRowModel: vi.fn(),
|
|
124
124
|
getGroupedRowModel: vi.fn(),
|
|
125
125
|
getExpandedRowModel: vi.fn(),
|
|
126
|
-
flexRender: vi.fn((
|
|
126
|
+
flexRender: vi.fn((_component: unknown, _props: unknown) => 'Mocked Cell'),
|
|
127
127
|
createColumnHelper: vi.fn(),
|
|
128
128
|
});
|
|
129
129
|
|
|
@@ -132,23 +132,31 @@ export const createTanStackTableModuleMock = (tableMock: any = {}) => ({
|
|
|
132
132
|
*/
|
|
133
133
|
export const createPerformanceUtilsMock = () => ({
|
|
134
134
|
DataChunkManager: class MockDataChunkManager {
|
|
135
|
-
constructor(
|
|
135
|
+
constructor(_config: unknown) {
|
|
136
|
+
// Mock constructor - config parameter kept for API compatibility
|
|
137
|
+
}
|
|
136
138
|
getChunk = vi.fn(() => [])
|
|
137
139
|
getMemoryUsage = vi.fn(() => 5)
|
|
138
140
|
clear = vi.fn()
|
|
139
141
|
},
|
|
140
142
|
SearchIndex: class MockSearchIndex {
|
|
141
|
-
constructor(
|
|
143
|
+
constructor(_config: unknown) {
|
|
144
|
+
// Mock constructor - config parameter kept for API compatibility
|
|
145
|
+
}
|
|
142
146
|
buildIndex = vi.fn()
|
|
143
147
|
search = vi.fn(() => [{ id: '1', name: 'Test User' }])
|
|
144
148
|
},
|
|
145
149
|
PerformanceMonitor: class MockPerformanceMonitor {
|
|
146
|
-
constructor() {
|
|
150
|
+
constructor() {
|
|
151
|
+
// Mock constructor - no initialization needed
|
|
152
|
+
}
|
|
147
153
|
startRender = vi.fn()
|
|
148
154
|
endRender = vi.fn()
|
|
149
155
|
},
|
|
150
156
|
VisibilityTracker: class MockVisibilityTracker {
|
|
151
|
-
constructor() {
|
|
157
|
+
constructor() {
|
|
158
|
+
// Mock constructor - no initialization needed
|
|
159
|
+
}
|
|
152
160
|
observe = vi.fn()
|
|
153
161
|
unobserve = vi.fn()
|
|
154
162
|
disconnect = vi.fn()
|
|
@@ -97,7 +97,7 @@ function ActionButtonsComponent<TData extends DataRecord = DataRecord>({
|
|
|
97
97
|
return null;
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
-
const renderAction = (action: DataTableAction<TData>,
|
|
100
|
+
const renderAction = (action: DataTableAction<TData>, _actionIndex: number) => {
|
|
101
101
|
let Icon = action.icon;
|
|
102
102
|
let label = action.label;
|
|
103
103
|
|
|
@@ -124,11 +124,12 @@ function ActionButtonsComponent<TData extends DataRecord = DataRecord>({
|
|
|
124
124
|
{visibleActions.map((action, actionIndex) => {
|
|
125
125
|
const { Icon, label } = renderAction(action, actionIndex);
|
|
126
126
|
const isDisabled = evaluateCondition(action.disabled, rowData, false);
|
|
127
|
+
const hasIcon = Boolean(Icon);
|
|
127
128
|
|
|
128
129
|
return (
|
|
129
130
|
<Button
|
|
130
131
|
key={actionIndex}
|
|
131
|
-
variant={action.variant
|
|
132
|
+
variant={action.variant || 'ghost'}
|
|
132
133
|
size="sm"
|
|
133
134
|
onClick={() => {
|
|
134
135
|
if (!isDisabled) {
|
|
@@ -139,9 +140,13 @@ function ActionButtonsComponent<TData extends DataRecord = DataRecord>({
|
|
|
139
140
|
aria-disabled={isDisabled}
|
|
140
141
|
data-testid={action.testId}
|
|
141
142
|
aria-label={label}
|
|
142
|
-
className="size-8 p-0"
|
|
143
|
+
className={hasIcon ? "size-8 p-0" : "h-8 px-2"}
|
|
143
144
|
>
|
|
144
|
-
{Icon
|
|
145
|
+
{Icon ? (
|
|
146
|
+
<Icon className="size-4" />
|
|
147
|
+
) : (
|
|
148
|
+
<span className="text-xs whitespace-nowrap">{label}</span>
|
|
149
|
+
)}
|
|
145
150
|
</Button>
|
|
146
151
|
);
|
|
147
152
|
})}
|
|
@@ -52,7 +52,7 @@ import { Button } from '../../Button/Button';
|
|
|
52
52
|
import {
|
|
53
53
|
MoreHorizontal,
|
|
54
54
|
Download,
|
|
55
|
-
|
|
55
|
+
Trash2
|
|
56
56
|
} from 'lucide-react';
|
|
57
57
|
|
|
58
58
|
/**
|
|
@@ -64,7 +64,7 @@ export interface BulkOperationsDropdownProps {
|
|
|
64
64
|
/** Currently selected rows */
|
|
65
65
|
selectedRows: Record<string, boolean>;
|
|
66
66
|
/** Handler for bulk operations */
|
|
67
|
-
onOperation?: (operation: string, selectedRows:
|
|
67
|
+
onOperation?: (operation: string, selectedRows: string[]) => void;
|
|
68
68
|
/** Custom class names */
|
|
69
69
|
className?: string;
|
|
70
70
|
}
|
|
@@ -93,7 +93,7 @@ export function BulkOperationsDropdown({
|
|
|
93
93
|
// Icon mapping for operations
|
|
94
94
|
const operationIcons = {
|
|
95
95
|
export: Download,
|
|
96
|
-
delete:
|
|
96
|
+
delete: Trash2,
|
|
97
97
|
};
|
|
98
98
|
|
|
99
99
|
// Label mapping for operations
|
|
@@ -4,12 +4,13 @@ import { Select, SelectTrigger, SelectValue, SelectContent, SelectItem } from '.
|
|
|
4
4
|
import type { Column } from '@tanstack/react-table';
|
|
5
5
|
import { getColumnHeaderText } from '../utils/columnUtils';
|
|
6
6
|
import { Filter } from 'lucide-react';
|
|
7
|
+
import type { DataRecord } from '../types';
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* Props for the ColumnFilter component.
|
|
10
11
|
*/
|
|
11
12
|
interface ColumnFilterProps {
|
|
12
|
-
column: Column<
|
|
13
|
+
column: Column<DataRecord, unknown>;
|
|
13
14
|
placeholder?: string;
|
|
14
15
|
filterType?: 'text' | 'select' | 'number' | 'date';
|
|
15
16
|
options?: Array<{ value: string; label: string }>;
|
|
@@ -43,12 +44,6 @@ export function ColumnFilter({
|
|
|
43
44
|
}
|
|
44
45
|
};
|
|
45
46
|
|
|
46
|
-
const clearFilter = () => {
|
|
47
|
-
column.setFilterValue(undefined);
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
const hasFilter = columnFilterValue !== undefined && columnFilterValue !== '';
|
|
51
|
-
|
|
52
47
|
// Get the default placeholder using column header text (for Input components)
|
|
53
48
|
const defaultPlaceholder = `Filter ${getColumnHeaderText(column)}...`;
|
|
54
49
|
// For Select components, use just the column name (icon will replace "Filter" text)
|
|
@@ -8,13 +8,10 @@
|
|
|
8
8
|
* This is the main component that consumers will use.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import React, { useMemo, useCallback, useEffect, useLayoutEffect, useRef, useState
|
|
12
|
-
import { useReactTable } from '@tanstack/react-table';
|
|
11
|
+
import React, { useMemo, useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react';
|
|
12
|
+
import { useReactTable, type SortingState } from '@tanstack/react-table';
|
|
13
13
|
import { useLocation } from 'react-router-dom';
|
|
14
|
-
import
|
|
15
|
-
SortingState,
|
|
16
|
-
} from '@tanstack/react-table';
|
|
17
|
-
import { Edit, Trash } from 'lucide-react';
|
|
14
|
+
import { Edit, Trash2 } from 'lucide-react';
|
|
18
15
|
import { useDataTablePerformance } from '../../../hooks/useDataTablePerformance';
|
|
19
16
|
import { LoadingState } from './LoadingState';
|
|
20
17
|
import { DataTableLayout } from './DataTableLayout';
|
|
@@ -25,10 +22,8 @@ import { useDataTableState } from '../hooks/useDataTableState';
|
|
|
25
22
|
import { useDataTableDataPipeline } from '../hooks/useDataTableDataPipeline';
|
|
26
23
|
import { useServerSideDataEffect } from '../hooks/useServerSideDataEffect';
|
|
27
24
|
import { useEffectiveColumnOrder } from '../hooks/useEffectiveColumnOrder';
|
|
28
|
-
import { useTableHandlers } from '../hooks/useTableHandlers';
|
|
25
|
+
import { useTableHandlers, type TableStateSnapshot } from '../hooks/useTableHandlers';
|
|
29
26
|
import { useDataTableConfiguration } from '../hooks/useDataTableConfiguration';
|
|
30
|
-
import type { TableStateSnapshot } from '../hooks/useTableHandlers';
|
|
31
|
-
import { ColumnFactory } from '../core/ColumnFactory';
|
|
32
27
|
import { AccessDeniedPage } from './AccessDeniedPage';
|
|
33
28
|
// NOTE: All toast() calls in this component use the default timeout (5 seconds).
|
|
34
29
|
// Do NOT set duration or timeout properties - let the toast system use its default.
|
|
@@ -44,23 +39,23 @@ import { usePermissionTracking } from './hooks/usePermissionTracking';
|
|
|
44
39
|
import { useImportModalFocus } from './hooks/useImportModalFocus';
|
|
45
40
|
import { toCellValueRecord } from './cellValueUtils';
|
|
46
41
|
|
|
47
|
-
import {
|
|
48
|
-
|
|
49
|
-
DataRecord,
|
|
50
|
-
GetRowId,
|
|
51
|
-
PerformanceConfig,
|
|
52
|
-
ServerSideConfig,
|
|
53
|
-
ChunkingConfig,
|
|
54
|
-
SearchIndexConfig,
|
|
55
|
-
PaginationMode,
|
|
56
|
-
EmptyStateConfig,
|
|
57
|
-
DataTableFeatureConfig,
|
|
58
|
-
NormalizedDataTableFeatureConfig,
|
|
59
|
-
DataTableColumn,
|
|
60
|
-
AggregateConfig,
|
|
61
|
-
DataTableAction,
|
|
62
|
-
HierarchicalConfig,
|
|
63
|
-
DataTableRBACConfig,
|
|
42
|
+
import {
|
|
43
|
+
normalizeDataTableFeatures,
|
|
44
|
+
type DataRecord,
|
|
45
|
+
type GetRowId,
|
|
46
|
+
type PerformanceConfig,
|
|
47
|
+
type ServerSideConfig,
|
|
48
|
+
type ChunkingConfig,
|
|
49
|
+
type SearchIndexConfig,
|
|
50
|
+
type PaginationMode,
|
|
51
|
+
type EmptyStateConfig,
|
|
52
|
+
type DataTableFeatureConfig,
|
|
53
|
+
type NormalizedDataTableFeatureConfig,
|
|
54
|
+
type DataTableColumn,
|
|
55
|
+
type AggregateConfig,
|
|
56
|
+
type DataTableAction,
|
|
57
|
+
type HierarchicalConfig,
|
|
58
|
+
type DataTableRBACConfig,
|
|
64
59
|
} from '../types';
|
|
65
60
|
import type { ImportModalConfig } from './ImportModal';
|
|
66
61
|
|
|
@@ -120,7 +115,7 @@ export interface DataTableCoreProps<TData extends DataRecord> {
|
|
|
120
115
|
// Utilities
|
|
121
116
|
getRowId?: GetRowId<TData>;
|
|
122
117
|
isLoading?: boolean;
|
|
123
|
-
emptyState?: EmptyStateConfig | React.ReactElement
|
|
118
|
+
emptyState?: EmptyStateConfig | React.ReactElement;
|
|
124
119
|
aggregates?: AggregateConfig[];
|
|
125
120
|
importModalConfig?: ImportModalConfig;
|
|
126
121
|
actions?: DataTableAction<TData>[];
|
|
@@ -129,6 +124,8 @@ export interface DataTableCoreProps<TData extends DataRecord> {
|
|
|
129
124
|
// Default state configuration
|
|
130
125
|
defaultGrouping?: string[];
|
|
131
126
|
defaultSorting?: SortingState;
|
|
127
|
+
/** Initial column visibility state - columns with value `false` will be hidden by default */
|
|
128
|
+
initialColumnVisibility?: Record<string, boolean>;
|
|
132
129
|
|
|
133
130
|
// Persistence configuration
|
|
134
131
|
storageKey?: string;
|
|
@@ -158,7 +155,7 @@ function DataTableInternal<TData extends DataRecord>(props: DataTableCoreProps<T
|
|
|
158
155
|
virtualHeight = 600,
|
|
159
156
|
enhancedPagination = false,
|
|
160
157
|
loadingComponent: LoadingComponent = LoadingState,
|
|
161
|
-
errorComponent:
|
|
158
|
+
errorComponent: _ErrorComponent,
|
|
162
159
|
initialPageSize = 10,
|
|
163
160
|
onEditRow,
|
|
164
161
|
onDeleteRow,
|
|
@@ -177,6 +174,7 @@ function DataTableInternal<TData extends DataRecord>(props: DataTableCoreProps<T
|
|
|
177
174
|
columnOrder: externalColumnOrder,
|
|
178
175
|
defaultGrouping,
|
|
179
176
|
defaultSorting,
|
|
177
|
+
initialColumnVisibility: initialColumnVisibilityProp,
|
|
180
178
|
storageKey,
|
|
181
179
|
onLayoutChange,
|
|
182
180
|
} = props;
|
|
@@ -242,11 +240,6 @@ function DataTableInternal<TData extends DataRecord>(props: DataTableCoreProps<T
|
|
|
242
240
|
useEffect(() => {
|
|
243
241
|
dataChangeCountRef.current += 1;
|
|
244
242
|
|
|
245
|
-
const previousLength = previousDataLengthRef.current;
|
|
246
|
-
const currentLength = data.length;
|
|
247
|
-
const snapshotLength = dataSnapshotRef.current.length;
|
|
248
|
-
const lengthDecreased = currentLength < previousLength;
|
|
249
|
-
|
|
250
243
|
// Data prop changed (logging removed for performance)
|
|
251
244
|
}, [data, isDeleting]);
|
|
252
245
|
|
|
@@ -304,18 +297,19 @@ function DataTableInternal<TData extends DataRecord>(props: DataTableCoreProps<T
|
|
|
304
297
|
updateColumnVisibility: updateSavedColumnVisibility,
|
|
305
298
|
} = useColumnVisibilityPersistence({
|
|
306
299
|
tableId: title ? `datatable-${title.toLowerCase().replace(/\s+/g, '-')}` : undefined,
|
|
307
|
-
defaultVisibility: {},
|
|
300
|
+
defaultVisibility: initialColumnVisibilityProp || {},
|
|
308
301
|
enablePersistence: secureFeatures.columnVisibility,
|
|
309
302
|
storageKey,
|
|
310
303
|
});
|
|
311
304
|
|
|
312
|
-
// Merge saved column visibility into initial state
|
|
305
|
+
// Merge saved column visibility into initial state (saved visibility takes precedence over prop)
|
|
313
306
|
const initialColumnVisibility = useMemo(() => {
|
|
314
307
|
if (secureFeatures.columnVisibility && savedColumnVisibility && Object.keys(savedColumnVisibility).length > 0) {
|
|
315
308
|
return savedColumnVisibility;
|
|
316
309
|
}
|
|
317
|
-
|
|
318
|
-
|
|
310
|
+
// Fall back to prop if no saved visibility
|
|
311
|
+
return initialColumnVisibilityProp || {};
|
|
312
|
+
}, [secureFeatures.columnVisibility, savedColumnVisibility, initialColumnVisibilityProp]);
|
|
319
313
|
|
|
320
314
|
// Get location for route-based key derivation
|
|
321
315
|
let location: { pathname: string } | null = null;
|
|
@@ -337,7 +331,7 @@ function DataTableInternal<TData extends DataRecord>(props: DataTableCoreProps<T
|
|
|
337
331
|
|
|
338
332
|
// Use the centralized state management hook for ALL table state
|
|
339
333
|
// Note: 'actions' prop parameter is shadowed by destructuring, so we rename to stateActions
|
|
340
|
-
const { state, actions: stateActions
|
|
334
|
+
const { state, actions: stateActions } = useDataTableState<TData>({
|
|
341
335
|
initialPageSize,
|
|
342
336
|
columnIds: effectiveColumnOrder,
|
|
343
337
|
initialRowSelection: selection || {},
|
|
@@ -386,9 +380,8 @@ function DataTableInternal<TData extends DataRecord>(props: DataTableCoreProps<T
|
|
|
386
380
|
}
|
|
387
381
|
}, [defaultGrouping, stateActions]);
|
|
388
382
|
|
|
389
|
-
// Extract commonly used state values
|
|
390
|
-
|
|
391
|
-
showImportModal, showFilterRow, isCreating, creationData, editingRowId, editingData } = state;
|
|
383
|
+
// Extract commonly used state values (only what's needed)
|
|
384
|
+
// Note: Most state values are accessed via state object directly when needed
|
|
392
385
|
|
|
393
386
|
// ============================================================================
|
|
394
387
|
// PERFORMANCE HOOK - ALWAYS call this hook
|
|
@@ -404,7 +397,6 @@ function DataTableInternal<TData extends DataRecord>(props: DataTableCoreProps<T
|
|
|
404
397
|
|
|
405
398
|
const {
|
|
406
399
|
paginationMode: detectedMode,
|
|
407
|
-
isVirtualized,
|
|
408
400
|
pageSizeOptions: optimizedPageSizeOptions,
|
|
409
401
|
isLoading: performanceLoading,
|
|
410
402
|
searchQuery,
|
|
@@ -461,11 +453,12 @@ function DataTableInternal<TData extends DataRecord>(props: DataTableCoreProps<T
|
|
|
461
453
|
|
|
462
454
|
// Cleanup deletion timeout on unmount
|
|
463
455
|
useEffect(() => {
|
|
456
|
+
const pendingDeletions = pendingDeletionsRef.current;
|
|
464
457
|
return () => {
|
|
465
458
|
if (deletionTimeoutRef.current) {
|
|
466
459
|
clearTimeout(deletionTimeoutRef.current);
|
|
467
460
|
}
|
|
468
|
-
|
|
461
|
+
pendingDeletions.clear();
|
|
469
462
|
};
|
|
470
463
|
}, []);
|
|
471
464
|
|
|
@@ -707,7 +700,7 @@ function DataTableInternal<TData extends DataRecord>(props: DataTableCoreProps<T
|
|
|
707
700
|
};
|
|
708
701
|
|
|
709
702
|
return handlers;
|
|
710
|
-
}, [permissions.canUpdate.can, permissions.canDelete.can, permissions.canCreate.can, permissions.canImport.can, permissions.canExport.can, wrappedOnEditRow, onDeleteRow, wrappedOnCreateRow, onImport, onExport, onDeleteSelected
|
|
703
|
+
}, [permissions.canUpdate.can, permissions.canDelete.can, permissions.canCreate.can, permissions.canImport.can, permissions.canExport.can, wrappedOnEditRow, onDeleteRow, wrappedOnCreateRow, onImport, onExport, onDeleteSelected]);
|
|
711
704
|
|
|
712
705
|
// MANDATORY: Process actions with RBAC checks
|
|
713
706
|
const effectiveActions = useMemo(() => {
|
|
@@ -771,11 +764,10 @@ function DataTableInternal<TData extends DataRecord>(props: DataTableCoreProps<T
|
|
|
771
764
|
|
|
772
765
|
try {
|
|
773
766
|
// Call the delete handler - this may update the parent's data prop
|
|
774
|
-
const
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
await result;
|
|
767
|
+
const result = secureHandlers.onDeleteRow!(row);
|
|
768
|
+
// Handle async operations (even though typed as void, handlers might return Promise)
|
|
769
|
+
if (result !== undefined && result !== null && typeof result === 'object' && 'then' in result && typeof (result as { then: unknown }).then === 'function') {
|
|
770
|
+
await (result as Promise<unknown>);
|
|
779
771
|
}
|
|
780
772
|
// Remove from pending deletions
|
|
781
773
|
pendingDeletionsRef.current.delete(rowId);
|
|
@@ -810,7 +802,7 @@ function DataTableInternal<TData extends DataRecord>(props: DataTableCoreProps<T
|
|
|
810
802
|
});
|
|
811
803
|
}
|
|
812
804
|
},
|
|
813
|
-
icon:
|
|
805
|
+
icon: Trash2,
|
|
814
806
|
testId: 'delete',
|
|
815
807
|
variant: 'destructive' as const,
|
|
816
808
|
hidden: !permissions.canDelete.can,
|
|
@@ -818,7 +810,7 @@ function DataTableInternal<TData extends DataRecord>(props: DataTableCoreProps<T
|
|
|
818
810
|
}
|
|
819
811
|
|
|
820
812
|
return result;
|
|
821
|
-
}, [actions, secureFeatures, permissions, secureHandlers, resolvedGetRowId, stateActions,
|
|
813
|
+
}, [actions, secureFeatures, permissions, secureHandlers, resolvedGetRowId, stateActions, data, isDeleting, logger]);
|
|
822
814
|
|
|
823
815
|
// Normalize columnOrder for useTableColumns: ensure 'select' is always first
|
|
824
816
|
const normalizedColumnOrderForColumns = useMemo(() => {
|
|
@@ -842,7 +834,7 @@ function DataTableInternal<TData extends DataRecord>(props: DataTableCoreProps<T
|
|
|
842
834
|
pageSize: effectivePageSize,
|
|
843
835
|
}), [state.pagination, effectivePageSize]);
|
|
844
836
|
|
|
845
|
-
const tableStateSnapshot = useMemo<TableStateSnapshot
|
|
837
|
+
const tableStateSnapshot = useMemo<TableStateSnapshot>(() => {
|
|
846
838
|
// Normalize columnOrder in snapshot: ensure 'select' is always first if selection is enabled
|
|
847
839
|
const normalizedColumnOrder = secureFeatures.selection && state.columnOrder.includes('select')
|
|
848
840
|
? ['select', ...state.columnOrder.filter(id => id !== 'select')]
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { Edit, Trash } from 'lucide-react';
|
|
3
2
|
import { SortIndicator } from './SortIndicator';
|
|
4
|
-
import type { Table } from '@tanstack/react-table';
|
|
3
|
+
import type { Table, Column } from '@tanstack/react-table';
|
|
5
4
|
import { cn } from '../../../utils/core/cn';
|
|
6
5
|
import { Button } from '../../Button/Button';
|
|
7
6
|
import { DataTableToolbar } from './DataTableToolbar';
|
|
@@ -21,17 +20,16 @@ import type {
|
|
|
21
20
|
DataTableRBACConfig,
|
|
22
21
|
EmptyStateConfig,
|
|
23
22
|
ExportOptions,
|
|
23
|
+
GetRowId,
|
|
24
24
|
HierarchicalConfig,
|
|
25
25
|
NormalizedDataTableFeatureConfig,
|
|
26
26
|
PaginationMode,
|
|
27
27
|
} from '../types';
|
|
28
28
|
import type { DataTableState, DataTableStateActions } from '../hooks/useDataTableState';
|
|
29
29
|
import type { UseDataTablePermissionsReturn } from '../hooks/useDataTablePermissions';
|
|
30
|
-
import type { GetRowId } from '../types';
|
|
31
30
|
import type { ImportModalConfig } from './ImportModal';
|
|
32
31
|
import type { UseDataTableDataPipelineResult } from '../hooks/useDataTableDataPipeline';
|
|
33
32
|
import type { UseKeyboardNavigationReturn } from '../hooks/useKeyboardNavigation';
|
|
34
|
-
import type { Column } from '@tanstack/react-table';
|
|
35
33
|
import type { createLogger } from '../../../utils/core/logger';
|
|
36
34
|
|
|
37
35
|
interface DataTableLayoutProps<TData extends DataRecord> {
|
|
@@ -45,8 +43,8 @@ interface DataTableLayoutProps<TData extends DataRecord> {
|
|
|
45
43
|
enhancedPagination: boolean;
|
|
46
44
|
searchQuery: string;
|
|
47
45
|
onSearch: (value: string) => void;
|
|
48
|
-
state: DataTableState
|
|
49
|
-
stateActions: DataTableStateActions
|
|
46
|
+
state: DataTableState;
|
|
47
|
+
stateActions: DataTableStateActions;
|
|
50
48
|
rowSelection: Record<string, boolean>;
|
|
51
49
|
onCreateRow?: (data: Partial<TData>) => void;
|
|
52
50
|
onEditRow?: (row: TData, data: Partial<TData>) => void;
|
|
@@ -64,7 +62,7 @@ interface DataTableLayoutProps<TData extends DataRecord> {
|
|
|
64
62
|
aggregates: AggregateConfig[];
|
|
65
63
|
resolvedGetRowId: GetRowId<TData>;
|
|
66
64
|
data: TData[];
|
|
67
|
-
emptyState?: EmptyStateConfig | React.ReactElement
|
|
65
|
+
emptyState?: EmptyStateConfig | React.ReactElement;
|
|
68
66
|
virtualHeight: number;
|
|
69
67
|
hierarchical?: HierarchicalConfig;
|
|
70
68
|
hierarchicalState: UseDataTableDataPipelineResult<TData>['hierarchicalState'];
|
|
@@ -109,8 +107,8 @@ export function DataTableLayout<TData extends DataRecord>({
|
|
|
109
107
|
onCreateRow,
|
|
110
108
|
onEditRow,
|
|
111
109
|
onImport,
|
|
112
|
-
onExport,
|
|
113
|
-
onDeleteSelected,
|
|
110
|
+
onExport: _onExport,
|
|
111
|
+
onDeleteSelected: _onDeleteSelected,
|
|
114
112
|
rbac,
|
|
115
113
|
permissions,
|
|
116
114
|
effectiveActions,
|
|
@@ -140,6 +138,10 @@ export function DataTableLayout<TData extends DataRecord>({
|
|
|
140
138
|
}, [state.editingData]);
|
|
141
139
|
const handleExport = async () => {
|
|
142
140
|
try {
|
|
141
|
+
// IMPORTANT: Use getFilteredRowModel() to get ALL filtered rows (not just current page)
|
|
142
|
+
// getFilteredRowModel() returns all filtered rows regardless of pagination
|
|
143
|
+
// This ensures exports include all data, not just the visible paginated rows
|
|
144
|
+
// Note: There is NO limit on the number of rows exported - all filtered rows are included
|
|
143
145
|
const tableRows = table.getFilteredRowModel().rows;
|
|
144
146
|
const tableColumns = table.getAllColumns();
|
|
145
147
|
const visibleTableColumns = tableColumns.filter((col) => !SYSTEM_COLUMN_IDS.has(col.id) && col.getIsVisible());
|
|
@@ -183,12 +185,13 @@ export function DataTableLayout<TData extends DataRecord>({
|
|
|
183
185
|
header?: string;
|
|
184
186
|
id?: string;
|
|
185
187
|
accessorKey?: string;
|
|
186
|
-
accessorFn?: (row:
|
|
188
|
+
accessorFn?: (row: TData) => unknown;
|
|
187
189
|
editAccessorKey?: string;
|
|
188
190
|
isIdColumn?: boolean;
|
|
189
191
|
}> = exportOptions.visibleColumns.map((col) => {
|
|
190
192
|
const colId = col.id || col.accessorKey;
|
|
191
|
-
|
|
193
|
+
// Check if col has accessorFn property directly (DataTableColumn) or in columnDef (Column)
|
|
194
|
+
const hasAccessorFn = 'accessorFn' in col && typeof (col as { accessorFn?: (row: TData) => unknown }).accessorFn === 'function';
|
|
192
195
|
|
|
193
196
|
return {
|
|
194
197
|
...col,
|
|
@@ -196,13 +199,20 @@ export function DataTableLayout<TData extends DataRecord>({
|
|
|
196
199
|
? col.header
|
|
197
200
|
: col.accessorKey || colId || 'Column',
|
|
198
201
|
id: colId ? String(colId) : undefined,
|
|
199
|
-
accessorFn: hasAccessorFn ? (col as
|
|
202
|
+
accessorFn: hasAccessorFn ? ((col as { accessorFn: (row: TData) => unknown }).accessorFn as (row: DataRecord) => unknown) : undefined,
|
|
200
203
|
};
|
|
201
204
|
});
|
|
202
205
|
|
|
203
206
|
await exportToCSVWithTableRows(
|
|
204
207
|
exportOptions.tableRows,
|
|
205
|
-
exportColumns
|
|
208
|
+
exportColumns as Array<{
|
|
209
|
+
header?: string;
|
|
210
|
+
id?: string;
|
|
211
|
+
accessorKey?: string;
|
|
212
|
+
accessorFn?: (row: DataRecord) => unknown;
|
|
213
|
+
editAccessorKey?: string;
|
|
214
|
+
isIdColumn?: boolean;
|
|
215
|
+
}>,
|
|
206
216
|
exportOptions.columnIdToTableColumn,
|
|
207
217
|
exportOptions.filename
|
|
208
218
|
);
|
|
@@ -286,9 +296,9 @@ export function DataTableLayout<TData extends DataRecord>({
|
|
|
286
296
|
return;
|
|
287
297
|
}
|
|
288
298
|
try {
|
|
289
|
-
const result = secureHandlers.onDeleteSelected!(selectedRows)
|
|
290
|
-
if (result !== undefined && result !== null && typeof result === 'object' && typeof result.then === 'function') {
|
|
291
|
-
await result;
|
|
299
|
+
const result = secureHandlers.onDeleteSelected!(selectedRows);
|
|
300
|
+
if (result !== undefined && result !== null && typeof result === 'object' && 'then' in result && typeof (result as { then: unknown }).then === 'function') {
|
|
301
|
+
await (result as Promise<unknown>);
|
|
292
302
|
}
|
|
293
303
|
// Clear selection after successful deletion
|
|
294
304
|
stateActions.clearRowSelection();
|
|
@@ -358,7 +368,7 @@ export function DataTableLayout<TData extends DataRecord>({
|
|
|
358
368
|
() => {
|
|
359
369
|
const originalHandler = header.column.getToggleSortingHandler();
|
|
360
370
|
if (originalHandler) {
|
|
361
|
-
originalHandler({}
|
|
371
|
+
originalHandler({});
|
|
362
372
|
}
|
|
363
373
|
|
|
364
374
|
const columnName =
|
|
@@ -477,7 +487,7 @@ export function DataTableLayout<TData extends DataRecord>({
|
|
|
477
487
|
grouping={state.grouping}
|
|
478
488
|
aggregates={aggregates}
|
|
479
489
|
getRowId={resolvedGetRowId}
|
|
480
|
-
emptyState={React.isValidElement(emptyState) ? undefined : (emptyState as
|
|
490
|
+
emptyState={React.isValidElement(emptyState) ? undefined : (emptyState as EmptyStateConfig)}
|
|
481
491
|
isFiltered={searchQuery !== '' || state.columnFilters.length > 0}
|
|
482
492
|
onClearFilters={() => {
|
|
483
493
|
onSearch('');
|
|
@@ -497,8 +507,14 @@ export function DataTableLayout<TData extends DataRecord>({
|
|
|
497
507
|
collapseAll: hierarchicalState.collapseAll,
|
|
498
508
|
isAllExpanded:
|
|
499
509
|
hierarchicalState.getExpandedIds().length > 0 &&
|
|
500
|
-
hierarchicalState.getExpandedIds().length ===
|
|
501
|
-
|
|
510
|
+
hierarchicalState.getExpandedIds().length === finalTableData.filter((row) => {
|
|
511
|
+
const hierarchicalRow = row as TData & { isParent?: boolean };
|
|
512
|
+
return hierarchicalRow.isParent === true;
|
|
513
|
+
}).length,
|
|
514
|
+
hasAnyChildren: finalTableData.some((row) => {
|
|
515
|
+
const hierarchicalRow = row as TData & { isParent?: boolean };
|
|
516
|
+
return hierarchicalRow.isParent === true;
|
|
517
|
+
}),
|
|
502
518
|
}
|
|
503
519
|
: undefined
|
|
504
520
|
}
|
|
@@ -534,12 +550,7 @@ export function DataTableLayout<TData extends DataRecord>({
|
|
|
534
550
|
if (result && typeof result.then === 'function') {
|
|
535
551
|
await result;
|
|
536
552
|
}
|
|
537
|
-
|
|
538
|
-
toast({
|
|
539
|
-
title: 'Import Successful',
|
|
540
|
-
description: `Successfully imported ${modalData.length} ${modalData.length === 1 ? 'row' : 'rows'}`,
|
|
541
|
-
variant: 'default',
|
|
542
|
-
});
|
|
553
|
+
// Toast notification removed - will be handled by parent component or ImportModal
|
|
543
554
|
} catch (error) {
|
|
544
555
|
logger.error('Import error:', error);
|
|
545
556
|
toast({
|