SetSnapshotDialog.vue 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. <template>
  2. <base-dialog @cancel="cancelDialog">
  3. <div slot="header">{{$t('compute.disk_perform_setup_snapshot_policy')}}</div>
  4. <div slot="body">
  5. <a-alert class="mb-2" type="warning" :message="$t('compute.snapshotpolicy_bind_disk_tip')" />
  6. <dialog-selected-tips :count="params.data.length" :name="$t('dictionary.disk')" :action="$t('compute.disk_perform_setup_snapshot_policy')" />
  7. <dialog-table v-if="params.columns && params.columns.length" :data="params.data" :columns="[...params.columns.slice(0, 3), { field: 'guest_snapshotpolicy_count', title: $t('compute.guest_snapshotpolicy_count'), formatter: ({ row }) => { return row.guest_snapshotpolicy_count || 0 } }]" />
  8. <a-form
  9. :form="form.fc">
  10. <a-form-item :label="$t('compute.text_427')" v-bind="formItemLayout">
  11. <a-switch :checkedChildren="$t('compute.text_115')" :unCheckedChildren="$t('compute.text_116')" v-decorator="decorators.isOpen" />
  12. </a-form-item>
  13. <template v-if="enable">
  14. <a-form-item :label="$t('compute.text_428')" v-bind="formItemLayout">
  15. <a-row :gutter="8">
  16. <a-col :span="12">
  17. <a-select v-decorator="decorators.snapshotpolicy" :filterOption="filterOption" showSearch>
  18. <a-select-option v-for="item in snapshotpolicyOptions" :key="item.id">
  19. {{getPolicyLabel(item)}}
  20. </a-select-option>
  21. </a-select>
  22. </a-col>
  23. <a-col :span="12">
  24. <a-icon type="sync" class="mr-1" @click="refresh" />
  25. <!-- <router-link target="_blank" :to="{ path: '/snapshotpolicy' }" style="color: #409EFF;">{{$t('compute.text_429')}}</router-link> -->
  26. <dialog-trigger :vm="params.vm" :extParams="{ tenant, domain, types: ['disk'] }" :name="$t('compute.text_430')" value="CreateSnapshotPolicyDialog" resource="snapshotpolicies" @success="successCallback" />
  27. </a-col>
  28. </a-row>
  29. </a-form-item>
  30. <a-form-item :label="$t('compute.text_431')" v-bind="formItemLayout">
  31. <span class="ant-form-text">
  32. {{ weekTips }}
  33. </span>
  34. </a-form-item>
  35. <a-form-item :label="$t('compute.text_432')" v-bind="formItemLayout">
  36. <span class="ant-form-text">
  37. {{ timeTips }}
  38. </span>
  39. </a-form-item>
  40. <a-form-item :label="$t('compute.text_433')" v-bind="formItemLayout">
  41. <span class="ant-form-text">
  42. {{ dayTips }}
  43. </span>
  44. </a-form-item>
  45. </template>
  46. </a-form>
  47. </div>
  48. <div slot="footer">
  49. <a-button type="primary" @click="handleConfirm" :loading="loading">{{ $t('dialog.ok') }}</a-button>
  50. <a-button @click="cancelDialog">{{ $t('dialog.cancel') }}</a-button>
  51. </div>
  52. </base-dialog>
  53. </template>
  54. <script>
  55. import * as R from 'ramda'
  56. import DialogMixin from '@/mixins/dialog'
  57. import WindowsMixin from '@/mixins/windows'
  58. import { weekOptions, timeOptions } from '../../../constants'
  59. export default {
  60. name: 'DiskSetSnapshotDialog',
  61. mixins: [DialogMixin, WindowsMixin],
  62. data () {
  63. return {
  64. loading: false,
  65. scope: this.$store.getters.scope,
  66. form: {
  67. fc: this.$form.createForm(this, {
  68. onValuesChange: (props, values) => {
  69. if (values.hasOwnProperty('snapshotpolicy')) {
  70. this.assembly(values.snapshotpolicy)
  71. }
  72. if (values.hasOwnProperty('isOpen')) {
  73. this.enable = !this.enable
  74. if (values.isOpen === true && this.snapshotpolicyOptions.length) {
  75. this.$nextTick(function () {
  76. this.form.fc.setFieldsValue({ snapshotpolicy: this.snapshotpolicyOptions[0].id })
  77. })
  78. }
  79. }
  80. },
  81. }),
  82. },
  83. decorators: {
  84. isOpen: [
  85. 'isOpen',
  86. {
  87. valuePropName: 'checked',
  88. initialValue: this.params.data[0].snapshotpolicies && this.params.data[0].snapshotpolicies.length > 0,
  89. },
  90. ],
  91. snapshotpolicy: [
  92. 'snapshotpolicy',
  93. {
  94. initialValue: this.params.data[0].snapshotpolicies && this.params.data[0].snapshotpolicies.length ? this.params.data[0].snapshotpolicies[0].id : '',
  95. rules: [
  96. { required: true },
  97. ],
  98. },
  99. ],
  100. },
  101. formItemLayout: {
  102. labelCol: {
  103. sm: { span: 3 },
  104. },
  105. wrapperCol: {
  106. sm: { span: 21 },
  107. },
  108. },
  109. snapshotpolicyOptions: [],
  110. attchedPolices: this.params.data[0].snapshotpolicies && this.params.data[0].snapshotpolicies.length ? this.params.data[0].snapshotpolicies : [],
  111. weekTips: '',
  112. timeTips: '',
  113. dayTips: '',
  114. enable: this.params.data[0].snapshotpolicies && this.params.data[0].snapshotpolicies.length,
  115. }
  116. },
  117. computed: {
  118. domain () {
  119. return this.params.data[0].domain_id
  120. },
  121. tenant () {
  122. return this.params.data[0].tenant_id
  123. },
  124. },
  125. created () {
  126. this.fetchSnaphotpolicy().then(() => {
  127. if (this.params.data[0].snapshotpolicies && this.params.data[0].snapshotpolicies.length) {
  128. this.assembly(this.params.data[0].snapshotpolicies[0].id)
  129. }
  130. })
  131. this.manager = new this.$Manager('snapshotpolicies')
  132. },
  133. methods: {
  134. refresh () {
  135. this.fetchSnaphotpolicy()
  136. },
  137. detachPolicy (id) {
  138. return this.params.onManager('batchPerformAction', {
  139. id: this.params.data.map(item => item.id),
  140. steadyStatus: 'ready',
  141. managerArgs: {
  142. action: 'unbind-snapshotpolicy',
  143. data: {
  144. snapshotpolicy_id: id,
  145. },
  146. },
  147. })
  148. },
  149. detachPolices () {
  150. const promiseArr = this.attchedPolices.map(item => {
  151. return this.detachPolicy(item.id)
  152. })
  153. return Promise.all(promiseArr)
  154. },
  155. async handleConfirm () {
  156. this.loading = true
  157. try {
  158. const values = await this.form.fc.validateFields()
  159. this.loading = true
  160. if (this.enable) {
  161. await this.detachPolices()
  162. await this.params.onManager('performAction', {
  163. id: this.params.data[0].id,
  164. steadyStatus: 'ready',
  165. managerArgs: {
  166. action: 'set-snapshotpolicy',
  167. data: {
  168. snapshotpolicy_id: values.snapshotpolicy,
  169. },
  170. },
  171. })
  172. } else {
  173. if (this.attchedPolices.length) {
  174. await this.detachPolices()
  175. }
  176. }
  177. this.loading = false
  178. this.params.refresh()
  179. this.cancelDialog()
  180. } catch (error) {
  181. this.loading = false
  182. throw error
  183. }
  184. },
  185. getPolicyLabel (item) {
  186. let text = item.name
  187. if (item.repeat_weekdays && item.repeat_weekdays.length) {
  188. text += this.$t('compute.text_434') + item.repeat_weekdays.map(item => weekOptions[item - 1]).join('、')
  189. }
  190. if (item.time_points && item.time_points.length) {
  191. text += ',' + item.time_points.map(item => timeOptions[item]).join('、')
  192. }
  193. if (item.retention_days === -1) {
  194. text += this.$t('compute.text_435')
  195. } else if (item.retention_days) {
  196. text += this.$t('compute.text_436', [item.retention_days])
  197. }
  198. if (text.length > 24) {
  199. return text.substring(0, 24) + '...'
  200. }
  201. return text
  202. },
  203. async fetchSnaphotpolicy () {
  204. const manager = new this.$Manager('snapshotpolicies')
  205. const params = {
  206. scope: this.scope,
  207. type: 'disk',
  208. }
  209. if (this.params.data[0].manager_id) {
  210. params.manager_id = this.params.data[0].manager_id
  211. }
  212. if (this.params.data[0].cloud_env) {
  213. params.cloud_env = this.params.data[0].cloud_env
  214. }
  215. try {
  216. const res = await manager.list({ params })
  217. const data = res.data.data
  218. if (data && data.length) {
  219. this.snapshotpolicyOptions = data.filter((item) => {
  220. return item.status === 'available'
  221. })
  222. }
  223. } catch (error) {}
  224. },
  225. assembly (id) {
  226. const snapshotpolicyObj = R.indexBy(R.prop('id'), this.snapshotpolicyOptions)
  227. const selectItem = snapshotpolicyObj[id]
  228. this.weekTips = (
  229. selectItem.repeat_weekdays &&
  230. selectItem.repeat_weekdays.map(item => weekOptions[item - 1]).join('、')
  231. ) || '-'
  232. this.timeTips = (
  233. selectItem.time_points &&
  234. selectItem.time_points.map(item => timeOptions[item]).join('、')
  235. ) || '-'
  236. let ret = '-'
  237. if (selectItem.retention_count) {
  238. ret = `${this.$t('compute.retention_count_prefix')} ${selectItem.retention_count} ${this.$t('compute.retention_count_suffix')}`
  239. } else if (selectItem.retention_days === -1) {
  240. ret = this.$t('compute.text_437')
  241. } else if (selectItem.retention_days) {
  242. ret = this.$t('compute.text_438', [selectItem.retention_days])
  243. }
  244. this.dayTips = ret
  245. },
  246. async successCallback () {
  247. await this.fetchSnaphotpolicy()
  248. this.form.fc.setFieldsValue({ snapshotpolicy: this.snapshotpolicyOptions[0].id })
  249. },
  250. filterOption (input, option) {
  251. return (
  252. option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
  253. )
  254. },
  255. },
  256. }
  257. </script>