List.vue 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  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. :showSingleActions="isTemplate ? false : showActions"
  13. :showGroupActions="showActions && showGroupActions"
  14. :show-page="!isTemplate" />
  15. </template>
  16. <script>
  17. import WindowsMixin from '@/mixins/windows'
  18. import GlobalSearchMixin from '@/mixins/globalSearch'
  19. import ListMixin from '@/mixins/list'
  20. import ResTemplateListMixin from '@/mixins/resTemplateList'
  21. import {
  22. getNameFilter,
  23. getTenantFilter,
  24. getStatusFilter,
  25. getBrandFilter,
  26. getDomainFilter,
  27. getAccountFilter,
  28. getOsArchFilter,
  29. getRegionFilter,
  30. getDescriptionFilter,
  31. getDistinctFieldsFilter,
  32. } from '@/utils/common/tableFilter'
  33. import SingleActionsMixin from '../mixins/singleActions'
  34. import ColumnsMixin from '../mixins/columns'
  35. import { steadyStatus } from '../constants'
  36. export default {
  37. name: 'SnapshotList',
  38. mixins: [WindowsMixin, ListMixin, GlobalSearchMixin, ColumnsMixin, SingleActionsMixin, ResTemplateListMixin],
  39. props: {
  40. id: String,
  41. getParams: {
  42. type: [Function, Object],
  43. },
  44. cloudEnv: String,
  45. },
  46. data () {
  47. return {
  48. list: this.$list.createList(this, {
  49. ctx: this,
  50. id: this.id,
  51. resource: 'snapshots',
  52. getParams: this.getParam,
  53. isTemplate: this.isTemplate,
  54. templateLimit: this.templateLimit,
  55. steadyStatus,
  56. filterOptions: {
  57. id: {
  58. label: this.$t('table.title.id'),
  59. },
  60. name: getNameFilter(),
  61. description: getDescriptionFilter(),
  62. status: getStatusFilter('snapshot'),
  63. server_id: {
  64. label: this.$t('res.server'),
  65. hiddenField: 'guest',
  66. },
  67. brand: getBrandFilter(),
  68. projects: getTenantFilter(),
  69. project_domains: getDomainFilter(),
  70. account: getAccountFilter(),
  71. disk_name: {
  72. label: this.$t('res.disk'),
  73. filter: true,
  74. jointFilter: true,
  75. formatter: val => {
  76. return `disks.id(disk_id).name.in(${val})`
  77. },
  78. },
  79. disk_type: {
  80. label: this.$t('table.title.disk_type'),
  81. dropdown: true,
  82. multiple: true,
  83. items: [
  84. { label: this.$t('compute.text_50'), key: 'data' },
  85. { label: this.$t('compute.text_49'), key: 'sys' },
  86. ],
  87. },
  88. region: getRegionFilter(),
  89. os_arch: getOsArchFilter(),
  90. storage: getDistinctFieldsFilter({
  91. label: this.$t('compute.text_99'),
  92. filter: true,
  93. multiple: false,
  94. type: 'extra_field',
  95. field: ['id', 'name'],
  96. mapper: (list, data) => {
  97. const { extra_fields = [] } = data
  98. const ret = extra_fields.map(item => ({ label: item.name, key: item.id })).filter(item => item.label && item.key)
  99. return ret
  100. },
  101. formatter: (val) => {
  102. const realVal = val.map(item => `'${item}'`)
  103. return `storage_id.in(${realVal})`
  104. },
  105. getParams: { extra_resource: 'storage', module: 'snapshots' },
  106. }),
  107. },
  108. responseData: this.responseData,
  109. hiddenColumns: ['storage_type', 'created_at', 'os_arch'],
  110. autoHiddenFilterKey: 'snapshot_hidden_columns',
  111. }),
  112. groupActions: [
  113. {
  114. label: this.$t('compute.perform_sync_status'),
  115. permission: 'snapshots_perform_syncstatus',
  116. action: () => {
  117. this.onManager('batchPerformAction', {
  118. steadyStatus: ['running', 'ready'],
  119. managerArgs: {
  120. action: 'syncstatus',
  121. },
  122. })
  123. },
  124. meta: () => ({
  125. validate: this.list.selected.length,
  126. }),
  127. },
  128. {
  129. label: this.$t('table.action.set_tag'),
  130. permission: 'snapshots_perform_set_user_metadata',
  131. action: () => {
  132. this.createDialog('SetTagDialog', {
  133. data: this.list.selectedItems,
  134. columns: this.columns,
  135. onManager: this.onManager,
  136. mode: 'add',
  137. params: {
  138. resources: 'snapshot',
  139. },
  140. tipName: this.$t('compute.text_462'),
  141. })
  142. },
  143. meta: () => {
  144. return {
  145. validate: this.list.selected.length,
  146. tooltip: null,
  147. }
  148. },
  149. },
  150. {
  151. label: this.$t('compute.perform_delete'),
  152. permission: 'snapshots_delete',
  153. action: () => {
  154. this.createDialog('DeleteResDialog', {
  155. vm: this,
  156. data: this.list.selectedItems,
  157. columns: this.columns,
  158. onManager: this.onManager,
  159. title: this.$t('compute.perform_delete'),
  160. name: this.$t('compute.text_462'),
  161. })
  162. },
  163. meta: () => {
  164. const ret = {
  165. validate: this.list.selected.length,
  166. tooltip: null,
  167. }
  168. if (this.list.selectedItems.some(item => !item.can_delete)) {
  169. ret.validate = false
  170. return ret
  171. }
  172. if (this.list.selectedItems.some(item => item.is_sub_snapshot)) {
  173. ret.validate = false
  174. ret.tooltip = this.$t('compute.text_1062')
  175. return ret
  176. }
  177. return ret
  178. },
  179. },
  180. ],
  181. }
  182. },
  183. computed: {
  184. showActions () {
  185. return !this.$isScopedPolicyMenuHidden('snapshot_hidden_columns.perform_action')
  186. },
  187. exportDataOptions () {
  188. return {
  189. downloadType: 'local',
  190. title: this.$t('compute.text_101'),
  191. items: [
  192. { field: 'id', title: 'ID' },
  193. { field: 'external_id', title: this.$t('table.title.external_id') },
  194. ...this.columns,
  195. ],
  196. }
  197. },
  198. },
  199. watch: {
  200. cloudEnv (val) {
  201. this.$nextTick(() => {
  202. this.list.fetchData(0)
  203. })
  204. },
  205. },
  206. created () {
  207. this.initSidePageTab('snapshot-detail')
  208. this.list.fetchData()
  209. },
  210. methods: {
  211. getParam () {
  212. const ret = {
  213. details: true,
  214. with_meta: true,
  215. is_instance_snapshot: false,
  216. ...this.getParams,
  217. }
  218. if (this.cloudEnv) ret.cloud_env = this.cloudEnv
  219. return ret
  220. },
  221. handleOpenSidepage (row, tab) {
  222. this.sidePageTriggerHandle(this, 'SnapshotSidePage', {
  223. id: row.id,
  224. resource: 'snapshots',
  225. getParams: this.getParam,
  226. steadyStatus: this.list.steadyStatus,
  227. }, {
  228. list: this.list,
  229. type: 'disk',
  230. tab,
  231. })
  232. },
  233. },
  234. }
  235. </script>