@@ -11,18 +11,22 @@ import {
1111 opportunityPreviewRefetchIntervalMs ,
1212 OpportunityPreviewStatus ,
1313} from '../types' ;
14+ import { OpportunityState } from '../protobuf/opportunity' ;
1415import { useAuthContext } from '../../../contexts/AuthContext' ;
1516import { oneMinute } from '../../../lib/dateFormat' ;
1617import { useUpdateQuery } from '../../../hooks/useUpdateQuery' ;
1718
1819export type OpportunityPreviewContextType = OpportunityPreviewResponse & {
1920 opportunity ?: Opportunity ;
21+ isParsing ?: boolean ;
2022} ;
2123
2224type UseOpportunityPreviewProps = PropsWithChildren & {
2325 mockData ?: OpportunityPreviewContextType ;
2426} ;
2527
28+ const parseOpportunityIntervalMs = 3000 ;
29+
2630const [ OpportunityPreviewProvider , useOpportunityPreviewContext ] =
2731 createContextProvider ( ( { mockData } : UseOpportunityPreviewProps = { } ) => {
2832 const { user } = useAuthContext ( ) ;
@@ -31,6 +35,47 @@ const [OpportunityPreviewProvider, useOpportunityPreviewContext] =
3135 | string
3236 | undefined ;
3337
38+ const isValidOpportunityId =
39+ ! ! opportunityIdParam && opportunityIdParam !== 'new' ;
40+
41+ const [ , updateOpportunity ] = useUpdateQuery (
42+ opportunityByIdOptions ( { id : opportunityIdParam || '' } ) ,
43+ ) ;
44+
45+ // Fetch opportunity from URL param with polling for PARSING state
46+ const { data : opportunity } = useQuery ( {
47+ ...opportunityByIdOptions ( { id : opportunityIdParam || '' } ) ,
48+ enabled : isValidOpportunityId && ! mockData ,
49+ refetchInterval : ( query ) => {
50+ const retries = Math . max (
51+ query . state . dataUpdateCount ,
52+ query . state . fetchFailureCount ,
53+ ) ;
54+
55+ const state = query . state . data ?. state ;
56+
57+ if ( state !== OpportunityState . PARSING ) {
58+ return false ;
59+ }
60+
61+ const maxRetries = ( oneMinute * 1000 ) / parseOpportunityIntervalMs ;
62+
63+ if ( retries > maxRetries ) {
64+ updateOpportunity ( {
65+ ...query . state . data ,
66+ state : OpportunityState . ERROR ,
67+ } ) ;
68+
69+ return false ;
70+ }
71+
72+ return parseOpportunityIntervalMs ;
73+ } ,
74+ } ) ;
75+
76+ const isParsing = opportunity ?. state === OpportunityState . PARSING ;
77+ const isParseError = opportunity ?. state === OpportunityState . ERROR ;
78+
3479 const [ , setOpportunityPreview ] = useUpdateQuery (
3580 opportunityPreviewQueryOptions ( {
3681 opportunityId : opportunityIdParam ,
@@ -39,11 +84,17 @@ const [OpportunityPreviewProvider, useOpportunityPreviewContext] =
3984 } ) ,
4085 ) ;
4186
87+ // Only fetch preview once opportunity is no longer in PARSING state
4288 const { data } = useQuery ( {
4389 ...opportunityPreviewQueryOptions ( {
4490 opportunityId : opportunityIdParam ,
4591 user : user || undefined ,
46- enabled : ! mockData && opportunityIdParam !== 'new' ,
92+ enabled :
93+ ! mockData &&
94+ isValidOpportunityId &&
95+ ! ! opportunity &&
96+ ! isParsing &&
97+ ! isParseError ,
4798 } ) ,
4899 refetchInterval : ( query ) => {
49100 if (
@@ -92,18 +143,11 @@ const [OpportunityPreviewProvider, useOpportunityPreviewContext] =
92143 } ,
93144 } ) ;
94145
95- const opportunityId = data ?. result ?. opportunityId ;
96-
97- const { data : opportunity } = useQuery ( {
98- ...opportunityByIdOptions ( { id : opportunityId || '' } ) ,
99- enabled : ! ! opportunityId && ! mockData ,
100- } ) ;
101-
102146 if ( mockData ) {
103147 return mockData ;
104148 }
105149
106- return { ...data , opportunity } ;
150+ return { ...data , opportunity, isParsing } ;
107151 } ) ;
108152
109153export { OpportunityPreviewProvider , useOpportunityPreviewContext } ;
0 commit comments