feat: implement hybrid image extraction and memory management
Backend: - Add hybrid image extraction for Direct track (inline image blocks) - Add render_inline_image_regions() fallback when OCR doesn't find images - Add check_document_for_missing_images() for detecting missing images - Add memory management system (MemoryGuard, ModelManager, ServicePool) - Update pdf_generator_service to handle HYBRID processing track - Add ElementType.LOGO for logo extraction Frontend: - Fix PDF viewer re-rendering issues with memoization - Add TaskNotFound component and useTaskValidation hook - Disable StrictMode due to react-pdf incompatibility - Fix task detail and results page loading states 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
64
frontend/src/hooks/useTaskValidation.ts
Normal file
64
frontend/src/hooks/useTaskValidation.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import { useUploadStore } from '@/store/uploadStore'
|
||||
import { apiClientV2 } from '@/services/apiV2'
|
||||
import type { TaskDetail } from '@/types/apiV2'
|
||||
|
||||
interface UseTaskValidationResult {
|
||||
taskId: string | null
|
||||
taskDetail: TaskDetail | undefined
|
||||
isLoading: boolean
|
||||
isNotFound: boolean
|
||||
clearAndReset: () => void
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook for validating task existence and handling deleted tasks gracefully.
|
||||
* Shows loading state first, then either returns task data or marks as not found.
|
||||
*/
|
||||
export function useTaskValidation(options?: {
|
||||
refetchInterval?: number | false | ((query: any) => number | false)
|
||||
}): UseTaskValidationResult {
|
||||
const { batchId, clearUpload } = useUploadStore()
|
||||
const taskId = batchId ? String(batchId) : null
|
||||
|
||||
const [isNotFound, setIsNotFound] = useState(false)
|
||||
|
||||
const { data: taskDetail, isLoading, error, isFetching } = useQuery({
|
||||
queryKey: ['taskDetail', taskId],
|
||||
queryFn: () => apiClientV2.getTask(taskId!),
|
||||
enabled: !!taskId && !isNotFound,
|
||||
retry: (failureCount, error: any) => {
|
||||
// Don't retry on 404
|
||||
if (error?.response?.status === 404) {
|
||||
return false
|
||||
}
|
||||
return failureCount < 2
|
||||
},
|
||||
refetchInterval: options?.refetchInterval ?? false,
|
||||
// Disable stale time to ensure we check fresh data
|
||||
staleTime: 0,
|
||||
})
|
||||
|
||||
// Handle 404 error - mark as not found immediately
|
||||
useEffect(() => {
|
||||
if (error && (error as any)?.response?.status === 404) {
|
||||
setIsNotFound(true)
|
||||
}
|
||||
}, [error])
|
||||
|
||||
// Clear state and store
|
||||
const clearAndReset = () => {
|
||||
clearUpload()
|
||||
setIsNotFound(false)
|
||||
}
|
||||
|
||||
return {
|
||||
taskId,
|
||||
taskDetail,
|
||||
// Show loading if we have a taskId and are still fetching (but not if already marked as not found)
|
||||
isLoading: !!taskId && !isNotFound && (isLoading || isFetching) && !taskDetail,
|
||||
isNotFound,
|
||||
clearAndReset,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user