11import { InfinityLightIcon } from "@hashintel/design-system" ;
22import { Box , Container , Typography } from "@mui/material" ;
33import { useRouter } from "next/router" ;
4- import { useCallback , useEffect , useMemo , useState } from "react" ;
4+ import { useEffect , useMemo , useState } from "react" ;
55
66import type { NextPageWithLayout } from "../../shared/layout" ;
77import { getLayoutWithSidebar } from "../../shared/layout" ;
@@ -18,13 +18,17 @@ import {
1818} from "../ingest.page/routing" ;
1919import type { IngestRunView } from "../ingest.page/types" ;
2020
21+ const normalizeQueryParam = (
22+ value : string | string [ ] | undefined ,
23+ ) : string | undefined => ( typeof value === "string" ? value : value ?. [ 0 ] ) ;
24+
2125const IngestResultsPage : NextPageWithLayout = ( ) => {
2226 const router = useRouter ( ) ;
2327 const source = useMemo (
2428 ( ) =>
2529 getIngestResultsSource ( {
26- runId : router . query . runId as string | undefined ,
27- fixture : router . query . fixture as string | undefined ,
30+ runId : normalizeQueryParam ( router . query . runId ) ,
31+ fixture : normalizeQueryParam ( router . query . fixture ) ,
2832 } ) ,
2933 [ router . query . runId , router . query . fixture ] ,
3034 ) ;
@@ -35,7 +39,9 @@ const IngestResultsPage: NextPageWithLayout = () => {
3539 const [ currentPage , setCurrentPage ] = useState ( 1 ) ;
3640 const [ loading , setLoading ] = useState ( false ) ;
3741
38- const fetchResults = useCallback ( async ( ) => {
42+ useEffect ( ( ) => {
43+ const abortController = new AbortController ( ) ;
44+
3945 setView ( null ) ;
4046 setError ( null ) ;
4147 setSelection ( null ) ;
@@ -44,36 +50,55 @@ const IngestResultsPage: NextPageWithLayout = () => {
4450
4551 const endpoint =
4652 source . kind === "fixture"
47- ? `/api/ingest-fixtures/${ source . fixtureId } /view`
48- : `/api/ingest/${ source . runId } /view` ;
53+ ? `/api/ingest-fixtures/${ encodeURIComponent ( source . fixtureId ) } /view`
54+ : `/api/ingest/${ encodeURIComponent ( source . runId ) } /view` ;
55+
56+ void ( async ( ) => {
57+ try {
58+ const response = await fetch ( endpoint , {
59+ signal : abortController . signal ,
60+ } ) ;
61+ if ( ! response . ok ) {
62+ throw new Error ( `Failed to load results: ${ response . status } ` ) ;
63+ }
64+ const data = ( await response . json ( ) ) as IngestRunView ;
65+ if ( ! abortController . signal . aborted ) {
66+ setView ( data ) ;
67+ }
68+ } catch ( err ) {
69+ if (
70+ abortController . signal . aborted ||
71+ ( err instanceof Error && err . name === "AbortError" )
72+ ) {
73+ return ;
74+ }
4975
50- try {
51- const response = await fetch ( endpoint ) ;
52- if ( ! response . ok ) {
53- throw new Error ( `Failed to load results: ${ response . status } ` ) ;
76+ setError ( err instanceof Error ? err . message : String ( err ) ) ;
77+ } finally {
78+ if ( ! abortController . signal . aborted ) {
79+ setLoading ( false ) ;
80+ }
5481 }
55- const data = ( await response . json ( ) ) as IngestRunView ;
56- setView ( data ) ;
57- } catch ( err ) {
58- setError ( err instanceof Error ? err . message : String ( err ) ) ;
59- } finally {
60- setLoading ( false ) ;
61- }
82+ } ) ( ) ;
83+
84+ return ( ) => {
85+ abortController . abort ( ) ;
86+ } ;
6287 } , [ source ] ) ;
6388
64- useEffect ( ( ) => {
65- void fetchResults ( ) ;
66- } , [ fetchResults ] ) ;
89+ const evidence = useMemo (
90+ ( ) =>
91+ view && selection
92+ ? resolveEvidence ( selection , view . corpus . blocks )
93+ : { blockIds : [ ] , targetPage : null } ,
94+ [ selection , view ] ,
95+ ) ;
6796
6897 useEffect ( ( ) => {
69- if ( ! view || ! selection ) {
70- return ;
71- }
72- const { targetPage } = resolveEvidence ( selection , view . corpus . blocks ) ;
73- if ( targetPage !== null ) {
74- setCurrentPage ( targetPage ) ;
98+ if ( evidence . targetPage !== null ) {
99+ setCurrentPage ( evidence . targetPage ) ;
75100 }
76- } , [ selection , view ] ) ;
101+ } , [ evidence ] ) ;
77102
78103 const handleFixtureChange = ( fixtureId : string ) => {
79104 void router . push ( getIngestResultsPath ( { kind : "fixture" , fixtureId } ) ) ;
@@ -163,11 +188,7 @@ const IngestResultsPage: NextPageWithLayout = () => {
163188 < PageViewer
164189 pageImages = { view . pageImages }
165190 blocks = { view . corpus . blocks }
166- highlightedBlockIds = {
167- selection
168- ? resolveEvidence ( selection , view . corpus . blocks ) . blockIds
169- : [ ]
170- }
191+ highlightedBlockIds = { evidence . blockIds }
171192 currentPage = { currentPage }
172193 onPageChange = { setCurrentPage }
173194 />
0 commit comments