@jmruthers/pace-core 0.2.5 → 0.2.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{DataTable-BHlzyKZP.d.ts → DataTable-C1AEm9Cx.d.ts} +1 -1
- package/dist/{DataTable-GEY5U7OI.js → DataTable-EEUDXPE5.js} +2 -8
- package/dist/{api-T6CBS7IO.js → api-ETQ6YJ3C.js} +2 -3
- package/dist/{chunk-DY5E3AT7.js → chunk-BEZRLNK3.js} +13 -3
- package/dist/chunk-BEZRLNK3.js.map +1 -0
- package/dist/{chunk-ANE4PDC2.js → chunk-C5G2A4PO.js} +159 -6
- package/dist/chunk-C5G2A4PO.js.map +1 -0
- package/dist/{chunk-WYB6MBZA.js → chunk-EWKPTNPO.js} +579 -973
- package/dist/chunk-EWKPTNPO.js.map +1 -0
- package/dist/{chunk-TMRLB2LA.js → chunk-HEMJ4SUJ.js} +2 -2
- package/dist/{chunk-O4T53L7X.js → chunk-HNDFPXUU.js} +5 -5
- package/dist/{chunk-UY7AM4QG.js → chunk-RRUYHORU.js} +161 -74
- package/dist/chunk-RRUYHORU.js.map +1 -0
- package/dist/{chunk-PFRRIDYA.js → chunk-TIVL4UQ7.js} +2 -2
- package/dist/{chunk-2MKP6IYD.js → chunk-VYG4AXYW.js} +2 -2
- package/dist/components.d.ts +2 -2
- package/dist/components.js +15 -16
- package/dist/components.js.map +1 -1
- package/dist/hooks.d.ts +1 -1
- package/dist/hooks.js +4 -4
- package/dist/index.d.ts +2 -2
- package/dist/index.js +16 -17
- package/dist/index.js.map +1 -1
- package/dist/providers.js +2 -2
- package/dist/rbac/index.js +25 -20
- package/dist/rbac/index.js.map +1 -1
- package/dist/styles/core.css +83 -62
- package/dist/{types-CInEi-ng.d.ts → types-DiRQsGJs.d.ts} +0 -2
- package/dist/utils.d.ts +2 -2
- package/dist/utils.js +1 -1
- package/docs/api/classes/ErrorBoundary.md +1 -1
- package/docs/api/classes/PublicErrorBoundary.md +1 -1
- package/docs/api/interfaces/AggregateConfig.md +1 -1
- package/docs/api/interfaces/ButtonProps.md +1 -1
- package/docs/api/interfaces/CardProps.md +1 -1
- package/docs/api/interfaces/ColorPalette.md +1 -1
- package/docs/api/interfaces/ColorShade.md +1 -1
- package/docs/api/interfaces/DataTableAction.md +1 -1
- package/docs/api/interfaces/DataTableColumn.md +1 -1
- package/docs/api/interfaces/DataTableProps.md +33 -33
- package/docs/api/interfaces/DataTableToolbarButton.md +1 -1
- package/docs/api/interfaces/EmptyStateConfig.md +1 -1
- package/docs/api/interfaces/EventContextType.md +1 -1
- package/docs/api/interfaces/EventLogoProps.md +1 -1
- package/docs/api/interfaces/EventProviderProps.md +1 -1
- package/docs/api/interfaces/FileSizeLimits.md +1 -1
- package/docs/api/interfaces/FileUploadProps.md +1 -1
- package/docs/api/interfaces/FooterProps.md +1 -1
- package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
- package/docs/api/interfaces/InputProps.md +1 -1
- package/docs/api/interfaces/LabelProps.md +1 -1
- package/docs/api/interfaces/LoginFormProps.md +1 -1
- package/docs/api/interfaces/NavigationItem.md +1 -1
- package/docs/api/interfaces/NavigationMenuProps.md +1 -1
- package/docs/api/interfaces/Organisation.md +1 -1
- package/docs/api/interfaces/OrganisationContextType.md +1 -1
- package/docs/api/interfaces/OrganisationMembership.md +1 -1
- package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
- package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
- package/docs/api/interfaces/PaceAppLayoutProps.md +1 -1
- package/docs/api/interfaces/PaceLoginPageProps.md +1 -1
- package/docs/api/interfaces/PaletteData.md +1 -1
- package/docs/api/interfaces/PublicErrorBoundaryProps.md +1 -1
- package/docs/api/interfaces/PublicErrorBoundaryState.md +1 -1
- package/docs/api/interfaces/PublicLoadingSpinnerProps.md +1 -1
- package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
- package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
- package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
- package/docs/api/interfaces/StorageConfig.md +1 -1
- package/docs/api/interfaces/StorageFileInfo.md +1 -1
- package/docs/api/interfaces/StorageFileMetadata.md +1 -1
- package/docs/api/interfaces/StorageListOptions.md +1 -1
- package/docs/api/interfaces/StorageListResult.md +1 -1
- package/docs/api/interfaces/StorageUploadOptions.md +1 -1
- package/docs/api/interfaces/StorageUploadResult.md +1 -1
- package/docs/api/interfaces/StorageUrlOptions.md +1 -1
- package/docs/api/interfaces/StyleImport.md +1 -1
- package/docs/api/interfaces/ToastActionElement.md +1 -1
- package/docs/api/interfaces/ToastProps.md +1 -1
- package/docs/api/interfaces/UnifiedAuthContextType.md +1 -1
- package/docs/api/interfaces/UnifiedAuthProviderProps.md +1 -1
- package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
- package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
- package/docs/api/interfaces/UsePublicEventLogoOptions.md +1 -1
- package/docs/api/interfaces/UsePublicEventLogoReturn.md +1 -1
- package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
- package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
- package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
- package/docs/api/interfaces/UserEventAccess.md +1 -1
- package/docs/api/interfaces/UserMenuProps.md +1 -1
- package/docs/api/interfaces/UserProfile.md +1 -1
- package/docs/api/modules.md +10 -10
- package/docs/architecture/README.md +1 -1
- package/package.json +1 -1
- package/src/__tests__/shared/testUtils.optimized.tsx +65 -7
- package/src/components/DataTable/DataTable.tsx +1 -3
- package/src/components/DataTable/__tests__/DataTable.errorHandling.test.tsx +0 -8
- package/src/components/DataTable/__tests__/DataTable.hierarchical.test.tsx +17 -12
- package/src/components/DataTable/__tests__/DataTable.infinite-loop.test.tsx +0 -1
- package/src/components/DataTable/__tests__/DataTable.integration.test.tsx +4 -12
- package/src/components/DataTable/__tests__/DataTable.performance.test.tsx +0 -8
- package/src/components/DataTable/__tests__/DataTable.permissions.test.tsx +21 -11
- package/src/components/DataTable/__tests__/DataTable.sorting.test.tsx +321 -0
- package/src/components/DataTable/__tests__/DataTable.userWorkflows.test.tsx +21 -11
- package/src/components/DataTable/__tests__/DataTable.workflowValidation.test.tsx +94 -0
- package/src/components/DataTable/__tests__/DataTable.workflows.test.tsx +25 -15
- package/src/components/DataTable/__tests__/README.md +11 -2
- package/src/components/DataTable/__tests__/performance-regression.test.tsx +0 -11
- package/src/components/DataTable/__tests__/test-utils/sharedTestUtils.tsx +0 -1
- package/src/components/DataTable/components/ColumnVisibilityDropdown.tsx +2 -2
- package/src/components/DataTable/components/DataTableBody.tsx +34 -35
- package/src/components/DataTable/components/DataTableCore.tsx +205 -133
- package/src/components/DataTable/components/DataTableToolbar.tsx +9 -10
- package/src/components/DataTable/components/DraggableColumnHeader.tsx +3 -7
- package/src/components/DataTable/components/EditableRow.tsx +6 -7
- package/src/components/DataTable/components/FilterRow.tsx +0 -1
- package/src/components/DataTable/components/GroupingDropdown.tsx +2 -2
- package/src/components/DataTable/components/UnifiedTableBody.tsx +83 -281
- package/src/components/DataTable/components/VirtualizedDataTable.tsx +9 -89
- package/src/components/DataTable/components/__tests__/DataTable.accessibility.test.tsx +111 -5
- package/src/components/DataTable/components/__tests__/DataTable.integration.test.tsx +82 -13
- package/src/components/DataTable/components/__tests__/DataTable.performance.test.tsx +0 -1
- package/src/components/DataTable/components/__tests__/DataTable.real.test.tsx +2 -2
- package/src/components/DataTable/components/__tests__/DataTable.security.test.tsx +0 -1
- package/src/components/DataTable/components/__tests__/DataTable.unit.test.tsx +2 -2
- package/src/components/DataTable/components/__tests__/FilteringToggle.unit.test.tsx +3 -0
- package/src/components/DataTable/components/index.ts +0 -1
- package/src/components/DataTable/core/DataTableContext.tsx +0 -1
- package/src/components/DataTable/index.ts +0 -2
- package/src/components/DataTable/types.ts +0 -2
- package/src/components/Input/Input.tsx +2 -2
- package/src/components/Input/__tests__/Input.unit.test.tsx +4 -4
- package/src/components/PaceAppLayout/__tests__/PaceAppLayout.integration.test.tsx +6 -2
- package/src/components/RBAC/PagePermissionGuard.tsx +13 -0
- package/src/components/RBAC/__tests__/PagePermissionGuard.unit.test.tsx +10 -1
- package/src/components/Select/Select.tsx +7 -1
- package/src/components/__tests__/EdgeCaseTesting.enhanced.test.tsx +2 -1
- package/src/hooks/__tests__/useRBAC.unit.test.ts +32 -24
- package/src/providers/RBACProvider.tsx +14 -2
- package/src/providers/__tests__/UnifiedAuthProvider.unit.test.tsx +11 -3
- package/src/rbac/__tests__/cache-invalidation.test.ts +2 -2
- package/src/rbac/__tests__/cache.test.ts +3 -3
- package/src/rbac/hooks.ts +15 -7
- package/src/styles/core.css +83 -62
- package/src/utils/__tests__/lazyLoad.unit.test.tsx +13 -18
- package/src/utils/storage/__tests__/helpers.unit.test.ts +9 -7
- package/dist/cache-I72HKDOA.js +0 -12
- package/dist/cache-I72HKDOA.js.map +0 -1
- package/dist/chunk-ANE4PDC2.js.map +0 -1
- package/dist/chunk-DY5E3AT7.js.map +0 -1
- package/dist/chunk-MRRFJ6SA.js +0 -161
- package/dist/chunk-MRRFJ6SA.js.map +0 -1
- package/dist/chunk-UY7AM4QG.js.map +0 -1
- package/dist/chunk-WYB6MBZA.js.map +0 -1
- package/src/components/DataTable/__tests__/DataTable.autoSizing.test.tsx +0 -526
- package/src/components/DataTable/components/DataTableHeader.tsx +0 -31
- package/src/components/DataTable/components/__tests__/DataTableHeader.unit.test.tsx +0 -143
- package/src/components/DataTable/examples/AutoSizingExample.tsx +0 -180
- package/src/components/DataTable/examples/ColumnSizingComparison.tsx +0 -235
- package/src/components/DataTable/utils/__tests__/columnSizing.test.ts +0 -237
- package/src/components/DataTable/utils/columnSizing.ts +0 -125
- /package/dist/{DataTable-GEY5U7OI.js.map → DataTable-EEUDXPE5.js.map} +0 -0
- /package/dist/{api-T6CBS7IO.js.map → api-ETQ6YJ3C.js.map} +0 -0
- /package/dist/{chunk-TMRLB2LA.js.map → chunk-HEMJ4SUJ.js.map} +0 -0
- /package/dist/{chunk-O4T53L7X.js.map → chunk-HNDFPXUU.js.map} +0 -0
- /package/dist/{chunk-PFRRIDYA.js.map → chunk-TIVL4UQ7.js.map} +0 -0
- /package/dist/{chunk-2MKP6IYD.js.map → chunk-VYG4AXYW.js.map} +0 -0
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
getPaginationRowModel,
|
|
18
18
|
getGroupedRowModel,
|
|
19
19
|
getExpandedRowModel,
|
|
20
|
+
flexRender,
|
|
20
21
|
type SortingState,
|
|
21
22
|
type ColumnDef,
|
|
22
23
|
type ColumnFiltersState,
|
|
@@ -27,12 +28,12 @@ import {
|
|
|
27
28
|
type HeaderContext,
|
|
28
29
|
type CellContext,
|
|
29
30
|
} from '@tanstack/react-table';
|
|
30
|
-
import { Edit, Trash } from 'lucide-react';
|
|
31
|
+
import { Edit, Trash, ChevronUp, ChevronDown, ChevronsUpDown } from 'lucide-react';
|
|
31
32
|
import { cn } from '../../../utils/cn';
|
|
32
33
|
import { Checkbox } from '../../Checkbox/Checkbox';
|
|
34
|
+
import { Button } from '../../Button/Button';
|
|
33
35
|
import { getTableClasses, getMainContainerClasses } from '../styles';
|
|
34
36
|
import { useDataTablePerformance } from '../../../hooks/useDataTablePerformance';
|
|
35
|
-
import { DataTableHeader } from './DataTableHeader';
|
|
36
37
|
import { DataTableToolbar } from './DataTableToolbar';
|
|
37
38
|
import { UnifiedTableBody } from './UnifiedTableBody';
|
|
38
39
|
import { PaginationControls, EnhancedPaginationControls } from './PaginationControls';
|
|
@@ -44,7 +45,6 @@ import { useHierarchicalState } from '../hooks/useHierarchicalState';
|
|
|
44
45
|
import { useDataTableState } from '../hooks/useDataTableState';
|
|
45
46
|
import { validateHierarchicalData, sortHierarchicalData } from '../utils/hierarchicalUtils';
|
|
46
47
|
import { sortHierarchicalData as sortHierarchicalDataWithSorting } from '../utils/hierarchicalSorting';
|
|
47
|
-
import { calculateColumnWidths, getColumnSizingConfig } from '../utils/columnSizing';
|
|
48
48
|
import { ColumnFactory } from '../core/ColumnFactory';
|
|
49
49
|
|
|
50
50
|
import type {
|
|
@@ -551,17 +551,6 @@ function DataTableInternal<TData extends DataRecord>({
|
|
|
551
551
|
// COLUMN WIDTHS
|
|
552
552
|
// ============================================================================
|
|
553
553
|
|
|
554
|
-
const columnWidths = useMemo(() => {
|
|
555
|
-
if (features.autoColumnSizing) {
|
|
556
|
-
return calculateColumnWidths(data, enhancedColumns, {
|
|
557
|
-
minWidth: 80,
|
|
558
|
-
maxWidth: 400,
|
|
559
|
-
padding: 32,
|
|
560
|
-
sampleSize: Math.min(100, data.length)
|
|
561
|
-
});
|
|
562
|
-
}
|
|
563
|
-
return undefined;
|
|
564
|
-
}, [data, enhancedColumns, features.autoColumnSizing]);
|
|
565
554
|
|
|
566
555
|
// ============================================================================
|
|
567
556
|
// TABLE CONFIGURATION
|
|
@@ -610,7 +599,6 @@ function DataTableInternal<TData extends DataRecord>({
|
|
|
610
599
|
manualFiltering: finalPaginationMode === 'server',
|
|
611
600
|
manualPagination: finalPaginationMode === 'server',
|
|
612
601
|
pageCount: finalPaginationMode === 'server' ? Math.ceil(dataCount / pagination.pageSize) : undefined,
|
|
613
|
-
...getColumnSizingConfig(features.autoColumnSizing || false, columnWidths),
|
|
614
602
|
}), [
|
|
615
603
|
finalTableData,
|
|
616
604
|
enhancedColumns,
|
|
@@ -629,8 +617,6 @@ function DataTableInternal<TData extends DataRecord>({
|
|
|
629
617
|
onRowSelectionChange,
|
|
630
618
|
finalPaginationMode,
|
|
631
619
|
features.pagination,
|
|
632
|
-
features.autoColumnSizing,
|
|
633
|
-
columnWidths,
|
|
634
620
|
dataCount,
|
|
635
621
|
pagination.pageSize
|
|
636
622
|
]);
|
|
@@ -707,135 +693,221 @@ function DataTableInternal<TData extends DataRecord>({
|
|
|
707
693
|
? EnhancedPaginationControls
|
|
708
694
|
: PaginationControls;
|
|
709
695
|
|
|
696
|
+
// Calculate column counts for colgroup
|
|
697
|
+
const visibleColumns = table?.getVisibleFlatColumns() || [];
|
|
698
|
+
const dataColumns = visibleColumns.filter(col =>
|
|
699
|
+
col.id !== 'select' && col.id !== 'actions'
|
|
700
|
+
).length;
|
|
701
|
+
const hasSelectColumn = visibleColumns.some(col => col.id === 'select');
|
|
702
|
+
const hasActionsColumn = visibleColumns.some(col => col.id === 'actions');
|
|
703
|
+
|
|
710
704
|
return (
|
|
711
705
|
<>
|
|
712
|
-
{/*
|
|
713
|
-
{(title || description) && (
|
|
714
|
-
<DataTableHeader
|
|
715
|
-
title={title}
|
|
716
|
-
description={description}
|
|
717
|
-
/>
|
|
718
|
-
)}
|
|
719
|
-
|
|
720
|
-
{/* Toolbar */}
|
|
721
|
-
<DataTableToolbar
|
|
722
|
-
features={features}
|
|
723
|
-
globalFilter={searchQuery}
|
|
724
|
-
onGlobalFilterChange={handleSearch}
|
|
725
|
-
columns={columns}
|
|
726
|
-
grouping={grouping}
|
|
727
|
-
onGroupByChange={(columnId) => {
|
|
728
|
-
setGrouping(columnId ? [columnId] : []);
|
|
729
|
-
}}
|
|
730
|
-
tableColumns={table?.getAllColumns() || []}
|
|
731
|
-
onColumnVisibilityChange={(columnId, visible) => {
|
|
732
|
-
setColumnVisibility(prev => ({ ...prev, [columnId]: visible }));
|
|
733
|
-
}}
|
|
734
|
-
onCreateRow={features.creation && onCreateRow ? () => tableActions.setCreating(true) : undefined}
|
|
735
|
-
onImportClick={() => setShowImportModal(true)}
|
|
736
|
-
onExport={() => {
|
|
737
|
-
// Export logic here
|
|
738
|
-
}}
|
|
739
|
-
rowSelection={rowSelection}
|
|
740
|
-
onDeleteSelected={onDeleteSelected}
|
|
741
|
-
onToggleFilterRow={() => setShowFilterRow(!showFilterRow)}
|
|
742
|
-
showFilterRow={showFilterRow}
|
|
743
|
-
/>
|
|
744
|
-
|
|
745
|
-
{/* Table */}
|
|
706
|
+
{/* Table with semantic HTML structure */}
|
|
746
707
|
<table className={getTableClasses({
|
|
747
|
-
isFixed:
|
|
708
|
+
isFixed: true,
|
|
748
709
|
variant,
|
|
749
710
|
className: cn('border-collapse relative w-full', className)
|
|
750
711
|
})} style={{
|
|
751
|
-
tableLayout:
|
|
712
|
+
tableLayout: 'fixed',
|
|
752
713
|
width: '100%'
|
|
753
714
|
}}>
|
|
715
|
+
{/* Caption with title, description, and toolbar */}
|
|
716
|
+
<caption className="text-left pb-2">
|
|
717
|
+
{(title || description) && (
|
|
718
|
+
<>
|
|
719
|
+
{title && <h2 >{title}</h2>}
|
|
720
|
+
{description && <p>{description}</p>}
|
|
721
|
+
</>
|
|
722
|
+
)}
|
|
723
|
+
<>
|
|
724
|
+
<DataTableToolbar
|
|
725
|
+
features={features}
|
|
726
|
+
globalFilter={searchQuery}
|
|
727
|
+
onGlobalFilterChange={handleSearch}
|
|
728
|
+
columns={columns}
|
|
729
|
+
grouping={grouping}
|
|
730
|
+
onGroupByChange={(columnId) => {
|
|
731
|
+
setGrouping(columnId ? [columnId] : []);
|
|
732
|
+
}}
|
|
733
|
+
tableColumns={table?.getAllColumns() || []}
|
|
734
|
+
onColumnVisibilityChange={(columnId, visible) => {
|
|
735
|
+
setColumnVisibility(prev => ({ ...prev, [columnId]: visible }));
|
|
736
|
+
}}
|
|
737
|
+
onCreateRow={features.creation && onCreateRow ? () => tableActions.setCreating(true) : undefined}
|
|
738
|
+
onImportClick={() => setShowImportModal(true)}
|
|
739
|
+
onExport={() => {
|
|
740
|
+
// Export logic here
|
|
741
|
+
}}
|
|
742
|
+
rowSelection={rowSelection}
|
|
743
|
+
onDeleteSelected={onDeleteSelected}
|
|
744
|
+
onToggleFilterRow={() => setShowFilterRow(!showFilterRow)}
|
|
745
|
+
showFilterRow={showFilterRow}
|
|
746
|
+
/>
|
|
747
|
+
</>
|
|
748
|
+
</caption>
|
|
749
|
+
|
|
750
|
+
{/* Column groups */}
|
|
751
|
+
<colgroup>
|
|
752
|
+
{hasSelectColumn && <col span={1} data-col-type="select" />}
|
|
753
|
+
<col span={dataColumns} data-col-type="data" />
|
|
754
|
+
{hasActionsColumn && <col span={1} data-col-type="actions" />}
|
|
755
|
+
</colgroup>
|
|
756
|
+
|
|
757
|
+
{/* Table header */}
|
|
758
|
+
<thead>
|
|
759
|
+
{table?.getHeaderGroups().map((headerGroup) => (
|
|
760
|
+
<tr key={headerGroup.id}>
|
|
761
|
+
{headerGroup.headers
|
|
762
|
+
.filter(header => {
|
|
763
|
+
return typeof header.column.getIsVisible === 'function'
|
|
764
|
+
? header.column.getIsVisible()
|
|
765
|
+
: true;
|
|
766
|
+
})
|
|
767
|
+
.map((header) => {
|
|
768
|
+
const isSortable = header.column.getCanSort();
|
|
769
|
+
const ariaSort = isSortable
|
|
770
|
+
? (header.column.getIsSorted() === 'asc'
|
|
771
|
+
? 'ascending'
|
|
772
|
+
: header.column.getIsSorted() === 'desc'
|
|
773
|
+
? 'descending'
|
|
774
|
+
: 'none')
|
|
775
|
+
: undefined;
|
|
776
|
+
return (
|
|
777
|
+
<th
|
|
778
|
+
key={header.id}
|
|
779
|
+
{...(isSortable ? { 'aria-sort': ariaSort } : {})}
|
|
780
|
+
>
|
|
781
|
+
{header.isPlaceholder ? null : (
|
|
782
|
+
isSortable ? (
|
|
783
|
+
<Button
|
|
784
|
+
variant="ghost"
|
|
785
|
+
className="h-auto p-0 font-medium hover:bg-transparent"
|
|
786
|
+
onClick={header.column.getToggleSortingHandler()}
|
|
787
|
+
aria-label={`Sort by ${typeof header.column.columnDef.header === 'string' ? header.column.columnDef.header : 'column'}`}
|
|
788
|
+
tabIndex={0}
|
|
789
|
+
>
|
|
790
|
+
<div className="flex items-center gap-1">
|
|
791
|
+
{typeof header.column.columnDef.header === 'function'
|
|
792
|
+
? header.column.columnDef.header(header.getContext())
|
|
793
|
+
: header.column.columnDef.header}
|
|
794
|
+
{header.column.getIsSorted() === 'asc' ? (
|
|
795
|
+
<ChevronUp className="h-4 w-4" />
|
|
796
|
+
) : header.column.getIsSorted() === 'desc' ? (
|
|
797
|
+
<ChevronDown className="h-4 w-4" />
|
|
798
|
+
) : (
|
|
799
|
+
<ChevronsUpDown className="h-4 w-4" />
|
|
800
|
+
)}
|
|
801
|
+
</div>
|
|
802
|
+
</Button>
|
|
803
|
+
) : (
|
|
804
|
+
<div>
|
|
805
|
+
{typeof header.column.columnDef.header === 'function'
|
|
806
|
+
? header.column.columnDef.header(header.getContext())
|
|
807
|
+
: header.column.columnDef.header}
|
|
808
|
+
</div>
|
|
809
|
+
)
|
|
810
|
+
)}
|
|
811
|
+
</th>
|
|
812
|
+
);
|
|
813
|
+
})}
|
|
814
|
+
</tr>
|
|
815
|
+
))}
|
|
816
|
+
</thead>
|
|
817
|
+
|
|
818
|
+
{/* Table body */}
|
|
754
819
|
<UnifiedTableBody
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
820
|
+
table={table}
|
|
821
|
+
isCreating={isCreating}
|
|
822
|
+
creationData={creationData}
|
|
823
|
+
onCreationDataChange={tableActions.setCreationData}
|
|
824
|
+
onSaveCreation={() => {
|
|
825
|
+
if (onCreateRow) {
|
|
826
|
+
onCreateRow(creationData as Partial<TData>);
|
|
827
|
+
tableActions.clearCreationData();
|
|
828
|
+
tableActions.setCreating(false);
|
|
829
|
+
}
|
|
830
|
+
}}
|
|
831
|
+
onCancelCreation={() => {
|
|
762
832
|
tableActions.clearCreationData();
|
|
763
833
|
tableActions.setCreating(false);
|
|
764
|
-
}
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
editingData={editingData}
|
|
772
|
-
onEditingDataChange={(data) => {
|
|
773
|
-
// Update the editing data in the centralized state
|
|
774
|
-
if (editingRowId) {
|
|
775
|
-
tableActions.setEditingRow(editingRowId, data);
|
|
776
|
-
}
|
|
777
|
-
}}
|
|
778
|
-
onSaveEditing={() => {
|
|
779
|
-
if (onEditRow && editingRowId) {
|
|
780
|
-
// Find the original row data
|
|
781
|
-
const originalRow = data.find(row => {
|
|
782
|
-
const rowId = getRowId ? getRowId(row, 0) : (row as any).id || String(0);
|
|
783
|
-
return rowId === editingRowId;
|
|
784
|
-
});
|
|
785
|
-
if (originalRow) {
|
|
786
|
-
onEditRow(originalRow, editingData as Partial<TData>);
|
|
834
|
+
}}
|
|
835
|
+
editingRowId={editingRowId}
|
|
836
|
+
editingData={editingData}
|
|
837
|
+
onEditingDataChange={(data) => {
|
|
838
|
+
// Update the editing data in the centralized state
|
|
839
|
+
if (editingRowId) {
|
|
840
|
+
tableActions.setEditingRow(editingRowId, data);
|
|
787
841
|
}
|
|
788
|
-
}
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
842
|
+
}}
|
|
843
|
+
onSaveEditing={() => {
|
|
844
|
+
if (onEditRow && editingRowId) {
|
|
845
|
+
// Find the original row data
|
|
846
|
+
const originalRow = data.find(row => {
|
|
847
|
+
const rowId = getRowId ? getRowId(row, 0) : (row as any).id || String(0);
|
|
848
|
+
return rowId === editingRowId;
|
|
849
|
+
});
|
|
850
|
+
if (originalRow) {
|
|
851
|
+
onEditRow(originalRow, editingData as Partial<TData>);
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
tableActions.clearEditing();
|
|
855
|
+
}}
|
|
856
|
+
onCancelEditing={() => {
|
|
857
|
+
tableActions.clearEditing();
|
|
858
|
+
}}
|
|
859
|
+
grouping={grouping}
|
|
860
|
+
aggregates={aggregates}
|
|
861
|
+
getRowId={getRowId}
|
|
862
|
+
emptyState={React.isValidElement(emptyState) ? undefined : emptyState as any}
|
|
863
|
+
isFiltered={searchQuery !== '' || columnFilters.length > 0}
|
|
864
|
+
onClearFilters={() => {
|
|
865
|
+
setSearchQuery('');
|
|
866
|
+
setColumnFilters([]);
|
|
867
|
+
}}
|
|
868
|
+
enableFiltering={features.filtering}
|
|
869
|
+
showFilterRow={showFilterRow}
|
|
870
|
+
enableColumnReordering={features.columnReordering}
|
|
871
|
+
onColumnOrderChange={setColumnOrder}
|
|
872
|
+
onColumnDrop={(draggedColumnId, targetColumnId) => {
|
|
873
|
+
// Handle column drop
|
|
874
|
+
}}
|
|
875
|
+
savedColumnOrder={savedColumnOrder}
|
|
876
|
+
enablePersistence={features.columnReordering}
|
|
877
|
+
tableId={title ? `datatable-${title.toLowerCase().replace(/\s+/g, '-')}` : undefined}
|
|
878
|
+
dataLength={finalTableData?.length || 0}
|
|
879
|
+
virtualHeight={virtualHeight}
|
|
880
|
+
forceVirtualization={false}
|
|
881
|
+
hierarchical={features.hierarchical && hierarchical?.enabled ? {
|
|
882
|
+
...hierarchical,
|
|
883
|
+
state: hierarchicalState,
|
|
884
|
+
expandAll: hierarchicalState.expandAll,
|
|
885
|
+
collapseAll: hierarchicalState.collapseAll,
|
|
886
|
+
isAllExpanded: hierarchicalState.getExpandedIds().length > 0 &&
|
|
887
|
+
hierarchicalState.getExpandedIds().length === (finalTableData as any[]).filter(row => row.isParent).length,
|
|
888
|
+
hasAnyChildren: (finalTableData as any[]).some(row => row.isParent),
|
|
889
|
+
} : undefined}
|
|
890
|
+
actions={effectiveActions}
|
|
891
|
+
/>
|
|
828
892
|
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
893
|
+
{/* Table footer with pagination */}
|
|
894
|
+
{features.pagination && (
|
|
895
|
+
<tfoot>
|
|
896
|
+
<tr>
|
|
897
|
+
<td colSpan={visibleColumns.length}>
|
|
898
|
+
<PaginationComponent
|
|
899
|
+
table={table}
|
|
900
|
+
pageSizeOptions={finalPageSizeOptions}
|
|
901
|
+
paginationMode={finalPaginationMode}
|
|
902
|
+
totalCount={finalDataCount}
|
|
903
|
+
isLoading={isLoading}
|
|
904
|
+
/>
|
|
905
|
+
</td>
|
|
906
|
+
</tr>
|
|
907
|
+
</tfoot>
|
|
908
|
+
)}
|
|
909
|
+
|
|
910
|
+
</table>
|
|
839
911
|
|
|
840
912
|
{/* Modal Dialogs */}
|
|
841
913
|
<DataTableModals
|
|
@@ -150,11 +150,10 @@ export function DataTableToolbar<TData extends DataRecord>({
|
|
|
150
150
|
const currentGroupBy = grouping.length > 0 ? grouping[0] : null;
|
|
151
151
|
|
|
152
152
|
return (
|
|
153
|
-
|
|
154
|
-
|
|
153
|
+
|
|
154
|
+
<nav className="flex justify-end flex-wrap gap-2">
|
|
155
155
|
{features.search && (
|
|
156
|
-
|
|
157
|
-
<Search className="h-4 w-4 text-sec-500 flex-shrink-0" />
|
|
156
|
+
|
|
158
157
|
<Input
|
|
159
158
|
id="table-search"
|
|
160
159
|
placeholder="Search..."
|
|
@@ -162,13 +161,13 @@ export function DataTableToolbar<TData extends DataRecord>({
|
|
|
162
161
|
onChange={(e) => onGlobalFilterChange(e.target.value)}
|
|
163
162
|
aria-label="Search table"
|
|
164
163
|
tabIndex={0}
|
|
165
|
-
className="flex-1"
|
|
164
|
+
className="justify-self-start w-50 flex-1"
|
|
166
165
|
/>
|
|
167
|
-
|
|
166
|
+
|
|
168
167
|
)}
|
|
169
168
|
|
|
170
|
-
|
|
171
|
-
|
|
169
|
+
|
|
170
|
+
|
|
172
171
|
{/* Grouping */}
|
|
173
172
|
{features.grouping && (
|
|
174
173
|
<GroupingDropdown
|
|
@@ -245,7 +244,7 @@ export function DataTableToolbar<TData extends DataRecord>({
|
|
|
245
244
|
</Button>
|
|
246
245
|
)}
|
|
247
246
|
|
|
248
|
-
</
|
|
249
|
-
|
|
247
|
+
</nav>
|
|
248
|
+
|
|
250
249
|
);
|
|
251
250
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import React, { useState } from 'react';
|
|
2
2
|
import { Button } from '../../Button/Button';
|
|
3
|
-
import { TableHead } from '../../Table/Table';
|
|
4
3
|
import { ChevronUp, ChevronDown,ChevronsUpDown } from 'lucide-react';
|
|
5
4
|
import { cn } from '../../../utils/cn';
|
|
6
5
|
import type { Header } from '@tanstack/react-table';
|
|
@@ -89,7 +88,7 @@ export function DraggableColumnHeader<TData>({
|
|
|
89
88
|
};
|
|
90
89
|
|
|
91
90
|
return (
|
|
92
|
-
<
|
|
91
|
+
<th
|
|
93
92
|
className={cn(
|
|
94
93
|
'px-3 py-2 text-sm font-medium text-left relative group',
|
|
95
94
|
isSortable && 'cursor-pointer hover:bg-sec-50',
|
|
@@ -97,10 +96,7 @@ export function DraggableColumnHeader<TData>({
|
|
|
97
96
|
dragOver && 'bg-main-50 border-main-200',
|
|
98
97
|
enableReordering && 'cursor-move'
|
|
99
98
|
)}
|
|
100
|
-
style={{
|
|
101
|
-
width: header.getSize ? header.getSize() : 150,
|
|
102
|
-
minWidth: header.getSize ? header.getSize() : 150,
|
|
103
|
-
}}
|
|
99
|
+
style={{}}
|
|
104
100
|
draggable={enableReordering}
|
|
105
101
|
onDragStart={handleDragStart}
|
|
106
102
|
onDragEnd={handleDragEnd}
|
|
@@ -143,6 +139,6 @@ export function DraggableColumnHeader<TData>({
|
|
|
143
139
|
)}
|
|
144
140
|
</div>
|
|
145
141
|
</div>
|
|
146
|
-
</
|
|
142
|
+
</th>
|
|
147
143
|
);
|
|
148
144
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { flexRender } from '@tanstack/react-table';
|
|
3
|
-
import { TableRow, TableCell } from '../../Table/Table';
|
|
4
3
|
import { ActionButtons } from './ActionButtons';
|
|
5
4
|
import { Input } from '../../Input/Input';
|
|
6
5
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../../Select/Select';
|
|
@@ -109,9 +108,9 @@ export function EditableRow<TData extends DataRecord>({
|
|
|
109
108
|
}));
|
|
110
109
|
|
|
111
110
|
return (
|
|
112
|
-
<
|
|
111
|
+
<tr>
|
|
113
112
|
{row.getVisibleCells().map((cell: any) => (
|
|
114
|
-
<
|
|
113
|
+
<td key={cell.id}>
|
|
115
114
|
{cell.column.id !== 'actions' ? (
|
|
116
115
|
renderEditField(cell.column, editingData[cell.column.id], (value) => {
|
|
117
116
|
if (typeof value === 'object' && value !== null) {
|
|
@@ -140,10 +139,10 @@ export function EditableRow<TData extends DataRecord>({
|
|
|
140
139
|
</Button>
|
|
141
140
|
</div>
|
|
142
141
|
)}
|
|
143
|
-
</
|
|
142
|
+
</td>
|
|
144
143
|
))}
|
|
145
144
|
{actions.length > 0 && (
|
|
146
|
-
<
|
|
145
|
+
<td>
|
|
147
146
|
<ActionButtons
|
|
148
147
|
row={row.original}
|
|
149
148
|
rowId={rowId}
|
|
@@ -153,8 +152,8 @@ export function EditableRow<TData extends DataRecord>({
|
|
|
153
152
|
isParent={isParent}
|
|
154
153
|
hierarchical={hierarchical}
|
|
155
154
|
/>
|
|
156
|
-
</
|
|
155
|
+
</td>
|
|
157
156
|
)}
|
|
158
|
-
</
|
|
157
|
+
</tr>
|
|
159
158
|
);
|
|
160
159
|
}
|
|
@@ -56,7 +56,7 @@ export function GroupingDropdown<TData extends DataRecord>({
|
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
return (
|
|
59
|
-
<Select>
|
|
59
|
+
<Select className="w-40">
|
|
60
60
|
<SelectTrigger asChild>
|
|
61
61
|
<Button
|
|
62
62
|
variant="outline"
|
|
@@ -66,7 +66,7 @@ export function GroupingDropdown<TData extends DataRecord>({
|
|
|
66
66
|
<span className="truncate">Grouping</span>
|
|
67
67
|
</Button>
|
|
68
68
|
</SelectTrigger>
|
|
69
|
-
<SelectContent
|
|
69
|
+
<SelectContent>
|
|
70
70
|
<SelectItem
|
|
71
71
|
value="no-grouping"
|
|
72
72
|
onClick={() => onGroupByChange(null)}
|