@@ -33,11 +33,16 @@ import {
3333 DescriptionListTerm ,
3434 DescriptionListDescription ,
3535 Divider ,
36+ Select ,
37+ SelectVariant ,
38+ SelectOption ,
3639} from "@patternfly/react-core"
3740
3841import ProfileSelect from "./ProfileSelect"
3942import DashboardSelect from "./DashboardSelect"
4043import ProfileWatcher from "../tray/watchers/profile/list"
44+ import ProfileStatusWatcher from "../tray/watchers/profile/status"
45+ import UpdateFunction from "../tray/update"
4146import { handleBoot , handleShutdown } from "../controller/profile/actions"
4247
4348import "../../web/scss/components/Dashboard/Description.scss"
@@ -49,9 +54,12 @@ type Props = {
4954
5055type State = {
5156 watcher : ProfileWatcher
57+ statusWatcher : ProfileStatusWatcher
5258 selectedProfile ?: string
5359 profiles ?: Profiles . Profile [ ]
5460 catastrophicError ?: unknown
61+
62+ updateCount : number
5563}
5664
5765export default class ProfileExplorer extends React . PureComponent < Props , State > {
@@ -60,6 +68,12 @@ export default class ProfileExplorer extends React.PureComponent<Props, State> {
6068 this . init ( )
6169 }
6270
71+ private readonly statusWatcherUpdateFn : UpdateFunction = ( ) => {
72+ this . setState ( ( curState ) => ( {
73+ updateCount : ( curState ?. updateCount || 0 ) + 1 ,
74+ } ) )
75+ }
76+
6377 private readonly _handleProfileSelection = ( selectedProfile : string ) => {
6478 this . setState ( { selectedProfile } )
6579
@@ -70,7 +84,7 @@ export default class ProfileExplorer extends React.PureComponent<Props, State> {
7084
7185 private updateDebouncer : null | ReturnType < typeof setTimeout > = null
7286
73- private readonly updateFn = ( ) => {
87+ private readonly profileWatcherUpdateFn = ( ) => {
7488 if ( this . updateDebouncer ) {
7589 clearTimeout ( this . updateDebouncer )
7690 }
@@ -117,7 +131,10 @@ export default class ProfileExplorer extends React.PureComponent<Props, State> {
117131
118132 private async init ( ) {
119133 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 ( )
121138 this . setState ( {
122139 watcher,
123140 profiles : [ ] ,
@@ -129,13 +146,19 @@ export default class ProfileExplorer extends React.PureComponent<Props, State> {
129146 }
130147
131148 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 } )
134157 }
135158 }
136159
137160 public render ( ) {
138- if ( this . state && this . state . catastrophicError ) {
161+ if ( this . state ? .catastrophicError ) {
139162 return "Internal Error"
140163 } else if ( ! this . state || ! this . state . profiles || ! this . state . selectedProfile ) {
141164 return < Loading />
@@ -146,20 +169,38 @@ export default class ProfileExplorer extends React.PureComponent<Props, State> {
146169 profile = { this . state . selectedProfile }
147170 profiles = { this . state . profiles }
148171 onSelectProfile = { this . _handleProfileSelection }
172+ profileReadiness = { this . state . statusWatcher ?. readiness }
173+ profileStatus = { this . state . statusWatcher }
149174 />
150175 </ div >
151176 )
152177 }
153178 }
154179}
155180
156- class ProfileCard extends React . PureComponent < {
181+ type ProfileCardProps = {
157182 profile : string
158183 profiles : Profiles . Profile [ ]
159184 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+ }
161201 private readonly _handleBoot = ( ) => handleBoot ( this . props . profile )
162202 private readonly _handleShutdown = ( ) => handleShutdown ( this . props . profile )
203+ private readonly _onToggle = ( ) => this . setState ( { isOpen : ! this . state . isOpen } )
163204
164205 private title ( ) {
165206 return (
@@ -174,7 +215,28 @@ class ProfileCard extends React.PureComponent<{
174215 }
175216
176217 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+ )
178240 }
179241
180242 private body ( ) {
0 commit comments