From 3d04995f97bcf99e6f4f2c9175f0dd574488ba84 Mon Sep 17 00:00:00 2001 From: "santasri.pachhal" Date: Fri, 7 Aug 2026 16:38:38 +0530 Subject: [PATCH] perf(ticket): paginate and cache detection previews --- .../components/TicketAssignmentsCard.tsx | 1 + .../components/TicketDetectionPreview.tsx | 28 +++++++++++++------ .../components/TicketDetectionPreviewCard.tsx | 1 + .../components/TicketUnassignedIssuesCard.tsx | 3 +- .../ticket/hooks/useTicketQueries.ts | 10 ++++++- 5 files changed, 32 insertions(+), 11 deletions(-) diff --git a/src/app/(modules)/ticket/[ticketId]/components/TicketAssignmentsCard.tsx b/src/app/(modules)/ticket/[ticketId]/components/TicketAssignmentsCard.tsx index 19f6cec..254850d 100644 --- a/src/app/(modules)/ticket/[ticketId]/components/TicketAssignmentsCard.tsx +++ b/src/app/(modules)/ticket/[ticketId]/components/TicketAssignmentsCard.tsx @@ -262,6 +262,7 @@ export function TicketAssignmentsCard({ {videoId ? (
void; } +const DETECTION_PAGE_SIZE = 10; + function DetectionMetadataBar({ items, }: { @@ -102,6 +104,8 @@ export function TicketDetectionPreview({ const [currentIndex, setCurrentIndex] = useState(0); const [isDiscardDialogOpen, setIsDiscardDialogOpen] = useState(false); const isUnassignedPreview = assignmentStatus === 'unassigned'; + const pageStart = + Math.floor(currentIndex / DETECTION_PAGE_SIZE) * DETECTION_PAGE_SIZE; useEffect(() => { setCurrentIndex(0); @@ -109,23 +113,26 @@ export function TicketDetectionPreview({ const queryParams = useMemo( () => ({ - skip: currentIndex, - limit: 1, + skip: pageStart, + limit: DETECTION_PAGE_SIZE, assignment_id: isUnassignedPreview ? undefined : assignmentId, assignment_status: isUnassignedPreview ? ('unassigned' as const) : undefined, sort: 'timestamp_asc', }), - [assignmentId, currentIndex, isUnassignedPreview], + [assignmentId, isUnassignedPreview, pageStart], ); const detectionsQuery = useTicketDetectionsQuery( videoId ?? undefined, queryParams, + { keepPreviousPage: true }, ); const detectionResult = detectionsQuery.data; - const activeDetection = detectionResult?.items[0]; + const activeDetection = detectionsQuery.isPlaceholderData + ? undefined + : detectionResult?.items[currentIndex - pageStart]; const confirmedDetectionCount = detectionResult?.total; const detectionCount = confirmedDetectionCount ?? 0; const activeVisual = getDefectVisual( @@ -156,12 +163,15 @@ export function TicketDetectionPreview({ }, [confirmedDetectionCount, currentIndex]); useEffect(() => { - onDetectionCountChange?.(confirmedDetectionCount); - }, [confirmedDetectionCount, onDetectionCountChange]); + onDetectionCountChange?.(detectionCount); + }, [detectionCount, onDetectionCountChange]); const isNavigationDisabled = - detectionCount === 0 || detectionsQuery.isLoading; - const isInitialLoading = detectionsQuery.isLoading; + detectionCount === 0 || + detectionsQuery.isLoading || + detectionsQuery.isPlaceholderData; + const isInitialLoading = + detectionsQuery.isLoading || detectionsQuery.isPlaceholderData; const isError = detectionsQuery.isError; const retry = () => void detectionsQuery.refetch(); @@ -221,7 +231,7 @@ export function TicketDetectionPreview({
- {isInitialLoading && !activeDetection ? ( + {isInitialLoading ? ( ) : isError ? (
diff --git a/src/app/(modules)/ticket/[ticketId]/components/TicketDetectionPreviewCard.tsx b/src/app/(modules)/ticket/[ticketId]/components/TicketDetectionPreviewCard.tsx index d1c04c1..9edeb82 100644 --- a/src/app/(modules)/ticket/[ticketId]/components/TicketDetectionPreviewCard.tsx +++ b/src/app/(modules)/ticket/[ticketId]/components/TicketDetectionPreviewCard.tsx @@ -22,6 +22,7 @@ export function TicketDetectionPreviewCard({
- {detectionCount ?? 0} Unassigned + {detectionCount ?? 0} Unassigned
({ skip: params.skip ?? 0, @@ -143,6 +150,7 @@ export function useTicketDetectionsQuery( queryFn: () => videoService.getVideoDetections(videoId as string, queryParams), enabled: Boolean(enabled && videoId), + placeholderData: keepPreviousPage ? keepPreviousData : undefined, staleTime: Infinity, }); }