Skip to content

Commit f49651f

Browse files
committed
Show name,description fields only for synchronous backup provider plugins in create backup (nas & dummy).
1 parent 55486d6 commit f49651f

File tree

3 files changed

+154
-7
lines changed

3 files changed

+154
-7
lines changed

ui/public/locales/en.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2854,7 +2854,7 @@
28542854
"message.autoscale.vm.networks": "Please choose at least one Network for Instances in the autoscaling group. The default Network must be an Isolated Network or VPC Network Tier which supports Instance AutoScaling and has load balancing rules.",
28552855
"message.autoscale.vmprofile.update": "The autoscale Instance profile can be updated only when autoscaling group is DISABLED.",
28562856
"message.backup.attach.restore": "Please confirm that you want to restore and attach the volume from the backup?",
2857-
"message.backup.create": "Are you sure you want create an Instance backup?",
2857+
"message.backup.create": "Are you sure you want to create an Instance backup?",
28582858
"message.backup.offering.remove": "Are you sure you want to remove Instance from backup offering and delete the backup chain?",
28592859
"message.backup.restore": "Please confirm that you want to restore the Instance backup?",
28602860
"message.cancel.shutdown": "Please confirm that you would like to cancel the shutdown on this Management Server. It will resume accepting any new Async Jobs.",
@@ -2939,6 +2939,7 @@
29392939
"message.confirm.type": "To confirm, please type",
29402940
"message.confirm.upgrade.router.newer.template": "Please confirm that you want to upgrade router to use newer Template.",
29412941
"message.cpu.usage.info": "The CPU usage percentage can exceed 100% if the Instance has more than 1 vCPU or when CPU Cap is not enabled. This behavior happens according to the hypervisor being used (e.g: in KVM), due to how they account the stats",
2942+
"message.create.backup.failed": "Failed to create backup.",
29422943
"message.create.bucket.failed": "Failed to create bucket.",
29432944
"message.create.bucket.processing": "Bucket creation in progress",
29442945
"message.create.compute.offering": "Compute offering created",

ui/src/config/section/compute.js

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -243,13 +243,9 @@ export default {
243243
message: 'message.backup.create',
244244
docHelp: 'adminguide/virtual_machines.html#creating-vm-backups',
245245
dataView: true,
246-
args: ['name', 'description', 'virtualmachineid'],
247246
show: (record) => { return record.backupofferingid },
248-
mapping: {
249-
virtualmachineid: {
250-
value: (record, params) => { return record.id }
251-
}
252-
}
247+
popup: true,
248+
component: shallowRef(defineAsyncComponent(() => import('@/views/compute/StartBackup.vue')))
253249
},
254250
{
255251
api: 'createBackupSchedule',
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
<template>
19+
<div class="form-layout" v-ctrl-enter="handleSubmit">
20+
<a-spin :spinning="loading">
21+
<a-form
22+
:ref="formRef"
23+
:model="form"
24+
:rules="rules"
25+
layout="vertical"
26+
@finish="handleSubmit"
27+
>
28+
<div style="margin-bottom: 10px">
29+
<a-alert type="warning">
30+
<template #message>
31+
<div v-html="$t('message.backup.create')"></div>
32+
</template>
33+
</a-alert>
34+
</div>
35+
<div v-if="canSetNameAndDescription">
36+
<a-form-item name="name" ref="name" :label="$t('label.name')">
37+
<a-input v-model:value="form.name" v-focus="true" />
38+
</a-form-item>
39+
<a-form-item name="description" ref="description" :label="$t('label.description')">
40+
<a-input v-model:value="form.description" v-focus="true" />
41+
</a-form-item>
42+
</div>
43+
</a-form>
44+
<div :span="24" class="action-button">
45+
<a-button @click="closeAction">{{ $t('label.cancel') }}</a-button>
46+
<a-button :loading="loading" type="primary" @click="handleSubmit" ref="submit">{{ $t('label.ok') }}</a-button>
47+
</div>
48+
</a-spin>
49+
</div>
50+
</template>
51+
<script>
52+
import { ref, toRaw } from 'vue'
53+
import { api } from '@/api'
54+
import { mixinForm } from '@/utils/mixin'
55+
56+
export default {
57+
name: 'StartBackup',
58+
mixins: [mixinForm],
59+
props: {
60+
resource: {
61+
type: Object,
62+
required: true
63+
}
64+
},
65+
data () {
66+
return {
67+
plugin: null,
68+
loading: false
69+
}
70+
},
71+
created () {
72+
this.initForm()
73+
this.getBackupProviderPlugin()
74+
},
75+
computed: {
76+
canSetNameAndDescription () {
77+
return ['nas', 'dummy'].includes(this.plugin)
78+
}
79+
},
80+
methods: {
81+
initForm () {
82+
this.formRef = ref()
83+
this.form = ({})
84+
},
85+
getBackupProviderPlugin () {
86+
this.loading = true
87+
api('listConfigurations', { name: 'backup.framework.provider.plugin' }).then(json => {
88+
this.plugin = json.listconfigurationsresponse.configuration[0].value
89+
}).finally(() => {
90+
this.loading = false
91+
})
92+
},
93+
closeModal () {
94+
this.$emit('close-action')
95+
},
96+
handleSubmit (e) {
97+
e.preventDefault()
98+
if (this.loading) return
99+
this.formRef.value.validate().then(async () => {
100+
const formRaw = toRaw(this.form)
101+
const values = this.handleRemoveFields(formRaw)
102+
103+
var data = {
104+
virtualmachineid: this.resource.id,
105+
name: this.form.name,
106+
description: this.form.description
107+
}
108+
this.loading = true
109+
api('createBackup', data).then(response => {
110+
this.$pollJob({
111+
jobId: response.createbackupresponse.jobid,
112+
title: this.$t('label.create.bucket'),
113+
description: values.name,
114+
errorMessage: this.$t('message.create.backup.failed'),
115+
loadingMessage: `${this.$t('label.create.backup')}: ${this.resource.name || this.resource.id}`,
116+
catchMessage: this.$t('error.fetching.async.job.result')
117+
})
118+
this.closeModal()
119+
}).catch(error => {
120+
this.$notifyError(error)
121+
}).finally(() => {
122+
this.loading = false
123+
})
124+
}).catch((error) => {
125+
this.formRef.value.scrollToField(error.errorFields[0].name)
126+
})
127+
}
128+
}
129+
}
130+
131+
</script>
132+
<style lang="scss" scoped>
133+
.form-layout {
134+
width: 80vw;
135+
136+
@media (min-width: 500px) {
137+
width: 400px;
138+
}
139+
}
140+
.actions {
141+
display: flex;
142+
justify-content: flex-end;
143+
margin-top: 20px;
144+
button {
145+
&:not(:last-child) {
146+
margin-right: 10px;
147+
}
148+
}
149+
}
150+
</style>

0 commit comments

Comments
 (0)