@@ -33,11 +33,16 @@ import {
33
33
DescriptionListTerm ,
34
34
DescriptionListDescription ,
35
35
Divider ,
36
+ Select ,
37
+ SelectVariant ,
38
+ SelectOption ,
36
39
} from "@patternfly/react-core"
37
40
38
41
import ProfileSelect from "./ProfileSelect"
39
42
import DashboardSelect from "./DashboardSelect"
40
43
import ProfileWatcher from "../tray/watchers/profile/list"
44
+ import ProfileStatusWatcher from "../tray/watchers/profile/status"
45
+ import UpdateFunction from "../tray/update"
41
46
import { handleBoot , handleShutdown } from "../controller/profile/actions"
42
47
43
48
import "../../web/scss/components/Dashboard/Description.scss"
@@ -49,9 +54,12 @@ type Props = {
49
54
50
55
type State = {
51
56
watcher : ProfileWatcher
57
+ statusWatcher : ProfileStatusWatcher
52
58
selectedProfile ?: string
53
59
profiles ?: Profiles . Profile [ ]
54
60
catastrophicError ?: unknown
61
+
62
+ updateCount : number
55
63
}
56
64
57
65
export default class ProfileExplorer extends React . PureComponent < Props , State > {
@@ -60,6 +68,12 @@ export default class ProfileExplorer extends React.PureComponent<Props, State> {
60
68
this . init ( )
61
69
}
62
70
71
+ private readonly statusWatcherUpdateFn : UpdateFunction = ( ) => {
72
+ this . setState ( ( curState ) => ( {
73
+ updateCount : ( curState ?. updateCount || 0 ) + 1 ,
74
+ } ) )
75
+ }
76
+
63
77
private readonly _handleProfileSelection = ( selectedProfile : string ) => {
64
78
this . setState ( { selectedProfile } )
65
79
@@ -70,7 +84,7 @@ export default class ProfileExplorer extends React.PureComponent<Props, State> {
70
84
71
85
private updateDebouncer : null | ReturnType < typeof setTimeout > = null
72
86
73
- private readonly updateFn = ( ) => {
87
+ private readonly profileWatcherUpdateFn = ( ) => {
74
88
if ( this . updateDebouncer ) {
75
89
clearTimeout ( this . updateDebouncer )
76
90
}
@@ -117,7 +131,10 @@ export default class ProfileExplorer extends React.PureComponent<Props, State> {
117
131
118
132
private async init ( ) {
119
133
try {
120
- const watcher = await new ProfileWatcher ( this . updateFn , await Profiles . profilesPath ( { } , true ) ) . init ( )
134
+ const watcher = await new ProfileWatcher (
135
+ this . profileWatcherUpdateFn ,
136
+ await Profiles . profilesPath ( { } , true )
137
+ ) . init ( )
121
138
this . setState ( {
122
139
watcher,
123
140
profiles : [ ] ,
@@ -129,13 +146,19 @@ export default class ProfileExplorer extends React.PureComponent<Props, State> {
129
146
}
130
147
131
148
public componentWillUnmount ( ) {
132
- if ( this . state && this . state . watcher ) {
133
- this . state . watcher . close ( )
149
+ this . state ?. watcher ?. close ( )
150
+ }
151
+
152
+ public componentDidUpdate ( prevProps : Props , prevState : State ) {
153
+ if ( prevState ?. selectedProfile !== this . state ?. selectedProfile ) {
154
+ if ( ! this . state ?. selectedProfile ) return
155
+ const statusWatcher = new ProfileStatusWatcher ( this . state . selectedProfile , this . statusWatcherUpdateFn )
156
+ this . setState ( { statusWatcher } )
134
157
}
135
158
}
136
159
137
160
public render ( ) {
138
- if ( this . state && this . state . catastrophicError ) {
161
+ if ( this . state ? .catastrophicError ) {
139
162
return "Internal Error"
140
163
} else if ( ! this . state || ! this . state . profiles || ! this . state . selectedProfile ) {
141
164
return < Loading />
@@ -146,20 +169,38 @@ export default class ProfileExplorer extends React.PureComponent<Props, State> {
146
169
profile = { this . state . selectedProfile }
147
170
profiles = { this . state . profiles }
148
171
onSelectProfile = { this . _handleProfileSelection }
172
+ profileReadiness = { this . state . statusWatcher ?. readiness }
173
+ profileStatus = { this . state . statusWatcher }
149
174
/>
150
175
</ div >
151
176
)
152
177
}
153
178
}
154
179
}
155
180
156
- class ProfileCard extends React . PureComponent < {
181
+ type ProfileCardProps = {
157
182
profile : string
158
183
profiles : Profiles . Profile [ ]
159
184
onSelectProfile : ( profile : string ) => void
160
- } > {
185
+
186
+ profileReadiness : string
187
+ profileStatus : ProfileStatusWatcher
188
+ }
189
+
190
+ type ProfileCardState = {
191
+ isOpen : boolean
192
+ }
193
+
194
+ class ProfileCard extends React . PureComponent < ProfileCardProps , ProfileCardState > {
195
+ public constructor ( props : ProfileCardProps ) {
196
+ super ( props )
197
+ this . state = {
198
+ isOpen : false ,
199
+ }
200
+ }
161
201
private readonly _handleBoot = ( ) => handleBoot ( this . props . profile )
162
202
private readonly _handleShutdown = ( ) => handleShutdown ( this . props . profile )
203
+ private readonly _onToggle = ( ) => this . setState ( { isOpen : ! this . state . isOpen } )
163
204
164
205
private title ( ) {
165
206
return (
@@ -174,7 +215,28 @@ class ProfileCard extends React.PureComponent<{
174
215
}
175
216
176
217
private actions ( ) {
177
- return "Status: pending"
218
+ const StatusTitle = ( { readiness } : { readiness : string | undefined } ) => (
219
+ < React . Fragment >
220
+ < span > Status</ span >
221
+ < div
222
+ className = { `codeflare--profile-explorer--status-light codeflare--profile-explorer--status-light--${ readiness } ` }
223
+ > </ div >
224
+ </ React . Fragment >
225
+ )
226
+ return (
227
+ < Select
228
+ className = "codeflare--profile-explorer--select-status"
229
+ variant = { SelectVariant . single }
230
+ placeholderText = { < StatusTitle readiness = { this . props . profileStatus ?. readiness } /> }
231
+ label = "Status select"
232
+ onToggle = { this . _onToggle }
233
+ isOpen = { this . state . isOpen }
234
+ aria-labelledby = "select-status-label"
235
+ >
236
+ < SelectOption isPlaceholder > { this . props . profileStatus ?. head . label } </ SelectOption >
237
+ < SelectOption isPlaceholder > { this . props . profileStatus ?. workers . label } </ SelectOption >
238
+ </ Select >
239
+ )
178
240
}
179
241
180
242
private body ( ) {
0 commit comments