@@ -79,6 +79,26 @@ function AddEnvVarModal(p: EnvVarModalProps) {
79
79
</ Modal >
80
80
}
81
81
82
+ function DeleteEnvVarModal ( p : { variable : UserEnvVarValue , deleteVariable : ( ) => void , onClose : ( ) => void } ) {
83
+ return < Modal visible = { true } onClose = { p . onClose } >
84
+ < h3 className = "mb-4" > Delete Variable?</ h3 >
85
+ < div className = "border-t border-b border-gray-200 dark:border-gray-800 -mx-6 px-6 py-4 flex flex-col" >
86
+ < div className = "grid grid-cols-2 gap-4 px-3 text-sm text-gray-400" >
87
+ < span className = "truncate" > Name</ span >
88
+ < span className = "truncate" > Scope</ span >
89
+ </ div >
90
+ < div className = "grid grid-cols-2 gap-4 p-3 mt-3 text-gray-400 bg-gray-100 dark:bg-gray-800 rounded-xl" >
91
+ < span className = "truncate text-gray-900 dark:text-gray-50" > { p . variable . name } </ span >
92
+ < span className = "truncate text-sm" > { p . variable . repositoryPattern } </ span >
93
+ </ div >
94
+ </ div >
95
+ < div className = "flex justify-end mt-6" >
96
+ < button className = "secondary" onClick = { p . onClose } > Cancel</ button >
97
+ < button className = "ml-2 danger" onClick = { ( ) => { p . deleteVariable ( ) ; p . onClose ( ) ; } } > Delete Variable</ button >
98
+ </ div >
99
+ </ Modal > ;
100
+ }
101
+
82
102
function sortEnvVars ( a : UserEnvVarValue , b : UserEnvVarValue ) {
83
103
if ( a . name === b . name ) {
84
104
return a . repositoryPattern > b . repositoryPattern ? 1 : - 1 ;
@@ -90,6 +110,7 @@ export default function EnvVars() {
90
110
const [ envVars , setEnvVars ] = useState ( [ ] as UserEnvVarValue [ ] ) ;
91
111
const [ currentEnvVar , setCurrentEnvVar ] = useState ( { name : '' , value : '' , repositoryPattern : '' } as UserEnvVarValue ) ;
92
112
const [ isAddEnvVarModalVisible , setAddEnvVarModalVisible ] = useState ( false ) ;
113
+ const [ isDeleteEnvVarModalVisible , setDeleteEnvVarModalVisible ] = useState ( false ) ;
93
114
const update = async ( ) => {
94
115
await getGitpodService ( ) . server . getAllEnvVars ( ) . then ( r => setEnvVars ( r . sort ( sortEnvVars ) ) ) ;
95
116
}
@@ -102,19 +123,27 @@ export default function EnvVars() {
102
123
const add = ( ) => {
103
124
setCurrentEnvVar ( { name : '' , value : '' , repositoryPattern : '' } ) ;
104
125
setAddEnvVarModalVisible ( true ) ;
126
+ setDeleteEnvVarModalVisible ( false ) ;
105
127
}
106
128
107
- const edit = ( ev : UserEnvVarValue ) => {
108
- setCurrentEnvVar ( ev ) ;
129
+ const edit = ( variable : UserEnvVarValue ) => {
130
+ setCurrentEnvVar ( variable ) ;
109
131
setAddEnvVarModalVisible ( true ) ;
132
+ setDeleteEnvVarModalVisible ( false ) ;
133
+ }
134
+
135
+ const confirmDeleteVariable = ( variable : UserEnvVarValue ) => {
136
+ setCurrentEnvVar ( variable ) ;
137
+ setAddEnvVarModalVisible ( false ) ;
138
+ setDeleteEnvVarModalVisible ( true ) ;
110
139
}
111
140
112
141
const save = async ( variable : UserEnvVarValue ) => {
113
142
await getGitpodService ( ) . server . setEnvVar ( variable ) ;
114
143
await update ( ) ;
115
144
} ;
116
145
117
- const deleteV = async ( variable : UserEnvVarValue ) => {
146
+ const deleteVariable = async ( variable : UserEnvVarValue ) => {
118
147
await getGitpodService ( ) . server . deleteEnvVar ( variable ) ;
119
148
await update ( ) ;
120
149
} ;
@@ -145,26 +174,32 @@ export default function EnvVars() {
145
174
}
146
175
}
147
176
}
177
+ if ( ! variable . id && envVars . some ( v => v . name === name && v . repositoryPattern === pattern ) ) {
178
+ return 'A variable with this name and scope already exists' ;
179
+ }
148
180
return '' ;
149
181
} ;
150
182
151
- return < PageWithSubMenu subMenu = { settingsMenu } title = 'Variables' subtitle = 'Configure environment variables for all workspaces.' >
152
- { isAddEnvVarModalVisible ? < AddEnvVarModal
183
+ return < PageWithSubMenu subMenu = { settingsMenu } title = 'Variables' subtitle = 'Configure environment variables for all workspaces.' >
184
+ { isAddEnvVarModalVisible && < AddEnvVarModal
153
185
save = { save }
154
186
envVar = { currentEnvVar }
155
187
validate = { validate }
156
- onClose = { ( ) => setAddEnvVarModalVisible ( false ) } /> : null }
188
+ onClose = { ( ) => setAddEnvVarModalVisible ( false ) } /> }
189
+ { isDeleteEnvVarModalVisible && < DeleteEnvVarModal
190
+ variable = { currentEnvVar }
191
+ deleteVariable = { ( ) => deleteVariable ( currentEnvVar ) }
192
+ onClose = { ( ) => setDeleteEnvVarModalVisible ( false ) } /> }
157
193
< div className = "flex items-start sm:justify-between mb-2" >
158
194
< div >
159
195
< h3 > Environment Variables</ h3 >
160
196
< h2 className = "text-gray-500" > Variables are used to store information like passwords.</ h2 >
161
197
</ div >
162
198
{ envVars . length !== 0
163
- ?
164
- < div className = "mt-3 flex mt-0" >
165
- < button onClick = { add } className = "ml-2" > New Variable</ button >
166
- </ div >
167
- : null }
199
+ ? < div className = "mt-3 flex mt-0" >
200
+ < button onClick = { add } className = "ml-2" > New Variable</ button >
201
+ </ div >
202
+ : null }
168
203
</ div >
169
204
{ envVars . length === 0
170
205
? < div className = "bg-gray-100 dark:bg-gray-800 rounded-xl w-full h-96" >
@@ -183,22 +218,22 @@ export default function EnvVars() {
183
218
</ div >
184
219
</ div >
185
220
< div className = "flex flex-col" >
186
- { envVars . map ( ev => {
221
+ { envVars . map ( variable => {
187
222
return < div className = "rounded-xl whitespace-nowrap flex space-x-2 py-3 px-3 w-full justify-between hover:bg-gray-100 dark:hover:bg-gray-800 focus:bg-gitpod-kumquat-light transition ease-in-out group" >
188
- < div className = "w-5/12 m-auto" > { ev . name } </ div >
189
- < div className = "w-5/12 m-auto text-sm text-gray-400" > { ev . repositoryPattern } </ div >
223
+ < div className = "w-5/12 m-auto" > { variable . name } </ div >
224
+ < div className = "w-5/12 m-auto text-sm text-gray-400" > { variable . repositoryPattern } </ div >
190
225
< div className = "w-2/12 flex justify-end" >
191
226
< div className = "flex w-8 self-center hover:bg-gray-200 dark:hover:bg-gray-700 rounded-md cursor-pointer opacity-0 group-hover:opacity-100" >
192
227
< ContextMenu menuEntries = { [
193
228
{
194
229
title : 'Edit' ,
195
- onClick : ( ) => edit ( ev ) ,
230
+ onClick : ( ) => edit ( variable ) ,
196
231
separator : true
197
232
} ,
198
233
{
199
234
title : 'Delete' ,
200
235
customFontStyle : 'text-red-600 dark:text-red-400 hover:text-red-800 dark:hover:text-red-300' ,
201
- onClick : ( ) => deleteV ( ev )
236
+ onClick : ( ) => confirmDeleteVariable ( variable )
202
237
} ,
203
238
] } >
204
239
< svg className = "w-8 h-8 p-1 text-gray-600 dark:text-gray-300" xmlns = "http://www.w3.org/2000/svg" viewBox = "0 0 24 24" > < title > Actions</ title > < g fill = "currentColor" transform = "rotate(90 12 12)" > < circle cx = "1" cy = "1" r = "2" transform = "translate(5 11)" /> < circle cx = "1" cy = "1" r = "2" transform = "translate(11 11)" /> < circle cx = "1" cy = "1" r = "2" transform = "translate(17 11)" /> </ g > </ svg >
0 commit comments