fix: corretto posizionamento barra selezione rapida dopo l'aggiunta delle schede
This commit is contained in:
@@ -1167,7 +1167,7 @@ body {
|
|||||||
border-radius: var(--radius-lg);
|
border-radius: var(--radius-lg);
|
||||||
animation: slideDown 0.2s ease-out;
|
animation: slideDown 0.2s ease-out;
|
||||||
position: sticky;
|
position: sticky;
|
||||||
top: var(--topbar-height);
|
top: var(--topbar-total-height, var(--topbar-height));
|
||||||
z-index: 45;
|
z-index: 45;
|
||||||
box-shadow: var(--shadow-md);
|
box-shadow: var(--shadow-md);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ const App = {
|
|||||||
delete this.drafts[ticketId];
|
delete this.drafts[ticketId];
|
||||||
}
|
}
|
||||||
localStorage.setItem('otrs_turbo_drafts', JSON.stringify(this.drafts));
|
localStorage.setItem('otrs_turbo_drafts', JSON.stringify(this.drafts));
|
||||||
|
this.renderTabs();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -98,6 +99,7 @@ const App = {
|
|||||||
if (!bar) return;
|
if (!bar) return;
|
||||||
if (this.tabs.length === 0) {
|
if (this.tabs.length === 0) {
|
||||||
bar.style.display = 'none';
|
bar.style.display = 'none';
|
||||||
|
this.updateHeaderHeight();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
bar.style.display = 'flex';
|
bar.style.display = 'flex';
|
||||||
@@ -106,14 +108,26 @@ const App = {
|
|||||||
|
|
||||||
bar.innerHTML = this.tabs.map(t => {
|
bar.innerHTML = this.tabs.map(t => {
|
||||||
const isActive = currentHash === `#/tickets/${t.id}`;
|
const isActive = currentHash === `#/tickets/${t.id}`;
|
||||||
|
const hasEmailDraft = this.getDraft(t.id, 'email');
|
||||||
|
const emailIconHtml = hasEmailDraft ? `<span style="color:#22c55e; margin-right:4px;" title="Bozza email presente">✉️</span>` : '';
|
||||||
const displayTitle = t.title ? (t.title.length > 25 ? t.title.substring(0, 22) + '...' : t.title) : `#${t.tn}`;
|
const displayTitle = t.title ? (t.title.length > 25 ? t.title.substring(0, 22) + '...' : t.title) : `#${t.tn}`;
|
||||||
return `
|
return `
|
||||||
<div class="tab-item ${isActive ? 'active' : ''}" onclick="window.location.hash = '#/tickets/${t.id}'" title="${App.escapeHtml(t.title || '')}">
|
<div class="tab-item ${isActive ? 'active' : ''}" onclick="window.location.hash = '#/tickets/${t.id}'" title="${App.escapeHtml(t.title || '')}">
|
||||||
|
${emailIconHtml}
|
||||||
<span>${App.escapeHtml(displayTitle)}</span>
|
<span>${App.escapeHtml(displayTitle)}</span>
|
||||||
<button class="tab-close" onclick="App.closeTab(${t.id}, event)">✕</button>
|
<button class="tab-close" onclick="App.closeTab(${t.id}, event)">✕</button>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
}).join('');
|
}).join('');
|
||||||
|
this.updateHeaderHeight();
|
||||||
|
},
|
||||||
|
|
||||||
|
updateHeaderHeight() {
|
||||||
|
const topbar = document.getElementById('topbar');
|
||||||
|
if (topbar) {
|
||||||
|
const height = topbar.offsetHeight;
|
||||||
|
document.documentElement.style.setProperty('--topbar-total-height', `${height}px`);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
get currentAgentId() {
|
get currentAgentId() {
|
||||||
@@ -202,6 +216,9 @@ const App = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Initial route
|
// Initial route
|
||||||
|
window.addEventListener('resize', () => this.updateHeaderHeight());
|
||||||
|
setTimeout(() => this.updateHeaderHeight(), 100);
|
||||||
|
|
||||||
if (!window.location.hash || window.location.hash === '#/') {
|
if (!window.location.hash || window.location.hash === '#/') {
|
||||||
window.location.hash = '#/dashboard';
|
window.location.hash = '#/dashboard';
|
||||||
} else {
|
} else {
|
||||||
@@ -226,6 +243,7 @@ const App = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.renderTabs();
|
this.renderTabs();
|
||||||
|
this.updateHeaderHeight();
|
||||||
|
|
||||||
const container = document.getElementById('view-container');
|
const container = document.getElementById('view-container');
|
||||||
if (container) {
|
if (container) {
|
||||||
|
|||||||
@@ -606,6 +606,13 @@ const EmailCompose = (() => {
|
|||||||
if (currentOptions.ticketId) {
|
if (currentOptions.ticketId) {
|
||||||
App.clearDraft(currentOptions.ticketId, 'email');
|
App.clearDraft(currentOptions.ticketId, 'email');
|
||||||
}
|
}
|
||||||
|
const btn = document.getElementById('btn-open-email-compose');
|
||||||
|
if (btn) {
|
||||||
|
const svg = btn.querySelector('svg');
|
||||||
|
btn.innerHTML = '';
|
||||||
|
if (svg) btn.appendChild(svg);
|
||||||
|
btn.appendChild(document.createTextNode(' Invia Email'));
|
||||||
|
}
|
||||||
const overlay = document.getElementById('email-compose-overlay');
|
const overlay = document.getElementById('email-compose-overlay');
|
||||||
if (overlay) overlay.remove();
|
if (overlay) overlay.remove();
|
||||||
if (quillEditor) { quillEditor = null; }
|
if (quillEditor) { quillEditor = null; }
|
||||||
@@ -636,6 +643,15 @@ const EmailCompose = (() => {
|
|||||||
attachments: [...attachmentsList],
|
attachments: [...attachmentsList],
|
||||||
options: currentOptions
|
options: currentOptions
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const btn = document.getElementById('btn-open-email-compose');
|
||||||
|
if (btn) {
|
||||||
|
const svg = btn.querySelector('svg');
|
||||||
|
btn.innerHTML = '';
|
||||||
|
if (svg) btn.appendChild(svg);
|
||||||
|
btn.appendChild(document.createTextNode(' Continua mail'));
|
||||||
|
}
|
||||||
|
App.renderTabs();
|
||||||
}
|
}
|
||||||
|
|
||||||
return { open, close, saveDraft };
|
return { open, close, saveDraft };
|
||||||
|
|||||||
@@ -103,6 +103,9 @@ const TicketDetailView = {
|
|||||||
customer_last: ticket.customer_last,
|
customer_last: ticket.customer_last,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const hasEmailDraft = App.getDraft(id, 'email');
|
||||||
|
const emailBtnText = hasEmailDraft ? 'Continua mail' : 'Invia Email';
|
||||||
|
|
||||||
container.innerHTML = `
|
container.innerHTML = `
|
||||||
<a class="back-link" onclick="history.back()">
|
<a class="back-link" onclick="history.back()">
|
||||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="width:16px;height:16px;"><path d="M19 12H5M12 19l-7-7 7-7"/></svg>
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="width:16px;height:16px;"><path d="M19 12H5M12 19l-7-7 7-7"/></svg>
|
||||||
@@ -227,7 +230,7 @@ const TicketDetailView = {
|
|||||||
<button class="btn btn-ghost btn-sm" id="btn-open-email-compose" style="height:32px; display:flex; align-items:center; gap:var(--space-xs); border-color:var(--accent-secondary); color:var(--accent-secondary);"
|
<button class="btn btn-ghost btn-sm" id="btn-open-email-compose" style="height:32px; display:flex; align-items:center; gap:var(--space-xs); border-color:var(--accent-secondary); color:var(--accent-secondary);"
|
||||||
data-ticket-id="${ticket.id}" data-ticket-tn="${ticket.tn}" data-ticket-title="${App.escapeHtml(ticket.title)}" data-customer-email="${App.escapeHtml(ticket.customer_email || '')}">
|
data-ticket-id="${ticket.id}" data-ticket-tn="${ticket.tn}" data-ticket-title="${App.escapeHtml(ticket.title)}" data-customer-email="${App.escapeHtml(ticket.customer_email || '')}">
|
||||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="width:14px;height:14px;"><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/><polyline points="22,6 12,13 2,6"/></svg>
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="width:14px;height:14px;"><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/><polyline points="22,6 12,13 2,6"/></svg>
|
||||||
Invia Email
|
${emailBtnText}
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-primary btn-sm" id="note-send" style="height:32px; display:flex; align-items:center; gap:var(--space-xs);">
|
<button class="btn btn-primary btn-sm" id="note-send" style="height:32px; display:flex; align-items:center; gap:var(--space-xs);">
|
||||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="width:14px;height:14px;"><path d="M22 2L11 13M22 2l-7 20-4-9-9-4 20-7z"/></svg>
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="width:14px;height:14px;"><path d="M22 2L11 13M22 2l-7 20-4-9-9-4 20-7z"/></svg>
|
||||||
@@ -505,20 +508,6 @@ const TicketDetailView = {
|
|||||||
this.updateNoteAttachmentList();
|
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);
|
this.bindEvents(ticket, articles, container, groupsData);
|
||||||
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -863,12 +852,21 @@ const TicketDetailView = {
|
|||||||
if (btnEmailCompose) {
|
if (btnEmailCompose) {
|
||||||
btnEmailCompose.addEventListener('click', () => {
|
btnEmailCompose.addEventListener('click', () => {
|
||||||
if (window.EmailCompose) {
|
if (window.EmailCompose) {
|
||||||
EmailCompose.open({
|
const tId = parseInt(btnEmailCompose.dataset.ticketId, 10);
|
||||||
ticketId: parseInt(btnEmailCompose.dataset.ticketId, 10),
|
const emailDraft = App.getDraft(tId, 'email');
|
||||||
ticketTn: btnEmailCompose.dataset.ticketTn,
|
if (emailDraft) {
|
||||||
ticketTitle: btnEmailCompose.dataset.ticketTitle,
|
EmailCompose.open({
|
||||||
customerEmail: btnEmailCompose.dataset.customerEmail,
|
...emailDraft.options,
|
||||||
});
|
draft: emailDraft
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
EmailCompose.open({
|
||||||
|
ticketId: tId,
|
||||||
|
ticketTn: btnEmailCompose.dataset.ticketTn,
|
||||||
|
ticketTitle: btnEmailCompose.dataset.ticketTitle,
|
||||||
|
customerEmail: btnEmailCompose.dataset.customerEmail,
|
||||||
|
});
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Toast.error('Modulo email non disponibile');
|
Toast.error('Modulo email non disponibile');
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user