planif (feuille job mobile) : commentaire interne par défaut — plus de courriel client accidentel
Incident : un employé a envoyé un courriel au client en croyant ajouter un commentaire
privé au fil du ticket. Le composeur de la feuille (jobSheet) s'ouvrait en mode « Réponse ·
courriel » (public) par défaut.
- openJobSheet : `noteMode` défaut = TRUE (commentaire INTERNE) au lieu de false (réponse client) ;
ouverture en mode réponse seulement si `{ reply: true }` explicite (aucun appelant ne le fait)
- bascule réordonnée : « Note interne » (1re, défaut) · « Répondre au client » (2e, explicite) ;
couleur d'alerte (deep-orange) quand la réponse client est sélectionnée
- bouton d'envoi : « Enregistrer la note » (interne, neutre) vs « Envoyer au client » (orange) ;
indice/placeholder clarifiés (« ajoutée au fil, jamais envoyée au client » vs « ⚠ ENVOYÉE au client »)
- répondre au client reste possible mais = choix explicite (aligne le comportement sûr déjà
présent dans le panneau détail complet : case « Envoyer aussi au client » jdReplyPublic par défaut off)
- Vérifié en aperçu sur un job AVEC courriel client : le composeur s'ouvre en « Note interne »
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
d8325f7e55
commit
23e3c0d2e2
|
|
@ -359,15 +359,15 @@
|
|||
<!-- Conversation client UNIFIÉE — UN seul champ : Réponse au client (Outbox courriel/SMS) OU 📌 Note importante (épinglée au job). Fil le plus récent en premier. -->
|
||||
<div class="pm-opt-label">Conversation client <span v-if="sheetThread.messages.length" class="text-grey-5">({{ sheetThread.messages.length }})</span></div>
|
||||
<div class="pm-postbox">
|
||||
<q-input dense outlined v-model="composerText" type="textarea" rows="2" :placeholder="noteMode ? 'Note importante — épinglée au job (ex. appeler 30 min avant · préfère AM)…' : (replyChannel.ok ? ('Réponse au client par ' + replyChannel.label + '…') : 'Réponse au client…')" />
|
||||
<q-input dense outlined v-model="composerText" type="textarea" rows="2" :placeholder="noteMode ? 'Note interne — ajoutée au fil du ticket, jamais envoyée au client…' : (replyChannel.ok ? ('Réponse ENVOYÉE au client par ' + replyChannel.label + '…') : 'Réponse au client…')" />
|
||||
<div class="row items-center q-mt-xs q-gutter-xs">
|
||||
<q-btn-toggle v-model="noteMode" dense unelevated no-caps size="sm" :options="[{ label: replyChannel.ok ? ('Réponse · ' + replyChannel.label) : 'Réponse', value: false, icon: 'reply', disable: !replyChannel.ok }, { label: 'Note importante', value: true, icon: 'push_pin' }]" toggle-color="primary" color="grey-3" text-color="grey-8" />
|
||||
<q-btn-toggle v-model="noteMode" dense unelevated no-caps size="sm" :options="[{ label: 'Note interne', value: true, icon: 'sticky_note_2' }, { label: replyChannel.ok ? ('Répondre au client · ' + replyChannel.label) : 'Répondre au client', value: false, icon: 'reply', disable: !replyChannel.ok }]" :toggle-color="noteMode ? 'blue-grey-7' : 'deep-orange'" color="grey-3" text-color="grey-8" />
|
||||
<q-space />
|
||||
<q-btn dense unelevated no-caps size="sm" :color="noteMode ? 'deep-orange-6' : 'teal-7'" :icon="noteMode ? 'push_pin' : 'send'" :label="noteMode ? 'Enregistrer' : 'Envoyer'" :loading="postBusy" :disable="noteMode ? false : !postDraft.trim()" @mousedown.prevent="submitComposer()" />
|
||||
<q-btn dense unelevated no-caps size="sm" :color="noteMode ? 'blue-grey-7' : 'deep-orange'" :icon="noteMode ? 'sticky_note_2' : 'send'" :label="noteMode ? 'Enregistrer la note' : 'Envoyer au client'" :loading="postBusy" :disable="noteMode ? false : !postDraft.trim()" @mousedown.prevent="submitComposer()" />
|
||||
</div>
|
||||
<div class="row items-center q-mt-xs pm-postbox-foot">
|
||||
<q-icon :name="noteMode ? 'push_pin' : (replyChannel.ok ? 'public' : 'block')" size="12px" :color="noteMode ? 'deep-orange-6' : (replyChannel.ok ? 'teal-7' : 'grey-5')" />
|
||||
<span class="pm-postbox-hint">{{ noteMode ? 'Note interne épinglée au job — jamais envoyée au client' : (replyChannel.ok ? ('Envoyée au client par ' + replyChannel.label + (jobSheet.job.legacy_ticket_id ? ' · consignée au ticket' : '')) : 'Aucun courriel/téléphone au dossier client') }}</span>
|
||||
<span class="pm-postbox-hint">{{ noteMode ? 'Note interne — ajoutée au fil du ticket, jamais envoyée au client' : (replyChannel.ok ? ('⚠ ENVOYÉE au client par ' + replyChannel.label + (jobSheet.job.legacy_ticket_id ? ' · consignée au ticket' : '')) : 'Aucun courriel/téléphone au dossier client') }}</span>
|
||||
<q-space />
|
||||
<q-btn flat dense no-caps size="sm" color="primary" icon="open_in_new" label="Fil complet" @click="openFullThread()" />
|
||||
</div>
|
||||
|
|
@ -5499,7 +5499,7 @@ async function loadSheetThread (j) {
|
|||
} catch (e) { /* fil indisponible */ }
|
||||
if (jobSheet.job && jobSheet.job.name === tok) sheetThread.loading = false
|
||||
}
|
||||
function openJobSheet (j, opts) { jobSheet.job = j; snoozeDate.value = addDaysISO(todayISO(), 7); sheetNoteText.value = j.notes || ''; postDraft.value = ''; noteMode.value = !!(opts && opts.note); serviceCheck.done = false; serviceCheck.loading = false; jobSheet.open = true; loadSheetThread(j) }
|
||||
function openJobSheet (j, opts) { jobSheet.job = j; snoozeDate.value = addDaysISO(todayISO(), 7); sheetNoteText.value = j.notes || ''; postDraft.value = ''; noteMode.value = !(opts && opts.reply); /* défaut SÛR : commentaire INTERNE (jamais un courriel accidentel) — « Répondre au client » = bascule explicite */ serviceCheck.done = false; serviceCheck.loading = false; jobSheet.open = true; loadSheetThread(j) }
|
||||
// Auto-save de la note à la FERMETURE de la feuille (X · clic extérieur · bouton Fermer · Échap) — uniquement si modifiée. Plus de bouton Enregistrer.
|
||||
function onJobSheetHide () { const j = jobSheet.job; if (j && (sheetNoteText.value || '') !== (j.notes || '')) patchJob(j, { notes: sheetNoteText.value || '' }, 'Note enregistrée') }
|
||||
function openNote (j) { noteDialog.job = j; noteDialog.text = j.notes || ''; noteDialog.open = true }
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user