fix: ora le ricerche asincrone non si sovrappongono più alle attività. feat: aggiunta funzione Storico Consuntivazione
This commit is contained in:
1 parent
ba23635c7d
commit
3650bf5790
9 files changed
+737
-33
No files matched your search
@@ -9,10 +9,51 @@ const TicketListView = {
|
||||
sortDir: 'DESC',
|
||||
selectedIds: new Set(),
|
||||
selectedOrder: [],
|
||||
searchTimeout: null,
|
||||
lastQueryParams: null,
|
||||
cachedData: null,
|
||||
needsRefresh: false,
|
||||
|
||||
async render() {
|
||||
invalidateCache() {
|
||||
this.lastQueryParams = null;
|
||||
this.cachedData = null;
|
||||
},
|
||||
|
||||
async render(force = false) {
|
||||
const isMyTickets = window.location.hash.startsWith('#/tickets/my');
|
||||
Filters.currentMode = isMyTickets ? 'my' : 'general';
|
||||
Filters.load(); // Load state for current mode
|
||||
|
||||
if (isMyTickets) {
|
||||
const activeAgentId = localStorage.getItem('activeAgentId') || '1';
|
||||
Filters.state.user_id = activeAgentId;
|
||||
Filters.save();
|
||||
}
|
||||
|
||||
const params = Filters.toQueryParams();
|
||||
params.set('page', this.currentPage);
|
||||
params.set('per_page', this.perPage);
|
||||
params.set('sort_by', this.sortBy);
|
||||
params.set('sort_dir', this.sortDir);
|
||||
|
||||
const searchInput = document.getElementById('global-search');
|
||||
if (searchInput && searchInput.value.trim()) {
|
||||
params.set('search', searchInput.value.trim());
|
||||
}
|
||||
|
||||
const currentQueryString = `${Filters.currentMode}:${params.toString()}`;
|
||||
const container = document.getElementById('view-container');
|
||||
|
||||
// Return cached results instantly if query params haven't changed and no force refresh requested
|
||||
if (!force && !this.needsRefresh && this.lastQueryParams === currentQueryString && this.cachedData) {
|
||||
const currentHash = (window.location.hash || '#/dashboard').split('?')[0];
|
||||
if (currentHash !== '#/tickets' && currentHash !== '#/tickets/my') {
|
||||
return;
|
||||
}
|
||||
this.renderContent(container, this.cachedData);
|
||||
this.bindEvents(this.cachedData);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!container.querySelector('.ticket-table-wrapper') && !container.querySelector('.ticket-table')) {
|
||||
container.innerHTML = '<div class="loading-screen"><div class="spinner"></div><p>Caricamento ticket...</p></div>';
|
||||
}
|
||||
@@ -31,34 +72,28 @@ const TicketListView = {
|
||||
console.warn('Failed to load agent settings:', err);
|
||||
}
|
||||
|
||||
// Build query params
|
||||
const isMyTickets = window.location.hash.startsWith('#/tickets/my');
|
||||
Filters.currentMode = isMyTickets ? 'my' : 'general';
|
||||
Filters.load(); // Load state for current mode
|
||||
|
||||
if (isMyTickets) {
|
||||
const activeAgentId = localStorage.getItem('activeAgentId') || '1';
|
||||
Filters.state.user_id = activeAgentId;
|
||||
Filters.save();
|
||||
}
|
||||
|
||||
const params = Filters.toQueryParams();
|
||||
params.set('page', this.currentPage);
|
||||
params.set('per_page', this.perPage);
|
||||
params.set('sort_by', this.sortBy);
|
||||
params.set('sort_dir', this.sortDir);
|
||||
|
||||
const searchInput = document.getElementById('global-search');
|
||||
if (searchInput && searchInput.value.trim()) {
|
||||
params.set('search', searchInput.value.trim());
|
||||
}
|
||||
|
||||
const data = await App.api(`/api/tickets?${params.toString()}`);
|
||||
|
||||
// Route guard: if the user navigated away while the async search was in flight, do not overwrite the view
|
||||
const currentHash = (window.location.hash || '#/dashboard').split('?')[0];
|
||||
if (currentHash !== '#/tickets' && currentHash !== '#/tickets/my') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Save to cache
|
||||
this.lastQueryParams = currentQueryString;
|
||||
this.cachedData = data;
|
||||
this.needsRefresh = false;
|
||||
|
||||
this.renderContent(container, data);
|
||||
this.bindEvents(data);
|
||||
|
||||
} catch (err) {
|
||||
const currentHash = (window.location.hash || '#/dashboard').split('?')[0];
|
||||
if (currentHash !== '#/tickets' && currentHash !== '#/tickets/my') {
|
||||
return;
|
||||
}
|
||||
|
||||
container.innerHTML = `
|
||||
<div class="empty-state">
|
||||
<div class="empty-state-icon">⚠️</div>
|
||||
@@ -679,6 +714,7 @@ const TicketListView = {
|
||||
Toast.success(res.message || `${this.selectedIds.size} ticket aggiornati`);
|
||||
this.selectedIds.clear();
|
||||
this.selectedOrder = [];
|
||||
this.invalidateCache();
|
||||
this.render();
|
||||
} catch (err) {
|
||||
Toast.error('Errore aggiornamento batch: ' + err.message);
|
||||
@@ -727,6 +763,8 @@ const TicketListView = {
|
||||
Toast.success(res.message || 'Ticket uniti con successo');
|
||||
this.selectedIds.clear();
|
||||
this.selectedOrder = [];
|
||||
this.invalidateCache();
|
||||
this.render();
|
||||
} catch (err) {
|
||||
Toast.error('Errore durante l\'unione: ' + err.message);
|
||||
this.updateBatchBar();
|
||||
@@ -799,6 +837,7 @@ const TicketListView = {
|
||||
Toast.success(`${addedCount} ticket aggiunti al gruppo!`);
|
||||
this.selectedIds.clear();
|
||||
this.selectedOrder = [];
|
||||
this.invalidateCache();
|
||||
this.render();
|
||||
} else if (errorsCount > 0) {
|
||||
Toast.warning('I ticket selezionati appartengono già a questo gruppo.');
|
||||
|
||||
Reference in new issue
Block a user