11import Button from "@material-ui/core/Button"
22import Popover from "@material-ui/core/Popover"
33import { makeStyles } from "@material-ui/core/styles"
4- import { FC , ReactNode , useEffect , useRef , useState } from "react"
4+ import { FC , ReactNode , useEffect , useMemo , useRef , useState } from "react"
55import { Workspace } from "../../api/typesGenerated"
6- import { getWorkspaceStatus } from "../../util/workspace"
6+ import { getWorkspaceStatus , WorkspaceStatus } from "../../util/workspace"
77import { CloseDropdown , OpenDropdown } from "../DropdownArrows/DropdownArrows"
88import { CancelButton , DeleteButton , StartButton , StopButton , UpdateButton } from "./ActionCtas"
99import { ButtonTypesEnum , WorkspaceStateActions , WorkspaceStateEnum } from "./constants"
1010
11+ /**
12+ * Jobs submitted while another job is in progress will be discarded,
13+ * so check whether workspace job status has reached completion (whether successful or not).
14+ */
15+ const canAcceptJobs = ( workspaceStatus : WorkspaceStatus ) =>
16+ [ "started" , "stopped" , "deleted" , "error" , "canceled" ] . includes ( workspaceStatus )
17+
1118export interface WorkspaceActionsProps {
1219 workspace : Workspace
1320 handleStart : ( ) => void
@@ -34,7 +41,23 @@ export const WorkspaceActions: FC<WorkspaceActionsProps> = ({
3441 workspace . latest_build ,
3542 )
3643 const workspaceState = WorkspaceStateEnum [ workspaceStatus ]
37- const actions = WorkspaceStateActions [ workspaceState ]
44+
45+ const canUpdateWorkspace = workspace . outdated && canAcceptJobs ( workspaceStatus )
46+
47+ // actions are the primary and secondary CTAs that appear in the workspace actions dropdown
48+ const actions = useMemo ( ( ) => {
49+ if ( ! canUpdateWorkspace ) {
50+ return WorkspaceStateActions [ workspaceState ]
51+ }
52+
53+ // if an update is available, we make the update button the primary CTA
54+ // and move the former primary CTA to the secondary actions list
55+ const updatedActions = { ...WorkspaceStateActions [ workspaceState ] }
56+ updatedActions . secondary . unshift ( updatedActions . primary )
57+ updatedActions . primary = ButtonTypesEnum . update
58+
59+ return updatedActions
60+ } , [ canUpdateWorkspace , workspaceState ] )
3861
3962 /**
4063 * Ensures we close the popover before calling any action handler
@@ -58,16 +81,10 @@ export const WorkspaceActions: FC<WorkspaceActionsProps> = ({
5881
5982 // A mapping of button type to the corresponding React component
6083 const buttonMapping : ButtonMapping = {
84+ [ ButtonTypesEnum . update ] : < UpdateButton handleAction = { handleUpdate } /> ,
6185 [ ButtonTypesEnum . start ] : < StartButton handleAction = { handleStart } /> ,
6286 [ ButtonTypesEnum . stop ] : < StopButton handleAction = { handleStop } /> ,
6387 [ ButtonTypesEnum . delete ] : < DeleteButton handleAction = { handleDelete } /> ,
64- [ ButtonTypesEnum . update ] : (
65- < UpdateButton
66- handleAction = { handleUpdate }
67- workspace = { workspace }
68- workspaceStatus = { workspaceStatus }
69- />
70- ) ,
7188 [ ButtonTypesEnum . cancel ] : < CancelButton handleAction = { handleCancel } /> ,
7289 [ ButtonTypesEnum . canceling ] : disabledButton ,
7390 [ ButtonTypesEnum . disabled ] : disabledButton ,
0 commit comments