MergeMirror.vue 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. <template>
  2. <base-dialog @cancel="cancelDialog">
  3. <div slot="header">{{ $t('compute.image.merge_mirror') }}</div>
  4. <div slot="body">
  5. <dialog-selected-tips :name="$t('common_238')" :count="params.data.length" :action="$t('compute.image.merge_mirror')" />
  6. <dialog-table :data="params.data" :columns="columns" />
  7. <a-form
  8. :form="form.fc"
  9. v-bind="formItemLayout">
  10. <a-form-item :label="$t('compute.text_228')" :extra="$t('compute.image.merge_mirror.extra')">
  11. <a-input v-decorator="decorators.name" :placeholder="$t('compute.image.merge_mirror.placeholder')" />
  12. </a-form-item>
  13. <a-form-item :label="$t('compute.image.merge_mirror.order')" :extra="$t('compute.image.merge_mirror.order_extra')">
  14. <draggable
  15. handle=".drag-icon"
  16. chosen-class="chosen"
  17. v-model="images">
  18. <transition-group type="transition" name="flip-list">
  19. <template v-for="item of images">
  20. <div class="item" :key="item.id">
  21. <a-icon type="drag" class="drag-icon pr-3" @click.prevent="() => {}" />{{item.name}}
  22. </div>
  23. </template>
  24. </transition-group>
  25. </draggable>
  26. </a-form-item>
  27. </a-form>
  28. </div>
  29. <div slot="footer">
  30. <a-button type="primary" @click="handleConfirm" :loading="loading">{{ $t('dialog.ok') }}</a-button>
  31. <a-button @click="cancelDialog">{{ $t('dialog.cancel') }}</a-button>
  32. </div>
  33. </base-dialog>
  34. </template>
  35. <script>
  36. import draggable from 'vuedraggable'
  37. import DialogMixin from '@/mixins/dialog'
  38. import WindowsMixin from '@/mixins/windows'
  39. export default {
  40. name: 'MergeMirrorDialog',
  41. components: {
  42. draggable,
  43. },
  44. mixins: [DialogMixin, WindowsMixin],
  45. data () {
  46. return {
  47. loading: false,
  48. formItemLayout: {
  49. wrapperCol: {
  50. span: 21,
  51. },
  52. labelCol: {
  53. span: 3,
  54. },
  55. },
  56. form: {
  57. fc: this.$form.createForm(this, {
  58. onValuesChange: (props, values) => {
  59. Object.keys(values).forEach((key) => {
  60. this.$set(this.form.fd, key, values[key])
  61. })
  62. },
  63. }),
  64. fd: {},
  65. },
  66. decorators: {
  67. name: [
  68. 'name',
  69. {
  70. validateFirst: true,
  71. rules: [
  72. { required: true, message: this.$t('compute.text_660') },
  73. { validator: this.$validate('imageName') },
  74. ],
  75. },
  76. ],
  77. },
  78. images: [],
  79. }
  80. },
  81. computed: {
  82. columns () {
  83. return this.params.columns.filter(item => ['name', 'tenant'].includes(item.field))
  84. },
  85. },
  86. created () {
  87. this.init()
  88. },
  89. methods: {
  90. init () {
  91. this.images = this.params.data.map((item, index) => {
  92. return {
  93. order: item.is_data ? index : -1,
  94. ...item,
  95. }
  96. })
  97. this.images.sort((a, b) => a.order - b.order)
  98. },
  99. doAction (data) {
  100. return new this.$Manager('guestimages', 'v1').create({ data })
  101. },
  102. async handleConfirm () {
  103. this.loading = true
  104. try {
  105. const values = await this.form.fc.validateFields()
  106. const data = { images: this.images, name: values.name }
  107. await this.doAction(data)
  108. this.cancelDialog()
  109. this.params.refresh()
  110. } catch (error) {
  111. throw error
  112. } finally {
  113. this.loading = false
  114. }
  115. },
  116. onMoveHandle (e) {
  117. const { is_data } = e.draggedContext.element
  118. if (is_data && e.relatedContext.index === 0) return false
  119. if (this.images && this.images.length > 1) {
  120. if (e.draggedContext.index === 0 && this.images[1].is_data) return false
  121. }
  122. },
  123. },
  124. }
  125. </script>
  126. <style lang="scss" scoped>
  127. .item {
  128. padding: 0 10px;
  129. background-color: #fdfdfd;
  130. border: solid 1px #eee;
  131. margin-bottom: 10px;
  132. }
  133. .item:hover {
  134. background-color: #f1f1f1;
  135. }
  136. .chosen {
  137. border: solid 1px #1890ff !important;
  138. }
  139. </style>