Skip to content

Commit 72b99a3

Browse files
authored
Make resource deletion safer with name confirmation (#13104)
* enable double confirmation in delete flow for resource * address copilot comments
1 parent 4425ee4 commit 72b99a3

3 files changed

Lines changed: 30 additions & 17 deletions

File tree

ui/public/locales/en.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -795,6 +795,7 @@
795795
"label.delete.ciscoasa1000v": "Delete CiscoASA1000v",
796796
"label.delete.ciscovnmc.resource": "Delete CiscoVNMC resource",
797797
"label.delete.condition": "Delete condition",
798+
"label.delete.confirmation": "Enter the exact resource name to proceed with deletion",
798799
"label.delete.custom.action": "Delete Custom Action",
799800
"label.delete.dedicated.vlan.range": "Deleted dedicated VLAN/VNI range.",
800801
"label.delete.domain": "Delete domain",

ui/src/config/section/project.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ export default {
162162
},
163163
groupAction: true,
164164
popup: true,
165+
requireNameConfirmation: true,
165166
groupMap: (selection, values) => { return selection.map(x => { return { id: x, cleanup: values.cleanup || null } }) },
166167
args: (record, store) => {
167168
const fields = []

ui/src/views/AutogenView.vue

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,6 @@
195195
:footer="null"
196196
style="top: 20px;"
197197
:width="modalWidth"
198-
:ok-button-props="getOkProps()"
199-
:cancel-button-props="getCancelProps()"
200198
:confirmLoading="actionLoading"
201199
@cancel="cancelAction"
202200
centered
@@ -270,8 +268,18 @@
270268
</a-table>
271269
</div>
272270
<br v-if="currentAction.paramFields.length > 0" />
273-
</span>
274-
<a-form
271+
</span>
272+
<div v-if="currentAction.requireNameConfirmation && !(currentAction.groupAction && selectedRowKeys.length > 0)" style="margin-bottom: 5px">
273+
<a-form-item>
274+
<a-input v-model:value="actionConfirmText" :placeholder="resource.name" />
275+
</a-form-item>
276+
<a-alert type="info">
277+
<template #message>
278+
<div v-html="$t('label.delete.confirmation')"></div>
279+
</template>
280+
</a-alert>
281+
</div>
282+
<a-form
275283
:ref="formRef"
276284
:model="form"
277285
:rules="rules"
@@ -531,6 +539,7 @@
531539
type="primary"
532540
@click="handleSubmit"
533541
ref="submit"
542+
:disabled="isSubmitDisabled"
534543
>{{ $t('label.ok') }}</a-button>
535544
</div>
536545
</a-form>
@@ -691,6 +700,7 @@ export default {
691700
confirmDirty: false,
692701
firstIndex: 0,
693702
modalWidth: '30vw',
703+
actionConfirmText: '',
694704
promises: []
695705
}
696706
},
@@ -898,6 +908,12 @@ export default {
898908
return 'active'
899909
}
900910
return 'self'
911+
},
912+
isSubmitDisabled () {
913+
if (this.currentAction?.requireNameConfirmation && !(this.currentAction.groupAction && this.selectedRowKeys.length > 0)) {
914+
return this.actionConfirmText.trim() !== this.resource?.name?.trim()
915+
}
916+
return false
901917
}
902918
},
903919
methods: {
@@ -907,19 +923,6 @@ export default {
907923
}
908924
return 'inline-flex'
909925
},
910-
getOkProps () {
911-
if (this.selectedRowKeys.length > 0 && this.currentAction?.groupAction) {
912-
} else {
913-
return { props: { type: 'primary' } }
914-
}
915-
},
916-
getCancelProps () {
917-
if (this.selectedRowKeys.length > 0 && this.currentAction?.groupAction) {
918-
return { props: { type: 'primary' } }
919-
} else {
920-
return { props: { type: 'default' } }
921-
}
922-
},
923926
switchProject (projectId) {
924927
if (!projectId || !projectId.length || projectId.length !== 36) {
925928
return
@@ -1308,6 +1311,7 @@ export default {
13081311
this.actionLoading = false
13091312
this.showAction = false
13101313
this.currentAction = {}
1314+
this.actionConfirmText = ''
13111315
},
13121316
cancelAction () {
13131317
eventBus.emit('action-closing', { action: this.currentAction })
@@ -1365,6 +1369,7 @@ export default {
13651369
this.currentAction = action
13661370
this.currentAction.params = store.getters.apis[this.currentAction.api].params
13671371
this.resource = action.resource
1372+
this.actionConfirmText = ''
13681373
this.$emit('change-resource', this.resource)
13691374
var paramFields = this.currentAction.params
13701375
paramFields.sort(function (a, b) {
@@ -1647,6 +1652,12 @@ export default {
16471652
},
16481653
handleSubmit (e) {
16491654
if (this.actionLoading) return
1655+
1656+
if (this.currentAction?.requireNameConfirmation && !(this.currentAction.groupAction && this.selectedRowKeys.length > 0)) {
1657+
if (this.actionConfirmText.trim() !== this.resource?.name?.trim()) {
1658+
return
1659+
}
1660+
}
16501661
this.promises = []
16511662
if (!this.dataView && this.currentAction.groupAction && this.selectedRowKeys.length > 0) {
16521663
if (this.selectedRowKeys.length > 0) {

0 commit comments

Comments
 (0)