mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
Search synonyms empty prompt (#205723)
## Summary Implement empty prompt for the Synonyms page. <img width="1044" alt="Screenshot 2025-01-07 at 13 56 09" src="https://github.com/user-attachments/assets/d61c5251-afdb-4e34-bf18-a20ab1044800" /> ### Checklist Check the PR satisfies following conditions. Reviewers should verify this PR satisfies this list as well. - [x] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/src/platform/packages/shared/kbn-i18n/README.md) - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [ ] [Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed - [x] The PR description includes the appropriate Release Notes section, and the correct `release_note:*` label is applied per the [guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) --------- Co-authored-by: Liam Thompson <32779855+leemthompo@users.noreply.github.com> Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
efe44b2f2d
commit
5323067906
11 changed files with 329 additions and 5 deletions
|
@ -1020,5 +1020,8 @@ export const getDocLinks = ({ kibanaBranch, buildFlavor }: GetDocLinkOptions): D
|
|||
cases: {
|
||||
legacyApiDeprecations: `${KIBANA_DOCS}breaking-changes-summary.html#breaking-201004`,
|
||||
},
|
||||
synonyms: {
|
||||
synonymsAPIDocumentation: `${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/reference/current/synonyms-apis.html`,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
|
|
@ -688,6 +688,9 @@ export interface DocLinks {
|
|||
readonly cases: {
|
||||
readonly legacyApiDeprecations: string;
|
||||
};
|
||||
readonly synonyms: {
|
||||
readonly synonymsAPIDocumentation: string;
|
||||
};
|
||||
}
|
||||
|
||||
export type BuildFlavor = 'serverless' | 'traditional';
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { DocLinks } from '@kbn/doc-links';
|
||||
|
||||
class SynonymsDocLinks {
|
||||
public synonymsApi: string = '';
|
||||
|
||||
constructor() {}
|
||||
|
||||
setDocLinks(newDocLinks: DocLinks) {
|
||||
this.synonymsApi = newDocLinks.synonyms.synonymsAPIDocumentation;
|
||||
}
|
||||
}
|
||||
|
||||
export const docLinks = new SynonymsDocLinks();
|
|
@ -11,8 +11,9 @@ import { CoreStart } from '@kbn/core/public';
|
|||
import { KibanaRenderContextProvider } from '@kbn/react-kibana-context-render';
|
||||
import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public';
|
||||
import { I18nProvider } from '@kbn/i18n-react';
|
||||
import { Router } from '@kbn/shared-ux-router';
|
||||
import { Route, Router, Routes } from '@kbn/shared-ux-router';
|
||||
import { AppPluginStartDependencies } from './types';
|
||||
import { SearchSynonymsOverview } from './components/overview/overview';
|
||||
|
||||
export const renderApp = async (
|
||||
core: CoreStart,
|
||||
|
@ -24,7 +25,11 @@ export const renderApp = async (
|
|||
<KibanaContextProvider services={{ ...core, ...services }}>
|
||||
<I18nProvider>
|
||||
<Router history={services.history}>
|
||||
<div>Synonyms</div>
|
||||
<Routes>
|
||||
<Route path="/">
|
||||
<SearchSynonymsOverview />
|
||||
</Route>
|
||||
</Routes>
|
||||
</Router>
|
||||
</I18nProvider>
|
||||
</KibanaContextProvider>
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import { EmptyPrompt } from './empty_prompt';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { I18nProvider } from '@kbn/i18n-react';
|
||||
|
||||
jest.mock('../../../common/doc_links', () => ({
|
||||
docLinks: {
|
||||
synonymsApi: 'documentation-url',
|
||||
},
|
||||
}));
|
||||
const Wrapper = ({ children }: { children?: React.ReactNode }) => (
|
||||
<I18nProvider>{children}</I18nProvider>
|
||||
);
|
||||
|
||||
describe('Synonyms Overview Empty Prompt', () => {
|
||||
it('renders', () => {
|
||||
render(
|
||||
<Wrapper>
|
||||
<EmptyPrompt />
|
||||
</Wrapper>
|
||||
);
|
||||
expect(screen.getByTestId('searchSynonymsEmptyPromptGetStartedButton')).toBeInTheDocument();
|
||||
expect(screen.getByTestId('searchSynonymsEmptyPromptFooterLink').getAttribute('href')).toBe(
|
||||
'documentation-url'
|
||||
);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,206 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import {
|
||||
EuiButton,
|
||||
EuiFlexGrid,
|
||||
EuiFlexGroup,
|
||||
EuiFlexItem,
|
||||
EuiHorizontalRule,
|
||||
EuiIcon,
|
||||
EuiLink,
|
||||
EuiSpacer,
|
||||
EuiSplitPanel,
|
||||
EuiText,
|
||||
EuiTitle,
|
||||
useEuiTheme,
|
||||
} from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { css } from '@emotion/react';
|
||||
import { docLinks } from '../../../common/doc_links';
|
||||
|
||||
export const EmptyPrompt: React.FC = () => {
|
||||
const { euiTheme } = useEuiTheme();
|
||||
return (
|
||||
<EuiFlexGroup direction="row" gutterSize="l" alignItems="center" justifyContent="center">
|
||||
<EuiFlexItem grow={false}>
|
||||
<div
|
||||
css={css`
|
||||
max-width: calc(${euiTheme.size.base} * 50);
|
||||
`}
|
||||
>
|
||||
<EuiSplitPanel.Outer grow={false}>
|
||||
<EuiSplitPanel.Inner paddingSize="l">
|
||||
<EuiSpacer size="m" />
|
||||
<EuiTitle size="l">
|
||||
<h2>
|
||||
<FormattedMessage
|
||||
id="xpack.searchSynonyms.emptyPrompt.title"
|
||||
defaultMessage="Search with synonyms"
|
||||
/>
|
||||
</h2>
|
||||
</EuiTitle>
|
||||
<EuiSpacer size="m" />
|
||||
<EuiFlexGroup direction="column" gutterSize="m">
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiText size="m">
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.searchSynonyms.emptyPrompt.subtitle"
|
||||
defaultMessage="Improve search relevance by matching terms that express the same concept."
|
||||
/>
|
||||
</p>
|
||||
</EuiText>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<div>
|
||||
<EuiButton
|
||||
data-test-subj="searchSynonymsEmptyPromptGetStartedButton"
|
||||
color="primary"
|
||||
fill
|
||||
>
|
||||
<FormattedMessage
|
||||
id="xpack.searchSynonyms.emptyPrompt.getStartedButton"
|
||||
defaultMessage="Get started"
|
||||
/>
|
||||
</EuiButton>
|
||||
</div>
|
||||
</EuiFlexItem>
|
||||
<EuiHorizontalRule margin="m" />
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiFlexGrid columns={3} direction="row">
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiFlexGroup responsive={false} gutterSize="xs" direction="column">
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiFlexGroup responsive={false} gutterSize="s">
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiIcon type="check" />
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiTitle size="xxs">
|
||||
<h5>
|
||||
<FormattedMessage
|
||||
id="xpack.searchSynonyms.emptyPrompt.improveSearchRelevance.title"
|
||||
defaultMessage="Expand search coverage"
|
||||
/>
|
||||
</h5>
|
||||
</EuiTitle>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiText size="s" color="subdued">
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.searchSynonyms.emptyPrompt.improveSearchRelevance.description"
|
||||
defaultMessage="Include related terms your users actually use."
|
||||
/>
|
||||
</p>
|
||||
</EuiText>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiFlexGroup responsive={false} gutterSize="xs" direction="column">
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiFlexGroup responsive={false} gutterSize="s">
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiIcon type="check" />
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiTitle size="xxs">
|
||||
<h5>
|
||||
<FormattedMessage
|
||||
id="xpack.searchSynonyms.emptyPrompt.domainSpecific.title"
|
||||
defaultMessage="Match domain-specific terms"
|
||||
/>
|
||||
</h5>
|
||||
</EuiTitle>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiText size="s" color="subdued">
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.searchSynonyms.emptyPrompt.domainSpecific.description"
|
||||
defaultMessage="Connect industry terms with common search phrases."
|
||||
/>
|
||||
</p>
|
||||
</EuiText>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiFlexGroup responsive={false} gutterSize="xs" direction="column">
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiFlexGroup responsive={false} gutterSize="s">
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiIcon type="check" />
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiTitle size="xxs">
|
||||
<h5>
|
||||
<FormattedMessage
|
||||
id="xpack.searchSynonyms.emptyPrompt.improvePerformance.title"
|
||||
defaultMessage="Optimize performance"
|
||||
/>
|
||||
</h5>
|
||||
</EuiTitle>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiText size="s" color="subdued">
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.searchSynonyms.emptyPrompt.improvedPerformance.description"
|
||||
defaultMessage="Uses the built-in synonyms API for improved performance and flexibility."
|
||||
/>
|
||||
</p>
|
||||
</EuiText>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGrid>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiSplitPanel.Inner>
|
||||
<EuiSplitPanel.Inner color="subdued" paddingSize="l">
|
||||
<>
|
||||
<EuiTitle size="xxs">
|
||||
<span>
|
||||
<FormattedMessage
|
||||
id="xpack.searchSynonyms.emptyPrompt.footer"
|
||||
defaultMessage="Prefer to use the APIs?"
|
||||
/>
|
||||
</span>
|
||||
</EuiTitle>
|
||||
|
||||
<EuiLink
|
||||
data-test-subj="searchSynonymsEmptyPromptFooterLink"
|
||||
href={docLinks.synonymsApi}
|
||||
target="_blank"
|
||||
external
|
||||
>
|
||||
<FormattedMessage
|
||||
id="xpack.searchSynonyms.emptyPrompt.footerLink"
|
||||
defaultMessage="Synonyms API documentation"
|
||||
/>
|
||||
</EuiLink>
|
||||
</>
|
||||
</EuiSplitPanel.Inner>
|
||||
</EuiSplitPanel.Outer>
|
||||
</div>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
);
|
||||
};
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import React, { useMemo } from 'react';
|
||||
|
||||
import { KibanaPageTemplate } from '@kbn/shared-ux-page-kibana-template';
|
||||
import { useKibana } from '../../hooks/use_kibana';
|
||||
import { EmptyPrompt } from '../empty_prompt/empty_prompt';
|
||||
|
||||
export const SearchSynonymsOverview = () => {
|
||||
const {
|
||||
services: { console: consolePlugin, history, searchNavigation },
|
||||
} = useKibana();
|
||||
|
||||
const embeddableConsole = useMemo(
|
||||
() => (consolePlugin?.EmbeddableConsole ? <consolePlugin.EmbeddableConsole /> : null),
|
||||
[consolePlugin]
|
||||
);
|
||||
return (
|
||||
<KibanaPageTemplate
|
||||
offset={0}
|
||||
restrictWidth={false}
|
||||
grow={false}
|
||||
data-test-subj="searchSynonymsOverviewPage"
|
||||
solutionNav={searchNavigation?.useClassicNavigation(history)}
|
||||
>
|
||||
<EmptyPrompt />
|
||||
{embeddableConsole}
|
||||
</KibanaPageTemplate>
|
||||
);
|
||||
};
|
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { useKibana as _useKibana } from '@kbn/kibana-react-plugin/public';
|
||||
import { AppServicesContext } from '../types';
|
||||
|
||||
export const useKibana = () => _useKibana<AppServicesContext>();
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { CoreSetup, Plugin, AppMountParameters } from '@kbn/core/public';
|
||||
import type { CoreSetup, Plugin, AppMountParameters, CoreStart } from '@kbn/core/public';
|
||||
import { PLUGIN_ID, PLUGIN_NAME, PLUGIN_TITLE } from '../common';
|
||||
import {
|
||||
AppPluginSetupDependencies,
|
||||
|
@ -14,6 +14,7 @@ import {
|
|||
SearchSynonymsPluginStart,
|
||||
} from './types';
|
||||
import { SYNONYMS_UI_FLAG } from '../common/ui_flags';
|
||||
import { docLinks } from '../common/doc_links';
|
||||
|
||||
export class SearchSynonymsPlugin
|
||||
implements Plugin<SearchSynonymsPluginSetup, SearchSynonymsPluginStart>
|
||||
|
@ -60,7 +61,8 @@ export class SearchSynonymsPlugin
|
|||
return {};
|
||||
}
|
||||
|
||||
public start(): SearchSynonymsPluginStart {
|
||||
public start(core: CoreStart): SearchSynonymsPluginStart {
|
||||
docLinks.setDocLinks(core.docLinks.links);
|
||||
return {};
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
import { SearchNavigationPluginStart } from '@kbn/search-navigation/public';
|
||||
import { AppMountParameters } from '@kbn/core/public';
|
||||
import { AppMountParameters, CoreStart } from '@kbn/core/public';
|
||||
import type { ConsolePluginStart } from '@kbn/console-plugin/public';
|
||||
|
||||
export * from '../common/types';
|
||||
|
@ -15,3 +15,5 @@ export interface AppPluginStartDependencies {
|
|||
console?: ConsolePluginStart;
|
||||
searchNavigation?: SearchNavigationPluginStart;
|
||||
}
|
||||
|
||||
export type AppServicesContext = CoreStart & AppPluginStartDependencies;
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
"@kbn/console-plugin",
|
||||
"@kbn/features-plugin",
|
||||
"@kbn/search-navigation",
|
||||
"@kbn/doc-links",
|
||||
"@kbn/shared-ux-page-kibana-template",
|
||||
],
|
||||
"exclude": [
|
||||
"target/**/*",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue