1
- import MenuItem from "@mui/material/MenuItem" ;
2
- import Menu from "@mui/material/Menu" ;
3
- import { makeStyles } from "@mui/styles" ;
4
- import MoreVertOutlined from "@mui/icons-material/MoreVertOutlined" ;
5
- import { FC , Fragment , ReactNode , useRef , useState } from "react" ;
6
- import { Workspace , WorkspaceBuildParameter } from "api/typesGenerated" ;
1
+ import { type FC , Fragment , type ReactNode , useRef , useState } from "react" ;
2
+ import { ButtonMapping , actionsByWorkspaceStatus } from "./constants" ;
3
+ import {
4
+ type Workspace ,
5
+ type WorkspaceBuildParameter ,
6
+ } from "api/typesGenerated" ;
7
+
7
8
import {
8
9
ActionLoadingButton ,
9
10
CancelButton ,
@@ -14,11 +15,17 @@ import {
14
15
UpdateButton ,
15
16
ActivateButton ,
16
17
} from "./Buttons" ;
17
- import { ButtonMapping , actionsByWorkspaceStatus } from "./constants" ;
18
+
19
+ import { makeStyles } from "@mui/styles" ;
20
+ import Menu from "@mui/material/Menu" ;
21
+ import MenuItem from "@mui/material/MenuItem" ;
22
+ import IconButton from "@mui/material/IconButton" ;
23
+
18
24
import SettingsIcon from "@mui/icons-material/SettingsOutlined" ;
19
25
import HistoryIcon from "@mui/icons-material/HistoryOutlined" ;
20
26
import DeleteIcon from "@mui/icons-material/DeleteOutlined" ;
21
- import IconButton from "@mui/material/IconButton" ;
27
+ import MoreOptionsIcon from "@mui/icons-material/MoreVertOutlined" ;
28
+ import CloneIcon from "@mui/icons-material/ContentCopyOutlined" ;
22
29
23
30
export interface WorkspaceActionsProps {
24
31
workspace : Workspace ;
@@ -52,16 +59,6 @@ export const WorkspaceActions: FC<WorkspaceActionsProps> = ({
52
59
isRestarting,
53
60
canChangeVersions,
54
61
} ) => {
55
- const styles = useStyles ( ) ;
56
- const {
57
- canCancel,
58
- canAcceptJobs,
59
- actions : actionsByStatus ,
60
- } = actionsByWorkspaceStatus ( workspace , workspace . latest_build . status ) ;
61
- const canBeUpdated = workspace . outdated && canAcceptJobs ;
62
- const menuTriggerRef = useRef < HTMLButtonElement > ( null ) ;
63
- const [ isMenuOpen , setIsMenuOpen ] = useState ( false ) ;
64
-
65
62
// A mapping of button type to the corresponding React component
66
63
const buttonMapping : ButtonMapping = {
67
64
update : < UpdateButton handleAction = { handleUpdate } /> ,
@@ -90,21 +87,35 @@ export const WorkspaceActions: FC<WorkspaceActionsProps> = ({
90
87
activating : < ActivateButton loading handleAction = { handleDormantActivate } /> ,
91
88
} ;
92
89
90
+ const styles = useStyles ( ) ;
91
+ const menuTriggerRef = useRef < HTMLButtonElement > ( null ) ;
92
+ const [ isMenuOpen , setIsMenuOpen ] = useState ( false ) ;
93
+
93
94
// Returns a function that will execute the action and close the menu
94
95
const onMenuItemClick = ( actionFn : ( ) => void ) => ( ) => {
95
96
setIsMenuOpen ( false ) ;
96
97
actionFn ( ) ;
97
98
} ;
98
99
100
+ const {
101
+ canCancel,
102
+ canAcceptJobs,
103
+ actions : actionsByStatus ,
104
+ } = actionsByWorkspaceStatus ( workspace , workspace . latest_build . status ) ;
105
+ const canBeUpdated = workspace . outdated && canAcceptJobs ;
106
+
99
107
return (
100
108
< div className = { styles . actions } data-testid = "workspace-actions" >
101
109
{ canBeUpdated &&
102
110
( isUpdating ? buttonMapping . updating : buttonMapping . update ) }
111
+
103
112
{ isRestarting && buttonMapping . restarting }
113
+
104
114
{ ! isRestarting &&
105
115
actionsByStatus . map ( ( action ) => (
106
116
< Fragment key = { action } > { buttonMapping [ action ] } </ Fragment >
107
117
) ) }
118
+
108
119
{ canCancel && < CancelButton handleAction = { handleCancel } /> }
109
120
< div >
110
121
< IconButton
@@ -117,8 +128,9 @@ export const WorkspaceActions: FC<WorkspaceActionsProps> = ({
117
128
ref = { menuTriggerRef }
118
129
onClick = { ( ) => setIsMenuOpen ( true ) }
119
130
>
120
- < MoreVertOutlined />
131
+ < MoreOptionsIcon />
121
132
</ IconButton >
133
+
122
134
< Menu
123
135
id = "workspace-options"
124
136
anchorEl = { menuTriggerRef . current }
@@ -129,12 +141,19 @@ export const WorkspaceActions: FC<WorkspaceActionsProps> = ({
129
141
< SettingsIcon />
130
142
Settings
131
143
</ MenuItem >
144
+
132
145
{ canChangeVersions && (
133
146
< MenuItem onClick = { onMenuItemClick ( handleChangeVersion ) } >
134
147
< HistoryIcon />
135
148
Change version…
136
149
</ MenuItem >
137
150
) }
151
+
152
+ < MenuItem >
153
+ < CloneIcon />
154
+ Clone…
155
+ </ MenuItem >
156
+
138
157
< MenuItem
139
158
onClick = { onMenuItemClick ( handleDelete ) }
140
159
data-testid = "delete-button"
0 commit comments