Add frontend alerts imporvements

This commit is contained in:
Urtzi Alfaro
2025-12-29 08:11:29 +01:00
parent 96d8576103
commit 2e7e1f5557
7 changed files with 351 additions and 190 deletions

View File

@@ -3,7 +3,7 @@
* Main dashboard for enterprise parent tenants showing network-wide metrics
*/
import React, { useState, useEffect } from 'react';
import React, { useState, useEffect, useRef } from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import {
useNetworkSummary,
@@ -72,15 +72,21 @@ const EnterpriseDashboardPage: React.FC<EnterpriseDashboardPageProps> = ({ tenan
const queryClient = useQueryClient();
// SSE Integration for real-time updates
const { events: sseEvents } = useSSEEvents({
channels: ['*.alerts', '*.notifications', 'recommendations']
const { events: sseEvents } = useSSEEvents({
channels: ['*.alerts', '*.notifications', 'recommendations']
});
// Invalidate enterprise data on relevant SSE events
useEffect(() => {
if (sseEvents.length === 0 || !tenantId) return;
// Refs for debouncing SSE-triggered invalidations
const invalidationTimeoutRef = useRef<NodeJS.Timeout | null>(null);
const lastEventCountRef = useRef<number>(0);
// Invalidate enterprise data on relevant SSE events (debounced)
useEffect(() => {
// Skip if no new events since last check
if (sseEvents.length === 0 || !tenantId || sseEvents.length === lastEventCountRef.current) {
return;
}
const latest = sseEvents[0];
const relevantEventTypes = [
'batch_completed', 'batch_started', 'batch_state_changed',
'delivery_received', 'delivery_overdue', 'delivery_arriving_soon',
@@ -88,30 +94,49 @@ const EnterpriseDashboardPage: React.FC<EnterpriseDashboardPageProps> = ({ tenan
'production_delay', 'batch_start_delayed', 'equipment_maintenance',
'network_alert', 'outlet_performance_update', 'distribution_route_update'
];
if (relevantEventTypes.includes(latest.event_type)) {
// Invalidate all enterprise dashboard queries
queryClient.invalidateQueries({
queryKey: ['enterprise', 'network-summary', tenantId],
refetchType: 'active',
});
queryClient.invalidateQueries({
queryKey: ['enterprise', 'children-performance', tenantId],
refetchType: 'active',
});
queryClient.invalidateQueries({
queryKey: ['enterprise', 'distribution-overview', tenantId],
refetchType: 'active',
});
queryClient.invalidateQueries({
queryKey: ['enterprise', 'forecast-summary', tenantId],
refetchType: 'active',
});
queryClient.invalidateQueries({
queryKey: ['control-panel-data', tenantId],
refetchType: 'active',
});
// Check if any event is relevant
const hasRelevantEvent = sseEvents.some(event =>
relevantEventTypes.includes(event.event_type)
);
if (hasRelevantEvent) {
// Clear existing timeout to debounce rapid events
if (invalidationTimeoutRef.current) {
clearTimeout(invalidationTimeoutRef.current);
}
// Debounce the invalidation to prevent multiple rapid refetches
invalidationTimeoutRef.current = setTimeout(() => {
lastEventCountRef.current = sseEvents.length;
// Invalidate all enterprise dashboard queries in a single batch
queryClient.invalidateQueries({
queryKey: ['enterprise', 'network-summary', tenantId],
refetchType: 'active',
});
queryClient.invalidateQueries({
queryKey: ['enterprise', 'children-performance', tenantId],
refetchType: 'active',
});
queryClient.invalidateQueries({
queryKey: ['enterprise', 'distribution-overview', tenantId],
refetchType: 'active',
});
queryClient.invalidateQueries({
queryKey: ['enterprise', 'forecast-summary', tenantId],
refetchType: 'active',
});
// Note: control-panel-data has its own debounced invalidation in useControlPanelData
}, 500); // 500ms debounce
}
// Cleanup timeout on unmount or dependency change
return () => {
if (invalidationTimeoutRef.current) {
clearTimeout(invalidationTimeoutRef.current);
}
};
}, [sseEvents, tenantId, queryClient]);
// Check if tenantId is available at the start