@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
|
@@ -33,10 +33,8 @@ export type { DataRecord, CellValue, RowId };
|
|
|
33
33
|
/**
|
|
34
34
|
* DataTable state interface.
|
|
35
35
|
* Contains all state for table operations including sorting, filtering, pagination, and editing.
|
|
36
|
-
*
|
|
37
|
-
* @template TData - The type of data records in the table
|
|
38
36
|
*/
|
|
39
|
-
export interface DataTableState
|
|
37
|
+
export interface DataTableState {
|
|
40
38
|
// Table state
|
|
41
39
|
sorting: SortingState;
|
|
42
40
|
columnFilters: ColumnFiltersState;
|
|
@@ -66,10 +64,8 @@ export interface DataTableState<TData extends DataRecord> {
|
|
|
66
64
|
/**
|
|
67
65
|
* Actions interface for DataTable state management.
|
|
68
66
|
* Provides functions to update all aspects of table state.
|
|
69
|
-
*
|
|
70
|
-
* @template TData - The type of data records in the table
|
|
71
67
|
*/
|
|
72
|
-
export interface DataTableStateActions
|
|
68
|
+
export interface DataTableStateActions {
|
|
73
69
|
setSorting: (sorting: SortingState) => void;
|
|
74
70
|
setColumnFilters: (filters: ColumnFiltersState) => void;
|
|
75
71
|
setColumnVisibility: (visibility: VisibilityState) => void;
|
|
@@ -91,7 +87,7 @@ export interface DataTableStateActions<TData extends DataRecord> {
|
|
|
91
87
|
setFilterRow: (show: boolean) => void;
|
|
92
88
|
setSearchQuery: (query: string) => void;
|
|
93
89
|
resetState: () => void;
|
|
94
|
-
initializeState: (partialState: Partial<DataTableState
|
|
90
|
+
initializeState: (partialState: Partial<DataTableState>) => void;
|
|
95
91
|
}
|
|
96
92
|
|
|
97
93
|
/**
|
|
@@ -111,7 +107,7 @@ export interface DataTableComputed {
|
|
|
111
107
|
// ACTION TYPES
|
|
112
108
|
// ============================================================================
|
|
113
109
|
|
|
114
|
-
export type DataTableAction
|
|
110
|
+
export type DataTableAction =
|
|
115
111
|
| { type: 'SET_SORTING'; payload: SortingState }
|
|
116
112
|
| { type: 'SET_COLUMN_FILTERS'; payload: ColumnFiltersState }
|
|
117
113
|
| { type: 'SET_COLUMN_VISIBILITY'; payload: VisibilityState }
|
|
@@ -131,7 +127,7 @@ export type DataTableAction<TData extends DataRecord> =
|
|
|
131
127
|
| { type: 'SET_FILTER_ROW'; payload: boolean }
|
|
132
128
|
| { type: 'SET_SEARCH_QUERY'; payload: string }
|
|
133
129
|
| { type: 'RESET_STATE' }
|
|
134
|
-
| { type: 'INITIALIZE_STATE'; payload: Partial<DataTableState
|
|
130
|
+
| { type: 'INITIALIZE_STATE'; payload: Partial<DataTableState> };
|
|
135
131
|
|
|
136
132
|
// ============================================================================
|
|
137
133
|
// REDUCER
|
|
@@ -146,10 +142,10 @@ export type DataTableAction<TData extends DataRecord> =
|
|
|
146
142
|
* @param action - Action to perform
|
|
147
143
|
* @returns New table state
|
|
148
144
|
*/
|
|
149
|
-
export function dataTableReducer
|
|
150
|
-
state: DataTableState
|
|
151
|
-
action: DataTableAction
|
|
152
|
-
): DataTableState
|
|
145
|
+
export function dataTableReducer(
|
|
146
|
+
state: DataTableState,
|
|
147
|
+
action: DataTableAction
|
|
148
|
+
): DataTableState {
|
|
153
149
|
switch (action.type) {
|
|
154
150
|
case 'SET_SORTING':
|
|
155
151
|
return { ...state, sorting: action.payload };
|
|
@@ -216,7 +212,7 @@ export function dataTableReducer<TData extends DataRecord>(
|
|
|
216
212
|
return { ...state, searchQuery: action.payload };
|
|
217
213
|
|
|
218
214
|
case 'RESET_STATE':
|
|
219
|
-
return createInitialState
|
|
215
|
+
return createInitialState();
|
|
220
216
|
|
|
221
217
|
case 'INITIALIZE_STATE':
|
|
222
218
|
return { ...state, ...action.payload };
|
|
@@ -230,12 +226,12 @@ export function dataTableReducer<TData extends DataRecord>(
|
|
|
230
226
|
// INITIAL STATE
|
|
231
227
|
// ============================================================================
|
|
232
228
|
|
|
233
|
-
export function createInitialState
|
|
229
|
+
export function createInitialState(
|
|
234
230
|
initialPageSize: number = 10,
|
|
235
231
|
columnIds: string[] = [],
|
|
236
232
|
defaultSorting?: SortingState,
|
|
237
233
|
defaultGrouping?: GroupingState
|
|
238
|
-
): DataTableState
|
|
234
|
+
): DataTableState {
|
|
239
235
|
return {
|
|
240
236
|
sorting: defaultSorting || [],
|
|
241
237
|
columnFilters: [],
|
|
@@ -262,7 +258,7 @@ export function createInitialState<TData extends DataRecord>(
|
|
|
262
258
|
// HOOK
|
|
263
259
|
// ============================================================================
|
|
264
260
|
|
|
265
|
-
export interface UseDataTableStateOptions
|
|
261
|
+
export interface UseDataTableStateOptions {
|
|
266
262
|
initialPageSize?: number;
|
|
267
263
|
columnIds?: string[];
|
|
268
264
|
initialRowSelection?: Record<string, boolean>;
|
|
@@ -276,7 +272,7 @@ export interface UseDataTableStateOptions<TData extends DataRecord> {
|
|
|
276
272
|
columnFieldNames?: string[]; // Field names for sensitive field filtering
|
|
277
273
|
}
|
|
278
274
|
|
|
279
|
-
export function useDataTableState<
|
|
275
|
+
export function useDataTableState<_TData extends DataRecord = DataRecord>({
|
|
280
276
|
initialPageSize = 10,
|
|
281
277
|
columnIds = [],
|
|
282
278
|
initialRowSelection = {},
|
|
@@ -287,7 +283,7 @@ export function useDataTableState<TData extends DataRecord>({
|
|
|
287
283
|
title,
|
|
288
284
|
location,
|
|
289
285
|
columnFieldNames = [],
|
|
290
|
-
}: UseDataTableStateOptions
|
|
286
|
+
}: UseDataTableStateOptions = {}) {
|
|
291
287
|
|
|
292
288
|
// Call all hooks unconditionally at the top level
|
|
293
289
|
// Hooks must be called in the same order on every render
|
|
@@ -310,12 +306,12 @@ export function useDataTableState<TData extends DataRecord>({
|
|
|
310
306
|
|
|
311
307
|
// Create initial state
|
|
312
308
|
const baseInitialState = useMemo(() =>
|
|
313
|
-
createInitialState
|
|
309
|
+
createInitialState(initialPageSize, columnIds, defaultSorting, defaultGrouping),
|
|
314
310
|
[initialPageSize, columnIds, defaultSorting, defaultGrouping]
|
|
315
311
|
);
|
|
316
312
|
|
|
317
313
|
// Define state subset to persist (excluding sensitive fields from editing/creation data)
|
|
318
|
-
type PersistedState = Omit<DataTableState
|
|
314
|
+
type PersistedState = Omit<DataTableState, 'editingData' | 'creationData'> & {
|
|
319
315
|
editingData: Partial<Record<string, CellValue>>;
|
|
320
316
|
creationData: Partial<Record<string, CellValue>>;
|
|
321
317
|
};
|
|
@@ -353,13 +349,13 @@ export function useDataTableState<TData extends DataRecord>({
|
|
|
353
349
|
};
|
|
354
350
|
}, [baseInitialState, persistedState, initialRowSelection, persistenceKey]);
|
|
355
351
|
|
|
356
|
-
const [state, dispatch] = useReducer(dataTableReducer
|
|
352
|
+
const [state, dispatch] = useReducer(dataTableReducer, initialState);
|
|
357
353
|
|
|
358
354
|
// ============================================================================
|
|
359
355
|
// ACTION CREATORS
|
|
360
356
|
// ============================================================================
|
|
361
357
|
|
|
362
|
-
const actions = useMemo<DataTableStateActions
|
|
358
|
+
const actions = useMemo<DataTableStateActions>(() => ({
|
|
363
359
|
setSorting: (sorting: SortingState) =>
|
|
364
360
|
dispatch({ type: 'SET_SORTING', payload: sorting }),
|
|
365
361
|
|
|
@@ -425,7 +421,7 @@ export function useDataTableState<TData extends DataRecord>({
|
|
|
425
421
|
resetState: () =>
|
|
426
422
|
dispatch({ type: 'RESET_STATE' }),
|
|
427
423
|
|
|
428
|
-
initializeState: (partialState: Partial<DataTableState
|
|
424
|
+
initializeState: (partialState: Partial<DataTableState>) =>
|
|
429
425
|
dispatch({ type: 'INITIALIZE_STATE', payload: partialState })
|
|
430
426
|
}), [state.rowSelection, onRowSelectionChange]);
|
|
431
427
|
|
|
@@ -120,7 +120,7 @@ export function useKeyboardNavigation(
|
|
|
120
120
|
|
|
121
121
|
const cells = row.querySelectorAll('td[role="cell"], th[role="columnheader"]');
|
|
122
122
|
return cells[columnIndex] as HTMLElement || null;
|
|
123
|
-
}, []);
|
|
123
|
+
}, [tableRef]);
|
|
124
124
|
|
|
125
125
|
// Helper to get header element
|
|
126
126
|
const getHeaderElement = useCallback((columnIndex: number): HTMLElement | null => {
|
|
@@ -134,7 +134,7 @@ export function useKeyboardNavigation(
|
|
|
134
134
|
|
|
135
135
|
const headers = headerRow.querySelectorAll('th[role="columnheader"]');
|
|
136
136
|
return headers[columnIndex] as HTMLElement || null;
|
|
137
|
-
}, []);
|
|
137
|
+
}, [tableRef]);
|
|
138
138
|
|
|
139
139
|
// Focus a specific cell
|
|
140
140
|
const focusCell = useCallback((rowIndex: number, columnIndex: number) => {
|
|
@@ -295,7 +295,7 @@ export function useKeyboardNavigation(
|
|
|
295
295
|
}
|
|
296
296
|
};
|
|
297
297
|
|
|
298
|
-
const onFocus = (
|
|
298
|
+
const onFocus = (_event: React.FocusEvent) => {
|
|
299
299
|
setState(prev => ({
|
|
300
300
|
...prev,
|
|
301
301
|
focusedRowIndex: rowIndex,
|
|
@@ -306,7 +306,7 @@ export function useKeyboardNavigation(
|
|
|
306
306
|
onFocusChange?.(rowIndex, columnIndex);
|
|
307
307
|
};
|
|
308
308
|
|
|
309
|
-
const onBlur = (
|
|
309
|
+
const onBlur = (_event: React.FocusEvent) => {
|
|
310
310
|
// Clear navigation state after a delay to allow for focus transitions
|
|
311
311
|
if (navigationTimeoutRef.current) {
|
|
312
312
|
clearTimeout(navigationTimeoutRef.current);
|
|
@@ -386,7 +386,7 @@ export function useKeyboardNavigation(
|
|
|
386
386
|
}
|
|
387
387
|
};
|
|
388
388
|
|
|
389
|
-
const onFocus = (
|
|
389
|
+
const onFocus = (_event: React.FocusEvent) => {
|
|
390
390
|
// Headers don't participate in cell navigation state
|
|
391
391
|
};
|
|
392
392
|
|
|
@@ -3,6 +3,9 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import { useCallback, useEffect } from 'react';
|
|
6
|
+
import { createLogger } from '../../../utils/core/logger';
|
|
7
|
+
|
|
8
|
+
const logger = createLogger('useServerSideDataEffect');
|
|
6
9
|
import type {
|
|
7
10
|
DataRecord,
|
|
8
11
|
PaginationMode,
|
|
@@ -66,7 +69,16 @@ export function useServerSideDataEffect<TData extends DataRecord>({
|
|
|
66
69
|
grouping,
|
|
67
70
|
};
|
|
68
71
|
|
|
69
|
-
|
|
72
|
+
try {
|
|
73
|
+
await fetchServerData(params);
|
|
74
|
+
} catch (error) {
|
|
75
|
+
// Errors from fetchServerData are handled gracefully
|
|
76
|
+
// The error is caught to prevent unhandled promise rejections
|
|
77
|
+
// Error handling/display should be implemented in the fetchServerData function itself
|
|
78
|
+
if (import.meta.env.DEV) {
|
|
79
|
+
logger.error('Error fetching server data', error);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
70
82
|
}, [
|
|
71
83
|
finalPaginationMode,
|
|
72
84
|
serverSide,
|
|
@@ -12,14 +12,14 @@
|
|
|
12
12
|
import React, { useMemo } from 'react';
|
|
13
13
|
import { Checkbox } from '../../Checkbox/Checkbox';
|
|
14
14
|
import { ColumnFactory } from '../core/ColumnFactory';
|
|
15
|
+
import { findSelectLabel } from '../utils/selectFieldUtils';
|
|
15
16
|
import type {
|
|
16
17
|
NormalizedDataTableFeatureConfig,
|
|
17
18
|
DataTableColumn,
|
|
18
19
|
DataTableAction,
|
|
19
20
|
DataRecord
|
|
20
21
|
} from '../types';
|
|
21
|
-
import type { ColumnDef } from '@tanstack/react-table';
|
|
22
|
-
import type { HeaderContext, CellContext } from '@tanstack/react-table';
|
|
22
|
+
import type { ColumnDef, HeaderContext, CellContext } from '@tanstack/react-table';
|
|
23
23
|
|
|
24
24
|
/**
|
|
25
25
|
* Options for the useTableColumns hook.
|
|
@@ -59,20 +59,41 @@ export function useTableColumns<TData extends DataRecord>({
|
|
|
59
59
|
const enhancedColumns = useMemo(() => {
|
|
60
60
|
// Create enhanced base columns
|
|
61
61
|
const baseColumns: ColumnDef<TData>[] = [...columns].map(column => {
|
|
62
|
-
const
|
|
62
|
+
const dataTableColumn = column as DataTableColumn<TData>;
|
|
63
|
+
const baseColumn: ColumnDef<TData> = {
|
|
63
64
|
...column,
|
|
64
65
|
enableSorting: features.sorting && (column.enableSorting !== false),
|
|
65
66
|
enableColumnFilter: features.filtering && (column.enableColumnFilter !== false),
|
|
66
67
|
enableGrouping: features.grouping && (column.enableGrouping !== false),
|
|
67
68
|
};
|
|
68
69
|
|
|
70
|
+
// Automatically inject cell renderer for select fields if:
|
|
71
|
+
// 1. Column has fieldType: 'select'
|
|
72
|
+
// 2. Column has fieldOptions
|
|
73
|
+
// 3. Column doesn't already have a custom cell renderer
|
|
74
|
+
if (
|
|
75
|
+
dataTableColumn.fieldType === 'select' &&
|
|
76
|
+
dataTableColumn.fieldOptions &&
|
|
77
|
+
dataTableColumn.fieldOptions.length > 0 &&
|
|
78
|
+
!baseColumn.cell
|
|
79
|
+
) {
|
|
80
|
+
// Inject automatic cell renderer that displays labels in read mode
|
|
81
|
+
baseColumn.cell = ({ getValue }: { getValue: () => unknown }) => {
|
|
82
|
+
const value = getValue();
|
|
83
|
+
const label = findSelectLabel(value as string | number | null, dataTableColumn.fieldOptions);
|
|
84
|
+
|
|
85
|
+
// Display label if found, otherwise fall back to raw value (backward compatibility)
|
|
86
|
+
// In edit mode, EditableRow will handle rendering the Select component
|
|
87
|
+
return label !== null ? label : String(value ?? '');
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
69
91
|
// Automatically set right alignment for numeric columns
|
|
70
92
|
// Check if column is numeric by:
|
|
71
93
|
// 1. meta.type === 'number'
|
|
72
94
|
// 2. fieldType === 'number'
|
|
73
95
|
// 3. filterType === 'number'
|
|
74
96
|
// Exclude dates (fieldType === 'date' or meta.type === 'date')
|
|
75
|
-
const dataTableColumn = column as DataTableColumn<TData>;
|
|
76
97
|
const isNumericColumn =
|
|
77
98
|
column.meta?.type === 'number' ||
|
|
78
99
|
dataTableColumn.fieldType === 'number' ||
|
|
@@ -101,18 +122,6 @@ export function useTableColumns<TData extends DataRecord>({
|
|
|
101
122
|
header: ({ table }: HeaderContext<TData, unknown>) => {
|
|
102
123
|
const isAllSelected = table.getIsAllPageRowsSelected();
|
|
103
124
|
const isSomeSelected = table.getIsSomePageRowsSelected();
|
|
104
|
-
const pageRows = table.getRowModel().rows;
|
|
105
|
-
const selectedCount = Object.values(table.getState().rowSelection || {}).filter(Boolean).length;
|
|
106
|
-
|
|
107
|
-
// Always log - remove NODE_ENV check for debugging
|
|
108
|
-
console.log('[DataTable Selection] Header checkbox state:', {
|
|
109
|
-
isAllSelected,
|
|
110
|
-
isSomeSelected,
|
|
111
|
-
pageRowCount: pageRows.length,
|
|
112
|
-
totalSelectedCount: selectedCount,
|
|
113
|
-
rowSelection: table.getState().rowSelection,
|
|
114
|
-
pageRowIds: pageRows.map(row => row.id),
|
|
115
|
-
});
|
|
116
125
|
|
|
117
126
|
return React.createElement(Checkbox, {
|
|
118
127
|
checked: isAllSelected,
|
|
@@ -120,34 +129,23 @@ export function useTableColumns<TData extends DataRecord>({
|
|
|
120
129
|
onCheckedChange: (checked: boolean | 'indeterminate') => {
|
|
121
130
|
// Ensure we pass a boolean value
|
|
122
131
|
const shouldSelect = checked === true || checked === 'indeterminate';
|
|
123
|
-
|
|
124
|
-
// Always log - remove NODE_ENV check for debugging
|
|
125
|
-
console.log('[DataTable Selection] Header checkbox clicked:', {
|
|
126
|
-
checked,
|
|
127
|
-
shouldSelect,
|
|
128
|
-
pageRowCount: pageRows.length,
|
|
129
|
-
pageRowIds: pageRows.map(row => row.id),
|
|
130
|
-
currentSelection: table.getState().rowSelection,
|
|
131
|
-
});
|
|
132
|
-
|
|
133
132
|
table.toggleAllPageRowsSelected(shouldSelect);
|
|
134
|
-
|
|
135
|
-
// Log after toggle to see what changed
|
|
136
|
-
setTimeout(() => {
|
|
137
|
-
console.log('[DataTable Selection] After toggleAllPageRowsSelected:', {
|
|
138
|
-
newSelection: table.getState().rowSelection,
|
|
139
|
-
isAllSelected: table.getIsAllPageRowsSelected(),
|
|
140
|
-
isSomeSelected: table.getIsSomePageRowsSelected(),
|
|
141
|
-
pageRowIds: table.getRowModel().rows.map(row => row.id),
|
|
142
|
-
});
|
|
143
|
-
}, 0);
|
|
144
133
|
},
|
|
145
134
|
'aria-label': "Select all"
|
|
146
135
|
});
|
|
147
136
|
},
|
|
148
|
-
cell: ({ row }: CellContext<TData, unknown>) => {
|
|
137
|
+
cell: ({ row, table }: CellContext<TData, unknown>) => {
|
|
138
|
+
// CRITICAL FIX: Read selection state directly from table.getState().rowSelection
|
|
139
|
+
// instead of relying solely on row.getIsSelected() which may not trigger re-renders
|
|
140
|
+
// when the row object reference doesn't change
|
|
141
|
+
const rowSelection = table.getState().rowSelection;
|
|
142
|
+
const rowId = row.id;
|
|
143
|
+
// Read directly from rowSelection state to ensure reactivity
|
|
144
|
+
// This ensures the cell re-renders when the rowSelection object reference changes
|
|
145
|
+
const isSelected = rowSelection[rowId] === true;
|
|
146
|
+
|
|
149
147
|
return React.createElement(Checkbox, {
|
|
150
|
-
checked:
|
|
148
|
+
checked: isSelected,
|
|
151
149
|
onCheckedChange: (value: boolean | 'indeterminate') => row.toggleSelected(!!value),
|
|
152
150
|
'aria-label': "Select row"
|
|
153
151
|
});
|
|
@@ -26,10 +26,8 @@ export interface TableLayoutChange {
|
|
|
26
26
|
/**
|
|
27
27
|
* Snapshot of table state at a point in time.
|
|
28
28
|
* Used for state persistence and restoration.
|
|
29
|
-
*
|
|
30
|
-
* @template TData - The type of data records in the table
|
|
31
29
|
*/
|
|
32
|
-
export interface TableStateSnapshot
|
|
30
|
+
export interface TableStateSnapshot {
|
|
33
31
|
sorting: SortingState;
|
|
34
32
|
columnFilters: ColumnFiltersState;
|
|
35
33
|
columnVisibility: VisibilityState;
|
|
@@ -56,10 +54,10 @@ export interface TableHandlers {
|
|
|
56
54
|
onColumnOrderChange: (updaterOrValue: unknown) => void;
|
|
57
55
|
}
|
|
58
56
|
|
|
59
|
-
interface UseTableHandlersOptions
|
|
60
|
-
state: DataTableState
|
|
61
|
-
stateSnapshot: TableStateSnapshot
|
|
62
|
-
actions: DataTableStateActions
|
|
57
|
+
interface UseTableHandlersOptions {
|
|
58
|
+
state: DataTableState;
|
|
59
|
+
stateSnapshot: TableStateSnapshot;
|
|
60
|
+
actions: DataTableStateActions;
|
|
63
61
|
selection?: Record<string, boolean>;
|
|
64
62
|
onRowSelectionChange?: (selection: Record<string, boolean>) => void;
|
|
65
63
|
effectiveColumnOrder: string[];
|
|
@@ -70,7 +68,7 @@ interface UseTableHandlersOptions<TData extends DataRecord> {
|
|
|
70
68
|
onLayoutChange?: (layout: TableLayoutChange) => void;
|
|
71
69
|
}
|
|
72
70
|
|
|
73
|
-
export function useTableHandlers<
|
|
71
|
+
export function useTableHandlers<_TData extends DataRecord = DataRecord>({
|
|
74
72
|
state,
|
|
75
73
|
stateSnapshot,
|
|
76
74
|
actions,
|
|
@@ -82,7 +80,8 @@ export function useTableHandlers<TData extends DataRecord>({
|
|
|
82
80
|
updateSavedColumnVisibility,
|
|
83
81
|
updateColumnOrder,
|
|
84
82
|
onLayoutChange,
|
|
85
|
-
}: UseTableHandlersOptions
|
|
83
|
+
}: UseTableHandlersOptions): TableHandlers {
|
|
84
|
+
|
|
86
85
|
const handleSortingChange = useCallback((updaterOrValue: unknown) => {
|
|
87
86
|
const nextValue = typeof updaterOrValue === 'function'
|
|
88
87
|
? (updaterOrValue as (prev: SortingState) => SortingState)(stateSnapshot.sorting)
|
|
@@ -120,17 +119,6 @@ export function useTableHandlers<TData extends DataRecord>({
|
|
|
120
119
|
? (updaterOrValue as (prev: Record<string, boolean>) => Record<string, boolean>)(currentSelection)
|
|
121
120
|
: updaterOrValue as Record<string, boolean>;
|
|
122
121
|
|
|
123
|
-
// Always log - remove NODE_ENV check for debugging
|
|
124
|
-
console.log('[DataTable Selection] handleRowSelectionChange called:', {
|
|
125
|
-
isControlled: selection !== undefined,
|
|
126
|
-
currentSelectionCount: Object.values(currentSelection).filter(Boolean).length,
|
|
127
|
-
nextSelectionCount: Object.values(nextSelection).filter(Boolean).length,
|
|
128
|
-
currentSelectionKeys: Object.keys(currentSelection).filter(key => currentSelection[key]),
|
|
129
|
-
nextSelectionKeys: Object.keys(nextSelection).filter(key => nextSelection[key]),
|
|
130
|
-
added: Object.keys(nextSelection).filter(key => nextSelection[key] && !currentSelection[key]),
|
|
131
|
-
removed: Object.keys(currentSelection).filter(key => currentSelection[key] && !nextSelection[key]),
|
|
132
|
-
});
|
|
133
|
-
|
|
134
122
|
if (selection === undefined) {
|
|
135
123
|
// Uncontrolled mode - update internal state
|
|
136
124
|
actions.setRowSelection(nextSelection);
|
|
@@ -62,10 +62,32 @@ export type { ColumnDef, SortingState, ColumnFiltersState } from '@tanstack/reac
|
|
|
62
62
|
export { ColumnFactory } from './core/ColumnFactory';
|
|
63
63
|
|
|
64
64
|
// Components
|
|
65
|
-
export
|
|
65
|
+
export { ActionButtons } from './components/ActionButtons';
|
|
66
|
+
export { BulkOperationsDropdown } from './components/BulkOperationsDropdown';
|
|
67
|
+
export { ColumnVisibilityDropdown } from './components/ColumnVisibilityDropdown';
|
|
68
|
+
export { UnifiedTableBody } from './components/UnifiedTableBody';
|
|
69
|
+
export { EditableRow } from './components/EditableRow';
|
|
70
|
+
export { DataTableToolbar } from './components/DataTableToolbar';
|
|
71
|
+
export { DataTableModals } from './components/DataTableModals';
|
|
72
|
+
export { ImportModal } from './components/ImportModal';
|
|
73
|
+
export type { ImportModalConfig } from './components/ImportModal';
|
|
74
|
+
export { GroupingDropdown } from './components/GroupingDropdown';
|
|
75
|
+
export { LoadingState } from './components/LoadingState';
|
|
76
|
+
export { EmptyState } from './components/EmptyState';
|
|
77
|
+
export { SortIndicator } from './components/SortIndicator';
|
|
78
|
+
export type { SortIndicatorProps } from './components/SortIndicator';
|
|
66
79
|
|
|
67
80
|
// Utility functions
|
|
68
|
-
export * from './utils';
|
|
81
|
+
export * from './utils/aggregationUtils';
|
|
82
|
+
export * from './utils/exportUtils';
|
|
83
|
+
export * from './utils/rowUtils';
|
|
84
|
+
export * from './utils/hierarchicalUtils';
|
|
85
|
+
export * from './utils/hierarchicalSorting';
|
|
86
|
+
export * from './utils/a11yUtils';
|
|
87
|
+
export * from './utils/paginationUtils';
|
|
88
|
+
export * from './utils/columnUtils';
|
|
89
|
+
export * from './utils/errorHandling';
|
|
90
|
+
export * from './utils/selectFieldUtils';
|
|
69
91
|
|
|
70
92
|
// Aggregation utilities (explicitly exported for convenience)
|
|
71
93
|
export { sum, average, count, min, max } from './utils/aggregationUtils';
|
|
@@ -9,16 +9,14 @@ import React from 'react';
|
|
|
9
9
|
import type {
|
|
10
10
|
SortingState,
|
|
11
11
|
ColumnFiltersState,
|
|
12
|
-
VisibilityState,
|
|
13
12
|
GroupingState,
|
|
14
|
-
ExpandedState,
|
|
15
|
-
PaginationState,
|
|
16
13
|
ColumnDef
|
|
17
14
|
} from '@tanstack/react-table';
|
|
18
15
|
import type { ImportModalConfig } from './components/ImportModal';
|
|
19
16
|
|
|
20
17
|
// Extend TanStack Table types to include custom meta properties
|
|
21
18
|
declare module '@tanstack/react-table' {
|
|
19
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
22
20
|
interface ColumnMeta<TData, TValue> {
|
|
23
21
|
/** Text alignment for the column content */
|
|
24
22
|
align?: 'left' | 'right' | 'center';
|
|
@@ -26,6 +24,7 @@ declare module '@tanstack/react-table' {
|
|
|
26
24
|
type?: 'text' | 'number' | 'date' | 'boolean' | 'custom';
|
|
27
25
|
}
|
|
28
26
|
|
|
27
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
29
28
|
interface ColumnDefBase<TData, TValue> {
|
|
30
29
|
/** Alternative accessor key used while editing */
|
|
31
30
|
editAccessorKey?: string;
|
|
@@ -295,6 +294,8 @@ export interface DataTableColumn<TData extends DataRecord = DataRecord> extends
|
|
|
295
294
|
filterSelectOptions?: Array<{ value: string | number; label: string }>;
|
|
296
295
|
/** Whether this column is editable in edit mode (default: true) */
|
|
297
296
|
editable?: boolean;
|
|
297
|
+
/** Alternative CSV headers that should map to this column during import */
|
|
298
|
+
importAliases?: string[];
|
|
298
299
|
|
|
299
300
|
// Hierarchical rendering
|
|
300
301
|
/** Custom renderer for parent rows */
|
|
@@ -704,6 +705,8 @@ export interface DataTableProps<TData extends DataRecord> {
|
|
|
704
705
|
id: string;
|
|
705
706
|
desc: boolean;
|
|
706
707
|
}>;
|
|
708
|
+
/** Initial column visibility state - columns with value `false` will be hidden by default. Keys should match column `id` or `accessorKey`. */
|
|
709
|
+
initialColumnVisibility?: Record<string, boolean>;
|
|
707
710
|
|
|
708
711
|
// Event handlers
|
|
709
712
|
/** Row edit handler */
|
|
@@ -42,19 +42,13 @@ describe('[unit] a11yUtils', () => {
|
|
|
42
42
|
});
|
|
43
43
|
|
|
44
44
|
describe('initializeLiveRegion', () => {
|
|
45
|
-
it('creates live region element
|
|
45
|
+
it('creates live region element with correct accessibility attributes', () => {
|
|
46
46
|
const region = initializeLiveRegion();
|
|
47
47
|
|
|
48
48
|
expect(region).not.toBeNull();
|
|
49
49
|
expect(region).toBeInstanceOf(HTMLElement);
|
|
50
50
|
expect(region?.getAttribute('aria-live')).toBe('polite');
|
|
51
51
|
expect(region?.getAttribute('aria-atomic')).toBe('true');
|
|
52
|
-
expect(region?.getAttribute('class')).toBe('sr-only');
|
|
53
|
-
expect(region?.style.position).toBe('absolute');
|
|
54
|
-
expect(region?.style.left).toBe('-10000px');
|
|
55
|
-
expect(region?.style.width).toBe('1px');
|
|
56
|
-
expect(region?.style.height).toBe('1px');
|
|
57
|
-
expect(region?.style.overflow).toBe('hidden');
|
|
58
52
|
expect(document.body.contains(region!)).toBe(true);
|
|
59
53
|
});
|
|
60
54
|
|
|
@@ -75,16 +69,6 @@ describe('[unit] a11yUtils', () => {
|
|
|
75
69
|
expect(document.body.contains(secondRegion!)).toBe(true);
|
|
76
70
|
});
|
|
77
71
|
|
|
78
|
-
it('returns null in SSR environment', () => {
|
|
79
|
-
const originalWindow = global.window;
|
|
80
|
-
// @ts-expect-error - Testing SSR scenario
|
|
81
|
-
delete global.window;
|
|
82
|
-
|
|
83
|
-
const region = initializeLiveRegion();
|
|
84
|
-
expect(region).toBeNull();
|
|
85
|
-
|
|
86
|
-
global.window = originalWindow;
|
|
87
|
-
});
|
|
88
72
|
});
|
|
89
73
|
|
|
90
74
|
describe('cleanupLiveRegion', () => {
|
|
@@ -96,12 +80,12 @@ describe('[unit] a11yUtils', () => {
|
|
|
96
80
|
expect(document.body.contains(region!)).toBe(false);
|
|
97
81
|
});
|
|
98
82
|
|
|
99
|
-
it('
|
|
83
|
+
it('handles multiple cleanup calls gracefully', () => {
|
|
100
84
|
initializeLiveRegion();
|
|
101
85
|
cleanupLiveRegion();
|
|
102
86
|
|
|
103
87
|
// Second call should not throw
|
|
104
|
-
cleanupLiveRegion();
|
|
88
|
+
expect(() => cleanupLiveRegion()).not.toThrow();
|
|
105
89
|
expect(document.body.querySelector('.sr-only[aria-live]')).toBeNull();
|
|
106
90
|
});
|
|
107
91
|
|
|
@@ -109,22 +93,7 @@ describe('[unit] a11yUtils', () => {
|
|
|
109
93
|
expect(() => cleanupLiveRegion()).not.toThrow();
|
|
110
94
|
});
|
|
111
95
|
|
|
112
|
-
it('handles cleanup when region is not in document', () => {
|
|
113
|
-
const region = initializeLiveRegion();
|
|
114
|
-
document.body.removeChild(region!);
|
|
115
|
-
|
|
116
|
-
expect(() => cleanupLiveRegion()).not.toThrow();
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
it('returns early in SSR environment', () => {
|
|
120
|
-
const originalWindow = global.window;
|
|
121
|
-
// @ts-expect-error - Testing SSR scenario
|
|
122
|
-
delete global.window;
|
|
123
96
|
|
|
124
|
-
expect(() => cleanupLiveRegion()).not.toThrow();
|
|
125
|
-
|
|
126
|
-
global.window = originalWindow;
|
|
127
|
-
});
|
|
128
97
|
});
|
|
129
98
|
|
|
130
99
|
describe('announce', () => {
|
|
@@ -172,30 +141,6 @@ describe('[unit] a11yUtils', () => {
|
|
|
172
141
|
expect(region.textContent).toBe('');
|
|
173
142
|
});
|
|
174
143
|
|
|
175
|
-
it('does not clear message if content changed during delay', () => {
|
|
176
|
-
initializeLiveRegion();
|
|
177
|
-
announce('First message');
|
|
178
|
-
vi.advanceTimersByTime(100);
|
|
179
|
-
|
|
180
|
-
const region = document.body.querySelector('.sr-only[aria-live]') as HTMLElement;
|
|
181
|
-
expect(region.textContent).toBe('First message');
|
|
182
|
-
|
|
183
|
-
// Announce new message before first timeout clears
|
|
184
|
-
announce('Second message');
|
|
185
|
-
vi.advanceTimersByTime(100);
|
|
186
|
-
expect(region.textContent).toBe('Second message');
|
|
187
|
-
|
|
188
|
-
// First timeout should not clear since content changed (it was 'Second message', not 'First message')
|
|
189
|
-
vi.advanceTimersByTime(900);
|
|
190
|
-
// The second timeout should clear it after 1000ms, but we need to advance past the first timeout
|
|
191
|
-
// The first timeout (1000ms after first announce) checks if textContent === 'First message'
|
|
192
|
-
// Since it's now 'Second message', it won't clear
|
|
193
|
-
// Then we advance to the second timeout (1000ms after second announce)
|
|
194
|
-
vi.advanceTimersByTime(100);
|
|
195
|
-
// Now the second timeout should check if textContent === 'Second message' and clear it
|
|
196
|
-
expect(region.textContent).toBe('');
|
|
197
|
-
});
|
|
198
|
-
|
|
199
144
|
it('does not announce empty or whitespace-only messages', () => {
|
|
200
145
|
initializeLiveRegion();
|
|
201
146
|
const region = document.body.querySelector('.sr-only[aria-live]') as HTMLElement;
|
|
@@ -208,15 +153,6 @@ describe('[unit] a11yUtils', () => {
|
|
|
208
153
|
expect(region.textContent).toBe('');
|
|
209
154
|
});
|
|
210
155
|
|
|
211
|
-
it('returns early in SSR environment', () => {
|
|
212
|
-
const originalWindow = global.window;
|
|
213
|
-
// @ts-expect-error - Testing SSR scenario
|
|
214
|
-
delete global.window;
|
|
215
|
-
|
|
216
|
-
expect(() => announce('Test message')).not.toThrow();
|
|
217
|
-
|
|
218
|
-
global.window = originalWindow;
|
|
219
|
-
});
|
|
220
156
|
|
|
221
157
|
it('initializes live region if not already initialized', () => {
|
|
222
158
|
announce('Auto-init message');
|