1
1
import { useCallback , useEffect , useMemo , useRef , useState } from 'react' ;
2
2
import Fuse from 'fuse.js' ;
3
3
import { OverlayTrigger } from 'react-bootstrap' ;
4
- import { TextInput } from '@mantine/core' ;
4
+ import { TextInput , UnstyledButton } from '@mantine/core' ;
5
+
6
+ import { useQueryHistory } from '@/utils' ;
5
7
6
8
import InputLanguageSwitch from './components/InputLanguageSwitch' ;
7
9
import { useDebounce } from './utils' ;
@@ -22,6 +24,7 @@ export default function AutocompleteInput({
22
24
language,
23
25
showHotkey,
24
26
onSubmit,
27
+ queryHistoryType,
25
28
} : {
26
29
inputRef : React . RefObject < HTMLInputElement > ;
27
30
value : string ;
@@ -38,21 +41,46 @@ export default function AutocompleteInput({
38
41
onLanguageChange ?: ( language : 'sql' | 'lucene' ) => void ;
39
42
language ?: 'sql' | 'lucene' ;
40
43
showHotkey ?: boolean ;
44
+ queryHistoryType ?: string ;
41
45
} ) {
42
46
const suggestionsLimit = 10 ;
43
47
44
48
const [ isSearchInputFocused , setIsSearchInputFocused ] = useState ( false ) ;
45
49
const [ isInputDropdownOpen , setIsInputDropdownOpen ] = useState ( false ) ;
50
+ const [ showSearchHistory , setShowSearchHistory ] = useState ( false ) ;
46
51
47
52
const [ selectedAutocompleteIndex , setSelectedAutocompleteIndex ] =
48
53
useState ( - 1 ) ;
49
54
55
+ const [ selectedQueryHistoryIndex , setSelectedQueryHistoryIndex ] =
56
+ useState ( - 1 ) ;
57
+ // query search history
58
+ const [ queryHistory , setQueryHistory ] = useQueryHistory ( queryHistoryType ) ;
59
+ const queryHistoryList = useMemo ( ( ) => {
60
+ if ( ! queryHistoryType || ! queryHistory ) return [ ] ;
61
+ return queryHistory . map ( q => {
62
+ return {
63
+ value : q ,
64
+ label : q ,
65
+ } ;
66
+ } ) ;
67
+ } , [ queryHistory ] ) ;
68
+
50
69
useEffect ( ( ) => {
51
70
if ( isSearchInputFocused ) {
52
71
setIsInputDropdownOpen ( true ) ;
53
72
}
54
73
} , [ isSearchInputFocused ] ) ;
55
74
75
+ useEffect ( ( ) => {
76
+ // only show search history when: 1.no input, 2.has search type, 3.has history list
77
+ if ( value . length === 0 && queryHistoryList . length > 0 && queryHistoryType ) {
78
+ setShowSearchHistory ( true ) ;
79
+ } else {
80
+ setShowSearchHistory ( false ) ;
81
+ }
82
+ } , [ value , queryHistoryType , queryHistoryList ] ) ;
83
+
56
84
const fuse = useMemo (
57
85
( ) =>
58
86
new Fuse ( autocompleteOptions ?? [ ] , {
@@ -74,6 +102,14 @@ export default function AutocompleteInput({
74
102
return fuse . search ( lastToken ) . map ( result => result . item ) ;
75
103
} , [ debouncedValue , fuse , autocompleteOptions , showSuggestionsOnEmpty ] ) ;
76
104
105
+ const onSelectSearchHistory = ( query : string ) => {
106
+ setSelectedQueryHistoryIndex ( - 1 ) ;
107
+ onChange ( query ) ; // update inputText bar
108
+ setQueryHistory ( query ) ; // update history order
109
+ setIsInputDropdownOpen ( false ) ; // close dropdown since we execute search
110
+ onSubmit ?.( ) ; // search
111
+ } ;
112
+
77
113
const onAcceptSuggestion = ( suggestion : string ) => {
78
114
setSelectedAutocompleteIndex ( - 1 ) ;
79
115
@@ -154,6 +190,29 @@ export default function AutocompleteInput({
154
190
{ belowSuggestions }
155
191
</ div >
156
192
) }
193
+ < div >
194
+ { showSearchHistory && (
195
+ < div className = "border-top border-dark fs-8 py-2" >
196
+ < div className = "text-muted fs-8 fw-bold me-1 px-3" >
197
+ Search History:
198
+ </ div >
199
+ { queryHistoryList . map ( ( { value, label } , i ) => {
200
+ return (
201
+ < UnstyledButton
202
+ className = { `d-block w-100 text-start text-muted fw-normal px-3 py-2 fs-8 ${
203
+ selectedQueryHistoryIndex === i ? 'bg-hdx-dark' : ''
204
+ } `}
205
+ key = { value }
206
+ onMouseOver = { ( ) => setSelectedQueryHistoryIndex ( i ) }
207
+ onClick = { ( ) => onSelectSearchHistory ( value ) }
208
+ >
209
+ < span className = "me-1 text-truncate" > { label } </ span >
210
+ </ UnstyledButton >
211
+ ) ;
212
+ } ) }
213
+ </ div >
214
+ ) }
215
+ </ div >
157
216
</ div >
158
217
) }
159
218
popperConfig = { {
@@ -179,10 +238,12 @@ export default function AutocompleteInput({
179
238
onChange = { e => onChange ( e . target . value ) }
180
239
onFocus = { ( ) => {
181
240
setSelectedAutocompleteIndex ( - 1 ) ;
241
+ setSelectedQueryHistoryIndex ( - 1 ) ;
182
242
setIsSearchInputFocused ( true ) ;
183
243
} }
184
244
onBlur = { ( ) => {
185
245
setSelectedAutocompleteIndex ( - 1 ) ;
246
+ setSelectedQueryHistoryIndex ( - 1 ) ;
186
247
setIsSearchInputFocused ( false ) ;
187
248
} }
188
249
onKeyDown = { e => {
@@ -213,6 +274,9 @@ export default function AutocompleteInput({
213
274
suggestedProperties [ selectedAutocompleteIndex ] . value ,
214
275
) ;
215
276
} else {
277
+ if ( queryHistoryType ) {
278
+ setQueryHistory ( value ) ;
279
+ }
216
280
onSubmit ?.( ) ;
217
281
}
218
282
}
0 commit comments