@@ -277,7 +277,7 @@ export const Workspaces: React.FunctionComponent = () => {
277277 } ;
278278
279279 const workspaceDefaultActions = ( workspace : Workspace ) : IActions => {
280- const workspaceState = workspace . status . state ;
280+ const workspaceState = workspace . state ;
281281 const workspaceActions = [
282282 {
283283 title : 'View Details' ,
@@ -456,98 +456,116 @@ export const Workspaces: React.FunctionComponent = () => {
456456 Create Workspace
457457 </ Button >
458458 </ Content >
459- < Table aria-label = "Sortable table" ouiaId = "SortableTable" >
460- < Thead >
461- < Tr >
462- < Th />
463- { Object . values ( columnNames ) . map ( ( columnName , index ) => (
464- < Th
465- key = { `${ columnName } -col-name` }
466- sort = { columnName !== 'Redirect Status' ? getSortParams ( index ) : undefined }
459+ { /* Show a loading spinner if data is still loading */ }
460+ { ! loaded ? (
461+ < Spinner size = "xl" />
462+ ) : (
463+ < Table
464+ data-testid = "workspaces-table"
465+ aria-label = "Sortable table"
466+ ouiaId = "SortableTable"
467+ >
468+ < Thead >
469+ < Tr >
470+ < Th />
471+ { Object . values ( columnNames ) . map ( ( columnName , index ) => (
472+ < Th
473+ key = { `${ columnName } -col-name` }
474+ sort = { columnName !== 'Redirect Status' ? getSortParams ( index ) : undefined }
475+ >
476+ { columnName }
477+ </ Th >
478+ ) ) }
479+ < Th screenReaderText = "Primary action" />
480+ </ Tr >
481+ </ Thead >
482+ { sortedWorkspaces . map ( ( workspace , rowIndex ) => (
483+ < Tbody
484+ id = "workspaces-table-content"
485+ key = { rowIndex }
486+ isExpanded = { isWorkspaceExpanded ( workspace ) }
487+ data-testid = "table-body"
488+ >
489+ < Tr
490+ id = { `workspaces-table-row-${ rowIndex + 1 } ` }
491+ data-testid = { `workspace-row-${ rowIndex } ` }
467492 >
468- { columnName }
469- </ Th >
470- ) ) }
471- < Th screenReaderText = "Primary action" />
472- </ Tr >
473- </ Thead >
474- { sortedWorkspaces . map ( ( workspace , rowIndex ) => (
475- < Tbody
476- id = "workspaces-table-content"
477- key = { rowIndex }
478- isExpanded = { isWorkspaceExpanded ( workspace ) }
479- data-testid = "table-body"
480- >
481- < Tr id = { `workspaces-table-row-${ rowIndex + 1 } ` } >
482- < Td
483- expand = { {
484- rowIndex,
485- isExpanded : isWorkspaceExpanded ( workspace ) ,
486- onToggle : ( ) =>
487- setWorkspaceExpanded ( workspace , ! isWorkspaceExpanded ( workspace ) ) ,
488- } }
489- />
490- < Td dataLabel = { columnNames . redirectStatus } >
491- { workspaceRedirectStatus [ workspace . kind ]
492- ? getRedirectStatusIcon (
493- workspaceRedirectStatus [ workspace . kind ] ?. level ,
494- workspaceRedirectStatus [ workspace . kind ] ?. message ||
495- 'No API response available' ,
496- )
497- : getRedirectStatusIcon ( undefined , 'No API response available' ) }
498- </ Td >
499- < Td dataLabel = { columnNames . name } > { workspace . name } </ Td >
500- < Td dataLabel = { columnNames . kind } >
501- { kindLogoDict [ workspace . kind ] ? (
502- < Tooltip content = { workspace . kind } >
503- < Brand
504- src = { kindLogoDict [ workspace . kind ] }
505- alt = { workspace . kind }
506- style = { { width : '20px' , height : '20px' , cursor : 'pointer' } }
507- />
508- </ Tooltip >
509- ) : (
510- < Tooltip content = { workspace . kind } >
511- < CodeIcon />
512- </ Tooltip >
513- ) }
514- </ Td >
515- < Td dataLabel = { columnNames . image } > { workspace . options . imageConfig } </ Td >
516- < Td dataLabel = { columnNames . podConfig } > { workspace . options . podConfig } </ Td >
517- < Td dataLabel = { columnNames . state } >
518- < Label color = { stateColors [ workspace . status . state ] } >
519- { WorkspaceState [ workspace . status . state ] }
520- </ Label >
521- </ Td >
522- < Td dataLabel = { columnNames . homeVol } > { workspace . podTemplate . volumes . home } </ Td >
523- < Td dataLabel = { columnNames . cpu } > { `${ workspace . cpu } %` } </ Td >
524- < Td dataLabel = { columnNames . ram } > { formatRam ( workspace . ram ) } </ Td >
525- < Td dataLabel = { columnNames . lastActivity } >
526- < Timestamp
527- date = { new Date ( workspace . status . activity . lastActivity ) }
528- tooltip = { { variant : TimestampTooltipVariant . default } }
529- >
530- 1 hour ago
531- </ Timestamp >
532- </ Td >
533- < Td >
534- < WorkspaceConnectAction workspace = { workspace } />
535- </ Td >
536- < Td isActionCell data-testid = "action-column" >
537- < ActionsColumn
538- items = { workspaceDefaultActions ( workspace ) . map ( ( action ) => ( {
539- ...action ,
540- 'data-testid' : `action-${ typeof action . title === 'string' ? action . title . toLowerCase ( ) : '' } ` ,
541- } ) ) }
493+ < Td
494+ expand = { {
495+ rowIndex,
496+ isExpanded : isWorkspaceExpanded ( workspace ) ,
497+ onToggle : ( ) =>
498+ setWorkspaceExpanded ( workspace , ! isWorkspaceExpanded ( workspace ) ) ,
499+ } }
542500 />
543- </ Td >
544- </ Tr >
545- { isWorkspaceExpanded ( workspace ) && (
546- < ExpandedWorkspaceRow workspace = { workspace } columnNames = { columnNames } />
547- ) }
548- </ Tbody >
549- ) ) }
550- </ Table >
501+ < Td dataLabel = { columnNames . redirectStatus } >
502+ { workspaceRedirectStatus [ workspace . kind ]
503+ ? getRedirectStatusIcon (
504+ workspaceRedirectStatus [ workspace . kind ] ?. level ,
505+ workspaceRedirectStatus [ workspace . kind ] ?. message ||
506+ 'No API response available' ,
507+ )
508+ : getRedirectStatusIcon ( undefined , 'No API response available' ) }
509+ </ Td >
510+ < Td data-testid = "workspace-name" dataLabel = { columnNames . name } >
511+ { workspace . name }
512+ </ Td >
513+ < Td dataLabel = { columnNames . kind } >
514+ { kindLogoDict [ workspace . workspace_kind . name ] ? (
515+ < Tooltip content = { workspace . workspace_kind . name } >
516+ < Brand
517+ src = { kindLogoDict [ workspace . workspace_kind . name ] }
518+ alt = { workspace . workspace_kind . name }
519+ style = { { width : '20px' , height : '20px' , cursor : 'pointer' } }
520+ />
521+ </ Tooltip >
522+ ) : (
523+ < Tooltip content = { workspace . workspace_kind . name } >
524+ < CodeIcon />
525+ </ Tooltip >
526+ ) }
527+ </ Td >
528+ < Td dataLabel = { columnNames . image } >
529+ { workspace . pod_template . options . image_config . current . display_name }
530+ </ Td >
531+ < Td data-testid = "pod-config" dataLabel = { columnNames . podConfig } >
532+ { workspace . pod_template . options . pod_config . current . display_name }
533+ </ Td >
534+ < Td data-testid = "state-label" dataLabel = { columnNames . state } >
535+ < Label color = { stateColors [ workspace . state ] } > { workspace . state } </ Label > { ' ' }
536+ </ Td >
537+ < Td dataLabel = { columnNames . homeVol } >
538+ { workspace . pod_template . volumes . home . pvc_name }
539+ </ Td >
540+ < Td dataLabel = { columnNames . cpu } > { formatCPU ( getCpuValue ( workspace ) ) } </ Td >
541+ < Td dataLabel = { columnNames . ram } > { formatRam ( getRamValue ( workspace ) ) } </ Td >
542+ < Td dataLabel = { columnNames . lastActivity } >
543+ < Timestamp
544+ date = { new Date ( workspace . activity . last_activity ) }
545+ tooltip = { { variant : TimestampTooltipVariant . default } }
546+ >
547+ 1 hour ago
548+ </ Timestamp >
549+ </ Td >
550+ < Td >
551+ < WorkspaceConnectAction workspace = { workspace } />
552+ </ Td >
553+ < Td isActionCell data-testid = "action-column" >
554+ < ActionsColumn
555+ items = { workspaceDefaultActions ( workspace ) . map ( ( action ) => ( {
556+ ...action ,
557+ 'data-testid' : `action-${ typeof action . title === 'string' ? action . title . toLowerCase ( ) : '' } ` ,
558+ } ) ) }
559+ />
560+ </ Td >
561+ </ Tr >
562+ { isWorkspaceExpanded ( workspace ) && (
563+ < ExpandedWorkspaceRow workspace = { workspace } columnNames = { columnNames } />
564+ ) }
565+ </ Tbody >
566+ ) ) }
567+ </ Table >
568+ ) }
551569 { isActionAlertModalOpen && chooseAlertModal ( ) }
552570 < DeleteModal
553571 isOpen = { workspaceToDelete != null }
0 commit comments