v0.12.0 - Add modular system architecture with user-based module access
- Add Modules and UserModules database tables - Create home page with module selection grid - Implement per-user module assignment in user management - Add route guards for module access control - Refactor navigation: login -> home -> modules, admin console via button - Add Font Awesome icons
This commit is contained in:
@@ -129,6 +129,18 @@
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-label">Module Access</label>
|
||||
<div class="module-checkboxes" id="moduleCheckboxes">
|
||||
{% for module in modules %}
|
||||
<label class="checkbox-label">
|
||||
<input type="checkbox" name="modules" value="{{ module.module_id }}" class="module-checkbox">
|
||||
{{ module.module_name }}
|
||||
</label>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal-actions">
|
||||
<button type="button" class="btn btn-secondary" onclick="closeUserModal()">Cancel</button>
|
||||
<button type="submit" class="btn btn-primary">Save User</button>
|
||||
@@ -162,9 +174,10 @@ function openAddUser() {
|
||||
document.getElementById('passwordOptional').style.display = 'none';
|
||||
document.getElementById('password').required = true;
|
||||
document.getElementById('activeToggleGroup').style.display = 'none';
|
||||
// Uncheck all modules for new user
|
||||
document.querySelectorAll('.module-checkbox').forEach(cb => cb.checked = false);
|
||||
document.getElementById('userModal').style.display = 'flex';
|
||||
}
|
||||
|
||||
function openEditUser(userId) {
|
||||
editingUserId = userId;
|
||||
document.getElementById('modalTitle').textContent = 'Edit User';
|
||||
@@ -191,7 +204,22 @@ function openEditUser(userId) {
|
||||
const isEditingSelf = user.user_id === {{ session.user_id }};
|
||||
document.getElementById('role').disabled = isEditingSelf;
|
||||
|
||||
document.getElementById('userModal').style.display = 'flex';
|
||||
// Load user's modules
|
||||
fetch('/settings/users/' + userId + '/modules')
|
||||
.then(resp => resp.json())
|
||||
.then(moduleData => {
|
||||
// Uncheck all first
|
||||
document.querySelectorAll('.module-checkbox').forEach(cb => cb.checked = false);
|
||||
// Check assigned modules
|
||||
if (moduleData.success) {
|
||||
moduleData.module_ids.forEach(id => {
|
||||
const cb = document.querySelector(`.module-checkbox[value="${id}"]`);
|
||||
if (cb) cb.checked = true;
|
||||
});
|
||||
}
|
||||
// Show modal after modules are loaded
|
||||
document.getElementById('userModal').style.display = 'flex';
|
||||
});
|
||||
} else {
|
||||
alert(data.message);
|
||||
}
|
||||
@@ -201,7 +229,6 @@ function openEditUser(userId) {
|
||||
console.error(error);
|
||||
});
|
||||
}
|
||||
|
||||
function closeUserModal() {
|
||||
document.getElementById('userModal').style.display = 'none';
|
||||
document.getElementById('userForm').reset();
|
||||
@@ -234,8 +261,23 @@ document.getElementById('userForm').addEventListener('submit', function(e) {
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
closeUserModal();
|
||||
location.reload();
|
||||
// Save modules if editing existing user
|
||||
if (userId) {
|
||||
const moduleIds = Array.from(document.querySelectorAll('.module-checkbox:checked'))
|
||||
.map(cb => parseInt(cb.value));
|
||||
|
||||
fetch(`/settings/users/${userId}/modules`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ module_ids: moduleIds })
|
||||
}).then(() => {
|
||||
closeUserModal();
|
||||
location.reload();
|
||||
});
|
||||
} else {
|
||||
closeUserModal();
|
||||
location.reload();
|
||||
}
|
||||
} else {
|
||||
alert(data.message);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user