@@ -21,18 +21,14 @@ import { isEmpty } from "lodash";
2121import { theme } from "@zesty-io/material" ;
2222
2323import { useMetaKey } from "../../../shell/hooks/useMetaKey" ;
24- import {
25- useGetContentModelsQuery ,
26- useSearchContentQuery ,
27- } from "../../services/instance" ;
2824import { notify } from "../../store/notifications" ;
2925import { AdvancedSearch } from "./components/AdvancedSearch" ;
3026import useRecentSearches from "../../hooks/useRecentSearches" ;
3127import { GlobalSearchItem } from "./components/GlobalSearchItem" ;
3228import { getContentTitle , getItemIcon } from "./utils" ;
3329import { useSearchModelsByKeyword } from "../../hooks/useSearchModelsByKeyword" ;
3430import { useSearchCodeFilesByKeywords } from "../../hooks/useSearchCodeFilesByKeyword" ;
35- import { ResourceType } from "../../services/types" ;
31+ import { ContentItem , Language , ResourceType } from "../../services/types" ;
3632import { SearchAccelerator } from "./components/SearchAccelerator" ;
3733import { SEARCH_ACCELERATORS } from "./components/config" ;
3834import { useGetActiveApp } from "../../hooks/useGetActiveApp" ;
@@ -47,6 +43,10 @@ import { KeywordSearchItem } from "./components/KeywordSearchItem";
4743import { useParams } from "../../hooks/useParams" ;
4844import { withCursorPosition } from "../../components/withCursorPosition" ;
4945import { useSearchBlocksByKeyword } from "../../hooks/useSearchBlocksByKeyword" ;
46+ import { AppState } from "shell/store/types" ;
47+ import { fetchModels } from "shell/store/models" ;
48+ import { useDebounce } from "react-use" ;
49+ import { searchItems } from "shell/store/content" ;
5050
5151// List of dropdown options that are NOT suggestions
5252const AdditionalDropdownOptions = [
@@ -81,11 +81,7 @@ export const GlobalSearch = () => {
8181 const [ isAdvancedSearchOpen , setIsAdvancedSearchOpen ] = useState ( false ) ;
8282 const [ recentSearches , addSearchTerm , deleteSearchTerm ] = useRecentSearches ( ) ;
8383 const [ models , setModelKeyword ] = useSearchModelsByKeyword ( ) ;
84- const {
85- blocks,
86- setBlockKeyword,
87- isLoading : isFetchingBlocksResults ,
88- } = useSearchBlocksByKeyword ( ) ;
84+
8985 const [ codeFiles , setFileKeyword ] = useSearchCodeFilesByKeywords ( ) ;
9086 const [ mediaFolders , setMediaFolderKeyword ] =
9187 useSearchMediaFoldersByKeyword ( ) ;
@@ -97,22 +93,29 @@ export const GlobalSearch = () => {
9793 const dispatch = useDispatch ( ) ;
9894 const [ params , setParams ] = useParams ( ) ;
9995 const textfieldRef = useRef < HTMLDivElement > ( ) ;
100- const { data : allModels } = useGetContentModelsQuery ( ) ;
101-
102- const apiQueryTerm = useMemo ( ( ) => {
103- if ( ! ! typedSearchAccelerator && ! ! searchKeyword ) {
104- // Remove the accelerator from the keyword
105- return searchKeyword . replace ( typedAcceleratorRegex , "" ) ?. trim ( ) ;
106- }
107-
108- return searchKeyword ;
109- } , [ searchKeyword ] ) ;
110-
111- const {
112- data : contents ,
113- isError : isContentFetchingFailed ,
114- isFetching : isFetchingContentSearchResults ,
115- } = useSearchContentQuery ( { query : apiQueryTerm } ) ;
96+ const allModels = useSelector ( ( state : AppState ) => state ?. models ) ;
97+ const [ searchedContents , setSearchedContents ] = useState < ContentItem [ ] | [ ] > (
98+ [ ]
99+ ) ;
100+ const [ isFetchingContentSearchResults , setIsFetchingContentSearchResults ] =
101+ useState ( false ) ;
102+
103+ const [ apiQueryTerm , setApiQueryTerm ] = useState ( "" ) ;
104+
105+ //debounce to reduce API calls during user input.
106+ useDebounce (
107+ ( ) => {
108+ if ( ! ! typedSearchAccelerator && ! ! searchKeyword ) {
109+ // Remove the accelerator from the keyword
110+ setApiQueryTerm (
111+ searchKeyword . replace ( typedAcceleratorRegex , "" ) ?. trim ( )
112+ ) ;
113+ }
114+ setApiQueryTerm ( searchKeyword ) ;
115+ } ,
116+ 700 ,
117+ [ searchKeyword ]
118+ ) ;
116119
117120 const { data : bins } = useGetBinsQuery ( { instanceId, ecoId } ) ;
118121 const { data : mediaFiles , isFetching : isFetchingMediaSearchResults } =
@@ -128,35 +131,57 @@ export const GlobalSearch = () => {
128131 { skip : ! bins ?. length }
129132 ) ;
130133
134+ const { blocks, setBlockKeyword } = useSearchBlocksByKeyword ( {
135+ isLoading : isFetchingContentSearchResults ,
136+ } ) ;
137+
131138 const isLoading =
132139 isFetchingAllMediaFiles ||
133140 isFetchingMediaSearchResults ||
134- isFetchingContentSearchResults ||
135- isFetchingBlocksResults ;
141+ isFetchingContentSearchResults ;
142+
143+ useEffect ( ( ) => {
144+ //Update models in store to provide access to other search hooks
145+ dispatch ( fetchModels ( ) ) ;
146+ } , [ ] ) ;
147+
148+ useEffect ( ( ) => {
149+ if ( isEmpty ( apiQueryTerm ) ) return setSearchedContents ( [ ] ) ;
150+ setIsFetchingContentSearchResults ( true ) ;
151+ //Update contents in store to provide access to other search hooks
152+ dispatch ( searchItems ( apiQueryTerm ) )
153+ //@ts -ignore
154+ . then ( ( res ) => {
155+ if ( ! ! res ?. data ?. length ) {
156+ setSearchedContents ( res ?. data ) ;
157+ } else {
158+ setSearchedContents ( [ ] ) ;
159+ }
160+ setIsFetchingContentSearchResults ( false ) ;
161+ } ) ;
162+ } , [ apiQueryTerm ] ) ;
136163
137164 const suggestions : Suggestion [ ] = useMemo ( ( ) => {
165+ //Filter out redundant block model items
166+ const filteredContents = searchedContents ?. filter (
167+ ( item : ContentItem ) =>
168+ allModels ?. [ item ?. meta ?. contentModelZUID ] ?. type !== "block"
169+ ) ;
138170 // Content data needs to be reset to [] when api call fails
139- const contentSuggestions : Suggestion [ ] =
140- isContentFetchingFailed || isEmpty ( contents )
141- ? [ ]
142- : contents ?. map ( ( content ) => {
143- return {
144- type : "content" ,
145- ZUID : content . meta ?. ZUID ,
146- title : getContentTitle ( content , languages ) ,
147- updatedAt : content . meta ?. updatedAt ,
148- url : isEmpty ( content . meta )
149- ? ""
150- : `/${
151- allModels ?. find (
152- ( model ) => model . ZUID === content . meta . contentModelZUID
153- ) ?. type === "block"
154- ? "blocks"
155- : "content"
156- } /${ content . meta . contentModelZUID } /${ content . meta . ZUID } `,
157- noUrlErrorMessage : "Selected item is missing meta data" ,
158- } ;
159- } ) ;
171+ const contentSuggestions : Suggestion [ ] = isEmpty ( filteredContents )
172+ ? [ ]
173+ : filteredContents ?. map ( ( content ) => {
174+ return {
175+ type : "content" ,
176+ ZUID : content . meta ?. ZUID ,
177+ title : getContentTitle ( content , languages ) ,
178+ updatedAt : content . meta ?. updatedAt ,
179+ url : isEmpty ( content . meta )
180+ ? ""
181+ : `/content/${ content . meta . contentModelZUID } /${ content . meta . ZUID } ` ,
182+ noUrlErrorMessage : "Selected item is missing meta data" ,
183+ } ;
184+ } ) ;
160185
161186 const modelSuggestions : Suggestion [ ] =
162187 models ?. map ( ( model ) => {
@@ -171,12 +196,17 @@ export const GlobalSearch = () => {
171196
172197 const blocksSuggestions : Suggestion [ ] =
173198 blocks ?. map ( ( block ) => {
199+ const langCode = languages ?. find (
200+ ( lang : Language ) => lang ?. ID === block ?. langID
201+ ) ?. code ;
202+ const titlePrefix = ! ! langCode ? `(${ langCode } ) ` : "" ;
203+
174204 return {
175205 type : "block" ,
176206 ZUID : block ?. ZUID ,
177- title : block ?. label ,
207+ title : block ?. title , //`${titlePrefix}${block?. label}` ,
178208 updatedAt : block ?. updatedAt ,
179- url : `/blocks/ ${ block ?. ZUID } ` ,
209+ url : block ?. url ,
180210 } ;
181211 } ) || [ ] ;
182212
@@ -265,13 +295,12 @@ export const GlobalSearch = () => {
265295 new Date ( b . updatedAt ) . getTime ( ) - new Date ( a . updatedAt ) . getTime ( )
266296 ) ;
267297 } , [
268- contents ,
298+ searchedContents ,
269299 models ,
270300 blocks ,
271301 codeFiles ,
272302 mediaFiles ,
273303 mediaFolders ,
274- isContentFetchingFailed ,
275304 chipSearchAccelerator ,
276305 allMediaFiles ,
277306 ] ) ;
@@ -356,7 +385,7 @@ export const GlobalSearch = () => {
356385 } ) ;
357386 const url = `/search?${ searchParams . toString ( ) } ` ;
358387
359- // Do not save term as a recent keyword if it's empty
388+ // Do not save term as a recent keyword if it's empty1
360389 if ( ! ! queryTerm . trim ( ) ) {
361390 // If the user has selected a search accelerator, also save it in
362391 // the format of `[in:RESOURCE_TYPE]`
0 commit comments