mirror of
https://github.com/abhinavxd/libredesk.git
synced 2026-10-13 16:41:58 +00:00
fix: general fixes to email notification form
This commit is contained in:
@@ -63,6 +63,7 @@ const submitForm = async (values) => {
|
||||
title: 'Success',
|
||||
description: 'Settings updated successfully'
|
||||
})
|
||||
await getNotificationSettings()
|
||||
} catch (error) {
|
||||
emitter.emit(EMITTER_EVENTS.SHOW_TOAST, {
|
||||
title: 'Error',
|
||||
|
||||
@@ -1,145 +1,153 @@
|
||||
<template>
|
||||
<form @submit="onSmtpSubmit" class="space-y-6" :class="{ 'opacity-50 transition-opacity duration-300': isLoading }">
|
||||
<form
|
||||
@submit="onSmtpSubmit"
|
||||
class="space-y-6"
|
||||
:class="{ 'opacity-50 transition-opacity duration-300': isLoading }"
|
||||
>
|
||||
<!-- Enabled Field -->
|
||||
<FormField name="enabled" v-slot="{ value, handleChange }">
|
||||
<FormItem>
|
||||
<FormControl>
|
||||
<div class="flex items-center space-x-2">
|
||||
<Checkbox :checked="value" @update:checked="handleChange" />
|
||||
<Label>Enabled</Label>
|
||||
</div>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
</FormField>
|
||||
|
||||
<!-- SMTP Host Field -->
|
||||
<FormField v-slot="{ componentField }" name="host">
|
||||
<FormItem>
|
||||
<FormLabel>SMTP Host</FormLabel>
|
||||
<FormControl>
|
||||
<Input type="text" placeholder="smtp.gmail.com" v-bind="componentField" />
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
</FormField>
|
||||
<!-- SMTP Host Field -->
|
||||
<FormField v-slot="{ componentField }" name="host">
|
||||
<FormItem>
|
||||
<FormLabel>SMTP Host</FormLabel>
|
||||
<FormControl>
|
||||
<Input type="text" placeholder="smtp.gmail.com" v-bind="componentField" />
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
</FormField>
|
||||
|
||||
<!-- SMTP Port Field -->
|
||||
<FormField v-slot="{ componentField }" name="port">
|
||||
<FormItem>
|
||||
<FormLabel>SMTP Port</FormLabel>
|
||||
<FormControl>
|
||||
<Input type="number" placeholder="587" v-bind="componentField" />
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
</FormField>
|
||||
<!-- SMTP Port Field -->
|
||||
<FormField v-slot="{ componentField }" name="port">
|
||||
<FormItem>
|
||||
<FormLabel>SMTP Port</FormLabel>
|
||||
<FormControl>
|
||||
<Input type="number" placeholder="587" v-bind="componentField" />
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
</FormField>
|
||||
|
||||
<!-- Username Field -->
|
||||
<FormField v-slot="{ componentField }" name="username">
|
||||
<FormItem>
|
||||
<FormLabel>Username</FormLabel>
|
||||
<FormControl>
|
||||
<Input type="text" placeholder="admin@yourcompany.com" v-bind="componentField" />
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
</FormField>
|
||||
<!-- Username Field -->
|
||||
<FormField v-slot="{ componentField }" name="username">
|
||||
<FormItem>
|
||||
<FormLabel>Username</FormLabel>
|
||||
<FormControl>
|
||||
<Input type="text" placeholder="admin@yourcompany.com" v-bind="componentField" />
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
</FormField>
|
||||
|
||||
<!-- Password Field -->
|
||||
<FormField v-slot="{ componentField }" name="password">
|
||||
<FormItem>
|
||||
<FormLabel>Password</FormLabel>
|
||||
<FormControl>
|
||||
<Input type="password" placeholder="Enter your password" v-bind="componentField" />
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
</FormField>
|
||||
<!-- Password Field -->
|
||||
<FormField v-slot="{ componentField }" name="password">
|
||||
<FormItem>
|
||||
<FormLabel>Password</FormLabel>
|
||||
<FormControl>
|
||||
<Input type="password" placeholder="Enter your password" v-bind="componentField" />
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
</FormField>
|
||||
|
||||
<!-- Max Connections Field -->
|
||||
<FormField v-slot="{ componentField }" name="max_conns">
|
||||
<FormItem>
|
||||
<FormLabel>Max Connections</FormLabel>
|
||||
<FormControl>
|
||||
<Input type="number" placeholder="2" v-bind="componentField" />
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
</FormField>
|
||||
<!-- Max Connections Field -->
|
||||
<FormField v-slot="{ componentField }" name="max_conns">
|
||||
<FormItem>
|
||||
<FormLabel>Max Connections</FormLabel>
|
||||
<FormControl>
|
||||
<Input type="number" placeholder="2" v-bind="componentField" />
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
</FormField>
|
||||
|
||||
<!-- Idle Timeout Field -->
|
||||
<FormField v-slot="{ componentField }" name="idle_timeout">
|
||||
<FormItem>
|
||||
<FormLabel>Idle Timeout</FormLabel>
|
||||
<FormControl>
|
||||
<Input type="text" placeholder="15s" v-bind="componentField" />
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
</FormField>
|
||||
<!-- Idle Timeout Field -->
|
||||
<FormField v-slot="{ componentField }" name="idle_timeout">
|
||||
<FormItem>
|
||||
<FormLabel>Idle Timeout</FormLabel>
|
||||
<FormControl>
|
||||
<Input type="text" placeholder="15s" v-bind="componentField" />
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
</FormField>
|
||||
|
||||
<!-- Wait Timeout Field -->
|
||||
<FormField v-slot="{ componentField }" name="wait_timeout">
|
||||
<FormItem>
|
||||
<FormLabel>Wait Timeout</FormLabel>
|
||||
<FormControl>
|
||||
<Input type="text" placeholder="5s" v-bind="componentField" />
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
</FormField>
|
||||
<!-- Wait Timeout Field -->
|
||||
<FormField v-slot="{ componentField }" name="wait_timeout">
|
||||
<FormItem>
|
||||
<FormLabel>Wait Timeout</FormLabel>
|
||||
<FormControl>
|
||||
<Input type="text" placeholder="5s" v-bind="componentField" />
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
</FormField>
|
||||
|
||||
<!-- Authentication Protocol Field -->
|
||||
<FormField v-slot="{ componentField }" name="auth_protocol">
|
||||
<FormItem>
|
||||
<FormLabel>Authentication Protocol</FormLabel>
|
||||
<FormControl>
|
||||
<Select v-bind="componentField" v-model="componentField.modelValue">
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Select an authentication protocol" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectGroup>
|
||||
<SelectItem value="plain">Plain</SelectItem>
|
||||
<SelectItem value="login">Login</SelectItem>
|
||||
<SelectItem value="cram">CRAM-MD5</SelectItem>
|
||||
<SelectItem value="none">None</SelectItem>
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
</FormField>
|
||||
<!-- Authentication Protocol Field -->
|
||||
<FormField v-slot="{ componentField }" name="auth_protocol">
|
||||
<FormItem>
|
||||
<FormLabel>Authentication Protocol</FormLabel>
|
||||
<FormControl>
|
||||
<Select v-bind="componentField" v-model="componentField.modelValue">
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Select an authentication protocol" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectGroup>
|
||||
<SelectItem value="plain">Plain</SelectItem>
|
||||
<SelectItem value="login">Login</SelectItem>
|
||||
<SelectItem value="cram">CRAM-MD5</SelectItem>
|
||||
<SelectItem value="none">None</SelectItem>
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
</FormField>
|
||||
|
||||
<!-- Email Address Field -->
|
||||
<FormField v-slot="{ componentField }" name="email_address">
|
||||
<FormItem>
|
||||
<FormLabel>From Email Address</FormLabel>
|
||||
<FormControl>
|
||||
<Input type="text" placeholder="From email address. e.g. My Support <mysupport@example.com>"
|
||||
v-bind="componentField" />
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
<FormDescription>From email address. e.g. My Support <mysupport@example.com></FormDescription>
|
||||
</FormItem>
|
||||
</FormField>
|
||||
<!-- Email Address Field -->
|
||||
<FormField v-slot="{ componentField }" name="email_address">
|
||||
<FormItem>
|
||||
<FormLabel>From Email Address</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
type="text"
|
||||
placeholder="From email address. e.g. My Support <mysupport@example.com>"
|
||||
v-bind="componentField"
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
<FormDescription
|
||||
>From email address. e.g. My Support <mysupport@example.com></FormDescription
|
||||
>
|
||||
</FormItem>
|
||||
</FormField>
|
||||
|
||||
<!-- Max Message Retries Field -->
|
||||
<FormField v-slot="{ componentField }" name="max_msg_retries">
|
||||
<FormItem>
|
||||
<FormLabel>Max Message Retries</FormLabel>
|
||||
<FormControl>
|
||||
<Input type="number" placeholder="2" v-bind="componentField" />
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
</FormField>
|
||||
<!-- Max Message Retries Field -->
|
||||
<FormField v-slot="{ componentField }" name="max_msg_retries">
|
||||
<FormItem>
|
||||
<FormLabel>Max Message Retries</FormLabel>
|
||||
<FormControl>
|
||||
<Input type="number" placeholder="2" v-bind="componentField" />
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
</FormField>
|
||||
|
||||
<!-- Enabled Field -->
|
||||
<FormField name="enabled" v-slot="{ value, handleChange }">
|
||||
<FormItem>
|
||||
<FormControl>
|
||||
<div class="flex items-center space-x-2">
|
||||
<Checkbox :checked="value" @update:checked="handleChange" />
|
||||
<Label>Enabled</Label>
|
||||
</div>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
</FormField>
|
||||
|
||||
<Button type="submit" :isLoading="isLoading"> {{ submitLabel }} </Button>
|
||||
</form>
|
||||
<Button type="submit" :isLoading="isLoading"> {{ submitLabel }} </Button>
|
||||
</form>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
@@ -149,59 +157,59 @@ import { useForm } from 'vee-validate'
|
||||
import { toTypedSchema } from '@vee-validate/zod'
|
||||
import { smtpConfigSchema } from './formSchema.js'
|
||||
import {
|
||||
FormControl,
|
||||
FormField,
|
||||
FormItem,
|
||||
FormLabel,
|
||||
FormMessage,
|
||||
FormDescription,
|
||||
FormControl,
|
||||
FormField,
|
||||
FormItem,
|
||||
FormLabel,
|
||||
FormMessage,
|
||||
FormDescription
|
||||
} from '@/components/ui/form'
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectGroup,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectGroup,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue
|
||||
} from '@/components/ui/select'
|
||||
import { Checkbox } from '@/components/ui/checkbox'
|
||||
import { Label } from '@/components/ui/label'
|
||||
import { Input } from '@/components/ui/input'
|
||||
|
||||
const props = defineProps({
|
||||
initialValues: {
|
||||
type: Object,
|
||||
required: false
|
||||
},
|
||||
submitForm: {
|
||||
type: Function,
|
||||
required: true
|
||||
},
|
||||
submitLabel: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: () => 'Save'
|
||||
},
|
||||
isLoading: {
|
||||
type: Boolean,
|
||||
required: false
|
||||
},
|
||||
});
|
||||
initialValues: {
|
||||
type: Object,
|
||||
required: false
|
||||
},
|
||||
submitForm: {
|
||||
type: Function,
|
||||
required: true
|
||||
},
|
||||
submitLabel: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: () => 'Save'
|
||||
},
|
||||
isLoading: {
|
||||
type: Boolean,
|
||||
required: false
|
||||
}
|
||||
})
|
||||
|
||||
const smtpForm = useForm({
|
||||
validationSchema: toTypedSchema(smtpConfigSchema)
|
||||
validationSchema: toTypedSchema(smtpConfigSchema)
|
||||
})
|
||||
|
||||
const onSmtpSubmit = smtpForm.handleSubmit((values) => {
|
||||
props.submitForm(values);
|
||||
props.submitForm(values)
|
||||
})
|
||||
|
||||
// Watch for changes in initialValues and update the form.
|
||||
watch(
|
||||
() => props.initialValues,
|
||||
(newValues) => {
|
||||
smtpForm.setValues(newValues);
|
||||
},
|
||||
{ deep: true, immediate: true }
|
||||
() => props.initialValues,
|
||||
(newValues) => {
|
||||
smtpForm.setValues(newValues)
|
||||
},
|
||||
{ deep: true, immediate: true }
|
||||
)
|
||||
</script>
|
||||
</script>
|
||||
|
||||
@@ -3,11 +3,16 @@ import { isGoDuration } from '@/utils/strings';
|
||||
|
||||
export const smtpConfigSchema = z.object({
|
||||
enabled: z.boolean().describe('Enabled status').default(false),
|
||||
username: z.string().describe('SMTP username').email(),
|
||||
host: z.string().describe('SMTP host').default('smtp.gmail.com'),
|
||||
username: z.string().describe('SMTP username').email().nonempty({
|
||||
message: "SMTP username is required"
|
||||
}),
|
||||
host: z.string().describe('SMTP host').nonempty({
|
||||
message: "SMTP host is required"
|
||||
}),
|
||||
port: z
|
||||
.number({
|
||||
invalid_type_error: 'Port must be a number.'
|
||||
invalid_type_error: 'Port must be a number.',
|
||||
required_error: 'Port is required.'
|
||||
})
|
||||
.min(1, {
|
||||
message: 'Port must be at least 1.'
|
||||
@@ -17,16 +22,18 @@ export const smtpConfigSchema = z.object({
|
||||
})
|
||||
.describe('SMTP port')
|
||||
.default(587),
|
||||
password: z.string().describe('SMTP password').default(''),
|
||||
password: z.string().describe('SMTP password').nonempty({
|
||||
message: "SMTP password is required"
|
||||
}),
|
||||
max_conns: z
|
||||
.number({
|
||||
invalid_type_error: 'Must be a number.'
|
||||
invalid_type_error: 'Must be a number.',
|
||||
required_error: 'Maximum connections is required.'
|
||||
})
|
||||
.min(1, {
|
||||
message: 'Maximum connections must be at least 1.'
|
||||
})
|
||||
.describe('Maximum concurrent connections')
|
||||
.default(2),
|
||||
.describe('Maximum concurrent connections'),
|
||||
idle_timeout: z
|
||||
.string()
|
||||
.describe('Idle timeout duration')
|
||||
@@ -43,12 +50,14 @@ export const smtpConfigSchema = z.object({
|
||||
.default('5s'),
|
||||
auth_protocol: z
|
||||
.enum(['plain', 'login', 'cram', 'none'])
|
||||
.describe('Authentication protocol')
|
||||
.default('plain'),
|
||||
email_address: z.string().describe('Email address'),
|
||||
.describe('Authentication protocol'),
|
||||
email_address: z.string().describe('Email address').email().nonempty({
|
||||
message: "Email address is required"
|
||||
}),
|
||||
max_msg_retries: z
|
||||
.number({
|
||||
invalid_type_error: 'Must be a number.'
|
||||
invalid_type_error: 'Must be a number.',
|
||||
required_error: 'Maximum message retries is required.'
|
||||
})
|
||||
.min(0, {
|
||||
message: 'Max message retries must be at least 0.'
|
||||
|
||||
Reference in New Issue
Block a user