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

 ##########
 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'
+              })
+            }
+          }
+        }
+      }
+
+      return hasJobId
+    },
+    showInput () {
+      this.inputVisible = true
+      this.$nextTick(function () {
+        this.$refs.input.focus()
+      })
+    },
+    closeAction () {
+      this.$emit('close-action')
+    }
+  }
+}
+</script>
+
+<style lang="less" scoped>
+.form {
+  margin-top: 10px;
+}
+
+.tak-snapshot {
+  min-width: 500px;
 
 Review comment:
   Use this:
   ```
   -.tak-snapshot {
   -  min-width: 500px;
   +.take-snapshot {
   +  width: 85vw;
   +
   +  @media (min-width: 760px) {
   +    width: 500px;
   +  }
   
   ```

----------------------------------------------------------------
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