11/* eslint class-methods-use-this: "off" */
2+ /* eslint no-underscore-dangle: "off" */
23import memoize from 'memoize-one' ;
34import type { dh as DhType } from '@deephaven/jsapi-types' ;
45import Log from '@deephaven/log' ;
@@ -10,7 +11,7 @@ import {
1011 type CancelablePromise ,
1112} from '@deephaven/utils' ;
1213import { GridRange , type ModelIndex } from '@deephaven/grid' ;
13- import { type ColumnName , type UITotalsTableConfig } from './CommonTypes' ;
14+ import { type ColumnName } from './CommonTypes' ;
1415import type { DisplayColumn } from './IrisGridModel' ;
1516import ColumnHeaderGroup from './ColumnHeaderGroup' ;
1617import IrisGridModel from './IrisGridModel' ;
@@ -20,8 +21,8 @@ import IrisGridUtils from './IrisGridUtils';
2021import type { IrisGridThemeType } from './IrisGridTheme' ;
2122import {
2223 getSimplePivotColumnMap ,
24+ isColumnMapComplete ,
2325 KEY_TABLE_PIVOT_COLUMN ,
24- PIVOT_COLUMN_PREFIX ,
2526 TOTALS_COLUMN ,
2627 type KeyColumnArray ,
2728 type KeyTableSubscriptionData ,
@@ -74,6 +75,8 @@ class IrisGridSimplePivotModel extends IrisGridModel {
7475
7576 private totalsRowMap : Map < string , unknown > ;
7677
78+ private _layoutHints : DhType . LayoutHints | null | undefined ;
79+
7780 constructor (
7881 dh : typeof DhType ,
7982 table : DhType . Table ,
@@ -114,6 +117,16 @@ class IrisGridSimplePivotModel extends IrisGridModel {
114117 this . pivotWidget = pivotWidget ;
115118 this . schema = schema ;
116119
120+ this . _layoutHints = {
121+ backColumns : [ TOTALS_COLUMN ] ,
122+ hiddenColumns : [ ] ,
123+ frozenColumns : [ ] ,
124+ columnGroups : [ ] ,
125+ areSavedLayoutsAllowed : false ,
126+ frontColumns : [ ] ,
127+ searchDisplayMode : this . dh . SearchDisplayMode . SEARCH_DISPLAY_HIDE ,
128+ } ;
129+
117130 this . startListeningToKeyTable ( ) ;
118131
119132 this . startListeningToSchema ( ) ;
@@ -165,7 +178,7 @@ class IrisGridSimplePivotModel extends IrisGridModel {
165178 }
166179
167180 /**
168- * Add displayName property from the column map to the given column
181+ * Add displayName property to the given column
169182 * @param column Column to add displayName to
170183 * @param columnMap Column name map
171184 * @returns Column with the displayName
@@ -177,12 +190,7 @@ class IrisGridSimplePivotModel extends IrisGridModel {
177190 return new Proxy ( column , {
178191 get : ( target , prop ) => {
179192 if ( prop === 'displayName' ) {
180- if ( ! columnMap . has ( column . name ) ) {
181- return column . name . startsWith ( PIVOT_COLUMN_PREFIX )
182- ? ''
183- : column . name ;
184- }
185- return columnMap . get ( column . name ) ;
193+ return columnMap . get ( column . name ) ?? column . name ;
186194 }
187195 return Reflect . get ( target , prop ) ;
188196 } ,
@@ -193,27 +201,20 @@ class IrisGridSimplePivotModel extends IrisGridModel {
193201 (
194202 columnMap : SimplePivotColumnMap ,
195203 schema : SimplePivotSchema
196- ) : readonly ColumnHeaderGroup [ ] => {
197- log . debug ( 'getPivotColumnHeaderGroups' , schema . pivotDescription , {
198- schema,
199- columnMap : JSON . stringify ( [ ...columnMap ] ) ,
200- modelColumns : JSON . stringify ( this . model . columns . map ( c => c . name ) ) ,
201- } ) ;
202- return [
203- new ColumnHeaderGroup ( {
204- name : schema . pivotDescription ,
205- children : schema . rowColNames ,
206- depth : 1 ,
207- childIndexes : schema . rowColNames . map ( ( _ , index ) => index ) ,
208- } ) ,
209- new ColumnHeaderGroup ( {
210- name : schema . columnColNames . join ( ', ' ) ,
211- children : [ ...columnMap . keys ( ) ] ,
212- depth : 1 ,
213- childIndexes : [ ...columnMap . keys ( ) ] . map ( ( _ , index ) => index ) ,
214- } ) ,
215- ] ;
216- }
204+ ) : readonly ColumnHeaderGroup [ ] => [
205+ new ColumnHeaderGroup ( {
206+ name : schema . pivotDescription ,
207+ children : schema . rowColNames ,
208+ depth : 1 ,
209+ childIndexes : schema . rowColNames . map ( ( _ , index ) => index ) ,
210+ } ) ,
211+ new ColumnHeaderGroup ( {
212+ name : schema . columnColNames . join ( ', ' ) ,
213+ children : [ ...columnMap . keys ( ) ] ,
214+ depth : 1 ,
215+ childIndexes : [ ...columnMap . keys ( ) ] . map ( ( _ , index ) => index ) ,
216+ } ) ,
217+ ]
217218 ) ;
218219
219220 get initialColumnHeaderGroups ( ) : readonly ColumnHeaderGroup [ ] {
@@ -275,24 +276,6 @@ class IrisGridSimplePivotModel extends IrisGridModel {
275276 return false ;
276277 }
277278
278- set totalsConfig ( _ : UITotalsTableConfig | null ) {
279- // no-op
280- }
281-
282- get columnHeaderGroupMap ( ) : ReadonlyMap < string , ColumnHeaderGroup > {
283- log . debug ( 'get columnHeaderGroupMap' ) ;
284- return this . model . columnHeaderGroupMap ;
285- }
286-
287- get columnHeaderGroups ( ) : readonly ColumnHeaderGroup [ ] {
288- log . debug ( 'get columnHeaderGroups' ) ;
289- return this . model . columnHeaderGroups ;
290- }
291-
292- set columnHeaderGroups ( columnHeaderGroups : readonly ColumnHeaderGroup [ ] ) {
293- this . model . columnHeaderGroups = columnHeaderGroups ;
294- }
295-
296279 get rowCount ( ) : number {
297280 return this . model . rowCount + ( this . schema . hasTotals ? 1 : 0 ) ;
298281 }
@@ -379,6 +362,7 @@ class IrisGridSimplePivotModel extends IrisGridModel {
379362 }
380363
381364 handleKeyTableUpdate ( e : { detail : KeyTableSubscriptionData } ) : void {
365+ log . debug ( 'Key table updated' ) ;
382366 const pivotIdColumn = this . keyTable . findColumn ( KEY_TABLE_PIVOT_COLUMN ) ;
383367 const columns = this . keyTable . columns . filter (
384368 c => c . name !== KEY_TABLE_PIVOT_COLUMN
@@ -392,43 +376,46 @@ class IrisGridSimplePivotModel extends IrisGridModel {
392376 keyColumns . push ( [ TOTALS_COLUMN , 'Totals' ] ) ;
393377 }
394378 const columnMap = new Map ( keyColumns ) ;
395- log . debug (
396- 'Key table updated' ,
397- this . model . columns . map ( c => c . name ) ,
398- JSON . stringify ( [ ...columnMap ] ) ,
399- Boolean ( this . nextModel ) ,
400- Boolean ( this . nextColumnMap )
401- ) ;
402- if ( this . nextModel != null ) {
403- if (
404- this . nextModel . columns . some (
405- c => c . name . startsWith ( PIVOT_COLUMN_PREFIX ) && ! columnMap . has ( c . name )
406- )
407- ) {
408- log . debug ( 'next model not null, but columns do not match' ) ;
409- this . nextColumnMap = columnMap ;
379+
380+ if ( this . nextModel == null ) {
381+ if ( isColumnMapComplete ( columnMap , this . model . columns ) ) {
382+ log . debug2 (
383+ 'Key table update matches the existing model, update columns'
384+ ) ;
385+ this . columnMap = columnMap ;
386+ this . columnHeaderGroups = this . getCachedColumnHeaderGroups (
387+ this . columnMap ,
388+ this . schema
389+ ) ;
390+ this . dispatchEvent (
391+ new EventShimCustomEvent ( IrisGridModel . EVENT . COLUMNS_CHANGED , {
392+ detail : this . columns ,
393+ } )
394+ ) ;
410395 } else {
411- log . debug ( 'next model not null, all columns match' ) ;
412- assertNotNull ( this . nextTotalsTable ) ;
413- this . setModel ( this . nextModel , columnMap , this . nextTotalsTable ) ;
414- this . nextModel = null ;
396+ log . debug2 (
397+ 'Key table update does not match the existing model, save column map for the next schema update'
398+ ) ;
399+ this . nextColumnMap = columnMap ;
415400 }
416- } else if (
417- this . model . columns . some (
418- c => c . name . startsWith ( PIVOT_COLUMN_PREFIX ) && ! columnMap . has ( c . name )
419- )
420- ) {
421- log . debug (
422- 'next model is null, columns do not match - save nextColumnMap'
401+ return ;
402+ }
403+ if ( isColumnMapComplete ( columnMap , this . nextModel . columns ) ) {
404+ log . debug2 ( 'Key table update matches the saved model, update the model' ) ;
405+ assertNotNull ( this . nextTotalsTable ) ;
406+ this . setModel ( this . nextModel , columnMap , this . nextTotalsTable ) ;
407+ this . nextModel = null ;
408+ this . nextTotalsTable = null ;
409+ } else {
410+ log . debug2 (
411+ 'Key table update does not match the saved model, save column map for the next schema update'
423412 ) ;
424- // TODO: check if current model columns match?
425413 this . nextColumnMap = columnMap ;
426414 }
427415 }
428416
429417 async handleSchemaUpdate ( e : DhType . Event < DhType . Widget > ) : Promise < void > {
430418 log . debug ( 'Schema updated' ) ;
431- // Get the object, and make sure the keytable is fetched and usable
432419 const tables = e . detail . exportedObjects ;
433420 const tablePromise = tables [ 0 ] . fetch ( ) ;
434421 const totalsTablePromise = tables . length === 2 ? tables [ 1 ] . fetch ( ) : null ;
@@ -456,17 +443,7 @@ class IrisGridSimplePivotModel extends IrisGridModel {
456443 ) ;
457444
458445 get layoutHints ( ) : DhType . LayoutHints | null | undefined {
459- // log.debug('get layoutHints');
460- // TODO: memoize
461- return {
462- backColumns : [ TOTALS_COLUMN ] ,
463- hiddenColumns : [ ] ,
464- frozenColumns : [ ] ,
465- columnGroups : [ ] ,
466- areSavedLayoutsAllowed : false ,
467- frontColumns : [ ] ,
468- searchDisplayMode : this . dh . SearchDisplayMode . SEARCH_DISPLAY_HIDE ,
469- } ;
446+ return this . _layoutHints ;
470447 }
471448
472449 /**
@@ -544,16 +521,14 @@ class IrisGridSimplePivotModel extends IrisGridModel {
544521 }
545522 this . dispatchEvent (
546523 new EventShimCustomEvent ( IrisGridModel . EVENT . COLUMNS_CHANGED , {
547- detail : model . columns ,
524+ detail : this . columns ,
548525 } )
549526 ) ;
550527 }
551528
552529 setNextSchema (
553530 pivotTablesPromise : Promise < [ DhType . Table , DhType . Table ] >
554531 ) : void {
555- log . debug2 ( 'setNextSchema' ) ;
556-
557532 if ( this . schemaPromise ) {
558533 this . schemaPromise . cancel ( ) ;
559534 }
@@ -567,17 +542,31 @@ class IrisGridSimplePivotModel extends IrisGridModel {
567542 ) ;
568543 this . schemaPromise
569544 . then ( ( [ table , totalsTable ] ) => {
545+ log . debug ( 'Schema updated' ) ;
570546 this . schemaPromise = null ;
571547 const model = makeModel ( this . dh , table , this . formatter ) ;
572548 if ( this . nextColumnMap != null ) {
573- log . debug (
574- 'Schema updated, nextColumnMap is not null, setting new model'
575- ) ;
576- this . setModel ( model , this . nextColumnMap , totalsTable ) ;
577- this . nextColumnMap = null ;
549+ if ( isColumnMapComplete ( this . nextColumnMap , model . columns ) ) {
550+ log . debug2 (
551+ 'Schema updated, set new model with the saved column map'
552+ ) ;
553+ this . setModel ( model , this . nextColumnMap , totalsTable ) ;
554+ this . nextColumnMap = null ;
555+ } else {
556+ log . debug2 (
557+ 'Saved column map does not match the new model, save the model for the next key table update'
558+ ) ;
559+ this . nextModel = model ;
560+ this . nextTotalsTable = totalsTable ;
561+ }
562+ return ;
563+ }
564+ if ( isColumnMapComplete ( this . columnMap , model . columns ) ) {
565+ log . debug2 ( 'Schema updated, set new model with existing column map' ) ;
566+ this . setModel ( model , this . columnMap , totalsTable ) ;
578567 } else {
579- log . debug (
580- 'Schema updated, nextColumnMap is null , save new model as nextModel '
568+ log . debug2 (
569+ 'Existing column map does not match the new model , save the model for the next key table update '
581570 ) ;
582571 this . nextModel = model ;
583572 this . nextTotalsTable = totalsTable ;
0 commit comments