refactor: simplify ticket lifecycle flow, remove processing and completed state

This commit is contained in:
2026-06-30 13:01:08 +05:30
parent adff2e2c41
commit ec77696157
20 changed files with 36 additions and 326 deletions

View File

@@ -1,30 +1,15 @@
'use client';
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { useCallback, useEffect, useMemo, useRef } from 'react';
import { useQueryClient } from '@tanstack/react-query';
import { useRouter } from 'next/navigation';
import { API_ROUTES } from '@/constants/apiRoutes';
import { useSseWithToken } from '@/hooks/sse/useSseWithToken';
import { ticketService } from '@/services/api';
import type {
TicketDetailStatusEvent,
TicketProgressEvent,
TicketStreamErrorEvent,
} from '@/types';
import type { TicketDetailStatusEvent } from '@/types';
import { ticketKeys } from '../queries/ticketKeys';
export interface TicketProcessingProgress {
progress: number;
message: string | null;
}
export interface TicketDetailLiveState {
progress: TicketProcessingProgress | null;
errorMessage: string | null;
}
const TICKET_DETAIL_RECONNECT_EVENTS = ['error'] as const;
function isHeartbeatEvent(event: { type?: string } | null | undefined) {
@@ -35,14 +20,9 @@ export function useTicketDetailEvents(
ticketId: string | undefined,
defectClass: string | undefined,
enabled = true,
): TicketDetailLiveState {
const router = useRouter();
): void {
const queryClient = useQueryClient();
const defectClassRef = useRef(defectClass);
const [progress, setProgress] = useState<TicketProcessingProgress | null>(
null,
);
const [errorMessage, setErrorMessage] = useState<string | null>(null);
useEffect(() => {
defectClassRef.current = defectClass;
@@ -60,18 +40,6 @@ export function useTicketDetailEvents(
queryClient.invalidateQueries({ queryKey: ticketKeys.lists() });
}, [queryClient, ticketId]);
const selectDefectClass = useCallback(
(nextDefectClass: string | null | undefined) => {
if (!ticketId || !nextDefectClass || defectClassRef.current) return;
router.replace(
`/ticket/${ticketId}?defect_class=${encodeURIComponent(nextDefectClass)}`,
{ scroll: false },
);
},
[router, ticketId],
);
const getToken = useCallback(
() => ticketService.createTicketEventsToken(ticketId as string),
[ticketId],
@@ -89,30 +57,10 @@ export function useTicketDetailEvents(
if (isHeartbeatEvent(event)) return;
refetchTicket();
},
progress: (event: TicketProgressEvent) => {
setErrorMessage(null);
setProgress({
progress: event.progress,
message: event.message,
});
},
complete: (event: TicketProgressEvent) => {
setErrorMessage(null);
setProgress({
progress: 100,
message: event.message,
});
selectDefectClass(event.defect_class);
refetchTicket();
},
error: (event: TicketStreamErrorEvent) => {
setErrorMessage(
event.message ?? 'Live ticket updates disconnected. Reconnecting...',
);
},
error: () => undefined,
heartbeat: () => undefined,
}),
[refetchTicket, selectDefectClass],
[refetchTicket],
);
const shouldStop = useCallback(
@@ -122,15 +70,6 @@ export function useTicketDetailEvents(
[],
);
const onConnectionError = useCallback(() => {
setErrorMessage('Live ticket updates disconnected. Reconnecting...');
}, []);
useEffect(() => {
setProgress(null);
setErrorMessage(null);
}, [ticketId]);
useSseWithToken({
enabled: Boolean(enabled && ticketId),
getToken,
@@ -138,8 +77,5 @@ export function useTicketDetailEvents(
events,
reconnectOnEvents: TICKET_DETAIL_RECONNECT_EVENTS,
shouldStop,
onConnectionError,
});
return { progress, errorMessage };
}