[Enterprise Search] Fix bug where no content when user has no Enterprise Search access (#123877)

* Add docs link for kibana xpack-security

* Add callout when user has no Enterprise Search access

* Updated API documentation and the API review file
This commit is contained in:
Scotty Bollinger 2022-01-27 08:35:52 -06:00 committed by GitHub
parent d965ba791a
commit eeeef83ea4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 118 additions and 25 deletions

View file

@ -197,6 +197,7 @@ readonly links: {
readonly kibana: {
readonly guide: string;
readonly autocompleteSuggestions: string;
readonly xpackSecurity: string;
};
readonly upgradeAssistant: {
readonly overview: string;

File diff suppressed because one or more lines are too long

View file

@ -226,6 +226,7 @@ export class DocLinksService {
kibana: {
guide: `${KIBANA_DOCS}index.html`,
autocompleteSuggestions: `${KIBANA_DOCS}kibana-concepts-analysts.html#autocomplete-suggestions`,
xpackSecurity: `${KIBANA_DOCS}xpack-security.html`,
},
upgradeAssistant: {
overview: `${KIBANA_DOCS}upgrade-assistant.html`,
@ -797,6 +798,7 @@ export interface DocLinksStart {
readonly kibana: {
readonly guide: string;
readonly autocompleteSuggestions: string;
readonly xpackSecurity: string;
};
readonly upgradeAssistant: {
readonly overview: string;

View file

@ -680,6 +680,7 @@ export interface DocLinksStart {
readonly kibana: {
readonly guide: string;
readonly autocompleteSuggestions: string;
readonly xpackSecurity: string;
};
readonly upgradeAssistant: {
readonly overview: string;

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 74 KiB

View file

@ -11,6 +11,8 @@ import React from 'react';
import { shallow } from 'enzyme';
import { EuiEmptyPrompt } from '@elastic/eui';
import { WORKPLACE_SEARCH_PLUGIN } from '../../../../../common/constants';
import { LicenseCallout } from '../license_callout';
@ -35,12 +37,11 @@ describe('ProductSelector', () => {
expect(wrapper.find(LicenseCallout)).toHaveLength(0);
});
it('renders the license and trial callouts', () => {
it('renders the trial callout', () => {
setMockValues({ config: { host: 'localhost' } });
const wrapper = shallow(<ProductSelector {...props} />);
expect(wrapper.find(TrialCallout)).toHaveLength(1);
expect(wrapper.find(LicenseCallout)).toHaveLength(1);
});
it('passes correct URL when Workplace Search user is not an admin', () => {
@ -57,6 +58,15 @@ describe('ProductSelector', () => {
setMockValues({ config: { host: 'localhost' } });
});
it('renders the license callout when user has access to a product', () => {
setMockValues({ config: { host: 'localhost' } });
const wrapper = shallow(
<ProductSelector {...props} access={{ hasWorkplaceSearchAccess: true }} />
);
expect(wrapper.find(LicenseCallout)).toHaveLength(1);
});
it('does not render the App Search card if the user does not have access to AS', () => {
const wrapper = shallow(
<ProductSelector
@ -81,10 +91,12 @@ describe('ProductSelector', () => {
expect(wrapper.find(ProductCard).prop('product').ID).toEqual('appSearch');
});
it('does not render any cards if the user does not have access', () => {
it('renders empty prompt and no cards or license callout if the user does not have access', () => {
const wrapper = shallow(<ProductSelector {...props} />);
expect(wrapper.find(EuiEmptyPrompt)).toHaveLength(1);
expect(wrapper.find(ProductCard)).toHaveLength(0);
expect(wrapper.find(LicenseCallout)).toHaveLength(0);
});
});
});

View file

@ -9,7 +9,17 @@ import React from 'react';
import { useValues } from 'kea';
import { EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiText } from '@elastic/eui';
import {
EuiButton,
EuiEmptyPrompt,
EuiFlexGroup,
EuiFlexItem,
EuiImage,
EuiLink,
EuiSpacer,
EuiText,
EuiTitle,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import {
@ -18,6 +28,7 @@ import {
NO_DATA_PAGE_TEMPLATE_PROPS,
} from '../../../../../../../../src/plugins/kibana_react/public';
import { APP_SEARCH_PLUGIN, WORKPLACE_SEARCH_PLUGIN } from '../../../../../common/constants';
import { docLinks } from '../../../shared/doc_links';
import { KibanaLogic } from '../../../shared/kibana';
import { SetEnterpriseSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome';
import { SendEnterpriseSearchTelemetry as SendTelemetry } from '../../../shared/telemetry';
@ -29,6 +40,8 @@ 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;
@ -48,10 +61,89 @@ export const ProductSelector: React.FC<ProductSelectorProps> = ({
const shouldShowAppSearchCard = !config.host || hasAppSearchAccess;
const shouldShowWorkplaceSearchCard = !config.host || 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;
const WORKPLACE_SEARCH_URL = isWorkplaceSearchAdmin
? WORKPLACE_SEARCH_PLUGIN.URL
: WORKPLACE_SEARCH_PLUGIN.NON_ADMIN_URL;
const productCards = (
<>
<EuiFlexGroup justifyContent="center" gutterSize="xl">
{shouldShowAppSearchCard && (
<EuiFlexItem grow={false}>
<ProductCard product={APP_SEARCH_PLUGIN} image={AppSearchImage} />
</EuiFlexItem>
)}
{shouldShowWorkplaceSearchCard && (
<EuiFlexItem grow={false}>
<ProductCard
product={WORKPLACE_SEARCH_PLUGIN}
url={WORKPLACE_SEARCH_URL}
image={WorkplaceSearchImage}
/>
</EuiFlexItem>
)}
</EuiFlexGroup>
<EuiSpacer size="xxl" />
{config.host ? <LicenseCallout /> : <SetupGuideCta />}
</>
);
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 dont 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 (
<KibanaPageTemplate {...NO_DATA_PAGE_TEMPLATE_PROPS}>
<SetPageChrome />
@ -84,26 +176,7 @@ export const ProductSelector: React.FC<ProductSelectorProps> = ({
<EuiSpacer size="xxl" />
<EuiFlexGroup justifyContent="center" gutterSize="xl">
{shouldShowAppSearchCard && (
<EuiFlexItem grow={false}>
<ProductCard product={APP_SEARCH_PLUGIN} image={AppSearchImage} />
</EuiFlexItem>
)}
{shouldShowWorkplaceSearchCard && (
<EuiFlexItem grow={false}>
<ProductCard
product={WORKPLACE_SEARCH_PLUGIN}
url={WORKPLACE_SEARCH_URL}
image={WorkplaceSearchImage}
/>
</EuiFlexItem>
)}
</EuiFlexGroup>
<EuiSpacer size="xxl" />
{config.host ? <LicenseCallout /> : <SetupGuideCta />}
{shouldShowEnterpriseSearchCards ? productCards : insufficientAccessMessage}
</KibanaPageTemplate>
);
};

View file

@ -33,6 +33,7 @@ class DocLinks {
public enterpriseSearchConfig: string;
public enterpriseSearchMailService: string;
public enterpriseSearchUsersAccess: string;
public kibanaSecurity: string;
public licenseManagement: string;
public workplaceSearchApiKeys: string;
public workplaceSearchBox: string;
@ -86,6 +87,7 @@ class DocLinks {
this.enterpriseSearchConfig = '';
this.enterpriseSearchMailService = '';
this.enterpriseSearchUsersAccess = '';
this.kibanaSecurity = '';
this.licenseManagement = '';
this.workplaceSearchApiKeys = '';
this.workplaceSearchBox = '';
@ -140,6 +142,7 @@ class DocLinks {
this.enterpriseSearchConfig = docLinks.links.enterpriseSearch.configuration;
this.enterpriseSearchMailService = docLinks.links.enterpriseSearch.mailService;
this.enterpriseSearchUsersAccess = docLinks.links.enterpriseSearch.usersAccess;
this.kibanaSecurity = docLinks.links.kibana.xpackSecurity;
this.licenseManagement = docLinks.links.enterpriseSearch.licenseManagement;
this.workplaceSearchApiKeys = docLinks.links.workplaceSearch.apiKeys;
this.workplaceSearchBox = docLinks.links.workplaceSearch.box;