fix: afficher les notifications sur la vue ticket

This commit is contained in:
thibaud-lclr 2026-04-22 09:16:29 +02:00
parent c35778fe18
commit 618c30ef84

View file

@ -7,6 +7,7 @@ import {
import { useCallback, useEffect, useMemo, useRef, useState } from "react"; import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { useNavigate, useParams } from "react-router-dom"; import { useNavigate, useParams } from "react-router-dom";
import { import {
getTicketResult,
listNotifications, listNotifications,
markAllNotificationsRead, markAllNotificationsRead,
markNotificationRead, markNotificationRead,
@ -54,35 +55,68 @@ async function showSystemNotification(notification: OrchaiNotification) {
export default function NotificationCenter() { export default function NotificationCenter() {
const navigate = useNavigate(); const navigate = useNavigate();
const { projectId } = useParams(); const { projectId, ticketId } = useParams();
const containerRef = useRef<HTMLDivElement | null>(null); const containerRef = useRef<HTMLDivElement | null>(null);
const [open, setOpen] = useState(false); const [open, setOpen] = useState(false);
const [notifications, setNotifications] = useState<OrchaiNotification[]>([]); const [notifications, setNotifications] = useState<OrchaiNotification[]>([]);
const [ticketProjectId, setTicketProjectId] = useState<string | null>(null);
const [filter, setFilter] = useState<"all" | "unread" | "errors" | "fixes">( const [filter, setFilter] = useState<"all" | "unread" | "errors" | "fixes">(
"all" "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 () => { const loadNotifications = useCallback(async () => {
if (!projectId) { if (!scopedProjectId) {
setNotifications([]); setNotifications([]);
return; return;
} }
try { try {
const items = await listNotifications(projectId, false); const items = await listNotifications(scopedProjectId, false);
setNotifications(items); setNotifications(items);
} catch { } catch {
// Ignore load errors in layout chrome // Ignore load errors in layout chrome
} }
}, [projectId]); }, [scopedProjectId]);
useEffect(() => { useEffect(() => {
void loadNotifications(); void loadNotifications();
}, [loadNotifications]); }, [loadNotifications]);
useLiveRefresh({ useLiveRefresh({
enabled: Boolean(projectId), enabled: Boolean(scopedProjectId),
projectId, projectId: scopedProjectId,
refresh: loadNotifications, refresh: loadNotifications,
fallbackIntervalMs: 15_000, fallbackIntervalMs: 15_000,
}); });
@ -96,7 +130,7 @@ export default function NotificationCenter() {
const cleanup = await listen<NewNotificationEvent>("new-notification", (event) => { const cleanup = await listen<NewNotificationEvent>("new-notification", (event) => {
const incoming = event.payload.notification; const incoming = event.payload.notification;
if (projectId && incoming.project_id !== projectId) { if (scopedProjectId && incoming.project_id !== scopedProjectId) {
return; return;
} }
@ -127,7 +161,7 @@ export default function NotificationCenter() {
unlisten(); unlisten();
} }
}; };
}, [projectId]); }, [scopedProjectId]);
useEffect(() => { useEffect(() => {
if (!open) { if (!open) {
@ -199,12 +233,12 @@ export default function NotificationCenter() {
} }
async function handleMarkAllRead() { async function handleMarkAllRead() {
if (!projectId) { if (!scopedProjectId) {
return; return;
} }
try { try {
await markAllNotificationsRead(projectId); await markAllNotificationsRead(scopedProjectId);
setNotifications((prev) => prev.map((n) => ({ ...n, read: true }))); setNotifications((prev) => prev.map((n) => ({ ...n, read: true })));
} catch { } catch {
// ignore // ignore
@ -234,7 +268,7 @@ export default function NotificationCenter() {
type="button" type="button"
onClick={handleMarkAllRead} onClick={handleMarkAllRead}
className={buttonClass({ variant: "ghost", size: "xs" })} className={buttonClass({ variant: "ghost", size: "xs" })}
disabled={!projectId || unreadCount === 0} disabled={!scopedProjectId || unreadCount === 0}
> >
Mark all read Mark all read
</button> </button>