Create.vue 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. <template>
  2. <base-dialog @cancel="cancelDialog">
  3. <div slot="header">{{this.params.title}}</div>
  4. <div slot="body">
  5. <a-alert type="warning" class="mb-4">
  6. <div slot="message" v-if="showDocsLink()">{{ $t('storage.local_storage.help_alert_message') }}<help-link :href="localStorageUrl">{{ $t('storage.local_storage.help_link') }}</help-link></div>
  7. <div slot="message" v-else>{{ $t('storage.local_storage.help_alert_message_1') }}</div>
  8. </a-alert>
  9. <a-form :form="form.fc" v-bind="formItemLayout">
  10. <a-form-item :label="$t('storage.text_55', [$t('dictionary.domain')])">
  11. <domain-select v-if="isAdminMode && l3PermissionEnable" v-decorator="decorators.project_domain" />
  12. <template v-else> {{userInfo.domain.name}} </template>
  13. </a-form-item>
  14. <a-form-item :label="$t('storage.text_47')">
  15. <cloudregion-zone
  16. :cloudregionParams="{cloud_env: 'onpremise'}"
  17. :decorator="decorators.regionZone"
  18. filterBrandResource="loadbalancer_engine" />
  19. </a-form-item>
  20. <a-form-item :label="$t('storage.text_40')">
  21. <a-input :placeholder="$t('storage.text_56')" v-decorator="decorators.name" />
  22. </a-form-item>
  23. <a-form-item :label="$t('common.description')">
  24. <a-textarea :auto-size="{ minRows: 1, maxRows: 3 }" v-decorator="decorators.description" :placeholder="$t('common_367')" />
  25. </a-form-item>
  26. <a-form-item :label="$t('storage.text_39')">
  27. <a-radio-group v-decorator="decorators.medium_type" buttonStyle="solid">
  28. <a-radio-button v-for="(v, k) in MEDIUM_TYPES" :key="v" :value="k">{{v}}</a-radio-button>
  29. </a-radio-group>
  30. </a-form-item>
  31. <a-form-item :label="$t('storage.text_38')">
  32. <a-radio-group v-decorator="decorators.storage_type" buttonStyle="solid">
  33. <template v-for="(v, k) in STORAGE_TYPES">
  34. <a-radio-button v-if="storageTypes.indexOf(k) > -1" :key="k" :value="k">{{v}}</a-radio-button>
  35. </template>
  36. </a-radio-group>
  37. </a-form-item>
  38. <form-items :storage_type="getFieldValue('storage_type')" />
  39. <a-form-item :label="$t('common.text00012')" class="mb-0">
  40. <tag
  41. v-decorator="decorators.__meta__" :allowNoValue="false" />
  42. </a-form-item>
  43. </a-form>
  44. </div>
  45. <div slot="footer">
  46. <a-button type="primary" @click="handleConfirm" :loading="loading">{{ $t("dialog.ok") }}</a-button>
  47. <a-button @click="cancelDialog">{{ $t('dialog.cancel') }}</a-button>
  48. </div>
  49. </base-dialog>
  50. </template>
  51. <script>
  52. import { mapGetters } from 'vuex'
  53. import { MEDIUM_TYPES, STORAGE_TYPES, formItemLayout } from '@Storage/constants/index.js'
  54. import FormItems from '@Storage/views/blockstorage/components/FormItems'
  55. import DialogMixin from '@/mixins/dialog'
  56. import WindowsMixin from '@/mixins/windows'
  57. import CloudregionZone from '@/sections/CloudregionZone'
  58. import DomainSelect from '@/sections/DomainSelect'
  59. import Tag from '@/sections/Tag'
  60. import validateForm from '@/utils/validate'
  61. import { DOCS_MAP, showDocsLink } from '@/constants/docs'
  62. export default {
  63. name: 'BlockStorageCreateDialog',
  64. components: {
  65. CloudregionZone,
  66. FormItems,
  67. DomainSelect,
  68. Tag,
  69. },
  70. mixins: [DialogMixin, WindowsMixin],
  71. provide () {
  72. return {
  73. form: this.form,
  74. }
  75. },
  76. data () {
  77. return {
  78. showDocsLink,
  79. MEDIUM_TYPES,
  80. STORAGE_TYPES,
  81. loading: false,
  82. form: {
  83. fc: this.$form.createForm(this, {
  84. onValuesChange: (props, values) => {
  85. Object.keys(values).forEach((key) => {
  86. this.form.fd[key] = values[key]
  87. })
  88. },
  89. }),
  90. fd: {
  91. storage_type: 'rbd',
  92. },
  93. },
  94. formItemLayout,
  95. }
  96. },
  97. computed: {
  98. ...mapGetters(['isAdminMode', 'userInfo', 'l3PermissionEnable']),
  99. storageTypes () {
  100. return this.params.storageTypes || ['rbd', 'slvm', 'nfs', 'gpfs', 'local']
  101. },
  102. getFieldValue () {
  103. return this.form.fc.getFieldValue
  104. },
  105. decorators () {
  106. return {
  107. name: [
  108. 'name',
  109. {
  110. validateFirst: true,
  111. rules: [
  112. { required: true, message: this.$t('storage.text_56') },
  113. { validator: this.$validate('blockStorageName') },
  114. ],
  115. },
  116. ],
  117. description: ['description'],
  118. regionZone: {
  119. cloudregion: [
  120. 'cloudregion',
  121. {
  122. initialValue: { key: '', label: '' },
  123. rules: [
  124. { required: true, message: this.$t('storage.text_57') },
  125. ],
  126. },
  127. ],
  128. zone: [
  129. 'zone',
  130. {
  131. initialValue: { key: '', label: '' },
  132. rules: [
  133. { required: true, message: this.$t('storage.text_58') },
  134. ],
  135. },
  136. ],
  137. },
  138. medium_type: [
  139. 'medium_type',
  140. {
  141. initialValue: 'rotate',
  142. },
  143. ],
  144. storage_type: [
  145. 'storage_type',
  146. {
  147. initialValue: 'rbd',
  148. },
  149. ],
  150. project_domain: [
  151. 'project_domain',
  152. {
  153. initialValue: this.userInfo.projectDomainId,
  154. },
  155. ],
  156. __meta__: [
  157. '__meta__',
  158. {
  159. rules: [
  160. { validator: validateForm('tagName') },
  161. ],
  162. },
  163. ],
  164. }
  165. },
  166. isLocalStorage () {
  167. return this.form.fd.storage_type === 'local'
  168. },
  169. localStorageUrl () {
  170. return DOCS_MAP.blockStorage()
  171. },
  172. },
  173. methods: {
  174. validateForm () {
  175. return new Promise((resolve, reject) => {
  176. this.form.fc.validateFields((err, values) => {
  177. if (err) return reject(err)
  178. // eslint-disable-next-line camelcase
  179. const { storage_type, zone, cloudregion, slvm_vg_name } = values
  180. const deleteRbdKeys = ['nfs_host', 'nfs_shared_dir']
  181. const deleteNfsKeys = ['rbd_mon_host', 'rbd_key', 'rbd_pool']
  182. const deleteSlvmKeys = [...deleteRbdKeys, ...deleteNfsKeys]
  183. const deleteKeys = {
  184. rbd: [...deleteRbdKeys, 'slvm_vg_name'],
  185. slvm: deleteSlvmKeys,
  186. nfs: [...deleteNfsKeys, 'slvm_vg_name'],
  187. gpfs: [...deleteRbdKeys, ...deleteNfsKeys, 'slvm_vg_name'],
  188. }
  189. if (zone) {
  190. values.zone = zone.key
  191. }
  192. if (cloudregion) {
  193. values.area = cloudregion.key
  194. delete values.cloudregion
  195. }
  196. if (slvm_vg_name) {
  197. values.lvmlockd = true
  198. }
  199. deleteKeys[storage_type].forEach(key => {
  200. delete values[key]
  201. })
  202. resolve(Object.assign({}, { capacity: 0 }, values))
  203. })
  204. })
  205. },
  206. async handleConfirm () {
  207. this.loading = true
  208. try {
  209. const values = await this.validateForm()
  210. const manager = new this.$Manager('storages', 'v2')
  211. await manager.create({ data: values })
  212. this.cancelDialog()
  213. this.params.refresh()
  214. } catch (error) {
  215. this.loading = false
  216. throw error
  217. }
  218. },
  219. },
  220. }
  221. </script>