@@ -116,6 +116,7 @@ import {
116116 IrisGridContextMenuHandler ,
117117 IrisGridCopyCellMouseHandler ,
118118 IrisGridDataSelectMouseHandler ,
119+ IrisGridPartitionedTableMouseHandler ,
119120 IrisGridFilterMouseHandler ,
120121 IrisGridRowTreeMouseHandler ,
121122 IrisGridSortMouseHandler ,
@@ -734,6 +735,7 @@ class IrisGrid extends Component<IrisGridProps, IrisGridState> {
734735 new IrisGridContextMenuHandler ( this , dh ) ,
735736 new IrisGridDataSelectMouseHandler ( this ) ,
736737 new PendingMouseHandler ( this ) ,
738+ new IrisGridPartitionedTableMouseHandler ( this ) ,
737739 ] ;
738740 if ( canCopy ) {
739741 keyHandlers . push ( new CopyKeyHandler ( this ) ) ;
@@ -1781,12 +1783,12 @@ class IrisGrid extends Component<IrisGridProps, IrisGridState> {
17811783 * Rebuilds all the current filters. Necessary if something like the time zone has changed.
17821784 */
17831785 rebuildFilters ( ) : void {
1784- log . debug ( 'Rebuilding filters' ) ;
1785-
17861786 const { model } = this . props ;
17871787 const { advancedFilters, quickFilters } = this . state ;
17881788 const { columns, formatter } = model ;
17891789
1790+ log . debug ( 'Rebuilding filters' ) ;
1791+
17901792 const newAdvancedFilters = new Map ( ) ;
17911793 const newQuickFilters = new Map ( ) ;
17921794
@@ -1812,8 +1814,8 @@ class IrisGrid extends Component<IrisGridProps, IrisGridState> {
18121814 filter : this . makeQuickFilter ( column , text , formatter . timeZone ) ,
18131815 } ) ;
18141816 } ) ;
1815-
18161817 this . startLoading ( 'Rebuilding filters...' , { resetRanges : true } ) ;
1818+
18171819 this . setState ( {
18181820 quickFilters : newQuickFilters ,
18191821 advancedFilters : newAdvancedFilters ,
@@ -2024,11 +2026,15 @@ class IrisGrid extends Component<IrisGridProps, IrisGridState> {
20242026
20252027 async loadPartitionsTable ( model : PartitionedGridModel ) : Promise < void > {
20262028 try {
2027- const partitionConfig = await this . getInitialPartitionConfig ( model ) ;
2028- this . setState (
2029- { isSelectingPartition : true , partitionConfig } ,
2030- this . loadTableState
2031- ) ;
2029+ const { partitionConfig } = this . state ;
2030+ if ( ! partitionConfig ) {
2031+ this . startLoading ( 'Loading partitions...' , {
2032+ loadingCancelShown : false ,
2033+ resetRanges : true ,
2034+ } ) ;
2035+ this . initializePartitionConfig ( model ) ;
2036+ }
2037+ this . setState ( { isSelectingPartition : true } , this . loadTableState ) ;
20322038 } catch ( error ) {
20332039 if ( ! PromiseUtils . isCanceled ( error ) ) {
20342040 this . handleTableLoadError ( error ) ;
@@ -2037,19 +2043,9 @@ class IrisGrid extends Component<IrisGridProps, IrisGridState> {
20372043 }
20382044
20392045 /**
2040- * Gets the initial partition config for the currently set model.
2041- * Sorts the key table and gets the first key.
2042- * If the table is ticking, it will wait for the first tick.
2046+ * Initialize the partition config to the default partition.
20432047 */
2044- async getInitialPartitionConfig (
2045- model : PartitionedGridModel
2046- ) : Promise < PartitionConfig > {
2047- const { partitionConfig } = this . state ;
2048- if ( partitionConfig !== undefined ) {
2049- // User already has a partition selected, just use that
2050- return partitionConfig ;
2051- }
2052-
2048+ async initializePartitionConfig ( model : PartitionedGridModel ) : Promise < void > {
20532049 const keyTable = await this . pending . add (
20542050 model . partitionKeysTable ( ) ,
20552051 resolved => resolved . close ( )
@@ -2060,37 +2056,63 @@ class IrisGrid extends Component<IrisGridProps, IrisGridState> {
20602056 keyTable . applySort ( sorts ) ;
20612057 keyTable . setViewport ( 0 , 0 ) ;
20622058
2063- return new Promise ( ( resolve , reject ) => {
2064- // We want to wait for the first UPDATED event instead of just getting viewport data here
2065- // It's possible that the key table does not have any rows of data yet, so just wait until it does have one
2066- keyTable . addEventListener (
2067- dh . Table . EVENT_UPDATED ,
2068- ( event : CustomEvent < DhType . ViewportData > ) => {
2069- try {
2070- const { detail : data } = event ;
2071- if ( data . rows . length === 0 ) {
2072- // Table is empty, wait for the next updated event
2073- return ;
2074- }
2075- const row = data . rows [ 0 ] ;
2076- // Core JSAPI returns undefined for null table values, IrisGridPartitionSelector expects null
2077- // https://github.com/deephaven/deephaven-core/issues/5400
2078- const values = keyTable . columns . map (
2079- column => row . get ( column ) ?? null
2080- ) ;
2081- const newPartition : PartitionConfig = {
2082- partitions : values ,
2083- mode : 'partition' ,
2084- } ;
2085- keyTable . close ( ) ;
2086- resolve ( newPartition ) ;
2087- } catch ( e ) {
2088- keyTable . close ( ) ;
2089- reject ( e ) ;
2059+ // We want to wait for the first UPDATED event instead of just getting viewport data here
2060+ // It's possible that the key table does not have any rows of data yet, so just wait until it does have one
2061+ keyTable . addEventListener (
2062+ dh . Table . EVENT_UPDATED ,
2063+ ( event : CustomEvent < DhType . ViewportData > ) => {
2064+ try {
2065+ const { detail : data } = event ;
2066+ if ( data . rows . length === 0 ) {
2067+ // We received an update and the table is still empty. Stop showing the loading spinner so we know
2068+ this . stopLoading ( ) ;
2069+ return ;
20902070 }
2071+ const row = data . rows [ 0 ] ;
2072+ const values = keyTable . columns . map ( column => row . get ( column ) ) ;
2073+ const newPartition : PartitionConfig = {
2074+ partitions : values ,
2075+ mode : model . isPartitionAwareSourceTable ? 'partition' : 'keys' ,
2076+ } ;
2077+ keyTable . close ( ) ;
2078+ this . setState ( {
2079+ loadingSpinnerShown : false ,
2080+ partitionConfig : newPartition ,
2081+ } ) ;
2082+ } catch ( e ) {
2083+ keyTable . close ( ) ;
2084+ log . error ( 'Error getting initial partition config' , e ) ;
20912085 }
2086+ }
2087+ ) ;
2088+ }
2089+
2090+ /**
2091+ * Selects a partition key from the table based on the provided row index.
2092+ *
2093+ * @param rowIndex The index of the row from which the partition will be selected.
2094+ * @returns A promise that resolves when the partition key has been successfully selected.
2095+ */
2096+ selectPartitionKeyFromTable ( rowIndex : GridRangeIndex ) : void {
2097+ const { model } = this . props ;
2098+ assertNotNull ( rowIndex ) ;
2099+ if ( isPartitionedGridModel ( model ) ) {
2100+ const data = this . getRowDataMap ( rowIndex ) ;
2101+ const partitionColumnSet = new Set (
2102+ model . partitionColumns . map ( column => column . name )
20922103 ) ;
2093- } ) ;
2104+ const values = Object . entries ( data )
2105+ . filter ( ( [ key , _ ] ) => partitionColumnSet . has ( key ) )
2106+ . map ( ( [ key , columnData ] ) => columnData . value ) ;
2107+ const newPartition : PartitionConfig = {
2108+ partitions : values ,
2109+ mode : 'partition' ,
2110+ } ;
2111+ this . setState ( {
2112+ isSelectingPartition : true ,
2113+ partitionConfig : newPartition ,
2114+ } ) ;
2115+ }
20942116 }
20952117
20962118 copyCell (
@@ -2532,7 +2554,10 @@ class IrisGrid extends Component<IrisGridProps, IrisGridState> {
25322554
25332555 handlePartitionChange ( partitionConfig : PartitionConfig ) : void {
25342556 this . startLoading ( 'Partitioning...' ) ;
2535- this . setState ( { partitionConfig } ) ;
2557+ const { partitionConfig : prevConfig } = this . state ;
2558+ if ( prevConfig !== partitionConfig ) {
2559+ this . setState ( { partitionConfig } ) ;
2560+ }
25362561 }
25372562
25382563 handleTableLoadError ( error : unknown ) : void {
@@ -4700,15 +4725,13 @@ class IrisGrid extends Component<IrisGridProps, IrisGridState> {
47004725 unmountOnExit
47014726 >
47024727 < div className = "iris-grid-partition-selector-wrapper iris-grid-bar iris-grid-bar-primary" >
4703- { isPartitionedGridModel ( model ) &&
4704- model . isPartitionRequired &&
4705- partitionConfig && (
4706- < IrisGridPartitionSelector
4707- model = { model }
4708- partitionConfig = { partitionConfig }
4709- onChange = { this . handlePartitionChange }
4710- />
4711- ) }
4728+ { isPartitionedGridModel ( model ) && model . isPartitionRequired && (
4729+ < IrisGridPartitionSelector
4730+ model = { model }
4731+ partitionConfig = { partitionConfig }
4732+ onChange = { this . handlePartitionChange }
4733+ />
4734+ ) }
47124735 </ div >
47134736 </ CSSTransition >
47144737 < CSSTransition
0 commit comments