mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
[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:
parent
74472192ec
commit
e8359390b9
25 changed files with 2073 additions and 4 deletions
|
@ -139,6 +139,7 @@ export const applicationUsageSchema = {
|
|||
elasticsearch: commonSchema,
|
||||
appSearch: commonSchema,
|
||||
workplaceSearch: commonSchema,
|
||||
searchExperiences: commonSchema,
|
||||
graph: commonSchema,
|
||||
logs: commonSchema,
|
||||
metrics: commonSchema,
|
||||
|
|
|
@ -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": {
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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';
|
|
@ -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 />);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -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>
|
||||
);
|
||||
};
|
|
@ -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';
|
|
@ -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>
|
||||
);
|
||||
};
|
|
@ -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);
|
||||
});
|
||||
});
|
|
@ -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>
|
||||
);
|
||||
};
|
|
@ -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 = '/';
|
|
@ -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,
|
||||
]);
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -12,4 +12,5 @@ export {
|
|||
SetElasticsearchChrome,
|
||||
SetAppSearchChrome,
|
||||
SetWorkplaceSearchChrome,
|
||||
SetSearchExperiencesChrome,
|
||||
} from './set_chrome';
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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 |
|
@ -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,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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": "ダッシュボードに戻す",
|
||||
|
|
|
@ -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": "返回到您的仪表板",
|
||||
|
|
|
@ -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,
|
||||
];
|
||||
|
|
|
@ -32,6 +32,7 @@ export default function catalogueTests({ getService }: FtrProviderContext) {
|
|||
'elasticsearch',
|
||||
'appSearch',
|
||||
'workplaceSearch',
|
||||
'searchExperiences',
|
||||
];
|
||||
|
||||
describe('catalogue', () => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue