Group.vue 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. <template>
  2. <div class="mb-2 group-wrap" :class="{ active: showContent }">
  3. <div class="d-flex">
  4. <div class="d-flex group-title" @click.stop.prevent="toggleContent">
  5. <div>{{ group.label }}</div>
  6. <div class="arrow-icon">
  7. <a-icon type="down" class="ml-2" />
  8. </div>
  9. </div>
  10. <div>
  11. <div>
  12. <a-checkbox
  13. :checked="group.checkAll"
  14. @change="handleCheckAllChange"
  15. :indeterminate="group.isIndeterminate"
  16. :disabled="group.disabled">{{$t('system.text_320')}}</a-checkbox>
  17. </div>
  18. </div>
  19. </div>
  20. <a-card v-show="showContent">
  21. <template v-for="(item, idx) of group.resources">
  22. <div v-if="showResource(item)" v-show="hasSearchString(item)" :key="idx">
  23. <item
  24. :resource="item"
  25. @resourceCheckChange="resourceCheckChange"
  26. :permissions="permissions"
  27. :scope="scope"
  28. :itemPolicy="getItemPolicy(item)" />
  29. </div>
  30. </template>
  31. </a-card>
  32. </div>
  33. </template>
  34. <script>
  35. // import * as R from 'ramda'
  36. import yaml from 'js-yaml'
  37. import { SCOPES_MAP } from '@/constants'
  38. import { POLICY_RES_NAME_KEY_MAP } from '@/constants/policy'
  39. import Item from './Item'
  40. export default {
  41. name: 'PolicyRuleCheckboxGroup',
  42. components: {
  43. Item,
  44. },
  45. props: {
  46. group: Object,
  47. permissions: Object,
  48. scope: String,
  49. policy: Object,
  50. searchString: String,
  51. },
  52. data () {
  53. return {
  54. showContent: false,
  55. }
  56. },
  57. watch: {
  58. scope: {
  59. handler () {
  60. this.resourceCheckChange()
  61. },
  62. immediate: true,
  63. },
  64. },
  65. methods: {
  66. toggleContent () {
  67. this.showContent = !this.showContent
  68. },
  69. handleCheckAllChange (e) {
  70. const val = e.target.checked
  71. let groupCheckAll = true
  72. let groupIndeterminate = false
  73. const resources = this.group.resources.map(resource => {
  74. const unDisabledActions = resource.actions.filter(item => !item.disabled)
  75. const checked = val ? unDisabledActions.map(action => action.action) : []
  76. // let checked = []
  77. // if (val) {
  78. // if (resource.isIndeterminate) {
  79. // checked = []
  80. // } else {
  81. // checked = unDisabledActions.map(action => action.action)
  82. // }
  83. // } else {
  84. // if (!resource.isIndeterminate) {
  85. // checked = []
  86. // } else {
  87. // checked = unDisabledActions.map(action => action.action)
  88. // }
  89. // }
  90. const isIndeterminate = checked.length > 0 && checked.length < resource.actions.length
  91. const checkAll = checked.length === resource.actions.length
  92. let show = true
  93. if (this.scope === SCOPES_MAP.project.key) {
  94. if (resource.isDomainRes || resource.isSystemRes) show = false
  95. } else if (this.scope === SCOPES_MAP.domain.key) {
  96. if (resource.isSystemRes) show = false
  97. }
  98. if (show) {
  99. if (isIndeterminate) {
  100. groupIndeterminate = true
  101. }
  102. if (!checkAll) {
  103. groupCheckAll = false
  104. }
  105. }
  106. return {
  107. ...resource,
  108. isIndeterminate,
  109. checkAll,
  110. checked,
  111. }
  112. })
  113. this.$set(this.group, 'checkAll', groupCheckAll)
  114. this.$set(this.group, 'resources', resources)
  115. this.$set(this.group, 'isIndeterminate', groupIndeterminate)
  116. this.$emit('groupCheckChange')
  117. },
  118. resourceCheckChange () {
  119. let checkAll = true
  120. let checkedActionsTotal = 0
  121. let allActionsTotal = 0
  122. for (let i = 0, len = this.group.resources.length; i < len; i++) {
  123. const item = this.group.resources[i]
  124. let isContinue = true
  125. if (this.scope === SCOPES_MAP.project.key) {
  126. if (item.isDomainRes || item.isSystemRes) isContinue = false
  127. } else if (this.scope === SCOPES_MAP.domain.key) {
  128. if (item.isSystemRes) isContinue = false
  129. }
  130. if (!isContinue || item.resource === 'servers') continue
  131. const checkedCount = item.checked.length
  132. checkedActionsTotal += checkedCount
  133. allActionsTotal += item.actions.length
  134. if (checkedCount !== item.actions.length) {
  135. checkAll = false
  136. }
  137. }
  138. const isIndeterminate = checkedActionsTotal > 0 && checkedActionsTotal < allActionsTotal
  139. this.$set(this.group, 'checkAll', checkAll)
  140. this.$set(this.group, 'isIndeterminate', isIndeterminate)
  141. this.$emit('groupCheckChange')
  142. },
  143. showResource (resource) {
  144. let show = true
  145. if (this.scope === SCOPES_MAP.project.key) {
  146. if (resource.isDomainRes || resource.isSystemRes) show = false
  147. } else if (this.scope === SCOPES_MAP.domain.key) {
  148. if (resource.isSystemRes) show = false
  149. }
  150. if (Object.values(POLICY_RES_NAME_KEY_MAP).find(item => item.resource === resource.resource)) {
  151. show = false
  152. }
  153. return show
  154. },
  155. getItemPolicy (item) {
  156. if (item.resource === '*' && this.policy) {
  157. const { policy = {} } = yaml.safeLoad(this.policy)
  158. if (policy[item.service]) {
  159. return policy[item.service]['*'] || {}
  160. }
  161. }
  162. return {}
  163. },
  164. hasSearchString (item) {
  165. if (!this.searchString) {
  166. return true
  167. }
  168. if (item.label && item.label.includes(this.searchString)) {
  169. return true
  170. }
  171. return false
  172. },
  173. },
  174. }
  175. </script>
  176. <style lang="less" scoped>
  177. .group-title {
  178. width: 100px;
  179. cursor: pointer;
  180. }
  181. .active {
  182. .arrow-icon {
  183. > i {
  184. transform: rotate(180deg);
  185. }
  186. }
  187. }
  188. .group-wrap {
  189. .arrow-icon {
  190. > i {
  191. transition: transform 0.3s ease;
  192. }
  193. }
  194. }
  195. </style>