1
1
/* eslint-disable react/jsx-props-no-spreading */
2
2
/* eslint-disable react/no-unused-state */
3
3
import React , { Component , type ReactElement , type RefObject } from 'react' ;
4
+ import { IrisGridModel } from '@deephaven/iris-grid' ;
4
5
import ConnectedIrisGridPanel , {
5
6
type IrisGridPanel ,
6
7
type OwnProps as IrisGridPanelOwnProps ,
@@ -16,6 +17,7 @@ export interface PandasPanelProps extends IrisGridPanelOwnProps {
16
17
interface PandasPanelState {
17
18
shouldFocusGrid : boolean ;
18
19
panelState : PanelState | null ;
20
+ makeModel : IrisGridPanelOwnProps [ 'makeModel' ] ;
19
21
}
20
22
21
23
/**
@@ -28,11 +30,17 @@ class PandasPanel extends Component<PandasPanelProps, PandasPanelState> {
28
30
29
31
static COMPONENT = 'PandasPanel' ;
30
32
33
+ // eslint-disable-next-line react/sort-comp
34
+ private irisGridRef : RefObject < IrisGridPanel > ;
35
+
36
+ private model : IrisGridModel | null = null ;
37
+
31
38
constructor ( props : PandasPanelProps ) {
32
39
super ( props ) ;
33
40
34
41
this . irisGridRef = React . createRef ( ) ;
35
42
43
+ this . handleDisconnect = this . handleDisconnect . bind ( this ) ;
36
44
this . handleReload = this . handleReload . bind ( this ) ;
37
45
this . handleGridStateChange = this . handleGridStateChange . bind ( this ) ;
38
46
this . handlePanelStateUpdate = this . handlePanelStateUpdate . bind ( this ) ;
@@ -41,10 +49,58 @@ class PandasPanel extends Component<PandasPanelProps, PandasPanelState> {
41
49
this . state = {
42
50
shouldFocusGrid : false ,
43
51
panelState, // Dehydrated panel state that can load this panel
52
+ makeModel : this . wrapMakeModel ( props . makeModel ) ,
53
+ } ;
54
+ }
55
+
56
+ componentDidUpdate ( prevProps : Readonly < PandasPanelProps > ) : void {
57
+ const { makeModel : prevMakeModel } = prevProps ;
58
+ const { makeModel } = this . props ;
59
+ if ( prevMakeModel !== makeModel ) {
60
+ this . setState ( { makeModel : this . wrapMakeModel ( makeModel ) } ) ;
61
+ }
62
+ }
63
+
64
+ componentWillUnmount ( ) : void {
65
+ if ( this . model != null ) {
66
+ this . stopListening ( this . model ) ;
67
+ }
68
+ }
69
+
70
+ private wrapMakeModel (
71
+ makeModel : IrisGridPanelOwnProps [ 'makeModel' ]
72
+ ) : IrisGridPanelOwnProps [ 'makeModel' ] {
73
+ return async ( ) => {
74
+ // Need to listen for disconnect in the model, so we know when to throw this makeModel away
75
+ const model = await makeModel ( ) ;
76
+ if ( this . model != null ) {
77
+ this . stopListening ( this . model ) ;
78
+ }
79
+ this . model = model ;
80
+ this . startListening ( model ) ;
81
+ return model ;
44
82
} ;
45
83
}
46
84
47
- irisGridRef : RefObject < IrisGridPanel > ;
85
+ private startListening ( model : IrisGridModel ) : void {
86
+ model . addEventListener (
87
+ IrisGridModel . EVENT . DISCONNECT ,
88
+ this . handleDisconnect
89
+ ) ;
90
+ }
91
+
92
+ private stopListening ( model : IrisGridModel ) : void {
93
+ model . removeEventListener (
94
+ IrisGridModel . EVENT . DISCONNECT ,
95
+ this . handleDisconnect
96
+ ) ;
97
+ }
98
+
99
+ private handleDisconnect ( ) : void {
100
+ // Once a Pandas widget is closed, the underlying table is closed and cannot be reconnected to.
101
+ // Reset the model to undefined so IrisGridPanel doesn't try to use it anymore.
102
+ this . irisGridRef . current ?. setState ( { model : undefined } ) ;
103
+ }
48
104
49
105
handleReload ( ) : void {
50
106
this . irisGridRef . current ?. initModel ( ) ;
@@ -70,12 +126,14 @@ class PandasPanel extends Component<PandasPanelProps, PandasPanelState> {
70
126
}
71
127
72
128
render ( ) : ReactElement {
129
+ const { makeModel } = this . state ;
73
130
return (
74
131
< ConnectedIrisGridPanel
75
132
ref = { this . irisGridRef }
76
133
onStateChange = { this . handleGridStateChange }
77
134
onPanelStateUpdate = { this . handlePanelStateUpdate }
78
135
{ ...this . props }
136
+ makeModel = { makeModel }
79
137
>
80
138
< PandasReloadButton onClick = { this . handleReload } />
81
139
</ ConnectedIrisGridPanel >
0 commit comments