diff --git a/api/src/main/java/com/cloud/storage/ScopeType.java b/api/src/main/java/com/cloud/storage/ScopeType.java index e20f525c5f8..a944ebae10c 100644 --- a/api/src/main/java/com/cloud/storage/ScopeType.java +++ b/api/src/main/java/com/cloud/storage/ScopeType.java @@ -18,6 +18,21 @@ */ package com.cloud.storage; +import com.cloud.exception.InvalidParameterValueException; +import org.apache.commons.lang3.EnumUtils; + public enum ScopeType { HOST, CLUSTER, ZONE, REGION, GLOBAL; + + public static ScopeType validateAndGetScopeType(String value) { + if (value == null) { + return null; + } else { + ScopeType scopeType = EnumUtils.getEnumIgnoreCase(ScopeType.class, value); + if (scopeType == null) { + throw new InvalidParameterValueException("Invalid scope type: " + value); + } + return scopeType; + } + } } diff --git a/api/src/main/java/com/cloud/storage/StoragePoolStatus.java b/api/src/main/java/com/cloud/storage/StoragePoolStatus.java index 778d3881e3e..3bfd829d2f7 100644 --- a/api/src/main/java/com/cloud/storage/StoragePoolStatus.java +++ b/api/src/main/java/com/cloud/storage/StoragePoolStatus.java @@ -16,6 +16,21 @@ // under the License. package com.cloud.storage; +import com.cloud.exception.InvalidParameterValueException; +import org.apache.commons.lang3.EnumUtils; + public enum StoragePoolStatus { Initial, Initialized, Creating, Attaching, Up, PrepareForMaintenance, ErrorInMaintenance, CancelMaintenance, Maintenance, Disabled, Removed; + + public static StoragePoolStatus validateAndGetStatus(String value) { + if (value == null) { + return null; + } else { + StoragePoolStatus status = EnumUtils.getEnumIgnoreCase(StoragePoolStatus.class, value); + if (status == null) { + throw new InvalidParameterValueException("Invalid status: " + value); + } + return status; + } + } } diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/ListStoragePoolsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/ListStoragePoolsCmd.java index ce1164000fc..209aaac279c 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/ListStoragePoolsCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/ListStoragePoolsCmd.java @@ -66,6 +66,9 @@ public class ListStoragePoolsCmd extends BaseListCmd { @Parameter(name = ApiConstants.SCOPE, type = CommandType.STRING, entityType = StoragePoolResponse.class, description = "the ID of the storage pool") private String scope; + @Parameter(name = ApiConstants.STATUS, type = CommandType.STRING, description = "the status of the storage pool") + private String status; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -94,6 +97,10 @@ public class ListStoragePoolsCmd extends BaseListCmd { return zoneId; } + public String getStatus() { + return status; + } + public Long getId() { return id; } @@ -101,7 +108,7 @@ public class ListStoragePoolsCmd extends BaseListCmd { public void setId(Long id) { this.id = id; } -///////////////////////////////////////////////////// + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// diff --git a/server/src/main/java/com/cloud/api/query/QueryManagerImpl.java b/server/src/main/java/com/cloud/api/query/QueryManagerImpl.java index 6fecd2c3c6d..0968af0e7c0 100644 --- a/server/src/main/java/com/cloud/api/query/QueryManagerImpl.java +++ b/server/src/main/java/com/cloud/api/query/QueryManagerImpl.java @@ -229,6 +229,7 @@ import com.cloud.storage.ScopeType; import com.cloud.storage.Storage; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.TemplateType; +import com.cloud.storage.StoragePoolStatus; import com.cloud.storage.StoragePoolTagVO; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.Volume; @@ -2603,89 +2604,26 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q } private Pair, Integer> searchForStoragePoolsInternal(ListStoragePoolsCmd cmd) { - ScopeType scopeType = null; - if (cmd.getScope() != null) { - try { - scopeType = Enum.valueOf(ScopeType.class, cmd.getScope().toUpperCase()); - } catch (Exception e) { - throw new InvalidParameterValueException("Invalid scope type: " + cmd.getScope()); - } - } + ScopeType scopeType = ScopeType.validateAndGetScopeType(cmd.getScope()); + StoragePoolStatus status = StoragePoolStatus.validateAndGetStatus(cmd.getStatus()); Long zoneId = _accountMgr.checkAccessAndSpecifyAuthority(CallContext.current().getCallingAccount(), cmd.getZoneId()); - Object id = cmd.getId(); - Object name = cmd.getStoragePoolName(); - Object path = cmd.getPath(); - Object pod = cmd.getPodId(); - Object cluster = cmd.getClusterId(); - Object address = cmd.getIpAddress(); - Object keyword = cmd.getKeyword(); + Long id = cmd.getId(); + String name = cmd.getStoragePoolName(); + String path = cmd.getPath(); + Long pod = cmd.getPodId(); + Long cluster = cmd.getClusterId(); + String address = cmd.getIpAddress(); + String keyword = cmd.getKeyword(); Long startIndex = cmd.getStartIndex(); Long pageSize = cmd.getPageSizeVal(); Filter searchFilter = new Filter(StoragePoolJoinVO.class, "id", Boolean.TRUE, startIndex, pageSize); - SearchBuilder sb = _poolJoinDao.createSearchBuilder(); - sb.select(null, Func.DISTINCT, sb.entity().getId()); // select distinct - // ids - sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); - sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ); - sb.and("path", sb.entity().getPath(), SearchCriteria.Op.EQ); - sb.and("dataCenterId", sb.entity().getZoneId(), SearchCriteria.Op.EQ); - sb.and("podId", sb.entity().getPodId(), SearchCriteria.Op.EQ); - sb.and("clusterId", sb.entity().getClusterId(), SearchCriteria.Op.EQ); - sb.and("hostAddress", sb.entity().getHostAddress(), SearchCriteria.Op.EQ); - sb.and("scope", sb.entity().getScope(), SearchCriteria.Op.EQ); - sb.and("parent", sb.entity().getParent(), Op.EQ); + // search & count Pool details by ids + Pair, Integer> uniquePoolPair = _poolJoinDao.searchAndCount(id, name, zoneId, path, pod, + cluster, address, scopeType, status, keyword, searchFilter); - SearchCriteria sc = sb.create(); - - if (keyword != null) { - SearchCriteria ssc = _poolJoinDao.createSearchCriteria(); - ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%"); - ssc.addOr("poolType", SearchCriteria.Op.LIKE, "%" + keyword + "%"); - - sc.addAnd("name", SearchCriteria.Op.SC, ssc); - } - - if (id != null) { - sc.setParameters("id", id); - } - - if (name != null) { - sc.setParameters("name", name); - } - - if (path != null) { - sc.setParameters("path", path); - } - if (zoneId != null) { - sc.setParameters("dataCenterId", zoneId); - } - if (pod != null) { - SearchCriteria ssc = _poolJoinDao.createSearchCriteria(); - ssc.addOr("podId", Op.EQ, pod); - ssc.addOr("podId", Op.NULL); - - sc.addAnd("podId", SearchCriteria.Op.SC, ssc); - } - if (address != null) { - sc.setParameters("hostAddress", address); - } - if (cluster != null) { - SearchCriteria ssc = _poolJoinDao.createSearchCriteria(); - ssc.addOr("clusterId", Op.EQ, cluster); - ssc.addOr("clusterId", Op.NULL); - - sc.addAnd("clusterId", SearchCriteria.Op.SC, ssc); - } - if (scopeType != null) { - sc.setParameters("scope", scopeType.toString()); - } - sc.setParameters("parent", 0); - - // search Pool details by ids - Pair, Integer> uniquePoolPair = _poolJoinDao.searchAndCount(sc, searchFilter); Integer count = uniquePoolPair.second(); if (count.intValue() == 0) { // empty result diff --git a/server/src/main/java/com/cloud/api/query/dao/StoragePoolJoinDao.java b/server/src/main/java/com/cloud/api/query/dao/StoragePoolJoinDao.java index 55c028044f7..87659210ad7 100644 --- a/server/src/main/java/com/cloud/api/query/dao/StoragePoolJoinDao.java +++ b/server/src/main/java/com/cloud/api/query/dao/StoragePoolJoinDao.java @@ -18,6 +18,10 @@ package com.cloud.api.query.dao; import java.util.List; +import com.cloud.storage.ScopeType; +import com.cloud.storage.StoragePoolStatus; +import com.cloud.utils.Pair; +import com.cloud.utils.db.Filter; import org.apache.cloudstack.api.response.StoragePoolResponse; import com.cloud.api.query.vo.StoragePoolJoinVO; @@ -38,4 +42,6 @@ public interface StoragePoolJoinDao extends GenericDao List searchByIds(Long... spIds); + Pair, Integer> searchAndCount(Long storagePoolId, String storagePoolName, Long zoneId, String path, Long podId, Long clusterId, String address, ScopeType scopeType, StoragePoolStatus status, String keyword, Filter searchFilter); + } diff --git a/server/src/main/java/com/cloud/api/query/dao/StoragePoolJoinDaoImpl.java b/server/src/main/java/com/cloud/api/query/dao/StoragePoolJoinDaoImpl.java index 28ba1f63fc6..527cc949ed1 100644 --- a/server/src/main/java/com/cloud/api/query/dao/StoragePoolJoinDaoImpl.java +++ b/server/src/main/java/com/cloud/api/query/dao/StoragePoolJoinDaoImpl.java @@ -20,11 +20,15 @@ import com.cloud.api.ApiDBUtils; import com.cloud.api.query.vo.StoragePoolJoinVO; import com.cloud.capacity.CapacityManager; import com.cloud.storage.DataStoreRole; +import com.cloud.storage.ScopeType; import com.cloud.storage.Storage; import com.cloud.storage.StoragePool; +import com.cloud.storage.StoragePoolStatus; import com.cloud.storage.StorageStats; import com.cloud.user.AccountManager; +import com.cloud.utils.Pair; import com.cloud.utils.StringUtils; +import com.cloud.utils.db.Filter; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; @@ -291,4 +295,75 @@ public class StoragePoolJoinDaoImpl extends GenericDaoBase, Integer> searchAndCount(Long storagePoolId, String storagePoolName, Long zoneId, String path, Long podId, Long clusterId, String address, ScopeType scopeType, StoragePoolStatus status, String keyword, Filter searchFilter) { + SearchCriteria sc = createStoragePoolSearchCriteria(storagePoolId, storagePoolName, zoneId, path, podId, clusterId, address, scopeType, status, keyword); + return searchAndCount(sc, searchFilter); + } + + private SearchCriteria createStoragePoolSearchCriteria(Long storagePoolId, String storagePoolName, Long zoneId, String path, Long podId, Long clusterId, String address, ScopeType scopeType, StoragePoolStatus status, String keyword) { + SearchBuilder sb = createSearchBuilder(); + sb.select(null, SearchCriteria.Func.DISTINCT, sb.entity().getId()); // select distinct + // ids + sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); + sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ); + sb.and("path", sb.entity().getPath(), SearchCriteria.Op.EQ); + sb.and("dataCenterId", sb.entity().getZoneId(), SearchCriteria.Op.EQ); + sb.and("podId", sb.entity().getPodId(), SearchCriteria.Op.EQ); + sb.and("clusterId", sb.entity().getClusterId(), SearchCriteria.Op.EQ); + sb.and("hostAddress", sb.entity().getHostAddress(), SearchCriteria.Op.EQ); + sb.and("scope", sb.entity().getScope(), SearchCriteria.Op.EQ); + sb.and("status", sb.entity().getStatus(), SearchCriteria.Op.EQ); + sb.and("parent", sb.entity().getParent(), SearchCriteria.Op.EQ); + + SearchCriteria sc = sb.create(); + + if (keyword != null) { + SearchCriteria ssc = createSearchCriteria(); + ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%"); + ssc.addOr("poolType", SearchCriteria.Op.LIKE, "%" + keyword + "%"); + + sc.addAnd("name", SearchCriteria.Op.SC, ssc); + } + + if (storagePoolId != null) { + sc.setParameters("id", storagePoolId); + } + + if (storagePoolName != null) { + sc.setParameters("name", storagePoolName); + } + + if (path != null) { + sc.setParameters("path", path); + } + if (zoneId != null) { + sc.setParameters("dataCenterId", zoneId); + } + if (podId != null) { + SearchCriteria ssc = createSearchCriteria(); + ssc.addOr("podId", SearchCriteria.Op.EQ, podId); + ssc.addOr("podId", SearchCriteria.Op.NULL); + + sc.addAnd("podId", SearchCriteria.Op.SC, ssc); + } + if (address != null) { + sc.setParameters("hostAddress", address); + } + if (clusterId != null) { + SearchCriteria ssc = createSearchCriteria(); + ssc.addOr("clusterId", SearchCriteria.Op.EQ, clusterId); + ssc.addOr("clusterId", SearchCriteria.Op.NULL); + + sc.addAnd("clusterId", SearchCriteria.Op.SC, ssc); + } + if (scopeType != null) { + sc.setParameters("scope", scopeType.toString()); + } + if (status != null) { + sc.setParameters("status", status.toString()); + } + sc.setParameters("parent", 0); + return sc; + } } diff --git a/ui/public/locales/en.json b/ui/public/locales/en.json index dd94644c6f8..c026e5bb7f0 100644 --- a/ui/public/locales/en.json +++ b/ui/public/locales/en.json @@ -340,9 +340,9 @@ "label.associatednetworkid": "Associated network ID", "label.associatednetworkname": "Network name", "label.asyncbackup": "Async backup", +"label.attaching": "Attaching", "label.authentication.method": "Authentication Method", "label.authentication.sshkey": "System SSH Key", -"label.automigrate.volume": "Auto migrate volume to another storage pool if required", "label.autoscale": "AutoScale", "label.autoscalevmgroupname": "AutoScale VM Group", "label.author.email": "Author e-mail", @@ -402,6 +402,7 @@ "label.bypassvlanoverlapcheck": "Bypass VLAN id/range overlap", "label.cachemode": "Write-cache type", "label.cancel": "Cancel", +"label.cancelmaintenance": "Cancel maintenance", "label.capacity": "Capacity", "label.capacitybytes": "Capacity bytes", "label.capacityiops": "IOPS total", @@ -545,6 +546,7 @@ "label.create.user": "Create user", "label.create.vpn.connection": "Create VPN connection", "label.created": "Created", +"label.creating": "Creating", "label.creating.iprange": "Creating IP ranges", "label.credit": "Credit", "label.crosszones": "Cross zones", @@ -653,6 +655,7 @@ "label.destnetworkuuid": "Network", "label.destport": "Destination Ports", "label.destroy": "Destroy", +"label.destroyed": "Destroyed", "label.destroy.router": "Destroy router", "label.deststartport": "Destination Start Port", "label.desttaguuid": "Destination Tag", @@ -771,6 +774,7 @@ "label.enable.storage": "Enable storage pool", "label.enable.vpc.offering": "Enable VPC offering", "label.enable.vpn": "Enable remote access VPN", +"label.enabled": "Enabled", "label.encrypt": "Encrypt", "label.encryptroot": "Encrypt Root Disk", "label.end": "End", @@ -798,6 +802,7 @@ "label.error.setting": "Error setting", "label.error.something.went.wrong.please.correct.the.following": "Something went wrong; please correct the following", "label.error.upper": "ERROR", +"label.errorinmaintenance": "Error in maintenance", "label.espencryption": "ESP encryption", "label.esphash": "ESP hash", "label.esplifetime": "ESP lifetime (second)", @@ -957,6 +962,8 @@ "label.infrastructure": "Infrastructure", "label.ingress": "Ingress", "label.ingress.rule": "Ingress Rule", +"label.initial": "Inital", +"label.initialized": "Initalized", "label.insideportprofile": "Inside port profile", "label.installwizard.addzoneintro.title": "Let's add a zone", "label.installwizard.subtitle": "This guide will aid you in setting up your CloudStack™ installation", @@ -1147,6 +1154,7 @@ "label.local.storage.enabled.system.vms": "Enable local storage for system VMs", "label.localstorageenabled": "Enable local storage for user VMs", "label.localstorageenabledforsystemvm": "Enable local storage for system VMs", +"label.locked": "Locked", "label.login": "Login", "label.loginfo": "Log file information", "label.login.portal": "Portal login", @@ -1446,6 +1454,7 @@ "label.preferred": "Preferred", "label.prefix": "Prefix", "label.prefix.type": "Prefix type", +"label.prepareformaintenance": "Prepare for Maintenance", "label.presetup": "PreSetup", "label.prev": "Prev", "label.previous": "Previous", @@ -1591,6 +1600,7 @@ "label.remove.vmware.datacenter": "Remove VMware Datacenter", "label.remove.vpc": "Remove VPC", "label.remove.vpc.offering": "Remove VPC offering", +"label.removed": "Removed", "label.removing": "Removing", "label.replace.acl": "Replace ACL", "label.replace.acl.list": "Replace ACL list", @@ -1658,7 +1668,8 @@ "label.rules.file.import.description": "Click or drag rule definitions CSV file to import.", "label.rules.file.to.import": "Rule definitions CSV file to import", "label.run.proxy.locally": "Run proxy locally", -"label.running": "Running VMs", +"label.running": "Running", +"label.running.vms": "Running VMs", "label.s2scustomergatewayid": "Site to site customer gateway ID", "label.s2svpngatewayid": "Site to site VPN gateway ID", "label.s3.access.key": "Access key", @@ -1754,6 +1765,7 @@ "label.sharewith": "Share with", "label.showing": "Showing", "label.shrinkok": "Shrink OK", +"label.shutdown": "Shutdown", "label.shutdown.provider": "Shutdown provider", "label.simplified.chinese.keyboard": "Simplified Chinese keyboard", "label.site.to.site.vpn": "Site-to-site VPN", @@ -1822,6 +1834,7 @@ "label.start.rolling.maintenance": "Start rolling maintenance", "label.start.vm": "Start VM", "label.startdate": "By date (start)", +"label.starting": "Starting", "label.startip": "Start IP", "label.startipv4": "IPv4 start IP", "label.startipv6": "IPv6 start IP", @@ -1849,7 +1862,9 @@ "label.sticky.request-learn": "Request learn", "label.sticky.tablesize": "Table size", "label.stop": "Stop", -"label.stopped": "Stopped VMs", +"label.stopped": "Stopped", +"label.stopped.vms": "Stopped VMs", +"label.stopping": "Stopping", "label.storage": "Storage", "label.storage.migration.required": "Storage migration required", "label.storage.tags": "Storage tags", diff --git a/ui/src/config/section/account.js b/ui/src/config/section/account.js index 4de0cc6f5a4..21878c1fe36 100644 --- a/ui/src/config/section/account.js +++ b/ui/src/config/section/account.js @@ -31,6 +31,10 @@ export default { title: 'label.users', param: 'account' }], + filters: () => { + const filters = ['enabled', 'disabled', 'locked'] + return filters + }, tabs: [ { name: 'details', diff --git a/ui/src/config/section/infra/primaryStorages.js b/ui/src/config/section/infra/primaryStorages.js index ff5bb41be65..4537b993a06 100644 --- a/ui/src/config/section/infra/primaryStorages.js +++ b/ui/src/config/section/infra/primaryStorages.js @@ -41,6 +41,10 @@ export default { param: 'storageid' }], resourceType: 'PrimaryStorage', + filters: () => { + const filters = ['initial', 'initialized', 'creating', 'attaching', 'up', 'prepareformaintenance', 'errorinmaintenance', 'cancelmaintenance', 'maintenance', 'disabled', 'removed'] + return filters + }, tabs: [{ name: 'details', component: shallowRef(defineAsyncComponent(() => import('@/components/view/DetailsTab.vue'))) diff --git a/ui/src/config/section/infra/routers.js b/ui/src/config/section/infra/routers.js index 6f24d6b7d82..9e45cb73246 100644 --- a/ui/src/config/section/infra/routers.js +++ b/ui/src/config/section/infra/routers.js @@ -33,6 +33,10 @@ export default { searchFilters: ['name', 'zoneid', 'podid', 'clusterid'], details: ['name', 'id', 'version', 'softwareversion', 'requiresupgrade', 'guestnetworkname', 'vpcname', 'publicip', 'guestipaddress', 'linklocalip', 'serviceofferingname', 'networkdomain', 'isredundantrouter', 'redundantstate', 'hostname', 'account', 'zonename', 'created', 'hostcontrolstate'], resourceType: 'VirtualRouter', + filters: () => { + const filters = ['starting', 'running', 'stopping', 'stopped', 'destroyed', 'expunging', 'migrating', 'error', 'unknown', 'shutdown'] + return filters + }, tabs: [{ name: 'details', component: shallowRef(defineAsyncComponent(() => import('@/components/view/DetailsTab.vue'))) diff --git a/ui/src/config/section/infra/systemVms.js b/ui/src/config/section/infra/systemVms.js index a649ef1c11a..e48b19cb5d4 100644 --- a/ui/src/config/section/infra/systemVms.js +++ b/ui/src/config/section/infra/systemVms.js @@ -27,6 +27,10 @@ export default { columns: ['name', 'state', 'agentstate', 'systemvmtype', 'publicip', 'privateip', 'linklocalip', 'hostname', 'zonename'], details: ['name', 'id', 'agentstate', 'systemvmtype', 'publicip', 'privateip', 'linklocalip', 'gateway', 'hostname', 'zonename', 'created', 'activeviewersessions', 'isdynamicallyscalable', 'hostcontrolstate'], resourceType: 'SystemVm', + filters: () => { + const filters = ['starting', 'running', 'stopping', 'stopped', 'destroyed', 'expunging', 'migrating', 'error', 'unknown', 'shutdown'] + return filters + }, tabs: [ { name: 'details', diff --git a/ui/src/views/AutogenView.vue b/ui/src/views/AutogenView.vue index 4a8a909e794..3c49309bc02 100644 --- a/ui/src/views/AutogenView.vue +++ b/ui/src/views/AutogenView.vue @@ -55,9 +55,9 @@ :placeholder="$t('label.filterby')" :value="$route.query.filter || (projectView && $route.name === 'vm' || ['Admin', 'DomainAdmin'].includes($store.getters.userInfo.roletype) && - ['vm', 'iso', 'template', 'pod', 'cluster', 'host'].includes($route.name) + ['vm', 'iso', 'template', 'pod', 'cluster', 'host', 'systemvm', 'router', 'storagepool'].includes($route.name) ? 'all' : ['publicip'].includes($route.name) - ? 'allocated' : ['guestnetwork', 'guestvlans'].includes($route.name) + ? 'allocated' : ['account', 'guestnetwork', 'guestvlans'].includes($route.name) ? 'all' : ['volume'].includes($route.name) ? 'user' : 'self')" style="min-width: 120px; margin-left: 10px" @@ -70,7 +70,8 @@ {{ $t('label.all') }} @@ -1573,8 +1574,15 @@ export default { } else { query.networkfilter = filter } - } else if (this.$route.name === 'publicip') { - query.state = filter + } else if (['account', 'publicip', 'systemvm', 'router'].includes(this.$route.name)) { + if (filter !== 'all') { + query.state = filter + } + } else if (this.$route.name === 'storagepool') { + if (filter === 'all') { + delete query.status + } else { + query.status = filter } else if (['pod', 'cluster'].includes(this.$route.name)) { if (filter === 'all') { delete query.allocationstate diff --git a/ui/src/views/dashboard/UsageDashboard.vue b/ui/src/views/dashboard/UsageDashboard.vue index 77eb16ef496..4264a90f925 100644 --- a/ui/src/views/dashboard/UsageDashboard.vue +++ b/ui/src/views/dashboard/UsageDashboard.vue @@ -175,7 +175,7 @@ export default { count = json.listvirtualmachinesresponse.count } var tileColor = this.$config.theme['@dashboard-tile-runningvms-bg'] || '#dfe9cc' - this.stats.splice(0, 1, { name: this.$t('label.running'), count: count, icon: 'desktop-outlined', bgcolor: tileColor, path: '/vm', query: { state: 'running', filter: 'running' } }) + this.stats.splice(0, 1, { name: this.$t('label.running.vms'), count: count, icon: 'desktop-outlined', bgcolor: tileColor, path: '/vm', query: { state: 'running', filter: 'running' } }) }) api('listVirtualMachines', { state: 'Stopped', listall: true }).then(json => { var count = 0 @@ -183,7 +183,7 @@ export default { count = json.listvirtualmachinesresponse.count } var tileColor = this.$config.theme['@dashboard-tile-stoppedvms-bg'] || '#edcbce' - this.stats.splice(1, 1, { name: this.$t('label.stopped'), count: count, icon: 'poweroff-outlined', bgcolor: tileColor, path: '/vm', query: { state: 'stopped', filter: 'stopped' } }) + this.stats.splice(1, 1, { name: this.$t('label.stopped.vms'), count: count, icon: 'poweroff-outlined', bgcolor: tileColor, path: '/vm', query: { state: 'stopped', filter: 'stopped' } }) }) api('listVirtualMachines', { listall: true }).then(json => { var count = 0