You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ro...@apache.org on 2020/06/21 06:13:57 UTC

[cloudstack-primate] 01/02: dashboard: loading and assorted fixes

This is an automated email from the ASF dual-hosted git repository.

rohit pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cloudstack-primate.git

commit 223e59e354af1c8d65ec01532d73e645b27606a1
Author: Rohit Yadav <ro...@shapeblue.com>
AuthorDate: Sun Jun 21 11:36:35 2020 +0530

    dashboard: loading and assorted fixes
    
    Signed-off-by: Rohit Yadav <ro...@shapeblue.com>
---
 src/components/header/ProjectMenu.vue       |  1 +
 src/components/view/ListView.vue            |  5 ++++
 src/config/section/compute.js               | 37 ++++++++++++++++++++---------
 src/config/section/network.js               |  4 ++--
 src/config/section/storage.js               | 19 ++++++++++++++-
 src/permission.js                           |  4 ++--
 src/store/modules/user.js                   |  4 ----
 src/views/AutogenView.vue                   |  7 +++++-
 src/views/dashboard/CapacityDashboard.vue   |  5 ++--
 src/views/dashboard/UsageDashboard.vue      | 34 ++++++++++++++++----------
 src/views/dashboard/UsageDashboardChart.vue | 18 ++++++++++----
 11 files changed, 97 insertions(+), 41 deletions(-)

diff --git a/src/components/header/ProjectMenu.vue b/src/components/header/ProjectMenu.vue
index 25c6c23..0d1f8db 100644
--- a/src/components/header/ProjectMenu.vue
+++ b/src/components/header/ProjectMenu.vue
@@ -20,6 +20,7 @@
     <a-select
       class="project-select"
       defaultValue="Default View"
+      :loading="loading"
       :value="('id' in $store.getters.project) ? ($store.getters.project.displaytext || $store.getters.project.name) : 'Default View'"
       :disabled="isDisabled()"
       :filterOption="filterProject"
diff --git a/src/components/view/ListView.vue b/src/components/view/ListView.vue
index e05a842..26f9d36 100644
--- a/src/components/view/ListView.vue
+++ b/src/components/view/ListView.vue
@@ -129,6 +129,11 @@
       <router-link v-else-if="record.hostname" :to="{ path: $route.path + '/' + record.id }">{{ text }}</router-link>
       <span v-else>{{ text }}</span>
     </a>
+    <a slot="storage" slot-scope="text, record" href="javascript:;">
+      <router-link v-if="record.storageid" :to="{ path: '/storagepool/' + record.storageid }">{{ text }}</router-link>
+      <span v-else>{{ text }}</span>
+    </a>
+
     <a slot="clustername" slot-scope="text, record" href="javascript:;">
       <router-link :to="{ path: '/cluster/' + record.clusterid }">{{ text }}</router-link>
     </a>
diff --git a/src/config/section/compute.js b/src/config/section/compute.js
index f948d34..4b06a42 100644
--- a/src/config/section/compute.js
+++ b/src/config/section/compute.js
@@ -16,6 +16,7 @@
 // under the License.
 
 import kubernetes from '@/assets/icons/kubernetes.svg?inline'
+import store from '@/store'
 
 export default {
   name: 'compute',
@@ -30,16 +31,30 @@ export default {
       permission: ['listVirtualMachinesMetrics'],
       resourceType: 'UserVm',
       filters: ['self', 'running', 'stopped'],
-      columns: [
-        'name', 'state', 'instancename', 'ipaddress', 'cpunumber', 'cpuused', 'cputotal',
-        {
-          memoryused: (record) => {
-            return record.memorykbs && record.memoryintfreekbs ? parseFloat(100.0 * (record.memorykbs - record.memoryintfreekbs) / record.memorykbs).toFixed(2) + '%' : '0.0%'
-          }
-        },
-        'memorytotal', 'networkread', 'networkwrite', 'diskkbsread', 'diskkbswrite', 'diskiopstotal',
-        'account', 'zonename'
-      ],
+      columns: () => {
+        const fields = [
+          'name', 'state', 'ipaddress', 'cpunumber', 'cpuused', 'cputotal',
+          {
+            memoryused: (record) => {
+              return record.memorykbs && record.memoryintfreekbs ? parseFloat(100.0 * (record.memorykbs - record.memoryintfreekbs) / record.memorykbs).toFixed(2) + '%' : '0.0%'
+            }
+          },
+          'memorytotal', 'networkread', 'networkwrite', 'diskkbsread', 'diskkbswrite', 'diskiopstotal'
+        ]
+
+        if (store.getters.userInfo.roletype === 'Admin') {
+          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')
+        }
+        return fields
+      },
       related: [{
         name: 'volume',
         title: 'label.volumes',
@@ -105,7 +120,7 @@ export default {
         },
         {
           api: 'stopVirtualMachine',
-          icon: 'stop',
+          icon: 'poweroff',
           label: 'label.action.stop.instance',
           message: 'message.action.stop.instance',
           docHelp: 'adminguide/virtual_machines.html#stopping-and-starting-vms',
diff --git a/src/config/section/network.js b/src/config/section/network.js
index f989bcd..38999d1 100644
--- a/src/config/section/network.js
+++ b/src/config/section/network.js
@@ -25,7 +25,7 @@ export default {
     {
       name: 'guestnetwork',
       title: 'label.guest.networks',
-      icon: 'gateway',
+      icon: 'apartment',
       permission: ['listNetworks'],
       resourceType: 'Network',
       columns: ['name', 'state', 'type', 'cidr', 'ip6cidr', 'broadcasturi', 'account', 'zonename'],
@@ -267,7 +267,7 @@ export default {
     {
       name: 'privategw',
       title: 'label.private.gateway',
-      icon: 'branches',
+      icon: 'gateway',
       hidden: true,
       permission: ['listPrivateGateways'],
       columns: ['ipaddress', 'state', 'gateway', 'netmask', 'account', 'domain'],
diff --git a/src/config/section/storage.js b/src/config/section/storage.js
index eab50c7..775097c 100644
--- a/src/config/section/storage.js
+++ b/src/config/section/storage.js
@@ -15,6 +15,8 @@
 // specific language governing permissions and limitations
 // under the License.
 
+import store from '@/store'
+
 export default {
   name: 'storage',
   title: 'label.storage',
@@ -26,7 +28,22 @@ export default {
       icon: 'hdd',
       permission: ['listVolumesMetrics'],
       resourceType: 'Volume',
-      columns: ['name', 'state', 'type', 'vmname', 'size', 'physicalsize', 'utilization', 'diskkbsread', 'diskkbswrite', 'diskiopstotal', 'storage', 'account', 'zonename'],
+      columns: () => {
+        const fields = ['name', 'state', 'type', 'sizegb', 'vmname', 'diskkbsread', 'diskkbswrite', 'diskiopstotal']
+
+        if (store.getters.userInfo.roletype === 'Admin') {
+          fields.push('account')
+          fields.push('storage')
+          fields.push('zonename')
+        } else if (store.getters.userInfo.roletype === 'DomainAdmin') {
+          fields.push('account')
+          fields.push('zonename')
+        } else {
+          fields.push('zonename')
+        }
+
+        return fields
+      },
       details: ['name', 'id', 'type', 'storagetype', 'diskofferingdisplaytext', 'deviceid', 'sizegb', 'physicalsize', 'provisioningtype', 'utilization', 'diskkbsread', 'diskkbswrite', 'diskioread', 'diskiowrite', 'diskiopstotal', 'miniops', 'maxiops', 'path'],
       related: [{
         name: 'snapshot',
diff --git a/src/permission.js b/src/permission.js
index f73f09d..4d37e0d 100644
--- a/src/permission.js
+++ b/src/permission.js
@@ -69,7 +69,7 @@ router.beforeEach((to, from, next) => {
               description: 'Exception caught while discoverying features'
             })
             store.dispatch('Logout').then(() => {
-              next({ path: '/user/login', query: { redirect: to.fullPath } })
+              next({ path: '/user/login' })
             })
           })
       } else {
@@ -80,7 +80,7 @@ router.beforeEach((to, from, next) => {
     if (whiteList.includes(to.name)) {
       next()
     } else {
-      next({ path: '/user/login', query: { redirect: to.fullPath } })
+      next({ path: '/user/login' })
       NProgress.done()
     }
   }
diff --git a/src/store/modules/user.js b/src/store/modules/user.js
index 10c56db..3a0b054 100644
--- a/src/store/modules/user.js
+++ b/src/store/modules/user.js
@@ -128,10 +128,6 @@ const user = {
           // This will show the dashboard and some common navigation sections
           // to most users/roles, while we complete API autodiscovery
           const apis = {}
-          apis.listVirtualMachinesMetrics = {}
-          apis.listVolumesMetrics = {}
-          apis.listNetworks = {}
-          apis.listTemplates = {}
           apis.listUsers = {}
           apis.listAccounts = {}
           commit('SET_APIS', apis)
diff --git a/src/views/AutogenView.vue b/src/views/AutogenView.vue
index ab5bd9c..712967f 100644
--- a/src/views/AutogenView.vue
+++ b/src/views/AutogenView.vue
@@ -415,7 +415,12 @@ export default {
       if (this.$route && this.$route.meta && this.$route.meta.permission) {
         this.apiName = this.$route.meta.permission[0]
         if (this.$route.meta.columns) {
-          this.columnKeys = this.$route.meta.columns
+          const columns = this.$route.meta.columns
+          if (columns && typeof columns === 'function') {
+            this.columnKeys = columns()
+          } else {
+            this.columnKeys = columns
+          }
         }
 
         if (this.$route.meta.actions) {
diff --git a/src/views/dashboard/CapacityDashboard.vue b/src/views/dashboard/CapacityDashboard.vue
index 55b444b..01db271 100644
--- a/src/views/dashboard/CapacityDashboard.vue
+++ b/src/views/dashboard/CapacityDashboard.vue
@@ -24,6 +24,7 @@
             showSearch
             optionFilterProp="children"
             :defaultValue="zoneSelected.name"
+            :placeholder="$t('label.select.a.zone')"
             :value="zoneSelected.name"
             @change="changeZone">
             <a-select-option v-for="(zone, index) in zones" :key="index">
@@ -72,7 +73,7 @@
     </a-col>
 
     <a-col :xl="6">
-      <chart-card>
+      <chart-card :loading="loading">
         <div style="text-align: center">
           <a-tooltip placement="bottom" class="capacity-dashboard-button-wrapper">
             <template slot="title">
@@ -229,7 +230,7 @@ export default {
     listEvents () {
       const params = {
         page: 1,
-        pagesize: 7,
+        pagesize: 6,
         listall: true
       }
       this.loading = true
diff --git a/src/views/dashboard/UsageDashboard.vue b/src/views/dashboard/UsageDashboard.vue
index bde8d8c..01574b3 100644
--- a/src/views/dashboard/UsageDashboard.vue
+++ b/src/views/dashboard/UsageDashboard.vue
@@ -18,7 +18,7 @@
 <template>
   <a-row class="usage-dashboard" :gutter="12">
     <a-col :xl="16">
-      <a-row>
+      <a-row :gutter="12">
         <a-card>
           <a-tabs
             v-if="showProject"
@@ -44,21 +44,29 @@
             :md="8"
             v-for="stat in stats"
             :key="stat.type">
-            <chart-card class="usage-dashboard-chart-card" :loading="loading">
+            <a-card
+              class="usage-dashboard-chart-card"
+              :bordered="false"
+              :loading="loading"
+              :style="stat.bgcolor ? { 'background-color': stat.bgcolor } : {}">
               <router-link :to="{ name: stat.path }">
-                <div class="usage-dashboard-chart-card-inner">
-                  <h4>{{ stat.name }}</h4>
-                  <h1>{{ stat.count == undefined ? 0 : stat.count }}</h1>
+                <div
+                  class="usage-dashboard-chart-card-inner">
+                  <h3>{{ stat.name }}</h3>
+                  <h2>
+                    <a-icon :type="stat.icon" />
+                    {{ stat.count == undefined ? 0 : stat.count }}
+                  </h2>
                 </div>
               </router-link>
-            </chart-card>
+            </a-card>
           </a-col>
         </a-card>
       </a-row>
     </a-col>
     <a-col
       :xl="8">
-      <chart-card>
+      <chart-card :loading="loading" >
         <div class="usage-dashboard-chart-card-inner">
           <a-button>
             <router-link :to="{ name: 'event' }">
@@ -158,42 +166,42 @@ export default {
         if (json && json.listvirtualmachinesresponse) {
           count = json.listvirtualmachinesresponse.count
         }
-        this.stats.splice(0, 1, { name: this.$t('label.running'), count: count, path: 'vm' })
+        this.stats.splice(0, 1, { name: this.$t('label.running'), count: count, icon: 'desktop', bgcolor: '#dfe9cc', path: 'vm' })
       })
       api('listVirtualMachines', { state: 'Stopped', listall: true }).then(json => {
         var count = 0
         if (json && json.listvirtualmachinesresponse) {
           count = json.listvirtualmachinesresponse.count
         }
-        this.stats.splice(1, 1, { name: this.$t('label.stopped'), count: count, path: 'vm' })
+        this.stats.splice(1, 1, { name: this.$t('label.stopped'), count: count, icon: 'poweroff', bgcolor: '#edcbce', path: 'vm' })
       })
       api('listVirtualMachines', { listall: true }).then(json => {
         var count = 0
         if (json && json.listvirtualmachinesresponse) {
           count = json.listvirtualmachinesresponse.count
         }
-        this.stats.splice(2, 1, { name: this.$t('label.total.vms'), count: count, path: 'vm' })
+        this.stats.splice(2, 1, { name: this.$t('label.total.vms'), count: count, icon: 'number', path: 'vm' })
       })
       api('listVolumes', { listall: true }).then(json => {
         var count = 0
         if (json && json.listvolumesresponse) {
           count = json.listvolumesresponse.count
         }
-        this.stats.splice(3, 1, { name: 'Total Volumes', count: count, path: 'volume' })
+        this.stats.splice(3, 1, { name: 'Total Volumes', count: count, icon: 'database', path: 'volume' })
       })
       api('listNetworks', { listall: true }).then(json => {
         var count = 0
         if (json && json.listnetworksresponse) {
           count = json.listnetworksresponse.count
         }
-        this.stats.splice(4, 1, { name: 'Total Networks', count: count, path: 'guestnetwork' })
+        this.stats.splice(4, 1, { name: 'Total Networks', count: count, icon: 'apartment', path: 'guestnetwork' })
       })
       api('listPublicIpAddresses', { listall: true }).then(json => {
         var count = 0
         if (json && json.listpublicipaddressesresponse) {
           count = json.listpublicipaddressesresponse.count
         }
-        this.stats.splice(5, 1, { name: this.$t('label.public.ip.addresses'), count: count, path: 'publicip' })
+        this.stats.splice(5, 1, { name: this.$t('label.public.ip.addresses'), count: count, icon: 'environment', path: 'publicip' })
       })
       this.listEvents()
     },
diff --git a/src/views/dashboard/UsageDashboardChart.vue b/src/views/dashboard/UsageDashboardChart.vue
index b2244a9..711218e 100644
--- a/src/views/dashboard/UsageDashboardChart.vue
+++ b/src/views/dashboard/UsageDashboardChart.vue
@@ -23,14 +23,22 @@
       :md="8"
       v-for="stat in stats"
       :key="stat.type">
-      <chart-card class="usage-dashboard-chart-card" :loading="loading">
+      <a-card
+        class="usage-dashboard-chart-card"
+        :bordered="false"
+        :loading="loading"
+        :style="stat.bgcolor ? { 'background-color': stat.bgcolor } : {}">
         <router-link :to="{ name: stat.path }">
-          <div class="usage-dashboard-chart-card-inner">
-            <h4>{{ stat.name }}</h4>
-            <h1>{{ stat.count == undefined ? 0 : stat.count }}</h1>
+          <div
+            class="usage-dashboard-chart-card-inner">
+            <h3>{{ stat.name }}</h3>
+            <h2>
+              <a-icon :type="stat.icon" />
+              {{ stat.count == undefined ? 0 : stat.count }}
+            </h2>
           </div>
         </router-link>
-      </chart-card>
+      </a-card>
     </a-col>
   </div>
 </template>