List.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425
  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. :single-actions="singleActions"
  10. :group-actions="groupActions"
  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 { surpportLb } from '@Network/views/lb/constants'
  22. import ListMixin from '@/mixins/list'
  23. import ResTemplateListMixin from '@/mixins/resTemplateList'
  24. import WindowsMixin from '@/mixins/windows'
  25. import { getNameFilter, getBrandFilter, getTenantFilter, getDomainFilter, getAccountFilter, getStatusFilter, getCloudProviderFilter, getDescriptionFilter, getCreatedAtFilter } from '@/utils/common/tableFilter'
  26. import { getEnabledSwitchActions, disableDeleteAction } from '@/utils/common/tableActions'
  27. import expectStatus from '@/constants/expectStatus'
  28. import { PROVIDER_MAP } from '@/constants'
  29. import { changeToArr } from '@/utils/utils'
  30. import GlobalSearchMixin from '@/mixins/globalSearch'
  31. import { validateEnabled, validateDisable } from '../utils'
  32. import SingleActionsMixin from '../mixins/singleActions'
  33. import ColumnsMixin from '../mixins/columns'
  34. export default {
  35. name: 'LbList',
  36. mixins: [WindowsMixin, ListMixin, GlobalSearchMixin, ColumnsMixin, SingleActionsMixin, ResTemplateListMixin],
  37. props: {
  38. id: String,
  39. getParams: {
  40. type: [Function, Object],
  41. },
  42. cloudEnv: {
  43. type: String,
  44. },
  45. cloudEnvOptions: {
  46. type: Array,
  47. },
  48. },
  49. data () {
  50. const allBrandsFilter = getBrandFilter()
  51. const filterOptions = {
  52. external_id: {
  53. label: this.$t('table.title.external_id'),
  54. },
  55. id: {
  56. label: this.$t('table.title.id'),
  57. },
  58. name: getNameFilter(),
  59. description: getDescriptionFilter(),
  60. status: getStatusFilter('lb'),
  61. address: {
  62. label: this.$t('network.text_248'),
  63. },
  64. brand: {
  65. ...allBrandsFilter,
  66. items: allBrandsFilter.items.filter(val => surpportLb.includes(val.key.toLowerCase())),
  67. },
  68. projects: getTenantFilter(),
  69. project_domains: getDomainFilter(),
  70. cloudaccount: getAccountFilter(),
  71. manager: getCloudProviderFilter(),
  72. region: {
  73. label: this.$t('dashboard.text_101'),
  74. },
  75. zone: {
  76. label: this.$t('compute.text_270'),
  77. hiddenField: 'region',
  78. },
  79. created_at: getCreatedAtFilter(),
  80. }
  81. const { path } = this.$route
  82. if (path.includes('/cluster')) {
  83. delete filterOptions.brand
  84. delete filterOptions.cloudaccount
  85. }
  86. return {
  87. list: this.$list.createList(this, {
  88. ctx: this,
  89. id: this.id,
  90. resource: 'loadbalancers',
  91. getParams: this.getParam,
  92. isTemplate: this.isTemplate,
  93. templateLimit: this.templateLimit,
  94. filterOptions,
  95. steadyStatus: {
  96. status: Object.values(expectStatus.lb).flat(),
  97. },
  98. responseData: this.responseData,
  99. hiddenColumns: ['metadata', 'account', 'cluster', 'created_at'],
  100. autoHiddenFilterKey: 'slb_hidden_columns',
  101. fetchDataCb: (res) => {
  102. const { totals = {} } = res.data
  103. this.$emit('resStatisticsChange', totals)
  104. },
  105. }),
  106. tagConfigParams: {
  107. resource: 'loadbalancers',
  108. queryTreeId: 'project-tag-value-tree',
  109. },
  110. }
  111. },
  112. computed: {
  113. ...mapGetters(['userInfo', 'capability']),
  114. showActions () {
  115. return !this.$isScopedPolicyMenuHidden('slb_hidden_columns.perform_action')
  116. },
  117. groupActions () {
  118. let createBtn = {
  119. label: this.$t('network.text_26'),
  120. permission: 'lb_loadbalancers_create',
  121. action: () => {
  122. this.$router.push({
  123. path: '/lb/create',
  124. query: {
  125. type: this.cloudEnv,
  126. },
  127. })
  128. },
  129. meta: () => {
  130. return {
  131. buttonType: 'primary',
  132. validate: !this.cloudEnvEmpty,
  133. tooltip: this.cloudEnvEmpty ? this.$t('common.no_platform_available') : '',
  134. }
  135. },
  136. }
  137. if (this.getParam() && this.getParam().cluster) {
  138. createBtn = {
  139. label: this.$t('network.text_26'),
  140. permission: 'lb_loadbalancers_create',
  141. action: () => {
  142. this.$router.push({
  143. path: '/lb/create',
  144. query: {
  145. type: 'Onecloud',
  146. },
  147. })
  148. },
  149. meta: () => {
  150. return {
  151. buttonType: 'primary',
  152. validate: this.hasService(this.userInfo, 'lbagent'),
  153. }
  154. },
  155. }
  156. }
  157. const actions = [
  158. createBtn,
  159. {
  160. label: this.$t('network.text_201'),
  161. permission: 'lb_loadbalancers_perform_syncstatus',
  162. action: () => {
  163. this.onManager('batchPerformAction', {
  164. steadyStatus: ['running', 'ready'],
  165. managerArgs: {
  166. action: 'syncstatus',
  167. },
  168. })
  169. },
  170. meta: () => {
  171. const ret = {
  172. validate: this.list.selectedItems.length > 0,
  173. }
  174. const isExist = this.list.selectedItems.some(item => item.brand.toLowerCase() === 'onecloud')
  175. if (isExist) {
  176. ret.validate = false
  177. ret.tooltip = this.$t('network.text_652')
  178. return ret
  179. }
  180. return ret
  181. },
  182. },
  183. {
  184. label: this.$t('network.text_200'),
  185. actions: () => {
  186. return [
  187. {
  188. label: this.$t('compute.perform_change_owner', [this.$t('dictionary.project')]),
  189. permission: 'lb_loadbalancers_perform_change_owner',
  190. action: () => {
  191. this.createDialog('ChangeOwenrDialog', {
  192. data: this.list.selectedItems,
  193. custom_columns: this.columns.filter(o => ['name', 'address', 'tenant'].includes(o.field)),
  194. onManager: this.onManager,
  195. name: this.$t('network.text_714'),
  196. resource: 'loadbalancers',
  197. })
  198. },
  199. meta: () => {
  200. const ret = {
  201. validate: false,
  202. tooltip: null,
  203. }
  204. ret.validate = true
  205. return ret
  206. },
  207. },
  208. ...getEnabledSwitchActions(this, undefined, ['lb_loadbalancers_perform_enable', 'lb_loadbalancers_perform_disable'], {
  209. actions: [
  210. (obj) => {
  211. const ids = this.list.selectedItems.map(item => item.id)
  212. this.onManager('batchPerformAction', {
  213. steadyStatus: Object.values(expectStatus.lb).flat(),
  214. id: ids,
  215. managerArgs: {
  216. action: 'status',
  217. data: {
  218. status: 'enabled',
  219. },
  220. },
  221. })
  222. },
  223. (obj) => {
  224. const ids = this.list.selectedItems.map(item => item.id)
  225. this.onManager('batchPerformAction', {
  226. steadyStatus: Object.values(expectStatus.lb).flat(),
  227. id: ids,
  228. managerArgs: {
  229. action: 'status',
  230. data: {
  231. status: 'disabled',
  232. },
  233. },
  234. })
  235. },
  236. ],
  237. metas: [
  238. () => {
  239. return validateEnabled(this.list.selectedItems)
  240. },
  241. () => {
  242. return validateDisable(this.list.selectedItems)
  243. },
  244. ],
  245. }),
  246. {
  247. label: this.$t('network.text_253'),
  248. permission: 'lb_loadbalancers_update',
  249. action: () => {
  250. this.createDialog('LbUpdateCluster', {
  251. title: this.$t('network.text_253'),
  252. data: this.list.selectedItems,
  253. columns: this.columns,
  254. onManager: this.onManager,
  255. refresh: this.refresh,
  256. })
  257. },
  258. meta: () => {
  259. const zonsIds = {}
  260. const isOneCloud = this.list.selectedItems.every(item => {
  261. zonsIds[item.zone_id] = true
  262. return item.brand === 'OneCloud'
  263. })
  264. if (!isOneCloud) {
  265. return {
  266. validate: false,
  267. tooltip: this.$t('network.text_254'),
  268. }
  269. }
  270. if (Object.keys(zonsIds).length > 1) {
  271. return {
  272. validate: false,
  273. tooltip: this.$t('network.text_255'),
  274. }
  275. }
  276. return {
  277. validate: true,
  278. }
  279. },
  280. },
  281. {
  282. label: this.$t('table.action.set_tag'),
  283. permission: 'lb_loadbalancers_perform_set_user_metadata',
  284. action: () => {
  285. this.createDialog('SetTagDialog', {
  286. data: this.list.selectedItems,
  287. columns: this.columns,
  288. onManager: this.onManager,
  289. mode: 'add',
  290. params: {
  291. resources: 'loadbalancer',
  292. },
  293. })
  294. },
  295. },
  296. disableDeleteAction(this, {
  297. name: this.$t('dictionary.loadbalancer'),
  298. permission: 'lb_loadbalancers_update',
  299. }),
  300. {
  301. label: this.$t('network.text_131'),
  302. permission: 'lb_loadbalancers_delete',
  303. action: () => {
  304. this.createDialog('DeleteLbDialog', {
  305. vm: this,
  306. title: this.$t('network.text_131'),
  307. data: this.list.selectedItems,
  308. columns: this.columns,
  309. onManager: this.onManager,
  310. })
  311. },
  312. meta: () => {
  313. return {
  314. validate: this.list.allowDelete(),
  315. }
  316. },
  317. },
  318. ]
  319. },
  320. meta: () => {
  321. let ret = {
  322. validate: true,
  323. tooltip: null,
  324. }
  325. ret.validate = this.list.selectedItems.length > 0
  326. if (!ret.validate) return ret
  327. const hasAzure = this.list.selectedItems.filter((item) => {
  328. return item.provider && item.provider.toLowerCase() === 'azure'
  329. })
  330. if (hasAzure.length > 0) return { validate: false, tooltip: this.$t('network.text_309', [PROVIDER_MAP[hasAzure[0].provider].label]) }
  331. const hasGoogle = this.list.selectedItems.filter((item) => {
  332. return item.provider && item.provider.toLowerCase() === 'google'
  333. })
  334. if (hasGoogle.length > 0) return { validate: false, tooltip: this.$t('network.text_309', [PROVIDER_MAP[hasGoogle[0].provider].label]) }
  335. ret = this.$isValidateResourceLock(this.list.selectedItems)
  336. return ret
  337. },
  338. },
  339. ]
  340. return actions
  341. },
  342. exportDataOptions () {
  343. return {
  344. items: [
  345. { label: 'ID', key: 'id' },
  346. { label: this.$t('dictionary.external_id'), key: 'external_id' },
  347. ...this.columns,
  348. ],
  349. title: this.$t('network.text_714'),
  350. downloadType: 'local',
  351. }
  352. },
  353. },
  354. watch: {
  355. cloudEnv (val) {
  356. switch (val) {
  357. case 'onpremise':
  358. this.envParams = { is_on_premise: true }
  359. break
  360. case 'private':
  361. this.envParams = { private_cloud: true }
  362. break
  363. case 'public':
  364. this.envParams = { public_cloud: true }
  365. break
  366. default:
  367. this.envParams = {}
  368. }
  369. const params = this.list.getParams
  370. delete params.is_on_premise
  371. delete params.private_cloud
  372. delete params.public_cloud
  373. this.list.getParams = { ...params, ...this.envParams }
  374. this.list.fetchData()
  375. },
  376. },
  377. created () {
  378. this.list.fetchData()
  379. },
  380. methods: {
  381. getParam () {
  382. const ret = {
  383. ...(R.is(Function, this.getParams) ? this.getParams() : this.getParams),
  384. }
  385. return ret
  386. },
  387. hasService ($userInfo, service) {
  388. if ($userInfo && $userInfo.services && $userInfo.services.length) {
  389. const results = $userInfo.services.filter(item => {
  390. return item.type === service && item.status === true
  391. })
  392. return results && results.length > 0
  393. }
  394. return false
  395. },
  396. hasHypervisors (hypervisor) {
  397. const hypervisors = changeToArr(hypervisor)
  398. for (let i = 0, len = hypervisors.length; i < len; i++) {
  399. if ((this.capability.hypervisors || []).indexOf(hypervisors[i]) !== -1) {
  400. return true
  401. }
  402. }
  403. return false
  404. },
  405. handleOpenSidepage (row, tab) {
  406. this.sidePageTriggerHandle(this, 'LbSidePage', {
  407. id: row.id,
  408. resource: 'loadbalancers',
  409. getParams: this.getParam,
  410. steadyStatus: {
  411. status: Object.values(expectStatus.lb).flat(),
  412. },
  413. }, {
  414. row: row,
  415. list: this.list,
  416. tab,
  417. })
  418. },
  419. },
  420. }
  421. </script>