zrb 1.2.2__py3-none-any.whl → 1.3.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- zrb/builtin/llm/llm_chat.py +42 -6
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/column/add_column_util.py +28 -6
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/template/app_template/module/gateway/view/content/my-module/my-entity.html +206 -178
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/template/app_template/schema/my_entity.py +3 -1
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/role/repository/role_db_repository.py +18 -1
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/role/repository/role_repository.py +4 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/role/role_service.py +20 -11
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/repository/user_db_repository.py +17 -2
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/repository/user_repository.py +4 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/user_service.py +19 -11
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/content/auth/permission.html +209 -180
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/content/auth/role.html +362 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/content/auth/user.html +377 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/common/util.js +68 -13
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/crud/util.js +50 -29
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/schema/permission.py +3 -1
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/schema/role.py +6 -5
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/schema/user.py +9 -3
- zrb/input/any_input.py +5 -0
- zrb/input/base_input.py +6 -0
- zrb/input/bool_input.py +2 -0
- zrb/input/float_input.py +2 -0
- zrb/input/int_input.py +2 -0
- zrb/input/option_input.py +2 -0
- zrb/input/password_input.py +2 -0
- zrb/input/text_input.py +2 -0
- zrb/runner/cli.py +1 -1
- zrb/runner/common_util.py +3 -3
- zrb/runner/web_route/task_input_api_route.py +1 -1
- {zrb-1.2.2.dist-info → zrb-1.3.0.dist-info}/METADATA +84 -17
- {zrb-1.2.2.dist-info → zrb-1.3.0.dist-info}/RECORD +33 -33
- {zrb-1.2.2.dist-info → zrb-1.3.0.dist-info}/WHEEL +0 -0
- {zrb-1.2.2.dist-info → zrb-1.3.0.dist-info}/entry_points.txt +0 -0
@@ -20,6 +20,10 @@ class UserRepository(ABC):
|
|
20
20
|
async def get_by_ids(self, id_list: list[str]) -> UserResponse:
|
21
21
|
"""Get users by ids"""
|
22
22
|
|
23
|
+
@abstractmethod
|
24
|
+
async def validate_role_names(self, role_names: list[str]):
|
25
|
+
"""Validate Role names"""
|
26
|
+
|
23
27
|
@abstractmethod
|
24
28
|
async def add_roles(self, data: dict[str, list[str]], created_by: str):
|
25
29
|
"""Add roles to user"""
|
@@ -143,13 +143,15 @@ class UserService(BaseService):
|
|
143
143
|
async def create_user_bulk(
|
144
144
|
self, data: list[UserCreateWithRolesAndAudit]
|
145
145
|
) -> list[UserResponse]:
|
146
|
-
|
147
|
-
|
148
|
-
|
146
|
+
bulk_role_names = [row.get_role_names() for row in data]
|
147
|
+
for role_names in bulk_role_names:
|
148
|
+
await self.user_repository.validate_role_names(role_names)
|
149
|
+
bulk_user_data = [row.get_user_create_with_audit() for row in data]
|
150
|
+
users = await self.user_repository.create_bulk(bulk_user_data)
|
149
151
|
if len(users) > 0:
|
150
152
|
created_by = users[0].created_by
|
151
153
|
await self.user_repository.add_roles(
|
152
|
-
data={user.id:
|
154
|
+
data={user.id: bulk_role_names[i] for i, user in enumerate(users)},
|
153
155
|
created_by=created_by,
|
154
156
|
)
|
155
157
|
return await self.user_repository.get_by_ids([user.id for user in users])
|
@@ -161,8 +163,9 @@ class UserService(BaseService):
|
|
161
163
|
)
|
162
164
|
async def create_user(self, data: UserCreateWithRolesAndAudit) -> UserResponse:
|
163
165
|
role_names = data.get_role_names()
|
164
|
-
|
165
|
-
|
166
|
+
await self.user_repository.validate_role_names(role_names)
|
167
|
+
user_data = data.get_user_create_with_audit()
|
168
|
+
user = await self.user_repository.create(user_data)
|
166
169
|
await self.user_repository.add_roles(
|
167
170
|
data={user.id: role_names}, created_by=user.created_by
|
168
171
|
)
|
@@ -176,14 +179,18 @@ class UserService(BaseService):
|
|
176
179
|
async def update_user_bulk(
|
177
180
|
self, user_ids: list[str], data: UserUpdateWithRolesAndAudit
|
178
181
|
) -> list[UserResponse]:
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
+
bulk_role_names = [row.get_role_names() for row in data]
|
183
|
+
for role_names in bulk_role_names:
|
184
|
+
await self.user_repository.validate_role_names(role_names)
|
185
|
+
bulk_user_data = [row.get_user_update_with_audit() for row in data]
|
186
|
+
await self.user_repository.update_bulk(user_ids, bulk_user_data)
|
182
187
|
if len(user_ids) > 0:
|
183
|
-
updated_by =
|
188
|
+
updated_by = bulk_user_data[0].updated_by
|
184
189
|
await self.user_repository.remove_all_roles(user_ids)
|
185
190
|
await self.user_repository.add_roles(
|
186
|
-
data={
|
191
|
+
data={
|
192
|
+
user_id: bulk_role_names[i] for i, user_id in enumerate(user_ids)
|
193
|
+
},
|
187
194
|
updated_by=updated_by,
|
188
195
|
)
|
189
196
|
return await self.user_repository.get_by_ids(user_ids)
|
@@ -197,6 +204,7 @@ class UserService(BaseService):
|
|
197
204
|
self, user_id: str, data: UserUpdateWithRolesAndAudit
|
198
205
|
) -> UserResponse:
|
199
206
|
role_names = data.get_role_names()
|
207
|
+
await self.user_repository.validate_role_names(role_names)
|
200
208
|
user_data = data.get_user_update_with_audit()
|
201
209
|
await self.user_repository.update(user_id, user_data)
|
202
210
|
await self.user_repository.remove_all_roles([user_id])
|
@@ -1,14 +1,22 @@
|
|
1
1
|
<link rel="stylesheet" href="/static/crud/style.css">
|
2
2
|
|
3
|
-
<main
|
3
|
+
<main id="crud-app"
|
4
|
+
class="container"
|
5
|
+
data-page-size='{{ page_size | tojson }}'
|
6
|
+
data-page='{{ page | tojson }}'
|
7
|
+
data-sort='{{ sort | tojson }}'
|
8
|
+
data-filter='{{ filter | tojson }}'
|
9
|
+
data-allow-create='{{ allow_create | tojson }}'
|
10
|
+
data-allow-update='{{ allow_update | tojson }}'
|
11
|
+
data-allow-delete='{{ allow_delete | tojson }}'>
|
4
12
|
<article>
|
5
13
|
<h1>Permission</h1>
|
6
14
|
|
7
15
|
<fieldset id="crud-table-fieldset" role="group" class="grid">
|
8
|
-
<input id="crud-filter"
|
9
|
-
<button
|
16
|
+
<input id="crud-filter-input" placeholder="🔍 Filter" aria-label="Search" />
|
17
|
+
<button id="crud-search-button">🔍 Search</button>
|
10
18
|
{% if allow_create %}
|
11
|
-
<button
|
19
|
+
<button id="crud-show-create-button" class="contrast">➕ Add</button>
|
12
20
|
{% endif %}
|
13
21
|
</fieldset>
|
14
22
|
<div id="crud-table-container">
|
@@ -18,7 +26,6 @@
|
|
18
26
|
<th scope="col">ID</th>
|
19
27
|
<th scope="col">Name</th>
|
20
28
|
<th scope="col">Description</th>
|
21
|
-
<!-- Update this -->
|
22
29
|
{% if allow_update or allow_delete %}
|
23
30
|
<th scope="col">Actions</th>
|
24
31
|
{% endif %}
|
@@ -42,10 +49,9 @@
|
|
42
49
|
Description:
|
43
50
|
<input type="text" name="description" required>
|
44
51
|
</label>
|
45
|
-
<!-- Update this -->
|
46
52
|
<footer>
|
47
|
-
<button
|
48
|
-
<button
|
53
|
+
<button id="crud-create-button">➕ Save</button>
|
54
|
+
<button id="crud-cancel-create-button" class="secondary">❌ Cancel</button>
|
49
55
|
</footer>
|
50
56
|
</form>
|
51
57
|
</article>
|
@@ -65,10 +71,9 @@
|
|
65
71
|
Description:
|
66
72
|
<input type="text" name="description" required>
|
67
73
|
</label>
|
68
|
-
<!-- Update this -->
|
69
74
|
<footer>
|
70
|
-
<button
|
71
|
-
<button
|
75
|
+
<button id="crud-update-button">✏️ Save</button>
|
76
|
+
<button id="crud-cancel-update-button" class="secondary">❌ Cancel</button>
|
72
77
|
</footer>
|
73
78
|
</form>
|
74
79
|
</article>
|
@@ -88,10 +93,9 @@
|
|
88
93
|
Description:
|
89
94
|
<input type="text" name="description" readonly>
|
90
95
|
</label>
|
91
|
-
<!-- Update this -->
|
92
96
|
<footer>
|
93
|
-
<button
|
94
|
-
<button
|
97
|
+
<button id="crud-cancel-delete-button" class="secondary">❌ Cancel</button>
|
98
|
+
<button id="crud-delete-button">🗑️ Delete</button>
|
95
99
|
</footer>
|
96
100
|
</form>
|
97
101
|
</article>
|
@@ -103,209 +107,234 @@
|
|
103
107
|
<h2 id="crud-alert-title">Error</h2>
|
104
108
|
<pre id="crud-alert-message"></pre>
|
105
109
|
<footer>
|
106
|
-
<button
|
110
|
+
<button id="crud-alert-close-button">Close</button>
|
107
111
|
</footer>
|
108
112
|
</article>
|
109
113
|
</dialog>
|
110
|
-
|
111
114
|
</article>
|
112
115
|
</main>
|
113
116
|
|
114
117
|
<script src="/static/crud/util.js"></script>
|
115
118
|
<script>
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
allowCreate: {{allow_create | tojson}},
|
123
|
-
allowUpdate: {{allow_update | tojson}},
|
124
|
-
allowDelete: {{allow_delete | tojson}},
|
125
|
-
updatedRowId: null,
|
126
|
-
deletedRowId: null,
|
127
|
-
};
|
119
|
+
class CrudApp {
|
120
|
+
constructor(apiUrl, initialState) {
|
121
|
+
this.apiUrl = apiUrl;
|
122
|
+
this.state = { ...initialState };
|
123
|
+
this.init();
|
124
|
+
}
|
128
125
|
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
126
|
+
init() {
|
127
|
+
// Cache common elements
|
128
|
+
this.filterInput = document.getElementById("crud-filter-input");
|
129
|
+
this.searchButton = document.getElementById("crud-search-button");
|
130
|
+
this.filterInput.value = this.state.filter;
|
134
131
|
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
const crudPagination = document.getElementById("crud-pagination");
|
152
|
-
CRUD_UTIL.renderPagination(
|
153
|
-
crudPagination, crudState, result.count, "fetchRows"
|
154
|
-
);
|
155
|
-
} catch (error) {
|
156
|
-
console.error("Error fetching items:", error);
|
132
|
+
// Bind events
|
133
|
+
this.filterInput.addEventListener("change", (e) => this.applySearch(e));
|
134
|
+
this.searchButton.addEventListener("click", (e) => this.applySearch(e));
|
135
|
+
|
136
|
+
// Attach optional events
|
137
|
+
this.attachEvent("crud-show-create-button", this.showCreateForm.bind(this));
|
138
|
+
this.attachEvent("crud-create-button", this.createRow.bind(this));
|
139
|
+
this.attachEvent("crud-cancel-create-button", this.hideCreateForm.bind(this));
|
140
|
+
this.attachEvent("crud-update-button", this.updateRow.bind(this));
|
141
|
+
this.attachEvent("crud-cancel-update-button", this.hideUpdateForm.bind(this));
|
142
|
+
this.attachEvent("crud-delete-button", this.deleteRow.bind(this));
|
143
|
+
this.attachEvent("crud-cancel-delete-button", this.hideDeleteForm.bind(this));
|
144
|
+
this.attachEvent("crud-alert-close-button", this.hideAlert.bind(this));
|
145
|
+
|
146
|
+
// Initial data fetch
|
147
|
+
this.fetchRows(this.state.currentPage);
|
157
148
|
}
|
158
|
-
}
|
159
149
|
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
if (
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
150
|
+
attachEvent(elementId, handler) {
|
151
|
+
const el = document.getElementById(elementId);
|
152
|
+
if (el) el.addEventListener("click", handler);
|
153
|
+
}
|
154
|
+
|
155
|
+
async applySearch(event) {
|
156
|
+
if (event) event.preventDefault();
|
157
|
+
this.state.filter = this.filterInput.value;
|
158
|
+
await this.fetchRows(this.state.currentPage);
|
159
|
+
}
|
160
|
+
|
161
|
+
async fetchRows(page = null) {
|
162
|
+
try {
|
163
|
+
if (page !== null) {
|
164
|
+
this.state.currentPage = page;
|
165
|
+
}
|
166
|
+
const defaultSearchColumn = "name";
|
167
|
+
// Update address bar
|
168
|
+
const searchParam = CRUD_UTIL.getSearchParam(this.state, defaultSearchColumn, false);
|
169
|
+
const newUrl = `${window.location.pathname}?${searchParam}`;
|
170
|
+
window.history.pushState({ path: newUrl }, "", newUrl);
|
171
|
+
|
172
|
+
// Fetch table data
|
173
|
+
const apiSearchParam = CRUD_UTIL.getSearchParam(this.state, defaultSearchColumn, true);
|
174
|
+
const result = await UTIL.fetchAPI(`${this.apiUrl}?${apiSearchParam}`, { method: "GET" });
|
175
|
+
this.renderRows(result.data);
|
176
|
+
const crudPagination = document.getElementById("crud-pagination");
|
177
|
+
CRUD_UTIL.renderPagination(crudPagination, this, result.count);
|
178
|
+
} catch (error) {
|
179
|
+
console.error("Error fetching items:", error);
|
174
180
|
}
|
175
|
-
|
176
|
-
});
|
177
|
-
}
|
181
|
+
}
|
178
182
|
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
183
|
+
renderRows(rows) {
|
184
|
+
const tableBody = document.querySelector("#crud-table tbody");
|
185
|
+
let tableBodyHTML = "";
|
186
|
+
rows.forEach(row => {
|
187
|
+
const rowComponents = this.getRowComponents(row);
|
188
|
+
let actionColumn = "";
|
189
|
+
if (this.state.allowUpdate) {
|
190
|
+
actionColumn += `<button class="contrast" data-id="${row.id}" data-action="edit">✏️ Edit</button>`;
|
191
|
+
}
|
192
|
+
if (this.state.allowDelete) {
|
193
|
+
actionColumn += `<button class="secondary" data-id="${row.id}" data-action="delete">🗑️ Delete</button>`;
|
194
|
+
}
|
195
|
+
if (this.state.allowUpdate || this.state.allowDelete) {
|
196
|
+
actionColumn = `<td><fieldset class="grid" role="group">${actionColumn}</fieldset></td>`;
|
197
|
+
}
|
198
|
+
tableBodyHTML += `<tr>${rowComponents.join('')}${actionColumn}</tr>`;
|
199
|
+
});
|
200
|
+
tableBody.innerHTML = tableBodyHTML;
|
201
|
+
this.attachRowActionListeners();
|
202
|
+
}
|
187
203
|
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
204
|
+
attachRowActionListeners() {
|
205
|
+
document.querySelectorAll('button[data-action="edit"]').forEach(button => {
|
206
|
+
button.addEventListener("click", () => {
|
207
|
+
this.showUpdateForm(button.getAttribute("data-id"));
|
208
|
+
});
|
209
|
+
});
|
210
|
+
document.querySelectorAll('button[data-action="delete"]').forEach(button => {
|
211
|
+
button.addEventListener("click", () => {
|
212
|
+
this.showDeleteForm(button.getAttribute("data-id"));
|
213
|
+
});
|
214
|
+
});
|
215
|
+
}
|
195
216
|
|
196
|
-
|
197
|
-
|
198
|
-
|
217
|
+
getRowComponents(row) {
|
218
|
+
return [
|
219
|
+
`<td>${row.id}</td>`,
|
220
|
+
`<td>${row.name}</td>`,
|
221
|
+
`<td>${row.description}</td>`
|
222
|
+
];
|
199
223
|
}
|
200
|
-
|
224
|
+
|
225
|
+
// Create methods
|
226
|
+
showCreateForm(event = null) {
|
227
|
+
if (event) event.preventDefault();
|
228
|
+
const createDialog = document.getElementById("crud-create-form-dialog");
|
201
229
|
const createForm = document.getElementById("crud-create-form");
|
202
|
-
|
203
|
-
|
204
|
-
await fetchRows();
|
205
|
-
hideCreateForm();
|
206
|
-
} catch(error) {
|
207
|
-
showAlert("Create Permission Error", error);
|
230
|
+
UTIL.clearFormData(createForm);
|
231
|
+
createDialog.showModal();
|
208
232
|
}
|
209
|
-
}
|
210
233
|
|
211
|
-
|
212
|
-
|
213
|
-
|
234
|
+
async createRow(event = null) {
|
235
|
+
if (event) event.preventDefault();
|
236
|
+
try {
|
237
|
+
const createForm = document.getElementById("crud-create-form");
|
238
|
+
const formData = UTIL.getFormData(createForm);
|
239
|
+
await UTIL.fetchAPI(this.apiUrl, { method: "POST", body: JSON.stringify(formData) });
|
240
|
+
await this.fetchRows();
|
241
|
+
this.hideCreateForm();
|
242
|
+
} catch (error) {
|
243
|
+
console.error(error);
|
244
|
+
this.showAlert("Create Permission Error", error);
|
245
|
+
}
|
214
246
|
}
|
215
|
-
const createFormDialog = document.getElementById("crud-create-form-dialog");
|
216
|
-
createFormDialog.close();
|
217
|
-
}
|
218
|
-
{% endif %}
|
219
247
|
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
const updateFormDialog = document.getElementById("crud-update-form-dialog");
|
224
|
-
const updateForm = document.getElementById("crud-update-form");
|
225
|
-
result = await UTIL.fetchAPI(`${apiUrl}/${id}`, { method: "GET" });
|
226
|
-
UTIL.setFormData(updateForm, result);
|
227
|
-
updateFormDialog.showModal();
|
228
|
-
}
|
229
|
-
|
230
|
-
async function updateRow(event = null) {
|
231
|
-
if (event != null) {
|
232
|
-
event.preventDefault();
|
248
|
+
hideCreateForm(event = null) {
|
249
|
+
if (event) event.preventDefault();
|
250
|
+
document.getElementById("crud-create-form-dialog").close();
|
233
251
|
}
|
234
|
-
|
252
|
+
|
253
|
+
// Update methods
|
254
|
+
async showUpdateForm(id) {
|
255
|
+
this.state.updatedRowId = id;
|
256
|
+
const updateDialog = document.getElementById("crud-update-form-dialog");
|
235
257
|
const updateForm = document.getElementById("crud-update-form");
|
236
|
-
const formData =
|
237
|
-
|
238
|
-
|
239
|
-
);
|
240
|
-
await fetchRows();
|
241
|
-
hideUpdateForm();
|
242
|
-
} catch(error) {
|
243
|
-
showAlert("Update Permission Error", error);
|
258
|
+
const formData = await UTIL.fetchAPI(`${this.apiUrl}/${id}`, { method: "GET" });
|
259
|
+
UTIL.setFormData(updateForm, formData);
|
260
|
+
updateDialog.showModal();
|
244
261
|
}
|
245
|
-
}
|
246
262
|
|
247
|
-
|
248
|
-
|
249
|
-
|
263
|
+
async updateRow(event = null) {
|
264
|
+
if (event) event.preventDefault();
|
265
|
+
try {
|
266
|
+
const updateForm = document.getElementById("crud-update-form");
|
267
|
+
const formData = UTIL.getFormData(updateForm);
|
268
|
+
await UTIL.fetchAPI(`${this.apiUrl}/${this.state.updatedRowId}`, {
|
269
|
+
method: "PUT",
|
270
|
+
body: JSON.stringify(formData)
|
271
|
+
});
|
272
|
+
await this.fetchRows();
|
273
|
+
this.hideUpdateForm();
|
274
|
+
} catch (error) {
|
275
|
+
console.error(error);
|
276
|
+
this.showAlert("Update Permission Error", error);
|
277
|
+
}
|
250
278
|
}
|
251
|
-
const updateFormDialog = document.getElementById("crud-update-form-dialog");
|
252
|
-
updateFormDialog.close();
|
253
|
-
}
|
254
|
-
{% endif %}
|
255
279
|
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
const deleteForm = document.getElementById("crud-delete-form");
|
261
|
-
result = await UTIL.fetchAPI(`${apiUrl}/${id}`, { method: "GET" });
|
262
|
-
UTIL.setFormData(deleteForm, result);
|
263
|
-
deleteFormDialog.showModal();
|
264
|
-
}
|
280
|
+
hideUpdateForm(event = null) {
|
281
|
+
if (event) event.preventDefault();
|
282
|
+
document.getElementById("crud-update-form-dialog").close();
|
283
|
+
}
|
265
284
|
|
266
|
-
|
267
|
-
|
268
|
-
|
285
|
+
// Delete methods
|
286
|
+
async showDeleteForm(id) {
|
287
|
+
this.state.deletedRowId = id;
|
288
|
+
const deleteDialog = document.getElementById("crud-delete-form-dialog");
|
289
|
+
const deleteForm = document.getElementById("crud-delete-form");
|
290
|
+
const formData = await UTIL.fetchAPI(`${this.apiUrl}/${id}`, { method: "GET" });
|
291
|
+
UTIL.setFormData(deleteForm, formData);
|
292
|
+
deleteDialog.showModal();
|
269
293
|
}
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
294
|
+
|
295
|
+
async deleteRow(event = null) {
|
296
|
+
if (event) event.preventDefault();
|
297
|
+
try {
|
298
|
+
await UTIL.fetchAPI(`${this.apiUrl}/${this.state.deletedRowId}`, { method: "DELETE" });
|
299
|
+
await this.fetchRows();
|
300
|
+
this.hideDeleteForm();
|
301
|
+
} catch (error) {
|
302
|
+
console.error(error);
|
303
|
+
this.showAlert("Delete Permission Error", error);
|
304
|
+
}
|
276
305
|
}
|
277
|
-
}
|
278
306
|
|
279
|
-
|
280
|
-
|
281
|
-
|
307
|
+
hideDeleteForm(event = null) {
|
308
|
+
if (event) event.preventDefault();
|
309
|
+
document.getElementById("crud-delete-form-dialog").close();
|
282
310
|
}
|
283
|
-
const deleteFormDialog = document.getElementById("crud-delete-form-dialog");
|
284
|
-
deleteFormDialog.close();
|
285
|
-
}
|
286
|
-
{% endif %}
|
287
311
|
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
alertDialog.showModal();
|
296
|
-
}
|
312
|
+
// Alert methods
|
313
|
+
showAlert(title, error) {
|
314
|
+
const alertDialog = document.getElementById("crud-alert-dialog");
|
315
|
+
document.getElementById("crud-alert-title").textContent = title;
|
316
|
+
document.getElementById("crud-alert-message").textContent = error.message || String(error);
|
317
|
+
alertDialog.showModal();
|
318
|
+
}
|
297
319
|
|
298
|
-
|
299
|
-
|
300
|
-
|
320
|
+
hideAlert(event = null) {
|
321
|
+
if (event) event.preventDefault();
|
322
|
+
document.getElementById("crud-alert-dialog").close();
|
301
323
|
}
|
302
|
-
const alertDialog = document.getElementById("crud-alert-dialog");
|
303
|
-
alertDialog.close();
|
304
324
|
}
|
305
325
|
|
306
326
|
document.addEventListener("DOMContentLoaded", () => {
|
307
|
-
const
|
308
|
-
|
309
|
-
|
327
|
+
const app = document.getElementById("crud-app");
|
328
|
+
new CrudApp("/api/v1/permissions", {
|
329
|
+
pageSize: JSON.parse(app.dataset.pageSize),
|
330
|
+
currentPage: JSON.parse(app.dataset.page),
|
331
|
+
sort: JSON.parse(app.dataset.sort),
|
332
|
+
filter: JSON.parse(app.dataset.filter),
|
333
|
+
allowCreate: JSON.parse(app.dataset.allowCreate),
|
334
|
+
allowUpdate: JSON.parse(app.dataset.allowUpdate),
|
335
|
+
allowDelete: JSON.parse(app.dataset.allowDelete),
|
336
|
+
updatedRowId: null,
|
337
|
+
deletedRowId: null,
|
338
|
+
});
|
310
339
|
});
|
311
|
-
</script>
|
340
|
+
</script>
|