mirror of https://github.com/apache/cloudstack.git
UI: Show applied search filters (#9520)
This commit is contained in:
parent
7d52cd0e43
commit
0e94f7d771
|
|
@ -98,5 +98,6 @@
|
|||
"multipleServer": false,
|
||||
"allowSettingTheme": true,
|
||||
"docHelpMappings": {},
|
||||
"notifyLatestCSVersion": true
|
||||
"notifyLatestCSVersion": true,
|
||||
"showSearchFilters": true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,559 @@
|
|||
// 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>
|
||||
<a-row
|
||||
style="overflow: auto"
|
||||
:wrap="false"
|
||||
>
|
||||
<template
|
||||
v-for="filter in this.searchFilters"
|
||||
:key="filter.key + filter.value"
|
||||
>
|
||||
<a-col v-if="!['page', 'pagesize', 'q', 'keyword', 'tags'].includes(filter.key)">
|
||||
<a-tag
|
||||
v-if="!filter.isTag"
|
||||
closable
|
||||
@close="() => $emit('removeFilter', filter)"
|
||||
>
|
||||
<a-tooltip
|
||||
:title="retrieveFieldLabel(filter.key) + ': ' + filter.value"
|
||||
placement="bottom"
|
||||
>
|
||||
{{ retrieveFieldLabel(filter.key) }} : {{ getTrimmedText(filter.value, 20) }}
|
||||
</a-tooltip>
|
||||
</a-tag>
|
||||
<a-tag
|
||||
v-else
|
||||
closable
|
||||
@close="() => $emit('removeFilter', filter)"
|
||||
>
|
||||
<a-tooltip
|
||||
:title="$t('label.tag') + ': ' + filter.key + '=' + filter.value"
|
||||
placement="bottom"
|
||||
>
|
||||
{{ $t('label.tag') }}: {{ filter.key }}={{ getTrimmedText(filter.value, 20) }}
|
||||
</a-tooltip>
|
||||
</a-tag>
|
||||
</a-col>
|
||||
</template>
|
||||
</a-row>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import { api } from '@/api/index'
|
||||
|
||||
export default {
|
||||
name: 'SearchFilter',
|
||||
props: {
|
||||
filters: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
apiName: {
|
||||
type: String,
|
||||
default: () => ''
|
||||
},
|
||||
filterKey: {
|
||||
type: String,
|
||||
default: () => ''
|
||||
},
|
||||
filterValue: {
|
||||
type: String,
|
||||
default: () => ''
|
||||
},
|
||||
isTag: {
|
||||
type: Boolean,
|
||||
default: () => false
|
||||
}
|
||||
},
|
||||
emits: ['removeFilter'],
|
||||
data () {
|
||||
return {
|
||||
searchFilters: [],
|
||||
apiMap: {
|
||||
type: (value) => this.getType(value),
|
||||
hypervisor: (value) => this.getHypervisor(value),
|
||||
zoneid: {
|
||||
apiName: 'listZones',
|
||||
responseKey1: 'listzonesresponse',
|
||||
responseKey2: 'zone',
|
||||
field: 'name'
|
||||
},
|
||||
domainid: {
|
||||
apiName: 'listDomains',
|
||||
responseKey1: 'listdomainsresponse',
|
||||
responseKey2: 'domain',
|
||||
field: 'name'
|
||||
},
|
||||
account: {
|
||||
apiName: 'listAccounts',
|
||||
responseKey1: 'listaccountsresponse',
|
||||
responseKey2: 'account',
|
||||
field: 'name'
|
||||
},
|
||||
imagestoreid: {
|
||||
apiName: 'listImageStores',
|
||||
responseKey1: 'listimagestoresresponse',
|
||||
responseKey2: 'imagestore',
|
||||
field: 'name'
|
||||
},
|
||||
storageid: {
|
||||
apiName: 'listStoragePools',
|
||||
responseKey1: 'liststoragepoolsresponse',
|
||||
responseKey2: 'storagepool',
|
||||
field: 'name'
|
||||
},
|
||||
podid: {
|
||||
apiName: 'listPods',
|
||||
responseKey1: 'listpodsresponse',
|
||||
responseKey2: 'pod',
|
||||
field: 'name'
|
||||
},
|
||||
clusterid: {
|
||||
apiName: 'listClusters',
|
||||
responseKey1: 'listclustersresponse',
|
||||
responseKey2: 'cluster',
|
||||
field: 'name'
|
||||
},
|
||||
hostid: {
|
||||
apiName: 'listHosts',
|
||||
responseKey1: 'listhostsresponse',
|
||||
responseKey2: 'host',
|
||||
field: 'name'
|
||||
},
|
||||
groupid: {
|
||||
apiName: 'listInstanceGroups',
|
||||
responseKey1: 'listinstancegroupsresponse',
|
||||
responseKey2: 'instancegroup',
|
||||
field: 'name'
|
||||
},
|
||||
managementserverid: {
|
||||
apiName: 'listManagementServers',
|
||||
responseKey1: 'listmanagementserversresponse',
|
||||
responseKey2: 'managementserver',
|
||||
field: 'name'
|
||||
},
|
||||
serviceofferingid: {
|
||||
apiName: 'listServiceOfferings',
|
||||
responseKey1: 'listserviceofferingsresponse',
|
||||
responseKey2: 'serviceoffering',
|
||||
field: 'name'
|
||||
},
|
||||
diskofferingid: {
|
||||
apiName: 'listDiskOfferings',
|
||||
responseKey1: 'listdiskofferingsresponse',
|
||||
responseKey2: 'diskoffering',
|
||||
field: 'name'
|
||||
},
|
||||
networkid: {
|
||||
apiName: 'listNetworks',
|
||||
responseKey1: 'listnetworksresponse',
|
||||
responseKey2: 'network',
|
||||
field: 'name'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
filters: {
|
||||
immediate: true,
|
||||
handler (newFilters) {
|
||||
const clonedFilters = newFilters.map(filter => ({ ...filter }))
|
||||
const promises = []
|
||||
for (let idx = 0; idx < clonedFilters.length; idx++) {
|
||||
const filter = clonedFilters[idx]
|
||||
promises.push(new Promise((resolve) => {
|
||||
if (filter.key === 'tags') {
|
||||
clonedFilters[idx] = {
|
||||
key: filter.key,
|
||||
value: filter.value,
|
||||
isTag: true
|
||||
}
|
||||
resolve()
|
||||
} else {
|
||||
this.getSearchFilters(filter.key, filter.value).then((value) => {
|
||||
clonedFilters[idx] = {
|
||||
key: filter.key,
|
||||
value: value,
|
||||
isTag: filter.isTag
|
||||
}
|
||||
resolve()
|
||||
})
|
||||
}
|
||||
}))
|
||||
}
|
||||
Promise.all(promises).then(() => {
|
||||
this.searchFilters = clonedFilters
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getTrimmedText (text, length) {
|
||||
if (!text) {
|
||||
return ''
|
||||
}
|
||||
return (text.length <= length) ? text : (text.substring(0, length - 3) + '...')
|
||||
},
|
||||
retrieveFieldLabel (fieldName) {
|
||||
if (fieldName === 'groupid') {
|
||||
fieldName = 'group'
|
||||
}
|
||||
if (fieldName === 'keyword') {
|
||||
if ('listAnnotations' in this.$store.getters.apis) {
|
||||
return this.$t('label.annotation')
|
||||
} else {
|
||||
return this.$t('label.name')
|
||||
}
|
||||
}
|
||||
return this.$t('label.' + fieldName)
|
||||
},
|
||||
async getSearchFilters (key, value) {
|
||||
const val = this.getStaticFieldValue(key, value)
|
||||
if (val !== '') {
|
||||
return val
|
||||
} else {
|
||||
return this.getDynamicFieldValue(key, value)
|
||||
}
|
||||
},
|
||||
getStaticFieldValue (key, value) {
|
||||
let formattedValue = ''
|
||||
if (key.includes('type')) {
|
||||
if (this.$route.path === '/guestnetwork' || this.$route.path.includes('/guestnetwork/')) {
|
||||
formattedValue = this.getGuestNetworkType(value)
|
||||
} else if (this.$route.path === '/role' || this.$route.path.includes('/role/')) {
|
||||
formattedValue = this.getRoleType(value)
|
||||
}
|
||||
}
|
||||
|
||||
if (key.includes('scope')) {
|
||||
// Check storage pool scope first (more specific), then fall back to general scope
|
||||
const storagePoolScope = this.getStoragePoolScope(value)
|
||||
formattedValue = storagePoolScope && storagePoolScope.length > 0 ? storagePoolScope : this.getScope(value)
|
||||
}
|
||||
|
||||
if (key.includes('state')) {
|
||||
formattedValue = this.getState(value)
|
||||
}
|
||||
|
||||
if (key.includes('level')) {
|
||||
formattedValue = this.getLevel(value)
|
||||
}
|
||||
|
||||
if (key.includes('entitytype')) {
|
||||
formattedValue = this.getEntityType(value)
|
||||
}
|
||||
|
||||
if (key.includes('accounttype')) {
|
||||
formattedValue = this.getAccountType(value)
|
||||
}
|
||||
|
||||
if (key.includes('systemvmtype')) {
|
||||
formattedValue = this.getSystemVmType(value)
|
||||
}
|
||||
|
||||
if (key.includes('provider')) {
|
||||
formattedValue = this.getImageStoreProvider(value)
|
||||
}
|
||||
|
||||
if (key.includes('resourcetype')) {
|
||||
formattedValue = value
|
||||
}
|
||||
return formattedValue
|
||||
},
|
||||
async getDynamicFieldValue (key, value) {
|
||||
let formattedValue = ''
|
||||
|
||||
if (typeof this.apiMap[key] === 'function') {
|
||||
formattedValue = await this.apiMap[key](value)
|
||||
} else if (this.apiMap[key]) {
|
||||
const apiName = this.apiMap[key].apiName
|
||||
const responseKey1 = this.apiMap[key].responseKey1
|
||||
const responseKey2 = this.apiMap[key].responseKey2
|
||||
const field = this.apiMap[key].field
|
||||
formattedValue = await this.getResourceNameById(apiName, responseKey1, responseKey2, value, field)
|
||||
}
|
||||
if (formattedValue === '') {
|
||||
formattedValue = value
|
||||
}
|
||||
return formattedValue
|
||||
},
|
||||
getHypervisor (value) {
|
||||
return new Promise((resolve) => {
|
||||
api('listHypervisors').then(json => {
|
||||
if (json?.listhypervisorsresponse?.hypervisor) {
|
||||
for (const key in json.listhypervisorsresponse.hypervisor) {
|
||||
const hypervisor = json.listhypervisorsresponse.hypervisor[key]
|
||||
if (hypervisor.name === value) {
|
||||
return resolve(hypervisor.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
resolve(null)
|
||||
}).catch(() => {
|
||||
resolve(null)
|
||||
})
|
||||
})
|
||||
},
|
||||
getResourceNameById (apiName, responseKey1, responseKey2, id, field) {
|
||||
return new Promise((resolve) => {
|
||||
if (!this.$isValidUuid(id)) {
|
||||
return resolve('')
|
||||
}
|
||||
api(apiName, { listAll: true, id: id }).then(json => {
|
||||
const items = json && json[responseKey1] && json[responseKey1][responseKey2]
|
||||
if (Array.isArray(items) && items.length > 0 && items[0] && items[0][field] !== undefined) {
|
||||
resolve(items[0][field])
|
||||
} else {
|
||||
resolve('')
|
||||
}
|
||||
}).catch(() => {
|
||||
resolve('')
|
||||
})
|
||||
})
|
||||
},
|
||||
getType (type) {
|
||||
if (this.$route.path === '/alert') {
|
||||
return this.getAlertType(type)
|
||||
} else if (this.$route.path === '/affinitygroup') {
|
||||
return this.getAffinityGroupType(type)
|
||||
}
|
||||
},
|
||||
getAlertType (type) {
|
||||
return new Promise((resolve) => {
|
||||
api('listAlertTypes').then(json => {
|
||||
const alertTypes = {}
|
||||
for (const key in json.listalerttypesresponse.alerttype) {
|
||||
const alerttype = json.listalerttypesresponse.alerttype[key]
|
||||
alertTypes[alerttype.id] = alerttype.name
|
||||
}
|
||||
resolve(alertTypes[type])
|
||||
}).catch(() => {
|
||||
resolve(null)
|
||||
})
|
||||
})
|
||||
},
|
||||
getAffinityGroupType (type) {
|
||||
return new Promise((resolve) => {
|
||||
api('listAffinityGroupTypes').then(json => {
|
||||
const alertTypes = {}
|
||||
for (const key in json.listaffinitygrouptypesresponse.affinityGroupType) {
|
||||
const affinityGroupType = json.listaffinitygrouptypesresponse.affinityGroupType[key]
|
||||
if (affinityGroupType.type === 'host anti-affinity') {
|
||||
alertTypes[affinityGroupType.type] = 'host anti-affinity (Strict)'
|
||||
} else if (affinityGroupType.type === 'host affinity') {
|
||||
alertTypes[affinityGroupType.type] = 'host affinity (Strict)'
|
||||
} else if (affinityGroupType.type === 'non-strict host anti-affinity') {
|
||||
alertTypes[affinityGroupType.type] = 'host anti-affinity (Non-Strict)'
|
||||
} else if (affinityGroupType.type === 'non-strict host affinity') {
|
||||
alertTypes[affinityGroupType.type] = 'host affinity (Non-Strict)'
|
||||
}
|
||||
}
|
||||
this.alertTypes = alertTypes
|
||||
resolve(alertTypes[type])
|
||||
}).catch(() => {
|
||||
resolve(null)
|
||||
})
|
||||
})
|
||||
},
|
||||
getGuestNetworkType (value) {
|
||||
switch (value.toLowerCase()) {
|
||||
case 'isolated':
|
||||
return this.$t('label.isolated')
|
||||
case 'shared':
|
||||
return this.$t('label.shared')
|
||||
case 'l2':
|
||||
return this.$t('label.l2')
|
||||
}
|
||||
},
|
||||
getAccountType (type) {
|
||||
const types = []
|
||||
if (this.apiName.indexOf('listAccounts') > -1) {
|
||||
switch (type) {
|
||||
case '1':
|
||||
return 'Admin'
|
||||
case '2':
|
||||
return 'DomainAdmin'
|
||||
case '0':
|
||||
return 'User'
|
||||
}
|
||||
}
|
||||
return types
|
||||
},
|
||||
getSystemVmType (type) {
|
||||
if (this.apiName.indexOf('listSystemVms') > -1) {
|
||||
switch (type.toLowerCase()) {
|
||||
case 'consoleproxy':
|
||||
return this.$t('label.console.proxy.vm')
|
||||
case 'secondarystoragevm':
|
||||
return this.$t('label.secondary.storage.vm')
|
||||
}
|
||||
}
|
||||
},
|
||||
getStoragePoolScope (scope) {
|
||||
if (this.apiName.indexOf('listStoragePools') > -1) {
|
||||
switch (scope.toUpperCase()) {
|
||||
case 'CLUSTER':
|
||||
return this.$t('label.cluster')
|
||||
case 'ZONE':
|
||||
return this.$t('label.zone')
|
||||
case 'REGION':
|
||||
return this.$t('label.region')
|
||||
case 'GLOBAL':
|
||||
return this.$t('label.global')
|
||||
}
|
||||
}
|
||||
},
|
||||
getImageStoreProvider (provider) {
|
||||
if (this.apiName.indexOf('listImageStores') > -1) {
|
||||
switch (provider.toUpperCase()) {
|
||||
case 'NFS':
|
||||
return 'NFS'
|
||||
case 'SMB':
|
||||
return 'SMB/CIFS'
|
||||
case 'S3':
|
||||
return 'S3'
|
||||
case 'SWIFT':
|
||||
return 'Swift'
|
||||
}
|
||||
}
|
||||
},
|
||||
getRoleType (role) {
|
||||
switch (role.toLowerCase()) {
|
||||
case 'Admin'.toLowerCase():
|
||||
return 'Admin'
|
||||
case 'ResourceAdmin'.toLowerCase():
|
||||
return 'ResourceAdmin'
|
||||
case 'DomainAdmin'.toLowerCase():
|
||||
return 'DomainAdmin'
|
||||
case 'User'.toLowerCase():
|
||||
return 'User'
|
||||
}
|
||||
},
|
||||
getScope (scope) {
|
||||
switch (scope.toLowerCase()) {
|
||||
case 'local':
|
||||
return this.$t('label.local')
|
||||
case 'domain':
|
||||
return this.$t('label.domain')
|
||||
case 'global':
|
||||
return this.$t('label.global')
|
||||
}
|
||||
},
|
||||
getState (state) {
|
||||
if (this.apiName.includes('listVolumes')) {
|
||||
switch (state.toLowerCase()) {
|
||||
case 'allocated':
|
||||
return this.$t('label.allocated')
|
||||
case 'ready':
|
||||
return this.$t('label.isready')
|
||||
case 'destroy':
|
||||
return this.$t('label.destroy')
|
||||
case 'expunging':
|
||||
return this.$t('label.expunging')
|
||||
case 'expunged':
|
||||
return this.$t('label.expunged')
|
||||
case 'migrating':
|
||||
return this.$t('label.migrating')
|
||||
}
|
||||
} else if (this.apiName.includes('listKubernetesClusters')) {
|
||||
switch (state.toLowerCase()) {
|
||||
case 'created':
|
||||
return this.$t('label.created')
|
||||
case 'starting':
|
||||
return this.$t('label.starting')
|
||||
case 'running':
|
||||
return this.$t('label.running')
|
||||
case 'stopping':
|
||||
return this.$t('label.stopping')
|
||||
case 'stopped':
|
||||
return this.$t('label.stopped')
|
||||
case 'scaling':
|
||||
return this.$t('label.scaling')
|
||||
case 'upgrading':
|
||||
return this.$t('label.upgrading')
|
||||
case 'alert':
|
||||
return this.$t('label.alert')
|
||||
case 'recovering':
|
||||
return this.$t('label.recovering')
|
||||
case 'destroyed':
|
||||
return this.$t('label.destroyed')
|
||||
case 'destroying':
|
||||
return this.$t('label.destroying')
|
||||
case 'error':
|
||||
return this.$t('label.error')
|
||||
}
|
||||
} else if (this.apiName.indexOf('listWebhooks') > -1) {
|
||||
switch (state.toLowerCase()) {
|
||||
case 'enabled':
|
||||
return this.$t('label.enabled')
|
||||
case 'disabled':
|
||||
return this.$t('label.disabled')
|
||||
}
|
||||
}
|
||||
},
|
||||
getEntityType (type) {
|
||||
let entityType = ''
|
||||
if (this.apiName.indexOf('listAnnotations') > -1) {
|
||||
const allowedTypes = {
|
||||
VM: 'Virtual Machine',
|
||||
HOST: 'Host',
|
||||
VOLUME: 'Volume',
|
||||
SNAPSHOT: 'Snapshot',
|
||||
VM_SNAPSHOT: 'VM Snapshot',
|
||||
INSTANCE_GROUP: 'Instance Group',
|
||||
NETWORK: 'Network',
|
||||
VPC: 'VPC',
|
||||
PUBLIC_IP_ADDRESS: 'Public IP Address',
|
||||
VPN_CUSTOMER_GATEWAY: 'VPC Customer Gateway',
|
||||
TEMPLATE: 'Template',
|
||||
ISO: 'ISO',
|
||||
SSH_KEYPAIR: 'SSH Key Pair',
|
||||
DOMAIN: 'Domain',
|
||||
SERVICE_OFFERING: 'Service Offering',
|
||||
DISK_OFFERING: 'Disk Offering',
|
||||
NETWORK_OFFERING: 'Network Offering',
|
||||
POD: 'Pod',
|
||||
ZONE: 'Zone',
|
||||
CLUSTER: 'Cluster',
|
||||
PRIMARY_STORAGE: 'Primary Storage',
|
||||
SECONDARY_STORAGE: 'Secondary Storage',
|
||||
VR: 'Virtual Router',
|
||||
SYSTEM_VM: 'System VM',
|
||||
KUBERNETES_CLUSTER: 'Kubernetes Cluster'
|
||||
}
|
||||
entityType = allowedTypes[type.toUpperCase()]
|
||||
}
|
||||
return entityType
|
||||
},
|
||||
getLevel (level) {
|
||||
switch (level.toUpperCase()) {
|
||||
case 'INFO':
|
||||
return this.$t('label.info.upper')
|
||||
|
||||
case 'WARN':
|
||||
return this.$t('label.warn.upper')
|
||||
|
||||
case 'ERROR':
|
||||
return this.$t('label.error.upper')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
@ -106,6 +106,16 @@
|
|||
@change-filter="changeFilter"/>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row
|
||||
v-if="!dataView && $config.showSearchFilters"
|
||||
style="min-height: 36px; padding-top: 12px;"
|
||||
>
|
||||
<search-filter
|
||||
:filters="getActiveFilters()"
|
||||
:apiName="apiName"
|
||||
@removeFilter="removeFilter"
|
||||
/>
|
||||
</a-row>
|
||||
</a-card>
|
||||
</a-affix>
|
||||
|
||||
|
|
@ -469,6 +479,7 @@ import ListView from '@/components/view/ListView'
|
|||
import ResourceView from '@/components/view/ResourceView'
|
||||
import ActionButton from '@/components/view/ActionButton'
|
||||
import SearchView from '@/components/view/SearchView'
|
||||
import SearchFilter from '@/components/view/SearchFilter'
|
||||
import OsLogo from '@/components/widgets/OsLogo'
|
||||
import ResourceIcon from '@/components/view/ResourceIcon'
|
||||
import BulkActionProgress from '@/components/view/BulkActionProgress'
|
||||
|
|
@ -482,6 +493,7 @@ export default {
|
|||
ListView,
|
||||
ActionButton,
|
||||
SearchView,
|
||||
SearchFilter,
|
||||
BulkActionProgress,
|
||||
TooltipLabel,
|
||||
OsLogo,
|
||||
|
|
@ -1126,6 +1138,42 @@ export default {
|
|||
eventBus.emit('action-closing', { action: this.currentAction })
|
||||
this.closeAction()
|
||||
},
|
||||
getActiveFilters () {
|
||||
const queryParams = Object.assign({}, this.$route.query)
|
||||
const activeFilters = []
|
||||
for (const filter in queryParams) {
|
||||
if (!filter.startsWith('tags[')) {
|
||||
activeFilters.push({
|
||||
key: filter,
|
||||
value: queryParams[filter],
|
||||
isTag: false
|
||||
})
|
||||
} else if (filter.endsWith('].key')) {
|
||||
const tagIdx = filter.split('[')[1].split(']')[0]
|
||||
const tagKey = queryParams[`tags[${tagIdx}].key`]
|
||||
const tagValue = queryParams[`tags[${tagIdx}].value`]
|
||||
activeFilters.push({
|
||||
key: tagKey,
|
||||
value: tagValue,
|
||||
isTag: true,
|
||||
tagIdx: tagIdx
|
||||
})
|
||||
}
|
||||
}
|
||||
return activeFilters
|
||||
},
|
||||
removeFilter (filter) {
|
||||
const queryParams = Object.assign({}, this.$route.query)
|
||||
if (filter.isTag) {
|
||||
delete queryParams[`tags[${filter.tagIdx}].key`]
|
||||
delete queryParams[`tags[${filter.tagIdx}].value`]
|
||||
} else {
|
||||
delete queryParams[filter.key]
|
||||
}
|
||||
queryParams.page = '1'
|
||||
queryParams.pagesize = String(this.pageSize)
|
||||
this.$router.push({ query: queryParams })
|
||||
},
|
||||
onRowSelectionChange (selection) {
|
||||
this.selectedRowKeys = selection
|
||||
if (selection?.length > 0) {
|
||||
|
|
|
|||
|
|
@ -113,6 +113,10 @@ store = common.createMockStore(state, actions, mutations)
|
|||
i18n = common.createMockI18n('en', mockData.messages)
|
||||
|
||||
mocks = {
|
||||
$config: {
|
||||
showSearchFilters: true,
|
||||
docBase: 'http://docs.cloudstack.apache.org/en/latest'
|
||||
},
|
||||
$notifyError: jest.fn((error) => {
|
||||
return error
|
||||
}),
|
||||
|
|
|
|||
Loading…
Reference in New Issue