ImageSelectTemplate.vue 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. <template>
  2. <a-select label-in-value :value="value" :loading="loading" @change="imageChange" :filterOption="filterOption" :showSearch="true" option-filter-prop="children" :placeholder="$t('compute.text_214')" allowClear>
  3. <a-select-option v-for="item in imageOptions" :key="item.id" :value="item.id">
  4. <div :key="`${item.name} ${item.id}`">
  5. <a-row>
  6. <a-col :span="24">
  7. <div>{{ item.name }}<a-icon type="safety-certificate" v-if="isEncryped(item)" :title="$t('common.text.encrption_enable')" /></div>
  8. </a-col>
  9. </a-row>
  10. <a-row>
  11. <a-col :span="16">
  12. <div class="oc-selected-display-none text-color-secondary over-hidden" v-if="showExternalId && item.external_id">{{ $t('compute.text_1346') }}: {{ item.external_id }}</div>
  13. </a-col>
  14. <a-col :span="8" align="right">
  15. <div class="oc-selected-display-none text-color-secondary" style="text-align: right;">
  16. {{ imgLabels(item) }}
  17. </div>
  18. </a-col>
  19. </a-row>
  20. </div>
  21. <!-- <div class="d-flex align-items-center">
  22. <span class="flex-fill mr-2">{{ item.name }}</span>
  23. <a-tag v-show="item.feData.cached" color="green">{{$t('compute.text_152')}}</a-tag>
  24. </div> -->
  25. </a-select-option>
  26. </a-select>
  27. </template>
  28. <script>
  29. import * as R from 'ramda'
  30. import _ from 'lodash'
  31. import { IMAGES_TYPE_MAP } from '@/constants/compute'
  32. import { sizestr } from '@/utils/utils'
  33. export default {
  34. name: 'ImageSelectTemplate',
  35. props: {
  36. value: {
  37. },
  38. imageOpts: {
  39. type: Array,
  40. default: () => [],
  41. },
  42. loading: {
  43. type: Boolean,
  44. default: false,
  45. },
  46. imageType: {
  47. type: String,
  48. required: true,
  49. },
  50. },
  51. computed: {
  52. imageOptions () {
  53. return this.imageOpts.filter((item) => { return !item.hidden })
  54. },
  55. showExternalId () {
  56. const showExternalIdList = [IMAGES_TYPE_MAP.public.key, IMAGES_TYPE_MAP.public_customize.key]
  57. if (showExternalIdList.includes(this.imageType)) {
  58. return true
  59. }
  60. return false
  61. },
  62. },
  63. methods: {
  64. imageChange (imageObj) {
  65. if (imageObj && R.is(Object, imageObj)) {
  66. if (R.is(Array, imageObj.label)) {
  67. const label = _.get(imageObj, 'label[0].children[0].children[0].text')
  68. imageObj = {
  69. ...imageObj,
  70. label,
  71. }
  72. }
  73. }
  74. this.$emit('change', imageObj)
  75. this.$emit('imageChange', imageObj)
  76. },
  77. filterOption (inp, option) {
  78. const input = inp.toLowerCase()
  79. const text = _.get(option.componentOptions, 'children[0].key') || ''
  80. return text.toLowerCase().indexOf(input) >= 0
  81. },
  82. imgLabels (img) {
  83. let min_disk_mb = 0
  84. if (img.min_disk) {
  85. min_disk_mb = img.min_disk
  86. } else if (img.server_config && img.server_config.disks && img.server_config.disks.length > 0) {
  87. min_disk_mb = img.server_config.disks[0].size
  88. } else if (img.info && (img.info.min_disk || img.info.min_disk_mb)) {
  89. min_disk_mb = img.info.min_disk || img.info.min_disk_mb
  90. }
  91. const min_disk = sizestr(min_disk_mb, 'M', 1024)
  92. let size = img.size
  93. if (img.size) {
  94. size = img.size
  95. } else if (img.size_mb) {
  96. size = img.size_mb * 1024 * 1024
  97. }
  98. const sizeStr = sizestr(size, 'B', 1024)
  99. const props = img.properties || (img.info ? img.info.properties : undefined)
  100. const arch = img.os_arch || (props && props.os_arch && props.os_arch === 'aarch64' ? this.$t('compute.cpu_arch.aarch64') : props?.os_arch) || 'x86_64'
  101. let bios = 'BIOS'
  102. if (props) {
  103. const { uefi_support, bios_support } = props
  104. if (uefi_support === 'true' && bios_support === 'true') {
  105. bios = 'BIOS & UEFI'
  106. } else if (uefi_support === 'true' && bios_support !== 'true') {
  107. bios = 'UEFI'
  108. } else if ((uefi_support !== 'true' && bios_support === 'true') || (uefi_support !== 'true' && bios_support !== 'true')) {
  109. bios = 'BIOS'
  110. }
  111. } else if (img.server_config && img.server_config.bios) {
  112. bios = img.server_config.bios
  113. }
  114. let part = 'MBR'
  115. if (props && props.partition_type) {
  116. part = props.partition_type.toUpperCase()
  117. } else if (bios === 'UEFI' || bios === 'BIOS & UEFI') {
  118. part = 'GPT'
  119. }
  120. return `${min_disk}|${sizeStr}|${arch}|${part}|${bios}`
  121. },
  122. isEncryped (img) {
  123. return !!img.encrypt_key_id
  124. },
  125. },
  126. }
  127. </script>
  128. <style lang="less" scoped>
  129. .over-hidden{
  130. margin-right: 10px;
  131. overflow: hidden;
  132. text-overflow: ellipsis;
  133. white-space: nowrap;
  134. }
  135. </style>