diff --git a/ui/src/components/view/SearchView.vue b/ui/src/components/view/SearchView.vue new file mode 100644 index 00000000000..6e5cfb38d28 --- /dev/null +++ b/ui/src/components/view/SearchView.vue @@ -0,0 +1,481 @@ +// 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. + + + + + + diff --git a/ui/src/config/router.js b/ui/src/config/router.js index cad2aeebd1a..0c0699b818e 100644 --- a/ui/src/config/router.js +++ b/ui/src/config/router.js @@ -42,7 +42,7 @@ function generateRouterMap (section) { name: section.name, path: '/' + section.name, hidden: section.hidden, - meta: { title: section.title, icon: section.icon, docHelp: section.docHelp }, + meta: { title: section.title, icon: section.icon, docHelp: section.docHelp, searchFilters: section.searchFilters }, component: RouteView } @@ -67,6 +67,7 @@ function generateRouterMap (section) { params: child.params ? child.params : {}, columns: child.columns, details: child.details, + searchFilters: child.searchFilters, related: child.related, actions: child.actions, tabs: child.tabs @@ -86,6 +87,7 @@ function generateRouterMap (section) { resourceType: child.resourceType, params: child.params ? child.params : {}, details: child.details, + searchFilters: child.searchFilters, related: child.related, tabs: child.tabs, actions: child.actions ? child.actions : [] @@ -142,6 +144,7 @@ function generateRouterMap (section) { params: section.params ? section.params : {}, details: section.details, related: section.related, + searchFilters: section.searchFilters, tabs: section.tabs, actions: section.actions ? section.actions : [] }, diff --git a/ui/src/config/section/compute.js b/ui/src/config/section/compute.js index c2d0df2239b..72bcdcfb779 100644 --- a/ui/src/config/section/compute.js +++ b/ui/src/config/section/compute.js @@ -61,6 +61,7 @@ export default { } return fields }, + searchFilters: ['name', 'zoneid', 'domainid', 'account', 'tags'], details: ['displayname', 'name', 'id', 'state', 'ipaddress', 'templatename', 'ostypename', 'serviceofferingname', 'isdynamicallyscalable', 'haenable', 'hypervisor', 'boottype', 'bootmode', 'account', 'domain', 'zonename'], related: [{ name: 'vmsnapshot', diff --git a/ui/src/config/section/event.js b/ui/src/config/section/event.js index 7924286fd8a..eee70fab558 100644 --- a/ui/src/config/section/event.js +++ b/ui/src/config/section/event.js @@ -23,6 +23,7 @@ export default { permission: ['listEvents'], columns: ['username', 'description', 'state', 'level', 'type', 'account', 'domain', 'created'], details: ['username', 'id', 'description', 'state', 'level', 'type', 'account', 'domain', 'created'], + searchFilters: ['level', 'domainid', 'account', 'keyword'], related: [{ name: 'event', title: 'label.event.timeline', diff --git a/ui/src/config/section/image.js b/ui/src/config/section/image.js index 6c2fcec5a12..41a19703da1 100644 --- a/ui/src/config/section/image.js +++ b/ui/src/config/section/image.js @@ -40,6 +40,7 @@ export default { return fields }, details: ['name', 'id', 'displaytext', 'checksum', 'hypervisor', 'format', 'ostypename', 'size', 'isready', 'passwordenabled', 'directdownload', 'isextractable', 'isdynamicallyscalable', 'ispublic', 'isfeatured', 'crosszones', 'type', 'account', 'domain', 'created'], + searchFilters: ['name', 'zoneid', 'tags'], related: [{ name: 'vm', title: 'label.instances', @@ -130,6 +131,7 @@ export default { filters: ['self', 'shared', 'featured', 'community'], columns: ['name', 'ostypename', 'account', 'domain'], details: ['name', 'id', 'displaytext', 'checksum', 'ostypename', 'size', 'bootable', 'isready', 'directdownload', 'isextractable', 'ispublic', 'isfeatured', 'crosszones', 'account', 'domain', 'created'], + searchFilters: ['name', 'zoneid', 'tags'], related: [{ name: 'vm', title: 'label.instances', diff --git a/ui/src/config/section/infra/routers.js b/ui/src/config/section/infra/routers.js index 0be025d44ae..43679aa05ae 100644 --- a/ui/src/config/section/infra/routers.js +++ b/ui/src/config/section/infra/routers.js @@ -23,6 +23,7 @@ export default { permission: ['listRouters'], params: { projectid: '-1' }, columns: ['name', 'state', 'publicip', 'guestnetworkname', 'vpcname', 'redundantstate', 'version', 'hostname', 'account', 'zonename', 'requiresupgrade'], + searchFilters: ['name', 'zoneid', 'podid', 'clusterid'], details: ['name', 'id', 'version', 'requiresupgrade', 'guestnetworkname', 'vpcname', 'publicip', 'guestipaddress', 'linklocalip', 'serviceofferingname', 'networkdomain', 'isredundantrouter', 'redundantstate', 'hostname', 'account', 'zonename', 'created'], tabs: [{ name: 'details', diff --git a/ui/src/config/section/network.js b/ui/src/config/section/network.js index 95f9db06f1f..3cf924dcf6e 100644 --- a/ui/src/config/section/network.js +++ b/ui/src/config/section/network.js @@ -31,6 +31,7 @@ export default { resourceType: 'Network', columns: ['name', 'state', 'type', 'cidr', 'ip6cidr', 'broadcasturi', 'account', 'zonename'], details: ['name', 'id', 'description', 'type', 'traffictype', 'vpcid', 'vlan', 'broadcasturi', 'cidr', 'ip6cidr', 'netmask', 'gateway', 'ispersistent', 'restartrequired', 'reservediprange', 'redundantrouter', 'networkdomain', 'zonename', 'account', 'domain'], + searchFilters: ['keyword', 'zoneid', 'domainid', 'account', 'tags'], related: [{ name: 'vm', title: 'label.instances', @@ -113,6 +114,7 @@ export default { resourceType: 'Vpc', columns: ['name', 'state', 'displaytext', 'cidr', 'account', 'zonename'], details: ['name', 'id', 'displaytext', 'cidr', 'networkdomain', 'ispersistent', 'redundantvpcrouter', 'restartrequired', 'zonename', 'account', 'domain'], + searchFilters: ['name', 'zoneid', 'domainid', 'account', 'tags'], related: [{ name: 'vm', title: 'label.instances', @@ -554,6 +556,7 @@ export default { permission: ['listVpnCustomerGateways'], columns: ['name', 'gateway', 'cidrlist', 'ipsecpsk', 'account', 'domain'], details: ['name', 'id', 'gateway', 'cidrlist', 'ipsecpsk', 'ikepolicy', 'ikelifetime', 'esppolicy', 'esplifetime', 'dpd', 'forceencap', 'account', 'domain'], + searchFilters: ['keyword', 'domainid', 'account'], actions: [ { api: 'createVpnCustomerGateway', diff --git a/ui/src/config/section/project.js b/ui/src/config/section/project.js index e5fdb3f3c31..56e0d460197 100644 --- a/ui/src/config/section/project.js +++ b/ui/src/config/section/project.js @@ -23,6 +23,7 @@ export default { permission: ['listProjects'], resourceType: 'Project', columns: ['name', 'state', 'displaytext', 'account', 'domain'], + searchFilters: ['name', 'displaytext', 'domainid', 'account'], details: ['name', 'id', 'displaytext', 'projectaccountname', 'account', 'domain'], tabs: [ { diff --git a/ui/src/config/section/storage.js b/ui/src/config/section/storage.js index ac41970b40b..970d979367f 100644 --- a/ui/src/config/section/storage.js +++ b/ui/src/config/section/storage.js @@ -64,6 +64,7 @@ export default { title: 'label.snapshots', param: 'volumeid' }], + searchFilters: ['name', 'zoneid', 'domainid', 'account', 'state', 'tags'], actions: [ { api: 'createVolume', @@ -231,6 +232,7 @@ export default { resourceType: 'Snapshot', columns: ['name', 'state', 'volumename', 'intervaltype', 'created', 'account'], details: ['name', 'id', 'volumename', 'intervaltype', 'account', 'domain', 'created'], + searchFilters: ['name', 'domainid', 'account', 'tags'], actions: [ { api: 'createTemplate', @@ -283,6 +285,7 @@ export default { resourceType: 'VMSnapshot', columns: ['displayname', 'state', 'type', 'current', 'parentName', 'created', 'account'], details: ['name', 'id', 'displayname', 'description', 'type', 'current', 'parentName', 'virtualmachineid', 'account', 'domain', 'created'], + searchFilters: ['name', 'domainid', 'account', 'tags'], actions: [ { api: 'revertToVMSnapshot', diff --git a/ui/src/locales/en.json b/ui/src/locales/en.json index 24f0ede3faa..96d1229b2a6 100644 --- a/ui/src/locales/en.json +++ b/ui/src/locales/en.json @@ -514,6 +514,7 @@ "label.ciscovnmc.resource.details": "CiscoVNMC resource details", "label.cks.cluster.size": "Cluster size (Worker nodes)", "label.cleanup": "Clean up", +"label.clear": "Clear", "label.clear.list": "Clear list", "label.close": "Close", "label.cloud.console": "Cloud Management Console", @@ -723,7 +724,7 @@ "label.domain.name": "Domain Name", "label.domain.router": "Domain router", "label.domain.suffix": "DNS Domain Suffix (i.e., xyz.com)", -"label.domainid": "Domain ID", +"label.domainid": "Domain", "label.domainname": "Domain", "label.domainpath": "Domain", "label.domains": "Domains", @@ -801,6 +802,8 @@ "label.example": "Example", "label.existingnetworks": "Existing networks", "label.expunge": "Expunge", +"label.expunged": "Expunged", +"label.expunging": "Expunging", "label.external.link": "External link", "label.externalid": "External Id", "label.externalloadbalanceripaddress": "External load balancer IP address", diff --git a/ui/src/utils/plugins.js b/ui/src/utils/plugins.js index 0e3e7f974dc..5b9328dd131 100644 --- a/ui/src/utils/plugins.js +++ b/ui/src/utils/plugins.js @@ -21,7 +21,6 @@ import { api } from '@/api' import { message, notification } from 'ant-design-vue' export const pollJobPlugin = { - install (Vue) { Vue.prototype.$pollJob = function (options) { /** @@ -111,7 +110,6 @@ export const pollJobPlugin = { } export const notifierPlugin = { - install (Vue) { Vue.prototype.$notifyError = function (error) { console.log(error) diff --git a/ui/src/views/AutogenView.vue b/ui/src/views/AutogenView.vue index f1b5f221263..c2815a6c50a 100644 --- a/ui/src/views/AutogenView.vue +++ b/ui/src/views/AutogenView.vue @@ -68,13 +68,11 @@ :dataView="dataView" :resource="resource" @exec-action="execAction"/> - + :searchFilters="searchFilters" + :selectedFilters="paramsFilters" + :apiName="apiName"/> @@ -304,7 +302,7 @@ :current="page" :pageSize="pageSize" :total="itemCount" - :showTotal="total => `Showing ${1+((page-1)*pageSize)}-${Math.min(page*pageSize, total)} of ${total} items`" + :showTotal="total => `Showing ${Math.min(total, 1+((page-1)*pageSize))}-${Math.min(page*pageSize, total)} of ${total} items`" :pageSizeOptions="device === 'desktop' ? ['20', '50', '100', '500'] : ['10', '20', '50', '100', '500']" @change="changePage" @showSizeChange="changePageSize" @@ -326,6 +324,7 @@ import Status from '@/components/widgets/Status' import ListView from '@/components/view/ListView' import ResourceView from '@/components/view/ResourceView' import ActionButton from '@/components/view/ActionButton' +import SearchView from '@/components/view/SearchView' export default { name: 'Resource', @@ -335,7 +334,8 @@ export default { ResourceView, ListView, Status, - ActionButton + ActionButton, + SearchView }, mixins: [mixinDevice], provide: function () { @@ -344,6 +344,9 @@ export default { parentToggleLoading: this.toggleLoading, parentStartLoading: this.startLoading, parentFinishLoading: this.finishLoading, + parentSearch: this.onSearch, + parentChangeFilter: this.changeFilter, + parentFilter: this.onFilter, parentChangeResource: this.changeResource, parentPollActionCompletion: this.pollActionCompletion, parentEditTariffAction: () => {} @@ -367,6 +370,8 @@ export default { dataView: false, selectedFilter: '', filters: [], + searchFilters: [], + paramsFilters: {}, actions: [], formModel: {}, confirmDirty: false @@ -397,6 +402,7 @@ export default { '$route' (to, from) { if (to.fullPath !== from.fullPath && !to.fullPath.includes('action/')) { this.searchQuery = '' + this.paramsFilters = {} this.page = 1 this.itemCount = 0 this.selectedFilter = '' @@ -449,6 +455,11 @@ export default { } else if (this.$route.meta.params) { Object.assign(params, this.$route.meta.params) } + if (Object.keys(this.paramsFilters).length > 0) { + Object.assign(params, this.paramsFilters) + } + + this.searchFilters = this.$route && this.$route.meta && this.$route.meta.searchFilters if (this.$route && this.$route.params && this.$route.params.id) { this.dataView = true @@ -616,6 +627,16 @@ export default { this.$emit('change-resource', this.resource) } }).catch(error => { + if (Object.keys(this.paramsFilters).length > 0) { + this.itemCount = 0 + this.items = [] + this.$message.error({ + content: error.response.headers['x-description'], + duration: 5 + }) + return + } + this.$notifyError(error) if ([401, 405].includes(error.response.status)) { @@ -634,10 +655,19 @@ export default { }) }, onSearch (value) { + this.paramsFilters = {} this.searchQuery = value this.page = 1 this.fetchData() }, + onFilter (filters) { + this.paramsFilters = {} + if (filters && Object.keys(filters).length > 0) { + this.paramsFilters = filters + } + this.page = 1 + this.fetchData() + }, closeAction () { this.actionLoading = false this.showAction = false