]> BookStack Code Mirror - bookstack/blob - resources/js/components/entity-permissions.js
Improved user-permissions adding ux
[bookstack] / resources / js / components / entity-permissions.js
1 import {htmlToDom} from "../services/dom";
2 import {Component} from "./component";
3
4 export class EntityPermissions extends Component {
5
6     setup() {
7         this.container = this.$el;
8         this.entityType = this.$opts.entityType;
9
10         this.everyoneInheritToggle = this.$refs.everyoneInherit;
11         this.roleSelect = this.$refs.roleSelect;
12         this.roleContainer = this.$refs.roleContainer;
13         this.userContainer = this.$refs.userContainer;
14         this.userSelectContainer = this.$refs.userSelectContainer;
15
16         this.setupListeners();
17     }
18
19     setupListeners() {
20         // "Everyone Else" inherit toggle
21         this.everyoneInheritToggle.addEventListener('change', event => {
22             const inherit = event.target.checked;
23             const permissions = document.querySelectorAll('input[name^="permissions[0]["]');
24             for (const permission of permissions) {
25                 permission.disabled = inherit;
26                 permission.checked = false;
27             }
28         });
29
30         // Remove role row button click
31         this.container.addEventListener('click', event => {
32             const button = event.target.closest('button');
33             if (button && button.dataset.modelType) {
34                 this.removeRowOnButtonClick(button)
35             }
36         });
37
38         // Role select change
39         this.roleSelect.addEventListener('change', event => {
40             const roleId = this.roleSelect.value;
41             if (roleId) {
42                 this.addRoleRow(roleId);
43             }
44         });
45
46         // User select change
47         this.userSelectContainer.querySelector('input[name="user_select"]').addEventListener('change', event => {
48             const userId = event.target.value;
49             if (userId) {
50                 this.addUserRow(userId);
51             }
52         });
53     }
54
55     async addRoleRow(roleId) {
56         this.roleSelect.disabled = true;
57
58         // Remove option from select
59         const option = this.roleSelect.querySelector(`option[value="${roleId}"]`);
60         if (option) {
61             option.remove();
62         }
63
64         // Get and insert new row
65         const resp = await window.$http.get(`/permissions/role-form-row/${this.entityType}/${roleId}`);
66         const row = htmlToDom(resp.data);
67         this.roleContainer.append(row);
68
69         this.roleSelect.disabled = false;
70     }
71
72     async addUserRow(userId) {
73         const exists = this.userContainer.querySelector(`[name^="permissions[user][${userId}]"]`) !== null;
74         if (exists) {
75             return;
76         }
77
78         const toggle = this.userSelectContainer.querySelector('.dropdown-search-toggle-select');
79         toggle.classList.add('disabled');
80         this.userContainer.style.pointerEvents = 'none';
81
82         // Get and insert new row
83         const resp = await window.$http.get(`/permissions/user-form-row/${this.entityType}/${userId}`);
84         const row = htmlToDom(resp.data);
85         this.userContainer.append(row);
86
87         toggle.classList.remove('disabled');
88         this.userContainer.style.pointerEvents = null;
89
90         /** @var {UserSelect} **/
91         const userSelect = window.$components.firstOnElement(this.userSelectContainer.querySelector('.dropdown-search'), 'user-select');
92         userSelect.reset();
93     }
94
95     removeRowOnButtonClick(button) {
96         const row = button.closest('.item-list-row');
97         const modelId = button.dataset.modelId;
98         const modelName = button.dataset.modelName;
99         const modelType = button.dataset.modelType;
100
101         const option = document.createElement('option');
102         option.value = modelId;
103         option.textContent = modelName;
104
105         if (modelType === 'role') {
106             this.roleSelect.append(option);
107         }
108
109         row.remove();
110     }
111
112 }