ProjectList.vue 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. <template>
  2. <page-list
  3. :list="list"
  4. :columns="columns"
  5. :group-actions="groupActions"
  6. :single-actions="singleActions"
  7. :export-data-options="exportDataOptions"
  8. default-search-key="projects" />
  9. </template>
  10. <script>
  11. import * as R from 'ramda'
  12. import {
  13. getNameDescriptionTableColumn,
  14. getProjectDomainTableColumn,
  15. } from '@/utils/common/tableColumn'
  16. import i18n from '@/locales'
  17. import WindowsMixin from '@/mixins/windows'
  18. import ListMixin from '@/mixins/list'
  19. export default {
  20. name: 'GroupProjectList',
  21. mixins: [WindowsMixin, ListMixin],
  22. props: {
  23. resId: String,
  24. id: String,
  25. getParams: {
  26. type: Object,
  27. },
  28. data: {
  29. type: Object,
  30. },
  31. },
  32. data () {
  33. return {
  34. list: this.$list.createList(this, {
  35. id: this.id,
  36. resource: this.getList,
  37. getParams: this.getParam,
  38. idKey: '__index',
  39. filterOptions: {
  40. projects: {
  41. label: i18n.t('dictionary.project'),
  42. },
  43. },
  44. }),
  45. // exportDataOptions: {
  46. // items: [
  47. // { label: 'ID', key: 'id' },
  48. // { label: this.$t('table.title.name'), key: 'name' },
  49. // { label: this.$t('dictionary.role'), key: 'roles' },
  50. // ],
  51. // },
  52. columns: [
  53. {
  54. title: this.$t('common_389'),
  55. field: 'name',
  56. slots: {
  57. default: ({ row }) => {
  58. return [
  59. <list-body-cell-wrap copy row={row} onManager={this.onManager} field='name' title={row.name} message={row.name} hideField={true}>
  60. <side-page-trigger permission='projects_get' name='ProjectSidePage' id={row.id} vm={this}>{ row.name }</side-page-trigger>
  61. </list-body-cell-wrap>,
  62. ]
  63. },
  64. },
  65. },
  66. {
  67. field: 'roles',
  68. title: this.$t('dictionary.role'),
  69. formatter: ({ cellValue }) => {
  70. return cellValue.map(x => x.name).join(', ')
  71. },
  72. },
  73. {
  74. title: this.$t('dictionary.policy'),
  75. field: 'role',
  76. slots: {
  77. default: ({ row }) => {
  78. if (R.isNil(row.policies) || R.isEmpty(row.policies)) return '-'
  79. Object.values(row.policies).flat(Infinity).join(', ')
  80. const policies = Object.values(row.policies).flat(Infinity)
  81. const ret = policies.map((item, idx) => {
  82. return (
  83. <div style="display: inline-block;">
  84. <side-page-trigger permission='policies_get' name='PolicySidePage' id={item} vm={this}>{ item }</side-page-trigger>
  85. { idx !== policies.length - 1 ? '、' : '' }
  86. </div>
  87. )
  88. })
  89. return ret
  90. },
  91. },
  92. },
  93. {
  94. title: this.$t('table.title.owner_domain'),
  95. field: 'project_domain',
  96. slots: {
  97. default: ({ row }) => {
  98. return row.domain?.name || '-'
  99. },
  100. },
  101. },
  102. ],
  103. groupActions: [
  104. {
  105. label: this.$t('common_384'),
  106. permission: 'projects_perform_join',
  107. action: () => {
  108. this.createDialog('GroupJoinProjectDialog', {
  109. data: [this.data],
  110. columns: [
  111. getNameDescriptionTableColumn({
  112. onManager: this.onManager,
  113. hideField: true,
  114. slotCallback: row => {
  115. return (
  116. <side-page-trigger onTrigger={ () => this.handleOpenSidepage(row) }>{ row.name }</side-page-trigger>
  117. )
  118. },
  119. formRules: [{
  120. required: true,
  121. message: i18n.t('system.text_168'),
  122. whitespace: true,
  123. }],
  124. }),
  125. getProjectDomainTableColumn(),
  126. ],
  127. success: () => {
  128. this.refresh()
  129. this.$bus.$emit('GroupUserListRefresh')
  130. },
  131. })
  132. },
  133. meta: () => {
  134. return {
  135. buttonType: 'primary',
  136. }
  137. },
  138. },
  139. {
  140. label: this.$t('compute.text_950'),
  141. permission: 'projects_perform_leave',
  142. action: () => {
  143. this.createDialog('GroupLeaveProjectDialog', {
  144. data: this.list.selectedItems,
  145. columns: this.columns,
  146. resId: this.resId,
  147. success: () => {
  148. this.list.refresh()
  149. },
  150. })
  151. },
  152. meta: () => {
  153. return {
  154. validate: this.list.selectedItems.length >= 1,
  155. }
  156. },
  157. },
  158. ],
  159. singleActions: [
  160. {
  161. label: this.$t('common_490'),
  162. permission: 'projects_perform_join',
  163. action: (obj) => {
  164. this.createDialog('GroupEditRolesDialog', {
  165. data: [obj],
  166. columns: this.columns,
  167. title: this.$t('common_490'),
  168. uid: this.data.id,
  169. refresh: this.refresh,
  170. })
  171. },
  172. },
  173. {
  174. label: this.$t('compute.text_950'),
  175. permission: 'projects_perform_leave',
  176. action: (obj) => {
  177. this.createDialog('GroupLeaveProjectDialog', {
  178. data: [obj],
  179. columns: this.columns,
  180. resId: this.resId,
  181. success: () => {
  182. this.list.refresh()
  183. },
  184. })
  185. },
  186. },
  187. ],
  188. }
  189. },
  190. created () {
  191. this.list.fetchData()
  192. },
  193. methods: {
  194. async getList (params) {
  195. if (params.projects) {
  196. params.projects.map((item, index) => {
  197. params[`projects.${index}`] = item
  198. })
  199. Reflect.deleteProperty(params, 'projects')
  200. }
  201. const { data: { data } } = await new this.$Manager('role_assignments', 'v1').objectRpc({
  202. methodname: 'GetProjectRole',
  203. objId: this.data.id,
  204. params: {
  205. ...params,
  206. ...this.getParams,
  207. scope: this.$store.getters.scope,
  208. show_fail_reason: true,
  209. resource: 'group',
  210. group_by: 'project',
  211. limit: 20,
  212. },
  213. })
  214. return new Promise((resolve, reject) => {
  215. const ret = this.genResourceData(data)
  216. resolve(ret)
  217. })
  218. },
  219. genResourceData (data) {
  220. const arr = []
  221. data.map((item) => {
  222. const { groups, domain } = item
  223. groups.map((group, index) => {
  224. const { id, name } = item
  225. const obj = {
  226. id,
  227. name,
  228. __index: id + index,
  229. }
  230. const { id: groupId, name: groupName, roles, policies } = group
  231. if (groupId && groupName) {
  232. obj.groupId = groupId
  233. obj.groupName = groupName
  234. }
  235. obj.roles = roles
  236. obj.policies = policies
  237. obj.domain = domain
  238. arr.push(obj)
  239. })
  240. })
  241. const ret = {
  242. data: {
  243. data: arr,
  244. total: arr.length,
  245. },
  246. }
  247. return ret
  248. },
  249. getParam () {
  250. const ret = {
  251. ...this.getParams,
  252. details: true,
  253. }
  254. return ret
  255. },
  256. },
  257. }
  258. </script>