diff --git a/public/css/style.css b/public/css/style.css index 9e31f8f..5cb0bef 100644 --- a/public/css/style.css +++ b/public/css/style.css @@ -903,6 +903,36 @@ body { color: var(--accent-primary); } +/* Queue Custom Tooltip */ +.ticket-table td.queue-cell { + position: relative; + overflow: visible !important; +} +.queue-tooltip { + visibility: hidden; + opacity: 0; + position: absolute; + left: 50%; + bottom: 100%; + transform: translate(-50%, -6px); + background: var(--bg-tertiary); + color: var(--text-primary); + border: 1px solid var(--border-subtle); + padding: 6px 12px; + border-radius: var(--radius-md); + font-size: 0.8rem; + font-weight: 500; + white-space: nowrap; + box-shadow: var(--shadow-lg); + z-index: 1000; + transition: opacity 0.05s ease, visibility 0.05s ease; + pointer-events: none; +} +.queue-cell:hover .queue-tooltip { + visibility: visible; + opacity: 1; +} + .ticket-table td { padding: 10px var(--space-md); border-bottom: 1px solid var(--border-subtle); @@ -1067,6 +1097,12 @@ body { backdrop-filter: blur(12px); border: 1px solid var(--border-subtle); border-radius: var(--radius-lg); + position: relative; + z-index: 20; +} + +.state-multiselect-item:hover { + background: rgba(255, 255, 255, 0.05); } .filter-group { diff --git a/public/js/components/filters.js b/public/js/components/filters.js index de0b3fc..1d034f9 100644 --- a/public/js/components/filters.js +++ b/public/js/components/filters.js @@ -3,21 +3,50 @@ * Manages ticket list filter state and renders filter dropdowns. */ const Filters = { - state: { - queue_id: '', - state_id: '', - priority_id: '', - user_id: '', - date_from: '', - date_to: '', + currentMode: 'general', // 'general' or 'my' + + allStates: { + general: { + queue_id: '', + state_id: '', + priority_id: '', + user_id: '', + date_from: '', + date_to: '', + }, + my: { + queue_id: '', + state_id: '', + priority_id: '', + user_id: '', + date_from: '', + date_to: '', + } + }, + + // Dynamic state getter based on active mode + get state() { + return this.allStates[this.currentMode]; + }, + + set state(val) { + this.allStates[this.currentMode] = val; }, /** Load saved filters from localStorage */ load() { try { - const saved = localStorage.getItem('otrs_turbo_filters'); - if (saved) { - Object.assign(this.state, JSON.parse(saved)); + const savedGeneral = localStorage.getItem('otrs_turbo_filters_general'); + if (savedGeneral) { + Object.assign(this.allStates.general, JSON.parse(savedGeneral)); + } + const savedMy = localStorage.getItem('otrs_turbo_filters_my'); + if (savedMy) { + Object.assign(this.allStates.my, JSON.parse(savedMy)); + } else { + // Default to active agent if not saved yet + const activeAgentId = localStorage.getItem('activeAgentId') || '1'; + this.allStates.my.user_id = activeAgentId; } } catch (e) { /* ignore */ } }, @@ -25,13 +54,17 @@ const Filters = { /** Save filters to localStorage */ save() { try { - localStorage.setItem('otrs_turbo_filters', JSON.stringify(this.state)); + localStorage.setItem(`otrs_turbo_filters_${this.currentMode}`, JSON.stringify(this.state)); } catch (e) { /* ignore */ } }, /** Reset all filters */ reset() { this.state = { queue_id: '', state_id: '', priority_id: '', user_id: '', date_from: '', date_to: '' }; + if (this.currentMode === 'my') { + const activeAgentId = localStorage.getItem('activeAgentId') || '1'; + this.state.user_id = activeAgentId; + } this.save(); }, @@ -44,6 +77,36 @@ const Filters = { return params; }, + /** Helper to compute trigger button label text */ + getStateMultiselectLabel(lookups) { + const selectedList = Array.isArray(this.state.state_id) + ? this.state.state_id + : (typeof this.state.state_id === 'string' && this.state.state_id ? this.state.state_id.split(',') : []); + + if (selectedList.length === 0) { + return 'Tutti'; + } + const selectedNames = (lookups.states || []) + .filter(s => selectedList.includes(String(s.id))) + .map(s => s.name); + + if (selectedNames.length === (lookups.states || []).length) { + return 'Tutti'; + } else if (selectedNames.length <= 2) { + return selectedNames.join(', '); + } else { + return `${selectedNames.length} selezionati`; + } + }, + + /** Update label DOM element dynamically */ + updateStateMultiselectLabel(lookups) { + const labelEl = document.getElementById('state-multiselect-label'); + if (labelEl) { + labelEl.textContent = this.getStateMultiselectLabel(lookups); + } + }, + /** * Render filter bar HTML. * @param {Object} lookups - { queues, states, priorities, users } @@ -59,14 +122,36 @@ const Filters = { }).join(''); }; + const currentLabel = this.getStateMultiselectLabel(lookups); + return `
Caricamento ticket...
| N° | +N° | +Creato | +Stato | Titolo | -Stato | -Priorità | -Coda | -Owner | -Cliente | -Creato | +Coda | +Owner | +Cliente | +Priorità |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ${t.tn} | -${App.escapeHtml(t.title || '(senza titolo)')} | -${t.state_name} | -${App.priorityIndex(t.priority_name)} | -${t.queue_name} | -${t.owner_first || ''} ${t.owner_last || ''} | -${t.customer_first ? `${t.customer_first} ${t.customer_last}` : (t.customer_user_id || '—')} | -${App.formatDateTime(t.create_time)} | -|||||||
| + + ${t.tn} + ${data.otrsBaseUrl ? ` + + O + + ` : ''} + + | +${App.formatDateTime(t.create_time)} | +${t.state_name} | +${App.escapeHtml(t.title || '(senza titolo)')} | +${App.escapeHtml(shortQueue)} ${App.escapeHtml(t.queue_name)} |
+ ${t.owner_first || ''} ${t.owner_last || ''} | +${t.customer_first ? `${t.customer_first} ${t.customer_last}` : (t.customer_user_id || '—')} | +${App.priorityIndex(t.priority_name)} | +|||||||
| + |
📭
Nessun ticket trovato
@@ -141,9 +161,16 @@ const TicketListView = {
| |||||||||||||