mirror of https://github.com/apache/cloudstack.git
Merge remote-tracking branch 'origin/4.18'
Signed-off-by: Rohit Yadav <rohit.yadav@shapeblue.com>
This commit is contained in:
commit
62feb24de6
|
|
@ -61,6 +61,7 @@
|
|||
"label.action.create.snapshot.from.vmsnapshot": "Create snapshot from VM snapshot",
|
||||
"label.action.create.template.from.volume": "Create template from volume",
|
||||
"label.action.create.volume": "Create volume",
|
||||
"label.action.create.volume.add": "Create and Add Volume",
|
||||
"label.action.delete.account": "Delete account",
|
||||
"label.action.delete.backup.offering": "Delete backup offering",
|
||||
"label.action.delete.cluster": "Delete cluster",
|
||||
|
|
@ -1156,7 +1157,8 @@
|
|||
"label.license.agreements": "License agreements",
|
||||
"label.limit": "Limit",
|
||||
"label.limitcpuuse": "CPU cap",
|
||||
"label.limits": "Configure limits",
|
||||
"label.limits": "Limits",
|
||||
"label.limits.configure": "Configure limits",
|
||||
"label.link.domain.to.ldap": "Link domain to LDAP",
|
||||
"label.linklocalip": "Link-local/Control IP address",
|
||||
"label.linux": "Linux",
|
||||
|
|
@ -1824,6 +1826,7 @@
|
|||
"label.snapshotlimit": "Snapshot limits",
|
||||
"label.snapshotmemory": "Snapshot memory",
|
||||
"label.snapshots": "Snapshots",
|
||||
"label.snapshottype": "Snapshot Type",
|
||||
"label.sockettimeout": "Socket timeout",
|
||||
"label.softwareversion": "Software version",
|
||||
"label.source.based": "SourceBased",
|
||||
|
|
@ -2185,6 +2188,7 @@
|
|||
"label.volumename": "Volume name",
|
||||
"label.volumes": "Volumes",
|
||||
"label.volumetotal": "Volume",
|
||||
"label.volumetype": "Volume Type",
|
||||
"label.vpc": "VPC",
|
||||
"label.vpc.id": "VPC ID",
|
||||
"label.vpc.offerings": "VPC offerings",
|
||||
|
|
@ -2395,6 +2399,7 @@
|
|||
"message.attach.volume": "Please fill in the following data to attach a new volume. If you are attaching a disk volume to a Windows based virtual machine, you will need to reboot the instance to see the attached disk.",
|
||||
"message.attach.volume.failed": "Failed to attach volume.",
|
||||
"message.attach.volume.progress": "Attaching volume",
|
||||
"message.attach.volume.success": "Successfully attached the volume to the instance",
|
||||
"message.authorization.failed": "Session expired, authorization verification failed.",
|
||||
"message.autoscale.loadbalancer.update": "The load balancer rule can be updated only when autoscale VM group is DISABLED.",
|
||||
"message.autoscale.policies.update": "The scale up/down policies can be updated only when autoscale VM group is DISABLED.",
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
<a-dropdown>
|
||||
<span class="user-menu-dropdown action">
|
||||
<span v-if="image">
|
||||
<resource-icon :image="image" size="2x" style="margin-right: 5px"/>
|
||||
<resource-icon :image="image" size="4x" style="margin-right: 5px; margin-top: -3px"/>
|
||||
</span>
|
||||
<a-avatar v-else-if="userInitials" class="user-menu-avatar avatar" size="small" :style="{ backgroundColor: $config.theme['@primary-color'], color: 'white' }">
|
||||
{{ userInitials }}
|
||||
|
|
@ -43,6 +43,10 @@
|
|||
<UserOutlined class="user-menu-item-icon" />
|
||||
<span class="user-menu-item-name">{{ $t('label.profilename') }}</span>
|
||||
</a-menu-item>
|
||||
<a-menu-item class="user-menu-item" key="limits">
|
||||
<ControlOutlined class="user-menu-item-icon" />
|
||||
<span class="user-menu-item-name">{{ $t('label.limits') }}</span>
|
||||
</a-menu-item>
|
||||
<a-menu-item class="user-menu-item" key="timezone">
|
||||
<ClockCircleOutlined class="user-menu-item-icon" />
|
||||
<span class="user-menu-item-name" style="margin-right: 5px">{{ $t('label.use.local.timezone') }}</span>
|
||||
|
|
@ -142,6 +146,9 @@ export default {
|
|||
case 'profile':
|
||||
this.$router.push(`/accountuser/${this.$store.getters.userInfo.id}`)
|
||||
break
|
||||
case 'limits':
|
||||
this.$router.push(`/account/${this.$store.getters.userInfo.accountid}?tab=limits`)
|
||||
break
|
||||
case 'timezone':
|
||||
this.toggleUseBrowserTimezone()
|
||||
break
|
||||
|
|
|
|||
|
|
@ -119,14 +119,12 @@ export default {
|
|||
|
||||
.ant-menu-light {
|
||||
border-right-color: transparent;
|
||||
padding: 14px 0;
|
||||
}
|
||||
}
|
||||
|
||||
&.dark {
|
||||
.ant-menu-dark {
|
||||
border-right-color: transparent;
|
||||
padding: 14px 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,6 +51,21 @@
|
|||
{{ dataResource.rootdisksize }} GB
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="['template', 'iso'].includes($route.meta.name) && item === 'size'">
|
||||
<div>
|
||||
{{ parseFloat(dataResource.size / (1024.0 * 1024.0 * 1024.0)).toFixed(2) }} GiB
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="['volume', 'snapshot', 'template', 'iso'].includes($route.meta.name) && item === 'physicalsize'">
|
||||
<div>
|
||||
{{ parseFloat(dataResource.physicalsize / (1024.0 * 1024.0 * 1024.0)).toFixed(2) }} GiB
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="['volume', 'snapshot', 'template', 'iso'].includes($route.meta.name) && item === 'virtualsize'">
|
||||
<div>
|
||||
{{ parseFloat(dataResource.virtualsize / (1024.0 * 1024.0 * 1024.0)).toFixed(2) }} GiB
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="['name', 'type'].includes(item)">
|
||||
<span v-if="['USER.LOGIN', 'USER.LOGOUT', 'ROUTER.HEALTH.CHECKS', 'FIREWALL.CLOSE', 'ALERT.SERVICE.DOMAINROUTER'].includes(dataResource[item])">{{ $t(dataResource[item].toLowerCase()) }}</span>
|
||||
<span v-else>{{ dataResource[item] }}</span>
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
v-clipboard:copy="name" >
|
||||
<upload-resource-icon v-if="'uploadResourceIcon' in $store.getters.apis" :visible="showUpload" :resource="resource" @handle-close="showUpload(false)"/>
|
||||
<div class="ant-upload-preview" v-if="$showIcon() && !$route.path.includes('zones')">
|
||||
<camera-outlined class="upload-icon"/>
|
||||
<edit-outlined class="upload-icon"/>
|
||||
</div>
|
||||
<slot name="avatar">
|
||||
<span v-if="(resource.icon && resource.icon.base64image || images.template || images.iso || resourceIcon) && !['router', 'systemvm', 'volume'].includes($route.path.split('/')[1])">
|
||||
|
|
@ -139,14 +139,14 @@
|
|||
<div class="resource-detail-item__label">{{ $t('label.id') }}</div>
|
||||
<div class="resource-detail-item__details">
|
||||
<tooltip-button
|
||||
tooltipPlacement="right"
|
||||
tooltipPlacement="top"
|
||||
:tooltip="$t('label.copyid')"
|
||||
icon="barcode-outlined"
|
||||
type="dashed"
|
||||
size="small"
|
||||
:copyResource="String(resource.id)"
|
||||
@onClick="$message.success($t('label.copied.clipboard'))" />
|
||||
<span style="margin-left: 10px;">{{ resource.id }}</span>
|
||||
<span style="margin-left: 10px;"><copy-label :label="resource.id" /></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="resource-detail-item" v-if="resource.ostypename && resource.ostypeid">
|
||||
|
|
@ -159,6 +159,29 @@
|
|||
<span style="margin-left: 8px">{{ resource.ostypename }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="resource-detail-item" v-if="resource.ipaddress">
|
||||
<div class="resource-detail-item__label">{{ $t('label.ip') }}</div>
|
||||
<div class="resource-detail-item__details">
|
||||
<environment-outlined
|
||||
@click="$message.success(`${$t('label.copied.clipboard')} : ${ ipaddress }`)"
|
||||
v-clipboard:copy="ipaddress" />
|
||||
<router-link v-if="!isStatic && resource.ipaddressid" :to="{ path: '/publicip/' + resource.ipaddressid }">
|
||||
<copy-label :label="ipaddress" />
|
||||
</router-link>
|
||||
<span v-else>
|
||||
<span v-if="ipaddress.includes(',')">
|
||||
<span
|
||||
v-for="(value, index) in ipaddress.split(',')"
|
||||
:key="index">
|
||||
<copy-label :label="value" /><br/>
|
||||
</span>
|
||||
</span>
|
||||
<span v-else>
|
||||
<copy-label :label="ipaddress" />
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="resource-detail-item" v-if="('cpunumber' in resource && 'cpuspeed' in resource) || resource.cputotal">
|
||||
<div class="resource-detail-item__label">{{ $t('label.cpu') }}</div>
|
||||
<div class="resource-detail-item__details">
|
||||
|
|
@ -312,11 +335,19 @@
|
|||
v-for="(eth, index) in resource.nic"
|
||||
:key="eth.id"
|
||||
style="margin-left: -24px; margin-top: 5px;">
|
||||
<api-outlined /><strong>eth{{ index }}</strong> {{ eth.ip6address ? eth.ipaddress + ', ' + eth.ip6address : eth.ipaddress }}
|
||||
<router-link v-if="!isStatic && eth.networkname && eth.networkid" :to="{ path: '/guestnetwork/' + eth.networkid }">({{ eth.networkname }})</router-link>
|
||||
<api-outlined />
|
||||
<strong>eth{{ index }}</strong>
|
||||
<copy-label :label="eth.ip6address ? eth.ipaddress + ', ' + eth.ip6address : eth.ipaddress" />
|
||||
<a-tag v-if="eth.isdefault">
|
||||
{{ $t('label.default') }}
|
||||
</a-tag >
|
||||
</a-tag ><br/>
|
||||
<span v-if="!isStatic && eth.networkname && eth.networkid">
|
||||
|
||||
<apartment-outlined/>
|
||||
<router-link :to="{ path: '/guestnetwork/' + eth.networkid }">
|
||||
{{ eth.networkname }}
|
||||
</router-link>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -344,16 +375,6 @@
|
|||
<span>{{ resource.loadbalancer.name }} ( {{ resource.loadbalancer.publicip }}:{{ resource.loadbalancer.publicport }})</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="resource-detail-item" v-if="resource.ipaddress">
|
||||
<div class="resource-detail-item__label">{{ $t('label.ip') }}</div>
|
||||
<div class="resource-detail-item__details">
|
||||
<environment-outlined
|
||||
@click="$message.success(`${$t('label.copied.clipboard')} : ${ ipaddress }`)"
|
||||
v-clipboard:copy="ipaddress" />
|
||||
<router-link v-if="!isStatic && resource.ipaddressid" :to="{ path: '/publicip/' + resource.ipaddressid }">{{ ipaddress }}</router-link>
|
||||
<span v-else>{{ ipaddress }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="resource-detail-item" v-if="resource.projectid || resource.projectname">
|
||||
<div class="resource-detail-item__label">{{ $t('label.project') }}</div>
|
||||
<div class="resource-detail-item__details">
|
||||
|
|
@ -388,10 +409,15 @@
|
|||
<div class="resource-detail-item" v-if="resource.keypairs && resource.keypairs.length > 0">
|
||||
<div class="resource-detail-item__label">{{ $t('label.keypairs') }}</div>
|
||||
<div class="resource-detail-item__details">
|
||||
<key-outlined />
|
||||
<li v-for="keypair in keypairs" :key="keypair">
|
||||
<router-link :to="{ path: '/ssh/' + keypair }" style="margin-right: 5px">{{ keypair }}</router-link>
|
||||
</li>
|
||||
<div>
|
||||
<div
|
||||
v-for="keypair in keypairs"
|
||||
:key="keypair"
|
||||
style="margin-top: 5px;">
|
||||
<key-outlined />
|
||||
<router-link :to="{ path: '/ssh/' + keypair }" style="margin-right: 5px">{{ keypair }}</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="resource-detail-item" v-if="resource.resourcetype && resource.resourceid && routeFromResourceType">
|
||||
|
|
@ -440,7 +466,8 @@
|
|||
<div class="resource-detail-item__label">{{ $t('label.publicip') }}</div>
|
||||
<div class="resource-detail-item__details">
|
||||
<gateway-outlined />
|
||||
<router-link :to="{ path: '/publicip/' + resource.publicipid }">{{ resource.publicip }} </router-link>
|
||||
<router-link v-if="resource.publicipid" :to="{ path: '/publicip/' + resource.publicipid }">{{ resource.publicip }} </router-link>
|
||||
<copy-label :label="resource.publicip"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="resource-detail-item" v-if="resource.vpcid">
|
||||
|
|
@ -574,6 +601,7 @@
|
|||
</span>
|
||||
<global-outlined v-else />
|
||||
<router-link v-if="!isStatic && $router.resolve('/zone/' + resource.zoneid).matched[0].redirect !== '/exception/404'" :to="{ path: '/zone/' + resource.zoneid }">{{ resource.zone || resource.zonename || resource.zoneid }}</router-link>
|
||||
<router-link v-else-if="$router.resolve('/zones/' + resource.zoneid).matched[0].redirect !== '/exception/404'" :to="{ path: '/zones/' + resource.zoneid }">{{ resource.zone || resource.zonename || resource.zoneid }}</router-link>
|
||||
<span v-else>{{ resource.zone || resource.zonename || resource.zoneid }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -753,6 +781,7 @@ import { createPathBasedOnVmType } from '@/utils/plugins'
|
|||
import Console from '@/components/widgets/Console'
|
||||
import OsLogo from '@/components/widgets/OsLogo'
|
||||
import Status from '@/components/widgets/Status'
|
||||
import CopyLabel from '@/components/widgets/CopyLabel'
|
||||
import TooltipButton from '@/components/widgets/TooltipButton'
|
||||
import UploadResourceIcon from '@/components/view/UploadResourceIcon'
|
||||
import eventBus from '@/config/eventBus'
|
||||
|
|
@ -765,6 +794,7 @@ export default {
|
|||
Console,
|
||||
OsLogo,
|
||||
Status,
|
||||
CopyLabel,
|
||||
TooltipButton,
|
||||
UploadResourceIcon,
|
||||
ResourceIcon,
|
||||
|
|
|
|||
|
|
@ -41,9 +41,9 @@
|
|||
<template v-if="column.key === 'name'">
|
||||
<span v-if="['vm'].includes($route.path.split('/')[1])" style="margin-right: 5px">
|
||||
<span v-if="record.icon && record.icon.base64image">
|
||||
<resource-icon :image="record.icon.base64image" size="1x"/>
|
||||
<resource-icon :image="record.icon.base64image" size="2x"/>
|
||||
</span>
|
||||
<os-logo v-else :osId="record.ostypeid" :osName="record.osdisplayname" size="lg" />
|
||||
<os-logo v-else :osId="record.ostypeid" :osName="record.osdisplayname" size="2x" />
|
||||
</span>
|
||||
<span style="min-width: 120px" >
|
||||
<QuickView
|
||||
|
|
@ -56,8 +56,8 @@
|
|||
<tooltip-button type="dashed" size="small" icon="LoginOutlined" @onClick="changeProject(record)" />
|
||||
</span>
|
||||
<span v-if="$showIcon() && !['vm'].includes($route.path.split('/')[1])" style="margin-right: 5px">
|
||||
<resource-icon v-if="$showIcon() && record.icon && record.icon.base64image" :image="record.icon.base64image" size="1x"/>
|
||||
<os-logo v-else-if="record.ostypename" :osName="record.ostypename" size="1x" />
|
||||
<resource-icon v-if="$showIcon() && record.icon && record.icon.base64image" :image="record.icon.base64image" size="2x"/>
|
||||
<os-logo v-else-if="record.ostypename" :osName="record.ostypename" size="2x" />
|
||||
<render-icon v-else-if="typeof $route.meta.icon ==='string'" style="font-size: 16px;" :icon="$route.meta.icon"/>
|
||||
<render-icon v-else style="font-size: 16px;" :svgIcon="$route.meta.icon" />
|
||||
</span>
|
||||
|
|
@ -119,7 +119,7 @@
|
|||
</template>
|
||||
<template v-if="column.key === 'username'">
|
||||
<span v-if="$showIcon() && !['vm'].includes($route.path.split('/')[1])" style="margin-right: 5px">
|
||||
<resource-icon v-if="$showIcon() && record.icon && record.icon.base64image" :image="record.icon.base64image" size="1x"/>
|
||||
<resource-icon v-if="$showIcon() && record.icon && record.icon.base64image" :image="record.icon.base64image" size="2x"/>
|
||||
<user-outlined v-else style="font-size: 16px;" />
|
||||
</span>
|
||||
<router-link :to="{ path: $route.path + '/' + record.id }" v-if="['/accountuser', '/vpnuser'].includes($route.path)">{{ text }}</router-link>
|
||||
|
|
@ -138,7 +138,9 @@
|
|||
</template>
|
||||
<template v-if="column.key === 'ipaddress'" href="javascript:;">
|
||||
<router-link v-if="['/publicip', '/privategw'].includes($route.path)" :to="{ path: $route.path + '/' + record.id }">{{ text }}</router-link>
|
||||
<span v-else>{{ text }}</span>
|
||||
<span v-else>
|
||||
<copy-label :label="text" />
|
||||
</span>
|
||||
<span v-if="record.issourcenat">
|
||||
|
||||
<a-tag>source-nat</a-tag>
|
||||
|
|
@ -164,6 +166,25 @@
|
|||
<template v-if="column.key === 'virtualmachinename'">
|
||||
<router-link :to="{ path: getVmRouteUsingType(record) + record.virtualmachineid }">{{ text }}</router-link>
|
||||
</template>
|
||||
<template v-if="column.key === 'volumename'">
|
||||
<router-link :to="{ path: '/volume/' + record.volumeid }">{{ text }}</router-link>
|
||||
</template>
|
||||
<template v-if="column.key === 'size'">
|
||||
<span v-if="text">
|
||||
{{ parseFloat(parseFloat(text) / 1024.0 / 1024.0 / 1024.0).toFixed(2) }} GiB
|
||||
</span>
|
||||
</template>
|
||||
<template v-if="column.key === 'physicalsize'">
|
||||
<span v-if="text">
|
||||
{{ parseFloat(parseFloat(text) / 1024.0 / 1024.0 / 1024.0).toFixed(2) }} GiB
|
||||
</span>
|
||||
</template>
|
||||
<template v-if="column.key === 'physicalnetworkname'">
|
||||
<router-link :to="{ path: '/physicalnetwork/' + record.physicalnetworkid }">{{ text }}</router-link>
|
||||
</template>
|
||||
<template v-if="column.key === 'serviceofferingname'">
|
||||
<router-link :to="{ path: '/computeoffering/' + record.serviceofferingid }">{{ text }}</router-link>
|
||||
</template>
|
||||
<template v-if="column.key === 'hypervisor'">
|
||||
<span v-if="$route.name === 'hypervisorcapability'">
|
||||
<router-link :to="{ path: $route.path + '/' + record.id }">{{ text }}</router-link>
|
||||
|
|
@ -189,6 +210,9 @@
|
|||
<status v-if="$route.path.startsWith('/host')" :text="getHostState(record)" displayText />
|
||||
<status v-else :text="text ? text : ''" displayText :styles="{ 'min-width': '80px' }" />
|
||||
</template>
|
||||
<template v-if="column.key === 'status'">
|
||||
<status :text="text ? text : ''" displayText />
|
||||
</template>
|
||||
<template v-if="column.key === 'allocationstate'">
|
||||
<status :text="text ? text : ''" displayText />
|
||||
</template>
|
||||
|
|
@ -294,6 +318,7 @@
|
|||
</template>
|
||||
<template v-if="column.key === 'zonename'">
|
||||
<router-link v-if="$router.resolve('/zone/' + record.zoneid).matched[0].redirect !== '/exception/404'" :to="{ path: '/zone/' + record.zoneid }">{{ text }}</router-link>
|
||||
<router-link v-else-if="$router.resolve('/zones/' + record.zoneid).matched[0].redirect !== '/exception/404'" :to="{ path: '/zones/' + record.zoneid }">{{ text }}</router-link>
|
||||
<span v-else>{{ text }}</span>
|
||||
</template>
|
||||
<template v-if="column.key === 'rolename'">
|
||||
|
|
@ -446,6 +471,7 @@ import { api } from '@/api'
|
|||
import OsLogo from '@/components/widgets/OsLogo'
|
||||
import Status from '@/components/widgets/Status'
|
||||
import QuickView from '@/components/view/QuickView'
|
||||
import CopyLabel from '@/components/widgets/CopyLabel'
|
||||
import TooltipButton from '@/components/widgets/TooltipButton'
|
||||
import ResourceIcon from '@/components/view/ResourceIcon'
|
||||
import ResourceLabel from '@/components/widgets/ResourceLabel'
|
||||
|
|
@ -459,6 +485,7 @@ export default {
|
|||
OsLogo,
|
||||
Status,
|
||||
QuickView,
|
||||
CopyLabel,
|
||||
TooltipButton,
|
||||
ResourceIcon,
|
||||
ResourceLabel
|
||||
|
|
|
|||
|
|
@ -0,0 +1,51 @@
|
|||
// 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.
|
||||
|
||||
<template>
|
||||
<span @click="$message.success($t('label.copied.clipboard') + ': ' + label)">
|
||||
<a-tooltip :title="tooltip ? tooltip : $t('label.copy')" :placement="tooltipPlacement">
|
||||
<a href="javascript:;" v-clipboard:copy="label">{{ label }}</a>
|
||||
</a-tooltip>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: 'CopyLabel',
|
||||
props: {
|
||||
label: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
tooltip: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
tooltipPlacement: {
|
||||
type: String,
|
||||
default: 'top'
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.tooltip-icon {
|
||||
color: rgba(0,0,0,.45);
|
||||
}
|
||||
</style>
|
||||
|
|
@ -41,11 +41,11 @@ export default {
|
|||
component: shallowRef(defineAsyncComponent(() => import('@/components/view/DetailsTab.vue')))
|
||||
},
|
||||
{
|
||||
name: 'resources',
|
||||
name: 'limits',
|
||||
component: shallowRef(defineAsyncComponent(() => import('@/components/view/ResourceCountUsage.vue')))
|
||||
},
|
||||
{
|
||||
name: 'limits',
|
||||
name: 'limits.configure',
|
||||
show: (record, route, user) => { return ['Admin', 'DomainAdmin'].includes(user.roletype) },
|
||||
component: shallowRef(defineAsyncComponent(() => import('@/components/view/ResourceLimitTab.vue')))
|
||||
},
|
||||
|
|
|
|||
|
|
@ -46,8 +46,8 @@ export default {
|
|||
return filters
|
||||
},
|
||||
columns: () => {
|
||||
const fields = ['name', 'displayname', 'state', 'ipaddress']
|
||||
const metricsFields = ['cpunumber', 'cpuused', 'cputotal',
|
||||
const fields = ['name', 'state', 'ipaddress']
|
||||
const metricsFields = ['cpunumber', 'cputotal', 'cpuused', 'memorytotal',
|
||||
{
|
||||
memoryused: (record) => {
|
||||
if (record.memoryintfreekbs <= 0 || record.memorykbs <= 0) {
|
||||
|
|
@ -56,7 +56,7 @@ export default {
|
|||
return parseFloat(100.0 * (record.memorykbs - record.memoryintfreekbs) / record.memorykbs).toFixed(2) + '%'
|
||||
}
|
||||
},
|
||||
'memorytotal', 'networkread', 'networkwrite', 'diskread', 'diskwrite', 'diskiopstotal']
|
||||
'networkread', 'networkwrite', 'diskread', 'diskwrite', 'diskiopstotal']
|
||||
|
||||
if (store.getters.metrics) {
|
||||
fields.push(...metricsFields)
|
||||
|
|
@ -66,18 +66,17 @@ export default {
|
|||
fields.splice(2, 0, 'instancename')
|
||||
fields.push('account')
|
||||
fields.push('hostname')
|
||||
fields.push('zonename')
|
||||
} else if (store.getters.userInfo.roletype === 'DomainAdmin') {
|
||||
fields.push('account')
|
||||
fields.push('zonename')
|
||||
} else {
|
||||
fields.push('zonename')
|
||||
fields.push('serviceofferingname')
|
||||
}
|
||||
fields.push('zonename')
|
||||
return fields
|
||||
},
|
||||
searchFilters: ['name', 'zoneid', 'domainid', 'account', 'groupid', 'tags'],
|
||||
details: () => {
|
||||
var fields = ['displayname', 'name', 'id', 'state', 'ipaddress', 'ip6address', 'templatename', 'ostypename',
|
||||
var fields = ['name', 'displayname', 'id', 'state', 'ipaddress', 'ip6address', 'templatename', 'ostypename',
|
||||
'serviceofferingname', 'isdynamicallyscalable', 'haenable', 'hypervisor', 'boottype', 'bootmode', 'account',
|
||||
'domain', 'zonename', 'userdataid', 'userdataname', 'userdataparams', 'userdatadetails', 'userdatapolicy', 'hostcontrolstate']
|
||||
const listZoneHaveSGEnabled = store.getters.zones.filter(zone => zone.securitygroupsenabled === true)
|
||||
|
|
@ -455,7 +454,7 @@ export default {
|
|||
docHelp: 'plugins/cloudstack-kubernetes-service.html',
|
||||
permission: ['listKubernetesClusters'],
|
||||
columns: (store) => {
|
||||
var fields = ['name', 'state', 'clustertype', 'size', 'cpunumber', 'memory']
|
||||
var fields = ['name', 'state', 'clustertype', 'size', 'cpunumber', 'memory', 'kubernetesversionname']
|
||||
if (['Admin', 'DomainAdmin'].includes(store.userInfo.roletype)) {
|
||||
fields.push('account')
|
||||
}
|
||||
|
|
@ -556,7 +555,7 @@ export default {
|
|||
docHelp: 'adminguide/autoscale_without_netscaler.html',
|
||||
resourceType: 'AutoScaleVmGroup',
|
||||
permission: ['listAutoScaleVmGroups'],
|
||||
columns: ['name', 'account', 'associatednetworkname', 'publicip', 'publicport', 'privateport', 'minmembers', 'maxmembers', 'availablevirtualmachinecount', 'state'],
|
||||
columns: ['name', 'state', 'associatednetworkname', 'publicip', 'publicport', 'privateport', 'minmembers', 'maxmembers', 'availablevirtualmachinecount', 'account'],
|
||||
details: ['name', 'id', 'account', 'domain', 'associatednetworkname', 'associatednetworkid', 'lbruleid', 'lbprovider', 'publicip', 'publicipid', 'publicport', 'privateport', 'minmembers', 'maxmembers', 'availablevirtualmachinecount', 'interval', 'state', 'created'],
|
||||
related: [{
|
||||
name: 'vm',
|
||||
|
|
@ -660,7 +659,7 @@ export default {
|
|||
docHelp: 'adminguide/virtual_machines.html#changing-the-vm-name-os-or-group',
|
||||
resourceType: 'VMInstanceGroup',
|
||||
permission: ['listInstanceGroups'],
|
||||
columns: ['name', 'account'],
|
||||
columns: ['name', 'account', 'domain'],
|
||||
details: ['name', 'id', 'account', 'domain', 'created'],
|
||||
related: [{
|
||||
name: 'vm',
|
||||
|
|
@ -714,6 +713,7 @@ export default {
|
|||
var fields = ['name', 'fingerprint']
|
||||
if (['Admin', 'DomainAdmin'].includes(store.getters.userInfo.roletype)) {
|
||||
fields.push('account')
|
||||
fields.push('domain')
|
||||
}
|
||||
return fields
|
||||
},
|
||||
|
|
@ -791,6 +791,7 @@ export default {
|
|||
var fields = ['name', 'id']
|
||||
if (['Admin', 'DomainAdmin'].includes(store.getters.userInfo.roletype)) {
|
||||
fields.push('account')
|
||||
fields.push('domain')
|
||||
}
|
||||
return fields
|
||||
},
|
||||
|
|
@ -862,6 +863,7 @@ export default {
|
|||
var fields = ['name', 'type', 'description']
|
||||
if (['Admin', 'DomainAdmin'].includes(store.getters.userInfo.roletype)) {
|
||||
fields.push('account')
|
||||
fields.push('domain')
|
||||
}
|
||||
return fields
|
||||
},
|
||||
|
|
|
|||
|
|
@ -44,12 +44,12 @@ export default {
|
|||
component: shallowRef(defineAsyncComponent(() => import('@/components/view/DetailsTab.vue')))
|
||||
},
|
||||
{
|
||||
name: 'resources',
|
||||
name: 'limits',
|
||||
show: (record, route, user) => { return ['Admin', 'DomainAdmin'].includes(user.roletype) },
|
||||
component: shallowRef(defineAsyncComponent(() => import('@/components/view/ResourceCountUsage.vue')))
|
||||
},
|
||||
{
|
||||
name: 'limits',
|
||||
name: 'limits.configure',
|
||||
show: (record, route, user) => { return ['Admin'].includes(user.roletype) || (['DomainAdmin'].includes(user.roletype) && record.id !== user.domainid) },
|
||||
component: shallowRef(defineAsyncComponent(() => import('@/components/view/ResourceLimitTab.vue')))
|
||||
},
|
||||
|
|
|
|||
|
|
@ -35,8 +35,17 @@ export default {
|
|||
resourceType: 'Template',
|
||||
filters: ['self', 'shared', 'featured', 'community'],
|
||||
columns: () => {
|
||||
var fields = ['name', 'hypervisor', 'ostypename']
|
||||
var fields = ['name',
|
||||
{
|
||||
state: (record) => {
|
||||
if (record.isready) {
|
||||
return 'Ready'
|
||||
}
|
||||
return 'Not Ready'
|
||||
}
|
||||
}, 'ostypename', 'hypervisor']
|
||||
if (['Admin', 'DomainAdmin'].includes(store.getters.userInfo.roletype)) {
|
||||
fields.push('size')
|
||||
fields.push('account')
|
||||
}
|
||||
if (['Admin'].includes(store.getters.userInfo.roletype)) {
|
||||
|
|
@ -45,8 +54,8 @@ export default {
|
|||
return fields
|
||||
},
|
||||
details: () => {
|
||||
var fields = ['name', 'id', 'displaytext', 'checksum', 'hypervisor', 'format', 'ostypename', 'size', 'isready', 'passwordenabled',
|
||||
'directdownload', 'deployasis', 'ispublic', 'isfeatured', 'isextractable', 'isdynamicallyscalable', 'crosszones', 'type',
|
||||
var fields = ['name', 'id', 'displaytext', 'checksum', 'hypervisor', 'format', 'ostypename', 'size', 'physicalsize', 'isready', 'passwordenabled',
|
||||
'crossZones', 'directdownload', 'deployasis', 'ispublic', 'isfeatured', 'isextractable', 'isdynamicallyscalable', 'crosszones', 'type',
|
||||
'account', 'domain', 'created', 'userdatadetails', 'userdatapolicy']
|
||||
if (['Admin'].includes(store.getters.userInfo.roletype)) {
|
||||
fields.push('templatetype', 'url')
|
||||
|
|
@ -187,8 +196,17 @@ export default {
|
|||
resourceType: 'ISO',
|
||||
filters: ['self', 'shared', 'featured', 'community'],
|
||||
columns: () => {
|
||||
var fields = ['name', 'ostypename']
|
||||
var fields = ['name',
|
||||
{
|
||||
state: (record) => {
|
||||
if (record.isready) {
|
||||
return 'Ready'
|
||||
}
|
||||
return 'Not Ready'
|
||||
}
|
||||
}, 'ostypename']
|
||||
if (['Admin', 'DomainAdmin'].includes(store.getters.userInfo.roletype)) {
|
||||
fields.push('size')
|
||||
fields.push('account')
|
||||
}
|
||||
if (['Admin'].includes(store.getters.userInfo.roletype)) {
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ export default {
|
|||
permission: ['listNetworks'],
|
||||
resourceType: 'Network',
|
||||
columns: () => {
|
||||
var fields = ['name', 'state', 'type', 'vpcname', 'cidr', 'ip6cidr', 'broadcasturi', 'domain', 'account', 'zonename']
|
||||
var fields = ['name', 'state', 'type', 'vpcname', 'cidr', 'ip6cidr', 'broadcasturi', 'account', 'domain', 'zonename']
|
||||
if (!isAdmin()) {
|
||||
fields = fields.filter(function (e) { return e !== 'broadcasturi' })
|
||||
}
|
||||
|
|
@ -193,7 +193,7 @@ export default {
|
|||
docHelp: 'adminguide/networking_and_traffic.html#configuring-a-virtual-private-cloud',
|
||||
permission: ['listVPCs'],
|
||||
resourceType: 'Vpc',
|
||||
columns: ['name', 'state', 'displaytext', 'cidr', 'account', 'zonename'],
|
||||
columns: ['name', 'state', 'displaytext', 'cidr', 'account', 'domain', 'zonename'],
|
||||
details: ['name', 'id', 'displaytext', 'cidr', 'networkdomain', 'ip6routes', 'ispersistent', 'redundantvpcrouter', 'restartrequired', 'zonename', 'account', 'domain', 'dns1', 'dns2', 'ip6dns1', 'ip6dns2', 'publicmtu'],
|
||||
searchFilters: ['name', 'zoneid', 'domainid', 'account', 'tags'],
|
||||
related: [{
|
||||
|
|
@ -323,8 +323,8 @@ export default {
|
|||
docHelp: 'adminguide/networking_and_traffic.html#reserving-public-ip-addresses-and-vlans-for-accounts',
|
||||
permission: ['listPublicIpAddresses'],
|
||||
resourceType: 'PublicIpAddress',
|
||||
columns: ['ipaddress', 'state', 'associatednetworkname', 'vpcname', 'virtualmachinename', 'allocated', 'account', 'zonename'],
|
||||
details: ['ipaddress', 'id', 'associatednetworkname', 'virtualmachinename', 'networkid', 'issourcenat', 'isstaticnat', 'virtualmachinename', 'vmipaddress', 'vlan', 'allocated', 'account', 'zonename'],
|
||||
columns: ['ipaddress', 'state', 'associatednetworkname', 'vpcname', 'virtualmachinename', 'allocated', 'account', 'domain', 'zonename'],
|
||||
details: ['ipaddress', 'id', 'associatednetworkname', 'virtualmachinename', 'networkid', 'issourcenat', 'isstaticnat', 'virtualmachinename', 'vmipaddress', 'vlan', 'allocated', 'account', 'domain', 'zonename'],
|
||||
filters: ['allocated', 'reserved', 'free'],
|
||||
component: shallowRef(() => import('@/views/network/PublicIpResource.vue')),
|
||||
tabs: [{
|
||||
|
|
@ -427,7 +427,7 @@ export default {
|
|||
icon: 'gateway-outlined',
|
||||
hidden: true,
|
||||
permission: ['listPrivateGateways'],
|
||||
columns: ['ipaddress', 'state', 'gateway', 'netmask', 'account'],
|
||||
columns: ['ipaddress', 'state', 'gateway', 'netmask', 'account', 'domain'],
|
||||
details: ['ipaddress', 'gateway', 'netmask', 'vlan', 'sourcenatsupported', 'aclname', 'account', 'domain', 'zone', 'associatednetwork', 'associatednetworkid'],
|
||||
tabs: [{
|
||||
name: 'details',
|
||||
|
|
@ -713,7 +713,7 @@ export default {
|
|||
title: 'label.vpncustomergatewayid',
|
||||
icon: 'lock-outlined',
|
||||
permission: ['listVpnCustomerGateways'],
|
||||
columns: ['name', 'gateway', 'cidrlist', 'ipsecpsk', 'account'],
|
||||
columns: ['name', 'gateway', 'cidrlist', 'ipsecpsk', 'account', 'domain'],
|
||||
details: ['name', 'id', 'gateway', 'cidrlist', 'ipsecpsk', 'ikepolicy', 'ikelifetime', 'ikeversion', 'esppolicy', 'esplifetime', 'dpd', 'splitconnections', 'forceencap', 'account', 'domain'],
|
||||
searchFilters: ['keyword', 'domainid', 'account'],
|
||||
resourceType: 'VPNCustomerGateway',
|
||||
|
|
@ -913,8 +913,8 @@ export default {
|
|||
permission: ['listGuestVlans'],
|
||||
resourceType: 'GuestVlan',
|
||||
filters: ['allocatedonly', 'all'],
|
||||
columns: ['vlan', 'zonename', 'physicalnetworkname', 'allocationstate', 'taken', 'domain', 'account', 'project'],
|
||||
details: ['vlan', 'zonename', 'physicalnetworkname', 'allocationstate', 'taken', 'domain', 'account', 'project', 'isdedicated'],
|
||||
columns: ['vlan', 'allocationstate', 'physicalnetworkname', 'taken', 'account', 'project', 'domain', 'zonename'],
|
||||
details: ['vlan', 'allocationstate', 'physicalnetworkname', 'taken', 'account', 'project', 'domain', 'isdedicated', 'zonename'],
|
||||
searchFilters: ['zoneid'],
|
||||
tabs: [{
|
||||
name: 'details',
|
||||
|
|
|
|||
|
|
@ -47,11 +47,11 @@ export default {
|
|||
}
|
||||
},
|
||||
{
|
||||
name: 'resources',
|
||||
name: 'limits',
|
||||
component: shallowRef(defineAsyncComponent(() => import('@/components/view/ResourceCountUsage.vue')))
|
||||
},
|
||||
{
|
||||
name: 'limits',
|
||||
name: 'limits.configure',
|
||||
show: (record, route, user) => { return ['Admin', 'DomainAdmin'].includes(user.roletype) },
|
||||
component: shallowRef(defineAsyncComponent(() => import('@/components/view/ResourceLimitTab.vue')))
|
||||
},
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ export default {
|
|||
}
|
||||
},
|
||||
columns: () => {
|
||||
const fields = ['name', 'state', 'type', 'vmname', 'sizegb']
|
||||
const fields = ['name', 'state', 'sizegb', 'type', 'vmname']
|
||||
const metricsFields = ['diskkbsread', 'diskkbswrite', 'diskiopstotal']
|
||||
|
||||
if (store.getters.userInfo.roletype === 'Admin') {
|
||||
|
|
@ -308,14 +308,15 @@ export default {
|
|||
permission: ['listSnapshots'],
|
||||
resourceType: 'Snapshot',
|
||||
columns: () => {
|
||||
var fields = ['name', 'state', 'volumename', 'intervaltype', 'created']
|
||||
var fields = ['name', 'state', 'volumename', 'intervaltype', 'physicalsize', 'created']
|
||||
if (['Admin', 'DomainAdmin'].includes(store.getters.userInfo.roletype)) {
|
||||
fields.push('domain')
|
||||
fields.push('account')
|
||||
fields.push('domain')
|
||||
}
|
||||
fields.push('zonename')
|
||||
return fields
|
||||
},
|
||||
details: ['name', 'id', 'volumename', 'intervaltype', 'account', 'domain', 'created'],
|
||||
details: ['name', 'id', 'volumename', 'volumetype', 'snapshottype', 'intervaltype', 'physicalsize', 'virtualsize', 'account', 'domain', 'created'],
|
||||
tabs: [
|
||||
{
|
||||
name: 'details',
|
||||
|
|
@ -381,8 +382,8 @@ export default {
|
|||
columns: () => {
|
||||
const fields = ['displayname', 'state', 'name', 'type', 'current', 'parentName', 'created']
|
||||
if (['Admin', 'DomainAdmin'].includes(store.getters.userInfo.roletype)) {
|
||||
fields.push('domain')
|
||||
fields.push('account')
|
||||
fields.push('domain')
|
||||
}
|
||||
return fields
|
||||
},
|
||||
|
|
@ -447,7 +448,7 @@ export default {
|
|||
title: 'label.backup',
|
||||
icon: 'cloud-upload-outlined',
|
||||
permission: ['listBackups'],
|
||||
columns: [{ name: (record) => { return record.virtualmachinename } }, 'virtualmachinename', 'status', 'type', 'created', 'account', 'zone'],
|
||||
columns: [{ name: (record) => { return record.virtualmachinename } }, 'status', 'virtualmachinename', 'type', 'created', 'account', 'domain', 'zone'],
|
||||
details: ['virtualmachinename', 'id', 'type', 'externalid', 'size', 'virtualsize', 'volumes', 'backupofferingname', 'zone', 'account', 'domain', 'created'],
|
||||
actions: [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -35,24 +35,27 @@
|
|||
<span>{{ $t('message.select.a.zone') }}</span><br/>
|
||||
<a-form-item :label="$t('label.zoneid')" name="zoneid" ref="zoneid">
|
||||
<div v-if="zones.length <= 8">
|
||||
<a-row type="flex" :gutter="5" justify="start">
|
||||
<a-row type="flex" :gutter="[16,18]" justify="start">
|
||||
<div v-for="(zoneItem, idx) in zones" :key="idx">
|
||||
<a-radio-group
|
||||
:key="idx"
|
||||
:size="large"
|
||||
v-model:value="form.zoneid"
|
||||
@change="onSelectZoneId(zoneItem.id)">
|
||||
<a-col :span="8">
|
||||
<a-card style="width:200px;" :hoverable="false">
|
||||
<a-radio :value="zoneItem.id" />
|
||||
<div :style="{fontSize: '36px', marginLeft: '60px', marginTop: '-30px', marginBottom: '10px'}">
|
||||
<resource-icon
|
||||
v-if="zoneItem && zoneItem.icon && zoneItem.icon.base64image"
|
||||
:image="zoneItem.icon.base64image"
|
||||
size="36" />
|
||||
<global-outlined v-else />
|
||||
</div>
|
||||
<a-card-meta title="" :description="zoneItem.name" style="text-align:center; paddingTop: 10px;" />
|
||||
</a-card>
|
||||
<a-col :span="6">
|
||||
<a-radio-button
|
||||
:value="zoneItem.id"
|
||||
style="border-width: 2px"
|
||||
class="zone-radio-button">
|
||||
<span>
|
||||
<resource-icon
|
||||
v-if="zoneItem && zoneItem.icon && zoneItem.icon.base64image"
|
||||
:image="zoneItem.icon.base64image"
|
||||
size="2x" />
|
||||
<global-outlined size="2x" v-else />
|
||||
{{ zoneItem.name }}
|
||||
</span>
|
||||
</a-radio-button>
|
||||
</a-col>
|
||||
</a-radio-group>
|
||||
</div>
|
||||
|
|
@ -2942,6 +2945,15 @@ export default {
|
|||
margin: 0 0 1.2rem;
|
||||
}
|
||||
|
||||
.zone-radio-button {
|
||||
width:100%;
|
||||
min-width: 345px;
|
||||
height: 60px;
|
||||
display: flex;
|
||||
padding-left: 20px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.vm-info-card {
|
||||
.ant-card-body {
|
||||
min-height: 250px;
|
||||
|
|
|
|||
|
|
@ -35,24 +35,27 @@
|
|||
<span>{{ $t('message.select.a.zone') }}</span><br/>
|
||||
<a-form-item :label="$t('label.zoneid')" name="zoneid" ref="zoneid">
|
||||
<div v-if="zones.length <= 8">
|
||||
<a-row type="flex" :gutter="5" justify="start">
|
||||
<a-row type="flex" :gutter="[16, 18]" justify="start">
|
||||
<div v-for="(zoneItem, idx) in zones" :key="idx">
|
||||
<a-radio-group
|
||||
:key="idx"
|
||||
:size="large"
|
||||
v-model:value="form.zoneid"
|
||||
@change="onSelectZoneId(zoneItem.id)">
|
||||
<a-col :span="8">
|
||||
<a-card style="width:200px;" :hoverable="false">
|
||||
<a-radio :value="zoneItem.id" />
|
||||
<div :style="{fontSize: '36px', marginLeft: '60px', marginTop: '-30px', marginBottom: '10px'}">
|
||||
<resource-icon
|
||||
v-if="zoneItem && zoneItem.icon && zoneItem.icon.base64image"
|
||||
:image="zoneItem.icon.base64image"
|
||||
size="36" />
|
||||
<global-outlined v-else/>
|
||||
</div>
|
||||
<a-card-meta title="" :description="zoneItem.name" style="text-align:center; paddingTop: 10px;" />
|
||||
</a-card>
|
||||
<a-col :span="6">
|
||||
<a-radio-button
|
||||
:value="zoneItem.id"
|
||||
style="border-width: 2px"
|
||||
class="zone-radio-button">
|
||||
<span>
|
||||
<resource-icon
|
||||
v-if="zoneItem && zoneItem.icon && zoneItem.icon.base64image"
|
||||
:image="zoneItem.icon.base64image"
|
||||
size="2x" />
|
||||
<global-outlined size="2x" v-else />
|
||||
{{ zoneItem.name }}
|
||||
</span>
|
||||
</a-radio-button>
|
||||
</a-col>
|
||||
</a-radio-group>
|
||||
</div>
|
||||
|
|
@ -72,7 +75,7 @@
|
|||
>
|
||||
<a-select-option v-for="zone1 in zones" :key="zone1.id" :label="zone1.name">
|
||||
<span>
|
||||
<resource-icon v-if="zone1.icon && zone1.icon.base64image" :image="zone1.icon.base64image" size="1x" style="margin-right: 5px"/>
|
||||
<resource-icon v-if="zone1.icon && zone1.icon.base64image" :image="zone1.icon.base64image" size="2x" style="margin-right: 5px"/>
|
||||
<global-outlined v-else style="margin-right: 5px" />
|
||||
{{ zone1.name }}
|
||||
</span>
|
||||
|
|
@ -2721,6 +2724,15 @@ export default {
|
|||
margin: 0 0 1.2rem;
|
||||
}
|
||||
|
||||
.zone-radio-button {
|
||||
width:100%;
|
||||
min-width: 345px;
|
||||
height: 60px;
|
||||
display: flex;
|
||||
padding-left: 20px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.vm-info-card {
|
||||
.ant-card-body {
|
||||
min-height: 250px;
|
||||
|
|
|
|||
|
|
@ -34,13 +34,21 @@
|
|||
<barcode-outlined /> {{ vm.isoid }}
|
||||
</a-tab-pane>
|
||||
<a-tab-pane :tab="$t('label.volumes')" key="volumes">
|
||||
<volumes-tab :resource="vm" :items="volumes" :loading="loading" />
|
||||
<a-button
|
||||
type="primary"
|
||||
style="width: 100%; margin-bottom: 10px"
|
||||
@click="showAddVolModal"
|
||||
:loading="loading"
|
||||
:disabled="!('createVolume' in $store.getters.apis)">
|
||||
<template #icon><plus-outlined /></template> {{ $t('label.action.create.volume.add') }}
|
||||
</a-button>
|
||||
<volumes-tab :resource="vm" :loading="loading" />
|
||||
</a-tab-pane>
|
||||
<a-tab-pane :tab="$t('label.nics')" key="nics" v-if="'listNics' in $store.getters.apis">
|
||||
<a-button
|
||||
type="dashed"
|
||||
type="primary"
|
||||
style="width: 100%; margin-bottom: 10px"
|
||||
@click="showAddModal"
|
||||
@click="showAddNicModal"
|
||||
:loading="loadingNic"
|
||||
:disabled="!('addNicToVirtualMachine' in $store.getters.apis)">
|
||||
<template #icon><plus-outlined /></template> {{ $t('label.network.addvm') }}
|
||||
|
|
@ -135,6 +143,16 @@
|
|||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
|
||||
<a-modal
|
||||
:visible="showAddVolumeModal"
|
||||
:title="$t('label.action.create.volume.add')"
|
||||
:maskClosable="false"
|
||||
:closable="true"
|
||||
:footer="null"
|
||||
@cancel="closeModals">
|
||||
<CreateVolume :resource="resource" @close-action="closeModals" />
|
||||
</a-modal>
|
||||
|
||||
<a-modal
|
||||
:visible="showAddNetworkModal"
|
||||
:title="$t('label.network.addvm')"
|
||||
|
|
@ -294,6 +312,7 @@ import DetailsTab from '@/components/view/DetailsTab'
|
|||
import StatsTab from '@/components/view/StatsTab'
|
||||
import EventsTab from '@/components/view/EventsTab'
|
||||
import DetailSettings from '@/components/view/DetailSettings'
|
||||
import CreateVolume from '@/views/storage/CreateVolume'
|
||||
import NicsTable from '@/views/network/NicsTable'
|
||||
import InstanceSchedules from '@/views/compute/InstanceSchedules.vue'
|
||||
import ListResourceTable from '@/components/view/ListResourceTable'
|
||||
|
|
@ -310,6 +329,7 @@ export default {
|
|||
StatsTab,
|
||||
EventsTab,
|
||||
DetailSettings,
|
||||
CreateVolume,
|
||||
NicsTable,
|
||||
InstanceSchedules,
|
||||
ListResourceTable,
|
||||
|
|
@ -335,9 +355,11 @@ export default {
|
|||
vm: {},
|
||||
totalStorage: 0,
|
||||
currentTab: 'details',
|
||||
showAddVolumeModal: false,
|
||||
showAddNetworkModal: false,
|
||||
showUpdateIpModal: false,
|
||||
showSecondaryIpModal: false,
|
||||
diskOfferings: [],
|
||||
addNetworkData: {
|
||||
allNetworks: [],
|
||||
network: '',
|
||||
|
|
@ -415,6 +437,14 @@ export default {
|
|||
}
|
||||
})
|
||||
},
|
||||
listDiskOfferings () {
|
||||
api('listDiskOfferings', {
|
||||
listAll: 'true',
|
||||
zoneid: this.vm.zoneid
|
||||
}).then(response => {
|
||||
this.diskOfferings = response.listdiskofferingsresponse.diskoffering
|
||||
})
|
||||
},
|
||||
listNetworks () {
|
||||
api('listNetworks', {
|
||||
listAll: 'true',
|
||||
|
|
@ -463,11 +493,16 @@ export default {
|
|||
this.listIps.loading = false
|
||||
})
|
||||
},
|
||||
showAddModal () {
|
||||
showAddVolModal () {
|
||||
this.showAddVolumeModal = true
|
||||
this.listDiskOfferings()
|
||||
},
|
||||
showAddNicModal () {
|
||||
this.showAddNetworkModal = true
|
||||
this.listNetworks()
|
||||
},
|
||||
closeModals () {
|
||||
this.showAddVolumeModal = false
|
||||
this.showAddNetworkModal = false
|
||||
this.showUpdateIpModal = false
|
||||
this.showSecondaryIpModal = false
|
||||
|
|
|
|||
|
|
@ -37,13 +37,15 @@
|
|||
v-if="item.icon && item.icon.base64image"
|
||||
class="radio-group__os-logo"
|
||||
:image="item.icon.base64image"
|
||||
size="1x" />
|
||||
size="2x" />
|
||||
<os-logo
|
||||
v-else
|
||||
class="radio-group__os-logo"
|
||||
size="2x"
|
||||
:osId="item.ostypeid"
|
||||
:os-name="item.osName" />
|
||||
{{ item.displaytext }}
|
||||
|
||||
{{ item.displaytext }}
|
||||
</a-radio>
|
||||
</a-radio-group>
|
||||
</a-list-item>
|
||||
|
|
@ -156,15 +158,11 @@ export default {
|
|||
margin: 0.5rem 0;
|
||||
|
||||
:deep(.ant-radio) {
|
||||
margin-right: 20px;
|
||||
margin-right: 0px;
|
||||
}
|
||||
|
||||
&__os-logo {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
margin-top: 2px;
|
||||
margin-left: 23px;
|
||||
margin-top: -4px;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
}" >
|
||||
<a-select-option v-for="(zone, index) in zones" :key="index" :label="zone.name">
|
||||
<span>
|
||||
<resource-icon v-if="zone.icon && zone.icon.base64image" :image="zone.icon.base64image" size="1x" style="margin-right: 5px"/>
|
||||
<resource-icon v-if="zone.icon && zone.icon.base64image" :image="zone.icon.base64image" size="2x" style="margin-right: 5px"/>
|
||||
<global-outlined v-else style="margin-right: 5px" />
|
||||
{{ zone.name }}
|
||||
</span>
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@
|
|||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'zonename'">
|
||||
<span v-if="fetchZoneIcon(record.zoneid)">
|
||||
<resource-icon :image="zoneIcon" size="1x" style="margin-right: 5px"/>
|
||||
<resource-icon :image="zoneIcon" size="2x" style="margin-right: 5px"/>
|
||||
</span>
|
||||
<global-outlined v-else style="margin-right: 5px" />
|
||||
<span> {{ record.zonename }} </span>
|
||||
|
|
@ -126,7 +126,7 @@
|
|||
<a-select-option v-for="zone in zones" :key="zone.id" :label="zone.name">
|
||||
<div>
|
||||
<span v-if="zone.icon && zone.icon.base64image">
|
||||
<resource-icon :image="zone.icon.base64image" size="1x" style="margin-right: 5px"/>
|
||||
<resource-icon :image="zone.icon.base64image" size="2x" style="margin-right: 5px"/>
|
||||
</span>
|
||||
<global-outlined v-else style="margin-right: 5px" />
|
||||
{{ zone.name }}
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@
|
|||
v-model:value="form.name"
|
||||
:placeholder="apiParams.name.description" />
|
||||
</a-form-item>
|
||||
<a-form-item ref="zoneid" name="zoneid" v-if="!createVolumeFromSnapshot">
|
||||
<a-form-item ref="zoneid" name="zoneid" v-if="!createVolumeFromVM && !createVolumeFromSnapshot">
|
||||
<template #label>
|
||||
<tooltip-label :title="$t('label.zoneid')" :tooltip="apiParams.zoneid.description"/>
|
||||
</template>
|
||||
|
|
@ -151,6 +151,9 @@ export default {
|
|||
}
|
||||
},
|
||||
computed: {
|
||||
createVolumeFromVM () {
|
||||
return this.$route.path.startsWith('/vm/')
|
||||
},
|
||||
createVolumeFromSnapshot () {
|
||||
return this.$route.path.startsWith('/snapshot')
|
||||
}
|
||||
|
|
@ -193,7 +196,11 @@ export default {
|
|||
},
|
||||
fetchData () {
|
||||
this.loading = true
|
||||
api('listZones', { showicon: true }).then(json => {
|
||||
const params = { showicon: true }
|
||||
if (this.createVolumeFromVM) {
|
||||
params.id = this.resource.zoneid
|
||||
}
|
||||
api('listZones', params).then(json => {
|
||||
this.zones = json.listzonesresponse.zone || []
|
||||
this.form.zoneid = this.zones[0].id || ''
|
||||
this.fetchDiskOfferings(this.form.zoneid)
|
||||
|
|
@ -222,6 +229,12 @@ export default {
|
|||
this.formRef.value.validate().then(() => {
|
||||
const formRaw = toRaw(this.form)
|
||||
const values = this.handleRemoveFields(formRaw)
|
||||
if (this.createVolumeFromVM) {
|
||||
values.account = this.resource.account
|
||||
values.domainid = this.resource.domainid
|
||||
values.virtualmachineid = this.resource.id
|
||||
values.zoneid = this.resource.zoneid
|
||||
}
|
||||
if (this.createVolumeFromSnapshot) {
|
||||
values.snapshotid = this.resource.id
|
||||
}
|
||||
|
|
@ -232,6 +245,25 @@ export default {
|
|||
title: this.$t('message.success.create.volume'),
|
||||
description: values.name,
|
||||
successMessage: this.$t('message.success.create.volume'),
|
||||
successMethod: (result) => {
|
||||
this.closeModal()
|
||||
if (this.createVolumeFromVM) {
|
||||
const params = {}
|
||||
params.id = result.jobresult.volume.id
|
||||
params.virtualmachineid = this.resource.id
|
||||
api('attachVolume', params).then(response => {
|
||||
this.$pollJob({
|
||||
jobId: response.attachvolumeresponse.jobid,
|
||||
title: this.$t('message.success.attach.volume'),
|
||||
description: values.name,
|
||||
successMessage: this.$t('message.attach.volume.success'),
|
||||
errorMessage: this.$t('message.attach.volume.failed'),
|
||||
loadingMessage: this.$t('message.attach.volume.progress'),
|
||||
catchMessage: this.$t('error.fetching.async.job.result')
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
errorMessage: this.$t('message.create.volume.failed'),
|
||||
loadingMessage: this.$t('message.create.volume.processing'),
|
||||
catchMessage: this.$t('error.fetching.async.job.result')
|
||||
|
|
@ -263,7 +295,8 @@ export default {
|
|||
width: 80vw;
|
||||
|
||||
@media (min-width: 500px) {
|
||||
width: 400px;
|
||||
min-width: 400px;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
Loading…
Reference in New Issue