@@ -100,6 +100,9 @@ export const TopicRefiner: FC<Omit<TopicRefinerProps, 'isLlmProcessing'>> = ({
100100 const [ showConfirmationModal , setShowConfirmationModal ] = useState ( false ) ;
101101 const [ isLoadingUniqueCount , setIsLoadingUniqueCount ] = useState ( false ) ;
102102 const [ uniqueCountError , setUniqueCountError ] = useState < string | null > ( null ) ;
103+ const [ searchTermRemoved , setSearchTermRemoved ] = useState ( false ) ;
104+ const [ submitProgress , setSubmitProgress ] = useState ( 0 ) ;
105+ const [ submitStatus , setSubmitStatus ] = useState < string > ( '' ) ;
103106
104107 // Function to fetch unique repository count for all finalized topics
105108 const fetchUniqueReposCount = async ( topics : string [ ] ) => {
@@ -239,6 +242,10 @@ export const TopicRefiner: FC<Omit<TopicRefinerProps, 'isLlmProcessing'>> = ({
239242 delete newCounts [ topic ] ;
240243 return newCounts ;
241244 } ) ;
245+ // If removing the search term, mark it as removed
246+ if ( topic === searchTerm ) {
247+ setSearchTermRemoved ( true ) ;
248+ }
242249 } ;
243250
244251 useEffect ( ( ) => {
@@ -483,7 +490,7 @@ export const TopicRefiner: FC<Omit<TopicRefinerProps, 'isLlmProcessing'>> = ({
483490 if ( searchTerm && ! selectedTopics . includes ( searchTerm ) ) {
484491 setSelectedTopics ( [ ...selectedTopics , searchTerm ] ) ;
485492 }
486- if ( searchTerm && ! finalizedTopics . includes ( searchTerm ) ) {
493+ if ( searchTerm && ! finalizedTopics . includes ( searchTerm ) && ! searchTermRemoved ) {
487494 setFinalizedTopics ( [ ...finalizedTopics , searchTerm ] ) ;
488495 // Fetch topic count for the search term if not already available
489496 if ( ! topicCounts [ searchTerm ] ) {
@@ -521,6 +528,20 @@ export const TopicRefiner: FC<Omit<TopicRefinerProps, 'isLlmProcessing'>> = ({
521528 const submitTopics = async ( ) => {
522529 try {
523530 setIsSubmitting ( true ) ; // Start loading state
531+ setSubmitProgress ( 0 ) ;
532+ setSubmitStatus ( 'Initializing...' ) ;
533+
534+ // Simulate progress updates
535+ const progressInterval = setInterval ( ( ) => {
536+ setSubmitProgress ( prev => {
537+ if ( prev >= 90 ) return prev ;
538+ return prev + Math . random ( ) * 15 ;
539+ } ) ;
540+ } , 500 ) ;
541+
542+ setSubmitStatus ( 'Generating graph data...' ) ;
543+ setSubmitProgress ( 25 ) ;
544+
524545 const response = await fetch ( `${ API_ENDPOINTS . GENERATED_NODES } ` , {
525546 method : 'POST' ,
526547 headers : {
@@ -529,6 +550,10 @@ export const TopicRefiner: FC<Omit<TopicRefinerProps, 'isLlmProcessing'>> = ({
529550 body : JSON . stringify ( { topics : finalizedTopics } ) ,
530551 } ) ;
531552
553+ clearInterval ( progressInterval ) ;
554+ setSubmitProgress ( 90 ) ;
555+ setSubmitStatus ( 'Finalizing...' ) ;
556+
532557 if ( ! response . ok ) {
533558 throw new Error ( 'Failed to generate GEXF file' ) ;
534559 }
@@ -538,6 +563,9 @@ export const TopicRefiner: FC<Omit<TopicRefinerProps, 'isLlmProcessing'>> = ({
538563 throw new Error ( 'Failed to generate GEXF file' ) ;
539564 }
540565
566+ setSubmitProgress ( 100 ) ;
567+ setSubmitStatus ( 'Complete!' ) ;
568+
541569 const file = new File ( [ data . gexfContent ] , "generated_nodes.gexf" , { type : "application/xml" } ) ;
542570 // Use replace: false to ensure proper history entry is created
543571 navigate ( '/graph?l=1' , {
@@ -548,6 +576,8 @@ export const TopicRefiner: FC<Omit<TopicRefinerProps, 'isLlmProcessing'>> = ({
548576 console . error ( 'Error submitting finalized topics:' , error ) ;
549577 alert ( 'Failed to generate graph. Please try again.' ) ;
550578 setIsSubmitting ( false ) ; // Reset loading state on error
579+ setSubmitProgress ( 0 ) ;
580+ setSubmitStatus ( '' ) ;
551581 }
552582 } ;
553583
@@ -955,29 +985,71 @@ export const TopicRefiner: FC<Omit<TopicRefinerProps, 'isLlmProcessing'>> = ({
955985 </ div >
956986 ) }
957987 </ div >
958- < button
959- className = "btn d-flex align-items-center"
960- onClick = { handleSubmitFinalizedTopics }
961- disabled = { finalizedTopics . length === 0 || isSubmitting || isLoadingUniqueCount }
988+ < div
989+ className = "position-relative d-flex align-items-center justify-content-center"
962990 style = { {
963- color : 'white' ,
964- backgroundColor : '#198754' , // Bootstrap's success color
965- borderColor : '#198754' ,
966- opacity : finalizedTopics . length === 0 || isSubmitting || isLoadingUniqueCount ? 0.65 : 1
991+ minWidth : '200px' ,
992+ height : '38px' ,
993+ borderRadius : '6px' ,
994+ border : '1px solid #198754' ,
995+ backgroundColor : isSubmitting ? '#f8f9fa' : '#198754' ,
996+ color : isSubmitting ? '#6c757d' : 'white' ,
997+ cursor : isSubmitting ? 'default' : 'pointer' ,
998+ transition : 'all 0.3s ease' ,
999+ opacity : finalizedTopics . length === 0 || isLoadingUniqueCount ? 0.65 : 1
9671000 } }
1001+ onClick = { ! isSubmitting ? handleSubmitFinalizedTopics : undefined }
9681002 >
9691003 { isSubmitting ? (
9701004 < >
971- < Loader2 size = { 16 } className = "me-2 animate-spin" />
972- Generating Graph...
1005+ { /* Progress bar background */ }
1006+ < div
1007+ className = "position-absolute"
1008+ style = { {
1009+ top : 0 ,
1010+ left : 0 ,
1011+ height : '100%' ,
1012+ width : '100%' ,
1013+ borderRadius : '6px' ,
1014+ backgroundColor : '#e9ecef'
1015+ } }
1016+ />
1017+ { /* Progress bar fill */ }
1018+ < div
1019+ className = "position-absolute"
1020+ style = { {
1021+ top : 0 ,
1022+ left : 0 ,
1023+ height : '100%' ,
1024+ width : `${ submitProgress } %` ,
1025+ borderRadius : '6px' ,
1026+ backgroundColor : '#198754' ,
1027+ transition : 'width 0.3s ease'
1028+ } }
1029+ />
1030+ { /* Content overlay */ }
1031+ < div className = "position-relative d-flex align-items-center" >
1032+ < Loader2
1033+ size = { 16 }
1034+ className = "me-2 animate-spin"
1035+ style = { {
1036+ color : submitStatus === 'Generating graph data...' ? 'white' : '#6c757d'
1037+ } }
1038+ />
1039+ < span style = { {
1040+ color : submitStatus === 'Generating graph data...' ? 'white' : '#6c757d'
1041+ } } >
1042+ { submitStatus || 'Processing...' }
1043+ </ span >
1044+ </ div >
9731045 </ >
9741046 ) : (
9751047 < >
9761048 < ThumbsUp size = { 16 } className = "me-2" />
9771049 Submit Topics
9781050 </ >
9791051 ) }
980- </ button >
1052+ </ div >
9811053 </ div >
9821054 </ div >
9831055 </ div >
0 commit comments