/** * Ticket Detail View * Shows full ticket info with quick-edit dropdowns, article timeline, and add-note form. */ const TicketDetailView = { ticketId: null, htmlMode: false, originalValues: {}, noteAttachments: [], saveDraft() { if (!this.ticketId) return; const body = this.noteQuill ? this.noteQuill.root.innerHTML.trim() : ''; const subject = document.getElementById('note-subject') ? document.getElementById('note-subject').value.trim() : ''; const time_unit = document.getElementById('note-time-units') ? document.getElementById('note-time-units').value.trim() : ''; if ((body !== '
Caricamento ticket...
${App.escapeHtml(subject)}
`; if (this.noteQuill) { this.noteQuill.root.innerHTML = body; } } // If subject is empty but body is provided, fill subject with truncated plain text of body if (body && !subject) { const tempDiv = document.createElement('div'); tempDiv.innerHTML = body; const plainText = tempDiv.textContent || tempDiv.innerText || ''; subject = plainText.trim().substring(0, 50) || 'Nota interna'; document.getElementById('note-subject').value = subject; } // If both are still empty, show warning if (!body && !subject) { Toast.warning('Inserisci un oggetto o il corpo della nota prima di inviare'); return; } try { noteSendBtn.disabled = true; noteSendBtn.innerHTML = ' Invio...'; const res = await App.api(`/api/tickets/${this.ticketId}/articles`, { method: 'POST', body: JSON.stringify({ subject, body, time_unit, attachments: this.noteAttachments.length > 0 ? this.noteAttachments : undefined }), }); this.noteAttachments = []; // Clear attachments Toast.success(res.message || 'Nota aggiunta!'); App.clearDraft(this.ticketId, 'note'); App.updateDailyTimer(); this.render(this.ticketId); } catch (err) { Toast.error('Errore: ' + err.message); noteSendBtn.disabled = false; noteSendBtn.innerHTML = 'Invia Nota'; } }); // Note Attachments Upload Handlers const noteAttachBtn = document.getElementById('btn-note-add-attachments'); const noteFileInput = document.getElementById('note-attachments'); if (noteAttachBtn && noteFileInput) { noteAttachBtn.addEventListener('click', () => noteFileInput.click()); noteFileInput.addEventListener('change', (e) => { const files = Array.from(e.target.files); for (const file of files) { const reader = new FileReader(); reader.onload = () => { const base64Data = reader.result.split(',')[1]; this.noteAttachments.push({ filename: file.name, content: base64Data, content_type: file.type }); this.updateNoteAttachmentList(); }; reader.readAsDataURL(file); } noteFileInput.value = ''; // Reset input }); } // Email Compose Button const btnEmailCompose = document.getElementById('btn-open-email-compose'); if (btnEmailCompose) { btnEmailCompose.addEventListener('click', () => { if (window.EmailCompose) { EmailCompose.open({ ticketId: parseInt(btnEmailCompose.dataset.ticketId, 10), ticketTn: btnEmailCompose.dataset.ticketTn, ticketTitle: btnEmailCompose.dataset.ticketTitle, customerEmail: btnEmailCompose.dataset.customerEmail, }); } else { Toast.error('Modulo email non disponibile'); } }); } // Article Email Reply Buttons document.querySelectorAll('.btn-email-article').forEach(btn => { btn.addEventListener('click', () => { const articleId = parseInt(btn.dataset.articleId, 10); const article = articles.find(art => art.article_id == articleId); if (!article) return; if (window.EmailCompose) { const hasHtml = (article.a_content_type || '').toLowerCase().includes('html') || article.a_body.includes('') || article.a_body.includes('/>'); const quotedBody = hasHtml ? article.a_body : App.escapeHtml(article.a_body || '').replace(/\n/g, 'Il ${App.formatDateTime(article.create_time)}, ${App.escapeHtml(article.a_from || 'Sistema')} ha scritto:
${quotedBody}