Pages corrections widget

This commit is contained in:
alma 2026-01-16 17:24:36 +01:00
parent 430940cc12
commit ed9dadd77a
7 changed files with 164 additions and 116 deletions

View File

@ -117,7 +117,7 @@ export function CalendarWidget() {
if (currentEventCount !== lastEventCountRef.current) { if (currentEventCount !== lastEventCountRef.current) {
lastEventCountRef.current = currentEventCount; lastEventCountRef.current = currentEventCount;
// Prepare notification items // Always prepare notification items (even if count hasn't changed)
const notificationItems = upcomingEvents.map(event => ({ const notificationItems = upcomingEvents.map(event => ({
id: event.id, id: event.id,
title: event.title, title: event.title,
@ -133,12 +133,17 @@ export function CalendarWidget() {
}, },
})); }));
// Trigger notification update // Always trigger notification update to keep count fresh in Redis
// This ensures the count doesn't expire even if it hasn't changed
await triggerNotification({ await triggerNotification({
source: 'calendar', source: 'calendar',
count: currentEventCount, count: currentEventCount,
items: notificationItems, items: notificationItems,
}); });
// Update last count reference
if (currentEventCount !== lastEventCountRef.current) {
lastEventCountRef.current = currentEventCount;
} }
setEvents(upcomingEvents.slice(0, 5)); // Keep only 5 for display setEvents(upcomingEvents.slice(0, 5)); // Keep only 5 for display

View File

@ -195,12 +195,13 @@ export function Email() {
lastUnreadCountRef.current = currentUnreadCount; lastUnreadCountRef.current = currentUnreadCount;
isInitializedRef.current = true; isInitializedRef.current = true;
} else { } else {
// Trigger notification if count changed or new emails detected // Update count if it changed
if (currentUnreadCount !== lastUnreadCountRef.current || hasNewEmails) { if (currentUnreadCount !== lastUnreadCountRef.current) {
const previousCount = lastUnreadCountRef.current;
lastUnreadCountRef.current = currentUnreadCount; lastUnreadCountRef.current = currentUnreadCount;
}
}
// Prepare notification items (unread emails only, max 10) // Always prepare notification items (unread emails only, max 10)
const notificationItems = transformedEmails const notificationItems = transformedEmails
.filter(e => !e.read) .filter(e => !e.read)
.slice(0, 10) .slice(0, 10)
@ -219,7 +220,8 @@ export function Email() {
}; };
}); });
// Trigger notification update (for badge) // Always trigger notification update to keep count fresh in Redis
// This ensures the count doesn't expire even if it hasn't changed
await triggerNotification({ await triggerNotification({
source: 'email', source: 'email',
count: currentUnreadCount, count: currentUnreadCount,

View File

@ -218,9 +218,13 @@ export function Duties() {
// Calculate current task count // Calculate current task count
const currentTaskCount = sortedTasks.length; const currentTaskCount = sortedTasks.length;
// Trigger notification if count changed // Always trigger notification to keep the count fresh in Redis
if (currentTaskCount !== lastTaskCountRef.current) { // This prevents the count from expiring if it hasn't changed
const shouldUpdate = currentTaskCount !== lastTaskCountRef.current || lastTaskCountRef.current === -1;
if (shouldUpdate) {
lastTaskCountRef.current = currentTaskCount; lastTaskCountRef.current = currentTaskCount;
}
// Prepare notification items (max 10) // Prepare notification items (max 10)
const notificationItems = sortedTasks const notificationItems = sortedTasks
@ -244,13 +248,13 @@ export function Duties() {
}, },
})); }));
// Trigger notification update // Always trigger notification update to keep count fresh in Redis
// This ensures the count doesn't expire even if it hasn't changed
await triggerNotification({ await triggerNotification({
source: 'leantime', source: 'leantime',
count: currentTaskCount, count: currentTaskCount,
items: notificationItems, items: notificationItems,
}); });
}
setTasks(sortedTasks); setTasks(sortedTasks);

View File

@ -27,12 +27,21 @@ export const NotificationBadge = memo(function NotificationBadge({ className }:
const [isOpen, setIsOpen] = useState(false); const [isOpen, setIsOpen] = useState(false);
const [manualFetchAttempted, setManualFetchAttempted] = useState(false); const [manualFetchAttempted, setManualFetchAttempted] = useState(false);
console.log('[NOTIFICATION_BADGE] Auth status:', status); console.log('[NOTIFICATION_BADGE] 📊 Notification state:', {
console.log('[NOTIFICATION_BADGE] Session:', session ? 'exists' : 'null'); authStatus: status,
console.log('[NOTIFICATION_BADGE] Current notification count:', notificationCount); hasSession: !!session,
console.log('[NOTIFICATION_BADGE] Current notifications:', notifications.length > 0 ? `${notifications.length} loaded` : 'none loaded'); totalUnread: notificationCount.unread,
console.log('[NOTIFICATION_BADGE] Loading state:', loading); total: notificationCount.total,
console.log('[NOTIFICATION_BADGE] Error state:', error); sources: Object.keys(notificationCount.sources || {}).map(source => ({
source,
unread: notificationCount.sources[source]?.unread || 0,
total: notificationCount.sources[source]?.total || 0,
})),
hasUnread: notificationCount.unread > 0,
notificationsLoaded: notifications.length,
loading,
error: error || null,
});
// Manual fetch function with error handling // Manual fetch function with error handling
const manualFetch = async () => { const manualFetch = async () => {

View File

@ -96,12 +96,13 @@ export function Parole() {
lastUnreadCountRef.current = currentUnreadCount; lastUnreadCountRef.current = currentUnreadCount;
isInitializedRef.current = true; isInitializedRef.current = true;
} else { } else {
// Si le count a changé ou nouveaux messages détectés, déclencher notification // Update count if it changed
if (currentUnreadCount !== lastUnreadCountRef.current || hasNewMessages) { if (currentUnreadCount !== lastUnreadCountRef.current) {
const previousCount = lastUnreadCountRef.current;
lastUnreadCountRef.current = currentUnreadCount; lastUnreadCountRef.current = currentUnreadCount;
}
}
// Préparer les items pour les notifications (messages, max 10) // Always prepare notification items (messages, max 10)
const notificationItems = data.messages const notificationItems = data.messages
.slice(0, 10) .slice(0, 10)
.map((msg: any) => ({ .map((msg: any) => ({
@ -116,7 +117,8 @@ export function Parole() {
}, },
})); }));
// Déclencher notification update (for badge) // Always trigger notification update to keep count fresh in Redis
// This ensures the count doesn't expire even if it hasn't changed
await triggerNotification({ await triggerNotification({
source: 'rocketchat', source: 'rocketchat',
count: currentUnreadCount, count: currentUnreadCount,

View File

@ -58,7 +58,14 @@ export function useNotifications() {
); );
if (isMountedRef.current) { if (isMountedRef.current) {
console.log('[useNotifications] Received notification count:', data); console.log('[useNotifications] Received notification count:', {
total: data.total,
unread: data.unread,
sources: Object.keys(data.sources || {}).map(source => ({
source,
count: data.sources[source]?.unread || 0,
})),
});
setNotificationCount(data); setNotificationCount(data);
} }
} catch (err: any) { } catch (err: any) {

View File

@ -20,7 +20,7 @@ export class NotificationRegistry {
private static COUNT_CACHE_KEY = (userId: string) => `notifications:count:${userId}`; private static COUNT_CACHE_KEY = (userId: string) => `notifications:count:${userId}`;
private static ITEMS_CACHE_KEY = (userId: string, source: string) => private static ITEMS_CACHE_KEY = (userId: string, source: string) =>
`notifications:items:${userId}:${source}`; `notifications:items:${userId}:${source}`;
private static COUNT_CACHE_TTL = 30; // 30 seconds (aligned with refresh interval) private static COUNT_CACHE_TTL = 300; // 5 minutes (increased to prevent premature expiration)
private static ITEMS_CACHE_TTL = 300; // 5 minutes for items private static ITEMS_CACHE_TTL = 300; // 5 minutes for items
public static getInstance(): NotificationRegistry { public static getInstance(): NotificationRegistry {
@ -72,12 +72,31 @@ export class NotificationRegistry {
total: previousSourceCount + count, total: previousSourceCount + count,
unread: previousSourceCount + count, unread: previousSourceCount + count,
}; };
logger.debug('[NOTIFICATION_REGISTRY] Call count incremented', {
source,
previousCount: previousSourceCount,
newCount: currentCount.sources[source].unread,
});
} else { } else {
// For regular updates, set the count (widgets send their total) // For regular updates, set the count (widgets send their total)
// Only update if the new count is different or if we're setting it for the first time
if (count !== previousSourceCount || !currentCount.sources[source]) {
currentCount.sources[source] = { currentCount.sources[source] = {
total: count, total: count,
unread: count, unread: count,
}; };
logger.debug('[NOTIFICATION_REGISTRY] Count updated', {
source,
previousCount: previousSourceCount,
newCount: count,
});
} else {
// Count hasn't changed, but refresh the TTL to keep it alive
logger.debug('[NOTIFICATION_REGISTRY] Count unchanged, refreshing TTL', {
source,
count,
});
}
} }
// Recalculate total // Recalculate total