VmChangeBootIndex.vue 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. <template>
  2. <base-dialog @cancel="cancelDialog">
  3. <div slot="header">{{$t('compute.change_boot_index')}}</div>
  4. <div slot="body">
  5. <dialog-selected-tips :name="$t('dictionary.server')" :count="params.data.length" :action="$t('compute.change_boot_index')" />
  6. <dialog-table :data="params.data" :columns="params.columns.slice(0, 3)" />
  7. <div class="d-flex">
  8. <div class="form-label mt-2">{{$t('compute.boot_index')}}:</div>
  9. <draggable
  10. style="flex: 1 1 auto"
  11. handle=".drag-icon"
  12. ghost-class="ghost"
  13. v-model="boots">
  14. <transition-group type="transition" name="flip-list">
  15. <div class="checkbox-item d-flex" v-for="item in boots" :key="item">
  16. <div class="d-flex" style="flex: 1 1 auto">
  17. <div class="type-label">{{typesMap[item.type].label}}</div>
  18. <div class="type-name">{{item.name}}</div>
  19. </div>
  20. <a-icon type="drag" class="drag-icon" style="font-size:18px" @click="iconClick" />
  21. </div>
  22. </transition-group>
  23. </draggable>
  24. </div>
  25. </div>
  26. <div slot="footer">
  27. <a-button type="primary" @click="handleConfirm" :loading="loading">{{ $t('dialog.ok') }}</a-button>
  28. <a-button @click="cancelDialog">{{ $t('dialog.cancel') }}</a-button>
  29. </div>
  30. </base-dialog>
  31. </template>
  32. <script>
  33. import draggable from 'vuedraggable'
  34. import DialogMixin from '@/mixins/dialog'
  35. import WindowsMixin from '@/mixins/windows'
  36. import { sizestr } from '@/utils/utils'
  37. export default {
  38. name: 'VmChangeBootIndexDialog',
  39. components: {
  40. draggable,
  41. },
  42. mixins: [DialogMixin, WindowsMixin],
  43. data () {
  44. return {
  45. typesMap: {
  46. cdrom: {
  47. label: this.$t('compute.text_1273'),
  48. },
  49. data: {
  50. label: this.$t('compute.text_50'),
  51. },
  52. sys: {
  53. label: this.$t('compute.text_49'),
  54. },
  55. },
  56. boots: [],
  57. loading: false,
  58. }
  59. },
  60. created () {
  61. this.initBoots()
  62. },
  63. methods: {
  64. initBoots () {
  65. const { disks_info = [], cdrom = [] } = this.params.data[0] || {}
  66. const ret = []
  67. disks_info.map(item => {
  68. ret.push({
  69. type: item.disk_type,
  70. name: `${item.name} (${sizestr(item.size || 0, 'M', 1024)})`,
  71. size: item.size,
  72. boot_index: item.boot_index,
  73. index: item.index,
  74. })
  75. })
  76. cdrom.map(item => {
  77. ret.push({
  78. type: 'cdrom',
  79. name: item.detail,
  80. boot_index: item.boot_index,
  81. ordinal: item.ordinal,
  82. })
  83. })
  84. ret.sort((a, b) => {
  85. return a.boot_index - b.boot_index
  86. })
  87. this.boots = ret
  88. },
  89. async handleConfirm () {
  90. this.loading = true
  91. try {
  92. const data = { disks: {}, cdroms: {} }
  93. this.boots.map((item, index) => {
  94. if (item.type === 'cdrom') {
  95. data.cdroms[item.ordinal + ''] = index
  96. } else {
  97. data.disks[item.index + ''] = index
  98. }
  99. })
  100. await this.params.onManager('performAction', {
  101. id: this.params.data[0].id,
  102. managerArgs: {
  103. action: 'set-boot-index',
  104. data,
  105. },
  106. })
  107. this.loading = false
  108. this.cancelDialog()
  109. } catch (error) {
  110. this.loading = false
  111. }
  112. },
  113. iconClick (e) {
  114. e.preventDefault()
  115. },
  116. },
  117. }
  118. </script>
  119. <style lang="less" scoped>
  120. @import '@/styles/less/theme.less';
  121. .tag-fields-wrap {
  122. max-height: 100px;
  123. overflow: auto;
  124. }
  125. .checkbox-item {
  126. position: relative;
  127. padding: 5px 0;
  128. margin-bottom: 10px;
  129. background: #eee;
  130. ::v-deep {
  131. .checkbox-property {
  132. padding-right: 15px;
  133. }
  134. }
  135. .type-label {
  136. flex: 0 0 80px;
  137. background: var(--antd-wave-shadow-color);
  138. color: #fff;
  139. text-align: center;
  140. height: 25px;
  141. line-height: 25px;
  142. max-height: 25px;
  143. margin: 0 5px;
  144. font-size: 12px;
  145. }
  146. .type-name {
  147. line-height: 25px;
  148. padding-right: 20px;
  149. white-space: wrap;
  150. word-break: wrap;
  151. }
  152. }
  153. .flip-list-move {
  154. transition: transform 0.5s;
  155. }
  156. .drag-icon {
  157. position: absolute;
  158. right: 10px;
  159. cursor: move;
  160. top: 50%;
  161. transform: translateY(-50%);
  162. }
  163. .ghost {
  164. opacity: 0.7;
  165. background: @primary-color;
  166. ::v-deep {
  167. label span {
  168. color: #fff;
  169. }
  170. }
  171. }
  172. .form-label {
  173. flex: 0 0 100px;
  174. }
  175. </style>