Files
road-monitoring-ui/src/app/(modules)/ticket/hooks/useTicketDetailEvents.ts

72 lines
1.9 KiB
TypeScript

'use client';
import { useCallback, useMemo } from 'react';
import { useQueryClient } from '@tanstack/react-query';
import { API_ROUTES } from '@/constants/apiRoutes';
import { useSseWithToken } from '@/hooks/sse/useSseWithToken';
import { ticketService } from '@/services/api';
import type { TicketDetailStatusEvent } from '@/types';
import { ticketKeys } from '../queries/ticketKeys';
const TICKET_DETAIL_RECONNECT_EVENTS = ['error'] as const;
function isHeartbeatEvent(event: { type?: string } | null | undefined) {
return event?.type === 'heartbeat';
}
export function useTicketDetailEvents(
ticketId: string | undefined,
enabled = true,
): void {
const queryClient = useQueryClient();
const refetchTicket = useCallback(() => {
if (!ticketId) return;
queryClient.refetchQueries({ queryKey: ticketKeys.overview(ticketId) });
queryClient.refetchQueries({
queryKey: ticketKeys.assignments(ticketId),
});
queryClient.refetchQueries({
queryKey: ticketKeys.timeline(ticketId),
});
queryClient.invalidateQueries({
queryKey: ticketKeys.defectClasses(ticketId),
});
queryClient.invalidateQueries({ queryKey: ticketKeys.lists() });
}, [queryClient, ticketId]);
const getToken = useCallback(
() => ticketService.createTicketEventsToken(ticketId as string),
[ticketId],
);
const getPath = useCallback(
(token: string) =>
API_ROUTES.TICKETS.DETAIL_EVENTS(ticketId as string, token),
[ticketId],
);
const events = useMemo(
() => ({
ticket_status: (event: TicketDetailStatusEvent) => {
if (isHeartbeatEvent(event)) return;
refetchTicket();
},
error: () => undefined,
heartbeat: () => undefined,
}),
[refetchTicket],
);
useSseWithToken({
enabled: Boolean(enabled && ticketId),
getToken,
getPath,
events,
reconnectOnEvents: TICKET_DETAIL_RECONNECT_EVENTS,
});
}