rhtyd commented on a change in pull request #110: [WIP] - Take Volume Snapshot 
Action
URL: https://github.com/apache/cloudstack-primate/pull/110#discussion_r366790200
 
 

 ##########
 File path: src/views/storage/TakeSnapshot.vue
 ##########
 @@ -0,0 +1,264 @@
+<template>
+  <div class="tak-snapshot">
+    <a-spin :spinning="loading || actionLoading">
+      <label>
+        {{ $t('label.header.volume.take.snapshot') }}
+      </label>
+      <a-form
+        class="form"
+        :form="form"
+        layout="vertical"
+        @submit="handleSubmit">
+        <a-row :gutter="12">
+          <a-col :md="24" :lg="24">
+            <a-form-item :label="$t('name')">
+              <a-input
+                v-decorator="['name']"
+                :placeholder="apiParams.name.description" />
+            </a-form-item>
+          </a-col>
+          <a-col :md="24" :lg="24">
+            <a-form-item :label="$t('asyncbackup')">
+              <a-switch v-decorator="['asyncbackup']" />
+            </a-form-item>
+          </a-col>
+          <a-col :md="24" :lg="24" v-if="quiescevm">
+            <a-form-item :label="$t('quiescevm')">
+              <a-switch v-decorator="['quiescevm']" />
+            </a-form-item>
+          </a-col>
+        </a-row>
+        <a-divider/>
+        <div class="tagsTitle">{{ $t('tags') }}</div>
+        <div>
+          <template v-for="(tag, index) in tags">
+            <a-tag :key="index" :closable="true">
+              {{ tag.key }} = {{ tag.value }}
+            </a-tag>
+          </template>
+          <div v-if="inputVisible">
+            <a-input-group
+              type="text"
+              size="small"
+              @blur="handleInputConfirm"
+              @keyup.enter="handleInputConfirm"
+              compact>
+              <a-input ref="input" :value="inputKey" @change="handleKeyChange" 
style="width: 100px; text-align: center" placeholder="Key" />
+              <a-input style=" width: 30px; border-left: 0; pointer-events: 
none; backgroundColor: #fff" placeholder="=" disabled />
+              <a-input :value="inputValue" @change="handleValueChange" 
style="width: 100px; text-align: center; border-left: 0" placeholder="Value" />
+              <a-button shape="circle" size="small" 
@click="handleInputConfirm">
+                <a-icon type="check"/>
+              </a-button>
+              <a-button shape="circle" size="small" 
@click="inputVisible=false">
+                <a-icon type="close"/>
+              </a-button>
+            </a-input-group>
+          </div>
+          <a-tag v-else @click="showInput" style="background: #fff; 
borderStyle: dashed;">
+            <a-icon type="plus" /> {{ $t('label.new.tag') }}
+          </a-tag>
+        </div>
+        <div :span="24" class="action-button">
+          <a-button
+            :loading="actionLoading"
+            @click="closeAction">
+            {{ this.$t('Cancel') }}
+          </a-button>
+          <a-button
+            v-if="handleShowButton()"
+            :loading="actionLoading"
+            type="primary"
+            @click="handleSubmit">
+            {{ this.$t('OK') }}
+          </a-button>
+        </div>
+      </a-form>
+    </a-spin>
+  </div>
+</template>
+
+<script>
+import { api } from '@/api'
+
+export default {
+  name: 'TakeSnapshot',
+  props: {
+    loading: {
+      type: Boolean,
+      default: false
+    },
+    resource: {
+      type: Object,
+      required: true
+    }
+  },
+  data () {
+    return {
+      actionLoading: false,
+      quiescevm: false,
+      inputValue: '',
+      inputKey: '',
+      inputVisible: '',
+      tags: [],
+      dataSource: []
+    }
+  },
+  beforeCreate () {
+    this.form = this.$form.createForm(this)
+    this.apiConfig = this.$store.getters.apis.createSnapshot || {}
+    this.apiParams = {}
+    this.apiConfig.params.forEach(param => {
+      this.apiParams[param.name] = param
+    })
+  },
+  mounted () {
+    this.quiescevm = this.resource.quiescevm
+  },
+  methods: {
+    handleSubmit (e) {
+      e.preventDefault()
+      this.form.validateFields((error, values) => {
+        if (error) {
+          return
+        }
+
+        let params = {}
+        params.volumeId = this.resource.id
+        if (values.name) {
+          params.name = values.name
+        }
+        params.asyncBackup = false
+        if (values.asyncbackup) {
+          params.asyncBackup = values.asyncbackup
+        }
+        params.quiescevm = false
+        if (values.quiescevm) {
+          params.quiescevm = values.quiescevm
+        }
+        for (let i = 0; i < this.tags.length; i++) {
+          const formattedTagData = {}
+          const tag = this.tags[i]
+          formattedTagData['tags[' + i + '].key'] = tag.key
+          formattedTagData['tags[' + i + '].value'] = tag.value
+          params = Object.assign({}, params, formattedTagData)
+        }
+
+        this.actionLoading = true
+        const title = this.$t('label.action.take.snapshot')
+        const description = this.$t('volume') + ' ' + this.resource.id
+        const loading = this.$message.loading(title + 'in progress for ' + 
description, 0)
+        api('createSnapshot', params).then(json => {
+          this.checkForAddAsyncJob(json, title, description)
+          this.closeAction()
+        }).catch(error => {
+          this.$notification.error({
+            message: 'Request Failed',
+            description: (error.response && error.response.headers && 
error.response.headers['x-description']) || error.message
+          })
+        }).finally(() => {
+          this.actionLoading = false
+          setTimeout(loading, 1000)
+        })
+      })
+    },
+    handleVisibleInterval (intervalType) {
+      if (this.dataSource.length === 0) {
+        return false
+      }
+      const dataSource = this.dataSource.filter(item => item.intervaltype === 
intervalType)
+      if (dataSource && dataSource.length > 0) {
+        return true
+      }
+      return false
+    },
+    handleShowButton () {
+      if (this.dataSource.length === 0) {
+        return true
+      }
+      const dataSource = this.dataSource.filter(item => item.intervaltype === 
this.intervalValue)
+      if (dataSource && dataSource.length > 0) {
+        return false
+      }
+      return true
+    },
+    handleKeyChange (e) {
+      this.inputKey = e.target.value
+    },
+    handleValueChange (e) {
+      this.inputValue = e.target.value
+    },
+    handleInputConfirm () {
+      this.tags.push({
+        key: this.inputKey,
+        value: this.inputValue
+      })
+      this.inputVisible = false
+      this.inputKey = ''
+      this.inputValue = ''
+    },
+    checkForAddAsyncJob (json, title, description) {
+      let hasJobId = false
+
+      for (const obj in json) {
+        if (obj.includes('response')) {
+          for (const res in json[obj]) {
+            if (res === 'jobid') {
+              hasJobId = true
+              const jobId = json[obj][res]
+              this.$store.dispatch('AddAsyncJob', {
+                title: title,
+                jobid: jobId,
+                description: description,
+                status: 'progress'
+              })
 
 Review comment:
   Add break here. 
   

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services

Reply via email to