@@ -4,6 +4,7 @@ import Header from "../components/Header/Header";
44import HeaderTools from "../components/Header/HeaderTools" ;
55import PanelLeft from "../components/Panels/PanelLeft" ;
66import webSocketService from "../api/WebSocketService" ;
7+ import { useSelector } from 'react-redux' ;
78import {
89 Button ,
910 Text ,
@@ -478,6 +479,9 @@ const ModernizationPage = () => {
478479 const { batchId } = useParams < { batchId : string } > ( ) ;
479480 const navigate = useNavigate ( )
480481
482+ // Redux state to listen for start processing completion
483+ const batchState = useSelector ( ( state : any ) => state . batch ) ;
484+
481485 const [ batchSummary , setBatchSummary ] = useState < BatchSummary | null > ( null ) ;
482486 const styles = useStyles ( )
483487 const [ text , setText ] = useState ( "" ) ;
@@ -498,6 +502,8 @@ const ModernizationPage = () => {
498502 const [ isZipButtonDisabled , setIsZipButtonDisabled ] = useState ( true ) ;
499503 const [ fileLoading , setFileLoading ] = useState ( false ) ;
500504 const [ selectedFileTranslatedContent , setSelectedFileTranslatedContent ] = useState < string > ( "" ) ;
505+ const [ lastActivityTime , setLastActivityTime ] = useState < number > ( Date . now ( ) ) ;
506+ const [ pageLoadTime ] = useState < number > ( Date . now ( ) ) ;
501507
502508 // Fetch file content when a file is selected
503509 useEffect ( ( ) => {
@@ -593,6 +599,19 @@ const ModernizationPage = () => {
593599 fetchBatchData ( batchId ) ;
594600 } , [ batchId ] ) ;
595601
602+ // Listen for startProcessing completion and navigate to batch view
603+ useEffect ( ( ) => {
604+ if ( batchState && ! batchState . loading && batchState . status === "Processing completed" ) {
605+ console . log ( "Start processing API completed successfully - processing is done!" ) ;
606+
607+ // Check if we have the response with batch_id that matches current batchId
608+ if ( batchState . batchId === batchId ) {
609+ console . log ( "Processing completed for current batch, navigating to batch view page" ) ;
610+ navigate ( `/batch-view/${ batchId } ` ) ;
611+ }
612+ }
613+ } , [ batchState . loading , batchState . status , batchState . batchId , batchId , navigate ] ) ;
614+
596615 const handleDownloadZip = async ( ) => {
597616 if ( batchId ) {
598617 try {
@@ -789,11 +808,39 @@ const ModernizationPage = () => {
789808 try {
790809 const latestBatch = await fetchBatchSummary ( batchId ! ) ;
791810 setBatchSummary ( latestBatch ) ;
811+
812+ // Check if all files are in terminal states OR if the batch itself is marked as completed
792813 const allFilesDone = latestBatch . files . every ( file =>
793814 [ "completed" , "failed" , "error" ] . includes ( file . status ?. toLowerCase ( ) || "" )
794815 ) ;
816+
817+ // Also check if batch status indicates completion (for cases where some files remain queued)
818+ const batchCompleted = latestBatch . status ?. toLowerCase ( ) === "completed" ||
819+ latestBatch . status ?. toLowerCase ( ) === "failed" ;
820+
821+ // Special handling for stuck processing files - if no completed files and long time passed
822+ const hasProcessingFiles = latestBatch . files . some ( file =>
823+ file . status ?. toLowerCase ( ) === "in_process"
824+ ) ;
825+ const hasCompletedFiles = latestBatch . files . some ( file =>
826+ file . status ?. toLowerCase ( ) === "completed"
827+ ) ;
828+ const timeSinceLastActivity = Date . now ( ) - lastActivityTime ;
829+ const likelyStuckProcessing = hasProcessingFiles &&
830+ ! hasCompletedFiles &&
831+ timeSinceLastActivity > 60000 ; // 60 seconds of no activity
832+
833+ // Consider processing done if either all files are terminal OR batch is marked complete OR files appear stuck
834+ const processingComplete = allFilesDone || batchCompleted || likelyStuckProcessing ;
795835
796- if ( allFilesDone ) {
836+ if ( processingComplete ) {
837+ console . log ( "Processing complete detected:" , {
838+ allFilesDone,
839+ batchCompleted,
840+ likelyStuckProcessing,
841+ batchStatus : latestBatch . status ,
842+ timeSinceActivity : timeSinceLastActivity
843+ } ) ;
797844 setAllFilesCompleted ( true ) ;
798845 const hasUsableFile = latestBatch . files . some ( file =>
799846 file . status ?. toLowerCase ( ) === "completed" &&
@@ -820,7 +867,7 @@ const ModernizationPage = () => {
820867 } ) ;
821868
822869 // Navigate to batch view page when processing is complete
823- console . log ( "All files processed , navigating to batch view page" ) ;
870+ console . log ( "Processing complete (either all files done or batch completed) , navigating to batch view page" ) ;
824871 navigate ( `/batch-view/${ batchId } ` ) ;
825872 }
826873 } catch ( err ) {
@@ -838,6 +885,7 @@ const ModernizationPage = () => {
838885 }
839886
840887 setFileId ( data . file_id ) ;
888+ setLastActivityTime ( Date . now ( ) ) ; // Update activity time on WebSocket message
841889
842890 const agent = formatAgent ( data . agent_type ) ;
843891 const message = formatDescription ( data . agent_message ) ;
@@ -900,11 +948,23 @@ useEffect(() => {
900948 file . id === "summary" || // skip summary
901949 [ "completed" , "failed" , "error" ] . includes ( file . status ?. toLowerCase ( ) || "" )
902950 ) ;
951+
952+ // Also check if we have at least one completed file and no files currently processing
953+ const hasCompletedFiles = files . some ( file =>
954+ file . id !== "summary" && file . status === "completed"
955+ ) ;
956+ const hasProcessingFiles = files . some ( file =>
957+ file . id !== "summary" && file . status === "in_process"
958+ ) ;
959+
960+ // Consider done if all terminal OR (has completed files and no processing files)
961+ const effectivelyDone = areAllFilesTerminal || ( hasCompletedFiles && ! hasProcessingFiles ) ;
903962
904- if ( files . length > 1 && areAllFilesTerminal && ! allFilesCompleted ) {
963+ if ( files . length > 1 && effectivelyDone && ! allFilesCompleted ) {
964+ console . log ( "Files processing appears complete, checking batch status" ) ;
905965 updateSummaryStatus ( ) ;
906966 }
907- } , [ files , allFilesCompleted ] ) ;
967+ } , [ files , allFilesCompleted , updateSummaryStatus ] ) ;
908968
909969
910970useEffect ( ( ) => {
@@ -962,6 +1022,45 @@ useEffect(() => {
9621022 return ( ) => clearTimeout ( loadingTimeout ) ;
9631023 } , [ progressPercentage , showLoading ] ) ;
9641024
1025+ // Add timeout mechanism to navigate if no activity for 30 seconds
1026+ useEffect ( ( ) => {
1027+ const checkInactivity = setInterval ( ( ) => {
1028+ const timeSinceLastActivity = Date . now ( ) - lastActivityTime ;
1029+ const hasCompletedFiles = files . some ( file =>
1030+ file . id !== "summary" && file . status === "completed"
1031+ ) ;
1032+ const hasProcessingFiles = files . some ( file =>
1033+ file . id !== "summary" && file . status === "in_process"
1034+ ) ;
1035+ const nonSummaryFiles = files . filter ( f => f . id !== "summary" ) ;
1036+
1037+ // If we have completed files and no activity for 30 seconds, check if we should navigate
1038+ if ( hasCompletedFiles && timeSinceLastActivity > 30000 && ! allFilesCompleted ) {
1039+ console . log ( "No activity for 30 seconds with completed files, checking final status" ) ;
1040+ updateSummaryStatus ( ) ;
1041+ }
1042+
1043+ // Special case: If only harmful files that are stuck in processing for 60+ seconds
1044+ if ( nonSummaryFiles . length > 0 &&
1045+ hasProcessingFiles &&
1046+ ! hasCompletedFiles &&
1047+ timeSinceLastActivity > 60000 &&
1048+ ! allFilesCompleted ) {
1049+ console . log ( "Files stuck in processing for 60+ seconds, likely failed - checking batch status" ) ;
1050+ updateSummaryStatus ( ) ;
1051+ }
1052+
1053+ // Ultimate fallback: If on page for 2+ minutes with no completion, force navigation
1054+ const timeSincePageLoad = Date . now ( ) - pageLoadTime ;
1055+ if ( timeSincePageLoad > 120000 && ! allFilesCompleted && nonSummaryFiles . length > 0 ) {
1056+ console . log ( "Page loaded for 2+ minutes without completion, forcing navigation to batch view" ) ;
1057+ navigate ( `/batch-view/${ batchId } ` ) ;
1058+ }
1059+ } , 5000 ) ; // Check every 5 seconds
1060+
1061+ return ( ) => clearInterval ( checkInactivity ) ;
1062+ } , [ lastActivityTime , files , allFilesCompleted , updateSummaryStatus , pageLoadTime , navigate , batchId ] ) ;
1063+
9651064
9661065 useEffect ( ( ) => {
9671066 console . log ( 'Current files state:' , files ) ;
0 commit comments