mirror of
https://github.com/maziggy/bambuddy.git
synced 2026-10-18 21:47:39 +02:00
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>
This commit is contained in:
co-authored by
cadtoolbox
parent
21ca7cce19
commit
df75cc8e63
@@ -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",
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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}",
|
||||
},
|
||||
]
|
||||
|
||||
@@ -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",
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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() {
|
||||
</div>
|
||||
|
||||
{/* Tab Navigation */}
|
||||
<div className="flex flex-wrap gap-1 mb-6 border-b border-bambu-dark-tertiary overflow-y-auto max-h-32">
|
||||
<div className="flex flex-wrap gap-1 mb-6 border-b border-bambu-dark-tertiary">
|
||||
<button
|
||||
onClick={() => handleTabChange('general')}
|
||||
className={`px-4 py-2 text-sm font-medium transition-colors border-b-2 -mb-px ${
|
||||
@@ -3952,10 +3963,29 @@ export function SettingsPage() {
|
||||
|
||||
{/* Info box about auto-generated password when Advanced Auth is enabled */}
|
||||
{advancedAuthStatus?.advanced_auth_enabled && (
|
||||
<div className="bg-bambu-dark-secondary/50 border border-bambu-green/20 rounded-lg p-3">
|
||||
<div className="bg-bambu-dark-secondary/50 border border-bambu-green/20 rounded-lg p-3 space-y-3">
|
||||
<p className="text-sm text-bambu-gray">
|
||||
{t('users.form.passwordManagedByAdvancedAuth') || 'Password is managed by Advanced Authentication. Use "Reset Password" to send a new password to the user via email.'}
|
||||
</p>
|
||||
<Button
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
onClick={() => editingUserId && resetPasswordMutation.mutate(editingUserId)}
|
||||
disabled={resetPasswordMutation.isPending || !userFormData.email}
|
||||
className="w-full"
|
||||
>
|
||||
{resetPasswordMutation.isPending ? (
|
||||
<>
|
||||
<Loader2 className="w-4 h-4 animate-spin" />
|
||||
{t('users.form.resettingPassword') || 'Resetting Password...'}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<RotateCcw className="w-4 h-4" />
|
||||
{t('users.form.resetPassword') || 'Reset Password'}
|
||||
</>
|
||||
)}
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user