@@ -38,6 +38,16 @@ const GraphPattern: React.FC<TupleCreationProps> = ({
3838 } ) ;
3939 const sourceRef = useRef < HTMLDivElement | null > ( null ) ;
4040 const { userCredentials } = useCredentials ( ) ;
41+ const deduplicateOptions = ( options : OptionType [ ] ) : OptionType [ ] => {
42+ const seen = new Set < string > ( ) ;
43+ return options . filter ( ( option ) => {
44+ if ( seen . has ( option . value ) ) {
45+ return false ;
46+ }
47+ seen . add ( option . value ) ;
48+ return true ;
49+ } ) ;
50+ } ;
4151
4252 useEffect ( ( ) => {
4353 const isGlobalStateSet =
@@ -64,17 +74,53 @@ const GraphPattern: React.FC<TupleCreationProps> = ({
6474 target : { value : targetVal , label : targetVal } ,
6575 } ;
6676 } ) ;
67- const savedSources : OptionType [ ] = Array . from ( sourceSet ) . map ( ( val ) => ( { value : val , label : val } ) ) ;
6877 const savedTypes : OptionType [ ] = Array . from ( typeSet ) . map ( ( val ) => ( { value : val , label : val } ) ) ;
69- const savedTargets : OptionType [ ] = Array . from ( targetSet ) . map ( ( val ) => ( { value : val , label : val } ) ) ;
78+ const combinedSourceTarget = new Set ( [ ...sourceSet , ...targetSet ] ) ;
79+ const combinedSourceTargetOptions : OptionType [ ] = Array . from ( combinedSourceTarget ) . map ( ( val ) => ( {
80+ value : val ,
81+ label : val ,
82+ } ) ) ;
83+
7084 setSelectedRels ( mappedRels ) ;
71- setSourceOptions ( savedSources ) ;
85+ setSourceOptions ( combinedSourceTargetOptions ) ;
7286 setTypeOptions ( savedTypes ) ;
73- setTargetOptions ( savedTargets ) ;
87+ setTargetOptions ( combinedSourceTargetOptions ) ;
7488 }
7589 }
7690 } , [ ] ) ;
7791
92+ useEffect ( ( ) => {
93+ let timeoutId : NodeJS . Timeout ;
94+ timeoutId = setTimeout ( ( ) => {
95+ if ( sourceOptions . length > 0 ) {
96+ const deduped = deduplicateOptions ( sourceOptions ) ;
97+ if ( deduped . length !== sourceOptions . length ) {
98+ setSourceOptions ( deduped ) ;
99+ }
100+ }
101+
102+ if ( targetOptions . length > 0 ) {
103+ const deduped = deduplicateOptions ( targetOptions ) ;
104+ if ( deduped . length !== targetOptions . length ) {
105+ setTargetOptions ( deduped ) ;
106+ }
107+ }
108+
109+ if ( typeOptions . length > 0 ) {
110+ const deduped = deduplicateOptions ( typeOptions ) ;
111+ if ( deduped . length !== typeOptions . length ) {
112+ setTypeOptions ( deduped ) ;
113+ }
114+ }
115+ } , 1000 ) ;
116+
117+ return ( ) => {
118+ if ( timeoutId ) {
119+ clearTimeout ( timeoutId ) ;
120+ }
121+ } ;
122+ } , [ ] ) ;
123+
78124 const handleNewValue = ( newValue : string , type : 'source' | 'type' | 'target' ) => {
79125 const regex = / ^ [ ^ , ] * $ / ;
80126 if ( ! newValue . trim ( ) ) {
@@ -92,11 +138,16 @@ const GraphPattern: React.FC<TupleCreationProps> = ({
92138 } else {
93139 setShowWarning ( ( old ) => ( { ...old , [ type ] : { showError : false , errorMessage : '' } } ) ) ;
94140 const newOption : OptionType = { value : newValue . trim ( ) , label : newValue . trim ( ) } ;
95- const checkUniqueValue = ( list : OptionType [ ] , value : OptionType ) =>
96- ( list . some ( ( opt ) => opt . value === value . value ) ? list : [ ...list , value ] ) ;
141+ const checkUniqueValue = ( list : OptionType [ ] , value : OptionType ) => {
142+ const exists = list . some ( ( opt ) => opt . value === value . value ) ;
143+ const updatedList = exists ? list : [ ...list , value ] ;
144+ return deduplicateOptions ( updatedList ) ;
145+ } ;
146+
97147 switch ( type ) {
98148 case 'source' :
99149 setSourceOptions ( ( prev ) => checkUniqueValue ( prev , newOption ) ) ;
150+ setTargetOptions ( ( prev ) => checkUniqueValue ( prev , newOption ) ) ;
100151 onPatternChange ( newOption , selectedType as OptionType , selectedTarget as OptionType ) ;
101152 break ;
102153 case 'type' :
@@ -105,10 +156,11 @@ const GraphPattern: React.FC<TupleCreationProps> = ({
105156 break ;
106157 case 'target' :
107158 setTargetOptions ( ( prev ) => checkUniqueValue ( prev , newOption ) ) ;
159+ setSourceOptions ( ( prev ) => checkUniqueValue ( prev , newOption ) ) ;
108160 onPatternChange ( selectedSource as OptionType , selectedType as OptionType , newOption ) ;
109161 break ;
110162 default :
111- console . log ( 'wrong type added' ) ;
163+ // Invalid type provided
112164 break ;
113165 }
114166 setInputValues ( ( prev ) => ( { ...prev , [ type ] : '' } ) ) ;
0 commit comments