Improved empty state for nav search (#79123)
* Improved empty state for nav search * Updates tests to include required props * Update empty state text
This commit is contained in:
parent
0628cfecf4
commit
a7d9e2f481
5 changed files with 72 additions and 22 deletions
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 102 KiB |
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 102 KiB |
|
@ -8,6 +8,7 @@ import React from 'react';
|
|||
import { wait } from '@testing-library/react';
|
||||
import { of } from 'rxjs';
|
||||
import { mountWithIntl } from 'test_utils/enzyme_helpers';
|
||||
import { httpServiceMock, uiSettingsServiceMock } from '../../../../../src/core/public/mocks';
|
||||
import {
|
||||
GlobalSearchBatchedResults,
|
||||
GlobalSearchPluginStart,
|
||||
|
@ -47,6 +48,10 @@ const getSearchProps: any = (component: any) => component.find('EuiFieldSearch')
|
|||
describe('SearchBar', () => {
|
||||
let searchService: GlobalSearchPluginStart;
|
||||
let findSpy: jest.SpyInstance;
|
||||
const http = httpServiceMock.createSetupContract({ basePath: '/test' });
|
||||
const basePathUrl = http.basePath.prepend('/plugins/globalSearchBar/assets/');
|
||||
const uiSettings = uiSettingsServiceMock.createStartContract();
|
||||
const darkMode = uiSettings.get('theme:darkMode');
|
||||
|
||||
beforeEach(() => {
|
||||
searchService = globalSearchPluginMock.createStartContract();
|
||||
|
@ -66,7 +71,12 @@ describe('SearchBar', () => {
|
|||
.mockReturnValueOnce(of(createBatch('Discover', { id: 'My Dashboard', type: 'test' })));
|
||||
|
||||
const component = mountWithIntl(
|
||||
<SearchBar globalSearch={searchService.find} navigateToUrl={navigate} />
|
||||
<SearchBar
|
||||
globalSearch={searchService.find}
|
||||
navigateToUrl={navigate}
|
||||
basePathUrl={basePathUrl}
|
||||
darkMode={darkMode}
|
||||
/>
|
||||
);
|
||||
|
||||
expect(findSpy).toHaveBeenCalledTimes(0);
|
||||
|
@ -85,7 +95,14 @@ describe('SearchBar', () => {
|
|||
});
|
||||
|
||||
it('supports keyboard shortcuts', () => {
|
||||
mountWithIntl(<SearchBar globalSearch={searchService.find} navigateToUrl={jest.fn()} />);
|
||||
mountWithIntl(
|
||||
<SearchBar
|
||||
globalSearch={searchService.find}
|
||||
navigateToUrl={jest.fn()}
|
||||
basePathUrl={basePathUrl}
|
||||
darkMode={darkMode}
|
||||
/>
|
||||
);
|
||||
|
||||
const searchEvent = new KeyboardEvent('keydown', {
|
||||
key: '/',
|
||||
|
|
|
@ -12,6 +12,7 @@ import {
|
|||
EuiSelectableTemplateSitewideOption,
|
||||
EuiText,
|
||||
EuiIcon,
|
||||
EuiImage,
|
||||
EuiHeaderSectionItemButton,
|
||||
EuiSelectableMessage,
|
||||
} from '@elastic/eui';
|
||||
|
@ -27,6 +28,8 @@ import { GlobalSearchPluginStart, GlobalSearchResult } from '../../../global_sea
|
|||
interface Props {
|
||||
globalSearch: GlobalSearchPluginStart['find'];
|
||||
navigateToUrl: ApplicationStart['navigateToUrl'];
|
||||
basePathUrl: string;
|
||||
darkMode: boolean;
|
||||
}
|
||||
|
||||
const clearField = (field: HTMLInputElement) => {
|
||||
|
@ -42,7 +45,7 @@ const clearField = (field: HTMLInputElement) => {
|
|||
const cleanMeta = (str: string) => (str.charAt(0).toUpperCase() + str.slice(1)).replace(/-/g, ' ');
|
||||
const blurEvent = new FocusEvent('blur');
|
||||
|
||||
export function SearchBar({ globalSearch, navigateToUrl }: Props) {
|
||||
export function SearchBar({ globalSearch, navigateToUrl, basePathUrl, darkMode }: Props) {
|
||||
const isMounted = useMountedState();
|
||||
const [searchValue, setSearchValue] = useState<string>('');
|
||||
const [searchRef, setSearchRef] = useState<HTMLInputElement | null>(null);
|
||||
|
@ -134,6 +137,34 @@ export function SearchBar({ globalSearch, navigateToUrl }: Props) {
|
|||
}
|
||||
};
|
||||
|
||||
const emptyMessage = (
|
||||
<EuiSelectableMessage style={{ minHeight: 300 }}>
|
||||
<EuiImage
|
||||
alt={i18n.translate('xpack.globalSearchBar.searchBar.noResultsImageAlt', {
|
||||
defaultMessage: 'Illustration of black hole',
|
||||
})}
|
||||
size="fullWidth"
|
||||
url={`${basePathUrl}illustration_product_no_search_results_${
|
||||
darkMode ? 'dark' : 'light'
|
||||
}.svg`}
|
||||
/>
|
||||
<EuiText size="m">
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.globalSearchBar.searchBar.noResultsHeading"
|
||||
defaultMessage="No results found"
|
||||
/>
|
||||
</p>
|
||||
</EuiText>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.globalSearchBar.searchBar.noResults"
|
||||
defaultMessage="Try searching for applications, dashboards, visualizations, and more."
|
||||
/>
|
||||
</p>
|
||||
</EuiSelectableMessage>
|
||||
);
|
||||
|
||||
useEvent('keydown', onKeyDown);
|
||||
|
||||
return (
|
||||
|
@ -164,22 +195,8 @@ export function SearchBar({ globalSearch, navigateToUrl }: Props) {
|
|||
popoverProps={{
|
||||
repositionOnScroll: true,
|
||||
}}
|
||||
emptyMessage={
|
||||
<EuiSelectableMessage style={{ minHeight: 300 }}>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.globalSearchBar.searchBar.noResultsHeading"
|
||||
defaultMessage="No results found"
|
||||
/>
|
||||
</p>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.globalSearchBar.searchBar.noResults"
|
||||
defaultMessage="Try searching for applications and saved objects by name."
|
||||
/>
|
||||
</p>
|
||||
</EuiSelectableMessage>
|
||||
}
|
||||
emptyMessage={emptyMessage}
|
||||
noMatchesMessage={emptyMessage}
|
||||
popoverFooter={
|
||||
<EuiText color="subdued" size="xs">
|
||||
<EuiFlexGroup
|
||||
|
|
|
@ -24,7 +24,14 @@ export class GlobalSearchBarPlugin implements Plugin<{}, {}> {
|
|||
public start(core: CoreStart, { globalSearch }: GlobalSearchBarPluginStartDeps) {
|
||||
core.chrome.navControls.registerCenter({
|
||||
order: 1000,
|
||||
mount: (target) => this.mount(target, globalSearch, core.application.navigateToUrl),
|
||||
mount: (target) =>
|
||||
this.mount(
|
||||
target,
|
||||
globalSearch,
|
||||
core.application.navigateToUrl,
|
||||
core.http.basePath.prepend('/plugins/globalSearchBar/assets/'),
|
||||
core.uiSettings.get('theme:darkMode')
|
||||
),
|
||||
});
|
||||
return {};
|
||||
}
|
||||
|
@ -32,11 +39,18 @@ export class GlobalSearchBarPlugin implements Plugin<{}, {}> {
|
|||
private mount(
|
||||
targetDomElement: HTMLElement,
|
||||
globalSearch: GlobalSearchPluginStart,
|
||||
navigateToUrl: ApplicationStart['navigateToUrl']
|
||||
navigateToUrl: ApplicationStart['navigateToUrl'],
|
||||
basePathUrl: string,
|
||||
darkMode: boolean
|
||||
) {
|
||||
ReactDOM.render(
|
||||
<I18nProvider>
|
||||
<SearchBar globalSearch={globalSearch.find} navigateToUrl={navigateToUrl} />
|
||||
<SearchBar
|
||||
globalSearch={globalSearch.find}
|
||||
navigateToUrl={navigateToUrl}
|
||||
basePathUrl={basePathUrl}
|
||||
darkMode={darkMode}
|
||||
/>
|
||||
</I18nProvider>,
|
||||
targetDomElement
|
||||
);
|
||||
|
|
Loading…
Reference in a new issue