fix: aggiunta nota ticket unito. feat: possiblità di visualizzare ticket in schede. feat: possibilità di creare un nuovo gruppo dall'interfaccia del ticket.

This commit is contained in:
2026-07-12 19:17:07 +02:00
parent e764c37d46
commit 748f777a31
10 changed files with 585 additions and 82 deletions
+74 -7
View File
@@ -8,6 +8,25 @@ const TicketDetailView = {
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 !== '<p><br></p>' && body !== '') || subject !== '' || time_unit !== '' || this.noteAttachments.length > 0) {
App.saveDraft(this.ticketId, {
type: 'note',
body,
subject,
time_unit,
attachments: [...this.noteAttachments]
});
} else {
App.clearDraft(this.ticketId, 'note');
}
},
updateNoteAttachmentList() {
const listEl = document.getElementById('note-file-list');
if (!listEl) return;
@@ -41,6 +60,7 @@ const TicketDetailView = {
await App.ensureLookups();
const data = await App.api(`/api/tickets/${id}`);
const { ticket, articles, attachments } = data;
App.addTabWithoutRedirect(ticket.id, ticket.tn, ticket.title);
let groupsData = { asMaster: [], asMember: [] };
try {
@@ -75,6 +95,7 @@ const TicketDetailView = {
queue_id: ticket.queue_id,
queue_name: ticket.queue_name,
user_id: ticket.user_id,
responsible_user_id: ticket.responsible_user_id,
type_id: ticket.type_id,
customer_id: ticket.customer_id,
customer_user_id: ticket.customer_user_id,
@@ -143,6 +164,15 @@ const TicketDetailView = {
<select class="quick-edit-select" id="qe-owner" data-field="user_id">
${(App.lookups.users || []).map(u =>
`<option value="${u.id}" ${u.id === ticket.user_id ? 'selected' : ''}>${u.first_name} ${u.last_name}</option>`
).join('')}
</select>
</div>
<div class="quick-edit-field">
<label class="quick-edit-label">Responsabile</label>
<select class="quick-edit-select" id="qe-responsible" data-field="responsible_user_id">
<option value="">—</option>
${(App.lookups.users || []).map(u =>
`<option value="${u.id}" ${u.id === ticket.responsible_user_id ? 'selected' : ''}>${u.first_name} ${u.last_name}</option>`
).join('')}
</select>
</div>
@@ -333,12 +363,14 @@ const TicketDetailView = {
<span class="meta-value">${ticket.type_name}</span>
</div>
` : ''}
${ticket.responsible_first ? `
<div class="meta-row">
<span class="meta-label">Responsabile</span>
<span class="meta-value">${ticket.responsible_first} ${ticket.responsible_last}</span>
</div>
` : ''}
<div class="meta-row">
<span class="meta-label">Owner</span>
<span class="meta-value">${ticket.owner_first ? `${ticket.owner_first} ${ticket.owner_last}` : (ticket.owner_login || '—')}</span>
</div>
<div class="meta-row">
<span class="meta-label">Responsabile</span>
<span class="meta-value">${ticket.responsible_first ? `${ticket.responsible_first} ${ticket.responsible_last}` : '—'}</span>
</div>
${totalTime > 0 ? `
<div class="meta-row">
<span class="meta-label">Tempo Totale</span>
@@ -457,6 +489,36 @@ const TicketDetailView = {
this.noteQuill = null;
}
// Restore Note Draft
const noteDraft = App.getDraft(id, 'note');
if (noteDraft) {
if (this.noteQuill && noteDraft.body) {
this.noteQuill.root.innerHTML = noteDraft.body;
}
if (document.getElementById('note-subject')) {
document.getElementById('note-subject').value = noteDraft.subject || '';
}
if (document.getElementById('note-time-units')) {
document.getElementById('note-time-units').value = noteDraft.time_unit || '';
}
this.noteAttachments = noteDraft.attachments || [];
this.updateNoteAttachmentList();
}
// Restore Email Compose Draft
const emailDraft = App.getDraft(id, 'email');
if (emailDraft) {
// Re-open Email Compose with draft options
setTimeout(() => {
if (typeof EmailCompose !== 'undefined') {
EmailCompose.open({
...emailDraft.options,
draft: emailDraft
});
}
}, 100);
}
this.bindEvents(ticket, articles, container, groupsData);
} catch (err) {
@@ -760,6 +822,7 @@ const TicketDetailView = {
this.noteAttachments = []; // Clear attachments
Toast.success(res.message || 'Nota aggiunta!');
App.clearDraft(this.ticketId, 'note');
App.updateDailyTimer();
this.render(this.ticketId);
} catch (err) {
@@ -1107,7 +1170,11 @@ const TicketDetailView = {
btnAssociate.addEventListener('click', async () => {
const select = document.getElementById('group-association-select');
const groupId = select.value;
if (!groupId) return;
if (!groupId) {
sessionStorage.setItem('otrs_create_group_with_master_tn', ticket.tn);
window.location.hash = '#/tickets/groups';
return;
}
try {
btnAssociate.disabled = true;