diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/elasticsearch_card/elasticsearch_card.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/elasticsearch_card/elasticsearch_card.tsx index 0283249ac2890..fd84267ebb8e4 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/elasticsearch_card/elasticsearch_card.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/elasticsearch_card/elasticsearch_card.tsx @@ -11,9 +11,9 @@ import { EuiPanel, EuiFlexGroup, EuiFlexItem, EuiText, EuiTitle, EuiSpacer } fro import { i18n } from '@kbn/i18n'; +import { ElasticsearchResources } from '../../../shared/elasticsearch_resources'; import { EuiButtonTo } from '../../../shared/react_router_helpers'; import { ELASTICSEARCH_GUIDE_PATH } from '../../routes'; -import { ElasticsearchResources } from '../elasticsearch_resources'; export const ElasticsearchCard: React.FC = () => { return ( diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/elasticsearch_guide/elasticsearch_guide.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/elasticsearch_guide/elasticsearch_guide.tsx index fb1bc7a2820e2..d722cfd637cce 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/elasticsearch_guide/elasticsearch_guide.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/elasticsearch_guide/elasticsearch_guide.tsx @@ -24,10 +24,10 @@ import { import { i18n } from '@kbn/i18n'; import { docLinks } from '../../../shared/doc_links'; +import { ElasticsearchResources } from '../../../shared/elasticsearch_resources'; import { ElasticsearchClientInstructions } from '../elasticsearch_client_instructions'; import { ElasticsearchCloudId } from '../elasticsearch_cloud_id'; -import { ElasticsearchResources } from '../elasticsearch_resources'; // Replace FormattedMessage with i18n strings diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/layout/index.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/layout/index.ts index 09a1e910fbbda..ea69823f82b87 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/layout/index.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/layout/index.ts @@ -7,3 +7,4 @@ export { useEnterpriseSearchOverviewNav } from './nav'; export { EnterpriseSearchOverviewPageTemplate } from './page_template'; +export { EnterpriseSearchOverviewHeaderActions } from './kibana_header_actions'; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/layout/kibana_header_actions.test.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/layout/kibana_header_actions.test.tsx new file mode 100644 index 0000000000000..88f5da60e3627 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/layout/kibana_header_actions.test.tsx @@ -0,0 +1,34 @@ +/* + * 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 { mount } from 'enzyme'; + +import { EuiPopover, EuiButtonEmpty } from '@elastic/eui'; + +import { EnterpriseSearchOverviewHeaderActions } from './kibana_header_actions'; + +describe('Enterprise Search overview HeaderActions', () => { + it('renders', () => { + const wrapper = mount(); + const popover = wrapper.find(EuiPopover); + + expect(popover.find(EuiButtonEmpty).text()).toContain('Deployment details'); + expect(popover.prop('isOpen')).toBeFalsy(); + }); + + it('opens popover when clicked', () => { + const wrapper = mount(); + + expect(wrapper.find(EuiPopover).prop('isOpen')).toBeFalsy(); + wrapper.find(EuiPopover).find(EuiButtonEmpty).simulate('click'); + wrapper.update(); + + expect(wrapper.find(EuiPopover).prop('isOpen')).toBeTruthy(); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/layout/kibana_header_actions.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/layout/kibana_header_actions.tsx new file mode 100644 index 0000000000000..0383618ecf87b --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/layout/kibana_header_actions.tsx @@ -0,0 +1,115 @@ +/* + * 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, { useState } from 'react'; + +import { + EuiHeaderLinks, + EuiIcon, + EuiCopy, + EuiButton, + EuiButtonEmpty, + EuiButtonIcon, + EuiPopover, + EuiFormRow, + EuiFieldText, + EuiFlexGroup, + EuiFlexItem, + EuiSpacer, + EuiPopoverTitle, + EuiPopoverFooter, + EuiText, +} from '@elastic/eui'; + +import { i18n } from '@kbn/i18n'; + +export const EnterpriseSearchOverviewHeaderActions: React.FC = () => { + const [isPopoverOpen, setIsPopoverOpen] = useState(false); + // TODO change it with actual value + // TODO make this conditional only for users on cloud, as on-prem users will not have a deployment id to show. + const clientId = 'fgdshjafghj13eshfdjag718yfhjdskf'; + + return ( + + setIsPopoverOpen(!isPopoverOpen)}> + +   + {i18n.translate('xpack.enterpriseSearch.overview.deploymentDetails', { + defaultMessage: 'Deployment details', + })} + + } + isOpen={isPopoverOpen} + closePopover={() => setIsPopoverOpen(false)} + > + + {i18n.translate('xpack.enterpriseSearch.overview.deploymentDetails', { + defaultMessage: 'Deployment details', + })} + + +

+ {i18n.translate('xpack.enterpriseSearch.overview.deploymentDetails.description', { + defaultMessage: + 'Send data to Elastic from your applications by referencing your deployment and Elasticsearch information.', + })} +

+
+ + + + + + + + + {(copy) => ( + + )} + + + + + + {/* TODO need link to Create and manage API keys*/} + + {i18n.translate('xpack.enterpriseSearch.overview.createAndManageButton', { + defaultMessage: 'Create and manage API keys', + })} + + +
+
+ ); +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/overview_content/index.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/overview_content/index.ts new file mode 100644 index 0000000000000..83d1f526c36cb --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/overview_content/index.ts @@ -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 { OverviewContent } from './overview_content'; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/overview_content/overview_content.test.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/overview_content/overview_content.test.tsx new file mode 100644 index 0000000000000..53c31eaf0498a --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/overview_content/overview_content.test.tsx @@ -0,0 +1,73 @@ +/* + * 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 { EuiEmptyPrompt } from '@elastic/eui'; + +import { AddContentEmptyPrompt } from '../../../shared/add_content_empty_prompt'; +import { GettingStartedSteps } from '../../../shared/getting_started_steps'; + +import { LicenseCallout } from '../license_callout'; +import { SetupGuideCta } from '../setup_guide'; +import { TrialCallout } from '../trial_callout'; + +import { OverviewContent } from '.'; + +describe('OverviewContent', () => { + const props = { + access: {}, + isWorkplaceSearchAdmin: true, + }; + + it('renders the overview page, Getting Started steps & setup guide CTAs with no host set', () => { + setMockValues({ config: { host: '' } }); + const wrapper = shallow(); + + expect(wrapper.find(GettingStartedSteps)).toHaveLength(1); + expect(wrapper.find(AddContentEmptyPrompt)).toHaveLength(1); + expect(wrapper.find(SetupGuideCta)).toHaveLength(1); + expect(wrapper.find(LicenseCallout)).toHaveLength(0); + }); + + it('renders the trial callout', () => { + setMockValues({ config: { host: 'localhost' } }); + const wrapper = shallow(); + + expect(wrapper.find(TrialCallout)).toHaveLength(1); + }); + + // TODO Refactor this and other tests according to the search indices permissions + describe('access checks when host is set', () => { + beforeEach(() => { + setMockValues({ config: { host: 'localhost' } }); + }); + + it('renders the license callout when user has access to a product', () => { + setMockValues({ config: { host: 'localhost' } }); + const wrapper = shallow( + + ); + + expect(wrapper.find(LicenseCallout)).toHaveLength(1); + }); + + it('renders empty prompt and overview or license callout if the user does not have access', () => { + const wrapper = shallow(); + + expect(wrapper.find(EuiEmptyPrompt)).toHaveLength(1); + expect(wrapper.find(GettingStartedSteps)).toHaveLength(0); + expect(wrapper.find(AddContentEmptyPrompt)).toHaveLength(0); + expect(wrapper.find(LicenseCallout)).toHaveLength(0); + expect(wrapper.find(SetupGuideCta)).toHaveLength(0); + }); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/overview_content/overview_content.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/overview_content/overview_content.tsx new file mode 100644 index 0000000000000..3824a09a0bc1c --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/overview_content/overview_content.tsx @@ -0,0 +1,159 @@ +/* + * 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 { useValues } from 'kea'; + +import { + EuiButton, + EuiEmptyPrompt, + EuiFlexGroup, + EuiFlexItem, + EuiImage, + EuiLink, + EuiPageBody, + EuiSpacer, + EuiTitle, +} from '@elastic/eui'; +import { Chat } from '@kbn/cloud-plugin/public'; +import { i18n } from '@kbn/i18n'; + +import { AddContentEmptyPrompt } from '../../../shared/add_content_empty_prompt'; +import { docLinks } from '../../../shared/doc_links'; +import { ElasticsearchResources } from '../../../shared/elasticsearch_resources'; +import { GettingStartedSteps } from '../../../shared/getting_started_steps'; +import { KibanaLogic } from '../../../shared/kibana'; +import { SetEnterpriseSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome'; +import { SendEnterpriseSearchTelemetry as SendTelemetry } from '../../../shared/telemetry'; + +import { EnterpriseSearchOverviewPageTemplate } from '../layout'; +import { LicenseCallout } from '../license_callout'; +import illustration from '../product_selector/lock_light.svg'; +import { SetupGuideCta } from '../setup_guide'; + +import { TrialCallout } from '../trial_callout'; + +interface OverviewContentProps { + access: { + hasAppSearchAccess?: boolean; + hasWorkplaceSearchAccess?: boolean; + }; + isWorkplaceSearchAdmin: boolean; +} + +export const OverviewContent: React.FC = ({ access }) => { + const { hasAppSearchAccess, hasWorkplaceSearchAccess } = access; + const { config } = useValues(KibanaLogic); + + // TODO Refactor this and the tests according to the search indices permissions + // If Enterprise Search has been set up and the user does not have access to either product, show a message saying they + // need to contact an administrator to get access to one of the products. + const shouldShowEnterpriseSearchOverview = + !config.host || hasAppSearchAccess || hasWorkplaceSearchAccess; + + const enterpriseSearchOverview = ( + <> + + + + + + + + + + + + + {config.host ? : } + + ); + + const insufficientAccessMessage = ( + + } + title={ +

+ {i18n.translate('xpack.enterpriseSearch.overviewContent.insufficientPermissionsTitle', { + defaultMessage: 'Insufficient permissions', + })} +

+ } + layout="horizontal" + color="plain" + body={ + <> +

+ {i18n.translate('xpack.enterpriseSearch.overviewContent.insufficientPermissionsBody', { + defaultMessage: + 'You don’t have access to view this page. If you feel this may be an error, please contact your administrator.', + })} +

+ + } + actions={ + + {i18n.translate( + 'xpack.enterpriseSearch.overviewContent.insufficientPermissionsButtonLabel', + { + defaultMessage: 'Go to the Kibana dashboard', + } + )} + + } + footer={ + <> + + + {i18n.translate( + 'xpack.enterpriseSearch.overviewContent.insufficientPermissionsFooterBody', + { + defaultMessage: 'Go to the Kibana dashboard', + } + )} + + {' '} + + {i18n.translate( + 'xpack.enterpriseSearch.overviewContent.insufficientPermissionsFooterLinkLabel', + { + defaultMessage: 'Read documentation', + } + )} + + + } + /> + ); + return ( + + + + + + {shouldShowEnterpriseSearchOverview ? enterpriseSearchOverview : insufficientAccessMessage} + + + + ); +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/add_content_empty_prompt/add_content_empty_prompt.scss b/x-pack/plugins/enterprise_search/public/applications/shared/add_content_empty_prompt/add_content_empty_prompt.scss new file mode 100644 index 0000000000000..c0fafb151174d --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/shared/add_content_empty_prompt/add_content_empty_prompt.scss @@ -0,0 +1,7 @@ +.addContentEmptyPrompt { + @include euiBreakpoint('xs','s') { + flex-direction: column-reverse; + } + + border-bottom: $euiBorderThin; +} diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/add_content_empty_prompt/add_content_empty_prompt.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/add_content_empty_prompt/add_content_empty_prompt.test.tsx new file mode 100644 index 0000000000000..b9e23f00f06b5 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/shared/add_content_empty_prompt/add_content_empty_prompt.test.tsx @@ -0,0 +1,29 @@ +/* + * 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 { shallow, ShallowWrapper } from 'enzyme'; + +import { EuiLinkTo } from '../react_router_helpers'; + +import { AddContentEmptyPrompt } from '.'; + +describe('AddContentEmptyPrompt', () => { + let wrapper: ShallowWrapper; + + beforeAll(() => { + wrapper = shallow(); + }); + + it('renders', () => { + expect(wrapper.find('h2').text()).toEqual('Add content to Enterprise Search'); + expect(wrapper.find(EuiLinkTo).prop('to')).toEqual( + '/app/enterprise_search/content/search_indices' + ); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/add_content_empty_prompt/add_content_empty_prompt.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/add_content_empty_prompt/add_content_empty_prompt.tsx new file mode 100644 index 0000000000000..0679739a7683c --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/shared/add_content_empty_prompt/add_content_empty_prompt.tsx @@ -0,0 +1,96 @@ +/* + * 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 { generatePath } from 'react-router-dom'; + +import { + EuiImage, + EuiFlexGroup, + EuiFlexItem, + EuiButton, + EuiLink, + EuiPanel, + EuiTitle, + EuiText, + EuiSpacer, +} from '@elastic/eui'; + +import { i18n } from '@kbn/i18n'; + +import { ENTERPRISE_SEARCH_CONTENT_PLUGIN } from '../../../../common/constants'; +import { SEARCH_INDICES_PATH } from '../../enterprise_search_content/routes'; +import { EuiLinkTo } from '../react_router_helpers'; + +import searchIndicesIllustration from './search_indices.svg'; +import './add_content_empty_prompt.scss'; + +export const AddContentEmptyPrompt: React.FC = () => { + return ( + + + + + + +

+ {i18n.translate('xpack.enterpriseSearch.overview.emptyState.heading', { + defaultMessage: 'Add content to Enterprise Search', + })} +

+
+ + +

+ {i18n.translate('xpack.enterpriseSearch.emptyState.description', { + defaultMessage: + "Data you add in Enterprise Search is called a Search index and it's searchable in both App and Workplace Search. Now you can use your connectors in App Search and your web crawlers in Workplace Search.", + })} +

+
+
+ + + + + + {i18n.translate('xpack.enterpriseSearch.overview.emptyState.buttonTitle', { + defaultMessage: 'Add content to Enterprise Search', + })} + + + + + {/* TODO need link for Learn More link*/} + + {i18n.translate('xpack.enterpriseSearch.overview.emptyState.footerLinkTitle', { + defaultMessage: 'Learn more', + })} + + + + +
+
+ + + +
+
+ ); +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/add_content_empty_prompt/index.ts b/x-pack/plugins/enterprise_search/public/applications/shared/add_content_empty_prompt/index.ts new file mode 100644 index 0000000000000..1ae85c30a2f5c --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/shared/add_content_empty_prompt/index.ts @@ -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 { AddContentEmptyPrompt } from './add_content_empty_prompt'; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/product_selector/search_indices.svg b/x-pack/plugins/enterprise_search/public/applications/shared/add_content_empty_prompt/search_indices.svg similarity index 100% rename from x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/product_selector/search_indices.svg rename to x-pack/plugins/enterprise_search/public/applications/shared/add_content_empty_prompt/search_indices.svg diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/elasticsearch_resources/elasticsearch_resources.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/elasticsearch_resources/elasticsearch_resources.test.tsx new file mode 100644 index 0000000000000..3dd3b1c8ddfac --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/shared/elasticsearch_resources/elasticsearch_resources.test.tsx @@ -0,0 +1,47 @@ +/* + * 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('../doc_links', () => ({ + docLinks: { + elasticsearchGettingStarted: 'elasticsearchGettingStarted-link', + elasticsearchCreateIndex: 'elasticsearchCreateIndex-link', + clientsGuide: 'elasticsearchClientsGuide-link', + }, +})); +import React from 'react'; + +import { shallow, ShallowWrapper } from 'enzyme'; + +import { EuiLink } from '@elastic/eui'; + +import { ElasticsearchResources } from '.'; + +describe('ElasticsearchResources', () => { + let wrapper: ShallowWrapper; + + beforeAll(() => { + wrapper = shallow(); + }); + + it('renders', () => { + expect(wrapper.find('h4').text()).toEqual('Resources'); + + expect(wrapper.find(EuiLink).at(0).prop('href')).toEqual('elasticsearchGettingStarted-link'); + expect(wrapper.find(EuiLink).at(0).text()).toEqual('Getting started with Elasticsearch'); + + expect(wrapper.find(EuiLink).at(1).prop('href')).toEqual('elasticsearchCreateIndex-link'); + expect(wrapper.find(EuiLink).at(1).text()).toEqual('Create a new index'); + + expect(wrapper.find(EuiLink).at(2).prop('href')).toEqual('elasticsearchClientsGuide-link'); + expect(wrapper.find(EuiLink).at(2).text()).toEqual('Setup a language client'); + + expect(wrapper.find(EuiLink).at(3).prop('href')).toEqual( + 'https://github.com/elastic/search-ui/tree/master/packages/search-ui-elasticsearch-connector' + ); + expect(wrapper.find(EuiLink).at(3).text()).toEqual('Search UI for Elasticsearch'); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/elasticsearch_resources/elasticsearch_resources.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/elasticsearch_resources/elasticsearch_resources.tsx similarity index 92% rename from x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/elasticsearch_resources/elasticsearch_resources.tsx rename to x-pack/plugins/enterprise_search/public/applications/shared/elasticsearch_resources/elasticsearch_resources.tsx index b7d0390f40077..6a274e75179b1 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/elasticsearch_resources/elasticsearch_resources.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/elasticsearch_resources/elasticsearch_resources.tsx @@ -10,10 +10,10 @@ import React from 'react'; import { EuiSpacer, EuiPanel, EuiTitle, EuiLink } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { docLinks } from '../../../shared/doc_links'; +import { docLinks } from '../doc_links'; export const ElasticsearchResources: React.FC = () => ( - +

{i18n.translate('xpack.enterpriseSearch.overview.elasticsearchResources.title', { @@ -40,7 +40,7 @@ export const ElasticsearchResources: React.FC = () => ( {i18n.translate( 'xpack.enterpriseSearch.overview.elasticsearchResources.elasticsearchClients', - { defaultMessage: 'Elasticsearch clients' } + { defaultMessage: 'Setup a language client' } )} diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/elasticsearch_resources/index.ts b/x-pack/plugins/enterprise_search/public/applications/shared/elasticsearch_resources/index.ts similarity index 100% rename from x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/elasticsearch_resources/index.ts rename to x-pack/plugins/enterprise_search/public/applications/shared/elasticsearch_resources/index.ts diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/getting_started_steps/getting_started_steps.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/getting_started_steps/getting_started_steps.test.tsx new file mode 100644 index 0000000000000..0595e39475b4b --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/shared/getting_started_steps/getting_started_steps.test.tsx @@ -0,0 +1,56 @@ +/* + * 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('../doc_links', () => ({ + docLinks: { + elasticsearchGettingStarted: 'elasticsearchGettingStarted-link', + elasticsearchCreateIndex: 'elasticsearchCreateIndex-link', + clientsGuide: 'elasticsearchClientsGuide-link', + }, +})); +import React from 'react'; + +import { shallow, ShallowWrapper } from 'enzyme'; + +import { EuiSteps } from '@elastic/eui'; + +import { EuiLinkTo } from '../react_router_helpers'; + +import { IconRow } from './icon_row'; + +import { GettingStartedSteps } from '.'; + +describe('GettingStartedSteps', () => { + let wrapper: ShallowWrapper; + + beforeAll(() => { + wrapper = shallow(); + }); + + it('renders', () => { + const steps = wrapper + .find(EuiSteps) + .prop('steps') + .map(({ title, children, status, ...rest }) => ({ + title, + status, + children: shallow(
{children}
), + ...rest, + })); + + expect(steps[0].title).toEqual('Add your documents and data to Enterprise Search'); + expect(steps[0].status).toEqual('current'); + expect(steps[0].children.find(IconRow).length).toEqual(1); + + expect(steps[1].title).toEqual('Build a search experience'); + expect(steps[1].status).toEqual('incomplete'); + expect(steps[1].children.find(EuiLinkTo).prop('to')).toEqual('/elasticsearch_guide'); + + expect(steps[2].title).toEqual('Tune your search relevance'); + expect(steps[2].status).toEqual('incomplete'); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/getting_started_steps/getting_started_steps.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/getting_started_steps/getting_started_steps.tsx new file mode 100644 index 0000000000000..e9a3f477c7049 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/shared/getting_started_steps/getting_started_steps.tsx @@ -0,0 +1,181 @@ +/* + * 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, { useState } from 'react'; + +import { + EuiButton, + EuiFlexGroup, + EuiFlexItem, + EuiIcon, + EuiPopover, + EuiSpacer, + EuiSteps, + EuiText, + EuiContextMenuPanel, + EuiContextMenuItem, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; + +import { ELASTICSEARCH_GUIDE_PATH } from '../../enterprise_search_overview/routes'; + +import { EuiLinkTo } from '../react_router_helpers'; + +import { IconRow } from './icon_row'; + +export const GettingStartedSteps: React.FC = () => { + // TODO replace with logic file + const [isPopoverOpen, setIsPopoverOpen] = useState(false); + + return ( + + + + +

+ {i18n.translate( + 'xpack.enterpriseSearch.overview.gettingStartedSteps.addData.message', + { + defaultMessage: + 'Get started by adding your data to Enterprise Search. You can use the Elastic Web Crawler, API endpoints, existing Elasticsearch indices or third party connectors like Google Drive, Microsoft Sharepoint and more.', + } + )} +

+
+ + + + ), + status: 'current', + }, + { + title: i18n.translate( + 'xpack.enterpriseSearch.overview.gettingStartedSteps.buildSearchExperience.title', + { defaultMessage: 'Build a search experience' } + ), + children: ( + <> + +

+ {i18n.translate( + 'xpack.enterpriseSearch.overview.gettingStartedSteps.buildSearchExperience.message', + { + defaultMessage: + 'You can use Search Engines to build customized search experiences for your customers or internal teams with App Search or Workplace Search. Or you can use Search UI to connect directly to an Elasticsearch index to build client-side search experinces for your users.', + } + )} +

+
+ + + + setIsPopoverOpen(!isPopoverOpen)} + > + {i18n.translate( + 'xpack.enterpriseSearch.overview.gettingStartedSteps.createASearchEngineButton', + { defaultMessage: 'Create a search engine' } + )} + + } + isOpen={isPopoverOpen} + closePopover={() => setIsPopoverOpen(false)} + > + {/* TODO add onclick for these links*/} + {}}> + +

+ {i18n.translate( + 'xpack.enterpriseSearch.overview.gettingStartedSteps.createAppSearchEngine.title', + { defaultMessage: 'Create an App Search engine' } + )} +

+ {i18n.translate( + 'xpack.enterpriseSearch.overview.gettingStartedSteps.createAppSearchEngine.description', + { + defaultMessage: + 'All the power of Elasticsearch, without the learning curve.', + } + )} +
+ , + {}}> + +

+ {i18n.translate( + 'xpack.enterpriseSearch.overview.gettingStartedSteps.createWorkplaceSearchGroup.title', + { defaultMessage: 'Create a Workplace Search group' } + )} +

+ {i18n.translate( + 'xpack.enterpriseSearch.overview.gettingStartedSteps.createWorkplaceSearchGroup.description', + { + defaultMessage: 'A secure search experience for internal teams', + } + )} +
+
, + ]} + /> +
+
+ + + +   + {i18n.translate( + 'xpack.enterpriseSearch.overview.gettingStartedSteps.searchWithElasticsearchLink', + { defaultMessage: 'Search with the Elasticsearch API' } + )} + + +
+ + ), + status: 'incomplete', + }, + { + title: i18n.translate( + 'xpack.enterpriseSearch.overview.gettingStartedSteps.tuneSearchExperience.title', + { defaultMessage: 'Tune your search relevance' } + ), + children: ( + +

+ {i18n.translate( + 'xpack.enterpriseSearch.overview.gettingStartedSteps.tuneSearchExperience.message', + { + defaultMessage: + "Dive into analytics and tune the result settings to help your users find exactly what they're looking for", + } + )} +

+
+ ), + status: 'incomplete', + }, + ]} + /> +
+
+ ); +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/getting_started_steps/icon_row.scss b/x-pack/plugins/enterprise_search/public/applications/shared/getting_started_steps/icon_row.scss new file mode 100644 index 0000000000000..6992cdead2803 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/shared/getting_started_steps/icon_row.scss @@ -0,0 +1,13 @@ +.gettingStartedSteps { + .grayscaleSvg { + filter: grayscale(1); + } + + .addManyMoreButton { + border: $euiBorderThin; + } + + .iconTooltip { + border-bottom: $euiBorderThin; + } +} diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/getting_started_steps/icon_row.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/getting_started_steps/icon_row.tsx new file mode 100644 index 0000000000000..8ae50183914d3 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/shared/getting_started_steps/icon_row.tsx @@ -0,0 +1,115 @@ +/* + * 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, EuiIcon, EuiBadge, EuiToolTip, EuiText } from '@elastic/eui'; + +import { i18n } from '@kbn/i18n'; + +import { images } from '../../workplace_search/components/shared/assets/source_icons'; + +import './icon_row.scss'; + +const icons = [ + { + icon: 'logoElasticsearch', + title: 'Elasticsearch', + tooltip: i18n.translate('xpack.enterpriseSearch.overview.iconRow.elasticsearch.tooltip', { + defaultMessage: + 'Use App and Workplace Search Search Engines with existing Elasticsearch indices', + }), + }, + { + icon: 'desktop', + title: i18n.translate('xpack.enterpriseSearch.overview.iconRow.api.title', { + defaultMessage: 'API', + }), + tooltip: i18n.translate('xpack.enterpriseSearch.overview.iconRow.api.tooltip', { + defaultMessage: 'POST documents to an API endpoint from your own applications', + }), + }, + { + icon: 'globe', + title: i18n.translate('xpack.enterpriseSearch.overview.iconRow.crawler.title', { + defaultMessage: 'Elastic Web Crawler', + }), + tooltip: i18n.translate('xpack.enterpriseSearch.overview.iconRow.crawler.tooltip', { + defaultMessage: 'Automatically index content from your websites', + }), + }, + { + icon: images.confluence, + title: i18n.translate('xpack.enterpriseSearch.overview.iconRow.confluence.title', { + defaultMessage: 'Confluence', + }), + tooltip: i18n.translate('xpack.enterpriseSearch.overview.iconRow.confluence.tooltip', { + defaultMessage: 'Index content from Atlassian Confluence', + }), + }, + { + icon: images.googleDrive, + title: i18n.translate('xpack.enterpriseSearch.overview.iconRow.googleDrive.title', { + defaultMessage: 'Google Drive', + }), + tooltip: i18n.translate('xpack.enterpriseSearch.overview.iconRow.googleDrive.tooltip', { + defaultMessage: 'Index documents from Google Drive', + }), + }, + { + icon: images.sharePoint, + title: i18n.translate('xpack.enterpriseSearch.overview.iconRow.sharePoint.title', { + defaultMessage: 'Microsoft SharePoint', + }), + tooltip: i18n.translate('xpack.enterpriseSearch.overview.iconRow.sharePoint.tooltip', { + defaultMessage: 'Index content from Microsoft SharePoint', + }), + }, + { + icon: images.github, + title: i18n.translate('xpack.enterpriseSearch.overview.iconRow.github.title', { + defaultMessage: 'GitHub', + }), + tooltip: i18n.translate('xpack.enterpriseSearch.overview.iconRow.github.tooltip', { + defaultMessage: 'Index issues, pull requests, and more from GitHub', + }), + }, +]; + +export const IconRow: React.FC = () => { + return ( + + + + {icons.map((item, index) => { + return ( + + +

{item.title}

+ {item.tooltip} + + } + > + +
+
+ ); + })} +
+
+ + + {i18n.translate('xpack.enterpriseSearch.overview.iconRow.manyMoreBadge', { + defaultMessage: 'And many more', + })} + + +
+ ); +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/getting_started_steps/index.ts b/x-pack/plugins/enterprise_search/public/applications/shared/getting_started_steps/index.ts new file mode 100644 index 0000000000000..71ad56d84cb09 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/shared/getting_started_steps/index.ts @@ -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 { GettingStartedSteps } from './getting_started_steps'; diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index 73780164049a5..32bb864b582e4 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -11419,8 +11419,6 @@ "xpack.enterpriseSearch.overview.productCard.setupButton": "Configurer {productName}", "xpack.enterpriseSearch.overview.productName": "Enterprise Search", "xpack.enterpriseSearch.overview.setupCta.description": "Ajoutez des fonctions de recherche à votre application ou à votre organisation interne avec Elastic App Search et Workplace Search. Regardez la vidéo pour savoir ce qu'il est possible de faire lorsque la recherche est facilitée.", - "xpack.enterpriseSearch.overview.setupHeading": "Choisissez un produit à configurer et lancez-vous.", - "xpack.enterpriseSearch.overview.subheading": "Ajoutez une fonction de recherche à votre application ou à votre organisation.", "xpack.enterpriseSearch.productSelectorCalloutTitle": "Des fonctionnalités de niveau entreprise pour les grandes et petites équipes", "xpack.enterpriseSearch.readOnlyMode.warning": "Enterprise Search est en mode de lecture seule. Vous ne pourrez pas effectuer de changements tels que création, modification ou suppression.", "xpack.enterpriseSearch.roleMapping.addRoleMappingButtonLabel": "Ajouter un mapping",