@@ -36,6 +36,15 @@ q-dialog(
3636 :loading ="templatesLoading"
3737 color ="teal-7"
3838 )
39+ q-input.q-mt-md (
40+ v-model ="mailSubject"
41+ label ="Sujet du mail"
42+ hint ="Sujet affiché par le client mail (obligatoire)"
43+ outlined
44+ dense
45+ color ="teal-7"
46+ autocomplete ="off"
47+ )
3948 q-banner.q-mt-md (
4049 v-if ="mailPathsReady && recipientSourceOptions.length === 0"
4150 rounded
@@ -195,6 +204,15 @@ q-dialog(
195204 :loading ="templatesLoading"
196205 color ="teal-7"
197206 )
207+ q-input.q-mt-md (
208+ v-model ="mailSubject"
209+ label ="Sujet du mail"
210+ hint ="Sujet affiché par le client mail (obligatoire)"
211+ outlined
212+ dense
213+ color ="teal-7"
214+ autocomplete ="off"
215+ )
198216 q-banner.q-mt-md (
199217 v-if ="mailPathsReady && recipientSourceOptions.length === 0"
200218 rounded
@@ -336,6 +354,7 @@ q-dialog(
336354
337355<script lang="ts" setup>
338356import { ref , computed , onMounted , onBeforeUnmount , watch } from ' vue'
357+ import { watchDebounced } from ' @vueuse/core'
339358import { useDialogPluginComponent , useQuasar } from ' quasar'
340359
341360const props = defineProps ({
@@ -463,6 +482,7 @@ const showSendAll = computed(() => {
463482
464483const initAllIdentities = ref (false )
465484const templateName = ref <string >(' ' )
485+ const mailSubject = ref <string >(' ' )
466486const templates = ref <{ label: string ; value: string }[]>([])
467487const templatesLoading = ref (false )
468488const previewHtml = ref (' ' )
@@ -489,6 +509,7 @@ const recipientSourceOptions = computed(() => {
489509const canSendMailTemplate = computed (
490510 () =>
491511 mailPathsReady .value &&
512+ String (mailSubject .value || ' ' ).trim ().length > 0 &&
492513 (recipientAddressSource .value === ' principal' || recipientAddressSource .value === ' personnel' ),
493514)
494515
@@ -499,6 +520,9 @@ const sendButtonTitle = computed(() => {
499520 if (! mailPathsReady .value ) {
500521 return ' Chargement des paramètres SMTP…'
501522 }
523+ if (String (mailSubject .value || ' ' ).trim ().length === 0 ) {
524+ return ' Renseignez le sujet du mail.'
525+ }
502526 if (recipientSourceOptions .value .length === 0 ) {
503527 return ' Configurez au moins un chemin JSON (e-mail personnel ou principal) dans Paramètres → Serveur SMTP.'
504528 }
@@ -517,7 +541,7 @@ const variablesObject = computed(() => {
517541 const out: Record <string , string > = {}
518542 for (const row of variablesRows .value ) {
519543 const k = String (row .key || ' ' ).trim ()
520- if (! k ) continue
544+ if (! k || k === ' subject ' ) continue
521545 out [k ] = String (row .value ?? ' ' )
522546 }
523547 return out
@@ -529,7 +553,7 @@ const variablesToSend = computed(() => {
529553 // Toujours envoyer les variables déclarées dans la config (avec leur défaut)
530554 for (const v of availableVariables .value ) {
531555 const key = String (v ?.key || ' ' ).trim ()
532- if (! key ) continue
556+ if (! key || key === ' subject ' ) continue
533557 base [key ] = v .defaultValue !== undefined && v .defaultValue !== null ? String (v .defaultValue ) : ' '
534558 }
535559
@@ -582,7 +606,7 @@ async function fetchTemplatesConfig() {
582606 try {
583607 const res = await (useNuxtApp () as any ).$http .get (' /management/mail/templates/config' , { method: ' GET' })
584608 const vars = res ?._data ?.data ?.variables || []
585- availableVariables .value = Array .isArray (vars ) ? vars : []
609+ availableVariables .value = Array .isArray (vars ) ? vars . filter (( v : { key ? : string }) => String ( v ?. key || ' ' ). trim () !== ' subject ' ) : []
586610 } catch {
587611 availableVariables .value = []
588612 }
@@ -597,6 +621,7 @@ async function refreshPreview() {
597621 template: templateName .value ,
598622 variables: {
599623 ... variablesToSend .value ,
624+ subject: String (mailSubject .value || ' ' ).trim (),
600625 identity ,
601626 },
602627 },
@@ -617,12 +642,13 @@ onMounted(async () => {
617642 await refreshPreview ()
618643})
619644
620- watch (
621- () => [templateName .value , variablesToSend .value ],
622- async () => {
623- await refreshPreview ()
645+ // Ne pas watcher variablesToSend (nouvel objet à chaque lecture) : boucle de re-renders + perte de focus/valeur sur q-input.
646+ watchDebounced (
647+ [templateName , mailSubject , variablesRows , availableVariables ],
648+ () => {
649+ void refreshPreview ()
624650 },
625- { deep: true },
651+ { debounce: 400 , deep: true },
626652)
627653
628654watch (
@@ -650,6 +676,7 @@ const syncIdentities = () => {
650676 onDialogOK ({
651677 initAllIdentities: initAllIdentities .value ,
652678 template: templateName .value ,
679+ subject: String (mailSubject .value || ' ' ).trim (),
653680 variables: variablesToSend .value ,
654681 recipientAddressSource: recipientAddressSource .value ,
655682 })
0 commit comments