Skip to content

Commit 774d359

Browse files
authored
[Security Solution] Update security overview splash (#73050)
## Summary elastic/endpoint-app-team#591 How to verify: 1. go to: x-pack/test/security_solution_cypress/runner.ts 2. comment line 20 (await esArchiver.load('auditbeat');) 3. in line 25 change cypress:run for cypress:open 4. then in our directory run yarn cypress:run-as-ci when the cypress is open, 5. you can access the Kibana instance in port 5620 with username elastic and password changeme <img width="1674" alt="Screenshot 2020-07-23 at 14 48 34" src="https://user-images.githubusercontent.com/6295984/88294333-04a17c80-ccf4-11ea-861b-75a85d2b8129.png"> ### Checklist Delete any items that are not applicable to this PR. - [x] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/master/packages/kbn-i18n/README.md) - [ ] ~[Documentation](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#writing-documentation) was added for features that require explanation or tutorials~ - [ ] ~[Unit or functional tests](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#cross-browser-compatibility) were updated or added to match the most common scenarios~ - [ ] ~This was checked for [keyboard-only and screenreader accessibility](https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Accessibility#Accessibility_testing_checklist)~ - [ ] ~This renders correctly on smaller devices using a responsive layout. (You can test this [in your browser](https://www.browserstack.com/guide/responsive-testing-on-local-server)~ - [ ] ~This was checked for [cross-browser compatibility](https://www.elastic.co/support/matrix#matrix_browsers)~ ### For maintainers - [ ] ~This was checked for breaking API changes and was [labeled appropriately](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#release-notes-process)~
1 parent 17ec168 commit 774d359

File tree

16 files changed

+331
-118
lines changed

16 files changed

+331
-118
lines changed

src/core/public/doc_links/doc_links_service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ export class DocLinksService {
112112
kibana: `${ELASTIC_WEBSITE_URL}guide/en/kibana/${DOC_LINK_VERSION}/index.html`,
113113
siem: {
114114
guide: `${ELASTIC_WEBSITE_URL}guide/en/security/${DOC_LINK_VERSION}/index.html`,
115-
gettingStarted: `${ELASTIC_WEBSITE_URL}guide/en/security/${DOC_LINK_VERSION}/install-siem.html`,
115+
gettingStarted: `${ELASTIC_WEBSITE_URL}guide/en/security/${DOC_LINK_VERSION}/index.html`,
116116
},
117117
query: {
118118
luceneQuerySyntax: `${ELASTICSEARCH_DOCS}query-dsl-query-string-query.html#query-string-syntax`,

x-pack/plugins/security_solution/public/cases/pages/saved_object_no_permissions.tsx

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,29 @@
44
* you may not use this file except in compliance with the Elastic License.
55
*/
66

7-
import React from 'react';
7+
import React, { useMemo } from 'react';
88

99
import { EmptyPage } from '../../common/components/empty_page';
1010
import * as i18n from './translations';
1111
import { useKibana } from '../../common/lib/kibana';
1212

1313
export const CaseSavedObjectNoPermissions = React.memo(() => {
1414
const docLinks = useKibana().services.docLinks;
15+
const actions = useMemo(
16+
() => ({
17+
savedObject: {
18+
icon: 'documents',
19+
label: i18n.GO_TO_DOCUMENTATION,
20+
url: `${docLinks.ELASTIC_WEBSITE_URL}guide/en/security/${docLinks.DOC_LINK_VERSION}s`,
21+
target: '_blank',
22+
},
23+
}),
24+
[docLinks]
25+
);
1526

1627
return (
1728
<EmptyPage
18-
actionPrimaryIcon="documents"
19-
actionPrimaryLabel={i18n.GO_TO_DOCUMENTATION}
20-
actionPrimaryUrl={`${docLinks.ELASTIC_WEBSITE_URL}guide/en/security/${docLinks.DOC_LINK_VERSION}s`}
21-
actionPrimaryTarget="_blank"
29+
actions={actions}
2230
message={i18n.SAVED_OBJECT_NO_PERMISSIONS_MSG}
2331
data-test-subj="no_saved_objects_permissions"
2432
title={i18n.SAVED_OBJECT_NO_PERMISSIONS_TITLE}

x-pack/plugins/security_solution/public/common/components/empty_page/__snapshots__/index.test.tsx.snap

Lines changed: 18 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

x-pack/plugins/security_solution/public/common/components/empty_page/index.test.tsx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@ import React from 'react';
1010
import { EmptyPage } from './index';
1111

1212
test('renders correctly', () => {
13-
const EmptyComponent = shallow(
14-
<EmptyPage
15-
actionPrimaryLabel="Do Something"
16-
actionPrimaryUrl="my/url/from/nowwhere"
17-
title="My Super Title"
18-
/>
19-
);
13+
const actions = {
14+
actions: {
15+
label: 'Do Something',
16+
url: 'my/url/from/nowwhere',
17+
},
18+
};
19+
const EmptyComponent = shallow(<EmptyPage actions={actions} title="My Super Title" />);
2020
expect(EmptyComponent).toMatchSnapshot();
2121
});

x-pack/plugins/security_solution/public/common/components/empty_page/index.tsx

Lines changed: 98 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -4,84 +4,123 @@
44
* you may not use this file except in compliance with the Elastic License.
55
*/
66

7-
import { EuiButton, EuiEmptyPrompt, EuiFlexGroup, EuiFlexItem, IconType } from '@elastic/eui';
8-
import React, { MouseEventHandler, ReactNode } from 'react';
7+
import {
8+
EuiButton,
9+
EuiEmptyPrompt,
10+
EuiFlexGroup,
11+
EuiFlexItem,
12+
IconType,
13+
EuiCard,
14+
} from '@elastic/eui';
15+
import React, { MouseEventHandler, ReactNode, useMemo } from 'react';
916
import styled from 'styled-components';
1017

1118
const EmptyPrompt = styled(EuiEmptyPrompt)`
1219
align-self: center; /* Corrects horizontal centering in IE11 */
20+
max-width: 60em;
1321
`;
1422

1523
EmptyPrompt.displayName = 'EmptyPrompt';
1624

25+
interface EmptyPageActions {
26+
icon?: IconType;
27+
label: string;
28+
target?: string;
29+
url: string;
30+
descriptionTitle?: string;
31+
description?: string;
32+
fill?: boolean;
33+
onClick?: MouseEventHandler<HTMLButtonElement | HTMLAnchorElement>;
34+
}
35+
36+
export type EmptyPageActionsProps = Record<string, EmptyPageActions>;
37+
1738
interface EmptyPageProps {
18-
actionPrimaryIcon?: IconType;
19-
actionPrimaryLabel: string;
20-
actionPrimaryTarget?: string;
21-
actionPrimaryUrl: string;
22-
actionPrimaryFill?: boolean;
23-
actionSecondaryIcon?: IconType;
24-
actionSecondaryLabel?: string;
25-
actionSecondaryTarget?: string;
26-
actionSecondaryUrl?: string;
27-
actionSecondaryOnClick?: MouseEventHandler<HTMLButtonElement | HTMLAnchorElement>;
39+
actions: EmptyPageActionsProps;
2840
'data-test-subj'?: string;
2941
message?: ReactNode;
3042
title: string;
3143
}
3244

33-
export const EmptyPage = React.memo<EmptyPageProps>(
34-
({
35-
actionPrimaryIcon,
36-
actionPrimaryLabel,
37-
actionPrimaryTarget,
38-
actionPrimaryUrl,
39-
actionPrimaryFill = true,
40-
actionSecondaryIcon,
41-
actionSecondaryLabel,
42-
actionSecondaryTarget,
43-
actionSecondaryUrl,
44-
actionSecondaryOnClick,
45-
message,
46-
title,
47-
...rest
48-
}) => (
45+
const EmptyPageComponent = React.memo<EmptyPageProps>(({ actions, message, title, ...rest }) => {
46+
const titles = Object.keys(actions);
47+
const maxItemWidth = 283;
48+
const renderActions = useMemo(
49+
() =>
50+
Object.values(actions)
51+
.filter((a) => a.label && a.url)
52+
.map(
53+
(
54+
{
55+
icon,
56+
label,
57+
target,
58+
url,
59+
descriptionTitle = false,
60+
description = false,
61+
onClick,
62+
fill = true,
63+
},
64+
idx
65+
) =>
66+
descriptionTitle != null || description != null ? (
67+
<EuiFlexItem
68+
grow={false}
69+
style={{ maxWidth: maxItemWidth }}
70+
key={`empty-page-${titles[idx]}-action`}
71+
>
72+
<EuiCard
73+
title={descriptionTitle}
74+
description={description}
75+
footer={
76+
/* eslint-disable-next-line @elastic/eui/href-or-on-click */
77+
<EuiButton
78+
href={url}
79+
onClick={onClick}
80+
iconType={icon}
81+
target={target}
82+
fill={fill}
83+
data-test-subj={`empty-page-${titles[idx]}-action`}
84+
>
85+
{label}
86+
</EuiButton>
87+
}
88+
/>
89+
</EuiFlexItem>
90+
) : (
91+
<EuiFlexItem
92+
grow={false}
93+
style={{ maxWidth: maxItemWidth }}
94+
key={`empty-page-${titles[idx]}-action`}
95+
>
96+
{/* eslint-disable-next-line @elastic/eui/href-or-on-click */}
97+
<EuiButton
98+
href={url}
99+
onClick={onClick}
100+
iconType={icon}
101+
target={target}
102+
data-test-subj={`empty-page-${titles[idx]}-action`}
103+
>
104+
{label}
105+
</EuiButton>
106+
</EuiFlexItem>
107+
)
108+
),
109+
[actions, titles]
110+
);
111+
112+
return (
49113
<EmptyPrompt
50114
iconType="logoSecurity"
51115
title={<h2>{title}</h2>}
52116
body={message && <p>{message}</p>}
53-
actions={
54-
<EuiFlexGroup justifyContent="center">
55-
<EuiFlexItem grow={false}>
56-
<EuiButton
57-
fill={actionPrimaryFill}
58-
href={actionPrimaryUrl}
59-
iconType={actionPrimaryIcon}
60-
target={actionPrimaryTarget}
61-
>
62-
{actionPrimaryLabel}
63-
</EuiButton>
64-
</EuiFlexItem>
65-
66-
{actionSecondaryLabel && actionSecondaryUrl && (
67-
<EuiFlexItem grow={false}>
68-
{/* eslint-disable-next-line @elastic/eui/href-or-on-click */}
69-
<EuiButton
70-
href={actionSecondaryUrl}
71-
onClick={actionSecondaryOnClick}
72-
iconType={actionSecondaryIcon}
73-
target={actionSecondaryTarget}
74-
data-test-subj="empty-page-secondary-action"
75-
>
76-
{actionSecondaryLabel}
77-
</EuiButton>
78-
</EuiFlexItem>
79-
)}
80-
</EuiFlexGroup>
81-
}
117+
actions={<EuiFlexGroup justifyContent="center">{renderActions}</EuiFlexGroup>}
82118
{...rest}
83119
/>
84-
)
85-
);
120+
);
121+
});
122+
123+
EmptyPageComponent.displayName = 'EmptyPageComponent';
86124

125+
export const EmptyPage = React.memo(EmptyPageComponent);
87126
EmptyPage.displayName = 'EmptyPage';

x-pack/plugins/security_solution/public/common/translations.ts

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,39 @@
77
import { i18n } from '@kbn/i18n';
88

99
export const EMPTY_TITLE = i18n.translate('xpack.securitySolution.pages.common.emptyTitle', {
10-
defaultMessage: 'Welcome to Security Solution. Let’s get you started.',
10+
defaultMessage: 'Welcome to Elastic Security. Let’s get you started.',
1111
});
1212

13-
export const EMPTY_ACTION_PRIMARY = i18n.translate(
14-
'xpack.securitySolution.pages.common.emptyActionPrimary',
13+
export const EMPTY_ACTION_ELASTIC_AGENT = i18n.translate(
14+
'xpack.securitySolution.pages.common.emptyActionElasticAgent',
15+
{
16+
defaultMessage: 'Add data with Elastic Agent',
17+
}
18+
);
19+
20+
export const EMPTY_ACTION_ELASTIC_AGENT_DESCRIPTION = i18n.translate(
21+
'xpack.securitySolution.pages.common.emptyActionElasticAgentDescription',
22+
{
23+
defaultMessage:
24+
'The Elastic Agent provides a simple, unified way to add monitoring to your hosts.',
25+
}
26+
);
27+
28+
export const EMPTY_ACTION_BEATS = i18n.translate(
29+
'xpack.securitySolution.pages.common.emptyActionBeats',
1530
{
1631
defaultMessage: 'Add data with Beats',
1732
}
1833
);
1934

35+
export const EMPTY_ACTION_BEATS_DESCRIPTION = i18n.translate(
36+
'xpack.securitySolution.pages.common.emptyActionBeatsDescription',
37+
{
38+
defaultMessage:
39+
'Lightweight Beats can send data from hundreds or thousands of machines and systems',
40+
}
41+
);
42+
2043
export const EMPTY_ACTION_SECONDARY = i18n.translate(
2144
'xpack.securitySolution.pages.common.emptyActionSecondary',
2245
{
@@ -27,6 +50,14 @@ export const EMPTY_ACTION_SECONDARY = i18n.translate(
2750
export const EMPTY_ACTION_ENDPOINT = i18n.translate(
2851
'xpack.securitySolution.pages.common.emptyActionEndpoint',
2952
{
30-
defaultMessage: 'Add data with Elastic Agent (Beta)',
53+
defaultMessage: 'Add Elastic Endpoint Security',
54+
}
55+
);
56+
57+
export const EMPTY_ACTION_ENDPOINT_DESCRIPTION = i18n.translate(
58+
'xpack.securitySolution.pages.common.emptyActionEndpointDescription',
59+
{
60+
defaultMessage:
61+
'Protect your hosts with threat prevention, detection, and deep security data visibility.',
3162
}
3263
);

x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.test.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ jest.mock('react-router-dom', () => {
5353
useHistory: jest.fn(),
5454
};
5555
});
56+
jest.mock('../../components/alerts_info', () => ({
57+
useAlertInfo: jest.fn().mockReturnValue([]),
58+
}));
5659

5760
const state: State = {
5861
...mockGlobalState,

x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine_no_signal_index.tsx

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,29 @@
44
* you may not use this file except in compliance with the Elastic License.
55
*/
66

7-
import React from 'react';
7+
import React, { useMemo } from 'react';
88

99
import { EmptyPage } from '../../../common/components/empty_page';
1010
import * as i18n from './translations';
1111
import { useKibana } from '../../../common/lib/kibana';
1212

1313
export const DetectionEngineNoIndex = React.memo(() => {
1414
const docLinks = useKibana().services.docLinks;
15+
const actions = useMemo(
16+
() => ({
17+
detections: {
18+
icon: 'documents',
19+
label: i18n.GO_TO_DOCUMENTATION,
20+
url: `${docLinks.ELASTIC_WEBSITE_URL}guide/en/security/${docLinks.DOC_LINK_VERSION}/detection-engine-overview.html#detections-permissions`,
21+
target: '_blank',
22+
},
23+
}),
24+
[docLinks]
25+
);
26+
1527
return (
1628
<EmptyPage
17-
actionPrimaryIcon="documents"
18-
actionPrimaryLabel={i18n.GO_TO_DOCUMENTATION}
19-
actionPrimaryUrl={`${docLinks.ELASTIC_WEBSITE_URL}guide/en/security/${docLinks.DOC_LINK_VERSION}/detection-engine-overview.html#detections-permissions`}
20-
actionPrimaryTarget="_blank"
29+
actions={actions}
2130
message={i18n.NO_INDEX_MSG_BODY}
2231
data-test-subj="no_index"
2332
title={i18n.NO_INDEX_TITLE}

0 commit comments

Comments
 (0)