List.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392
  1. <template>
  2. <page-list
  3. :list="list"
  4. :columns="templateListColumns || columns"
  5. :show-tag-columns="true"
  6. :show-tag-filter="true"
  7. :export-data-options="exportDataOptions"
  8. :group-actions="groupActions"
  9. :showSearchbox="showSearchbox"
  10. :showGroupActions="showGroupActions"
  11. :single-actions="singleActions"
  12. :show-single-actions="!isTemplate"
  13. :show-page="!isTemplate" />
  14. </template>
  15. <script>
  16. import * as R from 'ramda'
  17. import { mapGetters } from 'vuex'
  18. import ListMixin from '@/mixins/list'
  19. import ResTemplateListMixin from '@/mixins/resTemplateList'
  20. import expectStatus from '@/constants/expectStatus'
  21. import { getFilter, getStatusFilter, getBrandFilter, getAccountFilter, getProjectDomainFilter, getDescriptionFilter, getCreatedAtFilter } from '@/utils/common/tableFilter'
  22. import { disableDeleteAction } from '@/utils/common/tableActions'
  23. import WindowsMixin from '@/mixins/windows'
  24. import i18n from '@/locales'
  25. import GlobalSearchMixin from '@/mixins/globalSearch'
  26. import SingleActionsMixin from '../mixins/singleActions'
  27. import ColumnsMixin from '../mixins/columns'
  28. import { checkReadOnly } from '../utils'
  29. export default {
  30. name: 'NatList',
  31. mixins: [WindowsMixin, ListMixin, GlobalSearchMixin, ColumnsMixin, SingleActionsMixin, ResTemplateListMixin],
  32. props: {
  33. id: String,
  34. getParams: {
  35. type: [Function, Object],
  36. },
  37. hiddenActions: {
  38. type: Array,
  39. default: () => ([]),
  40. },
  41. },
  42. data () {
  43. return {
  44. list: this.$list.createList(this, {
  45. ctx: this,
  46. id: this.id,
  47. resource: 'natgateways',
  48. getParams: this.getParam,
  49. isTemplate: this.isTemplate,
  50. templateLimit: this.templateLimit,
  51. steadyStatus: Object.values(expectStatus.nat).flat(),
  52. filterOptions: {
  53. id: {
  54. label: this.$t('table.title.id'),
  55. },
  56. name: {
  57. label: this.$t('network.text_21'),
  58. filter: true,
  59. formatter: val => {
  60. return `name.contains("${val}")`
  61. },
  62. },
  63. description: getDescriptionFilter(),
  64. status: getStatusFilter('nat'),
  65. network_type: {
  66. label: this.$t('network.text_249'),
  67. dropdown: true,
  68. filter: true,
  69. items: [
  70. { key: 'internet', label: this.$t('network.text_270') },
  71. { key: 'intranet', label: this.$t('network.text_271') },
  72. ],
  73. formatter: (val) => {
  74. return `network_type.equals(${val})`
  75. },
  76. },
  77. cloudaccount: getAccountFilter(),
  78. brand: getBrandFilter('nat_brands'),
  79. vpc: {
  80. label: this.$t('network.text_535'),
  81. },
  82. region: {
  83. label: this.$t('network.text_199'),
  84. },
  85. nat_spec: {
  86. label: this.$t('network.text_536'),
  87. },
  88. billing_type: getFilter({
  89. field: 'billing_type',
  90. title: this.$t('network.text_192'),
  91. items: [
  92. { label: this.$t('network.text_256'), key: 'postpaid' },
  93. { label: this.$t('network.text_257'), key: 'prepaid' },
  94. ],
  95. }),
  96. project_domains: getProjectDomainFilter(),
  97. created_at: getCreatedAtFilter(),
  98. },
  99. responseData: this.responseData,
  100. hiddenColumns: ['created_at'],
  101. }),
  102. groupActions: [
  103. {
  104. label: this.$t('network.text_26'),
  105. permission: 'natgateways_create',
  106. action: () => {
  107. this.$router.push({
  108. name: 'NatCreate',
  109. query: {
  110. type: this.cloudEnv,
  111. },
  112. })
  113. },
  114. meta: () => {
  115. return {
  116. buttonType: 'primary',
  117. validate: !this.cloudEnvEmpty,
  118. tooltip: this.cloudEnvEmpty ? this.$t('common.no_platform_available') : '',
  119. }
  120. },
  121. hidden: () => this.hiddenActions.includes('create'),
  122. },
  123. {
  124. label: this.$t('network.text_200'),
  125. actions: (obj) => {
  126. const selectedLength = this.list.selectedItems.length
  127. const notSelectedTooltip = selectedLength <= 0 ? this.$t('network.instance.select.at.least.one') : ''
  128. const isAvailable = this.list.selectedItems.every(item => item.status.toLowerCase() === 'available')
  129. const notAvailableTip = !isAvailable ? i18n.t('network.not.available.tooltip') : null
  130. const isPrepaid = this.list.selectedItems.every(item => item.billing_type.toLowerCase() === 'prpaid')
  131. const isOwner = this.list.selectedItems.every(item => this.isOwner(item))
  132. return [
  133. {
  134. label: this.$t('compute.text_283'),
  135. permission: 'natgateways_set_user_metadata',
  136. action: () => {
  137. this.createDialog('SetTagDialog', {
  138. data: this.list.selectedItems,
  139. columns: this.columns,
  140. onManager: this.onManager,
  141. params: {
  142. resources: 'natgateways',
  143. },
  144. mode: 'add',
  145. })
  146. },
  147. meta: () => {
  148. return checkReadOnly(this.list.selectedItems, this.$t('compute.text_283'))
  149. },
  150. },
  151. {
  152. label: this.$t('network.text_201'),
  153. permission: 'natgateways_perform_syncstatus',
  154. action: () => {
  155. this.onManager('batchPerformAction', {
  156. steadyStatus: ['available'],
  157. managerArgs: {
  158. action: 'syncstatus',
  159. },
  160. })
  161. },
  162. meta: () => {
  163. // const ret = checkReadOnly(this.list.selectedItems, this.$t('network.text_201'))
  164. // if (!ret.validate) return ret
  165. if (!isOwner) {
  166. return {
  167. validate: false,
  168. tooltip: i18n.t('network.text_627'),
  169. }
  170. }
  171. return {
  172. validate: selectedLength,
  173. tooltip: notSelectedTooltip,
  174. }
  175. },
  176. },
  177. {
  178. label: i18n.t('network.expired_release'),
  179. permission: 'natgateways_perform_postpaid_expire',
  180. action: () => {
  181. this.createDialog('SetDurationDialog', {
  182. data: this.list.selectedItems,
  183. alert: this.$t('network.text_764'),
  184. columns: this.columns,
  185. onManager: this.onManager,
  186. name: this.$t('dictionary.nat'),
  187. refresh: this.refresh,
  188. })
  189. },
  190. meta: () => {
  191. const ret = checkReadOnly(this.list.selectedItems, this.$t('network.expired_release'))
  192. if (!ret.validate) return ret
  193. if (!isOwner) {
  194. return {
  195. validate: false,
  196. tooltip: i18n.t('network.text_627'),
  197. }
  198. }
  199. if (isPrepaid) {
  200. ret.validate = false
  201. ret.tooltip = i18n.t('network.nat.prepaid.unsupported')
  202. return ret
  203. }
  204. if (selectedLength === 0) {
  205. ret.validate = false
  206. ret.tooltip = notSelectedTooltip
  207. return ret
  208. }
  209. return ret
  210. },
  211. },
  212. {
  213. label: i18n.t('network.renew'),
  214. permission: 'natgateways_perform_renew',
  215. action: () => {
  216. this.createDialog('RenewDialog', {
  217. name: this.$t('dictionary.nat'),
  218. data: this.list.selectedItems,
  219. alert: this.$t('network.text_765'),
  220. columns: this.columns,
  221. onManager: this.onManager,
  222. refresh: this.refresh,
  223. })
  224. },
  225. meta: () => {
  226. const ret = checkReadOnly(this.list.selectedItems, this.$t('network.renew'))
  227. if (!ret.validate) return ret
  228. if (!isOwner) {
  229. return {
  230. validate: false,
  231. tooltip: i18n.t('network.text_627'),
  232. }
  233. }
  234. if (!isAvailable) {
  235. ret.validate = false
  236. ret.tooltip = notAvailableTip
  237. return ret
  238. }
  239. if (!isPrepaid) {
  240. ret.validate = false
  241. ret.tooltip = i18n.t('network.nat.postpaid.unsupported')
  242. return ret
  243. }
  244. if (selectedLength === 0) {
  245. ret.validate = false
  246. ret.tooltip = notSelectedTooltip
  247. return ret
  248. }
  249. return ret
  250. },
  251. },
  252. {
  253. label: i18n.t('network.auto.renew'),
  254. permission: 'natgateways_perform_set_auto_renew',
  255. action: () => {
  256. this.createDialog('AutoRenewDialog', {
  257. name: i18n.t('dictionary.nat'),
  258. data: this.list.selectedItems,
  259. alert: this.$t('network.text_766'),
  260. columns: this.columns,
  261. onManager: this.onManager,
  262. refresh: this.refresh,
  263. })
  264. },
  265. meta: () => {
  266. const ret = checkReadOnly(this.list.selectedItems, this.$t('network.auto.renew'))
  267. if (!ret.validate) return ret
  268. if (!isOwner) {
  269. return {
  270. validate: false,
  271. tooltip: i18n.t('network.text_627'),
  272. }
  273. }
  274. if (!isAvailable) {
  275. ret.validate = false
  276. ret.tooltip = notAvailableTip
  277. return ret
  278. }
  279. if (!isPrepaid) {
  280. ret.validate = false
  281. ret.tooltip = i18n.t('network.nat.postpaid.unsupported')
  282. return ret
  283. }
  284. if (selectedLength === 0) {
  285. ret.validate = false
  286. ret.tooltip = notSelectedTooltip
  287. return ret
  288. }
  289. },
  290. },
  291. disableDeleteAction(this, {
  292. name: this.$t('dictionary.nat'),
  293. permission: 'natgateways_update',
  294. hidden: () => {
  295. if (!isOwner) {
  296. return {
  297. validate: false,
  298. tooltip: i18n.t('network.text_627'),
  299. }
  300. }
  301. },
  302. meta: () => {
  303. const ret = checkReadOnly(this.list.selectedItems, this.$t('common_277'))
  304. if (!ret.validate) return ret
  305. },
  306. }),
  307. {
  308. label: this.$t('network.text_131'),
  309. permission: 'natgateways_delete',
  310. action: () => {
  311. this.createDialog('DeleteResDialog', {
  312. vm: this,
  313. data: this.list.selectedItems,
  314. columns: this.columns,
  315. title: this.$t('network.text_131'),
  316. name: this.$t('dictionary.nat'),
  317. requestData: { force: true },
  318. onManager: this.onManager,
  319. })
  320. },
  321. meta: () => {
  322. const ret = checkReadOnly(this.list.selectedItems, this.$t('network.text_131'))
  323. if (!ret.validate) return ret
  324. if (!isOwner) {
  325. return {
  326. validate: false,
  327. tooltip: i18n.t('network.text_627'),
  328. }
  329. }
  330. return {
  331. validate: this.list.allowDelete(),
  332. }
  333. },
  334. },
  335. ]
  336. },
  337. meta: () => {
  338. const selectedLength = this.list.selectedItems.length
  339. return {
  340. validate: selectedLength,
  341. tooltip: '',
  342. }
  343. },
  344. },
  345. ],
  346. }
  347. },
  348. computed: {
  349. ...mapGetters(['isAdminMode', 'isDomainMode', 'userInfo']),
  350. exportDataOptions () {
  351. return {
  352. title: this.$t('dictionary.nat'),
  353. downloadType: 'local',
  354. items: [
  355. { field: 'id', title: 'ID' },
  356. ...this.columns,
  357. ],
  358. }
  359. },
  360. },
  361. created () {
  362. this.initSidePageTab('nat-detail')
  363. this.list.fetchData()
  364. },
  365. methods: {
  366. isOwner (obj) {
  367. if (this.isAdminMode) return true
  368. if (this.isDomainMode) return obj.domain_id === this.userInfo.projectDomainId
  369. return false
  370. },
  371. getParam () {
  372. const ret = {
  373. ...(R.is(Function, this.getParams) ? this.getParams() : this.getParams),
  374. detail: true,
  375. }
  376. return ret
  377. },
  378. handleOpenSidepage (row, tab) {
  379. this.sidePageTriggerHandle(this, 'NatSidePage', {
  380. id: row.id,
  381. resource: 'natgateways',
  382. getParams: this.getParam,
  383. }, {
  384. list: this.list,
  385. tab,
  386. })
  387. },
  388. },
  389. }
  390. </script>