55 NormalizedCacheObject ,
66 useApolloClient ,
77} from '@apollo/client' ;
8- import { SearchFunction , SearchResult } from 'hds-react' ;
9- import React from 'react' ;
8+ import { Option , SearchFunction , SearchResult , SelectData } from 'hds-react' ;
9+ import React , { useEffect } from 'react' ;
1010import { useTranslation } from 'react-i18next' ;
1111
1212import {
@@ -39,12 +39,15 @@ const getOption = ({
3939 return { label, value } ;
4040} ;
4141
42- export type KeywordSelectorProps = MultiSelectPropsWithValue < string > ;
42+ export type KeywordSelectorProps = MultiSelectPropsWithValue < string > & {
43+ handleClose : ( selectedOptions : OptionType [ ] ) => void ;
44+ } ;
4345
4446const KeywordSelector : React . FC < KeywordSelectorProps > = ( {
4547 texts,
4648 name,
4749 value,
50+ handleClose,
4851 ...rest
4952} ) => {
5053 const apolloClient = useApolloClient ( ) as ApolloClient < NormalizedCacheObject > ;
@@ -54,6 +57,9 @@ const KeywordSelector: React.FC<KeywordSelectorProps> = ({
5457 const [ selectedKeywords , setSelectedKeywords ] = React . useState < OptionType [ ] > (
5558 [ ]
5659 ) ;
60+ const [ options , setOptions ] = React . useState < OptionType [ ] > ( [ ] ) ;
61+
62+ const initialOptions = React . useRef < OptionType [ ] > ( [ ] ) ;
5763
5864 const {
5965 data : keywordsData ,
@@ -69,7 +75,7 @@ const KeywordSelector: React.FC<KeywordSelectorProps> = ({
6975 } ,
7076 } ) ;
7177
72- const getKeywordsData = React . useCallback (
78+ const keywordsOptions = React . useMemo (
7379 ( ) =>
7480 getValue (
7581 ( keywordsData || previousKeywordsData ) ?. keywords . data . map ( ( keyword ) =>
@@ -80,43 +86,71 @@ const KeywordSelector: React.FC<KeywordSelectorProps> = ({
8086 [ keywordsData , locale , previousKeywordsData ]
8187 ) ;
8288
83- const options = React . useMemo ( ( ) => getKeywordsData ( ) , [ getKeywordsData ] ) ;
84-
85- const handleSearch : SearchFunction = async (
86- searchValue : string
87- ) : Promise < SearchResult > => {
88- try {
89- const { error } = await refetch ( {
90- freeText : searchValue ,
91- } ) ;
89+ useEffect ( ( ) => {
90+ setOptions ( keywordsOptions ) ;
9291
93- if ( error ) {
94- throw error ;
92+ if ( keywordsData && ! initialOptions ?. current . length ) {
93+ initialOptions . current = keywordsOptions ;
94+ }
95+ } , [ keywordsOptions , keywordsData ] ) ;
96+
97+ const handleSearch : SearchFunction = React . useCallback (
98+ async ( searchValue : string ) : Promise < SearchResult > => {
99+ try {
100+ const { error, data : newKeywordsData } = await refetch ( {
101+ freeText : searchValue ,
102+ } ) ;
103+
104+ if ( error ) {
105+ throw error ;
106+ }
107+
108+ const newOptions = getValue (
109+ newKeywordsData ?. keywords . data . map ( ( keyword ) =>
110+ getOption ( { keyword : keyword as KeywordFieldsFragment , locale } )
111+ ) ,
112+ [ ]
113+ ) ;
114+
115+ return Promise . resolve ( { options : newOptions } ) ;
116+ } catch ( error ) {
117+ return Promise . reject ( error as ApolloError ) ;
95118 }
119+ } ,
120+ [ refetch , locale ]
121+ ) ;
96122
97- return Promise . resolve ( { options : getKeywordsData ( ) } ) ;
98- } catch ( error ) {
99- return Promise . reject ( error as ApolloError ) ;
100- }
101- } ;
123+ const onClose = React . useCallback (
124+ (
125+ selectedOptions : Option [ ] ,
126+ _clickedOption : undefined ,
127+ _data : SelectData
128+ ) => {
129+ setOptions ( initialOptions . current ) ;
130+
131+ if ( handleClose ) {
132+ handleClose ( selectedOptions ) ;
133+ }
134+ } ,
135+ [ handleClose ]
136+ ) ;
102137
103138 React . useEffect ( ( ) => {
104- const getSelectedKeywordsFromCache = async ( ) =>
105- setSelectedKeywords (
106- (
107- await Promise . all (
108- value . map ( async ( atId ) => {
109- const keyword = await getKeywordQueryResult (
110- getValue ( parseIdFromAtId ( atId ) , '' ) ,
111- apolloClient
112- ) ;
113- /* istanbul ignore next */
114- return keyword ? getOption ( { keyword : keyword , locale } ) : null ;
115- } )
116- )
117- ) . filter ( skipFalsyType )
139+ const getSelectedKeywordsFromCache = async ( ) => {
140+ const selectedOptions = await Promise . all (
141+ value . map ( async ( atId ) => {
142+ const keyword = await getKeywordQueryResult (
143+ getValue ( parseIdFromAtId ( atId ) , '' ) ,
144+ apolloClient
145+ ) ;
146+ /* istanbul ignore next */
147+ return keyword ? getOption ( { keyword : keyword , locale } ) : null ;
148+ } )
118149 ) ;
119150
151+ setSelectedKeywords ( selectedOptions . filter ( skipFalsyType ) ) ;
152+ } ;
153+
120154 getSelectedKeywordsFromCache ( ) ;
121155 } , [ apolloClient , locale , value ] ) ;
122156
@@ -125,6 +159,7 @@ const KeywordSelector: React.FC<KeywordSelectorProps> = ({
125159 { ...rest }
126160 multiSelect
127161 onSearch = { handleSearch }
162+ onClose = { onClose }
128163 id = { name }
129164 isLoading = { loading }
130165 texts = { {
0 commit comments