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.

198 lines
5.7 KiB

5 years ago
5 years ago
  1. <template lang="pug">
  2. div.user-table
  3. div.columns.is-multiline
  4. div.column.is-12
  5. a.button.is-primary(v-on:click="createNewRoleMapping()") Add Existing User
  6. div.column.is-12(v-if="newRoleMapping")
  7. div.box
  8. div.columns.is-multiline
  9. div.column
  10. b-field(
  11. label="User Name"
  12. v-bind:type="{ 'is-danger': getAddUserMessage }"
  13. v-bind:message="getAddUserMessage"
  14. )
  15. b-select(
  16. placeholder="e.g. Anne"
  17. v-model="newRoleMapping.username"
  18. v-on:input="option => {checkValidExistingUser(option);\
  19. newRoleMapping.userid = option}"
  20. )
  21. option(v-for="otherUser in otherUsers", v-bind:value="otherUser.id")
  22. | {{ otherUser.username }}
  23. div.column
  24. b-field(label="Role")
  25. b-select(
  26. placeholder="Select a role"
  27. v-model="newRoleMapping.roleid"
  28. )
  29. option(v-for="role in roles", v-bind:value="role.id", v-bind:key="role.id")
  30. | {{ role.name }}
  31. div.column
  32. div.field
  33. label.label &nbsp;
  34. div.field.is-grouped
  35. p.control
  36. b-button(type="is-light", v-on:click="cancelCreate()") Cancel
  37. p.control
  38. b-button(
  39. type="is-primary"
  40. v-on:click="addRoleMapping()"
  41. v-bind:disabled="isDisabled"
  42. ) Add User
  43. div.card
  44. b-table(v-bind:data="roleMappings", icon-pack="fas", default-sort="username", striped=true)
  45. template(slot-scope="props")
  46. b-table-column(field="username", label="User Name", sortable="")
  47. | {{ props.row.username }}
  48. b-table-column(field="rolename", label="Role", sortable="")
  49. b-dropdown(aria-role="list")
  50. button.button.is-primary(slot="trigger")
  51. span {{ props.row.rolename }}
  52. b-icon(icon="chevron-down", pack="fas", size="is-small", custom-size="fa-xs")
  53. b-dropdown-item(
  54. v-for="otherRole in getOtherRoles(props.row.role)"
  55. v-bind:key="otherRole.id"
  56. aria-role="listitem"
  57. v-on:click="switchRole(props.row.user, otherRole.id)"
  58. )
  59. | {{ otherRole.name }}
  60. b-table-column(label="Action")
  61. a.button.is-text(v-on:click="removeRoleMapping(props.row.id)")
  62. span.icon.is-small
  63. i.fas.fa-trash
  64. span Delete
  65. </template>
  66. <style>
  67. .user-table {
  68. padding: 40px 20px;
  69. }
  70. .user-table .table {
  71. width: 100%;
  72. }
  73. .user-table .card {
  74. padding: 20px 20px;
  75. }
  76. .user-table .has-addons {
  77. display: none;
  78. }
  79. </style>
  80. <script>
  81. import HTTP, { defaultHttpClient } from './http';
  82. export default {
  83. data: () => ({
  84. input: '',
  85. project: Object,
  86. newRoleMapping: null,
  87. hasNewUserError: false,
  88. roleMappings: [],
  89. allUsers: [],
  90. otherUsers: [],
  91. roles: [],
  92. }),
  93. computed: {
  94. isDisabled() {
  95. return !this.newRoleMapping.userid || !this.newRoleMapping.roleid || this.hasNewUserError;
  96. },
  97. getAddUserMessage() {
  98. if (this.hasNewUserError) {
  99. return 'Not an exsiting user!';
  100. }
  101. if (!this.otherUsers.length) {
  102. return 'No other users left to add!';
  103. }
  104. return null;
  105. },
  106. },
  107. created() {
  108. Promise.all([
  109. HTTP.get('roles'),
  110. defaultHttpClient.get('/v1/users'),
  111. defaultHttpClient.get('/v1/roles'),
  112. ]).then(([projectRoles, users, roles]) => {
  113. this.roleMappings = projectRoles.data;
  114. this.allUsers = users.data;
  115. this.otherUsers = this.getOtherUsers();
  116. this.roles = roles.data;
  117. });
  118. },
  119. methods: {
  120. createNewRoleMapping() {
  121. this.newRoleMapping = {
  122. userid: null,
  123. roleid: null,
  124. username: null,
  125. };
  126. },
  127. addRoleMapping() {
  128. HTTP.post('roles', { user: this.newRoleMapping.userid, role: this.newRoleMapping.roleid })
  129. .then((response) => {
  130. this.roleMappings.push(response.data);
  131. this.otherUsers = this.getOtherUsers();
  132. this.cancelCreate();
  133. });
  134. },
  135. checkValidExistingUser(inputValue) {
  136. this.hasNewUserError = !this.otherUsers.some(user => user.id === inputValue);
  137. return inputValue;
  138. },
  139. cancelCreate() {
  140. this.newRoleMapping = null;
  141. },
  142. removeRoleMapping(roleMappingId) {
  143. HTTP.delete(`roles/${roleMappingId}`).then(() => {
  144. this.roleMappings = this.roleMappings.filter(
  145. roleMapping => roleMapping.id !== roleMappingId,
  146. );
  147. this.otherUsers = this.getOtherUsers();
  148. });
  149. },
  150. switchRole(userId, newRoleId) {
  151. const currentRoleMapping = this.roleMappings.find(roleMapping => roleMapping.user === userId);
  152. const newRole = this.roles.find(role => role.id === newRoleId);
  153. HTTP.patch(`roles/${currentRoleMapping.id}`, { role: newRoleId }).then(() => {
  154. this.roleMappings = this.roleMappings.map((roleMapping) => {
  155. if (roleMapping.id === currentRoleMapping.id) {
  156. return {
  157. ...currentRoleMapping,
  158. role: newRole.id,
  159. rolename: newRole.name,
  160. };
  161. }
  162. return roleMapping;
  163. });
  164. });
  165. },
  166. getOtherRoles(currentRoleID) {
  167. return this.roles.filter(role => role.id !== currentRoleID);
  168. },
  169. getOtherUsers() {
  170. const currentUserIds = new Set(this.roleMappings.map(roleMapping => roleMapping.user));
  171. return this.allUsers.filter(user => !currentUserIds.has(user.id));
  172. },
  173. },
  174. };
  175. </script>