@@ -2,16 +2,15 @@ import { type Interpolation, type Theme } from "@emotion/react";
2
2
import Button from "@mui/material/Button" ;
3
3
import AlertTitle from "@mui/material/AlertTitle" ;
4
4
import { type FC , useEffect , useState } from "react" ;
5
- import { useNavigate , useSearchParams } from "react-router-dom" ;
5
+ import { useNavigate } from "react-router-dom" ;
6
6
import dayjs from "dayjs" ;
7
7
import type * as TypesGen from "api/typesGenerated" ;
8
8
import { Alert , AlertDetail } from "components/Alert/Alert" ;
9
- import { Resources } from "components/Resources/Resources" ;
10
9
import { Stack } from "components/Stack/Stack" ;
11
10
import { ErrorAlert } from "components/Alert/ErrorAlert" ;
12
11
import { DormantWorkspaceBanner } from "components/WorkspaceDeletion" ;
13
12
import { AgentRow } from "components/Resources/AgentRow" ;
14
- import { useLocalStorage } from "hooks" ;
13
+ import { useLocalStorage , useTab } from "hooks" ;
15
14
import {
16
15
ActiveTransition ,
17
16
WorkspaceBuildProgress ,
@@ -24,6 +23,9 @@ import { bannerHeight } from "components/Dashboard/DeploymentBanner/DeploymentBa
24
23
import HistoryOutlined from "@mui/icons-material/HistoryOutlined" ;
25
24
import { useTheme } from "@mui/material/styles" ;
26
25
import { SidebarIconButton } from "components/FullPageLayout/Sidebar" ;
26
+ import HubOutlined from "@mui/icons-material/HubOutlined" ;
27
+ import { ResourcesSidebar } from "./ResourcesSidebar" ;
28
+ import { ResourceCard } from "components/Resources/ResourceCard" ;
27
29
28
30
export type WorkspaceError =
29
31
| "getBuildsError"
@@ -45,7 +47,6 @@ export interface WorkspaceProps {
45
47
isUpdating : boolean ;
46
48
isRestarting : boolean ;
47
49
workspace : TypesGen . Workspace ;
48
- resources ?: TypesGen . WorkspaceResource [ ] ;
49
50
canUpdateWorkspace : boolean ;
50
51
updateMessage ?: string ;
51
52
canChangeVersions : boolean ;
@@ -78,8 +79,6 @@ export const Workspace: FC<React.PropsWithChildren<WorkspaceProps>> = ({
78
79
workspace,
79
80
isUpdating,
80
81
isRestarting,
81
- resources,
82
-
83
82
canUpdateWorkspace,
84
83
updateMessage,
85
84
canChangeVersions,
@@ -99,8 +98,6 @@ export const Workspace: FC<React.PropsWithChildren<WorkspaceProps>> = ({
99
98
const { saveLocal, getLocal } = useLocalStorage ( ) ;
100
99
const theme = useTheme ( ) ;
101
100
102
- const [ searchParams , setSearchParams ] = useSearchParams ( ) ;
103
-
104
101
const [ showAlertPendingInQueue , setShowAlertPendingInQueue ] = useState ( false ) ;
105
102
106
103
// 2023-11-15 - MES - This effect will be called every single render because
@@ -148,6 +145,29 @@ export const Workspace: FC<React.PropsWithChildren<WorkspaceProps>> = ({
148
145
const transitionStats =
149
146
template !== undefined ? ActiveTransition ( template , workspace ) : undefined ;
150
147
148
+ const sidebarOption = useTab ( "sidebar" , "" ) ;
149
+ const setSidebarOption = ( newOption : string ) => {
150
+ const { set, value } = sidebarOption ;
151
+ if ( value === newOption ) {
152
+ set ( "" ) ;
153
+ } else {
154
+ set ( newOption ) ;
155
+ }
156
+ } ;
157
+
158
+ const selectedResourceId = useTab ( "resources" , "" ) ;
159
+ const resources = [ ...workspace . latest_build . resources ] . sort (
160
+ ( a , b ) => countAgents ( b ) - countAgents ( a ) ,
161
+ ) ;
162
+ const selectedResource = workspace . latest_build . resources . find (
163
+ ( r ) => r . id === selectedResourceId . value ,
164
+ ) ;
165
+ useEffect ( ( ) => {
166
+ if ( resources . length > 0 && selectedResourceId . value === "" ) {
167
+ selectedResourceId . set ( resources [ 0 ] . id ) ;
168
+ }
169
+ } , [ resources , selectedResourceId ] ) ;
170
+
151
171
return (
152
172
< div
153
173
css = { {
@@ -187,25 +207,37 @@ export const Workspace: FC<React.PropsWithChildren<WorkspaceProps>> = ({
187
207
height : "100%" ,
188
208
overflowY : "auto" ,
189
209
borderRight : `1px solid ${ theme . palette . divider } ` ,
210
+ display : "flex" ,
211
+ flexDirection : "column" ,
190
212
} }
191
213
>
192
214
< SidebarIconButton
193
- isActive = { searchParams . get ( "sidebar" ) === "history " }
215
+ isActive = { sidebarOption . value === "resources " }
194
216
onClick = { ( ) => {
195
- const sidebarOption = searchParams . get ( "sidebar" ) ;
196
- if ( sidebarOption === "history" ) {
197
- searchParams . delete ( "sidebar" ) ;
198
- } else {
199
- searchParams . set ( "sidebar" , "history" ) ;
200
- }
201
- setSearchParams ( searchParams ) ;
217
+ setSidebarOption ( "resources" ) ;
218
+ } }
219
+ >
220
+ < HubOutlined />
221
+ </ SidebarIconButton >
222
+ < SidebarIconButton
223
+ isActive = { sidebarOption . value === "history" }
224
+ onClick = { ( ) => {
225
+ setSidebarOption ( "history" ) ;
202
226
} }
203
227
>
204
228
< HistoryOutlined />
205
229
</ SidebarIconButton >
206
230
</ div >
207
231
208
- { searchParams . get ( "sidebar" ) === "history" && (
232
+ { sidebarOption . value === "resources" && (
233
+ < ResourcesSidebar
234
+ failed = { workspace . latest_build . status === "failed" }
235
+ resources = { resources }
236
+ selected = { selectedResourceId . value }
237
+ onChange = { selectedResourceId . set }
238
+ />
239
+ ) }
240
+ { sidebarOption . value === "history" && (
209
241
< HistorySidebar workspace = { workspace } />
210
242
) }
211
243
@@ -342,9 +374,9 @@ export const Workspace: FC<React.PropsWithChildren<WorkspaceProps>> = ({
342
374
343
375
{ buildLogs }
344
376
345
- { resources && resources . length > 0 && (
346
- < Resources
347
- resources = { resources }
377
+ { selectedResource && (
378
+ < ResourceCard
379
+ resource = { selectedResource }
348
380
agentRow = { ( agent ) => (
349
381
< AgentRow
350
382
key = { agent . id }
@@ -369,6 +401,10 @@ export const Workspace: FC<React.PropsWithChildren<WorkspaceProps>> = ({
369
401
) ;
370
402
} ;
371
403
404
+ const countAgents = ( resource : TypesGen . WorkspaceResource ) => {
405
+ return resource . agents ? resource . agents . length : 0 ;
406
+ } ;
407
+
372
408
const styles = {
373
409
content : {
374
410
padding : 24 ,
@@ -377,6 +413,7 @@ const styles = {
377
413
} ,
378
414
379
415
dotBackground : ( theme ) => ( {
416
+ minHeight : "100%" ,
380
417
padding : 24 ,
381
418
"--d" : "1px" ,
382
419
background : `
0 commit comments