diff --git a/ui/src/config/eventBus.js b/ui/src/config/eventBus.js
new file mode 100644
index 00000000000..ed61648940b
--- /dev/null
+++ b/ui/src/config/eventBus.js
@@ -0,0 +1,19 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+import Vue from 'vue'
+export default new Vue()
diff --git a/ui/src/config/section/compute.js b/ui/src/config/section/compute.js
index 818f6bc3348..03d68b1a5e8 100644
--- a/ui/src/config/section/compute.js
+++ b/ui/src/config/section/compute.js
@@ -94,8 +94,11 @@ export default {
groupAction: true,
groupMap: (selection) => { return selection.map(x => { return { id: x } }) },
show: (record) => { return ['Stopped'].includes(record.state) },
- args: (record, store) => {
+ args: (record, store, group) => {
var fields = []
+ if (group) {
+ return fields
+ }
if (store.userInfo.roletype === 'Admin') {
fields = ['podid', 'clusterid', 'hostid']
}
@@ -116,7 +119,7 @@ export default {
docHelp: 'adminguide/virtual_machines.html#stopping-and-starting-vms',
dataView: true,
groupAction: true,
- groupMap: (selection) => { return selection.map(x => { return { id: x } }) },
+ groupMap: (selection, values) => { return selection.map(x => { return { id: x, forced: values.forced } }) },
args: ['forced'],
show: (record) => { return ['Running'].includes(record.state) }
},
@@ -384,8 +387,9 @@ export default {
docHelp: 'adminguide/virtual_machines.html#deleting-vms',
dataView: true,
groupAction: true,
+ args: ['expunge'],
popup: true,
- groupMap: (selection) => { return selection.map(x => { return { id: x, expunge: true } }) },
+ groupMap: (selection, values) => { return selection.map(x => { return { id: x, expunge: values.expunge } }) },
show: (record) => { return ['Running', 'Stopped', 'Error'].includes(record.state) },
component: () => import('@/views/compute/DestoryVM.vue')
}
diff --git a/ui/src/locales/en.json b/ui/src/locales/en.json
index a40047211e0..00dc0486bfc 100644
--- a/ui/src/locales/en.json
+++ b/ui/src/locales/en.json
@@ -612,11 +612,11 @@
"label.create.nfs.secondary.staging.store": "Create NFS secondary staging store",
"label.create.project": "Create project",
"label.create.project.role": "Create Project Role",
-"label.create.user": "Create user",
"label.create.site.vpn.connection": "Create Site-to-Site VPN Connection",
"label.create.site.vpn.gateway": "Create Site-to-Site VPN Gateway",
"label.create.ssh.key.pair": "Create a SSH Key Pair",
"label.create.template": "Create template",
+"label.create.user": "Create user",
"label.create.vpn.connection": "Create VPN Connection",
"label.created": "Created",
"label.created.by.system": "Created by system",
@@ -635,6 +635,7 @@
"label.daily": "Daily",
"label.dashboard": "Dashboard",
"label.dashboard.endpoint": "Dashboard endpoint",
+"label.data.disk": "Data Disk",
"label.data.disk.offering": "Data Disk Offering",
"label.date": "Date",
"label.day": "Day",
@@ -699,9 +700,9 @@
"label.deleting.failed": "Deleting Failed",
"label.deleting.iso": "Deleting ISO",
"label.deleting.processing": "Deleting....",
+"label.deleting.template": "Deleting template",
"label.demote.project.owner": "Demote account to Regular role",
"label.demote.project.owner.user": "Demote user to Regular role",
-"label.deleting.template": "Deleting template",
"label.deny": "Deny",
"label.deployasis":"Deploy As-Is",
"label.deploymentplanner": "Deployment planner",
@@ -805,10 +806,10 @@
"label.edit.region": "Edit Region",
"label.edit.role": "Edit Role",
"label.edit.rule": "Edit rule",
-"label.edit.user": "Edit user",
"label.edit.secondary.ips": "Edit secondary IPs",
"label.edit.tags": "Edit tags",
"label.edit.traffic.type": "Edit traffic type",
+"label.edit.user": "Edit user",
"label.edit.vpc": "Edit VPC",
"label.egress": "Egress",
"label.egress.default.policy": "Egress Default Policy",
@@ -1004,6 +1005,7 @@
"label.hypervisortype": "Hypervisor",
"label.hypervisorversion": "Hypervisor Version",
"label.hypervnetworklabel": "HyperV Traffic Label",
+"label.i.accept.all.license.agreements": "I accept all license agreement",
"label.icmp": "ICMP",
"label.icmpcode": "ICMP Code",
"label.icmpcode.end.port": "ICMP Code / End Port",
@@ -1145,7 +1147,6 @@
"label.isvolatile": "Volatile",
"label.item.listing": "Item listing",
"label.items": "items",
-"label.i.accept.all.license.agreements": "I accept all license agreement",
"label.japanese.keyboard": "Japanese keyboard",
"label.keep": "Keep",
"label.keep.colon": "Keep:",
@@ -1290,6 +1291,7 @@
"label.memallocated": "Mem Allocation",
"label.memory": "Memory",
"label.memory.maximum.mb": "Max Memory (in MB)",
+"label.memory.mb": "Memory (in MB)",
"label.memory.total": "Memory Total",
"label.memory.used": "Memory Used",
"label.memoryallocated": "Memory Allocated",
@@ -1602,7 +1604,6 @@
"label.profiledn": "Associated Profile",
"label.profilename": "Profile",
"label.project": "Project",
-"label.projectname": "Project",
"label.project.dashboard": "Project dashboard",
"label.project.ids": "Project IDs",
"label.project.invitation": "Project Invitations",
@@ -1610,12 +1611,13 @@
"label.project.name": "Project name",
"label.project.owner": "Project Owner(s)",
"label.project.role": "Project Role",
-"label.project.roles": "Project Roles",
"label.project.role.permissions": "Project Role Permissions",
+"label.project.roles": "Project Roles",
"label.project.view": "Project View",
"label.projectaccountname": "Project Account Name",
"label.projectid": "Project ID",
"label.projectlimit": "Project Limits",
+"label.projectname": "Project",
"label.projects": "Projects",
"label.promiscuousmode": "Promiscuous Mode",
"label.property": "Property",
@@ -1690,9 +1692,9 @@
"label.rbdmonitor": "Ceph monitor",
"label.rbdpool": "Ceph pool",
"label.rbdsecret": "Cephx secret",
-"label.readonly": "Read-Only",
"label.read": "Read",
"label.read.io": "Read (IO)",
+"label.readonly": "Read-Only",
"label.reason": "Reason",
"label.reboot": "Reboot",
"label.receivedbytes": "Bytes Received",
@@ -2929,8 +2931,8 @@
"message.number.storage": "
# of Primary Storage Volumes
",
"message.number.zones": " # of Zones
",
"message.outofbandmanagement.action.maintenance": "Warning host is in maintenance mode",
-"message.ovf.properties.available": "There are OVF properties available for customizing the selected appliance. Please edit the values accordingly.",
"message.ovf.configurations": "OVF configurations available for the selected appliance. Please select the desired value. Incompatible compute offerings will get disbaled.",
+"message.ovf.properties.available": "There are OVF properties available for customizing the selected appliance. Please edit the values accordingly.",
"message.password.has.been.reset.to": "Password has been reset to",
"message.password.of.the.vm.has.been.reset.to": "Password of the VM has been reset to",
"message.pending.projects.1": "You have pending project invitations:",
@@ -3035,9 +3037,6 @@
"message.step.4.desc": "Please select the primary network that your virtual instance will be connected to.",
"message.step.license.agreements.continue": "Please aceept all license agreements to continue",
"message.storage.traffic": "Traffic between CloudStack's internal resources, including any components that communicate with the Management Server, such as hosts and CloudStack system VMs. Please configure storage traffic here.",
-"message.success.enable.saml.auth": "Successfully enabled SAML Authorization",
-"message.success.create.user": "Successfully created user",
-"message.success.update.user": "Successfully updated user",
"message.success.acquire.ip": "Successfully acquired IP",
"message.success.add.egress.rule": "Successfully added new Egress rule",
"message.success.add.firewall.rule": "Successfully added new Firewall rule",
@@ -3071,6 +3070,7 @@
"message.success.create.kubernetes.cluter": "Successfully created Kubernetes cluster",
"message.success.create.l2.network": "Successfully created L2 network",
"message.success.create.snapshot.from.vmsnapshot": "Successfully created Snapshot from VM snapshot",
+"message.success.create.user": "Successfully created user",
"message.success.create.volume": "Successfully created volume",
"message.success.delete": "Delete success",
"message.success.delete.acl.rule": "Successfully removed ACL rule",
@@ -3106,6 +3106,7 @@
"message.success.scale.kubernetes": "Successfully scaled Kubernetes cluster",
"message.success.update.ipaddress": "Successfully updated IP Address",
"message.success.update.kubeversion": "Successfully updated Kubernetes supported version",
+"message.success.update.user": "Successfully updated user",
"message.success.upgrade.kubernetes": "Successfully upgraded Kubernetes cluster",
"message.success.upload": "Upload Successfully",
"message.success.upload.description": "This ISO file has been uploaded. Please check its status at Templates menu",
diff --git a/ui/src/views/AutogenView.vue b/ui/src/views/AutogenView.vue
index 4acf5227c1b..a00637feaba 100644
--- a/ui/src/views/AutogenView.vue
+++ b/ui/src/views/AutogenView.vue
@@ -70,7 +70,7 @@
:selectedRowKeys="selectedRowKeys"
:dataView="dataView"
:resource="resource"
- @exec-action="execAction"/>
+ @exec-action="(action) => execAction(action, action.groupAction && !dataView)"/>
0) {
this.currentAction.paramFields = args.map(function (arg) {
@@ -814,24 +819,28 @@ export default {
},
handleSubmit (e) {
if (!this.dataView && this.currentAction.groupAction && this.selectedRowKeys.length > 0) {
- const paramsList = this.currentAction.groupMap(this.selectedRowKeys)
- this.actionLoading = true
- for (const params of paramsList) {
- api(this.currentAction.api, params).then(json => {
- }).catch(error => {
- this.$notifyError(error)
- })
- }
- this.$message.info({
- content: this.$t(this.currentAction.label),
- key: this.currentAction.label,
- duration: 3
+ this.form.validateFields((err, values) => {
+ if (!err) {
+ const paramsList = this.currentAction.groupMap(this.selectedRowKeys, values)
+ this.actionLoading = true
+ for (const params of paramsList) {
+ api(this.currentAction.api, params).then(json => {
+ }).catch(error => {
+ this.$notifyError(error)
+ })
+ }
+ this.$message.info({
+ content: this.$t(this.currentAction.label),
+ key: this.currentAction.label,
+ duration: 3
+ })
+ setTimeout(() => {
+ this.actionLoading = false
+ this.closeAction()
+ this.fetchData()
+ }, 2000)
+ }
})
- setTimeout(() => {
- this.actionLoading = false
- this.closeAction()
- this.fetchData()
- }, 2000)
} else {
this.execSubmit(e)
}
diff --git a/ui/src/views/compute/DeployVM.vue b/ui/src/views/compute/DeployVM.vue
index 18f90a44034..35ea64c62ec 100644
--- a/ui/src/views/compute/DeployVM.vue
+++ b/ui/src/views/compute/DeployVM.vue
@@ -193,7 +193,7 @@
:isConstrained="'serviceofferingdetails' in serviceOffering"
:minCpu="'serviceofferingdetails' in serviceOffering ? serviceOffering.serviceofferingdetails.mincpunumber*1 : 1"
:maxCpu="'serviceofferingdetails' in serviceOffering ? serviceOffering.serviceofferingdetails.maxcpunumber*1 : Number.MAX_SAFE_INTEGER"
- :minMemory="'serviceofferingdetails' in serviceOffering ? serviceOffering.serviceofferingdetails.minmemory*1 : 1"
+ :minMemory="'serviceofferingdetails' in serviceOffering ? serviceOffering.serviceofferingdetails.minmemory*1 : 0"
:maxMemory="'serviceofferingdetails' in serviceOffering ? serviceOffering.serviceofferingdetails.maxmemory*1 : Number.MAX_SAFE_INTEGER"
@update-compute-cpunumber="updateFieldValue"
@update-compute-cpuspeed="updateFieldValue"
@@ -215,7 +215,7 @@
@@ -543,6 +543,7 @@ import { api } from '@/api'
import _ from 'lodash'
import { mixin, mixinDevice } from '@/utils/mixin.js'
import store from '@/store'
+import eventBus from '@/config/eventBus'
import InfoCard from '@/components/view/InfoCard'
import ComputeOfferingSelection from '@views/compute/wizard/ComputeOfferingSelection'
@@ -1289,7 +1290,7 @@ export default {
}
// step 3: select service offering
deployVmData.serviceofferingid = values.computeofferingid
- if (values.cpunumber || values.cpuspeed || values.memory) {
+ if (this.serviceOffering && this.serviceOffering.iscustomized) {
if (values.cpunumber) {
deployVmData['details[0].cpuNumber'] = values.cpunumber
}
@@ -1383,9 +1384,16 @@ export default {
duration: 0
})
}
+ eventBus.$emit('refresh-data')
+ },
+ errorMethod: () => {
+ eventBus.$emit('refresh-data')
},
loadingMessage: `${title} ${this.$t('label.in.progress')}`,
- catchMessage: this.$t('error.fetching.async.job.result')
+ catchMessage: this.$t('error.fetching.async.job.result'),
+ catchMethod: () => {
+ eventBus.$emit('refresh-data')
+ }
})
this.$store.dispatch('AddAsyncJob', {
title: title,
diff --git a/ui/src/views/compute/wizard/ComputeSelection.vue b/ui/src/views/compute/wizard/ComputeSelection.vue
index bd5ee02442d..2b402682edc 100644
--- a/ui/src/views/compute/wizard/ComputeSelection.vue
+++ b/ui/src/views/compute/wizard/ComputeSelection.vue
@@ -56,7 +56,7 @@
@@ -71,8 +71,6 @@
updateComputeMemory($event)"
/>
@@ -106,7 +104,7 @@ export default {
},
minMemory: {
type: Number,
- default: 1
+ default: 0
},
maxMemory: {
type: Number,
@@ -158,19 +156,22 @@ export default {
watch: {
computeOfferingId (newValue, oldValue) {
if (newValue !== oldValue) {
- this.cpuNumberInputValue = this.minCpu
- this.memoryInputValue = this.minMemory
+ this.fillValue()
}
}
},
mounted () {
- this.cpuNumberInputValue = this.minCpu
- this.memoryInputValue = this.minMemory
this.fillValue()
},
methods: {
fillValue () {
+ this.cpuNumberInputValue = this.minCpu
+ this.memoryInputValue = this.minMemory
+
if (!this.preFillContent) {
+ this.updateComputeCpuNumber(this.cpuNumberInputValue)
+ this.updateComputeCpuSpeed(this.cpuSpeedInputValue)
+ this.updateComputeMemory(this.memoryInputValue)
return
}
if (this.preFillContent.cpunumber) {
@@ -182,6 +183,9 @@ export default {
if (this.preFillContent.memory) {
this.memoryInputValue = this.preFillContent.memory
}
+ this.updateComputeCpuNumber(this.preFillContent.cpunumber || this.cpuNumberInputValue)
+ this.updateComputeCpuSpeed(this.preFillContent.cpuspeed || this.cpuSpeedInputValue)
+ this.updateComputeMemory(this.preFillContent.memory || this.memoryInputValue)
},
updateComputeCpuNumber (value) {
if (!this.validateInput('cpu', value)) {
diff --git a/ui/src/views/image/RegisterOrUploadIso.vue b/ui/src/views/image/RegisterOrUploadIso.vue
index f632fc66287..501d52848cc 100644
--- a/ui/src/views/image/RegisterOrUploadIso.vue
+++ b/ui/src/views/image/RegisterOrUploadIso.vue
@@ -29,6 +29,7 @@
layout="vertical">
- {{ $t('label.memory') }}
+ {{ $t('label.memory.mb') }}