diff --git a/x-pack/plugins/global_search_bar/public/components/search_bar.tsx b/x-pack/plugins/global_search_bar/public/components/search_bar.tsx
index c8ac154b34c9f..6c7eef92c6623 100644
--- a/x-pack/plugins/global_search_bar/public/components/search_bar.tsx
+++ b/x-pack/plugins/global_search_bar/public/components/search_bar.tsx
@@ -39,10 +39,6 @@ import { PopoverPlaceholder } from './popover_placeholder';
import './search_bar.scss';
import { SearchBarProps } from './types';
-const NoMatchesMessage = (props: { basePathUrl: string }) => {
- return ;
-};
-
const SearchCharLimitExceededMessage = (props: { basePathUrl: string }) => {
const charLimitMessage = (
<>
@@ -90,17 +86,17 @@ export const SearchBar: FC = (opts) => {
// General hooks
const [initialLoad, setInitialLoad] = useState(false);
const [searchValue, setSearchValue] = useState('');
- const [searchTerm, setSearchTerm] = useState('');
const [searchRef, setSearchRef] = useState(null);
const [buttonRef, setButtonRef] = useState(null);
const searchSubscription = useRef(null);
- const [options, _setOptions] = useState([]);
+ const [options, setOptions] = useState([]);
const [searchableTypes, setSearchableTypes] = useState([]);
const [showAppend, setShowAppend] = useState(true);
const UNKNOWN_TAG_ID = '__unknown__';
const [isLoading, setIsLoading] = useState(false);
const [searchCharLimitExceeded, setSearchCharLimitExceeded] = useState(false);
+ // Initialize searchableTypes data
useEffect(() => {
if (initialLoad) {
const fetch = async () => {
@@ -111,6 +107,11 @@ export const SearchBar: FC = (opts) => {
}
}, [globalSearch, initialLoad]);
+ // Whenever searchValue changes, isLoading = true
+ useEffect(() => {
+ setIsLoading(true);
+ }, [searchValue]);
+
const loadSuggestions = useCallback(
(term: string) => {
return getSuggestions({
@@ -122,17 +123,13 @@ export const SearchBar: FC = (opts) => {
[taggingApi, searchableTypes]
);
- const setOptions = useCallback(
+ const setDecoratedOptions = useCallback(
(
_options: GlobalSearchResult[],
suggestions: SearchSuggestion[],
searchTagIds: string[] = []
) => {
- if (!isMounted()) {
- return;
- }
-
- _setOptions([
+ setOptions([
...suggestions.map(suggestionToOption),
..._options.map((option) =>
resultToOption(
@@ -143,7 +140,7 @@ export const SearchBar: FC = (opts) => {
),
]);
},
- [isMounted, _setOptions, taggingApi]
+ [setOptions, taggingApi]
);
useDebounce(
@@ -163,9 +160,7 @@ export const SearchBar: FC = (opts) => {
setSearchCharLimitExceeded(false);
}
- setIsLoading(true);
const suggestions = loadSuggestions(searchValue.toLowerCase());
- setIsLoading(false);
let aggregatedResults: GlobalSearchResult[] = [];
@@ -187,26 +182,23 @@ export const SearchBar: FC = (opts) => {
types: rawParams.filters.types,
tags: tagIds,
};
- // TODO technically a subtle bug here
- // this term won't be set until the next time the debounce is fired
- // so the SearchOption won't highlight anything if only one call is fired
- // in practice, this is hard to spot, unlikely to happen, and is a negligible issue
- setSearchTerm(rawParams.term ?? '');
- setIsLoading(true);
+
searchSubscription.current = globalSearch.find(searchParams, {}).subscribe({
next: ({ results }) => {
+ if (!isMounted()) {
+ return;
+ }
+
if (searchValue.length > 0) {
aggregatedResults = [...results, ...aggregatedResults].sort(sort.byScore);
- setOptions(aggregatedResults, suggestions, searchParams.tags);
+ setDecoratedOptions(aggregatedResults, suggestions, searchParams.tags);
return;
}
// if searchbar is empty, filter to only applications and sort alphabetically
results = results.filter(({ type }: GlobalSearchResult) => type === 'application');
-
aggregatedResults = [...results, ...aggregatedResults].sort(sort.byTitle);
-
- setOptions(aggregatedResults, suggestions, searchParams.tags);
+ setDecoratedOptions(aggregatedResults, suggestions, searchParams.tags);
},
error: (err) => {
setIsLoading(false);
@@ -371,7 +363,7 @@ export const SearchBar: FC = (opts) => {
className="kbnSearchBar"
popoverButtonBreakpoints={['xs', 's']}
singleSelection={true}
- renderOption={(option) => euiSelectableTemplateSitewideRenderOptions(option, searchTerm)}
+ renderOption={(option) => euiSelectableTemplateSitewideRenderOptions(option, searchValue)}
listProps={{
className: 'eui-yScroll',
css: css`
@@ -401,7 +393,7 @@ export const SearchBar: FC = (opts) => {
}}
errorMessage={searchCharLimitExceeded ? : null}
emptyMessage={}
- noMatchesMessage={}
+ noMatchesMessage={}
popoverProps={{
'data-test-subj': 'nav-search-popover',
panelClassName: 'navSearch__panel',
diff --git a/x-pack/plugins/global_search_bar/public/telemetry/telemetry.test.tsx b/x-pack/plugins/global_search_bar/public/telemetry/telemetry.test.tsx
index 2137679fcf5c3..e4302c1e64aec 100644
--- a/x-pack/plugins/global_search_bar/public/telemetry/telemetry.test.tsx
+++ b/x-pack/plugins/global_search_bar/public/telemetry/telemetry.test.tsx
@@ -194,9 +194,7 @@ describe('SearchBar', () => {
});
it(`tracks the user's search term`, async () => {
- searchService.find.mockReturnValueOnce(
- of(createBatch('Discover', { id: 'My Dashboard', type: 'test' }))
- );
+ searchService.find.mockReturnValue(of(createBatch('Discover')));
render(