From 618c30ef8483c166f1db0942e05089396a88bdbf Mon Sep 17 00:00:00 2001 From: thibaud-lclr Date: Wed, 22 Apr 2026 09:16:29 +0200 Subject: [PATCH] fix: afficher les notifications sur la vue ticket --- src/components/layout/NotificationCenter.tsx | 56 ++++++++++++++++---- 1 file changed, 45 insertions(+), 11 deletions(-) diff --git a/src/components/layout/NotificationCenter.tsx b/src/components/layout/NotificationCenter.tsx index a319d83..bdbffbb 100644 --- a/src/components/layout/NotificationCenter.tsx +++ b/src/components/layout/NotificationCenter.tsx @@ -7,6 +7,7 @@ import { import { useCallback, useEffect, useMemo, useRef, useState } from "react"; import { useNavigate, useParams } from "react-router-dom"; import { + getTicketResult, listNotifications, markAllNotificationsRead, markNotificationRead, @@ -54,35 +55,68 @@ async function showSystemNotification(notification: OrchaiNotification) { export default function NotificationCenter() { const navigate = useNavigate(); - const { projectId } = useParams(); + const { projectId, ticketId } = useParams(); const containerRef = useRef(null); const [open, setOpen] = useState(false); const [notifications, setNotifications] = useState([]); + const [ticketProjectId, setTicketProjectId] = useState(null); const [filter, setFilter] = useState<"all" | "unread" | "errors" | "fixes">( "all" ); + const scopedProjectId = projectId ?? ticketProjectId; + + useEffect(() => { + if (projectId) { + setTicketProjectId(null); + return; + } + + if (!ticketId) { + setTicketProjectId(null); + return; + } + + setTicketProjectId(null); + let cancelled = false; + + void getTicketResult(ticketId) + .then((result) => { + if (!cancelled) { + setTicketProjectId(result.ticket.project_id); + } + }) + .catch(() => { + if (!cancelled) { + setTicketProjectId(null); + } + }); + + return () => { + cancelled = true; + }; + }, [projectId, ticketId]); const loadNotifications = useCallback(async () => { - if (!projectId) { + if (!scopedProjectId) { setNotifications([]); return; } try { - const items = await listNotifications(projectId, false); + const items = await listNotifications(scopedProjectId, false); setNotifications(items); } catch { // Ignore load errors in layout chrome } - }, [projectId]); + }, [scopedProjectId]); useEffect(() => { void loadNotifications(); }, [loadNotifications]); useLiveRefresh({ - enabled: Boolean(projectId), - projectId, + enabled: Boolean(scopedProjectId), + projectId: scopedProjectId, refresh: loadNotifications, fallbackIntervalMs: 15_000, }); @@ -96,7 +130,7 @@ export default function NotificationCenter() { const cleanup = await listen("new-notification", (event) => { const incoming = event.payload.notification; - if (projectId && incoming.project_id !== projectId) { + if (scopedProjectId && incoming.project_id !== scopedProjectId) { return; } @@ -127,7 +161,7 @@ export default function NotificationCenter() { unlisten(); } }; - }, [projectId]); + }, [scopedProjectId]); useEffect(() => { if (!open) { @@ -199,12 +233,12 @@ export default function NotificationCenter() { } async function handleMarkAllRead() { - if (!projectId) { + if (!scopedProjectId) { return; } try { - await markAllNotificationsRead(projectId); + await markAllNotificationsRead(scopedProjectId); setNotifications((prev) => prev.map((n) => ({ ...n, read: true }))); } catch { // ignore @@ -234,7 +268,7 @@ export default function NotificationCenter() { type="button" onClick={handleMarkAllRead} className={buttonClass({ variant: "ghost", size: "xs" })} - disabled={!projectId || unreadCount === 0} + disabled={!scopedProjectId || unreadCount === 0} > Mark all read