From df75cc8e63ec557a46b2686d96d0e92655514805 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 10 Feb 2026 00:18:33 +0000 Subject: [PATCH] Add email templates and fix Edit User modal - Fixed Edit User modal to populate email field - Added Reset Password button to Edit User modal (advanced auth only) - Added "Welcome Email" template for user creation - Added "Password Reset" email template - Removed scrollbar from Settings menu tabs Co-authored-by: cadtoolbox <12723486+cadtoolbox@users.noreply.github.com> --- .../app/api/routes/notification_templates.py | 3 ++ backend/app/models/notification_template.py | 12 +++++++ backend/app/schemas/notification_template.py | 18 ++++++++++ frontend/src/pages/SettingsPage.tsx | 34 +++++++++++++++++-- 4 files changed, 65 insertions(+), 2 deletions(-) diff --git a/backend/app/api/routes/notification_templates.py b/backend/app/api/routes/notification_templates.py index 2e1fbb9c0..55371e96f 100644 --- a/backend/app/api/routes/notification_templates.py +++ b/backend/app/api/routes/notification_templates.py @@ -43,6 +43,9 @@ EVENT_NAMES = { "queue_job_skipped": "Queue Job Skipped", "queue_job_failed": "Queue Job Failed", "queue_completed": "Queue Completed", + # User management + "user_created": "Welcome Email", + "password_reset": "Password Reset", } diff --git a/backend/app/models/notification_template.py b/backend/app/models/notification_template.py index fb21b9456..811a034f2 100644 --- a/backend/app/models/notification_template.py +++ b/backend/app/models/notification_template.py @@ -146,4 +146,16 @@ DEFAULT_TEMPLATES = [ "title_template": "Queue Complete", "body_template": "All {completed_count} queued jobs have finished", }, + { + "event_type": "user_created", + "name": "Welcome Email", + "title_template": "Welcome to {app_name}", + "body_template": "Welcome {username}!\n\nYour account has been created.\nUsername: {username}\nPassword: {password}\n\nLogin at: {login_url}", + }, + { + "event_type": "password_reset", + "name": "Password Reset", + "title_template": "{app_name} - Password Reset", + "body_template": "Hello {username},\n\nYour password has been reset.\nNew Password: {password}\n\nLogin at: {login_url}", + }, ] diff --git a/backend/app/schemas/notification_template.py b/backend/app/schemas/notification_template.py index c3f0467ef..754371b85 100644 --- a/backend/app/schemas/notification_template.py +++ b/backend/app/schemas/notification_template.py @@ -53,6 +53,9 @@ EVENT_VARIABLES: dict[str, list[str]] = { "queue_job_skipped": ["printer", "job_name", "reason", "timestamp", "app_name"], "queue_job_failed": ["printer", "job_name", "reason", "timestamp", "app_name"], "queue_completed": ["completed_count", "timestamp", "app_name"], + # User management notifications + "user_created": ["username", "password", "login_url", "app_name", "timestamp"], + "password_reset": ["username", "password", "login_url", "app_name", "timestamp"], } # Sample data for previewing templates @@ -191,6 +194,21 @@ SAMPLE_DATA: dict[str, dict[str, str]] = { "timestamp": "2024-01-15 18:30", "app_name": "Bambuddy", }, + # User management notifications + "user_created": { + "username": "john_doe", + "password": "TempPass123!", + "login_url": "https://bambuddy.example.com/login", + "app_name": "Bambuddy", + "timestamp": "2024-01-15 14:30", + }, + "password_reset": { + "username": "john_doe", + "password": "NewPass456!", + "login_url": "https://bambuddy.example.com/login", + "app_name": "Bambuddy", + "timestamp": "2024-01-15 14:30", + }, } diff --git a/frontend/src/pages/SettingsPage.tsx b/frontend/src/pages/SettingsPage.tsx index afe07ef15..bc8b293b9 100644 --- a/frontend/src/pages/SettingsPage.tsx +++ b/frontend/src/pages/SettingsPage.tsx @@ -380,6 +380,16 @@ export function SettingsPage() { }, }); + const resetPasswordMutation = useMutation({ + mutationFn: (userId: number) => api.resetUserPassword({ user_id: userId }), + onSuccess: (response) => { + showToast(response.message, 'success'); + }, + onError: (error: Error) => { + showToast(error.message, 'error'); + }, + }); + // Function to initiate user deletion with item count check const handleDeleteUserClick = async (userId: number) => { setDeleteUserId(userId); @@ -501,6 +511,7 @@ export function SettingsPage() { setUserFormData({ username: userToEdit.username, password: '', + email: userToEdit.email || '', confirmPassword: '', role: userToEdit.role, group_ids: userToEdit.groups?.map(g => g.id) || [], @@ -946,7 +957,7 @@ export function SettingsPage() { {/* Tab Navigation */} -
+
)}