List.vue 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. <template>
  2. <page-list
  3. show-tag-columns
  4. show-tag-columns2
  5. show-tag-filter
  6. :list="list"
  7. :columns="templateListColumns || columns"
  8. :group-actions="groupActions"
  9. :single-actions="singleActions"
  10. :export-data-options="exportDataOptions"
  11. :showSearchbox="showSearchbox"
  12. :showGroupActions="showGroupActions"
  13. :show-single-actions="!isTemplate"
  14. :show-page="!isTemplate" />
  15. </template>
  16. <script>
  17. import { mapGetters } from 'vuex'
  18. import ListMixin from '@/mixins/list'
  19. import ResTemplateListMixin from '@/mixins/resTemplateList'
  20. import { getNameFilter, getTenantFilter, getStatusFilter, getDomainFilter, getOsArchFilter, getDescriptionFilter } from '@/utils/common/tableFilter'
  21. import expectStatus from '@/constants/expectStatus'
  22. import WindowsMixin from '@/mixins/windows'
  23. import GlobalSearchMixin from '@/mixins/globalSearch'
  24. import { getSetPublicAction } from '@/utils/common/tableActions'
  25. import SingleActionsMixin from '../mixins/singleActions'
  26. import ColumnsMixin from '../mixins/columns'
  27. export default {
  28. name: 'HostImageList',
  29. mixins: [WindowsMixin, ListMixin, GlobalSearchMixin, ColumnsMixin, SingleActionsMixin, ResTemplateListMixin],
  30. props: {
  31. id: String,
  32. getParams: {
  33. type: Object,
  34. default: () => ({}),
  35. },
  36. },
  37. data () {
  38. const validateAction = function (obj) {
  39. if (obj.is_guest_image === true || obj.is_guest_image === 'true') {
  40. return false
  41. }
  42. return true
  43. }
  44. return {
  45. list: this.$list.createList(this, {
  46. ctx: this,
  47. id: this.id,
  48. resource: 'guestimages',
  49. apiVersion: 'v1',
  50. getParams: this.getParam,
  51. isTemplate: this.isTemplate,
  52. templateLimit: this.templateLimit,
  53. steadyStatus: Object.values(expectStatus.image).flat(),
  54. filterOptions: {
  55. id: {
  56. label: this.$t('table.title.id'),
  57. },
  58. name: getNameFilter(),
  59. description: getDescriptionFilter(),
  60. status: getStatusFilter('image'),
  61. projects: getTenantFilter(),
  62. project_domains: getDomainFilter(),
  63. os_arch: getOsArchFilter(),
  64. },
  65. responseData: this.responseData,
  66. hiddenColumns: ['metadata', 'created_at', 'is_standard'],
  67. }),
  68. groupActions: [
  69. getSetPublicAction(this, {
  70. name: this.$t('dictionary.guestimage'),
  71. scope: 'project',
  72. resource: 'guestimages',
  73. }, {
  74. permission: 'guestimages_perform_public,guestimages_perform_private',
  75. meta: () => {
  76. if (!this.list.selectedItems || this.list.selectedItems.length <= 0) {
  77. return {
  78. validate: false,
  79. }
  80. }
  81. if (this.list.selectedItems.some(item => item.is_standard)) {
  82. return {
  83. validate: false,
  84. tooltip: this.$t('compute.text_612'),
  85. }
  86. }
  87. if (this.list.selectedItems.some(item => !validateAction(item))) {
  88. return {
  89. validate: false,
  90. }
  91. }
  92. // 1、管理后台视图可以对所有镜像进行操作;
  93. // 2、域管理后台视图只能对该域下的镜像进行操作,不能对其他域共享的镜像进行操作;
  94. // 3、项目视图只能对该项目下的镜像进行操作,不能对其他域、其他项目共享的镜像进行操作。
  95. if (this.isAdminMode) {
  96. return {
  97. validate: true,
  98. }
  99. }
  100. if (!this.isAdminMode && !this.isDomainAdmin) {
  101. if (this.list.selectedItems.some(item => this.userInfo.projectId !== item.tenant_id)) {
  102. return {
  103. validate: false,
  104. }
  105. }
  106. }
  107. if (this.isDomainAdmin) {
  108. if (this.list.selectedItems.some(item => this.userInfo.projectDomainId !== item.domain_id)) {
  109. return {
  110. validate: false,
  111. }
  112. }
  113. }
  114. return {
  115. validate: true,
  116. }
  117. },
  118. }),
  119. {
  120. label: this.$t('common.batchAction'),
  121. actions: () => {
  122. return [
  123. {
  124. label: this.$t('compute.perform_change_owner', [this.$t('dictionary.project')]),
  125. permission: 'guestimages_perform_change_owner',
  126. action: () => {
  127. this.createDialog('ChangeOwenrDialog', {
  128. data: this.list.selectedItems,
  129. columns: this.columns,
  130. onManager: this.onManager,
  131. name: this.$t('dictionary.guestimage'),
  132. resource: 'guestimages',
  133. apiVersion: 'v1',
  134. })
  135. },
  136. meta: () => {
  137. const ret = {
  138. validate: true,
  139. tooltip: null,
  140. }
  141. if (!this.isAdminMode && !this.isDomainMode) {
  142. ret.validate = false
  143. ret.tooltip = this.$t('compute.text_613')
  144. return ret
  145. }
  146. if (this.list.selectedItems.some(item => item.is_public)) {
  147. ret.validate = false
  148. ret.tooltip = this.$t('compute.text_614')
  149. return ret
  150. }
  151. return ret
  152. },
  153. },
  154. {
  155. label: this.$t('table.action.set_tag'),
  156. permission: 'guestimages_perform_set_user_metadata',
  157. action: () => {
  158. this.createDialog('SetTagDialog', {
  159. data: this.list.selectedItems,
  160. columns: this.columns,
  161. onManager: this.onManager,
  162. mode: 'add',
  163. params: {
  164. resources: 'guestimage',
  165. },
  166. tipName: this.$t('dictionary.guestimage'),
  167. })
  168. },
  169. },
  170. {
  171. label: this.$t('common_277'),
  172. permission: 'guestimages_update',
  173. action: () => {
  174. this.createDialog('ChangeDisableDelete', {
  175. name: this.$t('dictionary.guestimage'),
  176. columns: this.columns,
  177. onManager: this.onManager,
  178. data: this.list.selectedItems,
  179. })
  180. },
  181. meta: () => {
  182. const validate = this.list.selectedItems.length > 0
  183. return {
  184. validate: validate,
  185. tooltip: !validate && this.$t('compute.text_616'),
  186. }
  187. },
  188. },
  189. {
  190. label: this.$t('compute.perform_delete'),
  191. permission: 'guestimages_delete',
  192. action: () => {
  193. this.createDialog('DeleteResDialog', {
  194. vm: this,
  195. data: this.list.selectedItems,
  196. columns: this.columns,
  197. title: this.$t('compute.text_617'),
  198. name: this.$t('dictionary.guestimage'),
  199. onManager: this.onManager,
  200. alert: this.$t('compute.text_1393'),
  201. requestData: {
  202. override_pending_delete: true,
  203. },
  204. })
  205. },
  206. meta: () => this.$getDeleteResult(this.list.selectedItems),
  207. },
  208. ]
  209. },
  210. meta: () => {
  211. return {
  212. validate: this.list.selectedItems && this.list.selectedItems.length > 0,
  213. }
  214. },
  215. },
  216. ],
  217. }
  218. },
  219. computed: {
  220. ...mapGetters(['userInfo']),
  221. exportDataOptions () {
  222. return {
  223. items: this.columns,
  224. title: this.$t('dictionary.guestimage'),
  225. downloadType: 'local',
  226. }
  227. },
  228. },
  229. created () {
  230. this.initSidePageTab('host-image-detail')
  231. this.list.fetchData()
  232. },
  233. methods: {
  234. getParam () {
  235. const ret = {
  236. details: true,
  237. ...this.getParams,
  238. }
  239. if (this.cloudEnv) ret.cloud_env = this.cloudEnv
  240. return ret
  241. },
  242. handleOpenSidepage (row, tab) {
  243. this.sidePageTriggerHandle(this, 'HostImageSidePage', {
  244. id: row.id,
  245. resource: 'guestimages',
  246. apiVersion: 'v1',
  247. getParams: this.getParam,
  248. steadyStatus: Object.values(expectStatus.image).flat(),
  249. }, {
  250. list: this.list,
  251. tab,
  252. })
  253. },
  254. },
  255. }
  256. </script>