List.vue 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. <template>
  2. <page-list
  3. show-tag-columns
  4. show-tag-columns2
  5. show-tag-filter
  6. show-tag-config
  7. :list="list"
  8. :columns="templateListColumns || columns"
  9. :group-actions="groupActions"
  10. :single-actions="singleActions"
  11. :showSearchbox="showSearchbox"
  12. :showSingleActions="isTemplate ? false : showActions"
  13. :showGroupActions="showActions && showGroupActions"
  14. :export-data-options="exportDataOptions"
  15. :tag-config-params="tagConfigParams"
  16. :show-page="!isTemplate" />
  17. </template>
  18. <script>
  19. import * as R from 'ramda'
  20. import { mapGetters } from 'vuex'
  21. import { ACL_TYPE } from '@Storage/constants/index.js'
  22. import WindowsMixin from '@/mixins/windows'
  23. import ListMixin from '@/mixins/list'
  24. import ResTemplateListMixin from '@/mixins/resTemplateList'
  25. import { getNameFilter, getTenantFilter, getBrandFilter, getStatusFilter, getAccountFilter, getDomainFilter, getCloudProviderFilter, getDescriptionFilter, getCreatedAtFilter } from '@/utils/common/tableFilter'
  26. import { getSetPublicAction } from '@/utils/common/tableActions'
  27. import expectStatus from '@/constants/expectStatus'
  28. import GlobalSearchMixin from '@/mixins/globalSearch'
  29. import SingleActionsMixin from '../mixins/singleActions'
  30. import ColumnsMixin from '../mixins/columns'
  31. export default {
  32. name: 'BucketStorageList',
  33. mixins: [WindowsMixin, ListMixin, GlobalSearchMixin, ColumnsMixin, SingleActionsMixin, ResTemplateListMixin],
  34. props: {
  35. id: String,
  36. cloudEnv: String,
  37. cloudEnvOptions: {
  38. type: Array,
  39. },
  40. getParams: {
  41. type: [Object, Function],
  42. default: () => ({}),
  43. },
  44. },
  45. data () {
  46. return {
  47. list: this.$list.createList(this, {
  48. ctx: this,
  49. id: this.id,
  50. resource: 'buckets',
  51. isTemplate: this.isTemplate,
  52. templateLimit: this.templateLimit,
  53. getParams: this.getParam,
  54. steadyStatus: Object.values(expectStatus.bucket).flat(),
  55. filterOptions: {
  56. external_id: {
  57. label: this.$t('table.title.external_id'),
  58. },
  59. id: {
  60. label: this.$t('table.title.id'),
  61. },
  62. name: getNameFilter(),
  63. description: getDescriptionFilter(),
  64. brand: getBrandFilter('object_storage_brands'),
  65. projects: getTenantFilter(),
  66. status: getStatusFilter({ statusModule: 'bucket' }),
  67. cloudaccount: getAccountFilter(),
  68. manager: getCloudProviderFilter(),
  69. // region: {
  70. // label: '区域',
  71. // },
  72. storage_class: {
  73. label: this.$t('storage.text_38'),
  74. },
  75. acl: {
  76. label: this.$t('storage.text_93'),
  77. dropdown: true,
  78. items: Object.keys(ACL_TYPE).map(k => {
  79. return { label: ACL_TYPE[k], key: k }
  80. }),
  81. },
  82. region: {
  83. label: this.$t('dictionary.region'),
  84. },
  85. project_domains: getDomainFilter(),
  86. created_at: getCreatedAtFilter(),
  87. },
  88. responseData: this.responseData,
  89. hiddenColumns: ['storage_class', 'account', 'public_scope'],
  90. autoHiddenFilterKey: 'oss_hidden_columns',
  91. fetchDataCb: (res) => {
  92. const { totals = {} } = res.data
  93. this.$emit('resStatisticsChange', totals)
  94. },
  95. }),
  96. groupActions: [
  97. {
  98. label: this.$t('storage.text_31'),
  99. permission: 'buckets_create',
  100. action: () => {
  101. // this.createDialog('BucketCreateDialog', {
  102. // title: this.$t('storage.text_95'),
  103. // onManager: this.onManager,
  104. // refresh: this.refresh,
  105. // })
  106. this.$router.push({
  107. path: '/bucket/create',
  108. query: {
  109. type: this.cloudEnv,
  110. },
  111. })
  112. },
  113. meta: () => {
  114. return {
  115. buttonType: 'primary',
  116. validate: !this.cloudEnvEmpty,
  117. tooltip: this.cloudEnvEmpty ? this.$t('common.no_platform_available') : '',
  118. }
  119. },
  120. },
  121. {
  122. label: this.$t('storage.text_33'),
  123. actions: () => {
  124. return [
  125. getSetPublicAction(this, {
  126. name: this.$t('dictionary.bucket'),
  127. scope: 'project',
  128. resource: 'buckets',
  129. }, {
  130. permission: 'buckets_perform_public',
  131. }),
  132. {
  133. label: this.$t('storage.text_96', [this.$t('dictionary.project')]),
  134. permission: 'buckets_perform_change_owner',
  135. action: row => {
  136. this.createDialog('ChangeOwenrDialog', {
  137. name: this.$t('storage.text_18'),
  138. data: this.list.selectedItems,
  139. columns: this.columns,
  140. onManager: this.onManager,
  141. refresh: this.refresh,
  142. resource: 'buckets',
  143. })
  144. },
  145. meta: row => {
  146. if (this.list.selectedItems.some(item => item.is_public)) {
  147. return {
  148. validate: false,
  149. tooltip: this.$t('common_614'),
  150. }
  151. }
  152. const ret = {
  153. validate: false,
  154. tooltip: '',
  155. }
  156. if (this.isProjectMode) {
  157. ret.tooltip = this.$t('common_601')
  158. return ret
  159. }
  160. const domainIds = this.list.selectedItems.map(item => item.domain_id)
  161. const validate = R.uniq(domainIds).length === 1
  162. return {
  163. validate,
  164. tooltip: !validate && this.$t('storage.text_97', [this.$t('dictionary.domain')]),
  165. }
  166. },
  167. },
  168. {
  169. label: this.$t('storage.text_99'),
  170. permission: 'buckets_perform_limit',
  171. action: row => {
  172. this.createDialog('BucketUpdateBucketLimitDialog', {
  173. title: this.$t('storage.text_99'),
  174. data: this.list.selectedItems,
  175. columns: this.columns,
  176. onManager: this.onManager,
  177. refresh: this.refresh,
  178. })
  179. },
  180. },
  181. {
  182. label: this.$t('storage.text_100'),
  183. permission: 'buckets_perform_syncstatus',
  184. action: () => {
  185. this.onManager('batchPerformAction', {
  186. id: this.list.selectedItems.map(item => item.id),
  187. steadyStatus: ['running', 'ready'],
  188. managerArgs: {
  189. action: 'syncstatus',
  190. },
  191. })
  192. },
  193. },
  194. {
  195. label: this.$t('table.action.set_tag'),
  196. permission: 'buckets_perform_set_user_metadata',
  197. action: () => {
  198. this.createDialog('SetTagDialog', {
  199. data: this.list.selectedItems,
  200. columns: this.columns,
  201. onManager: this.onManager,
  202. mode: 'add',
  203. params: {
  204. resources: 'bucket',
  205. },
  206. tipName: this.$t('storage.text_18'),
  207. })
  208. },
  209. },
  210. {
  211. label: this.$t('storage.text_36'),
  212. permission: 'buckets_delete',
  213. action: obj => {
  214. this.createDialog('DeleteResDialog', {
  215. vm: this,
  216. data: this.list.selectedItems,
  217. columns: this.columns,
  218. title: this.$t('storage.text_36'),
  219. name: this.$t('storage.text_18'),
  220. onManager: this.onManager,
  221. refresh: this.refresh,
  222. })
  223. },
  224. meta: () => {
  225. const ret = { validate: true, tooltip: '' }
  226. for (const item of this.list.selectedItems) {
  227. if (this.isInternal(item.location)) {
  228. ret.tooltip = this.$t('storage.internal_bucket')
  229. ret.validate = false
  230. break
  231. }
  232. }
  233. if (!ret.validate) return ret
  234. return this.$getDeleteResult(this.list.selectedItems)
  235. },
  236. },
  237. ]
  238. },
  239. meta: row => {
  240. return {
  241. validate: !!this.list.selectedItems.length,
  242. }
  243. },
  244. },
  245. ],
  246. tagConfigParams: {
  247. resource: 'buckets',
  248. queryTreeId: 'project-tag-value-tree',
  249. },
  250. }
  251. },
  252. computed: {
  253. ...mapGetters(['isProjectMode']),
  254. showActions () {
  255. return !this.$isScopedPolicyMenuHidden('oss_hidden_columns.perform_action')
  256. },
  257. exportDataOptions () {
  258. return {
  259. items: [
  260. { label: 'ID', key: 'id' },
  261. ...this.columns,
  262. ],
  263. downloadType: 'local',
  264. title: this.$t('storage.text_18'),
  265. }
  266. },
  267. },
  268. watch: {
  269. cloudEnv (val) {
  270. this.$nextTick(() => {
  271. this.list.fetchData(0)
  272. })
  273. },
  274. },
  275. created () {
  276. this.list.fetchData()
  277. this.initSidePageTab('objects')
  278. },
  279. methods: {
  280. getParam () {
  281. const ret = {
  282. ...(R.is(Function, this.getParams) ? this.getParams() : this.getParams),
  283. }
  284. if (this.cloudEnv) ret.cloud_env = this.cloudEnv
  285. return ret
  286. },
  287. handleOpenSidepage (row, tab) {
  288. this.sidePageTriggerHandle(this, 'BucketStorageSidePage', {
  289. id: row.id,
  290. resource: 'buckets',
  291. getParams: this.getParams,
  292. }, {
  293. list: this.list,
  294. cancel: () => {
  295. this.list.singleRefresh(row.id, Object.values(expectStatus.bucket).flat())
  296. },
  297. tab,
  298. })
  299. },
  300. },
  301. }
  302. </script>