1
1
import { css } from "@emotion/css" ;
2
2
import { type Interpolation , type Theme } from "@emotion/react" ;
3
- import Link from "@mui/material/Link" ;
3
+ import Link , { LinkProps } from "@mui/material/Link" ;
4
4
import { WorkspaceOutdatedTooltip } from "components/WorkspaceOutdatedTooltip/WorkspaceOutdatedTooltip" ;
5
- import { type FC } from "react" ;
5
+ import { forwardRef , type FC } from "react" ;
6
6
import { Link as RouterLink } from "react-router-dom" ;
7
7
import {
8
8
getDisplayWorkspaceTemplateName ,
@@ -26,6 +26,8 @@ import {
26
26
} from "components/Popover/Popover" ;
27
27
import { workspaceQuota } from "api/queries/workspaceQuota" ;
28
28
import { useQuery } from "react-query" ;
29
+ import Tooltip from "@mui/material/Tooltip" ;
30
+ import _ from "lodash" ;
29
31
30
32
const Language = {
31
33
workspaceDetails : "Workspace Details" ,
@@ -120,16 +122,15 @@ export const WorkspaceStats: FC<WorkspaceStatsProps> = ({
120
122
css = { styles . statsItem }
121
123
label = { getScheduleLabel ( workspace ) }
122
124
value = {
123
- < span css = { styles . scheduleValue } >
124
- < Link
125
- component = { RouterLink }
126
- to = "settings/schedule"
127
- title = "Schedule settings"
128
- >
129
- { isWorkspaceOn ( workspace )
130
- ? autostopDisplay ( workspace )
131
- : autostartDisplay ( workspace . autostart_schedule ) }
132
- </ Link >
125
+ < div css = { styles . scheduleValue } >
126
+ { isWorkspaceOn ( workspace ) ? (
127
+ < AutoStopDisplay workspace = { workspace } />
128
+ ) : (
129
+ < ScheduleSettingsLink >
130
+ { autostartDisplay ( workspace . autostart_schedule ) }
131
+ </ ScheduleSettingsLink >
132
+ ) }
133
+
133
134
{ canUpdateWorkspace && canEditDeadline ( workspace ) && (
134
135
< span css = { styles . scheduleControls } >
135
136
< Popover >
@@ -178,7 +179,7 @@ export const WorkspaceStats: FC<WorkspaceStatsProps> = ({
178
179
</ Popover >
179
180
</ span >
180
181
) }
181
- </ span >
182
+ </ div >
182
183
}
183
184
/>
184
185
) }
@@ -220,6 +221,7 @@ const AddTimeContent = (props: {
220
221
} }
221
222
>
222
223
< TextField
224
+ autoFocus
223
225
name = "hours"
224
226
type = "number"
225
227
size = "small"
@@ -268,6 +270,7 @@ export const DecreaseTimeContent = (props: {
268
270
} }
269
271
>
270
272
< TextField
273
+ autoFocus
271
274
name = "hours"
272
275
type = "number"
273
276
size = "small"
@@ -292,6 +295,47 @@ export const DecreaseTimeContent = (props: {
292
295
) ;
293
296
} ;
294
297
298
+ const AutoStopDisplay = ( props : { workspace : Workspace } ) => {
299
+ const { workspace } = props ;
300
+ const display = autostopDisplay ( workspace ) ;
301
+
302
+ if ( display . tooltip ) {
303
+ return (
304
+ < Tooltip title = { display . tooltip } >
305
+ < ScheduleSettingsLink
306
+ css = { ( theme ) => ( {
307
+ color : isShutdownSoon ( workspace )
308
+ ? `${ theme . palette . warning . light } !important`
309
+ : undefined ,
310
+ } ) }
311
+ >
312
+ { display . message }
313
+ </ ScheduleSettingsLink >
314
+ </ Tooltip >
315
+ ) ;
316
+ }
317
+
318
+ return < ScheduleSettingsLink > { display . message } </ ScheduleSettingsLink > ;
319
+ } ;
320
+
321
+ const ScheduleSettingsLink = forwardRef < HTMLAnchorElement , LinkProps > (
322
+ ( props , ref ) => {
323
+ return (
324
+ < Link
325
+ ref = { ref }
326
+ component = { RouterLink }
327
+ to = "settings/schedule"
328
+ css = { {
329
+ "&:first-letter" : {
330
+ textTransform : "uppercase" ,
331
+ } ,
332
+ } }
333
+ { ...props }
334
+ />
335
+ ) ;
336
+ } ,
337
+ ) ;
338
+
295
339
export const canEditDeadline = ( workspace : Workspace ) : boolean => {
296
340
return isWorkspaceOn ( workspace ) && Boolean ( workspace . latest_build . deadline ) ;
297
341
} ;
@@ -307,7 +351,19 @@ export const shouldDisplayScheduleLabel = (workspace: Workspace): boolean => {
307
351
} ;
308
352
309
353
const getScheduleLabel = ( workspace : Workspace ) => {
310
- return isWorkspaceOn ( workspace ) ? "Stops at" : "Starts at" ;
354
+ return isWorkspaceOn ( workspace ) ? "Stops" : "Starts at" ;
355
+ } ;
356
+
357
+ const isShutdownSoon = ( workspace : Workspace ) : boolean => {
358
+ const deadline = workspace . latest_build . deadline ;
359
+ if ( ! deadline ) {
360
+ return false ;
361
+ }
362
+ const deadlineDate = new Date ( deadline ) ;
363
+ const now = new Date ( ) ;
364
+ const diff = deadlineDate . getTime ( ) - now . getTime ( ) ;
365
+ const oneHour = 1000 * 60 * 60 ;
366
+ return diff < oneHour ;
311
367
} ;
312
368
313
369
const timePopoverFieldInputStyles = css `
@@ -369,6 +425,7 @@ const styles = {
369
425
370
426
timePopoverTitle : {
371
427
fontWeight : 600 ,
428
+ marginBottom : 8 ,
372
429
} ,
373
430
374
431
timePopoverDescription : ( theme ) => ( {
@@ -380,6 +437,7 @@ const styles = {
380
437
alignItems : "center" ,
381
438
gap : 8 ,
382
439
padding : "8px 0" ,
440
+ marginTop : 12 ,
383
441
} ,
384
442
385
443
timePopoverField : {
0 commit comments