@@ -46,6 +46,7 @@ import {
46
46
BoundedAxisRange ,
47
47
isExpandableGridModel ,
48
48
isDeletableGridModel ,
49
+ isExpandableColumnGridModel ,
49
50
} from '@deephaven/grid' ;
50
51
import {
51
52
dhEye ,
@@ -387,6 +388,9 @@ export interface IrisGridState {
387
388
// Current ongoing copy operation
388
389
copyOperation : CopyOperation | null ;
389
390
391
+ // Map of column indexes to their current names
392
+ columnNameMap : Map < ModelIndex , ColumnName > ;
393
+
390
394
// The filter that is currently being applied. Reset after update is received
391
395
loadingText : string | null ;
392
396
loadingScrimProgress : number | null ;
@@ -791,6 +795,9 @@ class IrisGrid extends Component<IrisGridProps, IrisGridState> {
791
795
focusedFilterBarColumn : null ,
792
796
metricCalculator,
793
797
metrics : undefined ,
798
+ columnNameMap : new Map (
799
+ model . columns . map ( ( col , index ) => [ index , col . name ] )
800
+ ) ,
794
801
795
802
partitionConfig :
796
803
partitionConfig ??
@@ -1102,6 +1109,7 @@ class IrisGrid extends Component<IrisGridProps, IrisGridState> {
1102
1109
getCachedOptionItems = memoize (
1103
1110
(
1104
1111
isChartBuilderAvailable : boolean ,
1112
+ isOrganizeColumnsAvailable : boolean ,
1105
1113
isCustomColumnsAvailable : boolean ,
1106
1114
isFormatColumnsAvailable : boolean ,
1107
1115
isRollupAvailable : boolean ,
@@ -1126,11 +1134,13 @@ class IrisGrid extends Component<IrisGridProps, IrisGridState> {
1126
1134
icon : dhGraphLineUp ,
1127
1135
} ) ;
1128
1136
}
1129
- optionItems . push ( {
1130
- type : OptionType . VISIBILITY_ORDERING_BUILDER ,
1131
- title : 'Organize Columns' ,
1132
- icon : dhEye ,
1133
- } ) ;
1137
+ if ( isOrganizeColumnsAvailable ) {
1138
+ optionItems . push ( {
1139
+ type : OptionType . VISIBILITY_ORDERING_BUILDER ,
1140
+ title : 'Organize Columns' ,
1141
+ icon : dhEye ,
1142
+ } ) ;
1143
+ }
1134
1144
if ( isFormatColumnsAvailable ) {
1135
1145
optionItems . push ( {
1136
1146
type : OptionType . CONDITIONAL_FORMATTING ,
@@ -1814,6 +1824,12 @@ class IrisGrid extends Component<IrisGridProps, IrisGridState> {
1814
1824
rebuildFilters ( ) : void {
1815
1825
const { model } = this . props ;
1816
1826
const { advancedFilters, quickFilters } = this . state ;
1827
+
1828
+ if ( advancedFilters . size === 0 && quickFilters . size === 0 ) {
1829
+ log . debug ( 'No filters to rebuild' ) ;
1830
+ return ;
1831
+ }
1832
+
1817
1833
const { columns, formatter } = model ;
1818
1834
1819
1835
log . debug ( 'Rebuilding filters' ) ;
@@ -2483,6 +2499,36 @@ class IrisGrid extends Component<IrisGridProps, IrisGridState> {
2483
2499
} ) ;
2484
2500
}
2485
2501
2502
+ toggleExpandColumn ( modelIndex : ModelIndex ) : void {
2503
+ log . debug2 ( 'Toggle expand column' , modelIndex ) ;
2504
+ const { model } = this . props ;
2505
+ if ( isExpandableColumnGridModel ( model ) && model . hasExpandableColumns ) {
2506
+ model . setColumnExpanded ( modelIndex , ! model . isColumnExpanded ( modelIndex ) ) ;
2507
+ }
2508
+ }
2509
+
2510
+ expandAllColumns ( ) : void {
2511
+ log . debug2 ( 'Expand all columns' ) ;
2512
+ const { model } = this . props ;
2513
+ if (
2514
+ isExpandableColumnGridModel ( model ) &&
2515
+ model . isExpandAllColumnsAvailable
2516
+ ) {
2517
+ model . expandAllColumns ( ) ;
2518
+ }
2519
+ }
2520
+
2521
+ collapseAllColumns ( ) : void {
2522
+ log . debug2 ( 'Collapse all columns' ) ;
2523
+ const { model } = this . props ;
2524
+ if (
2525
+ isExpandableColumnGridModel ( model ) &&
2526
+ model . isExpandAllColumnsAvailable
2527
+ ) {
2528
+ model . collapseAllColumns ( ) ;
2529
+ }
2530
+ }
2531
+
2486
2532
handleColumnVisibilityChanged (
2487
2533
modelIndexes : readonly ModelIndex [ ] ,
2488
2534
isVisible : boolean
@@ -2653,6 +2699,42 @@ class IrisGrid extends Component<IrisGridProps, IrisGridState> {
2653
2699
this . grid ?. forceUpdate ( ) ;
2654
2700
}
2655
2701
2702
+ /**
2703
+ * Update the user column widths when indexes change after expand/collapse.
2704
+ */
2705
+ updateUserColumnWidths ( ) : void {
2706
+ const { model } = this . props ;
2707
+ const { metricCalculator, columnNameMap : prevColumnNameMap } = this . state ;
2708
+ const columnNameMap = new Map (
2709
+ model . columns . map ( ( col , index ) => [ index , col . name ] )
2710
+ ) ;
2711
+
2712
+ // Map userColumnWidths to column names
2713
+ const userColumnWidths = metricCalculator . getUserColumnWidths ( ) ;
2714
+ const namedUserColumnWidths = new Map < string , number > ( ) ;
2715
+ userColumnWidths . forEach ( ( width , modelIndex ) => {
2716
+ const name = prevColumnNameMap . get ( modelIndex ) ;
2717
+ if ( width != null && name != null ) {
2718
+ namedUserColumnWidths . set ( name , width ) ;
2719
+ }
2720
+ metricCalculator . resetColumnWidth ( modelIndex ) ;
2721
+ } ) ;
2722
+
2723
+ // Restore the column widths with new indexes
2724
+ namedUserColumnWidths . forEach ( ( width , name ) => {
2725
+ const modelIndex = model . getColumnIndexByName ( name ) ;
2726
+ if ( modelIndex != null ) {
2727
+ metricCalculator . setColumnWidth ( modelIndex , width ) ;
2728
+ }
2729
+ } ) ;
2730
+
2731
+ // We store metrics in both Grid and IrisGrid state, keep them in sync
2732
+ this . setState ( {
2733
+ metrics : this . grid ?. updateMetrics ( ) ,
2734
+ columnNameMap,
2735
+ } ) ;
2736
+ }
2737
+
2656
2738
toggleSort ( columnIndex : VisibleIndex , addToExisting : boolean ) : void {
2657
2739
log . info ( 'Toggling sort for column' , columnIndex ) ;
2658
2740
@@ -3412,8 +3494,11 @@ class IrisGrid extends Component<IrisGridProps, IrisGridState> {
3412
3494
log . debug ( 'custom columns changed' ) ;
3413
3495
const { isReady } = this . state ;
3414
3496
if ( isReady ) {
3497
+ this . updateUserColumnWidths ( ) ;
3498
+
3499
+ // Make sure stopLoading() is called after the updateMetrics call in updateUserColumnWidths,
3500
+ // otherwise IrisGridModelUpdater queues an extra setViewport based on old metrics.
3415
3501
this . stopLoading ( ) ;
3416
- this . grid ?. forceUpdate ( ) ;
3417
3502
} else {
3418
3503
this . loadTableState ( ) ;
3419
3504
}
@@ -4631,6 +4716,7 @@ class IrisGrid extends Component<IrisGridProps, IrisGridState> {
4631
4716
4632
4717
const optionItems = this . getCachedOptionItems (
4633
4718
onCreateChart !== undefined && model . isChartBuilderAvailable ,
4719
+ model . isOrganizeColumnsAvailable ,
4634
4720
model . isCustomColumnsAvailable ,
4635
4721
model . isFormatColumnsAvailable ,
4636
4722
model . isRollupAvailable ,
0 commit comments