[Ent. Search] Search experiences landing page (#143874)

* Scaffold plugin

* Layout

* Basic landing page layout

* Search experiences illustration

* [CI] Auto-commit changed files from 'node scripts/eslint --no-cache --fix'

* Test fixes

* More test fixes

* Use a different i18n key for the Search category

* Cleanup plugin primitives

* i18n

* Safe i18n

* [CI] Auto-commit changed files from 'node scripts/precommit_hook.js --ref HEAD~1..HEAD --fix'

* Test fixes

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Casey Zumwalt 2022-11-02 08:15:17 -05:00 committed by GitHub
parent 74472192ec
commit e8359390b9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
25 changed files with 2073 additions and 4 deletions

View file

@ -139,6 +139,7 @@ export const applicationUsageSchema = {
elasticsearch: commonSchema,
appSearch: commonSchema,
workplaceSearch: commonSchema,
searchExperiences: commonSchema,
graph: commonSchema,
logs: commonSchema,
metrics: commonSchema,

View file

@ -2622,6 +2622,137 @@
}
}
},
"searchExperiences": {
"properties": {
"appId": {
"type": "keyword",
"_meta": {
"description": "The application being tracked"
}
},
"viewId": {
"type": "keyword",
"_meta": {
"description": "Always `main`"
}
},
"clicks_total": {
"type": "long",
"_meta": {
"description": "General number of clicks in the application since we started counting them"
}
},
"clicks_7_days": {
"type": "long",
"_meta": {
"description": "General number of clicks in the application over the last 7 days"
}
},
"clicks_30_days": {
"type": "long",
"_meta": {
"description": "General number of clicks in the application over the last 30 days"
}
},
"clicks_90_days": {
"type": "long",
"_meta": {
"description": "General number of clicks in the application over the last 90 days"
}
},
"minutes_on_screen_total": {
"type": "float",
"_meta": {
"description": "Minutes the application is active and on-screen since we started counting them."
}
},
"minutes_on_screen_7_days": {
"type": "float",
"_meta": {
"description": "Minutes the application is active and on-screen over the last 7 days"
}
},
"minutes_on_screen_30_days": {
"type": "float",
"_meta": {
"description": "Minutes the application is active and on-screen over the last 30 days"
}
},
"minutes_on_screen_90_days": {
"type": "float",
"_meta": {
"description": "Minutes the application is active and on-screen over the last 90 days"
}
},
"views": {
"type": "array",
"items": {
"properties": {
"appId": {
"type": "keyword",
"_meta": {
"description": "The application being tracked"
}
},
"viewId": {
"type": "keyword",
"_meta": {
"description": "The application view being tracked"
}
},
"clicks_total": {
"type": "long",
"_meta": {
"description": "General number of clicks in the application sub view since we started counting them"
}
},
"clicks_7_days": {
"type": "long",
"_meta": {
"description": "General number of clicks in the active application sub view over the last 7 days"
}
},
"clicks_30_days": {
"type": "long",
"_meta": {
"description": "General number of clicks in the active application sub view over the last 30 days"
}
},
"clicks_90_days": {
"type": "long",
"_meta": {
"description": "General number of clicks in the active application sub view over the last 90 days"
}
},
"minutes_on_screen_total": {
"type": "float",
"_meta": {
"description": "Minutes the application sub view is active and on-screen since we started counting them."
}
},
"minutes_on_screen_7_days": {
"type": "float",
"_meta": {
"description": "Minutes the application is active and on-screen active application sub view over the last 7 days"
}
},
"minutes_on_screen_30_days": {
"type": "float",
"_meta": {
"description": "Minutes the application is active and on-screen active application sub view over the last 30 days"
}
},
"minutes_on_screen_90_days": {
"type": "float",
"_meta": {
"description": "Minutes the application is active and on-screen active application sub view over the last 90 days"
}
}
}
}
}
}
},
"graph": {
"properties": {
"appId": {

View file

@ -97,6 +97,26 @@ export const WORKPLACE_SEARCH_PLUGIN = {
SUPPORT_URL: 'https://discuss.elastic.co/c/enterprise-search/workplace-search/',
};
export const SEARCH_EXPERIENCES_PLUGIN = {
ID: 'searchExperiences',
NAME: i18n.translate('xpack.enterpriseSearch.searchExperiences.productName', {
defaultMessage: 'Enterprise Search',
}),
NAV_TITLE: i18n.translate('xpack.enterpriseSearch.searchExperiences.navTitle', {
defaultMessage: 'Search experiences',
}),
DESCRIPTION: i18n.translate('xpack.enterpriseSearch.searchExperiences.productDescription', {
defaultMessage: 'Build an intuitive, engaging search experience without reinventing the wheel.',
}),
URL: '/app/enterprise_search/search_experiences',
SUPPORT_URL: 'https://discuss.elastic.co/c/enterprise-search/',
GITHUB_URL: 'https://github.com/elastic/search-ui/',
DOCUMENTATION_URL: 'https://docs.elastic.co/search-ui/',
ELASTICSEARCH_TUTORIAL_URL: 'https://docs.elastic.co/search-ui/tutorials/elasticsearch',
APP_SEARCH_TUTORIAL_URL: 'https://docs.elastic.co/search-ui/tutorials/app-search',
WORKPLACE_SEARCH_TUTORIAL_URL: 'https://docs.elastic.co/search-ui/tutorials/workplace-search',
};
export const LICENSED_SUPPORT_URL = 'https://support.elastic.co';
export const JSON_HEADER = {

View file

@ -0,0 +1,8 @@
/*
* 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.
*/
export { EnterpriseSearchSearchExperiencesPageTemplate } from './page_template';

View file

@ -0,0 +1,77 @@
/*
* 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.
*/
jest.mock('../../../shared/layout/nav', () => ({
useEnterpriseSearchNav: () => [],
}));
import React from 'react';
import { shallow } from 'enzyme';
import { SetSearchExperiencesChrome } from '../../../shared/kibana_chrome';
import { EnterpriseSearchPageTemplateWrapper } from '../../../shared/layout';
import { SendEnterpriseSearchTelemetry } from '../../../shared/telemetry';
import { EnterpriseSearchSearchExperiencesPageTemplate } from './page_template';
describe('EnterpriseSearchSearchExperiencesPageTemplate', () => {
it('renders', () => {
const wrapper = shallow(
<EnterpriseSearchSearchExperiencesPageTemplate>
<div className="hello">world</div>
</EnterpriseSearchSearchExperiencesPageTemplate>
);
expect(wrapper.type()).toEqual(EnterpriseSearchPageTemplateWrapper);
expect(wrapper.prop('solutionNav')).toEqual({ name: 'Enterprise Search', items: [] });
expect(wrapper.find('.hello').text()).toEqual('world');
});
describe('page chrome', () => {
it('takes a breadcrumb array & renders a product-specific page chrome', () => {
const wrapper = shallow(
<EnterpriseSearchSearchExperiencesPageTemplate pageChrome={['Some page']} />
);
const setPageChrome = wrapper
.find(EnterpriseSearchPageTemplateWrapper)
.prop('setPageChrome') as any;
expect(setPageChrome.type).toEqual(SetSearchExperiencesChrome);
expect(setPageChrome.props.trail).toEqual(['Some page']);
});
});
describe('page telemetry', () => {
it('takes a metric & renders product-specific telemetry viewed event', () => {
const wrapper = shallow(
<EnterpriseSearchSearchExperiencesPageTemplate pageViewTelemetry="some_page" />
);
expect(wrapper.find(SendEnterpriseSearchTelemetry).prop('action')).toEqual('viewed');
expect(wrapper.find(SendEnterpriseSearchTelemetry).prop('metric')).toEqual('some_page');
});
});
describe('props', () => {
it('passes down any ...pageTemplateProps that EnterpriseSearchPageTemplateWrapper accepts', () => {
const wrapper = shallow(
<EnterpriseSearchSearchExperiencesPageTemplate
pageHeader={{ pageTitle: 'hello world' }}
isLoading={false}
emptyState={<div />}
/>
);
expect(
wrapper.find(EnterpriseSearchPageTemplateWrapper).prop('pageHeader')!.pageTitle
).toEqual('hello world');
expect(wrapper.find(EnterpriseSearchPageTemplateWrapper).prop('isLoading')).toEqual(false);
expect(wrapper.find(EnterpriseSearchPageTemplateWrapper).prop('emptyState')).toEqual(<div />);
});
});
});

View file

@ -0,0 +1,37 @@
/*
* 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 { SEARCH_EXPERIENCES_PLUGIN } from '../../../../../common/constants';
import { SetSearchExperiencesChrome } from '../../../shared/kibana_chrome';
import { EnterpriseSearchPageTemplateWrapper, PageTemplateProps } from '../../../shared/layout';
import { useEnterpriseSearchNav } from '../../../shared/layout';
import { SendEnterpriseSearchTelemetry } from '../../../shared/telemetry';
export const EnterpriseSearchSearchExperiencesPageTemplate: React.FC<PageTemplateProps> = ({
children,
pageChrome,
pageViewTelemetry,
...pageTemplateProps
}) => {
return (
<EnterpriseSearchPageTemplateWrapper
{...pageTemplateProps}
solutionNav={{
name: SEARCH_EXPERIENCES_PLUGIN.NAME,
items: useEnterpriseSearchNav(),
}}
setPageChrome={pageChrome && <SetSearchExperiencesChrome trail={pageChrome} />}
>
{pageViewTelemetry && (
<SendEnterpriseSearchTelemetry action="viewed" metric={pageViewTelemetry} />
)}
{children}
</EnterpriseSearchPageTemplateWrapper>
);
};

View file

@ -0,0 +1,8 @@
/*
* 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.
*/
export { SearchExperiencesGuide } from './search_experiences_guide';

View file

@ -0,0 +1,214 @@
/*
* 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 {
EuiFlexGroup,
EuiFlexItem,
EuiPanel,
EuiTitle,
EuiSpacer,
EuiText,
EuiButton,
EuiButtonEmpty,
EuiImage,
EuiHorizontalRule,
EuiCard,
EuiIcon,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
import { SEARCH_EXPERIENCES_PLUGIN } from '../../../../../common/constants';
import searchExperiencesIllustration from '../../../../assets/images/search_experiences.svg';
import { SetSearchExperiencesChrome as SetPageChrome } from '../../../shared/kibana_chrome';
import { EnterpriseSearchSearchExperiencesPageTemplate } from '../layout';
export const SearchExperiencesGuide: React.FC = () => {
return (
<EnterpriseSearchSearchExperiencesPageTemplate
restrictWidth
pageHeader={{
pageTitle: i18n.translate('xpack.enterpriseSearch.searchExperiences.guide.pageTitle', {
defaultMessage: 'Build a search experience with Search UI',
}),
}}
>
<SetPageChrome />
<EuiPanel color="transparent" paddingSize="none">
<EuiFlexGroup
className="addContentEmptyPrompt"
justifyContent="spaceBetween"
direction="row"
responsive
>
<EuiFlexItem grow>
<EuiFlexGroup direction="column" justifyContent="center" responsive={false}>
<EuiFlexItem grow={false}>
<EuiTitle>
<h2>About Search UI</h2>
</EuiTitle>
<EuiSpacer size="l" />
<EuiText grow={false}>
<p>
<FormattedMessage
id="xpack.enterpriseSearch.searchExperiences.guide.description"
defaultMessage="Search UI is a JavaScript library for implementing world-class search experiences without reinventing the wheel. It works out of the box with Elasticsearch, App Search, and Workplace Search, so you can focus on building the best experience for your users, customers, and employees."
/>
</p>
</EuiText>
</EuiFlexItem>
<EuiFlexItem>
<EuiFlexGroup>
<EuiFlexItem grow={false}>
<EuiButton
href={SEARCH_EXPERIENCES_PLUGIN.DOCUMENTATION_URL}
target="_blank"
color="primary"
fill
iconType={'popout'}
iconSide="right"
>
<FormattedMessage
id="xpack.enterpriseSearch.searchExperiences.guide.documentationLink"
defaultMessage="Visit the Search UI documentation"
/>
</EuiButton>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiButtonEmpty
href={SEARCH_EXPERIENCES_PLUGIN.GITHUB_URL}
target="_blank"
iconType={'popout'}
iconSide="right"
>
<FormattedMessage
id="xpack.enterpriseSearch.searchExperiences.guide.githubLink"
defaultMessage="Search UI on Github"
/>
</EuiButtonEmpty>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiTitle>
<h2>
<FormattedMessage
id="xpack.enterpriseSearch.searchExperiences.guide.featuresTitle"
defaultMessage="Features"
/>
</h2>
</EuiTitle>
<EuiSpacer size="l" />
<EuiText grow={false}>
<ul>
<li>
<FormattedMessage
id="xpack.enterpriseSearch.searchExperiences.guide.features.1"
defaultMessage="You know, for search. Elastic builds and maintains Search UI."
/>
</li>
<li>
<FormattedMessage
id="xpack.enterpriseSearch.searchExperiences.guide.features.2"
defaultMessage="Build a complete search experience quickly with a few lines of code."
/>
</li>
<li>
<FormattedMessage
id="xpack.enterpriseSearch.searchExperiences.guide.features.3"
defaultMessage="Search UI is highly customizable, so you can build the perfect search experience for your users."
/>
</li>
<li>
<FormattedMessage
id="xpack.enterpriseSearch.searchExperiences.guide.features.4"
defaultMessage="Searches, paging, filtering, and more, are captured in the URL for direct result linking."
/>
</li>
<li>
<FormattedMessage
id="xpack.enterpriseSearch.searchExperiences.guide.features.5"
defaultMessage="Not just for React. Use with any JavaScript library, even vanilla JavaScript."
/>
</li>
</ul>
</EuiText>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiImage
size="xl"
float="right"
src={searchExperiencesIllustration}
alt="Search experiences illustration"
/>
</EuiFlexItem>
</EuiFlexGroup>
<EuiHorizontalRule margin="xxl" />
<EuiTitle>
<h2>
<FormattedMessage
id="xpack.enterpriseSearch.searchExperiences.guide.tutorialsTitle"
defaultMessage="Get started quickly with a tutorial"
/>
</h2>
</EuiTitle>
<EuiSpacer size="xl" />
<EuiFlexGroup responsive>
<EuiFlexItem>
<EuiCard
icon={<EuiIcon size="xl" type="logoElasticsearch" />}
title="Elasticsearch"
description={i18n.translate(
'xpack.enterpriseSearch.searchExperiences.guide.tutorials.elasticsearch.description',
{
defaultMessage: 'Build a search experience with Elasticsearch and Search UI.',
}
)}
href={SEARCH_EXPERIENCES_PLUGIN.ELASTICSEARCH_TUTORIAL_URL}
target="_blank"
/>
</EuiFlexItem>
<EuiFlexItem>
<EuiCard
icon={<EuiIcon size="xl" type="logoAppSearch" />}
title="App Search"
description={i18n.translate(
'xpack.enterpriseSearch.searchExperiences.guide.tutorials.appSearch.description',
{
defaultMessage: 'Build a search experience with App Search and Search UI.',
}
)}
href={SEARCH_EXPERIENCES_PLUGIN.APP_SEARCH_TUTORIAL_URL}
target="_blank"
/>
</EuiFlexItem>
<EuiFlexItem>
<EuiCard
icon={<EuiIcon size="xl" type="logoWorkplaceSearch" />}
title="Workplace Search"
description={i18n.translate(
'xpack.enterpriseSearch.searchExperiences.guide.tutorials.workplaceSearch.description',
{
defaultMessage: 'Build a search experience with Workplace Search and Search UI.',
}
)}
href={SEARCH_EXPERIENCES_PLUGIN.WORKPLACE_SEARCH_TUTORIAL_URL}
target="_blank"
/>
</EuiFlexItem>
</EuiFlexGroup>
</EuiPanel>
</EnterpriseSearchSearchExperiencesPageTemplate>
);
};

View file

@ -0,0 +1,28 @@
/*
* 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 { setMockValues } from '../__mocks__/kea_logic';
import React from 'react';
import { shallow } from 'enzyme';
import { SearchExperiencesGuide } from './components/search_experiences_guide';
import { SearchExperiences } from '.';
describe('SearchExperiences', () => {
it('renders the Search Experiences guide', () => {
setMockValues({
errorConnectingMessage: '',
config: { host: 'localhost' },
});
const wrapper = shallow(<SearchExperiences />);
expect(wrapper.find(SearchExperiencesGuide)).toHaveLength(1);
});
});

View file

@ -0,0 +1,43 @@
/*
* 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 { Route, Switch } from 'react-router-dom';
import { isVersionMismatch } from '../../../common/is_version_mismatch';
import { InitialAppData } from '../../../common/types';
import { VersionMismatchPage } from '../shared/version_mismatch';
import { SearchExperiencesGuide } from './components/search_experiences_guide';
import { ROOT_PATH } from './routes';
export const SearchExperiences: React.FC<InitialAppData> = (props) => {
const { enterpriseSearchVersion, kibanaVersion } = props;
const incompatibleVersions = isVersionMismatch(enterpriseSearchVersion, kibanaVersion);
const showView = () => {
if (incompatibleVersions) {
return (
<VersionMismatchPage
enterpriseSearchVersion={enterpriseSearchVersion}
kibanaVersion={kibanaVersion}
/>
);
}
return <SearchExperiencesGuide />;
};
return (
<Switch>
<Route exact path={ROOT_PATH}>
{showView()}
</Route>
</Switch>
);
};

View file

@ -0,0 +1,8 @@
/*
* 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.
*/
export const ROOT_PATH = '/';

View file

@ -15,6 +15,7 @@ import {
APP_SEARCH_PLUGIN,
WORKPLACE_SEARCH_PLUGIN,
ENTERPRISE_SEARCH_CONTENT_PLUGIN,
SEARCH_EXPERIENCES_PLUGIN,
} from '../../../../common/constants';
import { stripLeadingSlash } from '../../../../common/strip_slashes';
@ -129,3 +130,9 @@ export const useEnterpriseSearchContentBreadcrumbs = (breadcrumbs: Breadcrumbs =
{ text: ENTERPRISE_SEARCH_CONTENT_PLUGIN.NAV_TITLE, path: '/' },
...breadcrumbs,
]);
export const useSearchExperiencesBreadcrumbs = (breadcrumbs: Breadcrumbs = []) =>
useEnterpriseSearchBreadcrumbs([
{ text: SEARCH_EXPERIENCES_PLUGIN.NAV_TITLE, path: '/' },
...breadcrumbs,
]);

View file

@ -10,6 +10,7 @@ import {
ANALYTICS_PLUGIN,
APP_SEARCH_PLUGIN,
WORKPLACE_SEARCH_PLUGIN,
SEARCH_EXPERIENCES_PLUGIN,
} from '../../../../common/constants';
/**
@ -43,3 +44,6 @@ export const appSearchTitle = (page: Title = []) =>
export const workplaceSearchTitle = (page: Title = []) =>
generateTitle([...page, WORKPLACE_SEARCH_PLUGIN.NAME]);
export const searchExperiencesTitle = (page: Title = []) =>
generateTitle([...page, SEARCH_EXPERIENCES_PLUGIN.NAME]);

View file

@ -12,4 +12,5 @@ export {
SetElasticsearchChrome,
SetAppSearchChrome,
SetWorkplaceSearchChrome,
SetSearchExperiencesChrome,
} from './set_chrome';

View file

@ -20,6 +20,7 @@ import {
useAppSearchBreadcrumbs,
useWorkplaceSearchBreadcrumbs,
BreadcrumbTrail,
useSearchExperiencesBreadcrumbs,
} from './generate_breadcrumbs';
import {
enterpriseSearchTitle,
@ -27,6 +28,7 @@ import {
elasticsearchTitle,
appSearchTitle,
workplaceSearchTitle,
searchExperiencesTitle,
} from './generate_title';
/**
@ -150,5 +152,22 @@ export const SetEnterpriseSearchContentChrome: React.FC<SetChromeProps> = ({ tra
return null;
};
export const SetSearchExperiencesChrome: React.FC<SetChromeProps> = ({ trail = [] }) => {
const { setBreadcrumbs, setDocTitle } = useValues(KibanaLogic);
const title = reverseArray(trail);
const docTitle = searchExperiencesTitle(title);
const crumbs = useGenerateBreadcrumbs(trail);
const breadcrumbs = useSearchExperiencesBreadcrumbs(crumbs);
useEffect(() => {
setBreadcrumbs(breadcrumbs);
setDocTitle(docTitle);
}, [trail]);
return null;
};
// Small util - performantly reverses an array without mutating the original array
const reverseArray = (array: string[]) => array.slice().reverse();

View file

@ -72,6 +72,11 @@ describe('useEnterpriseSearchContentNav', () => {
id: 'elasticsearch',
name: 'Elasticsearch',
},
{
href: '/app/enterprise_search/search_experiences',
id: 'searchExperiences',
name: 'Search Experiences',
},
{
href: '/app/enterprise_search/app_search',
id: 'app_search',
@ -108,6 +113,11 @@ describe('useEnterpriseSearchContentNav', () => {
id: 'elasticsearch',
name: 'Elasticsearch',
},
{
href: '/app/enterprise_search/search_experiences',
id: 'searchExperiences',
name: 'Search Experiences',
},
],
name: 'Search',
});
@ -129,6 +139,11 @@ describe('useEnterpriseSearchContentNav', () => {
id: 'elasticsearch',
name: 'Elasticsearch',
},
{
href: '/app/enterprise_search/search_experiences',
id: 'searchExperiences',
name: 'Search Experiences',
},
{
href: '/app/enterprise_search/workplace_search',
id: 'workplace_search',
@ -155,6 +170,11 @@ describe('useEnterpriseSearchContentNav', () => {
id: 'elasticsearch',
name: 'Elasticsearch',
},
{
href: '/app/enterprise_search/search_experiences',
id: 'searchExperiences',
name: 'Search Experiences',
},
{
href: '/app/enterprise_search/app_search',
id: 'app_search',

View file

@ -16,6 +16,7 @@ import {
ELASTICSEARCH_PLUGIN,
ENTERPRISE_SEARCH_CONTENT_PLUGIN,
ENTERPRISE_SEARCH_OVERVIEW_PLUGIN,
SEARCH_EXPERIENCES_PLUGIN,
WORKPLACE_SEARCH_PLUGIN,
} from '../../../../common/constants';
import { enableBehavioralAnalyticsSection } from '../../../../common/ui_settings_keys';
@ -106,6 +107,16 @@ export const useEnterpriseSearchNav = () => {
to: ELASTICSEARCH_PLUGIN.URL,
}),
},
{
id: 'searchExperiences',
name: i18n.translate('xpack.enterpriseSearch.nav.searchExperiencesTitle', {
defaultMessage: 'Search Experiences',
}),
...generateNavLink({
shouldNotCreateHref: true,
to: SEARCH_EXPERIENCES_PLUGIN.URL,
}),
},
...(productAccess.hasAppSearchAccess
? [
{
@ -135,7 +146,7 @@ export const useEnterpriseSearchNav = () => {
]
: []),
],
name: i18n.translate('xpack.enterpriseSearch.nav.searchExperiencesTitle', {
name: i18n.translate('xpack.enterpriseSearch.nav.searchTitle', {
defaultMessage: 'Search',
}),
},

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 410 KiB

View file

@ -30,6 +30,7 @@ import {
ENTERPRISE_SEARCH_CONTENT_PLUGIN,
ENTERPRISE_SEARCH_OVERVIEW_PLUGIN,
WORKPLACE_SEARCH_PLUGIN,
SEARCH_EXPERIENCES_PLUGIN,
} from '../common/constants';
import { InitialAppData } from '../common/types';
@ -215,6 +216,27 @@ export class EnterpriseSearchPlugin implements Plugin {
},
});
core.application.register({
id: SEARCH_EXPERIENCES_PLUGIN.ID,
title: SEARCH_EXPERIENCES_PLUGIN.NAME,
euiIconType: ENTERPRISE_SEARCH_OVERVIEW_PLUGIN.LOGO,
appRoute: SEARCH_EXPERIENCES_PLUGIN.URL,
category: DEFAULT_APP_CATEGORIES.enterpriseSearch,
mount: async (params: AppMountParameters) => {
const kibanaDeps = await this.getKibanaDeps(core, params, cloud);
const { chrome, http } = kibanaDeps.core;
chrome.docTitle.change(SEARCH_EXPERIENCES_PLUGIN.NAME);
await this.getInitialData(http);
const pluginData = this.getPluginData();
const { renderApp } = await import('./applications');
const { SearchExperiences } = await import('./applications/search_experiences');
return renderApp(SearchExperiences, kibanaDeps, pluginData);
},
});
if (plugins.home) {
plugins.home.featureCatalogue.registerSolution({
id: ENTERPRISE_SEARCH_OVERVIEW_PLUGIN.ID,
@ -266,6 +288,16 @@ export class EnterpriseSearchPlugin implements Plugin {
category: 'data',
showOnHomePage: false,
});
plugins.home.featureCatalogue.register({
id: SEARCH_EXPERIENCES_PLUGIN.ID,
title: SEARCH_EXPERIENCES_PLUGIN.NAME,
icon: 'logoEnterpriseSearch',
description: SEARCH_EXPERIENCES_PLUGIN.DESCRIPTION,
path: SEARCH_EXPERIENCES_PLUGIN.URL,
category: 'data',
showOnHomePage: false,
});
}
}

View file

@ -30,6 +30,7 @@ import {
ANALYTICS_PLUGIN,
APP_SEARCH_PLUGIN,
WORKPLACE_SEARCH_PLUGIN,
SEARCH_EXPERIENCES_PLUGIN,
ENTERPRISE_SEARCH_RELEVANCE_LOGS_SOURCE_ID,
ENTERPRISE_SEARCH_AUDIT_LOGS_SOURCE_ID,
ENTERPRISE_SEARCH_ANALYTICS_LOGS_SOURCE_ID,
@ -110,6 +111,7 @@ export class EnterpriseSearchPlugin implements Plugin {
ANALYTICS_PLUGIN.ID,
APP_SEARCH_PLUGIN.ID,
WORKPLACE_SEARCH_PLUGIN.ID,
SEARCH_EXPERIENCES_PLUGIN.ID,
];
if (customIntegrations) {
@ -158,6 +160,7 @@ export class EnterpriseSearchPlugin implements Plugin {
elasticsearch: showEnterpriseSearch,
appSearch: hasAppSearchAccess,
workplaceSearch: hasWorkplaceSearchAccess,
searchExperiences: showEnterpriseSearch,
},
catalogue: {
enterpriseSearch: showEnterpriseSearch,
@ -166,6 +169,7 @@ export class EnterpriseSearchPlugin implements Plugin {
elasticsearch: showEnterpriseSearch,
appSearch: hasAppSearchAccess,
workplaceSearch: hasWorkplaceSearchAccess,
searchExperiences: showEnterpriseSearch,
},
};
});

View file

@ -11678,7 +11678,7 @@
"xpack.enterpriseSearch.nav.contentTitle": "Contenu",
"xpack.enterpriseSearch.nav.elasticsearchTitle": "Elasticsearch",
"xpack.enterpriseSearch.nav.enterpriseSearchOverviewTitle": "Aperçu",
"xpack.enterpriseSearch.nav.searchExperiencesTitle": "Recherche",
"xpack.enterpriseSearch.nav.searchTitle": "Recherche",
"xpack.enterpriseSearch.nav.searchIndicesTitle": "Index",
"xpack.enterpriseSearch.nav.workplaceSearchTitle": "Workplace Search",
"xpack.enterpriseSearch.notFound.action1": "Retour à votre tableau de bord",

View file

@ -11664,7 +11664,7 @@
"xpack.enterpriseSearch.nav.contentTitle": "コンテンツ",
"xpack.enterpriseSearch.nav.elasticsearchTitle": "Elasticsearch",
"xpack.enterpriseSearch.nav.enterpriseSearchOverviewTitle": "概要",
"xpack.enterpriseSearch.nav.searchExperiencesTitle": "検索",
"xpack.enterpriseSearch.nav.searchTitle": "検索",
"xpack.enterpriseSearch.nav.searchIndicesTitle": "インデックス",
"xpack.enterpriseSearch.nav.workplaceSearchTitle": "Workplace Search",
"xpack.enterpriseSearch.notFound.action1": "ダッシュボードに戻す",

View file

@ -11683,7 +11683,7 @@
"xpack.enterpriseSearch.nav.contentTitle": "内容",
"xpack.enterpriseSearch.nav.elasticsearchTitle": "Elasticsearch",
"xpack.enterpriseSearch.nav.enterpriseSearchOverviewTitle": "概览",
"xpack.enterpriseSearch.nav.searchExperiencesTitle": "搜索",
"xpack.enterpriseSearch.nav.searchTitle": "搜索",
"xpack.enterpriseSearch.nav.searchIndicesTitle": "索引",
"xpack.enterpriseSearch.nav.workplaceSearchTitle": "Workplace Search",
"xpack.enterpriseSearch.notFound.action1": "返回到您的仪表板",

View file

@ -68,6 +68,7 @@ export default function catalogueTests({ getService }: FtrProviderContext) {
'elasticsearch',
'appSearch',
'workplaceSearch',
'searchExperiences',
'spaces',
...esFeatureExceptions,
];
@ -94,6 +95,7 @@ export default function catalogueTests({ getService }: FtrProviderContext) {
'elasticsearch',
'appSearch',
'workplaceSearch',
'searchExperiences',
'spaces',
...esFeatureExceptions,
];

View file

@ -32,6 +32,7 @@ export default function catalogueTests({ getService }: FtrProviderContext) {
'elasticsearch',
'appSearch',
'workplaceSearch',
'searchExperiences',
];
describe('catalogue', () => {