@@ -50,8 +50,7 @@ import { WorkspaceStopActionModal } from '~/app/pages/Workspaces/workspaceAction
5050import { useNamespaceContext } from '~/app/context/NamespaceContextProvider' ;
5151import { WorkspacesColumnNames } from '~/app/types' ;
5252import Filter , { FilteredColumn } from 'shared/components/Filter' ;
53- import { formatRam , formatCPU } from 'shared/utilities/WorkspaceResources' ;
54- import { formatRam } from 'shared/utilities/WorkspaceUtils' ; //check if still exist
53+ import { formatRam } from 'shared/utilities/WorkspaceUtils' ;
5554import { extractCpuValue , extractMemoryValue } from 'shared/utilities/WorkspaceUtils' ;
5655
5756export enum ActionType {
@@ -486,102 +485,116 @@ export const Workspaces: React.FunctionComponent = () => {
486485 < Content style = { { display : 'flex' , alignItems : 'flex-start' , columnGap : '20px' } } >
487486 < Filter id = "filter-workspaces" onFilter = { onFilter } columnNames = { filterableColumns } />
488487 </ Content >
489- < Table aria-label = "Sortable table" ouiaId = "SortableTable" >
490- < Thead >
491- < Tr >
492- < Th screenReaderText = "expand-action" />
493- { Object . values ( columnNames ) . map ( ( columnName , index ) => (
494- < Th
495- key = { `${ columnName } -col-name` }
496- sort = { columnName !== 'Redirect Status' ? getSortParams ( index ) : undefined }
497- >
498- { columnName }
499- </ Th >
500- ) ) }
501- < Th screenReaderText = "Primary action" />
502- </ Tr >
503- </ Thead >
504- { sortedWorkspaces . map ( ( workspace , rowIndex ) => (
505- < Tbody
506- id = "workspaces-table-content"
507- key = { rowIndex }
508- isExpanded = { isWorkspaceExpanded ( workspace ) }
509- data-testid = "table-body"
510- >
511- < Tr id = { `workspaces-table-row-${ rowIndex + 1 } ` } >
512- < Td
513- expand = { {
514- rowIndex,
515- isExpanded : isWorkspaceExpanded ( workspace ) ,
516- onToggle : ( ) =>
517- setWorkspaceExpanded ( workspace , ! isWorkspaceExpanded ( workspace ) ) ,
518- } }
519- />
520- < Td dataLabel = { columnNames . redirectStatus } >
521- { workspaceRedirectStatus [ workspace . workspaceKind . name ]
522- ? getRedirectStatusIcon (
523- workspaceRedirectStatus [ workspace . workspaceKind . name ] ?. message ?. level ,
524- workspaceRedirectStatus [ workspace . workspaceKind . name ] ?. message ?. text ||
525- 'No API response available' ,
526- )
527- : getRedirectStatusIcon ( undefined , 'No API response available' ) }
528- </ Td >
529- < Td dataLabel = { columnNames . name } > { workspace . name } </ Td >
530- < Td dataLabel = { columnNames . kind } >
531- { kindLogoDict [ workspace . workspaceKind . name ] ? (
532- < Tooltip content = { workspace . workspaceKind . name } >
533- < Brand
534- src = { kindLogoDict [ workspace . workspaceKind . name ] }
535- alt = { workspace . workspaceKind . name }
536- style = { { width : '20px' , height : '20px' , cursor : 'pointer' } }
537- />
538- </ Tooltip >
539- ) : (
540- < Tooltip content = { workspace . workspaceKind . name } >
541- < CodeIcon />
542- </ Tooltip >
543- ) }
544- </ Td >
545- < Td dataLabel = { columnNames . image } >
546- { workspace . podTemplate . options . imageConfig . current . displayName }
547- </ Td >
548- < Td dataLabel = { columnNames . podConfig } >
549- { workspace . podTemplate . options . podConfig . current . displayName }
550- </ Td >
551- < Td dataLabel = { columnNames . state } >
552- < Label color = { extractStateColor ( workspace . state ) } > { workspace . state } </ Label >
553- </ Td >
554- < Td dataLabel = { columnNames . homeVol } >
555- { workspace . podTemplate . volumes . home ?. pvcName ?? '' }
556- </ Td >
557- < Td dataLabel = { columnNames . cpu } > { extractCpuValue ( workspace ) } </ Td >
558- < Td dataLabel = { columnNames . ram } > { extractMemoryValue ( workspace ) } </ Td >
559- < Td dataLabel = { columnNames . lastActivity } >
560- < Timestamp
561- date = { new Date ( workspace . activity . lastActivity ) }
562- tooltip = { { variant : TimestampTooltipVariant . default } }
488+ { /* Show a loading spinner if data is still loading */ }
489+ { ! loaded ? (
490+ < Spinner size = "xl" />
491+ ) : (
492+ < Table
493+ data-testid = "workspaces-table"
494+ aria-label = "Sortable table"
495+ ouiaId = "SortableTable"
496+ >
497+ < Thead >
498+ < Tr >
499+ < Th />
500+ { Object . values ( columnNames ) . map ( ( columnName , index ) => (
501+ < Th
502+ key = { `${ columnName } -col-name` }
503+ sort = { columnName !== 'Redirect Status' ? getSortParams ( index ) : undefined }
563504 >
564- 1 hour ago
565- </ Timestamp >
566- </ Td >
567- < Td >
568- < WorkspaceConnectAction workspace = { workspace } />
569- </ Td >
570- < Td isActionCell data-testid = "action-column" >
571- < ActionsColumn
572- items = { workspaceDefaultActions ( workspace ) . map ( ( action ) => ( {
573- ...action ,
574- 'data-testid' : `action-${ action . id || '' } ` ,
575- } ) ) }
576- />
577- </ Td >
505+ { columnName }
506+ </ Th >
507+ ) ) }
508+ < Th screenReaderText = "Primary action" />
578509 </ Tr >
579- { isWorkspaceExpanded ( workspace ) && (
580- < ExpandedWorkspaceRow workspace = { workspace } columnNames = { columnNames } />
581- ) }
582- </ Tbody >
583- ) ) }
584- </ Table >
510+ </ Thead >
511+ { sortedWorkspaces . map ( ( workspace , rowIndex ) => (
512+ < Tbody
513+ id = "workspaces-table-content"
514+ key = { rowIndex }
515+ isExpanded = { isWorkspaceExpanded ( workspace ) }
516+ data-testid = "table-body"
517+ >
518+ < Tr
519+ id = { `workspaces-table-row-${ rowIndex + 1 } ` }
520+ data-testid = { `workspace-row-${ rowIndex } ` }
521+ >
522+ < Td
523+ expand = { {
524+ rowIndex,
525+ isExpanded : isWorkspaceExpanded ( workspace ) ,
526+ onToggle : ( ) =>
527+ setWorkspaceExpanded ( workspace , ! isWorkspaceExpanded ( workspace ) ) ,
528+ } }
529+ />
530+ < Td dataLabel = { columnNames . redirectStatus } >
531+ { workspaceRedirectStatus [ workspace . kind ]
532+ ? getRedirectStatusIcon (
533+ workspaceRedirectStatus [ workspace . kind ] ?. level ,
534+ workspaceRedirectStatus [ workspace . kind ] ?. message ||
535+ 'No API response available' ,
536+ )
537+ : getRedirectStatusIcon ( undefined , 'No API response available' ) }
538+ </ Td >
539+ < Td data-testid = "workspace-name" dataLabel = { columnNames . name } >
540+ { workspace . name }
541+ </ Td >
542+ < Td dataLabel = { columnNames . kind } >
543+ { kindLogoDict [ workspace . workspace_kind . name ] ? (
544+ < Tooltip content = { workspace . workspace_kind . name } >
545+ < Brand
546+ src = { kindLogoDict [ workspace . workspace_kind . name ] }
547+ alt = { workspace . workspace_kind . name }
548+ style = { { width : '20px' , height : '20px' , cursor : 'pointer' } }
549+ />
550+ </ Tooltip >
551+ ) : (
552+ < Tooltip content = { workspace . workspace_kind . name } >
553+ < CodeIcon />
554+ </ Tooltip >
555+ ) }
556+ </ Td >
557+ < Td dataLabel = { columnNames . image } >
558+ { workspace . pod_template . options . image_config . current . display_name }
559+ </ Td >
560+ < Td data-testid = "pod-config" dataLabel = { columnNames . podConfig } >
561+ { workspace . pod_template . options . pod_config . current . display_name }
562+ </ Td >
563+ < Td data-testid = "state-label" dataLabel = { columnNames . state } >
564+ < Label color = { stateColors [ workspace . state ] } > { workspace . state } </ Label > { ' ' }
565+ </ Td >
566+ < Td dataLabel = { columnNames . homeVol } >
567+ { workspace . pod_template . volumes . home . pvc_name }
568+ </ Td >
569+ < Td dataLabel = { columnNames . cpu } > { formatCPU ( getCpuValue ( workspace ) ) } </ Td >
570+ < Td dataLabel = { columnNames . ram } > { formatRam ( getRamValue ( workspace ) ) } </ Td >
571+ < Td dataLabel = { columnNames . lastActivity } >
572+ < Timestamp
573+ date = { new Date ( workspace . activity . last_activity ) }
574+ tooltip = { { variant : TimestampTooltipVariant . default } }
575+ >
576+ 1 hour ago
577+ </ Timestamp >
578+ </ Td >
579+ < Td >
580+ < WorkspaceConnectAction workspace = { workspace } />
581+ </ Td >
582+ < Td isActionCell data-testid = "action-column" >
583+ < ActionsColumn
584+ items = { workspaceDefaultActions ( workspace ) . map ( ( action ) => ( {
585+ ...action ,
586+ 'data-testid' : `action-${ typeof action . title === 'string' ? action . title . toLowerCase ( ) : '' } ` ,
587+ } ) ) }
588+ />
589+ </ Td >
590+ </ Tr >
591+ { isWorkspaceExpanded ( workspace ) && (
592+ < ExpandedWorkspaceRow workspace = { workspace } columnNames = { columnNames } />
593+ ) }
594+ </ Tbody >
595+ ) ) }
596+ </ Table >
597+ ) }
585598 { isActionAlertModalOpen && chooseAlertModal ( ) }
586599 < DeleteModal
587600 isOpen = { workspaceToDelete != null }
0 commit comments