RBAC and Doc updates

This commit is contained in:
James Pattinson
2025-10-13 14:05:01 +00:00
parent f721be7280
commit d4b88e0952
13 changed files with 1400 additions and 208 deletions

View File

@@ -57,6 +57,10 @@ class UIManager {
this.showMemberModal();
});
document.getElementById('addUserBtn').addEventListener('click', () => {
this.showUserModal();
});
// Member subscriptions modal
@@ -88,6 +92,11 @@ class UIManager {
this.handleSubscriptionFormSubmit();
});
document.getElementById('userForm').addEventListener('submit', (e) => {
e.preventDefault();
this.handleUserFormSubmit();
});
// Confirmation modal
document.getElementById('confirmOkBtn').addEventListener('click', () => {
if (this.confirmCallback) {
@@ -245,6 +254,42 @@ class UIManager {
this.showModal(modal);
}
/**
* Show user modal (add/edit)
*/
showUserModal(userData = null) {
const modal = document.getElementById('userModal');
const title = document.getElementById('userModalTitle');
const form = document.getElementById('userForm');
const passwordHelp = document.getElementById('passwordHelp');
const passwordField = document.getElementById('userPassword');
if (userData) {
// Edit mode
title.textContent = 'Edit User';
document.getElementById('userName').value = userData.username;
document.getElementById('userName').readOnly = true; // Can't change username
passwordField.placeholder = 'Leave blank to keep current password';
passwordField.required = false;
passwordHelp.style.display = 'block';
document.getElementById('userRole').value = userData.role;
document.getElementById('userActive').checked = userData.active;
this.currentEditingItem = userData;
} else {
// Add mode
title.textContent = 'Add User';
form.reset();
document.getElementById('userName').readOnly = false;
passwordField.placeholder = 'Password';
passwordField.required = true;
passwordHelp.style.display = 'none';
document.getElementById('userActive').checked = true;
this.currentEditingItem = null;
}
this.showModal(modal);
}
/**
* Show subscription modal
*/
@@ -400,6 +445,50 @@ class UIManager {
}
}
/**
* Handle user form submission
*/
async handleUserFormSubmit() {
const form = document.getElementById('userForm');
const formData = new FormData(form);
const userData = {
username: formData.get('userName'),
role: formData.get('userRole'),
active: formData.get('userActive') === 'on'
};
// Only include password if it's provided (for updates, empty means no change)
const password = formData.get('userPassword');
if (password) {
userData.password = password;
}
try {
this.setLoading(true);
if (this.currentEditingItem) {
// Update existing user
await apiClient.updateUser(this.currentEditingItem.user_id, userData);
this.showNotification('User updated successfully', 'success');
} else {
// Create new user
if (!userData.password) {
throw new Error('Password is required for new users');
}
await apiClient.createUser(userData);
this.showNotification('User created successfully', 'success');
}
this.closeModal(document.getElementById('userModal'));
await window.app.loadData();
} catch (error) {
this.handleError(error, 'Failed to save user');
} finally {
this.setLoading(false);
}
}
/**
* Show member subscriptions modal
*/