Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Enterprise Search] De-couple Overview from ent-search #161995

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ import React from 'react';

import { shallow } from 'enzyme';

import { EuiEmptyPrompt } from '@elastic/eui';

import { WORKPLACE_SEARCH_PLUGIN } from '../../../../../common/constants';
import { AddContentEmptyPrompt } from '../../../shared/add_content_empty_prompt';
import { ErrorStateCallout } from '../../../shared/error_state';

import { ProductCard } from '../product_card';
import { SetupGuideCta } from '../setup_guide';
Expand Down Expand Up @@ -51,6 +51,40 @@ describe('ProductSelector', () => {
);
});

it('does not render connection error callout without an error', () => {
setMockValues({ config: { canDeployEntSearch: true, host: 'localhost' } });
const wrapper = shallow(<ProductSelector {...props} />);

expect(wrapper.find(ErrorStateCallout)).toHaveLength(0);
});

it('does render connection error callout with an error', () => {
setMockValues({
config: { canDeployEntSearch: true, host: 'localhost' },
errorConnectingMessage: '502 Bad Gateway',
});
const wrapper = shallow(<ProductSelector {...props} />);

expect(wrapper.find(ErrorStateCallout)).toHaveLength(1);
});

it('renders add content', () => {
setMockValues({ config: { canDeployEntSearch: true, host: 'localhost' } });
const wrapper = shallow(<ProductSelector {...props} />);

expect(wrapper.find(AddContentEmptyPrompt)).toHaveLength(1);
});

it('does not render add content when theres a connection error', () => {
setMockValues({
config: { canDeployEntSearch: true, host: 'localhost' },
errorConnectingMessage: '502 Bad Gateway',
});
const wrapper = shallow(<ProductSelector {...props} />);

expect(wrapper.find(AddContentEmptyPrompt)).toHaveLength(0);
});

describe('access checks when host is set', () => {
beforeEach(() => {
setMockValues({ config: { canDeployEntSearch: true, host: 'localhost' } });
Expand Down Expand Up @@ -82,11 +116,11 @@ describe('ProductSelector', () => {
expect(wrapper.find('[data-test-subj="productCard-elasticsearch"]')).toHaveLength(1);
});

it('renders empty prompt and no cards or license callout if the user does not have access', () => {
it('renders elasticsearch card if the user does not have access app search & workplace search', () => {
const wrapper = shallow(<ProductSelector {...props} />);

expect(wrapper.find(EuiEmptyPrompt)).toHaveLength(1);
expect(wrapper.find(ProductCard)).toHaveLength(0);
expect(wrapper.find(ProductCard)).toHaveLength(1);
expect(wrapper.find('[data-test-subj="productCard-elasticsearch"]')).toHaveLength(1);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,7 @@ import React from 'react';

import { useValues } from 'kea';

import {
EuiButton,
EuiEmptyPrompt,
EuiFlexGroup,
EuiFlexItem,
EuiImage,
EuiLink,
EuiSpacer,
EuiTitle,
} from '@elastic/eui';
import { EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiTitle } from '@elastic/eui';
import { Chat } from '@kbn/cloud-chat-plugin/public';
import { i18n } from '@kbn/i18n';

Expand All @@ -29,6 +20,8 @@ import {
} from '../../../../../common/constants';
import { AddContentEmptyPrompt } from '../../../shared/add_content_empty_prompt';
import { docLinks } from '../../../shared/doc_links';
import { ErrorStateCallout } from '../../../shared/error_state';
import { HttpLogic } from '../../../shared/http';
import { KibanaLogic } from '../../../shared/kibana';
import { SetSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome';
import { SendEnterpriseSearchTelemetry as SendTelemetry } from '../../../shared/telemetry';
Expand All @@ -38,8 +31,6 @@ import { ProductCard } from '../product_card';
import { SetupGuideCta } from '../setup_guide';
import { TrialCallout } from '../trial_callout';

import illustration from './lock_light.svg';

interface ProductSelectorProps {
access: {
hasAppSearchAccess?: boolean;
Expand All @@ -54,32 +45,53 @@ export const ProductSelector: React.FC<ProductSelectorProps> = ({
}) => {
const { hasAppSearchAccess, hasWorkplaceSearchAccess } = access;
const { config } = useValues(KibanaLogic);
const { errorConnectingMessage } = useValues(HttpLogic);

const showErrorConnecting = !!(config.host && errorConnectingMessage);
// The create index flow does not work without ent-search, when content is updated
// to no longer rely on ent-search we can always show the Add Content component
const showAddContent = config.host && !errorConnectingMessage;

// If Enterprise Search hasn't been set up yet, show all products. Otherwise, only show products the user has access to
const shouldShowAppSearchCard = (!config.host && config.canDeployEntSearch) || hasAppSearchAccess;
const shouldShowWorkplaceSearchCard =
(!config.host && config.canDeployEntSearch) || hasWorkplaceSearchAccess;

// 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 shouldShowEnterpriseSearchCards =
shouldShowAppSearchCard || shouldShowWorkplaceSearchCard || !config.canDeployEntSearch;

const WORKPLACE_SEARCH_URL = isWorkplaceSearchAdmin
? WORKPLACE_SEARCH_PLUGIN.URL
: WORKPLACE_SEARCH_PLUGIN.NON_ADMIN_URL;

const productCards = (
<>
<AddContentEmptyPrompt
title={i18n.translate('xpack.enterpriseSearch.overview.emptyPromptTitle', {
defaultMessage: 'Add data and start searching',
})}
buttonLabel={i18n.translate('xpack.enterpriseSearch.overview.emptyPromptButtonLabel', {
defaultMessage: 'Create an Elasticsearch index',
})}
/>
<EuiSpacer size="xxl" />
return (
<EnterpriseSearchOverviewPageTemplate
restrictWidth
pageHeader={{
pageTitle: i18n.translate('xpack.enterpriseSearch.overview.pageTitle', {
defaultMessage: 'Welcome to Search',
}),
}}
>
<SetPageChrome />
<SendTelemetry action="viewed" metric="overview" />
<TrialCallout />
{showAddContent && (
<>
<AddContentEmptyPrompt
title={i18n.translate('xpack.enterpriseSearch.overview.emptyPromptTitle', {
defaultMessage: 'Add data and start searching',
})}
buttonLabel={i18n.translate('xpack.enterpriseSearch.overview.emptyPromptButtonLabel', {
defaultMessage: 'Create an Elasticsearch index',
})}
/>
<EuiSpacer size="xxl" />
</>
)}
{showErrorConnecting && (
<>
<SendTelemetry action="error" metric="cannot_connect" />
<ErrorStateCallout />
</>
)}
<EuiSpacer size="xxl" />
<EuiTitle>
<h3>
Expand Down Expand Up @@ -305,72 +317,6 @@ export const ProductSelector: React.FC<ProductSelectorProps> = ({
</EuiFlexItem>
)}
</EuiFlexGroup>
</>
);

const insufficientAccessMessage = (
<EuiEmptyPrompt
icon={<EuiImage size="fullWidth" src={illustration} alt="" />}
title={
<h2>
{i18n.translate('xpack.enterpriseSearch.overview.insufficientPermissionsTitle', {
defaultMessage: 'Insufficient permissions',
})}
</h2>
}
layout="horizontal"
color="plain"
body={
<>
<p>
{i18n.translate('xpack.enterpriseSearch.overview.insufficientPermissionsBody', {
defaultMessage:
'You don’t have access to view this page. If you feel this may be an error, please contact your administrator.',
})}
</p>
</>
}
actions={
<EuiButton color="primary" fill href="/">
{i18n.translate('xpack.enterpriseSearch.overview.insufficientPermissionsButtonLabel', {
defaultMessage: 'Go to the Kibana dashboard',
})}
</EuiButton>
}
footer={
<>
<EuiTitle size="xxs">
<span>
{i18n.translate('xpack.enterpriseSearch.overview.insufficientPermissionsFooterBody', {
defaultMessage: 'Go to the Kibana dashboard',
})}
</span>
</EuiTitle>{' '}
<EuiLink href={docLinks.kibanaSecurity} target="_blank">
{i18n.translate(
'xpack.enterpriseSearch.overview.insufficientPermissionsFooterLinkLabel',
{
defaultMessage: 'Read documentation',
}
)}
</EuiLink>
</>
}
/>
);
return (
<EnterpriseSearchOverviewPageTemplate
restrictWidth
pageHeader={{
pageTitle: i18n.translate('xpack.enterpriseSearch.overview.pageTitle', {
defaultMessage: 'Welcome to Enterprise Search',
}),
}}
>
<SetPageChrome />
<SendTelemetry action="viewed" metric="overview" />
<TrialCallout />
{shouldShowEnterpriseSearchCards ? productCards : insufficientAccessMessage}
<Chat />
</EnterpriseSearchOverviewPageTemplate>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@ import React from 'react';
import { shallow } from 'enzyme';

import { VersionMismatchPage } from '../shared/version_mismatch';
import { rerender } from '../test_helpers';

import { ErrorConnecting } from './components/error_connecting';
import { ProductSelector } from './components/product_selector';
import { SetupGuide } from './components/setup_guide';

Expand All @@ -32,29 +30,6 @@ describe('EnterpriseSearchOverview', () => {
expect(wrapper.find(ProductSelector)).toHaveLength(1);
});

it('renders the error connecting prompt only if host is configured', () => {
setMockValues({
errorConnectingMessage: '502 Bad Gateway',
config: { host: 'localhost' },
});
const wrapper = shallow(<EnterpriseSearchOverview />);

expect(wrapper.find(VersionMismatchPage)).toHaveLength(0);
const errorConnecting = wrapper.find(ErrorConnecting);
expect(errorConnecting).toHaveLength(1);
expect(wrapper.find(ProductSelector)).toHaveLength(0);

setMockValues({
errorConnectingMessage: '502 Bad Gateway',
config: { host: '' },
});
rerender(wrapper);

expect(wrapper.find(VersionMismatchPage)).toHaveLength(0);
expect(wrapper.find(ErrorConnecting)).toHaveLength(0);
expect(wrapper.find(ProductSelector)).toHaveLength(1);
});

it('renders the version error message if versions mismatch and the host is configured', () => {
setMockValues({
errorConnectingMessage: '',
Expand All @@ -65,7 +40,6 @@ describe('EnterpriseSearchOverview', () => {
);

expect(wrapper.find(VersionMismatchPage)).toHaveLength(1);
expect(wrapper.find(ErrorConnecting)).toHaveLength(0);
expect(wrapper.find(ProductSelector)).toHaveLength(0);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,9 @@ import { Routes, Route } from '@kbn/shared-ux-router';

import { isVersionMismatch } from '../../../common/is_version_mismatch';
import { InitialAppData } from '../../../common/types';
import { HttpLogic } from '../shared/http';
import { KibanaLogic } from '../shared/kibana';
import { VersionMismatchPage } from '../shared/version_mismatch';

import { ErrorConnecting } from './components/error_connecting';
import { ProductSelector } from './components/product_selector';
import { SetupGuide } from './components/setup_guide';
import { ROOT_PATH, SETUP_GUIDE_PATH } from './routes';
Expand All @@ -28,10 +26,8 @@ export const EnterpriseSearchOverview: React.FC<InitialAppData> = ({
enterpriseSearchVersion,
kibanaVersion,
}) => {
const { errorConnectingMessage } = useValues(HttpLogic);
const { config } = useValues(KibanaLogic);

const showErrorConnecting = !!(config.host && errorConnectingMessage);
const incompatibleVersions = !!(
config.host && isVersionMismatch(enterpriseSearchVersion, kibanaVersion)
);
Expand All @@ -45,8 +41,6 @@ export const EnterpriseSearchOverview: React.FC<InitialAppData> = ({
kibanaVersion={kibanaVersion}
/>
);
} else if (showErrorConnecting) {
return <ErrorConnecting />;
}

return <ProductSelector isWorkplaceSearchAdmin={isWorkplaceSearchAdmin} access={access} />;
Expand Down
Loading