You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

290 lines
9.5 KiB

  1. <template lang='pug'>
  2. v-card
  3. v-card(flat, :color='$vuetify.dark ? "grey darken-4" : "grey lighten-5"').pa-3.pt-4
  4. .admin-header-icon: v-icon(size='80', color='grey lighten-2') people
  5. .headline.blue--text.text--darken-2 Edit Group
  6. .subheading.grey--text {{name}}
  7. v-btn(color='primary', fab, absolute, bottom, right, small, to='/groups'): v-icon arrow_upward
  8. v-tabs(v-model='tab', :color='$vuetify.dark ? "primary" : "grey lighten-4"', fixed-tabs, :slider-color='$vuetify.dark ? "white" : "primary"', show-arrows)
  9. v-tab(key='properties') Properties
  10. v-tab(key='rights') Permissions
  11. v-tab(key='users') Users
  12. v-tab-item(key='properties', :transition='false', :reverse-transition='false')
  13. v-card
  14. v-card-text
  15. v-text-field(v-model='name', label='Group Name', counter='255', prepend-icon='people')
  16. v-card-actions.pa-3
  17. v-btn(color='primary', @click='updateGroup')
  18. v-icon(left) check
  19. | Save Changes
  20. .caption.ml-4.grey--text ID: {{group.id}}
  21. v-spacer
  22. v-dialog(v-model='deleteGroupDialog', max-width='500')
  23. v-btn(color='red', flat, @click='', slot='activator')
  24. v-icon(left) delete
  25. | Delete Group
  26. v-card
  27. .dialog-header.is-red Delete Group?
  28. v-card-text Are you sure you want to delete group #[strong {{ name }}]? All users will be unassigned from this group.
  29. v-card-actions
  30. v-spacer
  31. v-btn(flat, @click='deleteGroupDialog = false') Cancel
  32. v-btn(color='red', dark, @click='deleteGroup') Delete
  33. v-tab-item(key='rights', :transition='false', :reverse-transition='false')
  34. v-card
  35. v-card-title.pb-0
  36. v-subheader
  37. v-icon.mr-2 border_color
  38. .subheading Read and Write
  39. v-spacer
  40. v-btn(flat, outline)
  41. v-icon(left) arrow_drop_down
  42. | Load Preset
  43. v-btn(flat, outline)
  44. v-icon(left) vertical_align_bottom
  45. | Import Rules
  46. .pa-3.pl-4
  47. criterias
  48. v-divider.my-0
  49. v-card-title.pb-0
  50. v-subheader
  51. v-icon.mr-2 pageview
  52. .subheading Read Only
  53. v-spacer
  54. v-btn(flat, outline)
  55. v-icon(left) arrow_drop_down
  56. | Load Preset
  57. v-btn(flat, outline)
  58. v-icon(left) vertical_align_bottom
  59. | Import Rules
  60. .pa-3.pl-4
  61. criterias
  62. v-divider.my-0
  63. v-card-title.pb-0
  64. v-subheader Legend
  65. .px-4.pb-4
  66. .body-1.px-1.py-2 Any number of rules can be used at the same time. However, some rules requires more processing time than others. Rule types are color-coded as followed:
  67. .caption
  68. v-icon(color='blue') stop
  69. span Fast rules. None or insignificant latency introduced to all page loads.
  70. .caption
  71. v-icon(color='orange') stop
  72. span Medium rules. Some latency added to all page loads.
  73. .caption
  74. v-icon(color='red') stop
  75. span Slow rules. May adds noticeable latency to all page loads. Avoid using in multiple rules.
  76. v-tab-item(key='users', :transition='false', :reverse-transition='false')
  77. v-card
  78. v-card-title.pb-0
  79. v-btn(color='primary', @click='searchUserDialog = true')
  80. v-icon(left) assignment_ind
  81. | Assign User
  82. v-data-table(
  83. :items='group.users',
  84. :headers='headers',
  85. :search='search',
  86. :pagination.sync='pagination',
  87. :rows-per-page-items='[15]'
  88. hide-actions
  89. )
  90. template(slot='items', slot-scope='props')
  91. tr(:active='props.selected')
  92. td.text-xs-right {{ props.item.id }}
  93. td {{ props.item.name }}
  94. td {{ props.item.email }}
  95. td
  96. v-menu(bottom, right, min-width='200')
  97. v-btn(icon, slot='activator'): v-icon.grey--text.text--darken-1 more_horiz
  98. v-list
  99. v-list-tile(@click='unassignUser(props.item.id)')
  100. v-list-tile-action: v-icon(color='orange') highlight_off
  101. v-list-tile-content
  102. v-list-tile-title Unassign
  103. template(slot='no-data')
  104. v-alert.ma-3(icon='warning', :value='true', outline) No users to display.
  105. .text-xs-center.py-2(v-if='users.length > 15')
  106. v-pagination(v-model='pagination.page', :length='pages')
  107. user-search(v-model='searchUserDialog', @select='assignUser')
  108. </template>
  109. <script>
  110. import Criterias from '../common/criterias.vue'
  111. import UserSearch from '../common/user-search.vue'
  112. import groupQuery from 'gql/admin/groups/groups-query-single.gql'
  113. import assignUserMutation from 'gql/admin/groups/groups-mutation-assign.gql'
  114. import deleteGroupMutation from 'gql/admin/groups/groups-mutation-delete.gql'
  115. import unassignUserMutation from 'gql/admin/groups/groups-mutation-unassign.gql'
  116. import updateGroupMutation from 'gql/admin/groups/groups-mutation-update.gql'
  117. export default {
  118. components: {
  119. Criterias,
  120. UserSearch
  121. },
  122. data() {
  123. return {
  124. group: {
  125. id: 0,
  126. name: '',
  127. users: []
  128. },
  129. name: '',
  130. deleteGroupDialog: false,
  131. searchUserDialog: false,
  132. pagination: {},
  133. users: [],
  134. headers: [
  135. { text: 'ID', value: 'id', width: 50, align: 'right' },
  136. { text: 'Name', value: 'name' },
  137. { text: 'Email', value: 'email' },
  138. { text: '', value: 'actions', sortable: false, width: 50 }
  139. ],
  140. search: '',
  141. tab: '1'
  142. }
  143. },
  144. computed: {
  145. pages () {
  146. if (this.pagination.rowsPerPage == null || this.pagination.totalItems == null) {
  147. return 0
  148. }
  149. return Math.ceil(this.pagination.totalItems / this.pagination.rowsPerPage)
  150. }
  151. },
  152. watch: {
  153. group(newValue, oldValue) {
  154. this.name = newValue.name
  155. }
  156. },
  157. methods: {
  158. async updateGroup() {
  159. try {
  160. await this.$apollo.mutate({
  161. mutation: updateGroupMutation,
  162. variables: {
  163. id: this.group.id,
  164. name: this.name
  165. },
  166. watchLoading (isLoading) {
  167. this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-groups-update')
  168. }
  169. })
  170. this.$store.commit('showNotification', {
  171. style: 'success',
  172. message: `Group changes have been saved.`,
  173. icon: 'check'
  174. })
  175. } catch (err) {
  176. this.$store.commit('showNotification', {
  177. style: 'red',
  178. message: err.message,
  179. icon: 'warning'
  180. })
  181. }
  182. },
  183. async deleteGroup() {
  184. this.deleteGroupDialog = false
  185. try {
  186. await this.$apollo.mutate({
  187. mutation: deleteGroupMutation,
  188. variables: {
  189. id: this.group.id
  190. },
  191. watchLoading (isLoading) {
  192. this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-groups-delete')
  193. }
  194. })
  195. this.$store.commit('showNotification', {
  196. style: 'success',
  197. message: `Group ${this.group.name} has been deleted.`,
  198. icon: 'delete'
  199. })
  200. this.$router.replace('/groups')
  201. } catch (err) {
  202. this.$store.commit('showNotification', {
  203. style: 'red',
  204. message: err.message,
  205. icon: 'warning'
  206. })
  207. }
  208. },
  209. async assignUser(id) {
  210. try {
  211. await this.$apollo.mutate({
  212. mutation: assignUserMutation,
  213. variables: {
  214. groupId: this.group.id,
  215. userId: id
  216. },
  217. watchLoading (isLoading) {
  218. this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-groups-assign')
  219. }
  220. })
  221. this.$store.commit('showNotification', {
  222. style: 'success',
  223. message: `User has been assigned to ${this.group.name}.`,
  224. icon: 'assignment_ind'
  225. })
  226. this.$apollo.queries.group.refetch()
  227. } catch (err) {
  228. this.$store.commit('showNotification', {
  229. style: 'red',
  230. message: err.message,
  231. icon: 'warning'
  232. })
  233. }
  234. },
  235. async unassignUser(id) {
  236. try {
  237. await this.$apollo.mutate({
  238. mutation: unassignUserMutation,
  239. variables: {
  240. groupId: this.group.id,
  241. userId: id
  242. },
  243. watchLoading (isLoading) {
  244. this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-groups-unassign')
  245. }
  246. })
  247. this.$store.commit('showNotification', {
  248. style: 'success',
  249. message: `User has been unassigned from ${this.group.name}.`,
  250. icon: 'assignment_ind'
  251. })
  252. this.$apollo.queries.group.refetch()
  253. } catch (err) {
  254. this.$store.commit('showNotification', {
  255. style: 'red',
  256. message: err.message,
  257. icon: 'warning'
  258. })
  259. }
  260. }
  261. },
  262. apollo: {
  263. group: {
  264. query: groupQuery,
  265. variables() {
  266. return {
  267. id: this.$route.params.id
  268. }
  269. },
  270. fetchPolicy: 'network-only',
  271. update: (data) => data.groups.single,
  272. watchLoading (isLoading) {
  273. this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-groups-refresh')
  274. }
  275. }
  276. }
  277. }
  278. </script>
  279. <style lang='scss'>
  280. </style>