feat: gestione gruppi di ticket. feat: miglioramento filtri ticket a mio carico e ticket. feat: possiblità di copiare il numero del tocket con pulsante copia

This commit is contained in:
2026-07-09 08:36:03 +02:00
parent 5b914eb198
commit a89605b888
14 changed files with 1674 additions and 182 deletions
+44 -1
View File
@@ -77,6 +77,7 @@ const TicketListView = {
<div style="display:flex; align-items:center; gap:var(--space-sm);">
<span class="batch-count" id="batch-count">0 selezionati</span>
<button class="btn btn-ghost btn-xs" id="batch-select-all">Seleziona visibili</button>
<button class="btn btn-ghost btn-xs" id="batch-copy-tns" style="margin-left: 8px;">Copia numeri</button>
</div>
<div class="filter-group">
<span class="filter-label">Stato</span>
@@ -139,6 +140,7 @@ const TicketListView = {
<tr data-ticket-id="${t.id}" class="${this.selectedIds.has(String(t.id)) ? 'selected' : ''} ${this.selectedOrder[0] === String(t.id) ? 'first-selected' : ''}" style="cursor:pointer;">
<td>
<span class="ticket-tn" style="display:inline-flex; align-items:center;">
<span class="copy-ticket-btn" data-tn="${t.tn}" style="cursor: pointer; font-size: 0.82rem; display: inline-flex; align-items: center; margin-right: 4px;" onclick="event.stopPropagation();" title="Copia numero ticket">📋</span>
<a href="#/tickets/${t.id}" class="ticket-tn-link" onclick="event.stopPropagation()">${t.tn}</a>
${data.otrsBaseUrl ? `
<a href="${data.otrsBaseUrl}index.pl?Action=AgentTicketZoom;TicketID=${t.id}" target="_blank" title="Apri in OTRS" onclick="event.stopPropagation()" style="display:inline-flex; align-items:center; text-decoration:none;">
@@ -302,6 +304,47 @@ const TicketListView = {
batchMerge.addEventListener('click', () => this.mergeBatch());
}
// Batch Copy Ticket Numbers
const batchCopyTns = document.getElementById('batch-copy-tns');
if (batchCopyTns) {
batchCopyTns.addEventListener('click', (e) => {
e.stopPropagation();
const selectedTns = [];
this.selectedIds.forEach(id => {
const row = document.querySelector(`.ticket-table tbody tr[data-ticket-id="${id}"]`);
if (row) {
const tnLink = row.querySelector('.ticket-tn-link');
if (tnLink) {
selectedTns.push(tnLink.textContent.trim());
}
}
});
if (selectedTns.length > 0) {
const textToCopy = selectedTns.join('\n');
navigator.clipboard.writeText(textToCopy).then(() => {
Toast.success(`${selectedTns.length} numeri ticket copiati!`);
}).catch(err => {
Toast.error('Errore durante la copia: ' + err.message);
});
}
});
}
// Individual copy buttons
document.querySelectorAll('.copy-ticket-btn').forEach(btn => {
btn.addEventListener('click', (e) => {
e.stopPropagation();
const tn = btn.dataset.tn;
if (tn) {
navigator.clipboard.writeText(tn).then(() => {
Toast.success(`Numero ticket ${tn} copiato!`);
}).catch(err => {
Toast.error('Errore durante la copia: ' + err.message);
});
}
});
});
// Batch select all visible
const batchSelectAll = document.getElementById('batch-select-all');
if (batchSelectAll) {
@@ -531,7 +574,7 @@ const TicketListView = {
}
});
const confirmed = confirm(`Sei sicuro di voler unire i ticket ${sourceTns.join(', ')} nel ticket principale #${targetTn}? Questa azione sposterà tutti gli articoli e tempi consultivati.`);
const confirmed = await App.confirm('Unione Ticket', `Sei sicuro di voler unire i ticket ${sourceTns.join(', ')} nel ticket principale #${targetTn}? Questa azione sposterà tutti gli articoli e tempi consultivati.`);
if (!confirmed) return;
try {