fix: restore archive completion notification polling
Track monthly archive generation by generated_archive_id and poll notifications until completed/failed (up to timeout) instead of short PDF polling only. This restores completed ZIP notifications for calendar archive actions when generation takes longer. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -28,6 +28,9 @@ const DASHBOARD_FETCH_TTL_MS = 30_000; // 30 sekundi
|
||||
let dbPromise = null;
|
||||
let syncListenerStarted = false;
|
||||
let isSyncInProgress = false;
|
||||
const archiveNotificationPollers = new Map();
|
||||
const ARCHIVE_NOTIFICATION_POLL_INTERVAL_MS = 10_000;
|
||||
const ARCHIVE_NOTIFICATION_POLL_TIMEOUT_MS = 15 * 60 * 1000;
|
||||
|
||||
function isBrowser() {
|
||||
return typeof window !== 'undefined';
|
||||
@@ -866,6 +869,70 @@ function _schedulePdfNotificationPolling() {
|
||||
});
|
||||
}
|
||||
|
||||
function _findCompletedArchiveNotification(notifications, generatedArchiveId) {
|
||||
if (!generatedArchiveId || !Array.isArray(notifications)) {
|
||||
return null;
|
||||
}
|
||||
return notifications.find((notification) => {
|
||||
const metadata = notification?.metadata || {};
|
||||
return metadata.entity_type === 'fleet_archive'
|
||||
&& String(metadata.generated_archive_id || '') === String(generatedArchiveId)
|
||||
&& ['completed', 'failed'].includes(String(metadata.stage || ''));
|
||||
}) || null;
|
||||
}
|
||||
|
||||
function _clearArchiveNotificationPoller(generatedArchiveId) {
|
||||
const key = String(generatedArchiveId || '');
|
||||
const handles = archiveNotificationPollers.get(key);
|
||||
if (!handles) {
|
||||
return;
|
||||
}
|
||||
window.clearInterval(handles.intervalId);
|
||||
window.clearTimeout(handles.timeoutId);
|
||||
archiveNotificationPollers.delete(key);
|
||||
}
|
||||
|
||||
function _scheduleArchiveNotificationPolling(generatedArchiveId = null) {
|
||||
if (!isBrowser()) return;
|
||||
if (!generatedArchiveId) {
|
||||
[5000, 20000, 60000].forEach((delay) => {
|
||||
setTimeout(() => _refreshNotificationsAsync(), delay);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const key = String(generatedArchiveId);
|
||||
if (archiveNotificationPollers.has(key)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const pollOnce = async () => {
|
||||
try {
|
||||
const notificationModule = await import('./notificationStore.js');
|
||||
await notificationModule.fetchNotifications();
|
||||
const resolvedNotification = _findCompletedArchiveNotification(
|
||||
notificationModule.$notifications.get(),
|
||||
key
|
||||
);
|
||||
if (resolvedNotification) {
|
||||
_clearArchiveNotificationPoller(key);
|
||||
}
|
||||
} catch (_) {
|
||||
// silent — korisnik će i dalje vidjeti toast ili ručno osvježiti notifikacije
|
||||
}
|
||||
};
|
||||
|
||||
const intervalId = window.setInterval(() => {
|
||||
void pollOnce();
|
||||
}, ARCHIVE_NOTIFICATION_POLL_INTERVAL_MS);
|
||||
const timeoutId = window.setTimeout(() => {
|
||||
_clearArchiveNotificationPoller(key);
|
||||
}, ARCHIVE_NOTIFICATION_POLL_TIMEOUT_MS);
|
||||
|
||||
archiveNotificationPollers.set(key, { intervalId, timeoutId });
|
||||
void pollOnce();
|
||||
}
|
||||
|
||||
export async function downloadWorkOrderPdf(workOrderId) {
|
||||
if (!workOrderId) {
|
||||
throw new Error('Work order ID je obavezan.');
|
||||
@@ -1030,7 +1097,7 @@ export async function downloadMonthlyServiceTasksArchive(year, month) {
|
||||
return payload;
|
||||
}
|
||||
showToast('ZIP arhiva servisnih taskova se generira u pozadini. Preuzimanje je dostupno kroz notifikaciju.', 'info');
|
||||
_schedulePdfNotificationPolling();
|
||||
_scheduleArchiveNotificationPolling(payload?.generated_archive_id || null);
|
||||
return payload;
|
||||
} catch (err) {
|
||||
showToast(err?.message || 'Pokretanje generiranja ZIP arhive servisnih taskova nije uspjelo.', 'error');
|
||||
@@ -1047,7 +1114,7 @@ export async function downloadMonthlyWorkOrdersArchive(year, month) {
|
||||
return payload;
|
||||
}
|
||||
showToast('ZIP arhiva putnih naloga se generira u pozadini. Preuzimanje je dostupno kroz notifikaciju.', 'info');
|
||||
_schedulePdfNotificationPolling();
|
||||
_scheduleArchiveNotificationPolling(payload?.generated_archive_id || null);
|
||||
return payload;
|
||||
} catch (err) {
|
||||
showToast(err?.message || 'Pokretanje generiranja ZIP arhive putnih naloga nije uspjelo.', 'error');
|
||||
|
||||
Reference in New Issue
Block a user