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 2019/12/20 00:01:43 UTC

[cloudstack-primate] branch master updated: autogen: implement action response handler notification framework

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


The following commit(s) were added to refs/heads/master by this push:
     new e7b0a2b  autogen: implement action response handler notification framework
e7b0a2b is described below

commit e7b0a2b9adb9e569bdf43a17d9c3771e76b8c3c2
Author: Rohit Yadav <ro...@shapeblue.com>
AuthorDate: Fri Dec 20 05:29:56 2019 +0530

    autogen: implement action response handler notification framework
    
    This fixes #35
    This fixes #51
    This closes #78
    
    This adds the following:
    - Download iso, template, volume handler to show link
    - Show VM password on VM start and upon reset password action
    
    Signed-off-by: Rohit Yadav <ro...@shapeblue.com>
---
 src/config/section/compute.js |  6 ++++--
 src/config/section/image.js   | 19 +++++++++++++++++--
 src/config/section/storage.js |  4 +++-
 src/utils/plugins.js          | 10 ++++++----
 src/views/AutogenView.vue     | 32 +++++++++++++++++++-------------
 5 files changed, 49 insertions(+), 22 deletions(-)

diff --git a/src/config/section/compute.js b/src/config/section/compute.js
index 0fcd458..4af84c7 100644
--- a/src/config/section/compute.js
+++ b/src/config/section/compute.js
@@ -81,7 +81,8 @@ export default {
           dataView: true,
           groupAction: true,
           show: (record) => { return ['Stopped'].includes(record.state) },
-          args: ['podid', 'clusterid', 'hostid']
+          args: ['podid', 'clusterid', 'hostid'],
+          response: (result) => { return result.virtualmachine && result.virtualmachine.password ? `Password of the VM is ${result.virtualmachine.password}` : null }
         },
         {
           api: 'stopVirtualMachine',
@@ -214,7 +215,8 @@ export default {
           icon: 'key',
           label: 'Reset Instance Password',
           dataView: true,
-          show: (record) => { return ['Stopped'].includes(record.state) }
+          show: (record) => { return ['Stopped'].includes(record.state) },
+          response: (result) => { return result.virtualmachine && result.virtualmachine.password ? `Password of the VM is ${result.virtualmachine.password}` : null }
         },
         {
           api: 'resetSSHKeyForVirtualMachine',
diff --git a/src/config/section/image.js b/src/config/section/image.js
index e00de65..f4005ea 100644
--- a/src/config/section/image.js
+++ b/src/config/section/image.js
@@ -72,7 +72,17 @@ export default {
           icon: 'cloud-download',
           label: 'Download Template',
           dataView: true,
-          args: ['zoneid', 'mode']
+          show: (record) => { return record && record.isextractable },
+          args: ['zoneid', 'mode'],
+          mapping: {
+            zoneid: {
+              value: (record) => { return record.zoneid }
+            },
+            mode: {
+              value: (record) => { return 'HTTP_DOWNLOAD' }
+            }
+          },
+          response: (result) => { return `Please click <a href="${result.template.url}" target="_blank">${result.template.url}</a> to download.` }
         },
         {
           api: 'updateTemplatePermissions',
@@ -140,12 +150,17 @@ export default {
           icon: 'cloud-download',
           label: 'Download ISO',
           dataView: true,
+          show: (record) => { return record && record.isextractable },
           args: ['zoneid', 'mode'],
           mapping: {
+            zoneid: {
+              value: (record) => { return record.zoneid }
+            },
             mode: {
               value: (record) => { return 'HTTP_DOWNLOAD' }
             }
-          }
+          },
+          response: (result) => { return `Please click <a href="${result.iso.url}" target="_blank">${result.iso.url}</a> to download.` }
         },
         {
           api: 'updateIsoPermissions',
diff --git a/src/config/section/storage.js b/src/config/section/storage.js
index 51e8383..22b1bd6 100644
--- a/src/config/section/storage.js
+++ b/src/config/section/storage.js
@@ -133,6 +133,7 @@ export default {
           icon: 'cloud-download',
           label: 'Download Volume',
           dataView: true,
+          show: (record) => { return record && record.state === 'Ready' },
           args: ['zoneid', 'mode'],
           mapping: {
             zoneid: {
@@ -141,7 +142,8 @@ export default {
             mode: {
               value: (record) => { return 'HTTP_DOWNLOAD' }
             }
-          }
+          },
+          response: (result) => { return `Please click <a href="${result.volume.url}" target="_blank">${result.volume.url}</a> to download.` }
         },
         {
           api: 'createTemplate',
diff --git a/src/utils/plugins.js b/src/utils/plugins.js
index 0204916..c0081e0 100644
--- a/src/utils/plugins.js
+++ b/src/utils/plugins.js
@@ -32,6 +32,7 @@ export const pollJobPlugin = {
        * @param {String} [catchMessage=Error caught]
        * @param {Function} [catchMethod=() => {}]
        * @param {Number} [loadingDuration=3]
+       * @param {Object} [action=null]
        */
       const {
         jobId,
@@ -42,7 +43,8 @@ export const pollJobPlugin = {
         loadingMessage = 'Loading...',
         catchMessage = 'Error caught',
         catchMethod = () => {},
-        loadingDuration = 3
+        loadingDuration = 3,
+        action = null
       } = options
 
       api('queryAsyncJobResult', { jobId }).then(json => {
@@ -50,17 +52,17 @@ export const pollJobPlugin = {
 
         if (result.jobstatus === 1) {
           message.success(successMessage)
-          successMethod()
+          successMethod(result)
         } else if (result.jobstatus === 2) {
           notification.error({
             message: errorMessage,
             description: result.jobresult.errortext
           })
-          errorMethod()
+          errorMethod(result)
         } else if (result.jobstatus === 0) {
           message
             .loading(loadingMessage, loadingDuration)
-            .then(() => this.$pollJob(options))
+            .then(() => this.$pollJob(options, action))
         }
       }).catch(e => {
         console.error(`${catchMessage} - ${e}`)
diff --git a/src/views/AutogenView.vue b/src/views/AutogenView.vue
index 1a2f551..f18459f 100644
--- a/src/views/AutogenView.vue
+++ b/src/views/AutogenView.vue
@@ -243,6 +243,7 @@
 <script>
 import { api } from '@/api'
 import { mixinDevice } from '@/utils/mixin.js'
+import { genericCompare } from '@/utils/sort.js'
 import config from '@/config/settings'
 import store from '@/store'
 
@@ -252,7 +253,6 @@ import Status from '@/components/widgets/Status'
 import ListView from '@/components/view/ListView'
 import ResourceView from '@/components/view/ResourceView'
 import TreeView from '@/components/view/TreeView'
-import { genericCompare } from '@/utils/sort.js'
 
 export default {
   name: 'Resource',
@@ -577,19 +577,25 @@ export default {
       })
     },
     pollActionCompletion (jobId, action) {
-      api('queryAsyncJobResult', { jobid: jobId }).then(json => {
-        var result = json.queryasyncjobresultresponse
-        if (result.jobstatus === 1) {
-          this.fetchData()
-        } else if (result.jobstatus === 2) {
+      this.$pollJob({
+        jobId,
+        successMethod: result => {
           this.fetchData()
-        } else if (result.jobstatus === 0) {
-          this.$message
-            .loading(this.$t(action.label) + ' in progress for ' + this.resource.name, 3)
-            .then(() => this.pollActionCompletion(jobId, action))
-        }
-      }).catch(function (e) {
-        console.log('Error encountered while fetching async job result' + e)
+          if (action.response) {
+            const description = action.response(result.jobresult)
+            if (description) {
+              this.$notification.info({
+                message: action.label,
+                description: (<span domPropsInnerHTML={description}></span>),
+                duration: 0
+              })
+            }
+          }
+        },
+        errorMethod: () => this.fetchData(),
+        loadingMessage: `${this.$t(action.label)} in progress for ${this.resource.name}`,
+        catchMessage: 'Error encountered while fetching async job result',
+        action
       })
     },
     handleSubmit (e) {