From f4b0f9124c7461b52b5151c2316893650185de39 Mon Sep 17 00:00:00 2001
From: Michael Marcialis
Date: Mon, 7 Oct 2019 11:12:37 -0400
Subject: [PATCH 01/57] attempt at getting nav working
---
.../siem/public/components/link_to/index.ts | 4 +
.../link_to/redirect_to_detection_engine.tsx | 23 ++++++
.../public/components/url_state/constants.ts | 3 +-
.../detection_engine.test.tsx | 78 +++++++++++++++++++
.../detection_engine/detection_engine.tsx | 51 ++++++++++++
.../public/pages/detection_engine/index.tsx | 12 +++
.../pages/detection_engine/translations.ts | 36 +++++++++
.../public/pages/home/home_navigations.tsx | 10 +++
.../plugins/siem/public/pages/home/index.tsx | 3 +
.../siem/public/pages/home/translations.ts | 4 +
10 files changed, 223 insertions(+), 1 deletion(-)
create mode 100644 x-pack/legacy/plugins/siem/public/components/link_to/redirect_to_detection_engine.tsx
create mode 100644 x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.test.tsx
create mode 100644 x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
create mode 100644 x-pack/legacy/plugins/siem/public/pages/detection_engine/index.tsx
create mode 100644 x-pack/legacy/plugins/siem/public/pages/detection_engine/translations.ts
diff --git a/x-pack/legacy/plugins/siem/public/components/link_to/index.ts b/x-pack/legacy/plugins/siem/public/components/link_to/index.ts
index cbd01b720295f..ec846883b3acb 100644
--- a/x-pack/legacy/plugins/siem/public/components/link_to/index.ts
+++ b/x-pack/legacy/plugins/siem/public/components/link_to/index.ts
@@ -5,6 +5,10 @@
*/
export { LinkToPage } from './link_to';
+export {
+ getDetectionEngineUrl,
+ RedirectToDetectionEnginePage,
+} from './redirect_to_detection_engine';
export { getOverviewUrl, RedirectToOverviewPage } from './redirect_to_overview';
export { getHostsUrl } from './redirect_to_hosts';
export { getNetworkUrl, RedirectToNetworkPage } from './redirect_to_network';
diff --git a/x-pack/legacy/plugins/siem/public/components/link_to/redirect_to_detection_engine.tsx b/x-pack/legacy/plugins/siem/public/components/link_to/redirect_to_detection_engine.tsx
new file mode 100644
index 0000000000000..9780202787bea
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/components/link_to/redirect_to_detection_engine.tsx
@@ -0,0 +1,23 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import React from 'react';
+import { RouteComponentProps } from 'react-router';
+import { RedirectWrapper } from './redirect_wrapper';
+
+export type DetectionEngineComponentProps = RouteComponentProps<{
+ search: string;
+}>;
+
+export const DETECTION_ENGINE_PAGE_NAME = 'detection-engine';
+
+export const RedirectToDetectionEnginePage = ({
+ location: { search },
+}: DetectionEngineComponentProps) => (
+
+);
+
+export const getDetectionEngineUrl = () => `#/link-to/${DETECTION_ENGINE_PAGE_NAME}`;
diff --git a/x-pack/legacy/plugins/siem/public/components/url_state/constants.ts b/x-pack/legacy/plugins/siem/public/components/url_state/constants.ts
index e0ecfc1640bbe..0328e68b27e2f 100644
--- a/x-pack/legacy/plugins/siem/public/components/url_state/constants.ts
+++ b/x-pack/legacy/plugins/siem/public/components/url_state/constants.ts
@@ -5,6 +5,7 @@
*/
export enum CONSTANTS {
+ detectionEnginePage = 'detectionEngine.page',
hostsDetails = 'hosts.details',
hostsPage = 'hosts.page',
kqlQuery = 'kqlQuery',
@@ -17,4 +18,4 @@ export enum CONSTANTS {
unknown = 'unknown',
}
-export type UrlStateType = 'host' | 'network' | 'overview' | 'timeline';
+export type UrlStateType = 'detection-engine' | 'host' | 'network' | 'overview' | 'timeline';
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.test.tsx
new file mode 100644
index 0000000000000..833030e0dc8a1
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.test.tsx
@@ -0,0 +1,78 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { mount } from 'enzyme';
+import { cloneDeep } from 'lodash/fp';
+import * as React from 'react';
+import { MockedProvider } from 'react-apollo/test-utils';
+import { MemoryRouter } from 'react-router-dom';
+
+import { Overview } from './index';
+
+import '../../mock/ui_settings';
+import { mocksSource } from '../../containers/source/mock';
+import { TestProviders } from '../../mock';
+
+jest.mock('ui/documentation_links', () => ({
+ documentationLinks: {
+ kibana: 'http://www.example.com',
+ },
+}));
+
+let localSource: Array<{
+ request: {};
+ result: {
+ data: {
+ source: {
+ status: {
+ indicesExist: boolean;
+ };
+ };
+ };
+ };
+}>;
+
+describe('Overview', () => {
+ describe('rendering', () => {
+ beforeEach(() => {
+ localSource = cloneDeep(mocksSource);
+ });
+
+ test('it renders the Setup Instructions text when no index is available', async () => {
+ localSource[0].result.data.source.status.indicesExist = false;
+ const wrapper = mount(
+
+
+
+
+
+
+
+ );
+ // Why => https://github.com/apollographql/react-apollo/issues/1711
+ await new Promise(resolve => setTimeout(resolve));
+ wrapper.update();
+ expect(wrapper.find('[data-test-subj="empty-page"]').exists()).toBe(true);
+ });
+
+ test('it DOES NOT render the Getting started text when an index is available', async () => {
+ localSource[0].result.data.source.status.indicesExist = true;
+ const wrapper = mount(
+
+
+
+
+
+
+
+ );
+ // Why => https://github.com/apollographql/react-apollo/issues/1711
+ await new Promise(resolve => setTimeout(resolve));
+ wrapper.update();
+ expect(wrapper.find('[data-test-subj="empty-page"]').exists()).toBe(false);
+ });
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
new file mode 100644
index 0000000000000..af651bda99d5c
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
@@ -0,0 +1,51 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import React from 'react';
+import { pure } from 'recompose';
+import chrome from 'ui/chrome';
+import { documentationLinks } from 'ui/documentation_links';
+
+import { HeaderPage } from '../../components/header_page';
+import { GlobalTime } from '../../containers/global_time';
+
+import { EmptyPage } from '../../components/empty_page';
+import { WithSource, indicesExistOrDataTemporarilyUnavailable } from '../../containers/source';
+import { SpyRoute } from '../../utils/route/spy_routes';
+
+import * as i18n from './translations';
+
+const basePath = chrome.getBasePath();
+
+export const DetectionEngineComponent = pure(() => {
+ return (
+ <>
+
+
+ {/*
+ {({ indicesExist }) =>
+ indicesExistOrDataTemporarilyUnavailable(indicesExist) ? (
+ {({ setQuery }) => Testing...
}
+ ) : (
+
+ )
+ }
+ */}
+
+ >
+ );
+});
+DetectionEngineComponent.displayName = 'DetectionEngineComponent';
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/index.tsx
new file mode 100644
index 0000000000000..6f2b10e1e4dc0
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/index.tsx
@@ -0,0 +1,12 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import React, { memo } from 'react';
+
+import { DetectionEngineComponent } from './detection_engine';
+
+export const DetectionEngine = memo(() => );
+DetectionEngine.displayName = 'DetectionEngine';
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/translations.ts b/x-pack/legacy/plugins/siem/public/pages/detection_engine/translations.ts
new file mode 100644
index 0000000000000..d85dabd9324c2
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/translations.ts
@@ -0,0 +1,36 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { i18n } from '@kbn/i18n';
+
+export const PAGE_TITLE = i18n.translate('xpack.siem.detectionEngine.pageTitle', {
+ defaultMessage: 'Detection Engine',
+});
+
+export const PAGE_SUBTITLE = i18n.translate('xpack.siem.overview.pageSubtitle', {
+ defaultMessage: 'Security Information & Event Management with the Elastic Stack',
+});
+
+export const PAGE_BADGE_LABEL = i18n.translate('xpack.siem.overview.pageBadgeLabel', {
+ defaultMessage: 'Beta',
+});
+
+export const PAGE_BADGE_TOOLTIP = i18n.translate('xpack.siem.overview.pageBadgeTooltip', {
+ defaultMessage:
+ 'SIEM is still in beta. Please help us improve by reporting issues or bugs in the Kibana repo.',
+});
+
+export const EMPTY_TITLE = i18n.translate('xpack.siem.overview.emptyTitle', {
+ defaultMessage: 'It looks like you don’t have any indices relevant to the SIEM application',
+});
+
+export const EMPTY_ACTION_PRIMARY = i18n.translate('xpack.siem.overview.emptyActionPrimary', {
+ defaultMessage: 'View setup instructions',
+});
+
+export const EMPTY_ACTION_SECONDARY = i18n.translate('xpack.siem.overview.emptyActionSecondary', {
+ defaultMessage: 'Go to documentation',
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/home/home_navigations.tsx b/x-pack/legacy/plugins/siem/public/pages/home/home_navigations.tsx
index 329547fe202e0..cbe7dce31293c 100644
--- a/x-pack/legacy/plugins/siem/public/pages/home/home_navigations.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/home/home_navigations.tsx
@@ -5,6 +5,7 @@
*/
import * as i18n from './translations';
import {
+ getDetectionEngineUrl,
getOverviewUrl,
getNetworkUrl,
getTimelinesUrl,
@@ -16,6 +17,7 @@ export enum SiemPageName {
overview = 'overview',
hosts = 'hosts',
network = 'network',
+ detectionEngine = 'detection-engine',
timelines = 'timelines',
}
@@ -23,6 +25,7 @@ export type SiemNavTabKey =
| SiemPageName.overview
| SiemPageName.hosts
| SiemPageName.network
+ | SiemPageName.detectionEngine
| SiemPageName.timelines;
export type SiemNavTab = Record;
@@ -49,6 +52,13 @@ export const navTabs: SiemNavTab = {
disabled: false,
urlKey: 'network',
},
+ [SiemPageName.detectionEngine]: {
+ id: SiemPageName.detectionEngine,
+ name: i18n.DETECTION_ENGINE,
+ href: getDetectionEngineUrl(),
+ disabled: false,
+ urlKey: 'detection-engine',
+ },
[SiemPageName.timelines]: {
id: SiemPageName.timelines,
name: i18n.TIMELINES,
diff --git a/x-pack/legacy/plugins/siem/public/pages/home/index.tsx b/x-pack/legacy/plugins/siem/public/pages/home/index.tsx
index 94a1fcd203bfc..3815710a1224e 100644
--- a/x-pack/legacy/plugins/siem/public/pages/home/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/home/index.tsx
@@ -20,6 +20,7 @@ import { SiemNavigation } from '../../components/navigation';
import { StatefulTimeline } from '../../components/timeline';
import { AutoSaveWarningMsg } from '../../components/timeline/auto_save_warning';
import { NotFoundPage } from '../404';
+import { DetectionEngine } from '../detection_engine';
import { HostsContainer } from '../hosts';
import { NetworkContainer } from '../network';
import { Overview } from '../overview';
@@ -136,6 +137,7 @@ export const HomePage = pure(() => (
+
} />
@@ -151,6 +153,7 @@ export const HomePage = pure(() => (
)}
/>
+ } />
} />
Date: Mon, 7 Oct 2019 10:21:52 -0600
Subject: [PATCH 02/57] fix detection-engine href redirect issue
---
.../siem/public/components/link_to/link_to.tsx | 5 +++++
.../siem/public/components/navigation/index.tsx | 1 -
.../siem/public/components/url_state/helpers.ts | 4 ++++
.../siem/public/components/url_state/types.ts | 2 ++
.../detection_engine/detection_engine.test.tsx | 8 ++++----
.../pages/detection_engine/detection_engine.tsx | 16 ++++++++--------
.../plugins/siem/public/pages/home/index.tsx | 2 +-
7 files changed, 24 insertions(+), 14 deletions(-)
diff --git a/x-pack/legacy/plugins/siem/public/components/link_to/link_to.tsx b/x-pack/legacy/plugins/siem/public/components/link_to/link_to.tsx
index d0857e6ff8b48..53c3d188c8b46 100644
--- a/x-pack/legacy/plugins/siem/public/components/link_to/link_to.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/link_to/link_to.tsx
@@ -12,6 +12,7 @@ import { RedirectToHostsPage, RedirectToHostDetailsPage } from './redirect_to_ho
import { RedirectToNetworkPage } from './redirect_to_network';
import { RedirectToOverviewPage } from './redirect_to_overview';
import { RedirectToTimelinesPage } from './redirect_to_timelines';
+import { RedirectToDetectionEnginePage } from './redirect_to_detection_engine';
import { HostsTableType } from '../../store/hosts/model';
interface LinkToPageProps {
@@ -41,6 +42,10 @@ export const LinkToPage = pure(({ match }) => (
component={RedirectToNetworkPage}
/>
+
));
diff --git a/x-pack/legacy/plugins/siem/public/components/navigation/index.tsx b/x-pack/legacy/plugins/siem/public/components/navigation/index.tsx
index 06f7a2ffb0566..0fc385be42463 100644
--- a/x-pack/legacy/plugins/siem/public/components/navigation/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/navigation/index.tsx
@@ -60,7 +60,6 @@ export const SiemNavigationComponent = React.memo {
return 'overview';
} else if (pageName === SiemPageName.timelines) {
return 'timeline';
+ } else if (pageName === SiemPageName.detectionEngine) {
+ return 'detection-engine';
}
return 'overview';
};
@@ -114,6 +116,8 @@ export const getCurrentLocation = (
return CONSTANTS.overviewPage;
} else if (pageName === SiemPageName.timelines) {
return CONSTANTS.timelinePage;
+ } else if (pageName === SiemPageName.detectionEngine) {
+ return CONSTANTS.detectionEnginePage;
}
return CONSTANTS.unknown;
};
diff --git a/x-pack/legacy/plugins/siem/public/components/url_state/types.ts b/x-pack/legacy/plugins/siem/public/components/url_state/types.ts
index 58c261fd4c27a..aa8261b56714f 100644
--- a/x-pack/legacy/plugins/siem/public/components/url_state/types.ts
+++ b/x-pack/legacy/plugins/siem/public/components/url_state/types.ts
@@ -27,9 +27,11 @@ export const URL_STATE_KEYS: Record = {
network: [CONSTANTS.kqlQuery, CONSTANTS.timerange, CONSTANTS.timelineId],
timeline: [CONSTANTS.timelineId, CONSTANTS.timerange],
overview: [CONSTANTS.timelineId, CONSTANTS.timerange],
+ 'detection-engine': [],
};
export type LocationTypes =
+ | CONSTANTS.detectionEnginePage
| CONSTANTS.networkDetails
| CONSTANTS.networkPage
| CONSTANTS.hostsDetails
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.test.tsx
index 833030e0dc8a1..3fee7dc918471 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.test.tsx
@@ -10,7 +10,7 @@ import * as React from 'react';
import { MockedProvider } from 'react-apollo/test-utils';
import { MemoryRouter } from 'react-router-dom';
-import { Overview } from './index';
+import { DetectionEngine } from './index';
import '../../mock/ui_settings';
import { mocksSource } from '../../containers/source/mock';
@@ -35,7 +35,7 @@ let localSource: Array<{
};
}>;
-describe('Overview', () => {
+describe('DetectionEngine', () => {
describe('rendering', () => {
beforeEach(() => {
localSource = cloneDeep(mocksSource);
@@ -47,7 +47,7 @@ describe('Overview', () => {
-
+
@@ -64,7 +64,7 @@ describe('Overview', () => {
-
+
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
index af651bda99d5c..f038a74822902 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
@@ -6,25 +6,25 @@
import React from 'react';
import { pure } from 'recompose';
-import chrome from 'ui/chrome';
-import { documentationLinks } from 'ui/documentation_links';
+// import chrome from 'ui/chrome';
+// import { documentationLinks } from 'ui/documentation_links';
import { HeaderPage } from '../../components/header_page';
-import { GlobalTime } from '../../containers/global_time';
-
-import { EmptyPage } from '../../components/empty_page';
-import { WithSource, indicesExistOrDataTemporarilyUnavailable } from '../../containers/source';
+// import { GlobalTime } from '../../containers/global_time';
+//
+// import { EmptyPage } from '../../components/empty_page';
+// import { WithSource, indicesExistOrDataTemporarilyUnavailable } from '../../containers/source';
import { SpyRoute } from '../../utils/route/spy_routes';
import * as i18n from './translations';
-const basePath = chrome.getBasePath();
+// const basePath = chrome.getBasePath();
export const DetectionEngineComponent = pure(() => {
return (
<>
-
+ {'HELLO WORLD'}
{/*
{({ indicesExist }) =>
indicesExistOrDataTemporarilyUnavailable(indicesExist) ? (
diff --git a/x-pack/legacy/plugins/siem/public/pages/home/index.tsx b/x-pack/legacy/plugins/siem/public/pages/home/index.tsx
index 3815710a1224e..fe2ee59dcb28f 100644
--- a/x-pack/legacy/plugins/siem/public/pages/home/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/home/index.tsx
@@ -153,7 +153,7 @@ export const HomePage = pure(() => (
)}
/>
- } />
+ } />
} />
Date: Tue, 8 Oct 2019 16:02:57 -0400
Subject: [PATCH 03/57] rough out basic page routing
---
.../components/header_page/header_page.tsx | 42 ++++++++--
.../public/components/link_to/link_to.tsx | 26 +++++-
.../link_to/redirect_to_detection_engine.tsx | 27 ++++++
.../public/components/url_state/helpers.ts | 20 ++---
.../siem/public/components/url_state/types.ts | 8 +-
.../create_rule/index.test.tsx | 78 +++++++++++++++++
.../detection_engine/create_rule/index.tsx | 26 ++++++
.../create_rule/translations.ts | 11 +++
.../detection_engine/detection_engine.tsx | 83 ++++++++++++-------
.../detection_engine/edit_rule/index.test.tsx | 78 +++++++++++++++++
.../detection_engine/edit_rule/index.tsx | 31 +++++++
.../edit_rule/translations.ts | 11 +++
.../public/pages/detection_engine/index.tsx | 39 ++++++++-
.../rule_details/index.test.tsx | 78 +++++++++++++++++
.../detection_engine/rule_details/index.tsx | 44 ++++++++++
.../rule_details/translations.ts | 11 +++
.../detection_engine/rules/index.test.tsx | 78 +++++++++++++++++
.../pages/detection_engine/rules/index.tsx | 42 ++++++++++
.../detection_engine/rules/translations.ts | 11 +++
.../pages/detection_engine/translations.ts | 32 +++----
.../plugins/siem/public/pages/home/index.tsx | 9 +-
.../siem/public/pages/home/translations.ts | 2 +-
22 files changed, 709 insertions(+), 78 deletions(-)
create mode 100644 x-pack/legacy/plugins/siem/public/pages/detection_engine/create_rule/index.test.tsx
create mode 100644 x-pack/legacy/plugins/siem/public/pages/detection_engine/create_rule/index.tsx
create mode 100644 x-pack/legacy/plugins/siem/public/pages/detection_engine/create_rule/translations.ts
create mode 100644 x-pack/legacy/plugins/siem/public/pages/detection_engine/edit_rule/index.test.tsx
create mode 100644 x-pack/legacy/plugins/siem/public/pages/detection_engine/edit_rule/index.tsx
create mode 100644 x-pack/legacy/plugins/siem/public/pages/detection_engine/edit_rule/translations.ts
create mode 100644 x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.test.tsx
create mode 100644 x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.tsx
create mode 100644 x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/translations.ts
create mode 100644 x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.test.tsx
create mode 100644 x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
create mode 100644 x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/translations.ts
diff --git a/x-pack/legacy/plugins/siem/public/components/header_page/header_page.tsx b/x-pack/legacy/plugins/siem/public/components/header_page/header_page.tsx
index 2ba543b34307a..17906489cd191 100644
--- a/x-pack/legacy/plugins/siem/public/components/header_page/header_page.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/header_page/header_page.tsx
@@ -4,7 +4,15 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { EuiBetaBadge, EuiFlexGroup, EuiFlexItem, EuiText, EuiTitle } from '@elastic/eui';
+import {
+ EuiBetaBadge,
+ EuiFlexGroup,
+ EuiFlexItem,
+ EuiIcon,
+ EuiLink,
+ EuiText,
+ EuiTitle,
+} from '@elastic/eui';
import React from 'react';
import { pure } from 'recompose';
import styled from 'styled-components';
@@ -26,6 +34,8 @@ interface DraggableArguments {
}
export interface HeaderPageProps {
+ backLink?: string;
+ backText?: string;
badgeLabel?: string;
badgeTooltip?: string;
children?: React.ReactNode;
@@ -35,10 +45,30 @@ export interface HeaderPageProps {
}
export const HeaderPage = pure(
- ({ badgeLabel, badgeTooltip, children, draggableArguments, subtitle, title, ...rest }) => (
+ ({
+ backLink,
+ backText,
+ badgeLabel,
+ badgeTooltip,
+ children,
+ draggableArguments,
+ subtitle,
+ title,
+ ...rest
+ }) => (
+ {backLink && backText && (
+
+
+
+ {backText}
+
+
+
+ )}
+
{!draggableArguments ? (
@@ -64,9 +94,11 @@ export const HeaderPage = pure(
-
- {subtitle}
-
+ {subtitle && (
+
+ {subtitle}
+
+ )}
{children && {children}}
diff --git a/x-pack/legacy/plugins/siem/public/components/link_to/link_to.tsx b/x-pack/legacy/plugins/siem/public/components/link_to/link_to.tsx
index 53c3d188c8b46..6c1bf05f2acfe 100644
--- a/x-pack/legacy/plugins/siem/public/components/link_to/link_to.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/link_to/link_to.tsx
@@ -12,7 +12,13 @@ import { RedirectToHostsPage, RedirectToHostDetailsPage } from './redirect_to_ho
import { RedirectToNetworkPage } from './redirect_to_network';
import { RedirectToOverviewPage } from './redirect_to_overview';
import { RedirectToTimelinesPage } from './redirect_to_timelines';
-import { RedirectToDetectionEnginePage } from './redirect_to_detection_engine';
+import {
+ RedirectToCreateRulePage,
+ RedirectToDetectionEnginePage,
+ RedirectToEditRulePage,
+ RedirectToRuleDetailsPage,
+ RedirectToRulesPage,
+} from './redirect_to_detection_engine';
import { HostsTableType } from '../../store/hosts/model';
interface LinkToPageProps {
@@ -41,11 +47,27 @@ export const LinkToPage = pure(({ match }) => (
path={`${match.url}/:pageName(network)/ip/:detailName`}
component={RedirectToNetworkPage}
/>
-
+
+
+
+
+
));
diff --git a/x-pack/legacy/plugins/siem/public/components/link_to/redirect_to_detection_engine.tsx b/x-pack/legacy/plugins/siem/public/components/link_to/redirect_to_detection_engine.tsx
index 9780202787bea..6999fec2f00f8 100644
--- a/x-pack/legacy/plugins/siem/public/components/link_to/redirect_to_detection_engine.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/link_to/redirect_to_detection_engine.tsx
@@ -20,4 +20,31 @@ export const RedirectToDetectionEnginePage = ({
);
+export const RedirectToRulesPage = ({ location: { search } }: DetectionEngineComponentProps) => {
+ return ;
+};
+
+export const RedirectToCreateRulePage = ({
+ location: { search },
+}: DetectionEngineComponentProps) => {
+ return ;
+};
+
+export const RedirectToRuleDetailsPage = ({
+ location: { search },
+}: DetectionEngineComponentProps) => {
+ return ;
+};
+
+export const RedirectToEditRulePage = ({ location: { search } }: DetectionEngineComponentProps) => {
+ return (
+
+ );
+};
+
export const getDetectionEngineUrl = () => `#/link-to/${DETECTION_ENGINE_PAGE_NAME}`;
+export const getRulesUrl = () => `#/link-to/${DETECTION_ENGINE_PAGE_NAME}/rules`;
+export const getCreateRuleUrl = () => `#/link-to/${DETECTION_ENGINE_PAGE_NAME}/rules/create-rule`;
+export const getRuleDetailsUrl = () => `#/link-to/${DETECTION_ENGINE_PAGE_NAME}/rules/rule-details`;
+export const getEditRuleUrl = () =>
+ `#/link-to/${DETECTION_ENGINE_PAGE_NAME}/rules/rule-details/edit-rule`;
diff --git a/x-pack/legacy/plugins/siem/public/components/url_state/helpers.ts b/x-pack/legacy/plugins/siem/public/components/url_state/helpers.ts
index 903bec968d16b..bb390f3f2688a 100644
--- a/x-pack/legacy/plugins/siem/public/components/url_state/helpers.ts
+++ b/x-pack/legacy/plugins/siem/public/components/url_state/helpers.ts
@@ -75,16 +75,16 @@ export const replaceQueryStringInLocation = (location: Location, queryString: st
};
export const getUrlType = (pageName: string): UrlStateType => {
- if (pageName === SiemPageName.hosts) {
+ if (pageName === SiemPageName.overview) {
+ return 'overview';
+ } else if (pageName === SiemPageName.hosts) {
return 'host';
} else if (pageName === SiemPageName.network) {
return 'network';
- } else if (pageName === SiemPageName.overview) {
- return 'overview';
- } else if (pageName === SiemPageName.timelines) {
- return 'timeline';
} else if (pageName === SiemPageName.detectionEngine) {
return 'detection-engine';
+ } else if (pageName === SiemPageName.timelines) {
+ return 'timeline';
}
return 'overview';
};
@@ -102,7 +102,9 @@ export const getCurrentLocation = (
pageName: string,
detailName: string | undefined
): LocationTypes => {
- if (pageName === SiemPageName.hosts) {
+ if (pageName === SiemPageName.overview) {
+ return CONSTANTS.overviewPage;
+ } else if (pageName === SiemPageName.hosts) {
if (detailName != null) {
return CONSTANTS.hostsDetails;
}
@@ -112,12 +114,10 @@ export const getCurrentLocation = (
return CONSTANTS.networkDetails;
}
return CONSTANTS.networkPage;
- } else if (pageName === SiemPageName.overview) {
- return CONSTANTS.overviewPage;
- } else if (pageName === SiemPageName.timelines) {
- return CONSTANTS.timelinePage;
} else if (pageName === SiemPageName.detectionEngine) {
return CONSTANTS.detectionEnginePage;
+ } else if (pageName === SiemPageName.timelines) {
+ return CONSTANTS.timelinePage;
}
return CONSTANTS.unknown;
};
diff --git a/x-pack/legacy/plugins/siem/public/components/url_state/types.ts b/x-pack/legacy/plugins/siem/public/components/url_state/types.ts
index aa8261b56714f..596733923d35e 100644
--- a/x-pack/legacy/plugins/siem/public/components/url_state/types.ts
+++ b/x-pack/legacy/plugins/siem/public/components/url_state/types.ts
@@ -23,19 +23,19 @@ export const ALL_URL_STATE_KEYS: KeyUrlState[] = [
];
export const URL_STATE_KEYS: Record = {
+ 'detection-engine': [],
host: [CONSTANTS.kqlQuery, CONSTANTS.timerange, CONSTANTS.timelineId],
network: [CONSTANTS.kqlQuery, CONSTANTS.timerange, CONSTANTS.timelineId],
- timeline: [CONSTANTS.timelineId, CONSTANTS.timerange],
overview: [CONSTANTS.timelineId, CONSTANTS.timerange],
- 'detection-engine': [],
+ timeline: [CONSTANTS.timelineId, CONSTANTS.timerange],
};
export type LocationTypes =
| CONSTANTS.detectionEnginePage
- | CONSTANTS.networkDetails
- | CONSTANTS.networkPage
| CONSTANTS.hostsDetails
| CONSTANTS.hostsPage
+ | CONSTANTS.networkDetails
+ | CONSTANTS.networkPage
| CONSTANTS.overviewPage
| CONSTANTS.timelinePage
| CONSTANTS.unknown;
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/create_rule/index.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/create_rule/index.test.tsx
new file mode 100644
index 0000000000000..3fee7dc918471
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/create_rule/index.test.tsx
@@ -0,0 +1,78 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { mount } from 'enzyme';
+import { cloneDeep } from 'lodash/fp';
+import * as React from 'react';
+import { MockedProvider } from 'react-apollo/test-utils';
+import { MemoryRouter } from 'react-router-dom';
+
+import { DetectionEngine } from './index';
+
+import '../../mock/ui_settings';
+import { mocksSource } from '../../containers/source/mock';
+import { TestProviders } from '../../mock';
+
+jest.mock('ui/documentation_links', () => ({
+ documentationLinks: {
+ kibana: 'http://www.example.com',
+ },
+}));
+
+let localSource: Array<{
+ request: {};
+ result: {
+ data: {
+ source: {
+ status: {
+ indicesExist: boolean;
+ };
+ };
+ };
+ };
+}>;
+
+describe('DetectionEngine', () => {
+ describe('rendering', () => {
+ beforeEach(() => {
+ localSource = cloneDeep(mocksSource);
+ });
+
+ test('it renders the Setup Instructions text when no index is available', async () => {
+ localSource[0].result.data.source.status.indicesExist = false;
+ const wrapper = mount(
+
+
+
+
+
+
+
+ );
+ // Why => https://github.com/apollographql/react-apollo/issues/1711
+ await new Promise(resolve => setTimeout(resolve));
+ wrapper.update();
+ expect(wrapper.find('[data-test-subj="empty-page"]').exists()).toBe(true);
+ });
+
+ test('it DOES NOT render the Getting started text when an index is available', async () => {
+ localSource[0].result.data.source.status.indicesExist = true;
+ const wrapper = mount(
+
+
+
+
+
+
+
+ );
+ // Why => https://github.com/apollographql/react-apollo/issues/1711
+ await new Promise(resolve => setTimeout(resolve));
+ wrapper.update();
+ expect(wrapper.find('[data-test-subj="empty-page"]').exists()).toBe(false);
+ });
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/create_rule/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/create_rule/index.tsx
new file mode 100644
index 0000000000000..81dcc4782f2f8
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/create_rule/index.tsx
@@ -0,0 +1,26 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import React from 'react';
+
+import { HeaderPage } from '../../../components/header_page';
+import { SpyRoute } from '../../../utils/route/spy_routes';
+import * as i18n from './translations';
+
+export const CreateRuleComponent = React.memo(() => {
+ return (
+ <>
+
+
+
+ >
+ );
+});
+CreateRuleComponent.displayName = 'CreateRuleComponent';
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/create_rule/translations.ts b/x-pack/legacy/plugins/siem/public/pages/detection_engine/create_rule/translations.ts
new file mode 100644
index 0000000000000..884f3f3741228
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/create_rule/translations.ts
@@ -0,0 +1,11 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { i18n } from '@kbn/i18n';
+
+export const PAGE_TITLE = i18n.translate('xpack.siem.detectionEngine.createRule.pageTitle', {
+ defaultMessage: 'Create new rule',
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
index f038a74822902..2abe3d1d1bab0 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
@@ -4,46 +4,69 @@
* you may not use this file except in compliance with the Elastic License.
*/
+import { EuiButton, EuiButtonGroup, EuiFieldSearch, EuiPanel, EuiSpacer } from '@elastic/eui';
import React from 'react';
-import { pure } from 'recompose';
-// import chrome from 'ui/chrome';
-// import { documentationLinks } from 'ui/documentation_links';
+import { StickyContainer } from 'react-sticky';
+import { FiltersGlobal } from '../../components/filters_global';
import { HeaderPage } from '../../components/header_page';
-// import { GlobalTime } from '../../containers/global_time';
-//
-// import { EmptyPage } from '../../components/empty_page';
-// import { WithSource, indicesExistOrDataTemporarilyUnavailable } from '../../containers/source';
+import { HeaderPanel } from '../../components/header_panel';
import { SpyRoute } from '../../utils/route/spy_routes';
-
import * as i18n from './translations';
-// const basePath = chrome.getBasePath();
+export const DetectionEngineComponent = React.memo(() => {
+ const idPrefix = 'signalType';
+ const toggleButtons = [
+ {
+ id: `${idPrefix}0`,
+ label: 'Open signals',
+ },
+ {
+ id: `${idPrefix}1`,
+ label: 'Closed signals',
+ },
+ ];
-export const DetectionEngineComponent = pure(() => {
return (
<>
-
- {'HELLO WORLD'}
- {/*
- {({ indicesExist }) =>
- indicesExistOrDataTemporarilyUnavailable(indicesExist) ? (
- {({ setQuery }) => Testing...
}
- ) : (
-
+
+
+
+
+
+
+ {i18n.BUTTON_MANAGE_RULES}
+
+
+
+
+ {'Stack by...'}
+ {'Chart here...'}
+
+
+
+
+
+
+ null}
+ options={toggleButtons}
/>
- )
- }
- */}
+
+ {'Table here...'}
+
+
+
>
);
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/edit_rule/index.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/edit_rule/index.test.tsx
new file mode 100644
index 0000000000000..3fee7dc918471
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/edit_rule/index.test.tsx
@@ -0,0 +1,78 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { mount } from 'enzyme';
+import { cloneDeep } from 'lodash/fp';
+import * as React from 'react';
+import { MockedProvider } from 'react-apollo/test-utils';
+import { MemoryRouter } from 'react-router-dom';
+
+import { DetectionEngine } from './index';
+
+import '../../mock/ui_settings';
+import { mocksSource } from '../../containers/source/mock';
+import { TestProviders } from '../../mock';
+
+jest.mock('ui/documentation_links', () => ({
+ documentationLinks: {
+ kibana: 'http://www.example.com',
+ },
+}));
+
+let localSource: Array<{
+ request: {};
+ result: {
+ data: {
+ source: {
+ status: {
+ indicesExist: boolean;
+ };
+ };
+ };
+ };
+}>;
+
+describe('DetectionEngine', () => {
+ describe('rendering', () => {
+ beforeEach(() => {
+ localSource = cloneDeep(mocksSource);
+ });
+
+ test('it renders the Setup Instructions text when no index is available', async () => {
+ localSource[0].result.data.source.status.indicesExist = false;
+ const wrapper = mount(
+
+
+
+
+
+
+
+ );
+ // Why => https://github.com/apollographql/react-apollo/issues/1711
+ await new Promise(resolve => setTimeout(resolve));
+ wrapper.update();
+ expect(wrapper.find('[data-test-subj="empty-page"]').exists()).toBe(true);
+ });
+
+ test('it DOES NOT render the Getting started text when an index is available', async () => {
+ localSource[0].result.data.source.status.indicesExist = true;
+ const wrapper = mount(
+
+
+
+
+
+
+
+ );
+ // Why => https://github.com/apollographql/react-apollo/issues/1711
+ await new Promise(resolve => setTimeout(resolve));
+ wrapper.update();
+ expect(wrapper.find('[data-test-subj="empty-page"]').exists()).toBe(false);
+ });
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/edit_rule/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/edit_rule/index.tsx
new file mode 100644
index 0000000000000..d220dcc1dfbc5
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/edit_rule/index.tsx
@@ -0,0 +1,31 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { EuiButton } from '@elastic/eui';
+import React from 'react';
+
+import { HeaderPage } from '../../../components/header_page';
+import { SpyRoute } from '../../../utils/route/spy_routes';
+import * as i18n from './translations';
+
+export const EditRuleComponent = React.memo(() => {
+ return (
+ <>
+
+
+ {'Save changes'}
+
+
+
+
+ >
+ );
+});
+EditRuleComponent.displayName = 'EditRuleComponent';
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/edit_rule/translations.ts b/x-pack/legacy/plugins/siem/public/pages/detection_engine/edit_rule/translations.ts
new file mode 100644
index 0000000000000..cc2e2565eb8d0
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/edit_rule/translations.ts
@@ -0,0 +1,11 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { i18n } from '@kbn/i18n';
+
+export const PAGE_TITLE = i18n.translate('xpack.siem.detectionEngine.editRule.pageTitle', {
+ defaultMessage: 'Edit rule settings',
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/index.tsx
index 6f2b10e1e4dc0..f64d56c8822c4 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/index.tsx
@@ -4,9 +4,42 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import React, { memo } from 'react';
+import React from 'react';
+import { Redirect, Route, Switch, RouteComponentProps } from 'react-router-dom';
+import { CreateRuleComponent } from './create_rule';
+import { EditRuleComponent } from './edit_rule';
import { DetectionEngineComponent } from './detection_engine';
+import { RuleDetailsComponent } from './rule_details';
+import { RulesComponent } from './rules';
-export const DetectionEngine = memo(() => );
-DetectionEngine.displayName = 'DetectionEngine';
+const detectionEnginePath = `/:pageName(detection-engine)`;
+
+type Props = Partial> & { url: string };
+
+export const DetectionEngineContainer = React.memo(() => (
+
+ } strict />
+ } />
+ }
+ />
+ }
+ />
+ }
+ />
+ (
+
+ )}
+ />
+
+));
+DetectionEngineContainer.displayName = 'DetectionEngineContainer';
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.test.tsx
new file mode 100644
index 0000000000000..3fee7dc918471
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.test.tsx
@@ -0,0 +1,78 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { mount } from 'enzyme';
+import { cloneDeep } from 'lodash/fp';
+import * as React from 'react';
+import { MockedProvider } from 'react-apollo/test-utils';
+import { MemoryRouter } from 'react-router-dom';
+
+import { DetectionEngine } from './index';
+
+import '../../mock/ui_settings';
+import { mocksSource } from '../../containers/source/mock';
+import { TestProviders } from '../../mock';
+
+jest.mock('ui/documentation_links', () => ({
+ documentationLinks: {
+ kibana: 'http://www.example.com',
+ },
+}));
+
+let localSource: Array<{
+ request: {};
+ result: {
+ data: {
+ source: {
+ status: {
+ indicesExist: boolean;
+ };
+ };
+ };
+ };
+}>;
+
+describe('DetectionEngine', () => {
+ describe('rendering', () => {
+ beforeEach(() => {
+ localSource = cloneDeep(mocksSource);
+ });
+
+ test('it renders the Setup Instructions text when no index is available', async () => {
+ localSource[0].result.data.source.status.indicesExist = false;
+ const wrapper = mount(
+
+
+
+
+
+
+
+ );
+ // Why => https://github.com/apollographql/react-apollo/issues/1711
+ await new Promise(resolve => setTimeout(resolve));
+ wrapper.update();
+ expect(wrapper.find('[data-test-subj="empty-page"]').exists()).toBe(true);
+ });
+
+ test('it DOES NOT render the Getting started text when an index is available', async () => {
+ localSource[0].result.data.source.status.indicesExist = true;
+ const wrapper = mount(
+
+
+
+
+
+
+
+ );
+ // Why => https://github.com/apollographql/react-apollo/issues/1711
+ await new Promise(resolve => setTimeout(resolve));
+ wrapper.update();
+ expect(wrapper.find('[data-test-subj="empty-page"]').exists()).toBe(false);
+ });
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.tsx
new file mode 100644
index 0000000000000..09249d1cec70e
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.tsx
@@ -0,0 +1,44 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { EuiButton, EuiButtonIcon, EuiFlexGroup, EuiFlexItem, EuiSwitch } from '@elastic/eui';
+import React from 'react';
+
+import { HeaderPage } from '../../../components/header_page';
+import { SpyRoute } from '../../../utils/route/spy_routes';
+import * as i18n from './translations';
+
+export const RuleDetailsComponent = React.memo(() => {
+ return (
+ <>
+
+
+
+
+
+
+
+
+ {'Edit rule settings'}
+
+
+
+
+
+
+
+
+
+
+ >
+ );
+});
+RuleDetailsComponent.displayName = 'RuleDetailsComponent';
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/translations.ts b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/translations.ts
new file mode 100644
index 0000000000000..3dd5945ff597c
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/translations.ts
@@ -0,0 +1,11 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { i18n } from '@kbn/i18n';
+
+export const PAGE_TITLE = i18n.translate('xpack.siem.detectionEngine.ruleDetails.pageTitle', {
+ defaultMessage: 'Rule details',
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.test.tsx
new file mode 100644
index 0000000000000..3fee7dc918471
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.test.tsx
@@ -0,0 +1,78 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { mount } from 'enzyme';
+import { cloneDeep } from 'lodash/fp';
+import * as React from 'react';
+import { MockedProvider } from 'react-apollo/test-utils';
+import { MemoryRouter } from 'react-router-dom';
+
+import { DetectionEngine } from './index';
+
+import '../../mock/ui_settings';
+import { mocksSource } from '../../containers/source/mock';
+import { TestProviders } from '../../mock';
+
+jest.mock('ui/documentation_links', () => ({
+ documentationLinks: {
+ kibana: 'http://www.example.com',
+ },
+}));
+
+let localSource: Array<{
+ request: {};
+ result: {
+ data: {
+ source: {
+ status: {
+ indicesExist: boolean;
+ };
+ };
+ };
+ };
+}>;
+
+describe('DetectionEngine', () => {
+ describe('rendering', () => {
+ beforeEach(() => {
+ localSource = cloneDeep(mocksSource);
+ });
+
+ test('it renders the Setup Instructions text when no index is available', async () => {
+ localSource[0].result.data.source.status.indicesExist = false;
+ const wrapper = mount(
+
+
+
+
+
+
+
+ );
+ // Why => https://github.com/apollographql/react-apollo/issues/1711
+ await new Promise(resolve => setTimeout(resolve));
+ wrapper.update();
+ expect(wrapper.find('[data-test-subj="empty-page"]').exists()).toBe(true);
+ });
+
+ test('it DOES NOT render the Getting started text when an index is available', async () => {
+ localSource[0].result.data.source.status.indicesExist = true;
+ const wrapper = mount(
+
+
+
+
+
+
+
+ );
+ // Why => https://github.com/apollographql/react-apollo/issues/1711
+ await new Promise(resolve => setTimeout(resolve));
+ wrapper.update();
+ expect(wrapper.find('[data-test-subj="empty-page"]').exists()).toBe(false);
+ });
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
new file mode 100644
index 0000000000000..1db10a613c7d4
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
@@ -0,0 +1,42 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { EuiButton, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
+import React from 'react';
+
+import { HeaderPage } from '../../../components/header_page';
+import { SpyRoute } from '../../../utils/route/spy_routes';
+import * as i18n from './translations';
+
+export const RulesComponent = React.memo(() => {
+ return (
+ <>
+
+
+
+
+ {'Import rule…'}
+
+
+
+
+
+ {'Add new rule'}
+
+
+
+
+
+
+ >
+ );
+});
+RulesComponent.displayName = 'RulesComponent';
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/translations.ts b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/translations.ts
new file mode 100644
index 0000000000000..2b20c726d4b3f
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/translations.ts
@@ -0,0 +1,11 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { i18n } from '@kbn/i18n';
+
+export const PAGE_TITLE = i18n.translate('xpack.siem.detectionEngine.rules.pageTitle', {
+ defaultMessage: 'Rules',
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/translations.ts b/x-pack/legacy/plugins/siem/public/pages/detection_engine/translations.ts
index d85dabd9324c2..165a560484d1b 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/translations.ts
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/translations.ts
@@ -7,30 +7,20 @@
import { i18n } from '@kbn/i18n';
export const PAGE_TITLE = i18n.translate('xpack.siem.detectionEngine.pageTitle', {
- defaultMessage: 'Detection Engine',
+ defaultMessage: 'Detection engine',
});
-export const PAGE_SUBTITLE = i18n.translate('xpack.siem.overview.pageSubtitle', {
- defaultMessage: 'Security Information & Event Management with the Elastic Stack',
+export const PAGE_SUBTITLE = i18n.translate('xpack.siem.detectionEngine.pageSubtitle', {
+ defaultMessage: 'Last signal: X minutes ago',
});
-export const PAGE_BADGE_LABEL = i18n.translate('xpack.siem.overview.pageBadgeLabel', {
- defaultMessage: 'Beta',
+export const BUTTON_MANAGE_RULES = i18n.translate('xpack.siem.detectionEngine.buttonManageRules', {
+ defaultMessage: 'Manage rules',
});
-export const PAGE_BADGE_TOOLTIP = i18n.translate('xpack.siem.overview.pageBadgeTooltip', {
- defaultMessage:
- 'SIEM is still in beta. Please help us improve by reporting issues or bugs in the Kibana repo.',
-});
-
-export const EMPTY_TITLE = i18n.translate('xpack.siem.overview.emptyTitle', {
- defaultMessage: 'It looks like you don’t have any indices relevant to the SIEM application',
-});
-
-export const EMPTY_ACTION_PRIMARY = i18n.translate('xpack.siem.overview.emptyActionPrimary', {
- defaultMessage: 'View setup instructions',
-});
-
-export const EMPTY_ACTION_SECONDARY = i18n.translate('xpack.siem.overview.emptyActionSecondary', {
- defaultMessage: 'Go to documentation',
-});
+export const PANEL_SUBTITLE_SHOWING = i18n.translate(
+ 'xpack.siem.detectionEngine.panelSubtitleShowing',
+ {
+ defaultMessage: 'Showing',
+ }
+);
diff --git a/x-pack/legacy/plugins/siem/public/pages/home/index.tsx b/x-pack/legacy/plugins/siem/public/pages/home/index.tsx
index fe2ee59dcb28f..a1081762c3e4f 100644
--- a/x-pack/legacy/plugins/siem/public/pages/home/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/home/index.tsx
@@ -20,7 +20,7 @@ import { SiemNavigation } from '../../components/navigation';
import { StatefulTimeline } from '../../components/timeline';
import { AutoSaveWarningMsg } from '../../components/timeline/auto_save_warning';
import { NotFoundPage } from '../404';
-import { DetectionEngine } from '../detection_engine';
+import { DetectionEngineContainer } from '../detection_engine';
import { HostsContainer } from '../hosts';
import { NetworkContainer } from '../network';
import { Overview } from '../overview';
@@ -153,7 +153,12 @@ export const HomePage = pure(() => (
)}
/>
- } />
+ (
+
+ )}
+ />
} />
Date: Tue, 8 Oct 2019 16:23:09 -0400
Subject: [PATCH 04/57] kql placeholder
---
.../detection_engine/detection_engine.tsx | 11 ++--
.../public/pages/detection_engine/kql.tsx | 15 ++++++
.../detection_engine/rule_details/index.tsx | 52 ++++++++++++-------
.../pages/detection_engine/rules/index.tsx | 2 +-
.../pages/detection_engine/translations.ts | 8 +++
5 files changed, 60 insertions(+), 28 deletions(-)
create mode 100644 x-pack/legacy/plugins/siem/public/pages/detection_engine/kql.tsx
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
index 2abe3d1d1bab0..c108d6ce9b238 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
@@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { EuiButton, EuiButtonGroup, EuiFieldSearch, EuiPanel, EuiSpacer } from '@elastic/eui';
+import { EuiButton, EuiButtonGroup, EuiPanel, EuiSpacer } from '@elastic/eui';
import React from 'react';
import { StickyContainer } from 'react-sticky';
@@ -12,6 +12,7 @@ import { FiltersGlobal } from '../../components/filters_global';
import { HeaderPage } from '../../components/header_page';
import { HeaderPanel } from '../../components/header_panel';
import { SpyRoute } from '../../utils/route/spy_routes';
+import { DetectionEngineKql } from './kql';
import * as i18n from './translations';
export const DetectionEngineComponent = React.memo(() => {
@@ -31,11 +32,7 @@ export const DetectionEngineComponent = React.memo(() => {
<>
-
+
@@ -63,7 +60,7 @@ export const DetectionEngineComponent = React.memo(() => {
options={toggleButtons}
/>
- {'Table here...'}
+ {'Datagrid here...'}
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/kql.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/kql.tsx
new file mode 100644
index 0000000000000..9a9a4713bbd7c
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/kql.tsx
@@ -0,0 +1,15 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { EuiFieldSearch } from '@elastic/eui';
+import React from 'react';
+
+import * as i18n from './translations';
+
+export const DetectionEngineKql = React.memo(() => (
+
+));
+DetectionEngineKql.displayName = 'DetectionEngineKql';
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.tsx
index 09249d1cec70e..4b3bc2f7afbd0 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.tsx
@@ -6,36 +6,48 @@
import { EuiButton, EuiButtonIcon, EuiFlexGroup, EuiFlexItem, EuiSwitch } from '@elastic/eui';
import React from 'react';
+import { StickyContainer } from 'react-sticky';
+import { FiltersGlobal } from '../../../components/filters_global';
import { HeaderPage } from '../../../components/header_page';
import { SpyRoute } from '../../../utils/route/spy_routes';
+import { DetectionEngineKql } from '../kql';
import * as i18n from './translations';
export const RuleDetailsComponent = React.memo(() => {
return (
<>
-
-
-
-
-
+
+
+
+
-
-
- {'Edit rule settings'}
-
-
+
+
+
+
+
-
-
-
-
-
+
+
+ {'Edit rule settings'}
+
+
+
+
+
+
+
+
+
>
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
index 1db10a613c7d4..ca9e0e14465f0 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
@@ -23,7 +23,7 @@ export const RulesComponent = React.memo(() => {
- {'Import rule…'}
+ {'Import rule…'}
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/translations.ts b/x-pack/legacy/plugins/siem/public/pages/detection_engine/translations.ts
index 165a560484d1b..4bb5ec76e77cf 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/translations.ts
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/translations.ts
@@ -6,6 +6,14 @@
import { i18n } from '@kbn/i18n';
+export const KQL_ARIA_LABEL = i18n.translate('xpack.siem.detectionEngine.kqlAriaLabel', {
+ defaultMessage: 'KQL filter',
+});
+
+export const KQL_PLACEHOLDER = i18n.translate('xpack.siem.detectionEngine.kqlPlaceholder', {
+ defaultMessage: 'e.g. event.action: "foo"',
+});
+
export const PAGE_TITLE = i18n.translate('xpack.siem.detectionEngine.pageTitle', {
defaultMessage: 'Detection engine',
});
From ca77faaa5b8a5556ab6b10c00d1e20ff7fc6a0a2 Mon Sep 17 00:00:00 2001
From: Michael Marcialis
Date: Thu, 10 Oct 2019 11:05:37 -0400
Subject: [PATCH 05/57] update page and panel headers
---
.../components/header_page/header_page.tsx | 110 ------------
.../{header_page.test.tsx => index.test.tsx} | 0
.../public/components/header_page/index.tsx | 120 ++++++++++++-
.../public/components/header_panel/index.tsx | 27 ++-
.../__snapshots__/index.test.tsx.snap | 9 +
.../components/link_back/index.test.tsx | 160 ++++++++++++++++++
.../public/components/link_back/index.tsx | 41 +++++
.../__snapshots__/index.test.tsx.snap | 9 +
.../public/components/subtitle/index.test.tsx | 160 ++++++++++++++++++
.../siem/public/components/subtitle/index.tsx | 49 ++++++
.../detection_engine/create_rule/index.tsx | 4 +-
.../detection_engine/detection_engine.tsx | 63 ++++++-
.../detection_engine/edit_rule/index.tsx | 7 +-
.../detection_engine/rule_details/index.tsx | 11 +-
.../pages/detection_engine/rules/index.tsx | 130 +++++++++++++-
.../siem/public/pages/hosts/details/index.tsx | 3 +-
.../plugins/siem/public/pages/hosts/hosts.tsx | 3 +-
.../siem/public/pages/network/ip_details.tsx | 5 +-
.../siem/public/pages/network/network.tsx | 3 +-
.../siem/public/pages/overview/overview.tsx | 4 +-
.../public/pages/timelines/timelines_page.tsx | 2 +-
21 files changed, 769 insertions(+), 151 deletions(-)
delete mode 100644 x-pack/legacy/plugins/siem/public/components/header_page/header_page.tsx
rename x-pack/legacy/plugins/siem/public/components/header_page/{header_page.test.tsx => index.test.tsx} (100%)
create mode 100644 x-pack/legacy/plugins/siem/public/components/link_back/__snapshots__/index.test.tsx.snap
create mode 100644 x-pack/legacy/plugins/siem/public/components/link_back/index.test.tsx
create mode 100644 x-pack/legacy/plugins/siem/public/components/link_back/index.tsx
create mode 100644 x-pack/legacy/plugins/siem/public/components/subtitle/__snapshots__/index.test.tsx.snap
create mode 100644 x-pack/legacy/plugins/siem/public/components/subtitle/index.test.tsx
create mode 100644 x-pack/legacy/plugins/siem/public/components/subtitle/index.tsx
diff --git a/x-pack/legacy/plugins/siem/public/components/header_page/header_page.tsx b/x-pack/legacy/plugins/siem/public/components/header_page/header_page.tsx
deleted file mode 100644
index 17906489cd191..0000000000000
--- a/x-pack/legacy/plugins/siem/public/components/header_page/header_page.tsx
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import {
- EuiBetaBadge,
- EuiFlexGroup,
- EuiFlexItem,
- EuiIcon,
- EuiLink,
- EuiText,
- EuiTitle,
-} from '@elastic/eui';
-import React from 'react';
-import { pure } from 'recompose';
-import styled from 'styled-components';
-import { DefaultDraggable } from '../draggables';
-
-const Header = styled.header`
- ${({ theme }) => `
- border-bottom: ${theme.eui.euiBorderThin};
- padding-bottom: ${theme.eui.euiSizeL};
- margin: ${theme.eui.euiSizeL} 0;
- `}
-`;
-
-Header.displayName = 'Header';
-
-interface DraggableArguments {
- field: string;
- value: string;
-}
-
-export interface HeaderPageProps {
- backLink?: string;
- backText?: string;
- badgeLabel?: string;
- badgeTooltip?: string;
- children?: React.ReactNode;
- draggableArguments?: DraggableArguments;
- subtitle?: string | React.ReactNode;
- title: string | React.ReactNode;
-}
-
-export const HeaderPage = pure(
- ({
- backLink,
- backText,
- badgeLabel,
- badgeTooltip,
- children,
- draggableArguments,
- subtitle,
- title,
- ...rest
- }) => (
-
-
-
- {backLink && backText && (
-
-
-
- {backText}
-
-
-
- )}
-
-
-
- {!draggableArguments ? (
- title
- ) : (
-
- )}
- {badgeLabel && (
- <>
- {' '}
-
- >
- )}
-
-
-
- {subtitle && (
-
- {subtitle}
-
- )}
-
-
- {children && {children}}
-
-
- )
-);
-
-HeaderPage.displayName = 'HeaderPage';
diff --git a/x-pack/legacy/plugins/siem/public/components/header_page/header_page.test.tsx b/x-pack/legacy/plugins/siem/public/components/header_page/index.test.tsx
similarity index 100%
rename from x-pack/legacy/plugins/siem/public/components/header_page/header_page.test.tsx
rename to x-pack/legacy/plugins/siem/public/components/header_page/index.test.tsx
diff --git a/x-pack/legacy/plugins/siem/public/components/header_page/index.tsx b/x-pack/legacy/plugins/siem/public/components/header_page/index.tsx
index 9d89cdfc32893..0e830b53fed6b 100644
--- a/x-pack/legacy/plugins/siem/public/components/header_page/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/header_page/index.tsx
@@ -4,4 +4,122 @@
* you may not use this file except in compliance with the Elastic License.
*/
-export { HeaderPage } from './header_page';
+import { EuiBetaBadge, EuiBadge, EuiFlexGroup, EuiFlexItem, EuiTitle } from '@elastic/eui';
+import React from 'react';
+import styled, { css } from 'styled-components';
+
+import { DefaultDraggable } from '../draggables';
+import { LinkBack, LinkBackProps } from '../link_back';
+import { Subtitle, SubtitleProps } from '../subtitle';
+
+interface HeaderProps {
+ border?: boolean;
+}
+
+const Header = styled.header.attrs({
+ className: 'siemHeaderPage',
+})`
+ ${({ border, theme }) => css`
+ margin: ${theme.eui.euiSizeL} 0;
+
+ ${border &&
+ css`
+ border-bottom: ${theme.eui.euiBorderThin};
+ padding-bottom: ${theme.eui.euiSizeL};
+ `}
+ `}
+`;
+Header.displayName = 'Header';
+
+const FlexItem = styled(EuiFlexItem)`
+ display: block;
+`;
+FlexItem.displayName = 'FlexItem';
+
+const Badge = styled(EuiBadge)`
+ letter-spacing: 0;
+`;
+Badge.displayName = 'Badge';
+
+interface BackOptions {
+ href: LinkBackProps['href'];
+ text: LinkBackProps['text'];
+}
+
+interface BadgeOptions {
+ beta?: boolean;
+ text: string;
+ tooltip?: string;
+}
+
+interface DraggableArguments {
+ field: string;
+ value: string;
+}
+
+export interface HeaderPageProps extends HeaderProps {
+ backOptions?: BackOptions;
+ badgeOptions?: BadgeOptions;
+ children?: React.ReactNode;
+ draggableArguments?: DraggableArguments;
+ subtitle?: SubtitleProps['text'];
+ subtitle2?: SubtitleProps['text'];
+ title: string | React.ReactNode;
+}
+
+export const HeaderPage = React.memo(
+ ({
+ backOptions,
+ badgeOptions,
+ border,
+ children,
+ draggableArguments,
+ subtitle,
+ subtitle2,
+ title,
+ ...rest
+ }) => (
+
+
+
+ {backOptions && }
+
+
+
+ {!draggableArguments ? (
+ title
+ ) : (
+
+ )}
+ {badgeOptions && (
+ <>
+ {' '}
+ {badgeOptions.beta ? (
+
+ ) : (
+ {badgeOptions.text}
+ )}
+ >
+ )}
+
+
+
+ {subtitle && }
+ {subtitle2 && }
+
+
+ {children && {children}}
+
+
+ )
+);
+HeaderPage.displayName = 'HeaderPage';
diff --git a/x-pack/legacy/plugins/siem/public/components/header_panel/index.tsx b/x-pack/legacy/plugins/siem/public/components/header_panel/index.tsx
index e7b3fb9f2f400..e02091fcbdf39 100644
--- a/x-pack/legacy/plugins/siem/public/components/header_panel/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/header_panel/index.tsx
@@ -4,11 +4,12 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { EuiFlexGroup, EuiFlexItem, EuiIconTip, EuiText, EuiTitle } from '@elastic/eui';
+import { EuiFlexGroup, EuiFlexItem, EuiIconTip, EuiTitle } from '@elastic/eui';
import React from 'react';
import styled, { css } from 'styled-components';
import { InspectButton } from '../inspect';
+import { Subtitle, SubtitleProps } from '../subtitle';
interface HeaderProps {
border?: boolean;
@@ -17,24 +18,23 @@ interface HeaderProps {
const Header = styled.header.attrs({
className: 'siemHeaderPanel',
})`
- ${props => css`
- margin-bottom: ${props.theme.eui.euiSizeL};
+ ${({ border, theme }) => css`
+ margin-bottom: ${theme.eui.euiSizeL};
user-select: text;
- ${props.border &&
- `
- border-bottom: ${props.theme.eui.euiBorderThin};
- padding-bottom: ${props.theme.eui.euiSizeL};
- `}
+ ${border &&
+ css`
+ border-bottom: ${theme.eui.euiBorderThin};
+ padding-bottom: ${theme.eui.euiSizeL};
+ `}
`}
`;
-
Header.displayName = 'Header';
export interface HeaderPanelProps extends HeaderProps {
children?: React.ReactNode;
id?: string;
- subtitle?: string | React.ReactNode;
+ subtitle?: SubtitleProps['text'];
showInspect?: boolean;
title: string | React.ReactNode;
tooltip?: string;
@@ -59,11 +59,7 @@ export const HeaderPanel = React.memo(
- {subtitle && (
-
- {subtitle}
-
- )}
+ {subtitle && }
{id && (
@@ -83,5 +79,4 @@ export const HeaderPanel = React.memo(
)
);
-
HeaderPanel.displayName = 'HeaderPanel';
diff --git a/x-pack/legacy/plugins/siem/public/components/link_back/__snapshots__/index.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/link_back/__snapshots__/index.test.tsx.snap
new file mode 100644
index 0000000000000..39250c38ef8fc
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/components/link_back/__snapshots__/index.test.tsx.snap
@@ -0,0 +1,9 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`HeaderPanel it renders 1`] = `
+
+
+
+`;
diff --git a/x-pack/legacy/plugins/siem/public/components/link_back/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/link_back/index.test.tsx
new file mode 100644
index 0000000000000..9cdb85bcb3d76
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/components/link_back/index.test.tsx
@@ -0,0 +1,160 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import euiDarkVars from '@elastic/eui/dist/eui_theme_dark.json';
+import { mount, shallow } from 'enzyme';
+import toJson from 'enzyme-to-json';
+import 'jest-styled-components';
+import React from 'react';
+
+import '../../mock/ui_settings';
+import { TestProviders } from '../../mock';
+import { HeaderPanel } from './index';
+
+jest.mock('../../lib/settings/use_kibana_ui_setting');
+
+describe('HeaderPanel', () => {
+ test('it renders', () => {
+ const wrapper = shallow(
+
+
+
+ );
+
+ expect(toJson(wrapper)).toMatchSnapshot();
+ });
+
+ test('it renders the title', () => {
+ const wrapper = mount(
+
+
+
+ );
+
+ expect(
+ wrapper
+ .find('[data-test-subj="header-panel-title"]')
+ .first()
+ .exists()
+ ).toBe(true);
+ });
+
+ test('it renders the subtitle when provided', () => {
+ const wrapper = mount(
+
+
+
+ );
+
+ expect(
+ wrapper
+ .find(`[data-test-subj="header-panel-subtitle"]`)
+ .first()
+ .exists()
+ ).toBe(true);
+ });
+
+ test('it DOES NOT render the subtitle when not provided', () => {
+ const wrapper = mount(
+
+
+
+ );
+
+ expect(
+ wrapper
+ .find(`[data-test-subj="header-panel-subtitle"]`)
+ .first()
+ .exists()
+ ).toBe(false);
+ });
+
+ test('it renders a transparent inspect button when showInspect is false', () => {
+ const wrapper = mount(
+
+
+
+ );
+
+ expect(
+ wrapper
+ .find(`[data-test-subj="transparent-inspect-container"]`)
+ .first()
+ .exists()
+ ).toBe(true);
+ });
+
+ test('it renders an opaque inspect button when showInspect is true', () => {
+ const wrapper = mount(
+
+
+
+ );
+
+ expect(
+ wrapper
+ .find(`[data-test-subj="opaque-inspect-container"]`)
+ .first()
+ .exists()
+ ).toBe(true);
+ });
+
+ test('it renders supplements when children provided', () => {
+ const wrapper = mount(
+
+
+ {'Test children'}
+
+
+ );
+
+ expect(
+ wrapper
+ .find('[data-test-subj="header-panel-supplements"]')
+ .first()
+ .exists()
+ ).toBe(true);
+ });
+
+ test('it DOES NOT render supplements when children not provided', () => {
+ const wrapper = mount(
+
+
+
+ );
+
+ expect(
+ wrapper
+ .find('[data-test-subj="header-panel-supplements"]')
+ .first()
+ .exists()
+ ).toBe(false);
+ });
+
+ test('it applies border styles when border is true', () => {
+ const wrapper = mount(
+
+
+
+ );
+ const siemHeaderPanel = wrapper.find('.siemHeaderPanel').first();
+
+ expect(siemHeaderPanel).toHaveStyleRule('border-bottom', euiDarkVars.euiBorderThin);
+ expect(siemHeaderPanel).toHaveStyleRule('padding-bottom', euiDarkVars.euiSizeL);
+ });
+
+ test('it DOES NOT apply border styles when border is false', () => {
+ const wrapper = mount(
+
+
+
+ );
+ const siemHeaderPanel = wrapper.find('.siemHeaderPanel').first();
+
+ expect(siemHeaderPanel).not.toHaveStyleRule('border-bottom', euiDarkVars.euiBorderThin);
+ expect(siemHeaderPanel).not.toHaveStyleRule('padding-bottom', euiDarkVars.euiSizeL);
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/components/link_back/index.tsx b/x-pack/legacy/plugins/siem/public/components/link_back/index.tsx
new file mode 100644
index 0000000000000..8854478e3dc34
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/components/link_back/index.tsx
@@ -0,0 +1,41 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { EuiIcon, EuiLink } from '@elastic/eui';
+import React from 'react';
+import styled, { css } from 'styled-components';
+
+interface LinkProps {
+ href: string;
+}
+
+const Link = styled(EuiLink).attrs({
+ className: 'siemLinkBack',
+})`
+ ${({ theme }) => css`
+ display: inline-block;
+ font-size: ${theme.eui.euiFontSizeXS};
+ line-height: ${theme.eui.euiLineHeight};
+ margin-bottom: ${theme.eui.euiSizeS};
+
+ .euiIcon {
+ margin-right: ${theme.eui.euiSizeXS};
+ }
+ `}
+`;
+Link.displayName = 'Link';
+
+export interface LinkBackProps extends LinkProps {
+ text: string;
+}
+
+export const LinkBack = React.memo(({ href, text }) => (
+
+
+ {text}
+
+));
+LinkBack.displayName = 'LinkBack';
diff --git a/x-pack/legacy/plugins/siem/public/components/subtitle/__snapshots__/index.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/subtitle/__snapshots__/index.test.tsx.snap
new file mode 100644
index 0000000000000..39250c38ef8fc
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/components/subtitle/__snapshots__/index.test.tsx.snap
@@ -0,0 +1,9 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`HeaderPanel it renders 1`] = `
+
+
+
+`;
diff --git a/x-pack/legacy/plugins/siem/public/components/subtitle/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/subtitle/index.test.tsx
new file mode 100644
index 0000000000000..9cdb85bcb3d76
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/components/subtitle/index.test.tsx
@@ -0,0 +1,160 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import euiDarkVars from '@elastic/eui/dist/eui_theme_dark.json';
+import { mount, shallow } from 'enzyme';
+import toJson from 'enzyme-to-json';
+import 'jest-styled-components';
+import React from 'react';
+
+import '../../mock/ui_settings';
+import { TestProviders } from '../../mock';
+import { HeaderPanel } from './index';
+
+jest.mock('../../lib/settings/use_kibana_ui_setting');
+
+describe('HeaderPanel', () => {
+ test('it renders', () => {
+ const wrapper = shallow(
+
+
+
+ );
+
+ expect(toJson(wrapper)).toMatchSnapshot();
+ });
+
+ test('it renders the title', () => {
+ const wrapper = mount(
+
+
+
+ );
+
+ expect(
+ wrapper
+ .find('[data-test-subj="header-panel-title"]')
+ .first()
+ .exists()
+ ).toBe(true);
+ });
+
+ test('it renders the subtitle when provided', () => {
+ const wrapper = mount(
+
+
+
+ );
+
+ expect(
+ wrapper
+ .find(`[data-test-subj="header-panel-subtitle"]`)
+ .first()
+ .exists()
+ ).toBe(true);
+ });
+
+ test('it DOES NOT render the subtitle when not provided', () => {
+ const wrapper = mount(
+
+
+
+ );
+
+ expect(
+ wrapper
+ .find(`[data-test-subj="header-panel-subtitle"]`)
+ .first()
+ .exists()
+ ).toBe(false);
+ });
+
+ test('it renders a transparent inspect button when showInspect is false', () => {
+ const wrapper = mount(
+
+
+
+ );
+
+ expect(
+ wrapper
+ .find(`[data-test-subj="transparent-inspect-container"]`)
+ .first()
+ .exists()
+ ).toBe(true);
+ });
+
+ test('it renders an opaque inspect button when showInspect is true', () => {
+ const wrapper = mount(
+
+
+
+ );
+
+ expect(
+ wrapper
+ .find(`[data-test-subj="opaque-inspect-container"]`)
+ .first()
+ .exists()
+ ).toBe(true);
+ });
+
+ test('it renders supplements when children provided', () => {
+ const wrapper = mount(
+
+
+ {'Test children'}
+
+
+ );
+
+ expect(
+ wrapper
+ .find('[data-test-subj="header-panel-supplements"]')
+ .first()
+ .exists()
+ ).toBe(true);
+ });
+
+ test('it DOES NOT render supplements when children not provided', () => {
+ const wrapper = mount(
+
+
+
+ );
+
+ expect(
+ wrapper
+ .find('[data-test-subj="header-panel-supplements"]')
+ .first()
+ .exists()
+ ).toBe(false);
+ });
+
+ test('it applies border styles when border is true', () => {
+ const wrapper = mount(
+
+
+
+ );
+ const siemHeaderPanel = wrapper.find('.siemHeaderPanel').first();
+
+ expect(siemHeaderPanel).toHaveStyleRule('border-bottom', euiDarkVars.euiBorderThin);
+ expect(siemHeaderPanel).toHaveStyleRule('padding-bottom', euiDarkVars.euiSizeL);
+ });
+
+ test('it DOES NOT apply border styles when border is false', () => {
+ const wrapper = mount(
+
+
+
+ );
+ const siemHeaderPanel = wrapper.find('.siemHeaderPanel').first();
+
+ expect(siemHeaderPanel).not.toHaveStyleRule('border-bottom', euiDarkVars.euiBorderThin);
+ expect(siemHeaderPanel).not.toHaveStyleRule('padding-bottom', euiDarkVars.euiSizeL);
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/components/subtitle/index.tsx b/x-pack/legacy/plugins/siem/public/components/subtitle/index.tsx
new file mode 100644
index 0000000000000..10ec003baedc9
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/components/subtitle/index.tsx
@@ -0,0 +1,49 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import React from 'react';
+import styled, { css } from 'styled-components';
+
+const SubtitleWrapper = styled.div.attrs({
+ className: 'siemSubtitle',
+})`
+ ${({ theme }) => css`
+ margin-top: ${theme.eui.euiSizeS};
+
+ p {
+ color: ${theme.eui.textColors.subdued};
+ font-size: ${theme.eui.euiFontSizeXS};
+ line-height: ${theme.eui.euiLineHeight};
+
+ @media only screen and (min-width: ${theme.eui.euiBreakpoints.s}) {
+ display: inline-block;
+ margin-right: ${theme.eui.euiSize};
+
+ &:last-child {
+ margin-right: 0;
+ }
+ }
+ }
+ `}
+`;
+SubtitleWrapper.displayName = 'SubtitleWrapper';
+
+export interface SubtitleProps {
+ text: string | string[] | React.ReactNode;
+}
+
+export const Subtitle = React.memo(({ text }) => {
+ return (
+
+ {Array.isArray(text) ? (
+ (text as string[]).map((textItem, i) => {textItem}
)
+ ) : (
+ {text}
+ )}
+
+ );
+});
+Subtitle.displayName = 'Subtitle';
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/create_rule/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/create_rule/index.tsx
index 81dcc4782f2f8..5023d2cb58660 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/create_rule/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/create_rule/index.tsx
@@ -14,8 +14,8 @@ export const CreateRuleComponent = React.memo(() => {
return (
<>
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
index c108d6ce9b238..6db76f7c70f2d 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
@@ -4,7 +4,18 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { EuiButton, EuiButtonGroup, EuiPanel, EuiSpacer } from '@elastic/eui';
+import {
+ Chart,
+ BarSeries,
+ Axis,
+ HistogramBarSeries,
+ Position,
+ getAxisId,
+ getSpecId,
+ ScaleType,
+ Settings,
+} from '@elastic/charts';
+import { EuiButton, EuiButtonGroup, EuiPanel, EuiSelect, EuiSpacer } from '@elastic/eui';
import React from 'react';
import { StickyContainer } from 'react-sticky';
@@ -16,6 +27,19 @@ import { DetectionEngineKql } from './kql';
import * as i18n from './translations';
export const DetectionEngineComponent = React.memo(() => {
+ const stackOptions = [
+ { text: 'Risk scores', value: 'risk_scores' },
+ { text: 'Severities', value: 'severities' },
+ { text: 'Top destination IPs', value: 'destination_ips' },
+ { text: 'Top event actions', value: 'event_actions' },
+ { text: 'Top event categories', value: 'event_categories' },
+ { text: 'Top host names', value: 'host_names' },
+ { text: 'Top rule types', value: 'rule_types' },
+ { text: 'Top rules', value: 'rules' },
+ { text: 'Top source IPs', value: 'source_ips' },
+ { text: 'Top users', value: 'users' },
+ ];
+
const idPrefix = 'signalType';
const toggleButtons = [
{
@@ -35,15 +59,40 @@ export const DetectionEngineComponent = React.memo(() => {
-
+
{i18n.BUTTON_MANAGE_RULES}
- {'Stack by...'}
- {'Chart here...'}
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -56,11 +105,13 @@ export const DetectionEngineComponent = React.memo(() => {
null}
+ onChange={() => {
+ return null;
+ }}
options={toggleButtons}
/>
- {'Datagrid here...'}
+ {'Datagrid here (talk to Chandler Prall about possibility of early access)...'}
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/edit_rule/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/edit_rule/index.tsx
index d220dcc1dfbc5..86708a8544a79 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/edit_rule/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/edit_rule/index.tsx
@@ -15,8 +15,11 @@ export const EditRuleComponent = React.memo(() => {
return (
<>
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.tsx
index 4b3bc2f7afbd0..3e2f59da5fcdb 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.tsx
@@ -23,9 +23,14 @@ export const RuleDetailsComponent = React.memo(() => {
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
index ca9e0e14465f0..33e7f9808fcc6 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
@@ -4,7 +4,22 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { EuiButton, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
+import {
+ EuiBadge,
+ EuiButton,
+ EuiButtonIcon,
+ EuiCheckbox,
+ EuiFieldSearch,
+ EuiFlexGroup,
+ EuiFlexItem,
+ EuiHealth,
+ EuiIcon,
+ EuiLink,
+ EuiSpacer,
+ EuiSwitch,
+ EuiTab,
+ EuiTabs,
+} from '@elastic/eui';
import React from 'react';
import { HeaderPage } from '../../../components/header_page';
@@ -15,8 +30,7 @@ export const RulesComponent = React.memo(() => {
return (
<>
@@ -35,6 +49,116 @@ export const RulesComponent = React.memo(() => {
+
+ {'All rules'}
+ {'Activity monitor'}
+
+
+
+
+
+
+
+
{'All rules'}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {
+ return null;
+ }}
+ />
+ |
+ {'Rule'} |
+ {'Method'} |
+ {'Severity'} |
+ {'Last completed run'} |
+ {'Last response'} |
+ {'Tags'} |
+ {'Activate'} |
+ |
+
+
+
+
+
+
+ {
+ return null;
+ }}
+ />
+ |
+
+
+ {'Automated exfiltration'}
+ {' '}
+ {'Experimental'}
+ |
+ {'Kibana Query Language'} |
+
+ {'Medium'}
+ |
+
+
+ |
+
+ {'Success'}
+ |
+
+ {'attack.t1234'}
+ |
+
+
+ |
+
+
+ |
+
+
+
+
+
>
);
diff --git a/x-pack/legacy/plugins/siem/public/pages/hosts/details/index.tsx b/x-pack/legacy/plugins/siem/public/pages/hosts/details/index.tsx
index 192b692253316..3816d47e283c6 100644
--- a/x-pack/legacy/plugins/siem/public/pages/hosts/details/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/hosts/details/index.tsx
@@ -65,6 +65,7 @@ const HostDetailsComponent = React.memo(
}
@@ -145,7 +146,7 @@ const HostDetailsComponent = React.memo(
) : (
<>
-
+
>
diff --git a/x-pack/legacy/plugins/siem/public/pages/hosts/hosts.tsx b/x-pack/legacy/plugins/siem/public/pages/hosts/hosts.tsx
index bd0252877524e..e45f0f447f316 100644
--- a/x-pack/legacy/plugins/siem/public/pages/hosts/hosts.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/hosts/hosts.tsx
@@ -72,6 +72,7 @@ const HostsComponent = React.memo(
}
title={i18n.PAGE_TITLE}
/>
@@ -110,7 +111,7 @@ const HostsComponent = React.memo(
) : (
<>
-
+
>
)
diff --git a/x-pack/legacy/plugins/siem/public/pages/network/ip_details.tsx b/x-pack/legacy/plugins/siem/public/pages/network/ip_details.tsx
index c6aeaa1f1f4b8..93de041ef2604 100644
--- a/x-pack/legacy/plugins/siem/public/pages/network/ip_details.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/network/ip_details.tsx
@@ -81,10 +81,11 @@ export const IPDetailsComponent = pure(
}
title={ip}
- draggableArguments={{ field: `${flowTarget}.ip`, value: ip }}
>
@@ -280,7 +281,7 @@ export const IPDetailsComponent = pure(
) : (
<>
-
+
>
diff --git a/x-pack/legacy/plugins/siem/public/pages/network/network.tsx b/x-pack/legacy/plugins/siem/public/pages/network/network.tsx
index de75edfb33a4a..7159399da5491 100644
--- a/x-pack/legacy/plugins/siem/public/pages/network/network.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/network/network.tsx
@@ -81,6 +81,7 @@ const NetworkComponent = React.memo(
}
title={i18n.PAGE_TITLE}
/>
@@ -275,7 +276,7 @@ const NetworkComponent = React.memo(
) : (
<>
-
+
>
)
diff --git a/x-pack/legacy/plugins/siem/public/pages/overview/overview.tsx b/x-pack/legacy/plugins/siem/public/pages/overview/overview.tsx
index d8965f4d49491..f94e460eef4b9 100644
--- a/x-pack/legacy/plugins/siem/public/pages/overview/overview.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/overview/overview.tsx
@@ -33,8 +33,8 @@ export const OverviewComponent = pure(() => {
return (
<>
diff --git a/x-pack/legacy/plugins/siem/public/pages/timelines/timelines_page.tsx b/x-pack/legacy/plugins/siem/public/pages/timelines/timelines_page.tsx
index 90eae605de4b7..c4791cbda3396 100644
--- a/x-pack/legacy/plugins/siem/public/pages/timelines/timelines_page.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/timelines/timelines_page.tsx
@@ -30,7 +30,7 @@ export const DEFAULT_SEARCH_RESULTS_PER_PAGE = 10;
export const TimelinesPage = React.memo(({ apolloClient }) => (
<>
-
+
Date: Thu, 10 Oct 2019 13:57:33 -0400
Subject: [PATCH 06/57] rough out card table poc styles
---
.../pages/detection_engine/rules/index.tsx | 202 ++++++++++++++----
1 file changed, 164 insertions(+), 38 deletions(-)
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
index 33e7f9808fcc6..bcf479d1eb6a0 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
@@ -21,11 +21,99 @@ import {
EuiTabs,
} from '@elastic/eui';
import React from 'react';
+import styled, { css } from 'styled-components';
import { HeaderPage } from '../../../components/header_page';
import { SpyRoute } from '../../../utils/route/spy_routes';
import * as i18n from './translations';
+const TableCards = styled.table.attrs({
+ className: 'siemTableCards',
+})`
+ ${({ theme }) => css`
+ display: block;
+ `}
+`;
+TableCards.displayName = 'TableCards';
+
+const TableCardsThead = styled.thead.attrs({
+ className: 'siemTableCards__thead',
+})`
+ ${({ theme }) => css`
+ display: block;
+ `}
+`;
+TableCardsThead.displayName = 'TableCardsThead';
+
+const TableCardsTbody = styled.tbody.attrs({
+ className: 'siemTableCards__tbody',
+})`
+ ${({ theme }) => css`
+ display: block;
+ `}
+`;
+TableCardsTbody.displayName = 'TableCardsTbody';
+
+const TableCardsRow = styled.tr.attrs({
+ className: 'siemTableCards__tr',
+})`
+ ${({ theme }) => css`
+ border-collapse: separate;
+ display: table;
+ table-layout: fixed;
+ width: 100%;
+
+ .siemTableCards__thead & {
+ border: ${theme.eui.euiBorderWidthThin} solid transparent;
+ border-left-width: ${theme.eui.euiSizeXS};
+ }
+
+ .siemTableCards__tbody & {
+ background-color: ${theme.eui.euiColorEmptyShade};
+ border: ${theme.eui.euiBorderThin};
+ border-left-color: ${theme.eui.euiColorSuccess};
+ border-left-width: ${theme.eui.euiSizeXS};
+ border-radius: ${theme.eui.euiBorderRadius};
+ }
+
+ .siemTableCards__tbody & + & {
+ margin-top: ${theme.eui.euiSizeS};
+ }
+ `}
+`;
+TableCardsRow.displayName = 'TableCardsRow';
+
+const TableCardsTh = styled.th.attrs({
+ className: 'siemTableCards__th',
+})`
+ ${({ theme }) => css`
+ font-size: ${theme.eui.euiFontSizeXS};
+ font-weight: ${theme.eui.euiFontWeightSemiBold};
+ line-height: ${theme.eui.euiLineHeight};
+ padding: ${theme.eui.paddingSizes.s};
+ text-align: left;
+ vertical-align: middle;
+
+ .siemTableCards__tbody & {
+ font-size: ${theme.eui.euiFontSizeS};
+ font-weight: ${theme.eui.euiFontWeightRegular};
+ }
+ `}
+`;
+TableCardsTh.displayName = 'TableCardsTh';
+
+const TableCardsTd = styled.td.attrs({
+ className: 'siemTableCards__td',
+})`
+ ${({ theme }) => css`
+ font-size: ${theme.eui.euiFontSizeS};
+ line-height: ${theme.eui.euiLineHeight};
+ padding: ${theme.eui.paddingSizes.s};
+ vertical-align: middle;
+ `}
+`;
+TableCardsTd.displayName = 'TableCardsTd';
+
export const RulesComponent = React.memo(() => {
return (
<>
@@ -97,66 +185,104 @@ export const RulesComponent = React.memo(() => {
-
-
-
-
+
+
+
+
{
return null;
}}
/>
- |
- {'Rule'} |
- {'Method'} |
- {'Severity'} |
- {'Last completed run'} |
- {'Last response'} |
- {'Tags'} |
- {'Activate'} |
- |
-
-
-
-
-
-
+
+ {'Rule'}
+ {'Method'}
+ {'Severity'}
+ {'Last completed run'}
+ {'Last response'}
+ {'Tags'}
+
+ {'Activate'}
+
+
+
+
+
+
+
+
{
return null;
}}
/>
- |
-
+
+
{'Automated exfiltration'}
{' '}
{'Experimental'}
- |
- {'Kibana Query Language'} |
-
+
+ {'Kibana Query Language'}
+
{'Medium'}
- |
-
+
+
- |
-
+
+
{'Success'}
- |
-
+
+
+ {'attack.t1234'}
+
+
+
+
+
+
+
+
+
+
+
+ {
+ return null;
+ }}
+ />
+
+
+
+ {'Automated exfiltration'}
+ {' '}
+ {'Experimental'}
+
+ {'Kibana Query Language'}
+
+ {'Medium'}
+
+
+
+
+
+ {'Fail'}
+
+
{'attack.t1234'}
- |
-
+
+
- |
-
+
+
- |
-
-
-
+
+
+
+
From f82a1799fa855d589d4e4c4afad6c50d22e24f6d Mon Sep 17 00:00:00 2001
From: Michael Marcialis
Date: Thu, 10 Oct 2019 14:21:02 -0400
Subject: [PATCH 07/57] change HeaderPanel to HeaderSection
---
.../events_viewer/events_viewer.tsx | 4 +-
.../__snapshots__/index.test.tsx.snap | 0
.../index.test.tsx | 48 +++++++++----------
.../index.tsx | 12 ++---
.../components/matrix_over_time/index.tsx | 4 +-
.../ml/tables/anomalies_host_table.tsx | 4 +-
.../ml/tables/anomalies_network_table.tsx | 4 +-
.../open_timeline/title_row/index.tsx | 6 +--
.../page/overview/overview_host/index.tsx | 6 +--
.../page/overview/overview_network/index.tsx | 6 +--
.../components/paginated_table/index.tsx | 6 +--
.../detection_engine/detection_engine.tsx | 10 ++--
.../pages/detection_engine/rules/index.tsx | 21 ++++----
13 files changed, 63 insertions(+), 68 deletions(-)
rename x-pack/legacy/plugins/siem/public/components/{header_panel => header_section}/__snapshots__/index.test.tsx.snap (100%)
rename x-pack/legacy/plugins/siem/public/components/{header_panel => header_section}/index.test.tsx (66%)
rename x-pack/legacy/plugins/siem/public/components/{header_panel => header_section}/index.tsx (86%)
diff --git a/x-pack/legacy/plugins/siem/public/components/events_viewer/events_viewer.tsx b/x-pack/legacy/plugins/siem/public/components/events_viewer/events_viewer.tsx
index 4299657e36dab..e7d358295625e 100644
--- a/x-pack/legacy/plugins/siem/public/components/events_viewer/events_viewer.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/events_viewer/events_viewer.tsx
@@ -15,7 +15,7 @@ import { TimelineQuery } from '../../containers/timeline';
import { Direction } from '../../graphql/types';
import { KqlMode } from '../../store/timeline/model';
import { AutoSizer } from '../auto_sizer';
-import { HeaderPanel } from '../header_panel';
+import { HeaderSection } from '../header_section';
import { ColumnHeader } from '../timeline/body/column_headers/column_header';
import { defaultHeaders } from '../timeline/body/column_headers/default_headers';
import { Sort } from '../timeline/body/sort';
@@ -124,7 +124,7 @@ export const EventsViewer = React.memo(
totalCount = 0,
}) => (
<>
- {
+describe('HeaderSection', () => {
test('it renders', () => {
const wrapper = shallow(
-
+
);
@@ -30,13 +30,13 @@ describe('HeaderPanel', () => {
test('it renders the title', () => {
const wrapper = mount(
-
+
);
expect(
wrapper
- .find('[data-test-subj="header-panel-title"]')
+ .find('[data-test-subj="header-section-title"]')
.first()
.exists()
).toBe(true);
@@ -45,13 +45,13 @@ describe('HeaderPanel', () => {
test('it renders the subtitle when provided', () => {
const wrapper = mount(
-
+
);
expect(
wrapper
- .find(`[data-test-subj="header-panel-subtitle"]`)
+ .find(`[data-test-subj="header-section-subtitle"]`)
.first()
.exists()
).toBe(true);
@@ -60,13 +60,13 @@ describe('HeaderPanel', () => {
test('it DOES NOT render the subtitle when not provided', () => {
const wrapper = mount(
-
+
);
expect(
wrapper
- .find(`[data-test-subj="header-panel-subtitle"]`)
+ .find(`[data-test-subj="header-section-subtitle"]`)
.first()
.exists()
).toBe(false);
@@ -75,7 +75,7 @@ describe('HeaderPanel', () => {
test('it renders a transparent inspect button when showInspect is false', () => {
const wrapper = mount(
-
+
);
@@ -90,7 +90,7 @@ describe('HeaderPanel', () => {
test('it renders an opaque inspect button when showInspect is true', () => {
const wrapper = mount(
-
+
);
@@ -105,15 +105,15 @@ describe('HeaderPanel', () => {
test('it renders supplements when children provided', () => {
const wrapper = mount(
-
+
{'Test children'}
-
+
);
expect(
wrapper
- .find('[data-test-subj="header-panel-supplements"]')
+ .find('[data-test-subj="header-section-supplements"]')
.first()
.exists()
).toBe(true);
@@ -122,13 +122,13 @@ describe('HeaderPanel', () => {
test('it DOES NOT render supplements when children not provided', () => {
const wrapper = mount(
-
+
);
expect(
wrapper
- .find('[data-test-subj="header-panel-supplements"]')
+ .find('[data-test-subj="header-section-supplements"]')
.first()
.exists()
).toBe(false);
@@ -137,24 +137,24 @@ describe('HeaderPanel', () => {
test('it applies border styles when border is true', () => {
const wrapper = mount(
-
+
);
- const siemHeaderPanel = wrapper.find('.siemHeaderPanel').first();
+ const siemHeaderSection = wrapper.find('.siemHeaderSection').first();
- expect(siemHeaderPanel).toHaveStyleRule('border-bottom', euiDarkVars.euiBorderThin);
- expect(siemHeaderPanel).toHaveStyleRule('padding-bottom', euiDarkVars.euiSizeL);
+ expect(siemHeaderSection).toHaveStyleRule('border-bottom', euiDarkVars.euiBorderThin);
+ expect(siemHeaderSection).toHaveStyleRule('padding-bottom', euiDarkVars.euiSizeL);
});
test('it DOES NOT apply border styles when border is false', () => {
const wrapper = mount(
-
+
);
- const siemHeaderPanel = wrapper.find('.siemHeaderPanel').first();
+ const siemHeaderSection = wrapper.find('.siemHeaderSection').first();
- expect(siemHeaderPanel).not.toHaveStyleRule('border-bottom', euiDarkVars.euiBorderThin);
- expect(siemHeaderPanel).not.toHaveStyleRule('padding-bottom', euiDarkVars.euiSizeL);
+ expect(siemHeaderSection).not.toHaveStyleRule('border-bottom', euiDarkVars.euiBorderThin);
+ expect(siemHeaderSection).not.toHaveStyleRule('padding-bottom', euiDarkVars.euiSizeL);
});
});
diff --git a/x-pack/legacy/plugins/siem/public/components/header_panel/index.tsx b/x-pack/legacy/plugins/siem/public/components/header_section/index.tsx
similarity index 86%
rename from x-pack/legacy/plugins/siem/public/components/header_panel/index.tsx
rename to x-pack/legacy/plugins/siem/public/components/header_section/index.tsx
index e02091fcbdf39..e5aaf21e87a43 100644
--- a/x-pack/legacy/plugins/siem/public/components/header_panel/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/header_section/index.tsx
@@ -16,7 +16,7 @@ interface HeaderProps {
}
const Header = styled.header.attrs({
- className: 'siemHeaderPanel',
+ className: 'siemHeaderSection',
})`
${({ border, theme }) => css`
margin-bottom: ${theme.eui.euiSizeL};
@@ -31,7 +31,7 @@ const Header = styled.header.attrs({
`;
Header.displayName = 'Header';
-export interface HeaderPanelProps extends HeaderProps {
+export interface HeaderSectionProps extends HeaderProps {
children?: React.ReactNode;
id?: string;
subtitle?: SubtitleProps['text'];
@@ -40,7 +40,7 @@ export interface HeaderPanelProps extends HeaderProps {
tooltip?: string;
}
-export const HeaderPanel = React.memo(
+export const HeaderSection = React.memo(
({ border, children, id, showInspect = false, subtitle, title, tooltip }) => (
@@ -48,7 +48,7 @@ export const HeaderPanel = React.memo(
-
+
{title}
{tooltip && (
<>
@@ -71,7 +71,7 @@ export const HeaderPanel = React.memo(
{children && (
-
+
{children}
)}
@@ -79,4 +79,4 @@ export const HeaderPanel = React.memo(
)
);
-HeaderPanel.displayName = 'HeaderPanel';
+HeaderSection.displayName = 'HeaderSection';
diff --git a/x-pack/legacy/plugins/siem/public/components/matrix_over_time/index.tsx b/x-pack/legacy/plugins/siem/public/components/matrix_over_time/index.tsx
index 2898541a4a3d1..15e5af76c1c91 100644
--- a/x-pack/legacy/plugins/siem/public/components/matrix_over_time/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/matrix_over_time/index.tsx
@@ -12,7 +12,7 @@ import darkTheme from '@elastic/eui/dist/eui_theme_dark.json';
import lightTheme from '@elastic/eui/dist/eui_theme_light.json';
import { EuiLoadingContent } from '@elastic/eui';
import { BarChart } from '../charts/barchart';
-import { HeaderPanel } from '../header_panel';
+import { HeaderSection } from '../header_section';
import { ChartSeriesData, UpdateDateRange } from '../charts/common';
import { MatrixOverTimeHistogramData } from '../../graphql/types';
import { DEFAULT_DARK_MODE } from '../../../common/constants';
@@ -111,7 +111,7 @@ export const MatrixOverTimeHistogram = ({
onMouseEnter={() => setShowInspect(true)}
onMouseLeave={() => setShowInspect(false)}
>
- (
} else {
return (
- (
} else {
return (
- & {
/** The number of timelines currently selected */
@@ -23,7 +23,7 @@ type Props = Pick(
({ onAddTimelinesToFavorites, onDeleteSelected, selectedTimelinesCount, title }) => (
-
+
{(onAddTimelinesToFavorites || onDeleteSelected) && (
{onAddTimelinesToFavorites && (
@@ -55,7 +55,7 @@ export const TitleRow = pure(
)}
)}
-
+
)
);
diff --git a/x-pack/legacy/plugins/siem/public/components/page/overview/overview_host/index.tsx b/x-pack/legacy/plugins/siem/public/components/page/overview/overview_host/index.tsx
index bb96353c862c8..9380f25aaeff2 100644
--- a/x-pack/legacy/plugins/siem/public/components/page/overview/overview_host/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/page/overview/overview_host/index.tsx
@@ -9,7 +9,7 @@ import { FormattedMessage } from '@kbn/i18n/react';
import React, { useState } from 'react';
import { pure } from 'recompose';
-import { HeaderPanel } from '../../../header_panel';
+import { HeaderSection } from '../../../header_section';
import { manageQuery } from '../../../page/manage_query';
import {
ID as OverviewHostQueryId,
@@ -41,7 +41,7 @@ export const OverviewHost = pure(({ endDate, startDate, setQu
return (
setIsHover(true)} onMouseLeave={() => setIsHover(false)}>
- (({ endDate, startDate, setQu
-
+
{({ overviewHost, loading, id, inspect, refetch }) => (
diff --git a/x-pack/legacy/plugins/siem/public/components/page/overview/overview_network/index.tsx b/x-pack/legacy/plugins/siem/public/components/page/overview/overview_network/index.tsx
index c27395d157ebf..df7be994b8193 100644
--- a/x-pack/legacy/plugins/siem/public/components/page/overview/overview_network/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/page/overview/overview_network/index.tsx
@@ -9,7 +9,7 @@ import { FormattedMessage } from '@kbn/i18n/react';
import React, { useState } from 'react';
import { pure } from 'recompose';
-import { HeaderPanel } from '../../../header_panel';
+import { HeaderSection } from '../../../header_section';
import { manageQuery } from '../../../page/manage_query';
import {
ID as OverviewNetworkQueryId,
@@ -41,7 +41,7 @@ export const OverviewNetwork = pure(({ endDate, startDate, setQuery })
return (
setIsHover(true)} onMouseLeave={() => setIsHover(false)}>
- (({ endDate, startDate, setQuery })
defaultMessage="View network"
/>
-
+
{({ overviewNetwork, loading, id, inspect, refetch }) => (
diff --git a/x-pack/legacy/plugins/siem/public/components/paginated_table/index.tsx b/x-pack/legacy/plugins/siem/public/components/paginated_table/index.tsx
index 257ee03c944bf..90987741cf905 100644
--- a/x-pack/legacy/plugins/siem/public/components/paginated_table/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/paginated_table/index.tsx
@@ -28,7 +28,7 @@ import { NetworkTopNFlowColumns } from '../page/network/network_top_n_flow_table
import { TlsColumns } from '../page/network/tls_table/columns';
import { UncommonProcessTableColumns } from '../page/hosts/uncommon_process_table';
import { UsersColumns } from '../page/network/users_table/columns';
-import { HeaderPanel } from '../header_panel';
+import { HeaderSection } from '../header_section';
import { Loader } from '../loader';
import { useStateToaster } from '../toasters';
import { DEFAULT_MAX_TABLE_QUERY_SIZE } from '../../../common/constants';
@@ -225,7 +225,7 @@ export const PaginatedTable = memo(
onMouseEnter={() => setShowInspect(true)}
onMouseLeave={() => setShowInspect(false)}
>
- (
tooltip={headerTooltip}
>
{!loadingInitial && headerSupplement}
-
+
{loadingInitial ? (
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
index 6db76f7c70f2d..64044da615201 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
@@ -21,7 +21,7 @@ import { StickyContainer } from 'react-sticky';
import { FiltersGlobal } from '../../components/filters_global';
import { HeaderPage } from '../../components/header_page';
-import { HeaderPanel } from '../../components/header_panel';
+import { HeaderSection } from '../../components/header_section';
import { SpyRoute } from '../../utils/route/spy_routes';
import { DetectionEngineKql } from './kql';
import * as i18n from './translations';
@@ -66,9 +66,9 @@ export const DetectionEngineComponent = React.memo(() => {
-
+
-
+
@@ -98,7 +98,7 @@ export const DetectionEngineComponent = React.memo(() => {
-
@@ -110,7 +110,7 @@ export const DetectionEngineComponent = React.memo(() => {
}}
options={toggleButtons}
/>
-
+
{'Datagrid here (talk to Chandler Prall about possibility of early access)...'}
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
index bcf479d1eb6a0..1510e394a8bba 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
@@ -24,6 +24,7 @@ import React from 'react';
import styled, { css } from 'styled-components';
import { HeaderPage } from '../../../components/header_page';
+import { HeaderSection } from '../../../components/header_section';
import { SpyRoute } from '../../../utils/route/spy_routes';
import * as i18n from './translations';
@@ -145,19 +146,13 @@ export const RulesComponent = React.memo(() => {
-
-
-
{'All rules'}
-
-
-
-
-
-
+
+
+
From 30d5053f9088d035ed09c6162bc35972cc3909e3 Mon Sep 17 00:00:00 2001
From: Michael Marcialis
Date: Thu, 10 Oct 2019 17:19:16 -0400
Subject: [PATCH 08/57] cleanup and unit test updates
---
.../events_viewer/events_viewer.test.tsx | 2 +-
.../__snapshots__/header_page.test.tsx.snap | 14 --
.../__snapshots__/index.test.tsx.snap | 23 ++
.../components/header_page/index.test.tsx | 236 ++++++++++++++++--
.../public/components/header_page/index.tsx | 22 +-
.../__snapshots__/index.test.tsx.snap | 4 +-
.../components/header_section/index.test.tsx | 8 +-
.../components/header_section/index.tsx | 2 +-
.../__snapshots__/index.test.tsx.snap | 7 +-
.../components/link_back/index.test.tsx | 141 +----------
.../matrix_over_time/index.test.tsx | 4 +-
.../components/open_timeline/index.test.tsx | 2 +-
.../open_timeline/title_row/index.test.tsx | 2 +-
.../__snapshots__/index.test.tsx.snap | 6 +-
.../public/components/subtitle/index.test.tsx | 131 +---------
.../create_rule/index.test.tsx | 15 +-
.../detection_engine.test.tsx | 12 +-
.../detection_engine/detection_engine.tsx | 8 +-
.../detection_engine/edit_rule/index.test.tsx | 15 +-
.../public/pages/detection_engine/index.tsx | 2 +-
.../rule_details/index.test.tsx | 16 +-
.../detection_engine/rules/index.test.tsx | 15 +-
.../public/pages/network/ip_details.test.tsx | 2 +-
23 files changed, 323 insertions(+), 366 deletions(-)
delete mode 100644 x-pack/legacy/plugins/siem/public/components/header_page/__snapshots__/header_page.test.tsx.snap
create mode 100644 x-pack/legacy/plugins/siem/public/components/header_page/__snapshots__/index.test.tsx.snap
diff --git a/x-pack/legacy/plugins/siem/public/components/events_viewer/events_viewer.test.tsx b/x-pack/legacy/plugins/siem/public/components/events_viewer/events_viewer.test.tsx
index d85231b564da8..32e2f0f978fe6 100644
--- a/x-pack/legacy/plugins/siem/public/components/events_viewer/events_viewer.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/events_viewer/events_viewer.test.tsx
@@ -50,7 +50,7 @@ describe('EventsViewer', () => {
expect(
wrapper
- .find(`[data-test-subj="header-panel-subtitle"]`)
+ .find(`[data-test-subj="header-section-subtitle"]`)
.first()
.text()
).toEqual('Showing: 12 events');
diff --git a/x-pack/legacy/plugins/siem/public/components/header_page/__snapshots__/header_page.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/header_page/__snapshots__/header_page.test.tsx.snap
deleted file mode 100644
index 280acc0c63334..0000000000000
--- a/x-pack/legacy/plugins/siem/public/components/header_page/__snapshots__/header_page.test.tsx.snap
+++ /dev/null
@@ -1,14 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`rendering renders correctly 1`] = `
-
-
- My test supplement.
-
-
-`;
diff --git a/x-pack/legacy/plugins/siem/public/components/header_page/__snapshots__/index.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/header_page/__snapshots__/index.test.tsx.snap
new file mode 100644
index 0000000000000..0fe2890dc9f24
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/components/header_page/__snapshots__/index.test.tsx.snap
@@ -0,0 +1,23 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`HeaderPage it renders 1`] = `
+
+
+
+ Test supplement
+
+
+
+`;
diff --git a/x-pack/legacy/plugins/siem/public/components/header_page/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/header_page/index.test.tsx
index 16f2156e568e5..6e9150b566bb5 100644
--- a/x-pack/legacy/plugins/siem/public/components/header_page/index.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/header_page/index.test.tsx
@@ -4,39 +4,225 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { shallow } from 'enzyme';
+import euiDarkVars from '@elastic/eui/dist/eui_theme_dark.json';
+import { mount, shallow } from 'enzyme';
import toJson from 'enzyme-to-json';
+import 'jest-styled-components';
import React from 'react';
+import '../../mock/ui_settings';
+import { TestProviders } from '../../mock';
import { HeaderPage } from './index';
-describe('rendering', () => {
- test('renders correctly', () => {
+jest.mock('../../lib/settings/use_kibana_ui_setting');
+
+describe('HeaderPage', () => {
+ test('it renders', () => {
const wrapper = shallow(
-
- {'My test supplement.'}
-
+
+
+ {'Test supplement'}
+
+
);
+
expect(toJson(wrapper)).toMatchSnapshot();
});
- test('renders as a draggable when provided arguments', () => {
- const wrapper = shallow(
-
- {'My test supplement.'}
-
- );
- const draggableHeader = wrapper.dive().find('[data-test-subj="page_headline_draggable"]');
- expect(draggableHeader.exists()).toBeTruthy();
+
+ test('it renders the title', () => {
+ const wrapper = mount(
+
+
+
+ );
+
+ expect(
+ wrapper
+ .find('[data-test-subj="header-page-title"]')
+ .first()
+ .exists()
+ ).toBe(true);
+ });
+
+ test('it renders the back link when provided', () => {
+ const wrapper = mount(
+
+
+
+ );
+
+ expect(
+ wrapper
+ .find('[data-test-subj="header-page-back-link"]')
+ .first()
+ .exists()
+ ).toBe(true);
+ });
+
+ test('it DOES NOT render the back link when not provided', () => {
+ const wrapper = mount(
+
+
+
+ );
+
+ expect(
+ wrapper
+ .find('[data-test-subj="header-page-back-link"]')
+ .first()
+ .exists()
+ ).toBe(false);
+ });
+
+ test('it renders the first subtitle when provided', () => {
+ const wrapper = mount(
+
+
+
+ );
+
+ expect(
+ wrapper
+ .find('[data-test-subj="header-page-subtitle"]')
+ .first()
+ .exists()
+ ).toBe(true);
+ });
+
+ test('it DOES NOT render the first subtitle when not provided', () => {
+ const wrapper = mount(
+
+
+
+ );
+
+ expect(
+ wrapper
+ .find('[data-test-subj="header-section-subtitle"]')
+ .first()
+ .exists()
+ ).toBe(false);
+ });
+
+ test('it renders the second subtitle when provided', () => {
+ const wrapper = mount(
+
+
+
+ );
+
+ expect(
+ wrapper
+ .find('[data-test-subj="header-page-subtitle-2"]')
+ .first()
+ .exists()
+ ).toBe(true);
+ });
+
+ test('it DOES NOT render the second subtitle when not provided', () => {
+ const wrapper = mount(
+
+
+
+ );
+
+ expect(
+ wrapper
+ .find('[data-test-subj="header-section-subtitle-2"]')
+ .first()
+ .exists()
+ ).toBe(false);
+ });
+
+ test('it renders supplements when children provided', () => {
+ const wrapper = mount(
+
+
+ {'Test supplement'}
+
+
+ );
+
+ expect(
+ wrapper
+ .find('[data-test-subj="header-page-supplements"]')
+ .first()
+ .exists()
+ ).toBe(true);
+ });
+
+ test('it DOES NOT render supplements when children not provided', () => {
+ const wrapper = mount(
+
+
+
+ );
+
+ expect(
+ wrapper
+ .find('[data-test-subj="header-page-supplements"]')
+ .first()
+ .exists()
+ ).toBe(false);
+ });
+
+ test('it applies border styles when border is true', () => {
+ const wrapper = mount(
+
+
+
+ );
+ const siemHeaderPage = wrapper.find('.siemHeaderPage').first();
+
+ expect(siemHeaderPage).toHaveStyleRule('border-bottom', euiDarkVars.euiBorderThin);
+ expect(siemHeaderPage).toHaveStyleRule('padding-bottom', euiDarkVars.euiSizeL);
+ });
+
+ test('it DOES NOT apply border styles when border is false', () => {
+ const wrapper = mount(
+
+
+
+ );
+ const siemHeaderPage = wrapper.find('.siemHeaderPage').first();
+
+ expect(siemHeaderPage).not.toHaveStyleRule('border-bottom', euiDarkVars.euiBorderThin);
+ expect(siemHeaderPage).not.toHaveStyleRule('padding-bottom', euiDarkVars.euiSizeL);
+ });
+
+ test('it renders as a draggable when arguments provided', () => {
+ const wrapper = mount(
+
+
+
+ );
+
+ expect(
+ wrapper
+ .find('[data-test-subj="header-page-draggable"]')
+ .first()
+ .exists()
+ ).toBe(true);
+ });
+
+ test('it DOES NOT render as a draggable when arguments not provided', () => {
+ const wrapper = mount(
+
+
+
+ );
+
+ expect(
+ wrapper
+ .find('[data-test-subj="header-page-draggable"]')
+ .first()
+ .exists()
+ ).toBe(false);
});
});
diff --git a/x-pack/legacy/plugins/siem/public/components/header_page/index.tsx b/x-pack/legacy/plugins/siem/public/components/header_page/index.tsx
index 0e830b53fed6b..e5a696e862eb9 100644
--- a/x-pack/legacy/plugins/siem/public/components/header_page/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/header_page/index.tsx
@@ -82,15 +82,21 @@ export const HeaderPage = React.memo(
- {backOptions && }
+ {backOptions && (
+
+ )}
-
+
{!draggableArguments ? (
title
) : (
- {subtitle && }
- {subtitle2 && }
+ {subtitle && }
+ {subtitle2 && }
- {children && {children}}
+ {children && (
+
+ {children}
+
+ )}
)
diff --git a/x-pack/legacy/plugins/siem/public/components/header_section/__snapshots__/index.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/header_section/__snapshots__/index.test.tsx.snap
index 39250c38ef8fc..ecd2b15a841f6 100644
--- a/x-pack/legacy/plugins/siem/public/components/header_section/__snapshots__/index.test.tsx.snap
+++ b/x-pack/legacy/plugins/siem/public/components/header_section/__snapshots__/index.test.tsx.snap
@@ -1,8 +1,8 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`HeaderPanel it renders 1`] = `
+exports[`HeaderSection it renders 1`] = `
-
diff --git a/x-pack/legacy/plugins/siem/public/components/header_section/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/header_section/index.test.tsx
index 18356e65869ae..0a486bf82fdcf 100644
--- a/x-pack/legacy/plugins/siem/public/components/header_section/index.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/header_section/index.test.tsx
@@ -51,7 +51,7 @@ describe('HeaderSection', () => {
expect(
wrapper
- .find(`[data-test-subj="header-section-subtitle"]`)
+ .find('[data-test-subj="header-section-subtitle"]')
.first()
.exists()
).toBe(true);
@@ -66,7 +66,7 @@ describe('HeaderSection', () => {
expect(
wrapper
- .find(`[data-test-subj="header-section-subtitle"]`)
+ .find('[data-test-subj="header-section-subtitle"]')
.first()
.exists()
).toBe(false);
@@ -81,7 +81,7 @@ describe('HeaderSection', () => {
expect(
wrapper
- .find(`[data-test-subj="transparent-inspect-container"]`)
+ .find('[data-test-subj="transparent-inspect-container"]')
.first()
.exists()
).toBe(true);
@@ -96,7 +96,7 @@ describe('HeaderSection', () => {
expect(
wrapper
- .find(`[data-test-subj="opaque-inspect-container"]`)
+ .find('[data-test-subj="opaque-inspect-container"]')
.first()
.exists()
).toBe(true);
diff --git a/x-pack/legacy/plugins/siem/public/components/header_section/index.tsx b/x-pack/legacy/plugins/siem/public/components/header_section/index.tsx
index e5aaf21e87a43..c8e161aff766e 100644
--- a/x-pack/legacy/plugins/siem/public/components/header_section/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/header_section/index.tsx
@@ -59,7 +59,7 @@ export const HeaderSection = React.memo(
- {subtitle && }
+ {subtitle && }
{id && (
diff --git a/x-pack/legacy/plugins/siem/public/components/link_back/__snapshots__/index.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/link_back/__snapshots__/index.test.tsx.snap
index 39250c38ef8fc..f1d437379dd8c 100644
--- a/x-pack/legacy/plugins/siem/public/components/link_back/__snapshots__/index.test.tsx.snap
+++ b/x-pack/legacy/plugins/siem/public/components/link_back/__snapshots__/index.test.tsx.snap
@@ -1,9 +1,10 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`HeaderPanel it renders 1`] = `
+exports[`LinkBack it renders 1`] = `
-
`;
diff --git a/x-pack/legacy/plugins/siem/public/components/link_back/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/link_back/index.test.tsx
index 9cdb85bcb3d76..f6a5c672b63de 100644
--- a/x-pack/legacy/plugins/siem/public/components/link_back/index.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/link_back/index.test.tsx
@@ -4,157 +4,24 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import euiDarkVars from '@elastic/eui/dist/eui_theme_dark.json';
-import { mount, shallow } from 'enzyme';
+import { shallow } from 'enzyme';
import toJson from 'enzyme-to-json';
-import 'jest-styled-components';
import React from 'react';
import '../../mock/ui_settings';
import { TestProviders } from '../../mock';
-import { HeaderPanel } from './index';
+import { LinkBack } from './index';
jest.mock('../../lib/settings/use_kibana_ui_setting');
-describe('HeaderPanel', () => {
+describe('LinkBack', () => {
test('it renders', () => {
const wrapper = shallow(
-
+
);
expect(toJson(wrapper)).toMatchSnapshot();
});
-
- test('it renders the title', () => {
- const wrapper = mount(
-
-
-
- );
-
- expect(
- wrapper
- .find('[data-test-subj="header-panel-title"]')
- .first()
- .exists()
- ).toBe(true);
- });
-
- test('it renders the subtitle when provided', () => {
- const wrapper = mount(
-
-
-
- );
-
- expect(
- wrapper
- .find(`[data-test-subj="header-panel-subtitle"]`)
- .first()
- .exists()
- ).toBe(true);
- });
-
- test('it DOES NOT render the subtitle when not provided', () => {
- const wrapper = mount(
-
-
-
- );
-
- expect(
- wrapper
- .find(`[data-test-subj="header-panel-subtitle"]`)
- .first()
- .exists()
- ).toBe(false);
- });
-
- test('it renders a transparent inspect button when showInspect is false', () => {
- const wrapper = mount(
-
-
-
- );
-
- expect(
- wrapper
- .find(`[data-test-subj="transparent-inspect-container"]`)
- .first()
- .exists()
- ).toBe(true);
- });
-
- test('it renders an opaque inspect button when showInspect is true', () => {
- const wrapper = mount(
-
-
-
- );
-
- expect(
- wrapper
- .find(`[data-test-subj="opaque-inspect-container"]`)
- .first()
- .exists()
- ).toBe(true);
- });
-
- test('it renders supplements when children provided', () => {
- const wrapper = mount(
-
-
- {'Test children'}
-
-
- );
-
- expect(
- wrapper
- .find('[data-test-subj="header-panel-supplements"]')
- .first()
- .exists()
- ).toBe(true);
- });
-
- test('it DOES NOT render supplements when children not provided', () => {
- const wrapper = mount(
-
-
-
- );
-
- expect(
- wrapper
- .find('[data-test-subj="header-panel-supplements"]')
- .first()
- .exists()
- ).toBe(false);
- });
-
- test('it applies border styles when border is true', () => {
- const wrapper = mount(
-
-
-
- );
- const siemHeaderPanel = wrapper.find('.siemHeaderPanel').first();
-
- expect(siemHeaderPanel).toHaveStyleRule('border-bottom', euiDarkVars.euiBorderThin);
- expect(siemHeaderPanel).toHaveStyleRule('padding-bottom', euiDarkVars.euiSizeL);
- });
-
- test('it DOES NOT apply border styles when border is false', () => {
- const wrapper = mount(
-
-
-
- );
- const siemHeaderPanel = wrapper.find('.siemHeaderPanel').first();
-
- expect(siemHeaderPanel).not.toHaveStyleRule('border-bottom', euiDarkVars.euiBorderThin);
- expect(siemHeaderPanel).not.toHaveStyleRule('padding-bottom', euiDarkVars.euiSizeL);
- });
});
diff --git a/x-pack/legacy/plugins/siem/public/components/matrix_over_time/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/matrix_over_time/index.test.tsx
index e52d44173f656..76798983e92b9 100644
--- a/x-pack/legacy/plugins/siem/public/components/matrix_over_time/index.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/matrix_over_time/index.test.tsx
@@ -26,9 +26,9 @@ jest.mock('../../lib/settings/use_kibana_ui_setting', () => {
return { useKibanaUiSetting: () => [false] };
});
-jest.mock('../header_panel', () => {
+jest.mock('../header_section', () => {
return {
- HeaderPanel: () => ,
+ HeaderSection: () => ,
};
});
diff --git a/x-pack/legacy/plugins/siem/public/components/open_timeline/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/open_timeline/index.test.tsx
index 7a0caf14af302..f5207fc6a35fd 100644
--- a/x-pack/legacy/plugins/siem/public/components/open_timeline/index.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/open_timeline/index.test.tsx
@@ -492,7 +492,7 @@ describe('StatefulOpenTimeline', () => {
expect(
wrapper
- .find('[data-test-subj="header-panel-title"]')
+ .find('[data-test-subj="header-section-title"]')
.first()
.text()
).toEqual(title);
diff --git a/x-pack/legacy/plugins/siem/public/components/open_timeline/title_row/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/open_timeline/title_row/index.test.tsx
index db3d192f06ba1..9303c09c994aa 100644
--- a/x-pack/legacy/plugins/siem/public/components/open_timeline/title_row/index.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/open_timeline/title_row/index.test.tsx
@@ -30,7 +30,7 @@ describe('TitleRow', () => {
expect(
wrapper
- .find('[data-test-subj="header-panel-title"]')
+ .find('[data-test-subj="header-section-title"]')
.first()
.text()
).toEqual(title);
diff --git a/x-pack/legacy/plugins/siem/public/components/subtitle/__snapshots__/index.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/subtitle/__snapshots__/index.test.tsx.snap
index 39250c38ef8fc..fad93ad853a37 100644
--- a/x-pack/legacy/plugins/siem/public/components/subtitle/__snapshots__/index.test.tsx.snap
+++ b/x-pack/legacy/plugins/siem/public/components/subtitle/__snapshots__/index.test.tsx.snap
@@ -1,9 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`HeaderPanel it renders 1`] = `
+exports[`Subtitle it renders 1`] = `
-
`;
diff --git a/x-pack/legacy/plugins/siem/public/components/subtitle/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/subtitle/index.test.tsx
index 9cdb85bcb3d76..5c7bdbfe0309c 100644
--- a/x-pack/legacy/plugins/siem/public/components/subtitle/index.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/subtitle/index.test.tsx
@@ -4,157 +4,44 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import euiDarkVars from '@elastic/eui/dist/eui_theme_dark.json';
import { mount, shallow } from 'enzyme';
import toJson from 'enzyme-to-json';
-import 'jest-styled-components';
import React from 'react';
import '../../mock/ui_settings';
import { TestProviders } from '../../mock';
-import { HeaderPanel } from './index';
+import { Subtitle } from './index';
jest.mock('../../lib/settings/use_kibana_ui_setting');
-describe('HeaderPanel', () => {
+describe('Subtitle', () => {
test('it renders', () => {
const wrapper = shallow(
-
+
);
expect(toJson(wrapper)).toMatchSnapshot();
});
- test('it renders the title', () => {
+ test('it renders one subtitle item', () => {
const wrapper = mount(
-
+
);
- expect(
- wrapper
- .find('[data-test-subj="header-panel-title"]')
- .first()
- .exists()
- ).toBe(true);
+ expect(wrapper.find('p').length).toEqual(1);
});
- test('it renders the subtitle when provided', () => {
+ test('it renders multiple subtitle items', () => {
const wrapper = mount(
-
+
);
- expect(
- wrapper
- .find(`[data-test-subj="header-panel-subtitle"]`)
- .first()
- .exists()
- ).toBe(true);
- });
-
- test('it DOES NOT render the subtitle when not provided', () => {
- const wrapper = mount(
-
-
-
- );
-
- expect(
- wrapper
- .find(`[data-test-subj="header-panel-subtitle"]`)
- .first()
- .exists()
- ).toBe(false);
- });
-
- test('it renders a transparent inspect button when showInspect is false', () => {
- const wrapper = mount(
-
-
-
- );
-
- expect(
- wrapper
- .find(`[data-test-subj="transparent-inspect-container"]`)
- .first()
- .exists()
- ).toBe(true);
- });
-
- test('it renders an opaque inspect button when showInspect is true', () => {
- const wrapper = mount(
-
-
-
- );
-
- expect(
- wrapper
- .find(`[data-test-subj="opaque-inspect-container"]`)
- .first()
- .exists()
- ).toBe(true);
- });
-
- test('it renders supplements when children provided', () => {
- const wrapper = mount(
-
-
- {'Test children'}
-
-
- );
-
- expect(
- wrapper
- .find('[data-test-subj="header-panel-supplements"]')
- .first()
- .exists()
- ).toBe(true);
- });
-
- test('it DOES NOT render supplements when children not provided', () => {
- const wrapper = mount(
-
-
-
- );
-
- expect(
- wrapper
- .find('[data-test-subj="header-panel-supplements"]')
- .first()
- .exists()
- ).toBe(false);
- });
-
- test('it applies border styles when border is true', () => {
- const wrapper = mount(
-
-
-
- );
- const siemHeaderPanel = wrapper.find('.siemHeaderPanel').first();
-
- expect(siemHeaderPanel).toHaveStyleRule('border-bottom', euiDarkVars.euiBorderThin);
- expect(siemHeaderPanel).toHaveStyleRule('padding-bottom', euiDarkVars.euiSizeL);
- });
-
- test('it DOES NOT apply border styles when border is false', () => {
- const wrapper = mount(
-
-
-
- );
- const siemHeaderPanel = wrapper.find('.siemHeaderPanel').first();
-
- expect(siemHeaderPanel).not.toHaveStyleRule('border-bottom', euiDarkVars.euiBorderThin);
- expect(siemHeaderPanel).not.toHaveStyleRule('padding-bottom', euiDarkVars.euiSizeL);
+ expect(wrapper.find('p').length).toEqual(2);
});
});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/create_rule/index.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/create_rule/index.test.tsx
index 3fee7dc918471..59407227b5da5 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/create_rule/index.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/create_rule/index.test.tsx
@@ -10,11 +10,10 @@ import * as React from 'react';
import { MockedProvider } from 'react-apollo/test-utils';
import { MemoryRouter } from 'react-router-dom';
-import { DetectionEngine } from './index';
-
-import '../../mock/ui_settings';
-import { mocksSource } from '../../containers/source/mock';
-import { TestProviders } from '../../mock';
+import { mocksSource } from '../../../containers/source/mock';
+import { TestProviders } from '../../../mock';
+import '../../../mock/ui_settings';
+import { CreateRuleComponent } from './index';
jest.mock('ui/documentation_links', () => ({
documentationLinks: {
@@ -35,7 +34,7 @@ let localSource: Array<{
};
}>;
-describe('DetectionEngine', () => {
+describe('CreateRuleComponent', () => {
describe('rendering', () => {
beforeEach(() => {
localSource = cloneDeep(mocksSource);
@@ -47,7 +46,7 @@ describe('DetectionEngine', () => {
-
+
@@ -64,7 +63,7 @@ describe('DetectionEngine', () => {
-
+
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.test.tsx
index 3fee7dc918471..05030954af9c4 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.test.tsx
@@ -10,11 +10,11 @@ import * as React from 'react';
import { MockedProvider } from 'react-apollo/test-utils';
import { MemoryRouter } from 'react-router-dom';
-import { DetectionEngine } from './index';
-
-import '../../mock/ui_settings';
import { mocksSource } from '../../containers/source/mock';
import { TestProviders } from '../../mock';
+import '../../mock/match_media';
+import '../../mock/ui_settings';
+import { DetectionEngineComponent } from './detection_engine';
jest.mock('ui/documentation_links', () => ({
documentationLinks: {
@@ -35,7 +35,7 @@ let localSource: Array<{
};
}>;
-describe('DetectionEngine', () => {
+describe('DetectionEngineComponent', () => {
describe('rendering', () => {
beforeEach(() => {
localSource = cloneDeep(mocksSource);
@@ -47,7 +47,7 @@ describe('DetectionEngine', () => {
-
+
@@ -64,7 +64,7 @@ describe('DetectionEngine', () => {
-
+
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
index 64044da615201..52bbad2ed4adf 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
@@ -5,15 +5,15 @@
*/
import {
- Chart,
- BarSeries,
Axis,
+ BarSeries,
+ Chart,
HistogramBarSeries,
Position,
- getAxisId,
- getSpecId,
ScaleType,
Settings,
+ getAxisId,
+ getSpecId,
} from '@elastic/charts';
import { EuiButton, EuiButtonGroup, EuiPanel, EuiSelect, EuiSpacer } from '@elastic/eui';
import React from 'react';
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/edit_rule/index.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/edit_rule/index.test.tsx
index 3fee7dc918471..b8f71e2c599c9 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/edit_rule/index.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/edit_rule/index.test.tsx
@@ -10,11 +10,10 @@ import * as React from 'react';
import { MockedProvider } from 'react-apollo/test-utils';
import { MemoryRouter } from 'react-router-dom';
-import { DetectionEngine } from './index';
-
-import '../../mock/ui_settings';
-import { mocksSource } from '../../containers/source/mock';
-import { TestProviders } from '../../mock';
+import { mocksSource } from '../../../containers/source/mock';
+import { TestProviders } from '../../../mock';
+import '../../../mock/ui_settings';
+import { EditRuleComponent } from './index';
jest.mock('ui/documentation_links', () => ({
documentationLinks: {
@@ -35,7 +34,7 @@ let localSource: Array<{
};
}>;
-describe('DetectionEngine', () => {
+describe('EditRuleComponent', () => {
describe('rendering', () => {
beforeEach(() => {
localSource = cloneDeep(mocksSource);
@@ -47,7 +46,7 @@ describe('DetectionEngine', () => {
-
+
@@ -64,7 +63,7 @@ describe('DetectionEngine', () => {
-
+
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/index.tsx
index f64d56c8822c4..90524b4da0af4 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/index.tsx
@@ -8,8 +8,8 @@ import React from 'react';
import { Redirect, Route, Switch, RouteComponentProps } from 'react-router-dom';
import { CreateRuleComponent } from './create_rule';
-import { EditRuleComponent } from './edit_rule';
import { DetectionEngineComponent } from './detection_engine';
+import { EditRuleComponent } from './edit_rule';
import { RuleDetailsComponent } from './rule_details';
import { RulesComponent } from './rules';
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.test.tsx
index 3fee7dc918471..32b9891b4ad6b 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.test.tsx
@@ -10,11 +10,11 @@ import * as React from 'react';
import { MockedProvider } from 'react-apollo/test-utils';
import { MemoryRouter } from 'react-router-dom';
-import { DetectionEngine } from './index';
-
-import '../../mock/ui_settings';
-import { mocksSource } from '../../containers/source/mock';
-import { TestProviders } from '../../mock';
+import { mocksSource } from '../../../containers/source/mock';
+import { TestProviders } from '../../../mock';
+import '../../../mock/match_media';
+import '../../../mock/ui_settings';
+import { RuleDetailsComponent } from './index';
jest.mock('ui/documentation_links', () => ({
documentationLinks: {
@@ -35,7 +35,7 @@ let localSource: Array<{
};
}>;
-describe('DetectionEngine', () => {
+describe('RuleDetailsComponent', () => {
describe('rendering', () => {
beforeEach(() => {
localSource = cloneDeep(mocksSource);
@@ -47,7 +47,7 @@ describe('DetectionEngine', () => {
-
+
@@ -64,7 +64,7 @@ describe('DetectionEngine', () => {
-
+
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.test.tsx
index 3fee7dc918471..7472961a0cb90 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.test.tsx
@@ -10,11 +10,10 @@ import * as React from 'react';
import { MockedProvider } from 'react-apollo/test-utils';
import { MemoryRouter } from 'react-router-dom';
-import { DetectionEngine } from './index';
-
-import '../../mock/ui_settings';
-import { mocksSource } from '../../containers/source/mock';
-import { TestProviders } from '../../mock';
+import { mocksSource } from '../../../containers/source/mock';
+import { TestProviders } from '../../../mock';
+import '../../../mock/ui_settings';
+import { RulesComponent } from './index';
jest.mock('ui/documentation_links', () => ({
documentationLinks: {
@@ -35,7 +34,7 @@ let localSource: Array<{
};
}>;
-describe('DetectionEngine', () => {
+describe('RulesComponent', () => {
describe('rendering', () => {
beforeEach(() => {
localSource = cloneDeep(mocksSource);
@@ -47,7 +46,7 @@ describe('DetectionEngine', () => {
-
+
@@ -64,7 +63,7 @@ describe('DetectionEngine', () => {
-
+
diff --git a/x-pack/legacy/plugins/siem/public/pages/network/ip_details.test.tsx b/x-pack/legacy/plugins/siem/public/pages/network/ip_details.test.tsx
index 5a31bc8e7ae5d..41710813cb5db 100644
--- a/x-pack/legacy/plugins/siem/public/pages/network/ip_details.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/network/ip_details.test.tsx
@@ -146,7 +146,7 @@ describe('Ip Details', () => {
wrapper.update();
expect(
wrapper
- .find('[data-test-subj="ip-details-headline"] [data-test-subj="page_headline_title"]')
+ .find('[data-test-subj="ip-details-headline"] [data-test-subj="header-page-title"]')
.text()
).toEqual('fe80::24ce:f7ff:fede:a571');
});
From c847e77f7891337ccc40461e7463a8cd0202ec6f Mon Sep 17 00:00:00 2001
From: Michael Marcialis
Date: Fri, 11 Oct 2019 14:50:15 -0400
Subject: [PATCH 09/57] rough out utilityBar poc
---
.../__snapshots__/index.test.tsx.snap | 10 +
.../public/components/utility_bar/index.ts | 11 +
.../utility_bar/utility_bar.test.tsx | 27 +++
.../components/utility_bar/utility_bar.tsx | 37 ++++
.../utility_bar/utility_bar_action.tsx | 35 +++
.../utility_bar/utility_bar_group.tsx | 42 ++++
.../utility_bar/utility_bar_section.tsx | 27 +++
.../utility_bar/utility_bar_text.tsx | 28 +++
.../detection_engine/detection_engine.tsx | 96 ++++++++-
.../pages/detection_engine/rules/index.tsx | 203 +++++++++++++-----
10 files changed, 458 insertions(+), 58 deletions(-)
create mode 100644 x-pack/legacy/plugins/siem/public/components/utility_bar/__snapshots__/index.test.tsx.snap
create mode 100644 x-pack/legacy/plugins/siem/public/components/utility_bar/index.ts
create mode 100644 x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar.test.tsx
create mode 100644 x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar.tsx
create mode 100644 x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_action.tsx
create mode 100644 x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_group.tsx
create mode 100644 x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_section.tsx
create mode 100644 x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_text.tsx
diff --git a/x-pack/legacy/plugins/siem/public/components/utility_bar/__snapshots__/index.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/utility_bar/__snapshots__/index.test.tsx.snap
new file mode 100644
index 0000000000000..f1d437379dd8c
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/components/utility_bar/__snapshots__/index.test.tsx.snap
@@ -0,0 +1,10 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`LinkBack it renders 1`] = `
+
+
+
+`;
diff --git a/x-pack/legacy/plugins/siem/public/components/utility_bar/index.ts b/x-pack/legacy/plugins/siem/public/components/utility_bar/index.ts
new file mode 100644
index 0000000000000..b07fe8bb847c7
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/components/utility_bar/index.ts
@@ -0,0 +1,11 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+export { UtilityBar } from './utility_bar';
+export { UtilityBarAction } from './utility_bar_action';
+export { UtilityBarGroup } from './utility_bar_group';
+export { UtilityBarSection } from './utility_bar_section';
+export { UtilityBarText } from './utility_bar_text';
diff --git a/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar.test.tsx b/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar.test.tsx
new file mode 100644
index 0000000000000..f6a5c672b63de
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar.test.tsx
@@ -0,0 +1,27 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { shallow } from 'enzyme';
+import toJson from 'enzyme-to-json';
+import React from 'react';
+
+import '../../mock/ui_settings';
+import { TestProviders } from '../../mock';
+import { LinkBack } from './index';
+
+jest.mock('../../lib/settings/use_kibana_ui_setting');
+
+describe('LinkBack', () => {
+ test('it renders', () => {
+ const wrapper = shallow(
+
+
+
+ );
+
+ expect(toJson(wrapper)).toMatchSnapshot();
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar.tsx b/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar.tsx
new file mode 100644
index 0000000000000..be1f7a8bede58
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar.tsx
@@ -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;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { EuiFlexGroup } from '@elastic/eui';
+import React from 'react';
+import styled, { css } from 'styled-components';
+
+interface AsideProps {
+ border?: boolean;
+}
+
+const Aside = styled.aside.attrs({
+ className: 'siemUtilityBar',
+})`
+ ${({ border, theme }) => css`
+ ${border &&
+ css`
+ border-bottom: ${theme.eui.euiBorderThin};
+ padding-bottom: ${theme.eui.paddingSizes.s};
+ `}
+ `}
+`;
+Aside.displayName = 'Aside';
+
+export interface UtilityBarProps extends AsideProps {
+ children: React.ReactNode;
+}
+
+export const UtilityBar = React.memo(({ border, children }) => (
+
+));
+UtilityBar.displayName = 'UtilityBar';
diff --git a/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_action.tsx b/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_action.tsx
new file mode 100644
index 0000000000000..247124584a383
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_action.tsx
@@ -0,0 +1,35 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { EuiLink } from '@elastic/eui';
+import React from 'react';
+import styled, { css } from 'styled-components';
+
+interface LinkProps {
+ href?: string;
+ onClick?: Function;
+}
+
+const Link = styled(EuiLink).attrs({
+ className: 'siemUtilityBar__action',
+})`
+ ${({ theme }) => css`
+ font-size: ${theme.eui.euiFontSizeXS};
+ line-height: ${theme.eui.euiLineHeight};
+ `}
+`;
+Link.displayName = 'Link';
+
+export interface UtilityBarActionProps extends LinkProps {
+ children: React.ReactNode;
+}
+
+export const UtilityBarAction = React.memo(({ children, href, onClick }) => (
+
+ {children}
+
+));
+UtilityBarAction.displayName = 'UtilityBarAction';
diff --git a/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_group.tsx b/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_group.tsx
new file mode 100644
index 0000000000000..7c877a413f359
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_group.tsx
@@ -0,0 +1,42 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import React from 'react';
+import styled, { css } from 'styled-components';
+
+const Group = styled.div.attrs({
+ className: 'siemUtilityBar__group',
+})`
+ ${({ theme }) => css`
+ border-right: ${theme.eui.euiBorderThin};
+ padding-right: ${theme.eui.paddingSizes.m};
+
+ &:last-child {
+ border-right: none;
+ padding-right: 0;
+ }
+
+ &,
+ & > * {
+ display: inline-block;
+ margin-right: ${theme.eui.paddingSizes.m};
+
+ &:last-child {
+ margin-right: 0;
+ }
+ }
+ `}
+`;
+Group.displayName = 'Group';
+
+export interface UtilityBarGroupProps {
+ children: React.ReactNode;
+}
+
+export const UtilityBarGroup = React.memo(({ children }) => (
+ {children}
+));
+UtilityBarGroup.displayName = 'UtilityBarGroup';
diff --git a/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_section.tsx b/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_section.tsx
new file mode 100644
index 0000000000000..5cfd1353bc3bb
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_section.tsx
@@ -0,0 +1,27 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { EuiFlexItem } from '@elastic/eui';
+import React from 'react';
+import styled, { css } from 'styled-components';
+
+const Section = styled(EuiFlexItem).attrs({
+ className: 'siemUtilityBar__section',
+})`
+ ${({ theme }) => css`
+ display: block;
+ `}
+`;
+Section.displayName = 'Section';
+
+export interface UtilityBarSectionProps {
+ children: React.ReactNode;
+}
+
+export const UtilityBarSection = React.memo(({ children }) => (
+
+));
+UtilityBarSection.displayName = 'UtilityBarSection';
diff --git a/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_text.tsx b/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_text.tsx
new file mode 100644
index 0000000000000..c8b0af4972497
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_text.tsx
@@ -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;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import React from 'react';
+import styled, { css } from 'styled-components';
+
+const Text = styled.p.attrs({
+ className: 'siemUtilityBar__text',
+})`
+ ${({ theme }) => css`
+ color: ${theme.eui.textColors.subdued};
+ font-size: ${theme.eui.euiFontSizeXS};
+ line-height: ${theme.eui.euiLineHeight};
+ `}
+`;
+Text.displayName = 'Text';
+
+export interface UtilityBarTextProps {
+ children: string;
+}
+
+export const UtilityBarText = React.memo(({ children }) => (
+ {children}
+));
+UtilityBarText.displayName = 'UtilityBarText';
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
index 52bbad2ed4adf..e643deb73f37f 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
@@ -15,13 +15,20 @@ import {
getAxisId,
getSpecId,
} from '@elastic/charts';
-import { EuiButton, EuiButtonGroup, EuiPanel, EuiSelect, EuiSpacer } from '@elastic/eui';
+import { EuiButton, EuiButtonGroup, EuiIcon, EuiPanel, EuiSelect, EuiSpacer } from '@elastic/eui';
import React from 'react';
import { StickyContainer } from 'react-sticky';
import { FiltersGlobal } from '../../components/filters_global';
import { HeaderPage } from '../../components/header_page';
import { HeaderSection } from '../../components/header_section';
+import {
+ UtilityBar,
+ UtilityBarAction,
+ UtilityBarGroup,
+ UtilityBarSection,
+ UtilityBarText,
+} from '../../components/utility_bar';
import { SpyRoute } from '../../utils/route/spy_routes';
import { DetectionEngineKql } from './kql';
import * as i18n from './translations';
@@ -86,10 +93,39 @@ export const DetectionEngineComponent = React.memo(() => {
stackAccessors={['x']}
splitSeriesAccessors={['a', 'b']}
data={[
- { x: 1551438000000, y: 2, a: 'a' },
- { x: 1551438000000, y: 2, b: 'b' },
- { x: 1551439000000, y: 7, a: 'a' },
- { x: 1551440000000, y: 3, a: 'a' },
+ { x: 0, y: 2, a: 'a' },
+ { x: 0, y: 2, b: 'b' },
+ { x: 1, y: 7, a: 'a' },
+ { x: 2, y: 3, a: 'a' },
+ { x: 3, y: 2, a: 'a' },
+ { x: 4, y: 7, a: 'a' },
+ { x: 5, y: 3, a: 'a' },
+ { x: 6, y: 2, a: 'a' },
+ { x: 7, y: 7, a: 'a' },
+ { x: 8, y: 3, a: 'a' },
+ { x: 9, y: 2, a: 'a' },
+ { x: 10, y: 7, a: 'a' },
+ { x: 11, y: 3, a: 'a' },
+ { x: 12, y: 2, a: 'a' },
+ { x: 13, y: 7, a: 'a' },
+ { x: 14, y: 3, a: 'a' },
+ { x: 15, y: 2, a: 'a' },
+ { x: 16, y: 7, a: 'a' },
+ { x: 17, y: 3, a: 'a' },
+ { x: 18, y: 2, a: 'a' },
+ { x: 19, y: 7, a: 'a' },
+ { x: 20, y: 3, a: 'a' },
+ { x: 21, y: 2, a: 'a' },
+ { x: 22, y: 7, a: 'a' },
+ { x: 23, y: 3, a: 'a' },
+ { x: 24, y: 2, a: 'a' },
+ { x: 25, y: 7, a: 'a' },
+ { x: 26, y: 3, a: 'a' },
+ { x: 27, y: 2, a: 'a' },
+ { x: 28, y: 7, a: 'a' },
+ { x: 29, y: 3, a: 'a' },
+ { x: 30, y: 2, a: 'a' },
+ { x: 31, y: 7, a: 'a' },
]}
/>
@@ -98,10 +134,7 @@ export const DetectionEngineComponent = React.memo(() => {
-
+
{
options={toggleButtons}
/>
- {'Datagrid here (talk to Chandler Prall about possibility of early access)...'}
+
+
+
+
+ {`${i18n.PANEL_SUBTITLE_SHOWING}: 7,712 signals`}
+
+
+
+ {'Selected: 20 signals'}
+
+
+ {'Batch actions'}
+
+
+
+ {'Select all signals on all pages'}
+
+
+
+
+
+ {'Clear 7 filters'}
+
+
+
+ {'Clear aggregation'}
+
+
+
+
+
+
+
+ {'Customize columns'}
+
+
+
+ {'Aggregate data'}
+
+
+
+
+
+ {/* Datagrid here. Talk to Chandler Prall about possibility of early access. If not possible, use basic table. */}
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
index 1510e394a8bba..559b3cf737eea 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
@@ -6,6 +6,7 @@
import {
EuiBadge,
+ EuiBasicTable,
EuiButton,
EuiButtonIcon,
EuiCheckbox,
@@ -15,16 +16,23 @@ import {
EuiHealth,
EuiIcon,
EuiLink,
+ EuiPanel,
EuiSpacer,
EuiSwitch,
- EuiTab,
- EuiTabs,
+ EuiTabbedContent,
} from '@elastic/eui';
import React from 'react';
import styled, { css } from 'styled-components';
import { HeaderPage } from '../../../components/header_page';
import { HeaderSection } from '../../../components/header_section';
+import {
+ UtilityBar,
+ UtilityBarAction,
+ UtilityBarGroup,
+ UtilityBarSection,
+ UtilityBarText,
+} from '../../../components/utility_bar';
import { SpyRoute } from '../../../utils/route/spy_routes';
import * as i18n from './translations';
@@ -115,34 +123,9 @@ const TableCardsTd = styled.td.attrs({
`;
TableCardsTd.displayName = 'TableCardsTd';
-export const RulesComponent = React.memo(() => {
+const AllRules = React.memo(() => {
return (
<>
-
-
-
-
- {'Import rule…'}
-
-
-
-
-
- {'Add new rule'}
-
-
-
-
-
-
- {'All rules'}
- {'Activity monitor'}
-
-
@@ -154,31 +137,27 @@ export const RulesComponent = React.memo(() => {
/>
-
-
-
-
-
+
+
+
+
@@ -279,6 +258,134 @@ export const RulesComponent = React.memo(() => {
+ >
+ );
+});
+AllRules.displayName = 'AllRules';
+
+const ActivityMonitor = React.memo(() => {
+ const columns = [
+ {
+ field: 'checkbox',
+ name: 'Checkbox',
+ truncateText: true,
+ },
+ {
+ field: 'rule',
+ name: 'Rule',
+ truncateText: true,
+ },
+ {
+ field: 'ran',
+ name: 'Ran',
+ truncateText: true,
+ },
+ {
+ field: 'lookedBackTo',
+ name: 'Looked back to',
+ truncateText: true,
+ },
+ {
+ field: 'status',
+ name: 'Status',
+ truncateText: true,
+ },
+ {
+ field: 'response',
+ name: 'Response',
+ truncateText: true,
+ },
+ {
+ field: 'actions',
+ name: '',
+ },
+ ];
+
+ const items = [
+ {
+ checkbox: 'test',
+ rule: 'test',
+ ran: 'test',
+ lookedBackTo: 'test',
+ status: 'test',
+ response: 'test',
+ actions: 'test',
+ },
+ ];
+
+ return (
+ <>
+
+
+
+
+
+
+
+
+ {'Showing: 39 activites'}
+
+
+
+ {'Selected: 2 activities'}
+
+
+ {'Stop selected'}
+
+
+
+
+
+ {'Clear 7 filters'}
+
+
+
+
+
+
+
+ >
+ );
+});
+AllRules.displayName = 'AllRules';
+
+export const RulesComponent = React.memo(() => {
+ return (
+ <>
+
+
+
+
+ {'Import rule…'}
+
+
+
+
+
+ {'Add new rule'}
+
+
+
+
+
+ ,
+ },
+ {
+ id: 'tabActivityMonitor',
+ name: 'Activity monitor',
+ content: ,
+ },
+ ]}
+ />
>
From 33b3d3390e0127c1871250e43a9d2bd6cf6071ee Mon Sep 17 00:00:00 2001
From: Michael Marcialis
Date: Mon, 14 Oct 2019 11:20:40 -0400
Subject: [PATCH 10/57] clean up UtilityBar naming and styles
---
.../public/components/utility_bar/styles.tsx | 123 ++++++++++++++++++
.../components/utility_bar/utility_bar.tsx | 25 +---
.../utility_bar/utility_bar_action.tsx | 23 +---
.../utility_bar/utility_bar_group.tsx | 28 +---
.../utility_bar/utility_bar_section.tsx | 13 +-
.../utility_bar/utility_bar_text.tsx | 14 +-
6 files changed, 136 insertions(+), 90 deletions(-)
create mode 100644 x-pack/legacy/plugins/siem/public/components/utility_bar/styles.tsx
diff --git a/x-pack/legacy/plugins/siem/public/components/utility_bar/styles.tsx b/x-pack/legacy/plugins/siem/public/components/utility_bar/styles.tsx
new file mode 100644
index 0000000000000..2decb803c54ea
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/components/utility_bar/styles.tsx
@@ -0,0 +1,123 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { EuiLink } from '@elastic/eui';
+import styled, { css } from 'styled-components';
+
+/**
+ * UTILITY BAR
+ */
+
+export interface BarProps {
+ border?: boolean;
+}
+
+export const Bar = styled.aside.attrs({
+ className: 'siemUtilityBar',
+})`
+ ${({ border, theme }) => css`
+ ${border &&
+ css`
+ border-bottom: ${theme.eui.euiBorderThin};
+ padding-bottom: ${theme.eui.paddingSizes.s};
+ `}
+
+ @media only screen and (min-width: ${theme.eui.euiBreakpoints.l}) {
+ display: flex;
+ justify-content: space-between;
+ }
+ `}
+`;
+Bar.displayName = 'Bar';
+
+export const BarSection = styled.div.attrs({
+ className: 'siemUtilityBar__section',
+})`
+ ${({ theme }) => css`
+ & + & {
+ margin-top: ${theme.eui.euiSizeS};
+ }
+
+ @media only screen and (min-width: ${theme.eui.euiBreakpoints.m}) {
+ display: flex;
+ flex-wrap: wrap;
+ }
+
+ @media only screen and (min-width: ${theme.eui.euiBreakpoints.l}) {
+ & + & {
+ margin-top: 0;
+ margin-left: ${theme.eui.euiSize};
+ }
+ }
+ `}
+`;
+BarSection.displayName = 'BarSection';
+
+export const BarGroup = styled.div.attrs({
+ className: 'siemUtilityBar__group',
+})`
+ ${({ theme }) => css`
+ & + & {
+ margin-top: ${theme.eui.euiSizeS};
+ }
+
+ @media only screen and (min-width: ${theme.eui.euiBreakpoints.m}) {
+ align-items: flex-start;
+ border-right: ${theme.eui.euiBorderThin};
+ display: flex;
+ // flex-wrap: wrap;
+ margin-right: ${theme.eui.paddingSizes.m};
+ padding-right: ${theme.eui.paddingSizes.m};
+
+ & + & {
+ margin-top: 0;
+ }
+
+ &:last-child {
+ border-right: none;
+ margin-right: 0;
+ padding-right: 0;
+ }
+ }
+
+ & > * {
+ display: inline-block;
+ margin-right: ${theme.eui.euiSize};
+ white-space: nowrap;
+
+ &:last-child {
+ margin-right: 0;
+ }
+ }
+ `}
+`;
+BarGroup.displayName = 'BarGroup';
+
+export const BarText = styled.p.attrs({
+ className: 'siemUtilityBar__text',
+})`
+ ${({ theme }) => css`
+ color: ${theme.eui.textColors.subdued};
+ font-size: ${theme.eui.euiFontSizeXS};
+ line-height: ${theme.eui.euiLineHeight};
+ `}
+`;
+BarText.displayName = 'BarText';
+
+export interface BarActionLinkProps {
+ href?: string;
+ onClick?: Function;
+}
+
+export const BarActionLink = styled(EuiLink).attrs({
+ className: 'siemUtilityBar__action',
+})`
+ ${({ theme }) => css`
+ font-size: ${theme.eui.euiFontSizeXS};
+ line-height: ${theme.eui.euiLineHeight};
+ `}
+`;
+BarActionLink.displayName = 'BarActionLink';
diff --git a/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar.tsx b/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar.tsx
index be1f7a8bede58..f226e0e055391 100644
--- a/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar.tsx
@@ -4,34 +4,15 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { EuiFlexGroup } from '@elastic/eui';
import React from 'react';
-import styled, { css } from 'styled-components';
-interface AsideProps {
- border?: boolean;
-}
-
-const Aside = styled.aside.attrs({
- className: 'siemUtilityBar',
-})`
- ${({ border, theme }) => css`
- ${border &&
- css`
- border-bottom: ${theme.eui.euiBorderThin};
- padding-bottom: ${theme.eui.paddingSizes.s};
- `}
- `}
-`;
-Aside.displayName = 'Aside';
+import { Bar, BarProps } from './styles';
-export interface UtilityBarProps extends AsideProps {
+export interface UtilityBarProps extends BarProps {
children: React.ReactNode;
}
export const UtilityBar = React.memo(({ border, children }) => (
-
+ {children}
));
UtilityBar.displayName = 'UtilityBar';
diff --git a/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_action.tsx b/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_action.tsx
index 247124584a383..d2bacd746c8e7 100644
--- a/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_action.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_action.tsx
@@ -4,32 +4,17 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { EuiLink } from '@elastic/eui';
import React from 'react';
-import styled, { css } from 'styled-components';
-interface LinkProps {
- href?: string;
- onClick?: Function;
-}
-
-const Link = styled(EuiLink).attrs({
- className: 'siemUtilityBar__action',
-})`
- ${({ theme }) => css`
- font-size: ${theme.eui.euiFontSizeXS};
- line-height: ${theme.eui.euiLineHeight};
- `}
-`;
-Link.displayName = 'Link';
+import { BarActionLink, BarActionLinkProps } from './styles';
-export interface UtilityBarActionProps extends LinkProps {
+export interface UtilityBarActionProps extends BarActionLinkProps {
children: React.ReactNode;
}
export const UtilityBarAction = React.memo(({ children, href, onClick }) => (
-
+
{children}
-
+
));
UtilityBarAction.displayName = 'UtilityBarAction';
diff --git a/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_group.tsx b/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_group.tsx
index 7c877a413f359..1e23fd3498199 100644
--- a/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_group.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_group.tsx
@@ -5,38 +5,14 @@
*/
import React from 'react';
-import styled, { css } from 'styled-components';
-const Group = styled.div.attrs({
- className: 'siemUtilityBar__group',
-})`
- ${({ theme }) => css`
- border-right: ${theme.eui.euiBorderThin};
- padding-right: ${theme.eui.paddingSizes.m};
-
- &:last-child {
- border-right: none;
- padding-right: 0;
- }
-
- &,
- & > * {
- display: inline-block;
- margin-right: ${theme.eui.paddingSizes.m};
-
- &:last-child {
- margin-right: 0;
- }
- }
- `}
-`;
-Group.displayName = 'Group';
+import { BarGroup } from './styles';
export interface UtilityBarGroupProps {
children: React.ReactNode;
}
export const UtilityBarGroup = React.memo(({ children }) => (
- {children}
+ {children}
));
UtilityBarGroup.displayName = 'UtilityBarGroup';
diff --git a/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_section.tsx b/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_section.tsx
index 5cfd1353bc3bb..c457e6bc3dee0 100644
--- a/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_section.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_section.tsx
@@ -4,24 +4,15 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { EuiFlexItem } from '@elastic/eui';
import React from 'react';
-import styled, { css } from 'styled-components';
-const Section = styled(EuiFlexItem).attrs({
- className: 'siemUtilityBar__section',
-})`
- ${({ theme }) => css`
- display: block;
- `}
-`;
-Section.displayName = 'Section';
+import { BarSection } from './styles';
export interface UtilityBarSectionProps {
children: React.ReactNode;
}
export const UtilityBarSection = React.memo(({ children }) => (
-
+ {children}
));
UtilityBarSection.displayName = 'UtilityBarSection';
diff --git a/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_text.tsx b/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_text.tsx
index c8b0af4972497..f8eb25f03d4ad 100644
--- a/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_text.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_text.tsx
@@ -5,24 +5,14 @@
*/
import React from 'react';
-import styled, { css } from 'styled-components';
-const Text = styled.p.attrs({
- className: 'siemUtilityBar__text',
-})`
- ${({ theme }) => css`
- color: ${theme.eui.textColors.subdued};
- font-size: ${theme.eui.euiFontSizeXS};
- line-height: ${theme.eui.euiLineHeight};
- `}
-`;
-Text.displayName = 'Text';
+import { BarText } from './styles';
export interface UtilityBarTextProps {
children: string;
}
export const UtilityBarText = React.memo(({ children }) => (
- {children}
+ {children}
));
UtilityBarText.displayName = 'UtilityBarText';
From a4a8bef5b7873e71077dacf5d76cf456fdd0e022 Mon Sep 17 00:00:00 2001
From: Michael Marcialis
Date: Mon, 14 Oct 2019 15:29:27 -0400
Subject: [PATCH 11/57] support popovers in utility bar
---
.../public/components/link_back/index.tsx | 2 +
.../public/components/utility_bar/styles.tsx | 22 ++++++--
.../utility_bar/utility_bar_action.tsx | 56 ++++++++++++++++---
.../detection_engine/detection_engine.tsx | 27 ++++-----
4 files changed, 77 insertions(+), 30 deletions(-)
diff --git a/x-pack/legacy/plugins/siem/public/components/link_back/index.tsx b/x-pack/legacy/plugins/siem/public/components/link_back/index.tsx
index 8854478e3dc34..ece3ab57e286f 100644
--- a/x-pack/legacy/plugins/siem/public/components/link_back/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/link_back/index.tsx
@@ -23,6 +23,8 @@ const Link = styled(EuiLink).attrs({
.euiIcon {
margin-right: ${theme.eui.euiSizeXS};
+ position: relative;
+ top: -1px;
}
`}
`;
diff --git a/x-pack/legacy/plugins/siem/public/components/utility_bar/styles.tsx b/x-pack/legacy/plugins/siem/public/components/utility_bar/styles.tsx
index 2decb803c54ea..945041b01fc4d 100644
--- a/x-pack/legacy/plugins/siem/public/components/utility_bar/styles.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/utility_bar/styles.tsx
@@ -107,17 +107,31 @@ export const BarText = styled.p.attrs({
`;
BarText.displayName = 'BarText';
-export interface BarActionLinkProps {
+export interface BarActionProps {
+ children: React.ReactNode;
href?: string;
onClick?: Function;
}
-export const BarActionLink = styled(EuiLink).attrs({
+export const BarAction = styled(EuiLink).attrs({
className: 'siemUtilityBar__action',
-})`
+})`
${({ theme }) => css`
font-size: ${theme.eui.euiFontSizeXS};
line-height: ${theme.eui.euiLineHeight};
+
+ .euiIcon {
+ position: relative;
+ top: -1px;
+
+ &:first-child {
+ margin-right: ${theme.eui.euiSizeXS};
+ }
+
+ &:last-child {
+ margin-left: ${theme.eui.euiSizeXS};
+ }
+ }
`}
`;
-BarActionLink.displayName = 'BarActionLink';
+BarAction.displayName = 'BarAction';
diff --git a/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_action.tsx b/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_action.tsx
index d2bacd746c8e7..80eaa2bc694a7 100644
--- a/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_action.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_action.tsx
@@ -4,17 +4,55 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import React from 'react';
+import { EuiIcon, EuiPopover, IconType } from '@elastic/eui';
+import React, { useState } from 'react';
-import { BarActionLink, BarActionLinkProps } from './styles';
+import { BarAction, BarActionProps } from './styles';
-export interface UtilityBarActionProps extends BarActionLinkProps {
- children: React.ReactNode;
+interface PopoverProps {
+ children: BarActionProps['children'];
+ popoverContent?: React.ReactNode;
}
-export const UtilityBarAction = React.memo(({ children, href, onClick }) => (
-
- {children}
-
-));
+const Popover = React.memo(({ children, popoverContent }) => {
+ const [popoverState, setPopoverState] = useState(false);
+
+ return (
+ setPopoverState(!popoverState)}>
+ {children}
+
+
+ }
+ isOpen={popoverState}
+ closePopover={() => setPopoverState(false)}
+ >
+ {popoverContent}
+
+ );
+});
+Popover.displayName = 'Popover';
+
+export interface UtilityBarActionProps extends BarActionProps {
+ iconSide?: 'left' | 'right';
+ iconType?: IconType;
+ popoverContent?: PopoverProps['popoverContent'];
+}
+
+export const UtilityBarAction = React.memo(
+ ({ children, href, iconSide = 'left', iconType, onClick, popoverContent }) => {
+ if (popoverContent) {
+ return {children};
+ } else {
+ return (
+
+ {iconType && iconSide === 'left' && }
+ {children}
+ {iconType && iconSide === 'right' && }
+
+ );
+ }
+ }
+);
UtilityBarAction.displayName = 'UtilityBarAction';
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
index e643deb73f37f..2af2890e4396f 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
@@ -144,7 +144,6 @@ export const DetectionEngineComponent = React.memo(() => {
options={toggleButtons}
/>
-
@@ -154,40 +153,34 @@ export const DetectionEngineComponent = React.memo(() => {
{'Selected: 20 signals'}
-
- {'Batch actions'}
+ {'Batch actions context menu here.'}}>
+ {'Batch actions'}
-
- {'Select all signals on all pages'}
+
+ {'Select all signals on all pages'}
-
- {'Clear 7 filters'}
-
+ {'Clear 7 filters'}
-
- {'Clear aggregation'}
-
+ {'Clear aggregation'}
-
- {'Customize columns'}
+ {'Customize columns context menu here.'}}>
+ {'Customize columns'}
-
- {'Aggregate data'}
-
+ {'Aggregate data'}
- {/* Datagrid here. Talk to Chandler Prall about possibility of early access. If not possible, use basic table. */}
+ {/* Open signals datagrid here. Talk to Chandler Prall about possibility of early access. If not possible, use basic table. */}
From c6f96c6e9e944e9abb5ccc586fd373aa15e7362f Mon Sep 17 00:00:00 2001
From: Michael Marcialis
Date: Tue, 15 Oct 2019 09:26:42 -0400
Subject: [PATCH 12/57] refactor icon side
---
.../public/components/utility_bar/styles.tsx | 33 +++++++++++--------
.../utility_bar/utility_bar_action.tsx | 12 +++----
2 files changed, 24 insertions(+), 21 deletions(-)
diff --git a/x-pack/legacy/plugins/siem/public/components/utility_bar/styles.tsx b/x-pack/legacy/plugins/siem/public/components/utility_bar/styles.tsx
index 945041b01fc4d..2d2da184e3ced 100644
--- a/x-pack/legacy/plugins/siem/public/components/utility_bar/styles.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/utility_bar/styles.tsx
@@ -68,7 +68,6 @@ export const BarGroup = styled.div.attrs({
align-items: flex-start;
border-right: ${theme.eui.euiBorderThin};
display: flex;
- // flex-wrap: wrap;
margin-right: ${theme.eui.paddingSizes.m};
padding-right: ${theme.eui.paddingSizes.m};
@@ -84,9 +83,7 @@ export const BarGroup = styled.div.attrs({
}
& > * {
- display: inline-block;
margin-right: ${theme.eui.euiSize};
- white-space: nowrap;
&:last-child {
margin-right: 0;
@@ -101,8 +98,10 @@ export const BarText = styled.p.attrs({
})`
${({ theme }) => css`
color: ${theme.eui.textColors.subdued};
+ display: inline-block;
font-size: ${theme.eui.euiFontSizeXS};
line-height: ${theme.eui.euiLineHeight};
+ white-space: nowrap;
`}
`;
BarText.displayName = 'BarText';
@@ -110,28 +109,34 @@ BarText.displayName = 'BarText';
export interface BarActionProps {
children: React.ReactNode;
href?: string;
+ iconSide?: 'left' | 'right';
onClick?: Function;
}
export const BarAction = styled(EuiLink).attrs({
className: 'siemUtilityBar__action',
})`
- ${({ theme }) => css`
+ ${({ iconSide, theme }) => css`
+ align-items: center;
+ display: inline-flex;
font-size: ${theme.eui.euiFontSizeXS};
line-height: ${theme.eui.euiLineHeight};
- .euiIcon {
- position: relative;
- top: -1px;
+ ${iconSide === 'left' &&
+ css`
+ .euiIcon {
+ margin-right: ${theme.eui.euiSizeXS};
+ }
+ `}
- &:first-child {
- margin-right: ${theme.eui.euiSizeXS};
- }
+ ${iconSide === 'right' &&
+ css`
+ flex-direction: row-reverse;
- &:last-child {
- margin-left: ${theme.eui.euiSizeXS};
- }
- }
+ .euiIcon {
+ margin-left: ${theme.eui.euiSizeXS};
+ }
+ `}
`}
`;
BarAction.displayName = 'BarAction';
diff --git a/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_action.tsx b/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_action.tsx
index 80eaa2bc694a7..d48eba92cacaa 100644
--- a/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_action.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_action.tsx
@@ -20,9 +20,9 @@ const Popover = React.memo(({ children, popoverContent })
return (
setPopoverState(!popoverState)}>
- {children}
+ setPopoverState(!popoverState)}>
+ {children}
}
isOpen={popoverState}
@@ -35,7 +35,6 @@ const Popover = React.memo(({ children, popoverContent })
Popover.displayName = 'Popover';
export interface UtilityBarActionProps extends BarActionProps {
- iconSide?: 'left' | 'right';
iconType?: IconType;
popoverContent?: PopoverProps['popoverContent'];
}
@@ -46,10 +45,9 @@ export const UtilityBarAction = React.memo(
return {children};
} else {
return (
-
- {iconType && iconSide === 'left' && }
- {children}
- {iconType && iconSide === 'right' && }
+
+ {iconType && }
+ {children}
);
}
From 8b1b58009cdddf194af4553f7a58d2596b40d928 Mon Sep 17 00:00:00 2001
From: Michael Marcialis
Date: Tue, 15 Oct 2019 15:04:21 -0400
Subject: [PATCH 13/57] UtilityBar unit tests
---
.../components/header_page/index.test.tsx | 4 +-
.../public/components/header_page/index.tsx | 2 +-
.../components/header_section/index.test.tsx | 4 +-
.../components/header_section/index.tsx | 2 +-
.../public/components/link_back/index.tsx | 7 +-
.../__snapshots__/index.test.tsx.snap | 10 --
.../__snapshots__/utility_bar.test.tsx.snap | 35 +++++
.../utility_bar_action.test.tsx.snap | 9 ++
.../utility_bar_group.test.tsx.snap | 11 ++
.../utility_bar_section.test.tsx.snap | 13 ++
.../utility_bar_text.test.tsx.snap | 9 ++
.../public/components/utility_bar/styles.tsx | 15 ++-
.../utility_bar/utility_bar.test.tsx | 94 +++++++++++++-
.../utility_bar/utility_bar_action.test.tsx | 122 ++++++++++++++++++
.../utility_bar/utility_bar_action.tsx | 2 +-
.../utility_bar/utility_bar_group.test.tsx | 29 +++++
.../utility_bar/utility_bar_section.test.tsx | 31 +++++
.../utility_bar/utility_bar_text.test.tsx | 27 ++++
.../detection_engine/detection_engine.tsx | 1 +
.../pages/detection_engine/rules/index.tsx | 17 +--
20 files changed, 400 insertions(+), 44 deletions(-)
delete mode 100644 x-pack/legacy/plugins/siem/public/components/utility_bar/__snapshots__/index.test.tsx.snap
create mode 100644 x-pack/legacy/plugins/siem/public/components/utility_bar/__snapshots__/utility_bar.test.tsx.snap
create mode 100644 x-pack/legacy/plugins/siem/public/components/utility_bar/__snapshots__/utility_bar_action.test.tsx.snap
create mode 100644 x-pack/legacy/plugins/siem/public/components/utility_bar/__snapshots__/utility_bar_group.test.tsx.snap
create mode 100644 x-pack/legacy/plugins/siem/public/components/utility_bar/__snapshots__/utility_bar_section.test.tsx.snap
create mode 100644 x-pack/legacy/plugins/siem/public/components/utility_bar/__snapshots__/utility_bar_text.test.tsx.snap
create mode 100644 x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_action.test.tsx
create mode 100644 x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_group.test.tsx
create mode 100644 x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_section.test.tsx
create mode 100644 x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_text.test.tsx
diff --git a/x-pack/legacy/plugins/siem/public/components/header_page/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/header_page/index.test.tsx
index 6e9150b566bb5..2937ddc18dd82 100644
--- a/x-pack/legacy/plugins/siem/public/components/header_page/index.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/header_page/index.test.tsx
@@ -181,7 +181,7 @@ describe('HeaderPage', () => {
const siemHeaderPage = wrapper.find('.siemHeaderPage').first();
expect(siemHeaderPage).toHaveStyleRule('border-bottom', euiDarkVars.euiBorderThin);
- expect(siemHeaderPage).toHaveStyleRule('padding-bottom', euiDarkVars.euiSizeL);
+ expect(siemHeaderPage).toHaveStyleRule('padding-bottom', euiDarkVars.paddingSizes.l);
});
test('it DOES NOT apply border styles when border is false', () => {
@@ -193,7 +193,7 @@ describe('HeaderPage', () => {
const siemHeaderPage = wrapper.find('.siemHeaderPage').first();
expect(siemHeaderPage).not.toHaveStyleRule('border-bottom', euiDarkVars.euiBorderThin);
- expect(siemHeaderPage).not.toHaveStyleRule('padding-bottom', euiDarkVars.euiSizeL);
+ expect(siemHeaderPage).not.toHaveStyleRule('padding-bottom', euiDarkVars.paddingSizes.l);
});
test('it renders as a draggable when arguments provided', () => {
diff --git a/x-pack/legacy/plugins/siem/public/components/header_page/index.tsx b/x-pack/legacy/plugins/siem/public/components/header_page/index.tsx
index e5a696e862eb9..b62273d8f0466 100644
--- a/x-pack/legacy/plugins/siem/public/components/header_page/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/header_page/index.tsx
@@ -25,7 +25,7 @@ const Header = styled.header.attrs({
${border &&
css`
border-bottom: ${theme.eui.euiBorderThin};
- padding-bottom: ${theme.eui.euiSizeL};
+ padding-bottom: ${theme.eui.paddingSizes.l};
`}
`}
`;
diff --git a/x-pack/legacy/plugins/siem/public/components/header_section/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/header_section/index.test.tsx
index 0a486bf82fdcf..5d2d3effebafb 100644
--- a/x-pack/legacy/plugins/siem/public/components/header_section/index.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/header_section/index.test.tsx
@@ -143,7 +143,7 @@ describe('HeaderSection', () => {
const siemHeaderSection = wrapper.find('.siemHeaderSection').first();
expect(siemHeaderSection).toHaveStyleRule('border-bottom', euiDarkVars.euiBorderThin);
- expect(siemHeaderSection).toHaveStyleRule('padding-bottom', euiDarkVars.euiSizeL);
+ expect(siemHeaderSection).toHaveStyleRule('padding-bottom', euiDarkVars.paddingSizes.l);
});
test('it DOES NOT apply border styles when border is false', () => {
@@ -155,6 +155,6 @@ describe('HeaderSection', () => {
const siemHeaderSection = wrapper.find('.siemHeaderSection').first();
expect(siemHeaderSection).not.toHaveStyleRule('border-bottom', euiDarkVars.euiBorderThin);
- expect(siemHeaderSection).not.toHaveStyleRule('padding-bottom', euiDarkVars.euiSizeL);
+ expect(siemHeaderSection).not.toHaveStyleRule('padding-bottom', euiDarkVars.paddingSizes.l);
});
});
diff --git a/x-pack/legacy/plugins/siem/public/components/header_section/index.tsx b/x-pack/legacy/plugins/siem/public/components/header_section/index.tsx
index c8e161aff766e..38f216ccf65b0 100644
--- a/x-pack/legacy/plugins/siem/public/components/header_section/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/header_section/index.tsx
@@ -25,7 +25,7 @@ const Header = styled.header.attrs({
${border &&
css`
border-bottom: ${theme.eui.euiBorderThin};
- padding-bottom: ${theme.eui.euiSizeL};
+ padding-bottom: ${theme.eui.paddingSizes.l};
`}
`}
`;
diff --git a/x-pack/legacy/plugins/siem/public/components/link_back/index.tsx b/x-pack/legacy/plugins/siem/public/components/link_back/index.tsx
index ece3ab57e286f..1736fcb49bde3 100644
--- a/x-pack/legacy/plugins/siem/public/components/link_back/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/link_back/index.tsx
@@ -16,15 +16,14 @@ const Link = styled(EuiLink).attrs({
className: 'siemLinkBack',
})`
${({ theme }) => css`
- display: inline-block;
+ align-items: center;
+ display: inline-flex;
font-size: ${theme.eui.euiFontSizeXS};
line-height: ${theme.eui.euiLineHeight};
margin-bottom: ${theme.eui.euiSizeS};
.euiIcon {
margin-right: ${theme.eui.euiSizeXS};
- position: relative;
- top: -1px;
}
`}
`;
@@ -37,7 +36,7 @@ export interface LinkBackProps extends LinkProps {
export const LinkBack = React.memo(({ href, text }) => (
- {text}
+ {text}
));
LinkBack.displayName = 'LinkBack';
diff --git a/x-pack/legacy/plugins/siem/public/components/utility_bar/__snapshots__/index.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/utility_bar/__snapshots__/index.test.tsx.snap
deleted file mode 100644
index f1d437379dd8c..0000000000000
--- a/x-pack/legacy/plugins/siem/public/components/utility_bar/__snapshots__/index.test.tsx.snap
+++ /dev/null
@@ -1,10 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`LinkBack it renders 1`] = `
-
-
-
-`;
diff --git a/x-pack/legacy/plugins/siem/public/components/utility_bar/__snapshots__/utility_bar.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/utility_bar/__snapshots__/utility_bar.test.tsx.snap
new file mode 100644
index 0000000000000..66ad764ff445c
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/components/utility_bar/__snapshots__/utility_bar.test.tsx.snap
@@ -0,0 +1,35 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`UtilityBar it renders 1`] = `
+
+
+
+
+
+ Test text
+
+
+
+
+ Test popover
+
+ }
+ >
+ Test action
+
+
+
+
+
+
+ Test action
+
+
+
+
+
+`;
diff --git a/x-pack/legacy/plugins/siem/public/components/utility_bar/__snapshots__/utility_bar_action.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/utility_bar/__snapshots__/utility_bar_action.test.tsx.snap
new file mode 100644
index 0000000000000..82fb6d81d8033
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/components/utility_bar/__snapshots__/utility_bar_action.test.tsx.snap
@@ -0,0 +1,9 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`UtilityBarAction it renders 1`] = `
+
+
+ Test action
+
+
+`;
diff --git a/x-pack/legacy/plugins/siem/public/components/utility_bar/__snapshots__/utility_bar_group.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/utility_bar/__snapshots__/utility_bar_group.test.tsx.snap
new file mode 100644
index 0000000000000..62ff1b17dd55f
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/components/utility_bar/__snapshots__/utility_bar_group.test.tsx.snap
@@ -0,0 +1,11 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`UtilityBarGroup it renders 1`] = `
+
+
+
+ Test text
+
+
+
+`;
diff --git a/x-pack/legacy/plugins/siem/public/components/utility_bar/__snapshots__/utility_bar_section.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/utility_bar/__snapshots__/utility_bar_section.test.tsx.snap
new file mode 100644
index 0000000000000..f81717c892755
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/components/utility_bar/__snapshots__/utility_bar_section.test.tsx.snap
@@ -0,0 +1,13 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`UtilityBarSection it renders 1`] = `
+
+
+
+
+ Test text
+
+
+
+
+`;
diff --git a/x-pack/legacy/plugins/siem/public/components/utility_bar/__snapshots__/utility_bar_text.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/utility_bar/__snapshots__/utility_bar_text.test.tsx.snap
new file mode 100644
index 0000000000000..446b5556945d8
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/components/utility_bar/__snapshots__/utility_bar_text.test.tsx.snap
@@ -0,0 +1,9 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`UtilityBarText it renders 1`] = `
+
+
+ Test text
+
+
+`;
diff --git a/x-pack/legacy/plugins/siem/public/components/utility_bar/styles.tsx b/x-pack/legacy/plugins/siem/public/components/utility_bar/styles.tsx
index 2d2da184e3ced..4d049a1f7f2ec 100644
--- a/x-pack/legacy/plugins/siem/public/components/utility_bar/styles.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/utility_bar/styles.tsx
@@ -60,14 +60,17 @@ export const BarGroup = styled.div.attrs({
className: 'siemUtilityBar__group',
})`
${({ theme }) => css`
+ align-items: flex-start;
+ display: flex;
+ flex-wrap: wrap;
+
& + & {
margin-top: ${theme.eui.euiSizeS};
}
@media only screen and (min-width: ${theme.eui.euiBreakpoints.m}) {
- align-items: flex-start;
border-right: ${theme.eui.euiBorderThin};
- display: flex;
+ flex-wrap: nowrap;
margin-right: ${theme.eui.paddingSizes.m};
padding-right: ${theme.eui.paddingSizes.m};
@@ -83,7 +86,10 @@ export const BarGroup = styled.div.attrs({
}
& > * {
+ font-size: ${theme.eui.euiFontSizeXS};
+ line-height: ${theme.eui.euiLineHeight};
margin-right: ${theme.eui.euiSize};
+ white-space: nowrap;
&:last-child {
margin-right: 0;
@@ -99,9 +105,6 @@ export const BarText = styled.p.attrs({
${({ theme }) => css`
color: ${theme.eui.textColors.subdued};
display: inline-block;
- font-size: ${theme.eui.euiFontSizeXS};
- line-height: ${theme.eui.euiLineHeight};
- white-space: nowrap;
`}
`;
BarText.displayName = 'BarText';
@@ -119,8 +122,6 @@ export const BarAction = styled(EuiLink).attrs({
${({ iconSide, theme }) => css`
align-items: center;
display: inline-flex;
- font-size: ${theme.eui.euiFontSizeXS};
- line-height: ${theme.eui.euiLineHeight};
${iconSide === 'left' &&
css`
diff --git a/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar.test.tsx b/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar.test.tsx
index f6a5c672b63de..a0f684b90ea79 100644
--- a/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar.test.tsx
@@ -4,24 +4,110 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { shallow } from 'enzyme';
+import euiDarkVars from '@elastic/eui/dist/eui_theme_dark.json';
+import { mount, shallow } from 'enzyme';
import toJson from 'enzyme-to-json';
+import 'jest-styled-components';
import React from 'react';
import '../../mock/ui_settings';
import { TestProviders } from '../../mock';
-import { LinkBack } from './index';
+import {
+ UtilityBar,
+ UtilityBarAction,
+ UtilityBarGroup,
+ UtilityBarSection,
+ UtilityBarText,
+} from './index';
jest.mock('../../lib/settings/use_kibana_ui_setting');
-describe('LinkBack', () => {
+describe('UtilityBar', () => {
test('it renders', () => {
const wrapper = shallow(
-
+
+
+
+ {'Test text'}
+
+
+
+ {'Test popover'}}>
+ {'Test action'}
+
+
+
+
+
+
+ {'Test action'}
+
+
+
);
expect(toJson(wrapper)).toMatchSnapshot();
});
+
+ test('it applies border styles when border is true', () => {
+ const wrapper = mount(
+
+
+
+
+ {'Test text'}
+
+
+
+ {'Test popover'}}>
+ {'Test action'}
+
+
+
+
+
+
+ {'Test action'}
+
+
+
+
+ );
+ const siemUtilityBar = wrapper.find('.siemUtilityBar').first();
+
+ expect(siemUtilityBar).toHaveStyleRule('border-bottom', euiDarkVars.euiBorderThin);
+ expect(siemUtilityBar).toHaveStyleRule('padding-bottom', euiDarkVars.paddingSizes.s);
+ });
+
+ test('it DOES NOT apply border styles when border is false', () => {
+ const wrapper = mount(
+
+
+
+
+ {'Test text'}
+
+
+
+ {'Test popover'}}>
+ {'Test action'}
+
+
+
+
+
+
+ {'Test action'}
+
+
+
+
+ );
+ const siemUtilityBar = wrapper.find('.siemUtilityBar').first();
+
+ expect(siemUtilityBar).not.toHaveStyleRule('border-bottom', euiDarkVars.euiBorderThin);
+ expect(siemUtilityBar).not.toHaveStyleRule('padding-bottom', euiDarkVars.paddingSizes.s);
+ });
});
diff --git a/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_action.test.tsx b/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_action.test.tsx
new file mode 100644
index 0000000000000..c4f241e545800
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_action.test.tsx
@@ -0,0 +1,122 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { mount, shallow } from 'enzyme';
+import toJson from 'enzyme-to-json';
+import 'jest-styled-components';
+import React from 'react';
+
+import '../../mock/ui_settings';
+import { TestProviders } from '../../mock';
+import { UtilityBarAction } from './index';
+
+jest.mock('../../lib/settings/use_kibana_ui_setting');
+
+describe('UtilityBarAction', () => {
+ test('it renders', () => {
+ const wrapper = shallow(
+
+ {'Test action'}
+
+ );
+
+ expect(toJson(wrapper)).toMatchSnapshot();
+ });
+
+ test('it renders an action button', () => {
+ const wrapper = mount(
+
+ alert('Test alert')}>{'Test action'}
+
+ );
+
+ expect(
+ wrapper
+ .find('button')
+ .first()
+ .exists()
+ ).toBe(true);
+ });
+
+ test('it renders an action link', () => {
+ const wrapper = mount(
+
+ {'Test action'}
+
+ );
+
+ expect(
+ wrapper
+ .find('a')
+ .first()
+ .exists()
+ ).toBe(true);
+ });
+
+ test('it renders an icon', () => {
+ const wrapper = mount(
+
+ {'Test action'}
+
+ );
+
+ expect(
+ wrapper
+ .find('.euiIcon')
+ .first()
+ .exists()
+ ).toBe(true);
+ });
+
+ test('it can right-align an icon', () => {
+ const wrapper = mount(
+
+
+ {'Test action'}
+
+
+ );
+
+ expect(wrapper.find('.siemUtilityBar__action').first()).toHaveStyleRule(
+ 'flex-direction',
+ 'row-reverse'
+ );
+ });
+
+ test('it renders a popover', () => {
+ const wrapper = mount(
+
+ {'Test popover'}}>
+ {'Test action'}
+
+
+ );
+
+ expect(
+ wrapper
+ .find('.euiPopover')
+ .first()
+ .exists()
+ ).toBe(true);
+ });
+
+ test('the popover action has an arrow icon', () => {
+ const wrapper = mount(
+
+ {'Test popover'}}>
+ {'Test action'}
+
+
+ );
+
+ expect(
+ wrapper
+ .find('.euiIcon')
+ .first()
+ .exists()
+ ).toBe(true);
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_action.tsx b/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_action.tsx
index d48eba92cacaa..bb5dca77d76b8 100644
--- a/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_action.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_action.tsx
@@ -47,7 +47,7 @@ export const UtilityBarAction = React.memo(
return (
{iconType && }
- {children}
+ {children}
);
}
diff --git a/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_group.test.tsx b/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_group.test.tsx
new file mode 100644
index 0000000000000..3fa42a690d588
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_group.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;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { shallow } from 'enzyme';
+import toJson from 'enzyme-to-json';
+import React from 'react';
+
+import '../../mock/ui_settings';
+import { TestProviders } from '../../mock';
+import { UtilityBarGroup, UtilityBarText } from './index';
+
+jest.mock('../../lib/settings/use_kibana_ui_setting');
+
+describe('UtilityBarGroup', () => {
+ test('it renders', () => {
+ const wrapper = shallow(
+
+
+ {'Test text'}
+
+
+ );
+
+ expect(toJson(wrapper)).toMatchSnapshot();
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_section.test.tsx b/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_section.test.tsx
new file mode 100644
index 0000000000000..90837f2e4cc03
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_section.test.tsx
@@ -0,0 +1,31 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { shallow } from 'enzyme';
+import toJson from 'enzyme-to-json';
+import React from 'react';
+
+import '../../mock/ui_settings';
+import { TestProviders } from '../../mock';
+import { UtilityBarGroup, UtilityBarSection, UtilityBarText } from './index';
+
+jest.mock('../../lib/settings/use_kibana_ui_setting');
+
+describe('UtilityBarSection', () => {
+ test('it renders', () => {
+ const wrapper = shallow(
+
+
+
+ {'Test text'}
+
+
+
+ );
+
+ expect(toJson(wrapper)).toMatchSnapshot();
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_text.test.tsx b/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_text.test.tsx
new file mode 100644
index 0000000000000..71afd2230e2f6
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_text.test.tsx
@@ -0,0 +1,27 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { shallow } from 'enzyme';
+import toJson from 'enzyme-to-json';
+import React from 'react';
+
+import '../../mock/ui_settings';
+import { TestProviders } from '../../mock';
+import { UtilityBarText } from './index';
+
+jest.mock('../../lib/settings/use_kibana_ui_setting');
+
+describe('UtilityBarText', () => {
+ test('it renders', () => {
+ const wrapper = shallow(
+
+ {'Test text'}
+
+ );
+
+ expect(toJson(wrapper)).toMatchSnapshot();
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
index 2af2890e4396f..d85f9fa8a0028 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
@@ -144,6 +144,7 @@ export const DetectionEngineComponent = React.memo(() => {
options={toggleButtons}
/>
+
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
index 559b3cf737eea..8fbfbfa166de6 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
@@ -14,7 +14,6 @@ import {
EuiFlexGroup,
EuiFlexItem,
EuiHealth,
- EuiIcon,
EuiLink,
EuiPanel,
EuiSpacer,
@@ -146,15 +145,13 @@ const AllRules = React.memo(() => {
{'Selected: 2 rules'}
-
- {'Batch actions'}
+ {'Batch actions context menu here.'}}>
+ {'Batch actions'}
-
- {'Clear 7 filters'}
-
+ {'Clear 7 filters'}
@@ -329,15 +326,11 @@ const ActivityMonitor = React.memo(() => {
{'Selected: 2 activities'}
-
- {'Stop selected'}
-
+ {'Stop selected'}
-
- {'Clear 7 filters'}
-
+ {'Clear 7 filters'}
From d2837d07c345fd7db52ee671a67423ffcdb10d6a Mon Sep 17 00:00:00 2001
From: Michael Marcialis
Date: Tue, 15 Oct 2019 15:49:06 -0400
Subject: [PATCH 14/57] remove page tests for now
---
.../create_rule/index.test.tsx | 77 ------------------
.../detection_engine.test.tsx | 78 -------------------
.../detection_engine/edit_rule/index.test.tsx | 77 ------------------
.../rule_details/index.test.tsx | 78 -------------------
.../detection_engine/rules/index.test.tsx | 77 ------------------
5 files changed, 387 deletions(-)
delete mode 100644 x-pack/legacy/plugins/siem/public/pages/detection_engine/create_rule/index.test.tsx
delete mode 100644 x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.test.tsx
delete mode 100644 x-pack/legacy/plugins/siem/public/pages/detection_engine/edit_rule/index.test.tsx
delete mode 100644 x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.test.tsx
delete mode 100644 x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.test.tsx
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/create_rule/index.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/create_rule/index.test.tsx
deleted file mode 100644
index 59407227b5da5..0000000000000
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/create_rule/index.test.tsx
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import { mount } from 'enzyme';
-import { cloneDeep } from 'lodash/fp';
-import * as React from 'react';
-import { MockedProvider } from 'react-apollo/test-utils';
-import { MemoryRouter } from 'react-router-dom';
-
-import { mocksSource } from '../../../containers/source/mock';
-import { TestProviders } from '../../../mock';
-import '../../../mock/ui_settings';
-import { CreateRuleComponent } from './index';
-
-jest.mock('ui/documentation_links', () => ({
- documentationLinks: {
- kibana: 'http://www.example.com',
- },
-}));
-
-let localSource: Array<{
- request: {};
- result: {
- data: {
- source: {
- status: {
- indicesExist: boolean;
- };
- };
- };
- };
-}>;
-
-describe('CreateRuleComponent', () => {
- describe('rendering', () => {
- beforeEach(() => {
- localSource = cloneDeep(mocksSource);
- });
-
- test('it renders the Setup Instructions text when no index is available', async () => {
- localSource[0].result.data.source.status.indicesExist = false;
- const wrapper = mount(
-
-
-
-
-
-
-
- );
- // Why => https://github.com/apollographql/react-apollo/issues/1711
- await new Promise(resolve => setTimeout(resolve));
- wrapper.update();
- expect(wrapper.find('[data-test-subj="empty-page"]').exists()).toBe(true);
- });
-
- test('it DOES NOT render the Getting started text when an index is available', async () => {
- localSource[0].result.data.source.status.indicesExist = true;
- const wrapper = mount(
-
-
-
-
-
-
-
- );
- // Why => https://github.com/apollographql/react-apollo/issues/1711
- await new Promise(resolve => setTimeout(resolve));
- wrapper.update();
- expect(wrapper.find('[data-test-subj="empty-page"]').exists()).toBe(false);
- });
- });
-});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.test.tsx
deleted file mode 100644
index 05030954af9c4..0000000000000
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.test.tsx
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import { mount } from 'enzyme';
-import { cloneDeep } from 'lodash/fp';
-import * as React from 'react';
-import { MockedProvider } from 'react-apollo/test-utils';
-import { MemoryRouter } from 'react-router-dom';
-
-import { mocksSource } from '../../containers/source/mock';
-import { TestProviders } from '../../mock';
-import '../../mock/match_media';
-import '../../mock/ui_settings';
-import { DetectionEngineComponent } from './detection_engine';
-
-jest.mock('ui/documentation_links', () => ({
- documentationLinks: {
- kibana: 'http://www.example.com',
- },
-}));
-
-let localSource: Array<{
- request: {};
- result: {
- data: {
- source: {
- status: {
- indicesExist: boolean;
- };
- };
- };
- };
-}>;
-
-describe('DetectionEngineComponent', () => {
- describe('rendering', () => {
- beforeEach(() => {
- localSource = cloneDeep(mocksSource);
- });
-
- test('it renders the Setup Instructions text when no index is available', async () => {
- localSource[0].result.data.source.status.indicesExist = false;
- const wrapper = mount(
-
-
-
-
-
-
-
- );
- // Why => https://github.com/apollographql/react-apollo/issues/1711
- await new Promise(resolve => setTimeout(resolve));
- wrapper.update();
- expect(wrapper.find('[data-test-subj="empty-page"]').exists()).toBe(true);
- });
-
- test('it DOES NOT render the Getting started text when an index is available', async () => {
- localSource[0].result.data.source.status.indicesExist = true;
- const wrapper = mount(
-
-
-
-
-
-
-
- );
- // Why => https://github.com/apollographql/react-apollo/issues/1711
- await new Promise(resolve => setTimeout(resolve));
- wrapper.update();
- expect(wrapper.find('[data-test-subj="empty-page"]').exists()).toBe(false);
- });
- });
-});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/edit_rule/index.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/edit_rule/index.test.tsx
deleted file mode 100644
index b8f71e2c599c9..0000000000000
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/edit_rule/index.test.tsx
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import { mount } from 'enzyme';
-import { cloneDeep } from 'lodash/fp';
-import * as React from 'react';
-import { MockedProvider } from 'react-apollo/test-utils';
-import { MemoryRouter } from 'react-router-dom';
-
-import { mocksSource } from '../../../containers/source/mock';
-import { TestProviders } from '../../../mock';
-import '../../../mock/ui_settings';
-import { EditRuleComponent } from './index';
-
-jest.mock('ui/documentation_links', () => ({
- documentationLinks: {
- kibana: 'http://www.example.com',
- },
-}));
-
-let localSource: Array<{
- request: {};
- result: {
- data: {
- source: {
- status: {
- indicesExist: boolean;
- };
- };
- };
- };
-}>;
-
-describe('EditRuleComponent', () => {
- describe('rendering', () => {
- beforeEach(() => {
- localSource = cloneDeep(mocksSource);
- });
-
- test('it renders the Setup Instructions text when no index is available', async () => {
- localSource[0].result.data.source.status.indicesExist = false;
- const wrapper = mount(
-
-
-
-
-
-
-
- );
- // Why => https://github.com/apollographql/react-apollo/issues/1711
- await new Promise(resolve => setTimeout(resolve));
- wrapper.update();
- expect(wrapper.find('[data-test-subj="empty-page"]').exists()).toBe(true);
- });
-
- test('it DOES NOT render the Getting started text when an index is available', async () => {
- localSource[0].result.data.source.status.indicesExist = true;
- const wrapper = mount(
-
-
-
-
-
-
-
- );
- // Why => https://github.com/apollographql/react-apollo/issues/1711
- await new Promise(resolve => setTimeout(resolve));
- wrapper.update();
- expect(wrapper.find('[data-test-subj="empty-page"]').exists()).toBe(false);
- });
- });
-});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.test.tsx
deleted file mode 100644
index 32b9891b4ad6b..0000000000000
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.test.tsx
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import { mount } from 'enzyme';
-import { cloneDeep } from 'lodash/fp';
-import * as React from 'react';
-import { MockedProvider } from 'react-apollo/test-utils';
-import { MemoryRouter } from 'react-router-dom';
-
-import { mocksSource } from '../../../containers/source/mock';
-import { TestProviders } from '../../../mock';
-import '../../../mock/match_media';
-import '../../../mock/ui_settings';
-import { RuleDetailsComponent } from './index';
-
-jest.mock('ui/documentation_links', () => ({
- documentationLinks: {
- kibana: 'http://www.example.com',
- },
-}));
-
-let localSource: Array<{
- request: {};
- result: {
- data: {
- source: {
- status: {
- indicesExist: boolean;
- };
- };
- };
- };
-}>;
-
-describe('RuleDetailsComponent', () => {
- describe('rendering', () => {
- beforeEach(() => {
- localSource = cloneDeep(mocksSource);
- });
-
- test('it renders the Setup Instructions text when no index is available', async () => {
- localSource[0].result.data.source.status.indicesExist = false;
- const wrapper = mount(
-
-
-
-
-
-
-
- );
- // Why => https://github.com/apollographql/react-apollo/issues/1711
- await new Promise(resolve => setTimeout(resolve));
- wrapper.update();
- expect(wrapper.find('[data-test-subj="empty-page"]').exists()).toBe(true);
- });
-
- test('it DOES NOT render the Getting started text when an index is available', async () => {
- localSource[0].result.data.source.status.indicesExist = true;
- const wrapper = mount(
-
-
-
-
-
-
-
- );
- // Why => https://github.com/apollographql/react-apollo/issues/1711
- await new Promise(resolve => setTimeout(resolve));
- wrapper.update();
- expect(wrapper.find('[data-test-subj="empty-page"]').exists()).toBe(false);
- });
- });
-});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.test.tsx
deleted file mode 100644
index 7472961a0cb90..0000000000000
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.test.tsx
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import { mount } from 'enzyme';
-import { cloneDeep } from 'lodash/fp';
-import * as React from 'react';
-import { MockedProvider } from 'react-apollo/test-utils';
-import { MemoryRouter } from 'react-router-dom';
-
-import { mocksSource } from '../../../containers/source/mock';
-import { TestProviders } from '../../../mock';
-import '../../../mock/ui_settings';
-import { RulesComponent } from './index';
-
-jest.mock('ui/documentation_links', () => ({
- documentationLinks: {
- kibana: 'http://www.example.com',
- },
-}));
-
-let localSource: Array<{
- request: {};
- result: {
- data: {
- source: {
- status: {
- indicesExist: boolean;
- };
- };
- };
- };
-}>;
-
-describe('RulesComponent', () => {
- describe('rendering', () => {
- beforeEach(() => {
- localSource = cloneDeep(mocksSource);
- });
-
- test('it renders the Setup Instructions text when no index is available', async () => {
- localSource[0].result.data.source.status.indicesExist = false;
- const wrapper = mount(
-
-
-
-
-
-
-
- );
- // Why => https://github.com/apollographql/react-apollo/issues/1711
- await new Promise(resolve => setTimeout(resolve));
- wrapper.update();
- expect(wrapper.find('[data-test-subj="empty-page"]').exists()).toBe(true);
- });
-
- test('it DOES NOT render the Getting started text when an index is available', async () => {
- localSource[0].result.data.source.status.indicesExist = true;
- const wrapper = mount(
-
-
-
-
-
-
-
- );
- // Why => https://github.com/apollographql/react-apollo/issues/1711
- await new Promise(resolve => setTimeout(resolve));
- wrapper.update();
- expect(wrapper.find('[data-test-subj="empty-page"]').exists()).toBe(false);
- });
- });
-});
From e2d0a349ce63f5e878a0eac47242ccb9f267834a Mon Sep 17 00:00:00 2001
From: Michael Marcialis
Date: Tue, 15 Oct 2019 16:12:50 -0400
Subject: [PATCH 15/57] adjust routes
---
.../public/components/link_to/link_to.tsx | 40 ++++++++++---------
1 file changed, 22 insertions(+), 18 deletions(-)
diff --git a/x-pack/legacy/plugins/siem/public/components/link_to/link_to.tsx b/x-pack/legacy/plugins/siem/public/components/link_to/link_to.tsx
index 6c1bf05f2acfe..5cf854e4b3023 100644
--- a/x-pack/legacy/plugins/siem/public/components/link_to/link_to.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/link_to/link_to.tsx
@@ -8,10 +8,7 @@ import React from 'react';
import { match as RouteMatch, Redirect, Route, Switch } from 'react-router-dom';
import { pure } from 'recompose';
-import { RedirectToHostsPage, RedirectToHostDetailsPage } from './redirect_to_hosts';
-import { RedirectToNetworkPage } from './redirect_to_network';
-import { RedirectToOverviewPage } from './redirect_to_overview';
-import { RedirectToTimelinesPage } from './redirect_to_timelines';
+import { HostsTableType } from '../../store/hosts/model';
import {
RedirectToCreateRulePage,
RedirectToDetectionEnginePage,
@@ -19,7 +16,10 @@ import {
RedirectToRuleDetailsPage,
RedirectToRulesPage,
} from './redirect_to_detection_engine';
-import { HostsTableType } from '../../store/hosts/model';
+import { RedirectToHostsPage, RedirectToHostDetailsPage } from './redirect_to_hosts';
+import { RedirectToNetworkPage } from './redirect_to_network';
+import { RedirectToOverviewPage } from './redirect_to_overview';
+import { RedirectToTimelinesPage } from './redirect_to_timelines';
interface LinkToPageProps {
match: RouteMatch<{}>;
@@ -27,47 +27,51 @@ interface LinkToPageProps {
export const LinkToPage = pure(({ match }) => (
-
-
+
+
-
+
-
+
));
From 955bbc1428d97a04975c07b2888d2cf04a4ca430 Mon Sep 17 00:00:00 2001
From: Michael Marcialis
Date: Tue, 15 Oct 2019 16:13:04 -0400
Subject: [PATCH 16/57] add comment
---
.../plugins/siem/public/pages/detection_engine/rules/index.tsx | 2 ++
1 file changed, 2 insertions(+)
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
index 8fbfbfa166de6..6fd09bdecdf4b 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
@@ -156,6 +156,8 @@ const AllRules = React.memo(() => {
+ {/* Example of potentially new TableCards component. This new table type may no longer be required for implementation, given the requirements changes that have been made over time. At present, the only afforded benefits of using it are 1) differentiation from regular tables and 2) the presence of a colored status bar on the left of each row. Neither are dealbreakers in my mind. If creating a new table component is out of the question for MVP, go with a standard EUI basic table. */}
+
From 3ff9af423f9ba99ab72399fbb0676c8255afb1ac Mon Sep 17 00:00:00 2001
From: Michael Marcialis
Date: Tue, 15 Oct 2019 17:42:31 -0400
Subject: [PATCH 17/57] cleanup chart
---
.../detection_engine/detection_engine.tsx | 117 ++++++++++--------
1 file changed, 65 insertions(+), 52 deletions(-)
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
index d85f9fa8a0028..26c50d94e9468 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
@@ -6,18 +6,19 @@
import {
Axis,
- BarSeries,
Chart,
HistogramBarSeries,
- Position,
- ScaleType,
Settings,
getAxisId,
getSpecId,
+ niceTimeFormatByDay,
+ niceTimeFormatter,
+ timeFormatter,
} from '@elastic/charts';
-import { EuiButton, EuiButtonGroup, EuiIcon, EuiPanel, EuiSelect, EuiSpacer } from '@elastic/eui';
+import { EuiButton, EuiButtonGroup, EuiPanel, EuiSelect, EuiSpacer } from '@elastic/eui';
import React from 'react';
import { StickyContainer } from 'react-sticky';
+import { npStart } from 'ui/new_platform';
import { FiltersGlobal } from '../../components/filters_global';
import { HeaderPage } from '../../components/header_page';
@@ -34,7 +35,7 @@ import { DetectionEngineKql } from './kql';
import * as i18n from './translations';
export const DetectionEngineComponent = React.memo(() => {
- const stackOptions = [
+ const sampleChartOptions = [
{ text: 'Risk scores', value: 'risk_scores' },
{ text: 'Severities', value: 'severities' },
{ text: 'Top destination IPs', value: 'destination_ips' },
@@ -46,15 +47,50 @@ export const DetectionEngineComponent = React.memo(() => {
{ text: 'Top source IPs', value: 'source_ips' },
{ text: 'Top users', value: 'users' },
];
+ const sampleChartData = [
+ { x: 1571090784000, y: 2, a: 'a' },
+ { x: 1571090784000, y: 2, b: 'b' },
+ { x: 1571093484000, y: 7, a: 'a' },
+ { x: 1571096184000, y: 3, a: 'a' },
+ { x: 1571098884000, y: 2, a: 'a' },
+ { x: 1571101584000, y: 7, a: 'a' },
+ { x: 1571104284000, y: 3, a: 'a' },
+ { x: 1571106984000, y: 2, a: 'a' },
+ { x: 1571109684000, y: 7, a: 'a' },
+ { x: 1571112384000, y: 3, a: 'a' },
+ { x: 1571115084000, y: 2, a: 'a' },
+ { x: 1571117784000, y: 7, a: 'a' },
+ { x: 1571120484000, y: 3, a: 'a' },
+ { x: 1571123184000, y: 2, a: 'a' },
+ { x: 1571125884000, y: 7, a: 'a' },
+ { x: 1571128584000, y: 3, a: 'a' },
+ { x: 1571131284000, y: 2, a: 'a' },
+ { x: 1571133984000, y: 7, a: 'a' },
+ { x: 1571136684000, y: 3, a: 'a' },
+ { x: 1571139384000, y: 2, a: 'a' },
+ { x: 1571142084000, y: 7, a: 'a' },
+ { x: 1571144784000, y: 3, a: 'a' },
+ { x: 1571147484000, y: 2, a: 'a' },
+ { x: 1571150184000, y: 7, a: 'a' },
+ { x: 1571152884000, y: 3, a: 'a' },
+ { x: 1571155584000, y: 2, a: 'a' },
+ { x: 1571158284000, y: 7, a: 'a' },
+ { x: 1571160984000, y: 3, a: 'a' },
+ { x: 1571163684000, y: 2, a: 'a' },
+ { x: 1571166384000, y: 7, a: 'a' },
+ { x: 1571169084000, y: 3, a: 'a' },
+ { x: 1571171784000, y: 2, a: 'a' },
+ { x: 1571174484000, y: 7, a: 'a' },
+ ];
- const idPrefix = 'signalType';
- const toggleButtons = [
+ const signalTypePrefix = 'signalType';
+ const signalTypeButtons = [
{
- id: `${idPrefix}0`,
+ id: `${signalTypePrefix}0`,
label: 'Open signals',
},
{
- id: `${idPrefix}1`,
+ id: `${signalTypePrefix}1`,
label: 'Closed signals',
},
];
@@ -74,59 +110,36 @@ export const DetectionEngineComponent = React.memo(() => {
-
+
-
+
-
+
-
+
@@ -141,7 +154,7 @@ export const DetectionEngineComponent = React.memo(() => {
onChange={() => {
return null;
}}
- options={toggleButtons}
+ options={signalTypeButtons}
/>
From 630e77ed767ae5826d245e5e790f685758f8701d Mon Sep 17 00:00:00 2001
From: Michael Marcialis
Date: Wed, 16 Oct 2019 10:15:51 -0400
Subject: [PATCH 18/57] open/closed signals content toggle
---
.../detection_engine/detection_engine.tsx | 161 +++++++++++-------
1 file changed, 102 insertions(+), 59 deletions(-)
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
index 26c50d94e9468..ba588409438be 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
@@ -12,11 +12,17 @@ import {
getAxisId,
getSpecId,
niceTimeFormatByDay,
- niceTimeFormatter,
timeFormatter,
} from '@elastic/charts';
-import { EuiButton, EuiButtonGroup, EuiPanel, EuiSelect, EuiSpacer } from '@elastic/eui';
-import React from 'react';
+import {
+ EuiButton,
+ EuiFilterButton,
+ EuiFilterGroup,
+ EuiPanel,
+ EuiSelect,
+ EuiSpacer,
+} from '@elastic/eui';
+import React, { useState } from 'react';
import { StickyContainer } from 'react-sticky';
import { npStart } from 'ui/new_platform';
@@ -34,6 +40,76 @@ import { SpyRoute } from '../../utils/route/spy_routes';
import { DetectionEngineKql } from './kql';
import * as i18n from './translations';
+const OpenSignals = React.memo(() => {
+ return (
+ <>
+
+
+
+ {`${i18n.PANEL_SUBTITLE_SHOWING}: 7,712 signals`}
+
+
+
+ {'Selected: 20 signals'}
+
+ {'Batch actions context menu here.'}}>
+ {'Batch actions'}
+
+
+
+ {'Select all signals on all pages'}
+
+
+
+
+ {'Clear 7 filters'}
+
+ {'Clear aggregation'}
+
+
+
+
+
+ {'Customize columns context menu here.'}}>
+ {'Customize columns'}
+
+
+ {'Aggregate data'}
+
+
+
+
+ {/* Open signals datagrid here. Talk to Chandler Prall about possibility of early access. If not possible, use basic table. */}
+ >
+ );
+});
+
+const ClosedSignals = React.memo(() => {
+ return (
+ <>
+
+
+
+ {`${i18n.PANEL_SUBTITLE_SHOWING}: 7,712 signals`}
+
+
+
+
+
+ {'Customize columns context menu here.'}}>
+ {'Customize columns'}
+
+
+ {'Aggregate data'}
+
+
+
+
+ {/* Closed signals datagrid here. Talk to Chandler Prall about possibility of early access. If not possible, use basic table. */}
+ >
+ );
+});
+
export const DetectionEngineComponent = React.memo(() => {
const sampleChartOptions = [
{ text: 'Risk scores', value: 'risk_scores' },
@@ -83,17 +159,8 @@ export const DetectionEngineComponent = React.memo(() => {
{ x: 1571174484000, y: 7, a: 'a' },
];
- const signalTypePrefix = 'signalType';
- const signalTypeButtons = [
- {
- id: `${signalTypePrefix}0`,
- label: 'Open signals',
- },
- {
- id: `${signalTypePrefix}1`,
- label: 'Closed signals',
- },
- ];
+ const filterGroupOptions = ['open', 'closed'];
+ const [filterGroupState, setFilterGroupState] = useState(filterGroupOptions[0]);
return (
<>
@@ -148,53 +215,29 @@ export const DetectionEngineComponent = React.memo(() => {
- {
- return null;
- }}
- options={signalTypeButtons}
- />
+
+ setFilterGroupState(filterGroupOptions[0])}
+ withNext
+ >
+ {'Open signals'}
+
+
+ setFilterGroupState(filterGroupOptions[1])}
+ >
+ {'Closed signals'}
+
+
-
-
-
- {`${i18n.PANEL_SUBTITLE_SHOWING}: 7,712 signals`}
-
-
-
- {'Selected: 20 signals'}
-
- {'Batch actions context menu here.'}}>
- {'Batch actions'}
-
-
-
- {'Select all signals on all pages'}
-
-
-
-
- {'Clear 7 filters'}
-
- {'Clear aggregation'}
-
-
-
-
-
- {'Customize columns context menu here.'}}>
- {'Customize columns'}
-
-
- {'Aggregate data'}
-
-
-
-
- {/* Open signals datagrid here. Talk to Chandler Prall about possibility of early access. If not possible, use basic table. */}
+ {filterGroupState === filterGroupOptions[0] ? : }
From 91b39b4c52bc77ab69f928f779ec3d7f7112fe06 Mon Sep 17 00:00:00 2001
From: Michael Marcialis
Date: Wed, 16 Oct 2019 11:21:19 -0400
Subject: [PATCH 19/57] remove EuiFilterButton icons
---
.../siem/public/pages/detection_engine/detection_engine.tsx | 4 ----
1 file changed, 4 deletions(-)
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
index ba588409438be..787985ea2459a 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
@@ -218,8 +218,6 @@ export const DetectionEngineComponent = React.memo(() => {
setFilterGroupState(filterGroupOptions[0])}
withNext
>
@@ -228,8 +226,6 @@ export const DetectionEngineComponent = React.memo(() => {
setFilterGroupState(filterGroupOptions[1])}
>
{'Closed signals'}
From 9f32e1da8a3ccdc554359f3bc530f3263c9a85db Mon Sep 17 00:00:00 2001
From: Michael Marcialis
Date: Wed, 16 Oct 2019 11:41:08 -0400
Subject: [PATCH 20/57] fix misaligned popover button
---
.../siem/public/components/utility_bar/styles.tsx | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/x-pack/legacy/plugins/siem/public/components/utility_bar/styles.tsx b/x-pack/legacy/plugins/siem/public/components/utility_bar/styles.tsx
index 4d049a1f7f2ec..0dc1f0edcca43 100644
--- a/x-pack/legacy/plugins/siem/public/components/utility_bar/styles.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/utility_bar/styles.tsx
@@ -86,10 +86,7 @@ export const BarGroup = styled.div.attrs({
}
& > * {
- font-size: ${theme.eui.euiFontSizeXS};
- line-height: ${theme.eui.euiLineHeight};
margin-right: ${theme.eui.euiSize};
- white-space: nowrap;
&:last-child {
margin-right: 0;
@@ -104,7 +101,9 @@ export const BarText = styled.p.attrs({
})`
${({ theme }) => css`
color: ${theme.eui.textColors.subdued};
- display: inline-block;
+ font-size: ${theme.eui.euiFontSizeXS};
+ line-height: ${theme.eui.euiLineHeight};
+ white-space: nowrap;
`}
`;
BarText.displayName = 'BarText';
@@ -121,7 +120,10 @@ export const BarAction = styled(EuiLink).attrs({
})`
${({ iconSide, theme }) => css`
align-items: center;
- display: inline-flex;
+ display: flex;
+ font-size: ${theme.eui.euiFontSizeXS};
+ line-height: ${theme.eui.euiLineHeight};
+ white-space: nowrap;
${iconSide === 'left' &&
css`
From 4027a651fd1f239c7687b472df218d6ebaebbd58 Mon Sep 17 00:00:00 2001
From: Michael Marcialis
Date: Wed, 16 Oct 2019 13:16:02 -0400
Subject: [PATCH 21/57] add split prop for HeaderSection
---
.../components/header_section/index.test.tsx | 34 +++
.../components/header_section/index.tsx | 5 +-
.../pages/detection_engine/rules/index.tsx | 258 +++++++++---------
3 files changed, 165 insertions(+), 132 deletions(-)
diff --git a/x-pack/legacy/plugins/siem/public/components/header_section/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/header_section/index.test.tsx
index 5d2d3effebafb..1ea64bb72fe46 100644
--- a/x-pack/legacy/plugins/siem/public/components/header_section/index.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/header_section/index.test.tsx
@@ -157,4 +157,38 @@ describe('HeaderSection', () => {
expect(siemHeaderSection).not.toHaveStyleRule('border-bottom', euiDarkVars.euiBorderThin);
expect(siemHeaderSection).not.toHaveStyleRule('padding-bottom', euiDarkVars.paddingSizes.l);
});
+
+ test('it splits the title and supplement areas evenly when split is true', () => {
+ const wrapper = mount(
+
+
+ {'Test children'}
+
+
+ );
+
+ expect(
+ wrapper
+ .find('.euiFlexItem--flexGrowZero[data-test-subj="header-section-supplements"]')
+ .first()
+ .exists()
+ ).toBe(false);
+ });
+
+ test('it DOES NOT split the title and supplement areas evenly when split is false', () => {
+ const wrapper = mount(
+
+
+ {'Test children'}
+
+
+ );
+
+ expect(
+ wrapper
+ .find('.euiFlexItem--flexGrowZero[data-test-subj="header-section-supplements"]')
+ .first()
+ .exists()
+ ).toBe(true);
+ });
});
diff --git a/x-pack/legacy/plugins/siem/public/components/header_section/index.tsx b/x-pack/legacy/plugins/siem/public/components/header_section/index.tsx
index 38f216ccf65b0..888c77987a94f 100644
--- a/x-pack/legacy/plugins/siem/public/components/header_section/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/header_section/index.tsx
@@ -34,6 +34,7 @@ Header.displayName = 'Header';
export interface HeaderSectionProps extends HeaderProps {
children?: React.ReactNode;
id?: string;
+ split?: boolean;
subtitle?: SubtitleProps['text'];
showInspect?: boolean;
title: string | React.ReactNode;
@@ -41,7 +42,7 @@ export interface HeaderSectionProps extends HeaderProps {
}
export const HeaderSection = React.memo(
- ({ border, children, id, showInspect = false, subtitle, title, tooltip }) => (
+ ({ border, children, id, showInspect = false, split, subtitle, title, tooltip }) => (
@@ -71,7 +72,7 @@ export const HeaderSection = React.memo(
{children && (
-
+
{children}
)}
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
index 6fd09bdecdf4b..99f475fe87876 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
@@ -127,136 +127,134 @@ const AllRules = React.memo(() => {
<>
-
-
-
-
-
-
-
-
- {'Showing: 39 rules'}
-
-
-
- {'Selected: 2 rules'}
-
- {'Batch actions context menu here.'}}>
- {'Batch actions'}
-
-
-
-
- {'Clear 7 filters'}
-
-
-
-
- {/* Example of potentially new TableCards component. This new table type may no longer be required for implementation, given the requirements changes that have been made over time. At present, the only afforded benefits of using it are 1) differentiation from regular tables and 2) the presence of a colored status bar on the left of each row. Neither are dealbreakers in my mind. If creating a new table component is out of the question for MVP, go with a standard EUI basic table. */}
-
-
-
-
-
- {
- return null;
- }}
- />
-
- {'Rule'}
- {'Method'}
- {'Severity'}
- {'Last completed run'}
- {'Last response'}
- {'Tags'}
-
- {'Activate'}
-
-
-
-
-
-
-
-
- {
- return null;
- }}
- />
-
-
-
- {'Automated exfiltration'}
- {' '}
- {'Experimental'}
-
- {'Kibana Query Language'}
-
- {'Medium'}
-
-
-
-
-
- {'Success'}
-
-
- {'attack.t1234'}
-
-
-
-
-
-
-
-
-
-
-
- {
- return null;
- }}
- />
-
-
-
- {'Automated exfiltration'}
- {' '}
- {'Experimental'}
-
- {'Kibana Query Language'}
-
- {'Medium'}
-
-
-
-
-
- {'Fail'}
-
-
- {'attack.t1234'}
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+ {'Showing: 39 rules'}
+
+
+
+ {'Selected: 2 rules'}
+
+ {'Batch actions context menu here.'}}>
+ {'Batch actions'}
+
+
+
+
+ {'Clear 7 filters'}
+
+
+
+
+ {/* Example of potentially new TableCards component. This new table type may no longer be required for implementation, given the requirements changes that have been made over time. At present, the only afforded benefits of using it are 1) differentiation from regular tables and 2) the presence of a colored status bar on the left of each row. Neither are dealbreakers in my mind. If creating a new table component is out of the question for MVP, go with a standard EUI basic table. */}
+
+
+
+
+
+ {
+ return null;
+ }}
+ />
+
+ {'Rule'}
+ {'Method'}
+ {'Severity'}
+ {'Last completed run'}
+ {'Last response'}
+ {'Tags'}
+
+ {'Activate'}
+
+
+
+
+
+
+
+
+ {
+ return null;
+ }}
+ />
+
+
+
+ {'Automated exfiltration'}
+ {' '}
+ {'Experimental'}
+
+ {'Kibana Query Language'}
+
+ {'Medium'}
+
+
+
+
+
+ {'Success'}
+
+
+ {'attack.t1234'}
+
+
+
+
+
+
+
+
+
+
+
+ {
+ return null;
+ }}
+ />
+
+
+
+ {'Automated exfiltration'}
+ {' '}
+ {'Experimental'}
+
+ {'Kibana Query Language'}
+
+ {'Medium'}
+
+
+
+
+
+ {'Fail'}
+
+
+ {'attack.t1234'}
+
+
+
+
+
+
+
+
+
+
>
);
});
From 92f063f6ec78fa3f48b7d702c7c375a4be8755ef Mon Sep 17 00:00:00 2001
From: Michael Marcialis
Date: Wed, 16 Oct 2019 18:03:22 -0400
Subject: [PATCH 22/57] fleshing out activity monitor table
---
.../pages/detection_engine/rules/index.tsx | 149 ++++++++++++++++--
1 file changed, 132 insertions(+), 17 deletions(-)
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
index 99f475fe87876..d966f92232372 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
@@ -14,15 +14,18 @@ import {
EuiFlexGroup,
EuiFlexItem,
EuiHealth,
+ EuiIconTip,
EuiLink,
EuiPanel,
EuiSpacer,
EuiSwitch,
EuiTabbedContent,
+ EuiText,
} from '@elastic/eui';
-import React from 'react';
+import React, { useState } from 'react';
import styled, { css } from 'styled-components';
+import { getEmptyTagValue } from '../../../components/empty_value';
import { HeaderPage } from '../../../components/header_page';
import { HeaderSection } from '../../../components/header_section';
import {
@@ -214,7 +217,7 @@ const AllRules = React.memo(() => {
-
+
@@ -250,7 +253,7 @@ const AllRules = React.memo(() => {
-
+
@@ -261,52 +264,141 @@ const AllRules = React.memo(() => {
AllRules.displayName = 'AllRules';
const ActivityMonitor = React.memo(() => {
- const columns = [
+ const [selectedState, setSelectedState] = useState([]);
+ const [sortFieldState, setSortFieldState] = useState('ran');
+ const [sortDirectionState, setSortDirectionState] = useState('desc');
+
+ // const actions = [
+ // {
+ // render: (item = {}) => {
+ // if (item.status === 'Running') {
+ // return {'Stop'};
+ // } else if (item.status === 'Stopped') {
+ // return {'Resume'};
+ // } else {
+ // return {'Nada'}
;
+ // }
+ // },
+ // },
+ // ];
+
+ const actions = [
{
- field: 'checkbox',
- name: 'Checkbox',
- truncateText: true,
+ available: (item = {}) => {
+ return item.status === 'Running' ? true : false;
+ },
+ name: 'Stop',
+ isPrimary: true,
+ description: 'Stop rule from running',
+ icon: 'stop',
+ type: 'button',
+ onClick: () => {},
+ },
+ {
+ available: (item = {}) => {
+ return item.status === 'Stopped' ? true : false;
+ },
+ name: 'Resume',
+ isPrimary: true,
+ description: 'Resume running rule',
+ icon: 'play',
+ type: 'button',
+ onClick: () => {},
},
+ ];
+
+ const columns = [
{
field: 'rule',
name: 'Rule',
+ render: (value: string) => (
+ {value}
+ ),
+ sortable: true,
truncateText: true,
},
{
field: 'ran',
name: 'Ran',
+ sortable: true,
truncateText: true,
},
{
field: 'lookedBackTo',
name: 'Looked back to',
+ sortable: true,
truncateText: true,
},
{
field: 'status',
name: 'Status',
+ sortable: true,
truncateText: true,
},
{
field: 'response',
name: 'Response',
+ render: (value: string | undefined) => {
+ return value === undefined ? (
+ getEmptyTagValue()
+ ) : (
+ <>
+ {value === 'Fail' ? (
+
+
+ {value}
+
+
+
+
+
+
+ ) : (
+ {value}
+ )}
+ >
+ );
+ },
+ sortable: true,
truncateText: true,
},
{
- field: 'actions',
- name: '',
+ actions,
},
];
const items = [
{
- checkbox: 'test',
- rule: 'test',
- ran: 'test',
- lookedBackTo: 'test',
- status: 'test',
- response: 'test',
- actions: 'test',
+ id: 1,
+ rule: 'Automated exfiltration',
+ ran: '12/28/2019, 12:00 PM',
+ lookedBackTo: '12/28/2019, 12:00 PM',
+ status: 'Running',
+ actions: 'Stop',
+ },
+ {
+ id: 2,
+ rule: 'Automated exfiltration',
+ ran: '12/28/2019, 12:00 PM',
+ lookedBackTo: '12/28/2019, 12:00 PM',
+ status: 'Stopped',
+ actions: 'Resume',
+ },
+ {
+ id: 3,
+ rule: 'Automated exfiltration',
+ ran: '12/28/2019, 12:00 PM',
+ lookedBackTo: '12/28/2019, 12:00 PM',
+ status: 'Completed',
+ response: 'Fail',
+ },
+ {
+ id: 4,
+ rule: 'Automated exfiltration',
+ ran: '12/28/2019, 12:00 PM',
+ lookedBackTo: '12/28/2019, 12:00 PM',
+ status: 'Completed',
+ response: 'Success',
},
];
@@ -335,7 +427,30 @@ const ActivityMonitor = React.memo(() => {
-
+ {
+ setSortFieldState(sort.field);
+ setSortDirectionState(sort.direction);
+ }}
+ selection={{
+ selectable: (item = {}) => item.status !== 'Completed',
+ selectableMessage: (item = {}) =>
+ item.status !== 'Completed' ? 'Completed runs cannot be acted upon' : undefined,
+ onSelectionChange: (item = {}) => {
+ setSelectedState(item);
+ },
+ }}
+ sorting={{
+ sort: {
+ field: sortFieldState,
+ direction: sortDirectionState,
+ },
+ }}
+ />
>
);
From f8c4acb7ec960febc2c662a6c53ab681fc86aeee Mon Sep 17 00:00:00 2001
From: Michael Marcialis
Date: Mon, 21 Oct 2019 15:57:28 -0400
Subject: [PATCH 23/57] update global header to include logo
---
.../components/header_global/index.test.tsx | 54 +++++++++++++
.../public/components/header_global/index.tsx | 76 +++++++++++++++++++
.../components/header_global/translations.ts | 15 ++++
.../components/header_page/index.test.tsx | 2 +-
.../components/header_section/index.test.tsx | 2 +-
.../public/components/navigation/index.tsx | 28 +++----
.../public/pages/home/home_navigations.tsx | 5 +-
.../plugins/siem/public/pages/home/index.tsx | 70 +++--------------
8 files changed, 174 insertions(+), 78 deletions(-)
create mode 100644 x-pack/legacy/plugins/siem/public/components/header_global/index.test.tsx
create mode 100644 x-pack/legacy/plugins/siem/public/components/header_global/index.tsx
create mode 100644 x-pack/legacy/plugins/siem/public/components/header_global/translations.ts
diff --git a/x-pack/legacy/plugins/siem/public/components/header_global/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/header_global/index.test.tsx
new file mode 100644
index 0000000000000..ac3d001b87de7
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/components/header_global/index.test.tsx
@@ -0,0 +1,54 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import euiDarkVars from '@elastic/eui/dist/eui_theme_dark.json';
+import { mount, shallow } from 'enzyme';
+import toJson from 'enzyme-to-json';
+import 'jest-styled-components';
+import React from 'react';
+
+import { TestProviders } from '../../mock';
+import '../../mock/match_media';
+import '../../mock/ui_settings';
+import { HeaderGlobal } from './index';
+
+jest.mock('../../lib/settings/use_kibana_ui_setting');
+
+describe('HeaderGlobal', () => {
+ test('it renders', () => {
+ const wrapper = shallow(
+
+
+
+ );
+
+ expect(toJson(wrapper)).toMatchSnapshot();
+ });
+
+ test('it applies offset styles when offsetRight is provided', () => {
+ const wrapper = mount(
+
+
+
+ );
+ const siemHeaderGlobal = wrapper.find('.siemHeaderGlobal').first();
+
+ expect(siemHeaderGlobal).toHaveStyleRule('margin-right', '-100px');
+ expect(siemHeaderGlobal).toHaveStyleRule('padding-right', '100px');
+ });
+
+ test('it DOES NOT apply offset styles when offsetRight is not provided', () => {
+ const wrapper = mount(
+
+
+
+ );
+ const siemHeaderGlobal = wrapper.find('.siemHeaderGlobal').first();
+
+ expect(siemHeaderGlobal).toHaveStyleRule('margin-right', euiDarkVars.euiSizeL);
+ expect(siemHeaderGlobal).toHaveStyleRule('padding-right', euiDarkVars.euiSizeL);
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/components/header_global/index.tsx b/x-pack/legacy/plugins/siem/public/components/header_global/index.tsx
new file mode 100644
index 0000000000000..93935b53d3698
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/components/header_global/index.tsx
@@ -0,0 +1,76 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { EuiFlexGroup, EuiFlexItem, EuiIcon, EuiLink, EuiButton } from '@elastic/eui';
+import React from 'react';
+import styled, { css } from 'styled-components';
+
+import { navTabs } from '../../pages/home/home_navigations';
+import { getOverviewUrl } from '../link_to';
+import { MlPopover } from '../ml_popover/ml_popover';
+import { SiemNavigation } from '../navigation';
+import * as i18n from './translations';
+
+interface HeaderProps {
+ offsetRight?: string;
+}
+
+const Header = styled.header.attrs({
+ className: 'siemHeaderGlobal',
+})`
+ ${({ offsetRight, theme }) => css`
+ background: ${theme.eui.euiColorEmptyShade};
+ border-bottom: ${theme.eui.euiBorderThin};
+ margin: 0 -${offsetRight ? offsetRight : theme.eui.euiSizeL} 0 -${theme.eui.euiSizeL};
+ padding: ${theme.eui.euiSize} ${offsetRight ? offsetRight : theme.eui.euiSizeL}
+ ${theme.eui.euiSize} ${theme.eui.euiSizeL};
+ `}
+`;
+Header.displayName = 'Header';
+
+const FlexItem = styled(EuiFlexItem)`
+ min-width: 0;
+`;
+FlexItem.displayName = 'FlexItem';
+
+export const HeaderGlobal = React.memo(({ offsetRight }) => (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {i18n.BUTTON_ADD_DATA}
+
+
+
+
+
+
+));
+HeaderGlobal.displayName = 'HeaderGlobal';
diff --git a/x-pack/legacy/plugins/siem/public/components/header_global/translations.ts b/x-pack/legacy/plugins/siem/public/components/header_global/translations.ts
new file mode 100644
index 0000000000000..c713f63016594
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/components/header_global/translations.ts
@@ -0,0 +1,15 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { i18n } from '@kbn/i18n';
+
+export const SIEM = i18n.translate('xpack.siem.headerGlobal.siem', {
+ defaultMessage: 'SIEM',
+});
+
+export const BUTTON_ADD_DATA = i18n.translate('xpack.siem.headerGlobal.buttonAddData', {
+ defaultMessage: 'Add data',
+});
diff --git a/x-pack/legacy/plugins/siem/public/components/header_page/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/header_page/index.test.tsx
index 2937ddc18dd82..0cd6151e59f6c 100644
--- a/x-pack/legacy/plugins/siem/public/components/header_page/index.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/header_page/index.test.tsx
@@ -10,8 +10,8 @@ import toJson from 'enzyme-to-json';
import 'jest-styled-components';
import React from 'react';
-import '../../mock/ui_settings';
import { TestProviders } from '../../mock';
+import '../../mock/ui_settings';
import { HeaderPage } from './index';
jest.mock('../../lib/settings/use_kibana_ui_setting');
diff --git a/x-pack/legacy/plugins/siem/public/components/header_section/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/header_section/index.test.tsx
index 1ea64bb72fe46..fffeece818d13 100644
--- a/x-pack/legacy/plugins/siem/public/components/header_section/index.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/header_section/index.test.tsx
@@ -10,8 +10,8 @@ import toJson from 'enzyme-to-json';
import 'jest-styled-components';
import React from 'react';
-import '../../mock/ui_settings';
import { TestProviders } from '../../mock';
+import '../../mock/ui_settings';
import { HeaderSection } from './index';
jest.mock('../../lib/settings/use_kibana_ui_setting');
diff --git a/x-pack/legacy/plugins/siem/public/components/navigation/index.tsx b/x-pack/legacy/plugins/siem/public/components/navigation/index.tsx
index ae8d09eeff112..a45da9b6a9112 100644
--- a/x-pack/legacy/plugins/siem/public/components/navigation/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/navigation/index.tsx
@@ -53,19 +53,21 @@ export const SiemNavigationComponent = React.memo
+
);
},
(prevProps, nextProps) => {
diff --git a/x-pack/legacy/plugins/siem/public/pages/home/home_navigations.tsx b/x-pack/legacy/plugins/siem/public/pages/home/home_navigations.tsx
index 0487330e7418e..220f8a958aa43 100644
--- a/x-pack/legacy/plugins/siem/public/pages/home/home_navigations.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/home/home_navigations.tsx
@@ -3,8 +3,7 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
-import * as i18n from './translations';
-import { SiemPageName, SiemNavTab } from './types';
+
import {
getDetectionEngineUrl,
getOverviewUrl,
@@ -12,6 +11,8 @@ import {
getTimelinesUrl,
getHostsUrl,
} from '../../components/link_to';
+import * as i18n from './translations';
+import { SiemPageName, SiemNavTab } from './types';
export const navTabs: SiemNavTab = {
[SiemPageName.overview]: {
diff --git a/x-pack/legacy/plugins/siem/public/pages/home/index.tsx b/x-pack/legacy/plugins/siem/public/pages/home/index.tsx
index 6fd714849ed72..d8e3fe7cd7008 100644
--- a/x-pack/legacy/plugins/siem/public/pages/home/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/home/index.tsx
@@ -4,64 +4,48 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { EuiButton, EuiFlexGroup, EuiFlexItem, EuiPage, EuiPageBody } from '@elastic/eui';
-import { FormattedMessage } from '@kbn/i18n/react';
+import { EuiPage, EuiPageBody } from '@elastic/eui';
import * as React from 'react';
import { Redirect, Route, Switch } from 'react-router-dom';
import { pure } from 'recompose';
import styled from 'styled-components';
-import { i18n } from '@kbn/i18n';
import { AutoSizer } from '../../components/auto_sizer';
import { DragDropContextWrapper } from '../../components/drag_and_drop/drag_drop_context_wrapper';
import { Flyout, flyoutHeaderHeight } from '../../components/flyout';
+import { HeaderGlobal } from '../../components/header_global';
import { HelpMenu } from '../../components/help_menu';
import { LinkToPage } from '../../components/link_to';
-import { SiemNavigation } from '../../components/navigation';
+import { MlHostConditionalContainer } from '../../components/ml/conditional_links/ml_host_conditional_container';
+import { MlNetworkConditionalContainer } from '../../components/ml/conditional_links/ml_network_conditional_container';
import { StatefulTimeline } from '../../components/timeline';
import { AutoSaveWarningMsg } from '../../components/timeline/auto_save_warning';
+import { UseUrlState } from '../../components/url_state';
+import { WithSource } from '../../containers/source';
+import { SpyRoute } from '../../utils/route/spy_routes';
import { NotFoundPage } from '../404';
import { DetectionEngineContainer } from '../detection_engine';
import { HostsContainer } from '../hosts';
import { NetworkContainer } from '../network';
import { Overview } from '../overview';
import { Timelines } from '../timelines';
-import { WithSource } from '../../containers/source';
-import { MlPopover } from '../../components/ml_popover/ml_popover';
-import { MlHostConditionalContainer } from '../../components/ml/conditional_links/ml_host_conditional_container';
-import { MlNetworkConditionalContainer } from '../../components/ml/conditional_links/ml_network_conditional_container';
import { navTabs } from './home_navigations';
import { SiemPageName } from './types';
-import { UseUrlState } from '../../components/url_state';
-import { SpyRoute } from '../../utils/route/spy_routes';
const WrappedByAutoSizer = styled.div`
height: 100%;
`;
-
WrappedByAutoSizer.displayName = 'WrappedByAutoSizer';
const gutterTimeline = '70px'; // Temporary until timeline is moved - MichaelMarcialis
const Page = styled(EuiPage)`
${({ theme }) => `
- padding: 0 ${gutterTimeline} ${theme.eui.euiSizeL} ${theme.eui.euiSizeL};
+ padding: 0 ${gutterTimeline} ${theme.eui.paddingSizes.l} ${theme.eui.paddingSizes.l};
`}
`;
-
Page.displayName = 'Page';
-const NavGlobal = styled.nav`
- ${({ theme }) => `
- background: ${theme.eui.euiColorEmptyShade};
- border-bottom: ${theme.eui.euiBorderThin};
- margin: 0 -${gutterTimeline} 0 -${theme.eui.euiSizeL};
- padding: ${theme.eui.euiSize} ${gutterTimeline} ${theme.eui.euiSize} ${theme.eui.euiSizeL};
- `}
-`;
-
-NavGlobal.displayName = 'NavGlobal';
-
const usersViewing = ['elastic']; // TODO: get the users viewing this timeline from Elasticsearch (persistance)
/** the global Kibana navigation at the top of every page */
@@ -106,43 +90,7 @@ export const HomePage = pure(() => (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
From 9cdcceb9b020e4d04297bb6e134f73c0c53afe83 Mon Sep 17 00:00:00 2001
From: Michael Marcialis
Date: Mon, 21 Oct 2019 17:29:39 -0400
Subject: [PATCH 24/57] fix tests
---
.../__snapshots__/index.test.tsx.snap | 7 ++++++
.../components/header_global/index.test.tsx | 23 +++++++++++++++----
.../public/components/header_global/index.tsx | 4 ++--
3 files changed, 28 insertions(+), 6 deletions(-)
create mode 100644 x-pack/legacy/plugins/siem/public/components/header_global/__snapshots__/index.test.tsx.snap
diff --git a/x-pack/legacy/plugins/siem/public/components/header_global/__snapshots__/index.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/header_global/__snapshots__/index.test.tsx.snap
new file mode 100644
index 0000000000000..665a5c75f3684
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/components/header_global/__snapshots__/index.test.tsx.snap
@@ -0,0 +1,7 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`HeaderGlobal it renders 1`] = `
+
+
+
+`;
diff --git a/x-pack/legacy/plugins/siem/public/components/header_global/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/header_global/index.test.tsx
index ac3d001b87de7..01abc73b18181 100644
--- a/x-pack/legacy/plugins/siem/public/components/header_global/index.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/header_global/index.test.tsx
@@ -17,6 +17,12 @@ import { HeaderGlobal } from './index';
jest.mock('../../lib/settings/use_kibana_ui_setting');
+// Test will fail because we will to need to mock some core services to make the test work
+// For now let's forget about SiemSearchBar
+jest.mock('../search_bar', () => ({
+ SiemSearchBar: () => null,
+}));
+
describe('HeaderGlobal', () => {
test('it renders', () => {
const wrapper = shallow(
@@ -36,8 +42,11 @@ describe('HeaderGlobal', () => {
);
const siemHeaderGlobal = wrapper.find('.siemHeaderGlobal').first();
- expect(siemHeaderGlobal).toHaveStyleRule('margin-right', '-100px');
- expect(siemHeaderGlobal).toHaveStyleRule('padding-right', '100px');
+ expect(siemHeaderGlobal).toHaveStyleRule('margin', `0 -100px 0 -${euiDarkVars.euiSizeL}`);
+ expect(siemHeaderGlobal).toHaveStyleRule(
+ 'padding',
+ `${euiDarkVars.paddingSizes.m} 100px ${euiDarkVars.paddingSizes.m} ${euiDarkVars.paddingSizes.l}`
+ );
});
test('it DOES NOT apply offset styles when offsetRight is not provided', () => {
@@ -48,7 +57,13 @@ describe('HeaderGlobal', () => {
);
const siemHeaderGlobal = wrapper.find('.siemHeaderGlobal').first();
- expect(siemHeaderGlobal).toHaveStyleRule('margin-right', euiDarkVars.euiSizeL);
- expect(siemHeaderGlobal).toHaveStyleRule('padding-right', euiDarkVars.euiSizeL);
+ expect(siemHeaderGlobal).toHaveStyleRule(
+ 'margin',
+ `0 -${euiDarkVars.euiSizeL} 0 -${euiDarkVars.euiSizeL}`
+ );
+ expect(siemHeaderGlobal).toHaveStyleRule(
+ 'padding',
+ `${euiDarkVars.paddingSizes.m} ${euiDarkVars.paddingSizes.l} ${euiDarkVars.paddingSizes.m} ${euiDarkVars.paddingSizes.l}`
+ );
});
});
diff --git a/x-pack/legacy/plugins/siem/public/components/header_global/index.tsx b/x-pack/legacy/plugins/siem/public/components/header_global/index.tsx
index 93935b53d3698..113b2494c44d1 100644
--- a/x-pack/legacy/plugins/siem/public/components/header_global/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/header_global/index.tsx
@@ -25,8 +25,8 @@ const Header = styled.header.attrs({
background: ${theme.eui.euiColorEmptyShade};
border-bottom: ${theme.eui.euiBorderThin};
margin: 0 -${offsetRight ? offsetRight : theme.eui.euiSizeL} 0 -${theme.eui.euiSizeL};
- padding: ${theme.eui.euiSize} ${offsetRight ? offsetRight : theme.eui.euiSizeL}
- ${theme.eui.euiSize} ${theme.eui.euiSizeL};
+ padding: ${theme.eui.paddingSizes.m} ${offsetRight ? offsetRight : theme.eui.paddingSizes.l}
+ ${theme.eui.paddingSizes.m} ${theme.eui.paddingSizes.l};
`}
`;
Header.displayName = 'Header';
From 247710dbd2b43e65dcb2df2b5f104a8abe3960bc Mon Sep 17 00:00:00 2001
From: Michael Marcialis
Date: Tue, 22 Oct 2019 11:35:28 -0400
Subject: [PATCH 25/57] correct table types; thanks Garrett!
---
.../pages/detection_engine/rules/index.tsx | 51 ++++++++++---------
1 file changed, 28 insertions(+), 23 deletions(-)
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
index d966f92232372..3624e9645b49d 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
@@ -264,9 +264,22 @@ const AllRules = React.memo(() => {
AllRules.displayName = 'AllRules';
const ActivityMonitor = React.memo(() => {
- const [selectedState, setSelectedState] = useState([]);
- const [sortFieldState, setSortFieldState] = useState('ran');
- const [sortDirectionState, setSortDirectionState] = useState('desc');
+ interface ColumnTypes {
+ id: number;
+ rule: string;
+ ran: string;
+ lookedBackTo: string;
+ status: string;
+ actions: string;
+ }
+
+ interface SortTypes {
+ field: string;
+ direction: string;
+ }
+
+ const [selectedState, setSelectedState] = useState([]);
+ const [sortState, setSortState] = useState({ field: 'ran', direction: 'desc' });
// const actions = [
// {
@@ -284,9 +297,7 @@ const ActivityMonitor = React.memo(() => {
const actions = [
{
- available: (item = {}) => {
- return item.status === 'Running' ? true : false;
- },
+ available: (item: ColumnTypes) => (item.status === 'Running' ? true : false),
name: 'Stop',
isPrimary: true,
description: 'Stop rule from running',
@@ -295,9 +306,7 @@ const ActivityMonitor = React.memo(() => {
onClick: () => {},
},
{
- available: (item = {}) => {
- return item.status === 'Stopped' ? true : false;
- },
+ available: (item: ColumnTypes) => (item.status === 'Stopped' ? true : false),
name: 'Resume',
isPrimary: true,
description: 'Resume running rule',
@@ -367,7 +376,7 @@ const ActivityMonitor = React.memo(() => {
},
];
- const items = [
+ const sampleTableData = [
{
id: 1,
rule: 'Automated exfiltration',
@@ -431,24 +440,20 @@ const ActivityMonitor = React.memo(() => {
columns={columns}
isSelectable={true}
itemId="id"
- items={items}
- onChange={({ sort = {} }) => {
- setSortFieldState(sort.field);
- setSortDirectionState(sort.direction);
+ items={sampleTableData}
+ onChange={({ sort }: { sort: SortTypes }) => {
+ setSortState(sort);
}}
selection={{
- selectable: (item = {}) => item.status !== 'Completed',
- selectableMessage: (item = {}) =>
- item.status !== 'Completed' ? 'Completed runs cannot be acted upon' : undefined,
- onSelectionChange: (item = {}) => {
- setSelectedState(item);
+ selectable: (item: ColumnTypes) => item.status !== 'Completed',
+ selectableMessage: (selectable: boolean) =>
+ selectable ? undefined : 'Completed runs cannot be acted upon',
+ onSelectionChange: (selectedItems: ColumnTypes[]) => {
+ setSelectedState(selectedItems);
},
}}
sorting={{
- sort: {
- field: sortFieldState,
- direction: sortDirectionState,
- },
+ sort: sortState,
}}
/>
From 0d14389653e154361f8b903ad2d34b51555c1fea Mon Sep 17 00:00:00 2001
From: Michael Marcialis
Date: Wed, 23 Oct 2019 14:29:44 -0400
Subject: [PATCH 26/57] LinkIcon comp poc
---
.../public/components/header_page/index.tsx | 31 ++-
.../__snapshots__/index.test.tsx.snap | 10 -
.../public/components/link_back/index.tsx | 42 ---
.../{link_back => link_icon}/index.test.tsx | 6 +-
.../public/components/link_icon/index.tsx | 75 ++++++
.../public/components/utility_bar/styles.tsx | 32 +--
.../utility_bar/utility_bar_action.tsx | 49 ++--
.../detection_engine/detection_engine.tsx | 31 ++-
.../pages/detection_engine/rules/index.tsx | 250 +++++++++++++++---
9 files changed, 366 insertions(+), 160 deletions(-)
delete mode 100644 x-pack/legacy/plugins/siem/public/components/link_back/__snapshots__/index.test.tsx.snap
delete mode 100644 x-pack/legacy/plugins/siem/public/components/link_back/index.tsx
rename x-pack/legacy/plugins/siem/public/components/{link_back => link_icon}/index.test.tsx (84%)
create mode 100644 x-pack/legacy/plugins/siem/public/components/link_icon/index.tsx
diff --git a/x-pack/legacy/plugins/siem/public/components/header_page/index.tsx b/x-pack/legacy/plugins/siem/public/components/header_page/index.tsx
index b62273d8f0466..d8dc08e7be0f7 100644
--- a/x-pack/legacy/plugins/siem/public/components/header_page/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/header_page/index.tsx
@@ -9,7 +9,7 @@ import React from 'react';
import styled, { css } from 'styled-components';
import { DefaultDraggable } from '../draggables';
-import { LinkBack, LinkBackProps } from '../link_back';
+import { LinkIcon, LinkIconProps } from '../link_icon';
import { Subtitle, SubtitleProps } from '../subtitle';
interface HeaderProps {
@@ -36,14 +36,25 @@ const FlexItem = styled(EuiFlexItem)`
`;
FlexItem.displayName = 'FlexItem';
+const LinkBack = styled.div.attrs({
+ className: 'siemHeaderPage__linkBack',
+})`
+ ${({ theme }) => css`
+ font-size: ${theme.eui.euiFontSizeXS};
+ line-height: ${theme.eui.euiLineHeight};
+ margin-bottom: ${theme.eui.euiSizeS};
+ `}
+`;
+LinkBack.displayName = 'LinkBack';
+
const Badge = styled(EuiBadge)`
letter-spacing: 0;
`;
Badge.displayName = 'Badge';
interface BackOptions {
- href: LinkBackProps['href'];
- text: LinkBackProps['text'];
+ href: LinkIconProps['href'];
+ text: LinkIconProps['children'];
}
interface BadgeOptions {
@@ -83,11 +94,15 @@ export const HeaderPage = React.memo(
{backOptions && (
-
+
+
+ {backOptions.text}
+
+
)}
diff --git a/x-pack/legacy/plugins/siem/public/components/link_back/__snapshots__/index.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/link_back/__snapshots__/index.test.tsx.snap
deleted file mode 100644
index f1d437379dd8c..0000000000000
--- a/x-pack/legacy/plugins/siem/public/components/link_back/__snapshots__/index.test.tsx.snap
+++ /dev/null
@@ -1,10 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`LinkBack it renders 1`] = `
-
-
-
-`;
diff --git a/x-pack/legacy/plugins/siem/public/components/link_back/index.tsx b/x-pack/legacy/plugins/siem/public/components/link_back/index.tsx
deleted file mode 100644
index 1736fcb49bde3..0000000000000
--- a/x-pack/legacy/plugins/siem/public/components/link_back/index.tsx
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import { EuiIcon, EuiLink } from '@elastic/eui';
-import React from 'react';
-import styled, { css } from 'styled-components';
-
-interface LinkProps {
- href: string;
-}
-
-const Link = styled(EuiLink).attrs({
- className: 'siemLinkBack',
-})`
- ${({ theme }) => css`
- align-items: center;
- display: inline-flex;
- font-size: ${theme.eui.euiFontSizeXS};
- line-height: ${theme.eui.euiLineHeight};
- margin-bottom: ${theme.eui.euiSizeS};
-
- .euiIcon {
- margin-right: ${theme.eui.euiSizeXS};
- }
- `}
-`;
-Link.displayName = 'Link';
-
-export interface LinkBackProps extends LinkProps {
- text: string;
-}
-
-export const LinkBack = React.memo(({ href, text }) => (
-
-
- {text}
-
-));
-LinkBack.displayName = 'LinkBack';
diff --git a/x-pack/legacy/plugins/siem/public/components/link_back/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/link_icon/index.test.tsx
similarity index 84%
rename from x-pack/legacy/plugins/siem/public/components/link_back/index.test.tsx
rename to x-pack/legacy/plugins/siem/public/components/link_icon/index.test.tsx
index f6a5c672b63de..aceffb3ea89e2 100644
--- a/x-pack/legacy/plugins/siem/public/components/link_back/index.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/link_icon/index.test.tsx
@@ -10,15 +10,15 @@ import React from 'react';
import '../../mock/ui_settings';
import { TestProviders } from '../../mock';
-import { LinkBack } from './index';
+import { LinkIcon } from './index';
jest.mock('../../lib/settings/use_kibana_ui_setting');
-describe('LinkBack', () => {
+describe('LinkIcon', () => {
test('it renders', () => {
const wrapper = shallow(
-
+ {'Test link'}
);
diff --git a/x-pack/legacy/plugins/siem/public/components/link_icon/index.tsx b/x-pack/legacy/plugins/siem/public/components/link_icon/index.tsx
new file mode 100644
index 0000000000000..5f85a3f2daf2e
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/components/link_icon/index.tsx
@@ -0,0 +1,75 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { EuiIcon, EuiLink, IconSize, IconType } from '@elastic/eui';
+import { LinkAnchorProps } from '@elastic/eui/src/components/link/link';
+import React from 'react';
+import styled, { css } from 'styled-components';
+
+interface IconOptions {
+ side?: 'left' | 'right';
+ size?: IconSize;
+ type: IconType;
+}
+
+interface LinkProps {
+ className?: string;
+ color?: LinkAnchorProps['color'];
+ href?: string;
+ // iconSide?: 'left' | 'right';
+ iconOptions: IconOptions;
+ onClick?: Function;
+}
+
+const Link = styled(EuiLink).attrs({
+ className: 'siemLinkIcon',
+})`
+ ${({ iconOptions, theme }) => css`
+ align-items: center;
+ display: inline-flex;
+ vertical-align: top;
+ white-space: nowrap;
+
+ ${iconOptions.side === 'left' &&
+ css`
+ .euiIcon {
+ margin-right: ${theme.eui.euiSizeXS};
+ }
+ `}
+
+ ${iconOptions.side === 'right' &&
+ css`
+ flex-direction: row-reverse;
+
+ .euiIcon {
+ margin-left: ${theme.eui.euiSizeXS};
+ }
+ `}
+ `}
+`;
+Link.displayName = 'Link';
+
+export interface LinkIconProps extends LinkProps {
+ children: string;
+ // iconSize?: IconSize;
+ // iconType: IconType;
+}
+
+export const LinkIcon = React.memo(
+ ({ children, className, color, href, iconOptions = { side: 'left', size: 's' }, onClick }) => (
+
+
+ {children}
+
+ )
+);
+LinkIcon.displayName = 'LinkIcon';
diff --git a/x-pack/legacy/plugins/siem/public/components/utility_bar/styles.tsx b/x-pack/legacy/plugins/siem/public/components/utility_bar/styles.tsx
index 0dc1f0edcca43..a279eb5cf4a05 100644
--- a/x-pack/legacy/plugins/siem/public/components/utility_bar/styles.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/utility_bar/styles.tsx
@@ -108,38 +108,12 @@ export const BarText = styled.p.attrs({
`;
BarText.displayName = 'BarText';
-export interface BarActionProps {
- children: React.ReactNode;
- href?: string;
- iconSide?: 'left' | 'right';
- onClick?: Function;
-}
-
-export const BarAction = styled(EuiLink).attrs({
+export const BarAction = styled.div.attrs({
className: 'siemUtilityBar__action',
-})`
- ${({ iconSide, theme }) => css`
- align-items: center;
- display: flex;
+})`
+ ${({ theme }) => css`
font-size: ${theme.eui.euiFontSizeXS};
line-height: ${theme.eui.euiLineHeight};
- white-space: nowrap;
-
- ${iconSide === 'left' &&
- css`
- .euiIcon {
- margin-right: ${theme.eui.euiSizeXS};
- }
- `}
-
- ${iconSide === 'right' &&
- css`
- flex-direction: row-reverse;
-
- .euiIcon {
- margin-left: ${theme.eui.euiSizeXS};
- }
- `}
`}
`;
BarAction.displayName = 'BarAction';
diff --git a/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_action.tsx b/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_action.tsx
index bb5dca77d76b8..a12bdf4b8de08 100644
--- a/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_action.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_action.tsx
@@ -4,26 +4,26 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { EuiIcon, EuiPopover, IconType } from '@elastic/eui';
+import { EuiPopover } from '@elastic/eui';
import React, { useState } from 'react';
-import { BarAction, BarActionProps } from './styles';
+import { LinkIcon, LinkIconProps } from '../link_icon';
+import { BarAction } from './styles';
interface PopoverProps {
- children: BarActionProps['children'];
+ children: LinkIconProps['children'];
popoverContent?: React.ReactNode;
}
-const Popover = React.memo(({ children, popoverContent }) => {
+const Popover = React.memo(({ children, iconOptions, popoverContent }) => {
const [popoverState, setPopoverState] = useState(false);
return (
setPopoverState(!popoverState)}>
-
+ setPopoverState(!popoverState)}>
{children}
-
+
}
isOpen={popoverState}
closePopover={() => setPopoverState(false)}
@@ -34,23 +34,30 @@ const Popover = React.memo(({ children, popoverContent })
});
Popover.displayName = 'Popover';
-export interface UtilityBarActionProps extends BarActionProps {
- iconType?: IconType;
+// type Omit = Pick>;
+// type PartialBy = Omit & Partial>;
+
+// export interface UtilityBarActionProps extends PartialBy {
+// popoverContent?: PopoverProps['popoverContent'];
+// }
+
+export interface UtilityBarActionProps extends LinkIconProps {
popoverContent?: PopoverProps['popoverContent'];
}
export const UtilityBarAction = React.memo(
- ({ children, href, iconSide = 'left', iconType, onClick, popoverContent }) => {
- if (popoverContent) {
- return {children};
- } else {
- return (
-
- {iconType && }
- {children}
-
- );
- }
- }
+ ({ children, href, iconOptions, onClick, popoverContent }) => (
+
+ {popoverContent ? (
+
+ {children}
+
+ ) : (
+
+ {children}
+
+ )}
+
+ )
);
UtilityBarAction.displayName = 'UtilityBarAction';
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
index 787985ea2459a..e6b9293bb7ada 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
@@ -52,29 +52,39 @@ const OpenSignals = React.memo(() => {
{'Selected: 20 signals'}
- {'Batch actions context menu here.'}}>
+ {'Batch actions context menu here.'}}
+ >
{'Batch actions'}
-
+
{'Select all signals on all pages'}
- {'Clear 7 filters'}
+ {'Clear 7 filters'}
- {'Clear aggregation'}
+
+ {'Clear aggregation'}
+
- {'Customize columns context menu here.'}}>
+ {'Customize columns context menu here.'}}
+ >
{'Customize columns'}
- {'Aggregate data'}
+
+ {'Aggregate data'}
+
@@ -96,11 +106,16 @@ const ClosedSignals = React.memo(() => {
- {'Customize columns context menu here.'}}>
+ {'Customize columns context menu here.'}}
+ >
{'Customize columns'}
- {'Aggregate data'}
+
+ {'Aggregate data'}
+
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
index 3624e9645b49d..9583b8060269e 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
@@ -28,6 +28,7 @@ import styled, { css } from 'styled-components';
import { getEmptyTagValue } from '../../../components/empty_value';
import { HeaderPage } from '../../../components/header_page';
import { HeaderSection } from '../../../components/header_section';
+import { LinkIcon } from '../../../components/link_icon';
import {
UtilityBar,
UtilityBarAction,
@@ -147,13 +148,16 @@ const AllRules = React.memo(() => {
{'Selected: 2 rules'}
- {'Batch actions context menu here.'}}>
+ {'Batch actions context menu here.'}}
+ >
{'Batch actions'}
- {'Clear 7 filters'}
+ {'Clear 7 filters'}
@@ -273,49 +277,51 @@ const ActivityMonitor = React.memo(() => {
actions: string;
}
+ interface PageTypes {
+ index: number;
+ size: number;
+ }
+
interface SortTypes {
field: string;
direction: string;
}
- const [selectedState, setSelectedState] = useState([]);
- const [sortState, setSortState] = useState({ field: 'ran', direction: 'desc' });
+ const actions = [
+ {
+ render: (item: ColumnTypes) => {
+ if (item.status === 'Running') {
+ return {'Stop'};
+ } else if (item.status === 'Stopped') {
+ return {'Resume'};
+ } else {
+ return <>{''}>;
+ }
+ },
+ },
+ ];
// const actions = [
// {
- // render: (item = {}) => {
- // if (item.status === 'Running') {
- // return {'Stop'};
- // } else if (item.status === 'Stopped') {
- // return {'Resume'};
- // } else {
- // return {'Nada'}
;
- // }
- // },
+ // available: (item: ColumnTypes) => (item.status === 'Running' ? true : false),
+ // name: 'Stop',
+ // isPrimary: true,
+ // description: 'Stop rule from running',
+ // icon: 'stop',
+ // type: 'button',
+ // onClick: () => {},
+ // },
+ // {
+ // available: (item: ColumnTypes) => (item.status === 'Stopped' ? true : false),
+ // name: 'Resume',
+ // isPrimary: true,
+ // description: 'Resume running rule',
+ // icon: 'play',
+ // type: 'button',
+ // onClick: () => {},
// },
// ];
- const actions = [
- {
- available: (item: ColumnTypes) => (item.status === 'Running' ? true : false),
- name: 'Stop',
- isPrimary: true,
- description: 'Stop rule from running',
- icon: 'stop',
- type: 'button',
- onClick: () => {},
- },
- {
- available: (item: ColumnTypes) => (item.status === 'Stopped' ? true : false),
- name: 'Resume',
- isPrimary: true,
- description: 'Resume running rule',
- icon: 'play',
- type: 'button',
- onClick: () => {},
- },
- ];
-
const columns = [
{
field: 'rule',
@@ -352,7 +358,7 @@ const ActivityMonitor = React.memo(() => {
getEmptyTagValue()
) : (
<>
- {value === 'Fail' ? (
+ {/* {value === 'Fail' ? (
{value}
@@ -364,6 +370,20 @@ const ActivityMonitor = React.memo(() => {
) : (
{value}
+ )} */}
+
+ {value === 'Fail' ? (
+
+
+ {value}
+
+
+
+
+
+
+ ) : (
+ {value}
)}
>
);
@@ -409,8 +429,149 @@ const ActivityMonitor = React.memo(() => {
status: 'Completed',
response: 'Success',
},
+ {
+ id: 5,
+ rule: 'Automated exfiltration',
+ ran: '12/28/2019, 12:00 PM',
+ lookedBackTo: '12/28/2019, 12:00 PM',
+ status: 'Completed',
+ response: 'Success',
+ },
+ {
+ id: 6,
+ rule: 'Automated exfiltration',
+ ran: '12/28/2019, 12:00 PM',
+ lookedBackTo: '12/28/2019, 12:00 PM',
+ status: 'Completed',
+ response: 'Success',
+ },
+ {
+ id: 7,
+ rule: 'Automated exfiltration',
+ ran: '12/28/2019, 12:00 PM',
+ lookedBackTo: '12/28/2019, 12:00 PM',
+ status: 'Completed',
+ response: 'Success',
+ },
+ {
+ id: 8,
+ rule: 'Automated exfiltration',
+ ran: '12/28/2019, 12:00 PM',
+ lookedBackTo: '12/28/2019, 12:00 PM',
+ status: 'Completed',
+ response: 'Success',
+ },
+ {
+ id: 9,
+ rule: 'Automated exfiltration',
+ ran: '12/28/2019, 12:00 PM',
+ lookedBackTo: '12/28/2019, 12:00 PM',
+ status: 'Completed',
+ response: 'Success',
+ },
+ {
+ id: 10,
+ rule: 'Automated exfiltration',
+ ran: '12/28/2019, 12:00 PM',
+ lookedBackTo: '12/28/2019, 12:00 PM',
+ status: 'Completed',
+ response: 'Success',
+ },
+ {
+ id: 11,
+ rule: 'Automated exfiltration',
+ ran: '12/28/2019, 12:00 PM',
+ lookedBackTo: '12/28/2019, 12:00 PM',
+ status: 'Completed',
+ response: 'Success',
+ },
+ {
+ id: 12,
+ rule: 'Automated exfiltration',
+ ran: '12/28/2019, 12:00 PM',
+ lookedBackTo: '12/28/2019, 12:00 PM',
+ status: 'Completed',
+ response: 'Success',
+ },
+ {
+ id: 13,
+ rule: 'Automated exfiltration',
+ ran: '12/28/2019, 12:00 PM',
+ lookedBackTo: '12/28/2019, 12:00 PM',
+ status: 'Completed',
+ response: 'Success',
+ },
+ {
+ id: 14,
+ rule: 'Automated exfiltration',
+ ran: '12/28/2019, 12:00 PM',
+ lookedBackTo: '12/28/2019, 12:00 PM',
+ status: 'Completed',
+ response: 'Success',
+ },
+ {
+ id: 15,
+ rule: 'Automated exfiltration',
+ ran: '12/28/2019, 12:00 PM',
+ lookedBackTo: '12/28/2019, 12:00 PM',
+ status: 'Completed',
+ response: 'Success',
+ },
+ {
+ id: 16,
+ rule: 'Automated exfiltration',
+ ran: '12/28/2019, 12:00 PM',
+ lookedBackTo: '12/28/2019, 12:00 PM',
+ status: 'Completed',
+ response: 'Success',
+ },
+ {
+ id: 17,
+ rule: 'Automated exfiltration',
+ ran: '12/28/2019, 12:00 PM',
+ lookedBackTo: '12/28/2019, 12:00 PM',
+ status: 'Completed',
+ response: 'Success',
+ },
+ {
+ id: 18,
+ rule: 'Automated exfiltration',
+ ran: '12/28/2019, 12:00 PM',
+ lookedBackTo: '12/28/2019, 12:00 PM',
+ status: 'Completed',
+ response: 'Success',
+ },
+ {
+ id: 19,
+ rule: 'Automated exfiltration',
+ ran: '12/28/2019, 12:00 PM',
+ lookedBackTo: '12/28/2019, 12:00 PM',
+ status: 'Completed',
+ response: 'Success',
+ },
+ {
+ id: 20,
+ rule: 'Automated exfiltration',
+ ran: '12/28/2019, 12:00 PM',
+ lookedBackTo: '12/28/2019, 12:00 PM',
+ status: 'Completed',
+ response: 'Success',
+ },
+ {
+ id: 21,
+ rule: 'Automated exfiltration',
+ ran: '12/28/2019, 12:00 PM',
+ lookedBackTo: '12/28/2019, 12:00 PM',
+ status: 'Completed',
+ response: 'Success',
+ },
];
+ const [itemsTotalState, setItemsTotalState] = useState(sampleTableData.length);
+ const [pageState, setPageState] = useState({ index: 0, size: 20 });
+ const [selectedState, setSelectedState] = useState([]);
+ const [sortState, setSortState] = useState({ field: 'ran', direction: 'desc' });
+
return (
<>
@@ -427,23 +588,34 @@ const ActivityMonitor = React.memo(() => {
{'Selected: 2 activities'}
- {'Stop selected'}
+ {'Stop selected'}
- {'Clear 7 filters'}
+
+ {'Clear 7 filters'}
+
{
+ onChange={({ page, sort }: { page: PageTypes; sort: SortTypes }) => {
+ setPageState(page);
setSortState(sort);
}}
+ pagination={{
+ pageIndex: pageState.index,
+ pageSize: pageState.size,
+ totalItemCount: itemsTotalState,
+ pageSizeOptions: [5, 10, 20],
+ }}
selection={{
selectable: (item: ColumnTypes) => item.status !== 'Completed',
selectableMessage: (selectable: boolean) =>
From 57cd4fd9631e8817975176f8c4a2eee6f660fc59 Mon Sep 17 00:00:00 2001
From: Michael Marcialis
Date: Wed, 23 Oct 2019 17:07:39 -0400
Subject: [PATCH 27/57] fix bugs, errors, tests
---
.../components/header_page/index.test.tsx | 4 +-
.../public/components/header_page/index.tsx | 6 +-
.../__snapshots__/index.test.tsx.snap | 14 +++
.../components/link_icon/index.test.tsx | 100 +++++++++++++++++-
.../public/components/link_icon/index.tsx | 38 +++----
.../utility_bar_action.test.tsx.snap | 4 +-
.../utility_bar/utility_bar_action.test.tsx | 81 +-------------
.../utility_bar/utility_bar_action.tsx | 73 +++++++------
.../detection_engine/detection_engine.tsx | 25 ++---
.../pages/detection_engine/rules/index.tsx | 15 ++-
10 files changed, 190 insertions(+), 170 deletions(-)
create mode 100644 x-pack/legacy/plugins/siem/public/components/link_icon/__snapshots__/index.test.tsx.snap
diff --git a/x-pack/legacy/plugins/siem/public/components/header_page/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/header_page/index.test.tsx
index 0cd6151e59f6c..ae33b63e93d39 100644
--- a/x-pack/legacy/plugins/siem/public/components/header_page/index.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/header_page/index.test.tsx
@@ -59,7 +59,7 @@ describe('HeaderPage', () => {
expect(
wrapper
- .find('[data-test-subj="header-page-back-link"]')
+ .find('.siemHeaderPage__linkBack')
.first()
.exists()
).toBe(true);
@@ -74,7 +74,7 @@ describe('HeaderPage', () => {
expect(
wrapper
- .find('[data-test-subj="header-page-back-link"]')
+ .find('.siemHeaderPage__linkBack')
.first()
.exists()
).toBe(false);
diff --git a/x-pack/legacy/plugins/siem/public/components/header_page/index.tsx b/x-pack/legacy/plugins/siem/public/components/header_page/index.tsx
index d8dc08e7be0f7..9ce16ebd40257 100644
--- a/x-pack/legacy/plugins/siem/public/components/header_page/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/header_page/index.tsx
@@ -95,11 +95,7 @@ export const HeaderPage = React.memo(
{backOptions && (
-
+
{backOptions.text}
diff --git a/x-pack/legacy/plugins/siem/public/components/link_icon/__snapshots__/index.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/link_icon/__snapshots__/index.test.tsx.snap
new file mode 100644
index 0000000000000..5902768383cb0
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/components/link_icon/__snapshots__/index.test.tsx.snap
@@ -0,0 +1,14 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`LinkIcon it renders 1`] = `
+
+
+ Test link
+
+
+`;
diff --git a/x-pack/legacy/plugins/siem/public/components/link_icon/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/link_icon/index.test.tsx
index aceffb3ea89e2..8e4387f35056e 100644
--- a/x-pack/legacy/plugins/siem/public/components/link_icon/index.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/link_icon/index.test.tsx
@@ -4,12 +4,13 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { shallow } from 'enzyme';
+import { mount, shallow } from 'enzyme';
import toJson from 'enzyme-to-json';
+import 'jest-styled-components';
import React from 'react';
-import '../../mock/ui_settings';
import { TestProviders } from '../../mock';
+import '../../mock/ui_settings';
import { LinkIcon } from './index';
jest.mock('../../lib/settings/use_kibana_ui_setting');
@@ -18,10 +19,103 @@ describe('LinkIcon', () => {
test('it renders', () => {
const wrapper = shallow(
- {'Test link'}
+
+ {'Test link'}
+
);
expect(toJson(wrapper)).toMatchSnapshot();
});
+
+ test('it renders an action button when onClick is provided', () => {
+ const wrapper = mount(
+
+ alert('Test alert')}>
+ {'Test link'}
+
+
+ );
+
+ expect(
+ wrapper
+ .find('button')
+ .first()
+ .exists()
+ ).toBe(true);
+ });
+
+ test('it renders an action link when href is provided', () => {
+ const wrapper = mount(
+
+
+ {'Test link'}
+
+
+ );
+
+ expect(
+ wrapper
+ .find('a')
+ .first()
+ .exists()
+ ).toBe(true);
+ });
+
+ test('it renders an icon', () => {
+ const wrapper = mount(
+
+ {'Test link'}
+
+ );
+
+ expect(
+ wrapper
+ .find('.euiIcon')
+ .first()
+ .exists()
+ ).toBe(true);
+ });
+
+ test('it positions the icon to the right when iconSide is right', () => {
+ const wrapper = mount(
+
+
+ {'Test link'}
+
+
+ );
+
+ expect(wrapper.find('.siemLinkIcon').first()).toHaveStyleRule('flex-direction', 'row-reverse');
+ });
+
+ test('it positions the icon to the left when iconSide is left (or not provided)', () => {
+ const wrapper = mount(
+
+
+ {'Test link'}
+
+
+ );
+
+ expect(wrapper.find('.siemLinkIcon').first()).not.toHaveStyleRule(
+ 'flex-direction',
+ 'row-reverse'
+ );
+ });
+
+ test('it renders a label', () => {
+ const wrapper = mount(
+
+ {'Test link'}
+
+ );
+
+ expect(
+ wrapper
+ .find('.siemLinkIcon__label')
+ .first()
+ .exists()
+ ).toBe(true);
+ });
});
diff --git a/x-pack/legacy/plugins/siem/public/components/link_icon/index.tsx b/x-pack/legacy/plugins/siem/public/components/link_icon/index.tsx
index 5f85a3f2daf2e..d83183adcf5e5 100644
--- a/x-pack/legacy/plugins/siem/public/components/link_icon/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/link_icon/index.tsx
@@ -9,38 +9,30 @@ import { LinkAnchorProps } from '@elastic/eui/src/components/link/link';
import React from 'react';
import styled, { css } from 'styled-components';
-interface IconOptions {
- side?: 'left' | 'right';
- size?: IconSize;
- type: IconType;
-}
-
interface LinkProps {
- className?: string;
color?: LinkAnchorProps['color'];
href?: string;
- // iconSide?: 'left' | 'right';
- iconOptions: IconOptions;
+ iconSide?: 'left' | 'right';
onClick?: Function;
}
-const Link = styled(EuiLink).attrs({
- className: 'siemLinkIcon',
-})`
- ${({ iconOptions, theme }) => css`
+const Link = styled(({ iconSide, children, ...rest }) => {children})<
+ LinkProps
+>`
+ ${({ iconSide, theme }) => css`
align-items: center;
display: inline-flex;
vertical-align: top;
white-space: nowrap;
- ${iconOptions.side === 'left' &&
+ ${iconSide === 'left' &&
css`
.euiIcon {
margin-right: ${theme.eui.euiSizeXS};
}
`}
- ${iconOptions.side === 'right' &&
+ ${iconSide === 'right' &&
css`
flex-direction: row-reverse;
@@ -54,20 +46,14 @@ Link.displayName = 'Link';
export interface LinkIconProps extends LinkProps {
children: string;
- // iconSize?: IconSize;
- // iconType: IconType;
+ iconSize?: IconSize;
+ iconType: IconType;
}
export const LinkIcon = React.memo(
- ({ children, className, color, href, iconOptions = { side: 'left', size: 's' }, onClick }) => (
-
-
+ ({ children, color, href, iconSide = 'left', iconSize = 's', iconType, onClick }) => (
+
+
{children}
)
diff --git a/x-pack/legacy/plugins/siem/public/components/utility_bar/__snapshots__/utility_bar_action.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/utility_bar/__snapshots__/utility_bar_action.test.tsx.snap
index 82fb6d81d8033..470b40cd1d960 100644
--- a/x-pack/legacy/plugins/siem/public/components/utility_bar/__snapshots__/utility_bar_action.test.tsx.snap
+++ b/x-pack/legacy/plugins/siem/public/components/utility_bar/__snapshots__/utility_bar_action.test.tsx.snap
@@ -2,7 +2,9 @@
exports[`UtilityBarAction it renders 1`] = `
-
+
Test action
diff --git a/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_action.test.tsx b/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_action.test.tsx
index c4f241e545800..b25aa7d4933ec 100644
--- a/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_action.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_action.test.tsx
@@ -19,77 +19,17 @@ describe('UtilityBarAction', () => {
test('it renders', () => {
const wrapper = shallow(
- {'Test action'}
+ {'Test action'}
);
expect(toJson(wrapper)).toMatchSnapshot();
});
- test('it renders an action button', () => {
- const wrapper = mount(
-
- alert('Test alert')}>{'Test action'}
-
- );
-
- expect(
- wrapper
- .find('button')
- .first()
- .exists()
- ).toBe(true);
- });
-
- test('it renders an action link', () => {
- const wrapper = mount(
-
- {'Test action'}
-
- );
-
- expect(
- wrapper
- .find('a')
- .first()
- .exists()
- ).toBe(true);
- });
-
- test('it renders an icon', () => {
- const wrapper = mount(
-
- {'Test action'}
-
- );
-
- expect(
- wrapper
- .find('.euiIcon')
- .first()
- .exists()
- ).toBe(true);
- });
-
- test('it can right-align an icon', () => {
- const wrapper = mount(
-
-
- {'Test action'}
-
-
- );
-
- expect(wrapper.find('.siemUtilityBar__action').first()).toHaveStyleRule(
- 'flex-direction',
- 'row-reverse'
- );
- });
-
test('it renders a popover', () => {
const wrapper = mount(
- {'Test popover'}}>
+ {'Test popover'}}>
{'Test action'}
@@ -102,21 +42,4 @@ describe('UtilityBarAction', () => {
.exists()
).toBe(true);
});
-
- test('the popover action has an arrow icon', () => {
- const wrapper = mount(
-
- {'Test popover'}}>
- {'Test action'}
-
-
- );
-
- expect(
- wrapper
- .find('.euiIcon')
- .first()
- .exists()
- ).toBe(true);
- });
});
diff --git a/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_action.tsx b/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_action.tsx
index a12bdf4b8de08..65002e30edb5e 100644
--- a/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_action.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_action.tsx
@@ -10,50 +10,59 @@ import React, { useState } from 'react';
import { LinkIcon, LinkIconProps } from '../link_icon';
import { BarAction } from './styles';
-interface PopoverProps {
- children: LinkIconProps['children'];
- popoverContent?: React.ReactNode;
-}
-
-const Popover = React.memo(({ children, iconOptions, popoverContent }) => {
- const [popoverState, setPopoverState] = useState(false);
+const Popover = React.memo(
+ ({ children, color, iconSide, iconSize, iconType, popoverContent }) => {
+ const [popoverState, setPopoverState] = useState(false);
- return (
- setPopoverState(!popoverState)}>
- {children}
-
- }
- isOpen={popoverState}
- closePopover={() => setPopoverState(false)}
- >
- {popoverContent}
-
- );
-});
+ return (
+ setPopoverState(!popoverState)}
+ >
+ {children}
+
+ }
+ closePopover={() => setPopoverState(false)}
+ isOpen={popoverState}
+ >
+ {popoverContent}
+
+ );
+ }
+);
Popover.displayName = 'Popover';
-// type Omit = Pick>;
-// type PartialBy = Omit & Partial>;
-
-// export interface UtilityBarActionProps extends PartialBy {
-// popoverContent?: PopoverProps['popoverContent'];
-// }
-
export interface UtilityBarActionProps extends LinkIconProps {
- popoverContent?: PopoverProps['popoverContent'];
+ popoverContent?: React.ReactNode;
}
export const UtilityBarAction = React.memo(
- ({ children, href, iconOptions, onClick, popoverContent }) => (
+ ({ children, color, href, iconSide, iconSize, iconType, onClick, popoverContent }) => (
{popoverContent ? (
-
+
{children}
) : (
-
+
{children}
)}
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
index e6b9293bb7ada..be85a616df9c4 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
@@ -53,38 +53,36 @@ const OpenSignals = React.memo(() => {
{'Selected: 20 signals'}
{'Batch actions context menu here.'}}
>
{'Batch actions'}
-
+
{'Select all signals on all pages'}
- {'Clear 7 filters'}
+ {'Clear 7 filters'}
-
- {'Clear aggregation'}
-
+ {'Clear aggregation'}
{'Customize columns context menu here.'}}
>
{'Customize columns'}
-
- {'Aggregate data'}
-
+ {'Aggregate data'}
@@ -107,15 +105,14 @@ const ClosedSignals = React.memo(() => {
{'Customize columns context menu here.'}}
>
{'Customize columns'}
-
- {'Aggregate data'}
-
+ {'Aggregate data'}
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
index 9583b8060269e..99c7014072d60 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
@@ -149,7 +149,8 @@ const AllRules = React.memo(() => {
{'Selected: 2 rules'}
{'Batch actions context menu here.'}}
>
{'Batch actions'}
@@ -157,7 +158,7 @@ const AllRules = React.memo(() => {
- {'Clear 7 filters'}
+ {'Clear 7 filters'}
@@ -291,9 +292,9 @@ const ActivityMonitor = React.memo(() => {
{
render: (item: ColumnTypes) => {
if (item.status === 'Running') {
- return {'Stop'};
+ return {'Stop'};
} else if (item.status === 'Stopped') {
- return {'Resume'};
+ return {'Resume'};
} else {
return <>{''}>;
}
@@ -588,13 +589,11 @@ const ActivityMonitor = React.memo(() => {
{'Selected: 2 activities'}
- {'Stop selected'}
+ {'Stop selected'}
-
- {'Clear 7 filters'}
-
+ {'Clear 7 filters'}
From 1531fcfb7474043a2c44eee693d561f7efee4da2 Mon Sep 17 00:00:00 2001
From: Michael Marcialis
Date: Wed, 23 Oct 2019 17:08:30 -0400
Subject: [PATCH 28/57] rm import
---
.../legacy/plugins/siem/public/components/utility_bar/styles.tsx | 1 -
1 file changed, 1 deletion(-)
diff --git a/x-pack/legacy/plugins/siem/public/components/utility_bar/styles.tsx b/x-pack/legacy/plugins/siem/public/components/utility_bar/styles.tsx
index a279eb5cf4a05..9d746bf3b0515 100644
--- a/x-pack/legacy/plugins/siem/public/components/utility_bar/styles.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/utility_bar/styles.tsx
@@ -4,7 +4,6 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { EuiLink } from '@elastic/eui';
import styled, { css } from 'styled-components';
/**
From bf1f127b38e6dd4aaf702f3e76da5af848d2099a Mon Sep 17 00:00:00 2001
From: Michael Marcialis
Date: Thu, 24 Oct 2019 11:18:29 -0400
Subject: [PATCH 29/57] table cleanup
---
.../pages/detection_engine/rules/index.tsx | 52 +++----------------
1 file changed, 6 insertions(+), 46 deletions(-)
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
index 99c7014072d60..b0521c5c2193e 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
@@ -20,7 +20,7 @@ import {
EuiSpacer,
EuiSwitch,
EuiTabbedContent,
- EuiText,
+ EuiTextColor,
} from '@elastic/eui';
import React, { useState } from 'react';
import styled, { css } from 'styled-components';
@@ -302,27 +302,6 @@ const ActivityMonitor = React.memo(() => {
},
];
- // const actions = [
- // {
- // available: (item: ColumnTypes) => (item.status === 'Running' ? true : false),
- // name: 'Stop',
- // isPrimary: true,
- // description: 'Stop rule from running',
- // icon: 'stop',
- // type: 'button',
- // onClick: () => {},
- // },
- // {
- // available: (item: ColumnTypes) => (item.status === 'Stopped' ? true : false),
- // name: 'Resume',
- // isPrimary: true,
- // description: 'Resume running rule',
- // icon: 'play',
- // type: 'button',
- // onClick: () => {},
- // },
- // ];
-
const columns = [
{
field: 'rule',
@@ -359,32 +338,12 @@ const ActivityMonitor = React.memo(() => {
getEmptyTagValue()
) : (
<>
- {/* {value === 'Fail' ? (
-
-
- {value}
-
-
-
-
-
-
- ) : (
- {value}
- )} */}
-
{value === 'Fail' ? (
-
-
- {value}
-
-
-
-
-
-
+
+ {value}
+
) : (
- {value}
+ {value}
)}
>
);
@@ -394,6 +353,7 @@ const ActivityMonitor = React.memo(() => {
},
{
actions,
+ width: '70px',
},
];
From 02f978df411aa51984a9d60178ed0ce10be322f0 Mon Sep 17 00:00:00 2001
From: Michael Marcialis
Date: Mon, 28 Oct 2019 10:20:30 -0400
Subject: [PATCH 30/57] correct merge errors
---
.../siem/public/pages/hosts/details/index.tsx | 169 +++++++++---------
.../plugins/siem/public/pages/hosts/hosts.tsx | 91 +++++-----
2 files changed, 129 insertions(+), 131 deletions(-)
diff --git a/x-pack/legacy/plugins/siem/public/pages/hosts/details/index.tsx b/x-pack/legacy/plugins/siem/public/pages/hosts/details/index.tsx
index 52e1ec0cb135d..ec18450312852 100644
--- a/x-pack/legacy/plugins/siem/public/pages/hosts/details/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/hosts/details/index.tsx
@@ -96,97 +96,94 @@ const HostDetailsComponent = React.memo(
],
});
return indicesExistOrDataTemporarilyUnavailable(indicesExist) ? (
- <>
-
-
-
-
+
+
+
+
+
+
+ }
+ title={detailName}
+ />
-
- }
- title={detailName}
- />
+
+ {({ hostOverview, loading, id, inspect, refetch }) => (
+
+ {({ isLoadingAnomaliesData, anomaliesData }) => (
+ {
+ const fromTo = scoreIntervalToDateTime(score, interval);
+ setAbsoluteRangeDatePicker({
+ id: 'global',
+ from: fromTo.from,
+ to: fromTo.to,
+ });
+ }}
+ />
+ )}
+
+ )}
+
-
- {({ hostOverview, loading, id, inspect, refetch }) => (
-
- {({ isLoadingAnomaliesData, anomaliesData }) => (
- {
- const fromTo = scoreIntervalToDateTime(score, interval);
- setAbsoluteRangeDatePicker({
- id: 'global',
- from: fromTo.from,
- to: fromTo.to,
- });
- }}
- />
- )}
-
- )}
-
+
-
+
+ {({ kpiHostDetails, id, inspect, loading, refetch }) => (
+ {
+ setAbsoluteRangeDatePicker({ id: 'global', from: min, to: max });
+ }}
+ />
+ )}
+
-
- {({ kpiHostDetails, id, inspect, loading, refetch }) => (
- {
- setAbsoluteRangeDatePicker({ id: 'global', from: min, to: max });
- }}
- />
- )}
-
+
-
+
-
-
+
(
indexPattern={indexPattern}
setAbsoluteRangeDatePicker={setAbsoluteRangeDatePicker}
/>
- >
+
) : (
<>
diff --git a/x-pack/legacy/plugins/siem/public/pages/hosts/hosts.tsx b/x-pack/legacy/plugins/siem/public/pages/hosts/hosts.tsx
index 6a16f65fb4f99..a43d36d538c96 100644
--- a/x-pack/legacy/plugins/siem/public/pages/hosts/hosts.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/hosts/hosts.tsx
@@ -63,50 +63,50 @@ const HostsComponent = React.memo(
filters,
});
return indicesExistOrDataTemporarilyUnavailable(indicesExist) ? (
- <>
-
-
-
-
-
- }
- title={i18n.PAGE_TITLE}
- />
-
-
- {({ kpiHosts, loading, id, inspect, refetch }) => (
- {
- setAbsoluteRangeDatePicker({ id: 'global', from: min, to: max });
- }}
- />
- )}
-
-
-
-
-
-
+
+
+
+
+
+ }
+ title={i18n.PAGE_TITLE}
+ />
+
+
+ {({ kpiHosts, loading, id, inspect, refetch }) => (
+ {
+ setAbsoluteRangeDatePicker({ id: 'global', from: min, to: max });
+ }}
+ />
+ )}
+
+
+
+
+
+
+
(
setAbsoluteRangeDatePicker={setAbsoluteRangeDatePicker}
hostsPagePath={hostsPagePath}
/>
- >
+
) : (
<>
+
>
);
From 694e0fa81591fc96961052b265773aedddc75cc1 Mon Sep 17 00:00:00 2001
From: Michael Marcialis
Date: Mon, 28 Oct 2019 15:28:37 -0400
Subject: [PATCH 31/57] switch All Rules to EuiBasicTable
---
.../pages/detection_engine/rules/index.tsx | 531 +++++++++---------
1 file changed, 268 insertions(+), 263 deletions(-)
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
index b0521c5c2193e..af3b87404fd17 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
@@ -22,6 +22,7 @@ import {
EuiTabbedContent,
EuiTextColor,
} from '@elastic/eui';
+import moment from 'moment';
import React, { useState } from 'react';
import styled, { css } from 'styled-components';
@@ -39,230 +40,235 @@ import {
import { SpyRoute } from '../../../utils/route/spy_routes';
import * as i18n from './translations';
-const TableCards = styled.table.attrs({
- className: 'siemTableCards',
-})`
- ${({ theme }) => css`
- display: block;
- `}
-`;
-TableCards.displayName = 'TableCards';
-
-const TableCardsThead = styled.thead.attrs({
- className: 'siemTableCards__thead',
-})`
- ${({ theme }) => css`
- display: block;
- `}
-`;
-TableCardsThead.displayName = 'TableCardsThead';
-
-const TableCardsTbody = styled.tbody.attrs({
- className: 'siemTableCards__tbody',
-})`
- ${({ theme }) => css`
- display: block;
- `}
-`;
-TableCardsTbody.displayName = 'TableCardsTbody';
-
-const TableCardsRow = styled.tr.attrs({
- className: 'siemTableCards__tr',
-})`
- ${({ theme }) => css`
- border-collapse: separate;
- display: table;
- table-layout: fixed;
- width: 100%;
-
- .siemTableCards__thead & {
- border: ${theme.eui.euiBorderWidthThin} solid transparent;
- border-left-width: ${theme.eui.euiSizeXS};
- }
-
- .siemTableCards__tbody & {
- background-color: ${theme.eui.euiColorEmptyShade};
- border: ${theme.eui.euiBorderThin};
- border-left-color: ${theme.eui.euiColorSuccess};
- border-left-width: ${theme.eui.euiSizeXS};
- border-radius: ${theme.eui.euiBorderRadius};
- }
-
- .siemTableCards__tbody & + & {
- margin-top: ${theme.eui.euiSizeS};
- }
- `}
-`;
-TableCardsRow.displayName = 'TableCardsRow';
-
-const TableCardsTh = styled.th.attrs({
- className: 'siemTableCards__th',
-})`
- ${({ theme }) => css`
- font-size: ${theme.eui.euiFontSizeXS};
- font-weight: ${theme.eui.euiFontWeightSemiBold};
- line-height: ${theme.eui.euiLineHeight};
- padding: ${theme.eui.paddingSizes.s};
- text-align: left;
- vertical-align: middle;
-
- .siemTableCards__tbody & {
- font-size: ${theme.eui.euiFontSizeS};
- font-weight: ${theme.eui.euiFontWeightRegular};
- }
- `}
-`;
-TableCardsTh.displayName = 'TableCardsTh';
-
-const TableCardsTd = styled.td.attrs({
- className: 'siemTableCards__td',
-})`
- ${({ theme }) => css`
- font-size: ${theme.eui.euiFontSizeS};
- line-height: ${theme.eui.euiLineHeight};
- padding: ${theme.eui.paddingSizes.s};
- vertical-align: middle;
- `}
-`;
-TableCardsTd.displayName = 'TableCardsTd';
+// Will need to change this to get the current datetime format from Kibana settings.
+const dateTimeFormat = (value: string) => {
+ return moment(value).format('M/D/YYYY, h:mm A');
+};
const AllRules = React.memo(() => {
+ interface ColumnTypes {
+ id: number;
+ rule: string;
+ method: string;
+ severity: string;
+ lastCompletedRun: string;
+ lastResponse: string;
+ tags: string;
+ activate: boolean;
+ }
+
+ interface PageTypes {
+ index: number;
+ size: number;
+ }
+
+ interface SortTypes {
+ field: string;
+ direction: string;
+ }
+
+ const actions = [
+ {
+ name: 'Edit rule settings',
+ description: 'Edit rule settings',
+ icon: 'visControls',
+ onClick: () => {},
+ },
+ {
+ name: 'Run rule manually…',
+ description: 'Run rule manually…',
+ icon: 'play',
+ onClick: () => {},
+ },
+ {
+ name: 'Duplicate rule…',
+ description: 'Duplicate rule…',
+ icon: 'copy',
+ onClick: () => {},
+ },
+ {
+ name: 'Export rule',
+ description: 'Export rule',
+ icon: 'export',
+ onClick: () => {},
+ },
+ {
+ name: 'Delete rule…',
+ description: 'Delete rule…',
+ icon: 'trash',
+ onClick: () => {},
+ },
+ ];
+
+ const columns = [
+ {
+ field: 'rule',
+ name: 'Rule',
+ render: (value: string) => (
+ {value}
+ ),
+ sortable: true,
+ truncateText: true,
+ },
+ {
+ field: 'method',
+ name: 'Method',
+ sortable: true,
+ truncateText: true,
+ },
+ {
+ field: 'severity',
+ name: 'Severity',
+ render: (value: string) => {value},
+ sortable: true,
+ truncateText: true,
+ },
+ {
+ field: 'lastCompletedRun',
+ name: 'Last completed run',
+ render: (value: string) => ,
+ sortable: true,
+ truncateText: true,
+ },
+ {
+ field: 'lastResponse',
+ name: 'Last response',
+ render: (value: string | undefined) => {
+ return value === undefined ? (
+ getEmptyTagValue()
+ ) : (
+ <>
+ {value === 'Fail' ? (
+
+ {value}
+
+ ) : (
+ {value}
+ )}
+ >
+ );
+ },
+ sortable: true,
+ truncateText: true,
+ },
+ {
+ field: 'tags',
+ name: 'Tags',
+ render: (value: string) => {value},
+ sortable: true,
+ truncateText: true,
+ },
+ {
+ align: 'center',
+ field: 'activate',
+ name: 'Activate',
+ render: (value: boolean) => ,
+ sortable: true,
+ },
+ {
+ actions,
+ },
+ ];
+
+ const sampleTableData = [
+ {
+ id: 1,
+ rule: 'Automated exfiltration',
+ method: 'Custom query',
+ severity: 'Medium',
+ lastCompletedRun: '2019-12-28 00:00:00.000-05:00',
+ lastResponse: 'Success',
+ tags: 'attack.t1234',
+ activate: true,
+ },
+ {
+ id: 2,
+ rule: 'Automated exfiltration',
+ method: 'Custom query',
+ severity: 'Medium',
+ lastCompletedRun: '2019-12-28 00:00:00.000-05:00',
+ lastResponse: 'Fail',
+ tags: 'attack.t1234',
+ activate: true,
+ },
+ {
+ id: 3,
+ rule: 'Automated exfiltration',
+ method: 'Custom query',
+ severity: 'Medium',
+ lastCompletedRun: '2019-12-28 00:00:00.000-05:00',
+ lastResponse: 'Success',
+ tags: 'attack.t1234',
+ activate: false,
+ },
+ ];
+
+ const [itemsTotalState, setItemsTotalState] = useState(sampleTableData.length);
+ const [pageState, setPageState] = useState({ index: 0, size: 20 });
+ const [selectedState, setSelectedState] = useState([]);
+ const [sortState, setSortState] = useState({ field: 'ran', direction: 'desc' });
+
return (
<>
-
-
+
+
+
+
+
+
+
+ {'Showing: 39 rules'}
+
+
+
+ {'Selected: 2 rules'}
+
+ {'Batch actions context menu here.'}}
+ >
+ {'Batch actions'}
+
+
+
+
+ {'Clear 7 filters'}
+
+
+
+
+ {
+ setPageState(page);
+ setSortState(sort);
+ }}
+ pagination={{
+ pageIndex: pageState.index,
+ pageSize: pageState.size,
+ totalItemCount: itemsTotalState,
+ pageSizeOptions: [5, 10, 20],
+ }}
+ selection={{
+ selectable: () => true,
+ onSelectionChange: (selectedItems: ColumnTypes[]) => {
+ setSelectedState(selectedItems);
+ },
+ }}
+ sorting={{
+ sort: sortState,
+ }}
/>
-
-
-
-
-
- {'Showing: 39 rules'}
-
-
-
- {'Selected: 2 rules'}
-
- {'Batch actions context menu here.'}}
- >
- {'Batch actions'}
-
-
-
-
- {'Clear 7 filters'}
-
-
-
-
- {/* Example of potentially new TableCards component. This new table type may no longer be required for implementation, given the requirements changes that have been made over time. At present, the only afforded benefits of using it are 1) differentiation from regular tables and 2) the presence of a colored status bar on the left of each row. Neither are dealbreakers in my mind. If creating a new table component is out of the question for MVP, go with a standard EUI basic table. */}
-
-
-
-
-
- {
- return null;
- }}
- />
-
- {'Rule'}
- {'Method'}
- {'Severity'}
- {'Last completed run'}
- {'Last response'}
- {'Tags'}
-
- {'Activate'}
-
-
-
-
-
-
-
-
- {
- return null;
- }}
- />
-
-
-
- {'Automated exfiltration'}
- {' '}
- {'Experimental'}
-
- {'Kibana Query Language'}
-
- {'Medium'}
-
-
-
-
-
- {'Success'}
-
-
- {'attack.t1234'}
-
-
-
-
-
-
-
-
-
-
-
- {
- return null;
- }}
- />
-
-
-
- {'Automated exfiltration'}
- {' '}
- {'Experimental'}
-
- {'Kibana Query Language'}
-
- {'Medium'}
-
-
-
-
-
- {'Fail'}
-
-
- {'attack.t1234'}
-
-
-
-
-
-
-
-
-
-
+
>
);
});
@@ -275,7 +281,6 @@ const ActivityMonitor = React.memo(() => {
ran: string;
lookedBackTo: string;
status: string;
- actions: string;
}
interface PageTypes {
@@ -315,12 +320,14 @@ const ActivityMonitor = React.memo(() => {
{
field: 'ran',
name: 'Ran',
+ render: (value: string) => ,
sortable: true,
truncateText: true,
},
{
field: 'lookedBackTo',
name: 'Looked back to',
+ render: (value: string) => ,
sortable: true,
truncateText: true,
},
@@ -361,168 +368,166 @@ const ActivityMonitor = React.memo(() => {
{
id: 1,
rule: 'Automated exfiltration',
- ran: '12/28/2019, 12:00 PM',
- lookedBackTo: '12/28/2019, 12:00 PM',
+ ran: '2019-12-28 00:00:00.000-05:00',
+ lookedBackTo: '2019-12-28 00:00:00.000-05:00',
status: 'Running',
- actions: 'Stop',
},
{
id: 2,
rule: 'Automated exfiltration',
- ran: '12/28/2019, 12:00 PM',
- lookedBackTo: '12/28/2019, 12:00 PM',
+ ran: '2019-12-28 00:00:00.000-05:00',
+ lookedBackTo: '2019-12-28 00:00:00.000-05:00',
status: 'Stopped',
- actions: 'Resume',
},
{
id: 3,
rule: 'Automated exfiltration',
- ran: '12/28/2019, 12:00 PM',
- lookedBackTo: '12/28/2019, 12:00 PM',
+ ran: '2019-12-28 00:00:00.000-05:00',
+ lookedBackTo: '2019-12-28 00:00:00.000-05:00',
status: 'Completed',
response: 'Fail',
},
{
id: 4,
rule: 'Automated exfiltration',
- ran: '12/28/2019, 12:00 PM',
- lookedBackTo: '12/28/2019, 12:00 PM',
+ ran: '2019-12-28 00:00:00.000-05:00',
+ lookedBackTo: '2019-12-28 00:00:00.000-05:00',
status: 'Completed',
response: 'Success',
},
{
id: 5,
rule: 'Automated exfiltration',
- ran: '12/28/2019, 12:00 PM',
- lookedBackTo: '12/28/2019, 12:00 PM',
+ ran: '2019-12-28 00:00:00.000-05:00',
+ lookedBackTo: '2019-12-28 00:00:00.000-05:00',
status: 'Completed',
response: 'Success',
},
{
id: 6,
rule: 'Automated exfiltration',
- ran: '12/28/2019, 12:00 PM',
- lookedBackTo: '12/28/2019, 12:00 PM',
+ ran: '2019-12-28 00:00:00.000-05:00',
+ lookedBackTo: '2019-12-28 00:00:00.000-05:00',
status: 'Completed',
response: 'Success',
},
{
id: 7,
rule: 'Automated exfiltration',
- ran: '12/28/2019, 12:00 PM',
- lookedBackTo: '12/28/2019, 12:00 PM',
+ ran: '2019-12-28 00:00:00.000-05:00',
+ lookedBackTo: '2019-12-28 00:00:00.000-05:00',
status: 'Completed',
response: 'Success',
},
{
id: 8,
rule: 'Automated exfiltration',
- ran: '12/28/2019, 12:00 PM',
- lookedBackTo: '12/28/2019, 12:00 PM',
+ ran: '2019-12-28 00:00:00.000-05:00',
+ lookedBackTo: '2019-12-28 00:00:00.000-05:00',
status: 'Completed',
response: 'Success',
},
{
id: 9,
rule: 'Automated exfiltration',
- ran: '12/28/2019, 12:00 PM',
- lookedBackTo: '12/28/2019, 12:00 PM',
+ ran: '2019-12-28 00:00:00.000-05:00',
+ lookedBackTo: '2019-12-28 00:00:00.000-05:00',
status: 'Completed',
response: 'Success',
},
{
id: 10,
rule: 'Automated exfiltration',
- ran: '12/28/2019, 12:00 PM',
- lookedBackTo: '12/28/2019, 12:00 PM',
+ ran: '2019-12-28 00:00:00.000-05:00',
+ lookedBackTo: '2019-12-28 00:00:00.000-05:00',
status: 'Completed',
response: 'Success',
},
{
id: 11,
rule: 'Automated exfiltration',
- ran: '12/28/2019, 12:00 PM',
- lookedBackTo: '12/28/2019, 12:00 PM',
+ ran: '2019-12-28 00:00:00.000-05:00',
+ lookedBackTo: '2019-12-28 00:00:00.000-05:00',
status: 'Completed',
response: 'Success',
},
{
id: 12,
rule: 'Automated exfiltration',
- ran: '12/28/2019, 12:00 PM',
- lookedBackTo: '12/28/2019, 12:00 PM',
+ ran: '2019-12-28 00:00:00.000-05:00',
+ lookedBackTo: '2019-12-28 00:00:00.000-05:00',
status: 'Completed',
response: 'Success',
},
{
id: 13,
rule: 'Automated exfiltration',
- ran: '12/28/2019, 12:00 PM',
- lookedBackTo: '12/28/2019, 12:00 PM',
+ ran: '2019-12-28 00:00:00.000-05:00',
+ lookedBackTo: '2019-12-28 00:00:00.000-05:00',
status: 'Completed',
response: 'Success',
},
{
id: 14,
rule: 'Automated exfiltration',
- ran: '12/28/2019, 12:00 PM',
- lookedBackTo: '12/28/2019, 12:00 PM',
+ ran: '2019-12-28 00:00:00.000-05:00',
+ lookedBackTo: '2019-12-28 00:00:00.000-05:00',
status: 'Completed',
response: 'Success',
},
{
id: 15,
rule: 'Automated exfiltration',
- ran: '12/28/2019, 12:00 PM',
- lookedBackTo: '12/28/2019, 12:00 PM',
+ ran: '2019-12-28 00:00:00.000-05:00',
+ lookedBackTo: '2019-12-28 00:00:00.000-05:00',
status: 'Completed',
response: 'Success',
},
{
id: 16,
rule: 'Automated exfiltration',
- ran: '12/28/2019, 12:00 PM',
- lookedBackTo: '12/28/2019, 12:00 PM',
+ ran: '2019-12-28 00:00:00.000-05:00',
+ lookedBackTo: '2019-12-28 00:00:00.000-05:00',
status: 'Completed',
response: 'Success',
},
{
id: 17,
rule: 'Automated exfiltration',
- ran: '12/28/2019, 12:00 PM',
- lookedBackTo: '12/28/2019, 12:00 PM',
+ ran: '2019-12-28 00:00:00.000-05:00',
+ lookedBackTo: '2019-12-28 00:00:00.000-05:00',
status: 'Completed',
response: 'Success',
},
{
id: 18,
rule: 'Automated exfiltration',
- ran: '12/28/2019, 12:00 PM',
- lookedBackTo: '12/28/2019, 12:00 PM',
+ ran: '2019-12-28 00:00:00.000-05:00',
+ lookedBackTo: '2019-12-28 00:00:00.000-05:00',
status: 'Completed',
response: 'Success',
},
{
id: 19,
rule: 'Automated exfiltration',
- ran: '12/28/2019, 12:00 PM',
- lookedBackTo: '12/28/2019, 12:00 PM',
+ ran: '2019-12-28 00:00:00.000-05:00',
+ lookedBackTo: '2019-12-28 00:00:00.000-05:00',
status: 'Completed',
response: 'Success',
},
{
id: 20,
rule: 'Automated exfiltration',
- ran: '12/28/2019, 12:00 PM',
- lookedBackTo: '12/28/2019, 12:00 PM',
+ ran: '2019-12-28 00:00:00.000-05:00',
+ lookedBackTo: '2019-12-28 00:00:00.000-05:00',
status: 'Completed',
response: 'Success',
},
{
id: 21,
rule: 'Automated exfiltration',
- ran: '12/28/2019, 12:00 PM',
- lookedBackTo: '12/28/2019, 12:00 PM',
+ ran: '2019-12-28 00:00:00.000-05:00',
+ lookedBackTo: '2019-12-28 00:00:00.000-05:00',
status: 'Completed',
response: 'Success',
},
@@ -591,7 +596,7 @@ const ActivityMonitor = React.memo(() => {
>
);
});
-AllRules.displayName = 'AllRules';
+ActivityMonitor.displayName = 'ActivityMonitor';
export const RulesComponent = React.memo(() => {
return (
From caf192659e18d769fd3a3be9996a06fde0de4995 Mon Sep 17 00:00:00 2001
From: Michael Marcialis
Date: Mon, 28 Oct 2019 16:29:06 -0400
Subject: [PATCH 32/57] expand table types and values
---
.../pages/detection_engine/rules/index.tsx | 181 ++++++++++++++----
1 file changed, 140 insertions(+), 41 deletions(-)
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
index af3b87404fd17..542f187996722 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
@@ -46,14 +46,20 @@ const dateTimeFormat = (value: string) => {
};
const AllRules = React.memo(() => {
+ interface RuleTypes {
+ href: string;
+ name: string;
+ status: string;
+ }
+
interface ColumnTypes {
id: number;
- rule: string;
+ rule: RuleTypes;
method: string;
severity: string;
lastCompletedRun: string;
lastResponse: string;
- tags: string;
+ tags: string | string[];
activate: boolean;
}
@@ -104,8 +110,10 @@ const AllRules = React.memo(() => {
{
field: 'rule',
name: 'Rule',
- render: (value: string) => (
- {value}
+ render: (value: ColumnTypes['rule']) => (
+ <>
+ {value.name} {value.status}
+ >
),
sortable: true,
truncateText: true,
@@ -119,21 +127,23 @@ const AllRules = React.memo(() => {
{
field: 'severity',
name: 'Severity',
- render: (value: string) => {value},
+ render: (value: ColumnTypes['severity']) => {value},
sortable: true,
truncateText: true,
},
{
field: 'lastCompletedRun',
name: 'Last completed run',
- render: (value: string) => ,
+ render: (value: ColumnTypes['lastCompletedRun']) => (
+
+ ),
sortable: true,
truncateText: true,
},
{
field: 'lastResponse',
name: 'Last response',
- render: (value: string | undefined) => {
+ render: (value: ColumnTypes['lastResponse']) => {
return value === undefined ? (
getEmptyTagValue()
) : (
@@ -154,7 +164,13 @@ const AllRules = React.memo(() => {
{
field: 'tags',
name: 'Tags',
- render: (value: string) => {value},
+ render: (value: ColumnTypes['tags']) => {
+ if (typeof value !== 'string') {
+ return value.map(tag => {tag});
+ } else {
+ return {value};
+ }
+ },
sortable: true,
truncateText: true,
},
@@ -162,28 +178,38 @@ const AllRules = React.memo(() => {
align: 'center',
field: 'activate',
name: 'Activate',
- render: (value: boolean) => ,
+ render: (value: ColumnTypes['activate']) => ,
sortable: true,
+ width: '57px',
},
{
actions,
+ width: '32px',
},
];
const sampleTableData = [
{
id: 1,
- rule: 'Automated exfiltration',
+ rule: {
+ href: '#/detection-engine/rules/rule-details',
+ name: 'Automated exfiltration',
+ status: 'Experimental',
+ },
method: 'Custom query',
severity: 'Medium',
lastCompletedRun: '2019-12-28 00:00:00.000-05:00',
lastResponse: 'Success',
- tags: 'attack.t1234',
+ tags: ['attack.t1234', 'attack.t4321'],
activate: true,
},
{
id: 2,
- rule: 'Automated exfiltration',
+ rule: {
+ href: '#/detection-engine/rules/rule-details',
+ name: 'Automated exfiltration',
+ status: 'Experimental',
+ },
method: 'Custom query',
severity: 'Medium',
lastCompletedRun: '2019-12-28 00:00:00.000-05:00',
@@ -193,7 +219,11 @@ const AllRules = React.memo(() => {
},
{
id: 3,
- rule: 'Automated exfiltration',
+ rule: {
+ href: '#/detection-engine/rules/rule-details',
+ name: 'Automated exfiltration',
+ status: 'Experimental',
+ },
method: 'Custom query',
severity: 'Medium',
lastCompletedRun: '2019-12-28 00:00:00.000-05:00',
@@ -275,12 +305,18 @@ const AllRules = React.memo(() => {
AllRules.displayName = 'AllRules';
const ActivityMonitor = React.memo(() => {
+ interface RuleTypes {
+ href: string;
+ name: string;
+ }
+
interface ColumnTypes {
id: number;
- rule: string;
+ rule: RuleTypes;
ran: string;
lookedBackTo: string;
status: string;
+ response: string | undefined;
}
interface PageTypes {
@@ -311,23 +347,23 @@ const ActivityMonitor = React.memo(() => {
{
field: 'rule',
name: 'Rule',
- render: (value: string) => (
- {value}
- ),
+ render: (value: ColumnTypes['rule']) => {value.name},
sortable: true,
truncateText: true,
},
{
field: 'ran',
name: 'Ran',
- render: (value: string) => ,
+ render: (value: ColumnTypes['ran']) => ,
sortable: true,
truncateText: true,
},
{
field: 'lookedBackTo',
name: 'Looked back to',
- render: (value: string) => ,
+ render: (value: ColumnTypes['lookedBackTo']) => (
+
+ ),
sortable: true,
truncateText: true,
},
@@ -340,7 +376,7 @@ const ActivityMonitor = React.memo(() => {
{
field: 'response',
name: 'Response',
- render: (value: string | undefined) => {
+ render: (value: ColumnTypes['response']) => {
return value === undefined ? (
getEmptyTagValue()
) : (
@@ -367,21 +403,30 @@ const ActivityMonitor = React.memo(() => {
const sampleTableData = [
{
id: 1,
- rule: 'Automated exfiltration',
+ rule: {
+ href: '#/detection-engine/rules/rule-details',
+ name: 'Automated exfiltration',
+ },
ran: '2019-12-28 00:00:00.000-05:00',
lookedBackTo: '2019-12-28 00:00:00.000-05:00',
status: 'Running',
},
{
id: 2,
- rule: 'Automated exfiltration',
+ rule: {
+ href: '#/detection-engine/rules/rule-details',
+ name: 'Automated exfiltration',
+ },
ran: '2019-12-28 00:00:00.000-05:00',
lookedBackTo: '2019-12-28 00:00:00.000-05:00',
status: 'Stopped',
},
{
id: 3,
- rule: 'Automated exfiltration',
+ rule: {
+ href: '#/detection-engine/rules/rule-details',
+ name: 'Automated exfiltration',
+ },
ran: '2019-12-28 00:00:00.000-05:00',
lookedBackTo: '2019-12-28 00:00:00.000-05:00',
status: 'Completed',
@@ -389,7 +434,10 @@ const ActivityMonitor = React.memo(() => {
},
{
id: 4,
- rule: 'Automated exfiltration',
+ rule: {
+ href: '#/detection-engine/rules/rule-details',
+ name: 'Automated exfiltration',
+ },
ran: '2019-12-28 00:00:00.000-05:00',
lookedBackTo: '2019-12-28 00:00:00.000-05:00',
status: 'Completed',
@@ -397,7 +445,10 @@ const ActivityMonitor = React.memo(() => {
},
{
id: 5,
- rule: 'Automated exfiltration',
+ rule: {
+ href: '#/detection-engine/rules/rule-details',
+ name: 'Automated exfiltration',
+ },
ran: '2019-12-28 00:00:00.000-05:00',
lookedBackTo: '2019-12-28 00:00:00.000-05:00',
status: 'Completed',
@@ -405,7 +456,10 @@ const ActivityMonitor = React.memo(() => {
},
{
id: 6,
- rule: 'Automated exfiltration',
+ rule: {
+ href: '#/detection-engine/rules/rule-details',
+ name: 'Automated exfiltration',
+ },
ran: '2019-12-28 00:00:00.000-05:00',
lookedBackTo: '2019-12-28 00:00:00.000-05:00',
status: 'Completed',
@@ -413,7 +467,10 @@ const ActivityMonitor = React.memo(() => {
},
{
id: 7,
- rule: 'Automated exfiltration',
+ rule: {
+ href: '#/detection-engine/rules/rule-details',
+ name: 'Automated exfiltration',
+ },
ran: '2019-12-28 00:00:00.000-05:00',
lookedBackTo: '2019-12-28 00:00:00.000-05:00',
status: 'Completed',
@@ -421,7 +478,10 @@ const ActivityMonitor = React.memo(() => {
},
{
id: 8,
- rule: 'Automated exfiltration',
+ rule: {
+ href: '#/detection-engine/rules/rule-details',
+ name: 'Automated exfiltration',
+ },
ran: '2019-12-28 00:00:00.000-05:00',
lookedBackTo: '2019-12-28 00:00:00.000-05:00',
status: 'Completed',
@@ -429,7 +489,10 @@ const ActivityMonitor = React.memo(() => {
},
{
id: 9,
- rule: 'Automated exfiltration',
+ rule: {
+ href: '#/detection-engine/rules/rule-details',
+ name: 'Automated exfiltration',
+ },
ran: '2019-12-28 00:00:00.000-05:00',
lookedBackTo: '2019-12-28 00:00:00.000-05:00',
status: 'Completed',
@@ -437,7 +500,10 @@ const ActivityMonitor = React.memo(() => {
},
{
id: 10,
- rule: 'Automated exfiltration',
+ rule: {
+ href: '#/detection-engine/rules/rule-details',
+ name: 'Automated exfiltration',
+ },
ran: '2019-12-28 00:00:00.000-05:00',
lookedBackTo: '2019-12-28 00:00:00.000-05:00',
status: 'Completed',
@@ -445,7 +511,10 @@ const ActivityMonitor = React.memo(() => {
},
{
id: 11,
- rule: 'Automated exfiltration',
+ rule: {
+ href: '#/detection-engine/rules/rule-details',
+ name: 'Automated exfiltration',
+ },
ran: '2019-12-28 00:00:00.000-05:00',
lookedBackTo: '2019-12-28 00:00:00.000-05:00',
status: 'Completed',
@@ -453,7 +522,10 @@ const ActivityMonitor = React.memo(() => {
},
{
id: 12,
- rule: 'Automated exfiltration',
+ rule: {
+ href: '#/detection-engine/rules/rule-details',
+ name: 'Automated exfiltration',
+ },
ran: '2019-12-28 00:00:00.000-05:00',
lookedBackTo: '2019-12-28 00:00:00.000-05:00',
status: 'Completed',
@@ -461,7 +533,10 @@ const ActivityMonitor = React.memo(() => {
},
{
id: 13,
- rule: 'Automated exfiltration',
+ rule: {
+ href: '#/detection-engine/rules/rule-details',
+ name: 'Automated exfiltration',
+ },
ran: '2019-12-28 00:00:00.000-05:00',
lookedBackTo: '2019-12-28 00:00:00.000-05:00',
status: 'Completed',
@@ -469,7 +544,10 @@ const ActivityMonitor = React.memo(() => {
},
{
id: 14,
- rule: 'Automated exfiltration',
+ rule: {
+ href: '#/detection-engine/rules/rule-details',
+ name: 'Automated exfiltration',
+ },
ran: '2019-12-28 00:00:00.000-05:00',
lookedBackTo: '2019-12-28 00:00:00.000-05:00',
status: 'Completed',
@@ -477,7 +555,10 @@ const ActivityMonitor = React.memo(() => {
},
{
id: 15,
- rule: 'Automated exfiltration',
+ rule: {
+ href: '#/detection-engine/rules/rule-details',
+ name: 'Automated exfiltration',
+ },
ran: '2019-12-28 00:00:00.000-05:00',
lookedBackTo: '2019-12-28 00:00:00.000-05:00',
status: 'Completed',
@@ -485,7 +566,10 @@ const ActivityMonitor = React.memo(() => {
},
{
id: 16,
- rule: 'Automated exfiltration',
+ rule: {
+ href: '#/detection-engine/rules/rule-details',
+ name: 'Automated exfiltration',
+ },
ran: '2019-12-28 00:00:00.000-05:00',
lookedBackTo: '2019-12-28 00:00:00.000-05:00',
status: 'Completed',
@@ -493,7 +577,10 @@ const ActivityMonitor = React.memo(() => {
},
{
id: 17,
- rule: 'Automated exfiltration',
+ rule: {
+ href: '#/detection-engine/rules/rule-details',
+ name: 'Automated exfiltration',
+ },
ran: '2019-12-28 00:00:00.000-05:00',
lookedBackTo: '2019-12-28 00:00:00.000-05:00',
status: 'Completed',
@@ -501,7 +588,10 @@ const ActivityMonitor = React.memo(() => {
},
{
id: 18,
- rule: 'Automated exfiltration',
+ rule: {
+ href: '#/detection-engine/rules/rule-details',
+ name: 'Automated exfiltration',
+ },
ran: '2019-12-28 00:00:00.000-05:00',
lookedBackTo: '2019-12-28 00:00:00.000-05:00',
status: 'Completed',
@@ -509,7 +599,10 @@ const ActivityMonitor = React.memo(() => {
},
{
id: 19,
- rule: 'Automated exfiltration',
+ rule: {
+ href: '#/detection-engine/rules/rule-details',
+ name: 'Automated exfiltration',
+ },
ran: '2019-12-28 00:00:00.000-05:00',
lookedBackTo: '2019-12-28 00:00:00.000-05:00',
status: 'Completed',
@@ -517,7 +610,10 @@ const ActivityMonitor = React.memo(() => {
},
{
id: 20,
- rule: 'Automated exfiltration',
+ rule: {
+ href: '#/detection-engine/rules/rule-details',
+ name: 'Automated exfiltration',
+ },
ran: '2019-12-28 00:00:00.000-05:00',
lookedBackTo: '2019-12-28 00:00:00.000-05:00',
status: 'Completed',
@@ -525,7 +621,10 @@ const ActivityMonitor = React.memo(() => {
},
{
id: 21,
- rule: 'Automated exfiltration',
+ rule: {
+ href: '#/detection-engine/rules/rule-details',
+ name: 'Automated exfiltration',
+ },
ran: '2019-12-28 00:00:00.000-05:00',
lookedBackTo: '2019-12-28 00:00:00.000-05:00',
status: 'Completed',
From e79634c3499a5d532acbaee2d5d4c8b10f0d93be Mon Sep 17 00:00:00 2001
From: Michael Marcialis
Date: Tue, 29 Oct 2019 12:22:57 -0400
Subject: [PATCH 33/57] fleshing out all rules table
---
.../pages/detection_engine/rules/index.tsx | 444 ++++++++++++++++--
1 file changed, 396 insertions(+), 48 deletions(-)
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
index 542f187996722..e6f01dead9a79 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
@@ -4,6 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
+import euiLightVars from '@elastic/eui/dist/eui_theme_light.json';
import {
EuiBadge,
EuiBasicTable,
@@ -40,7 +41,7 @@ import {
import { SpyRoute } from '../../../utils/route/spy_routes';
import * as i18n from './translations';
-// Will need to change this to get the current datetime format from Kibana settings.
+// Michael: Will need to change this to get the current datetime format from Kibana settings.
const dateTimeFormat = (value: string) => {
return moment(value).format('M/D/YYYY, h:mm A');
};
@@ -52,13 +53,18 @@ const AllRules = React.memo(() => {
status: string;
}
+ interface LastResponseTypes {
+ type: string;
+ message?: string;
+ }
+
interface ColumnTypes {
id: number;
rule: RuleTypes;
method: string;
severity: string;
lastCompletedRun: string;
- lastResponse: string;
+ lastResponse: LastResponseTypes;
tags: string | string[];
activate: boolean;
}
@@ -75,48 +81,51 @@ const AllRules = React.memo(() => {
const actions = [
{
- name: 'Edit rule settings',
description: 'Edit rule settings',
icon: 'visControls',
+ name: 'Edit rule settings',
onClick: () => {},
},
{
- name: 'Run rule manually…',
description: 'Run rule manually…',
icon: 'play',
+ name: 'Run rule manually…',
onClick: () => {},
},
{
- name: 'Duplicate rule…',
description: 'Duplicate rule…',
icon: 'copy',
+ name: 'Duplicate rule…',
onClick: () => {},
},
{
- name: 'Export rule',
description: 'Export rule',
- icon: 'export',
+ icon: 'exportAction',
+ name: 'Export rule',
onClick: () => {},
},
{
- name: 'Delete rule…',
description: 'Delete rule…',
icon: 'trash',
+ name: 'Delete rule…',
onClick: () => {},
},
];
+ // Michael: Are we able to do custom, in-table-header filters, as shown in my wireframes?
const columns = [
{
field: 'rule',
name: 'Rule',
render: (value: ColumnTypes['rule']) => (
- <>
- {value.name} {value.status}
- >
+
+ {value.name}{' '}
+ {value.status}
+
),
sortable: true,
truncateText: true,
+ width: '24%',
},
{
field: 'method',
@@ -127,18 +136,37 @@ const AllRules = React.memo(() => {
{
field: 'severity',
name: 'Severity',
- render: (value: ColumnTypes['severity']) => {value},
+ render: (value: ColumnTypes['severity']) => (
+
+ {value}
+
+ ),
sortable: true,
truncateText: true,
},
{
field: 'lastCompletedRun',
name: 'Last completed run',
- render: (value: ColumnTypes['lastCompletedRun']) => (
-
- ),
+ render: (value: ColumnTypes['lastCompletedRun']) => {
+ return value === undefined ? (
+ getEmptyTagValue()
+ ) : (
+
+ );
+ },
sortable: true,
truncateText: true,
+ width: '16%',
},
{
field: 'lastResponse',
@@ -148,12 +176,12 @@ const AllRules = React.memo(() => {
getEmptyTagValue()
) : (
<>
- {value === 'Fail' ? (
+ {value.type === 'Fail' ? (
- {value}
+ {value.type}
) : (
- {value}
+ {value.type}
)}
>
);
@@ -164,15 +192,22 @@ const AllRules = React.memo(() => {
{
field: 'tags',
name: 'Tags',
- render: (value: ColumnTypes['tags']) => {
- if (typeof value !== 'string') {
- return value.map(tag => {tag});
- } else {
- return {value};
- }
- },
+ render: (value: ColumnTypes['tags']) => (
+
+ {typeof value !== 'string' ? (
+ <>
+ {value.map(tag => (
+ {tag}
+ ))}
+ >
+ ) : (
+ {value}
+ )}
+
+ ),
sortable: true,
truncateText: true,
+ width: '20%',
},
{
align: 'center',
@@ -180,11 +215,11 @@ const AllRules = React.memo(() => {
name: 'Activate',
render: (value: ColumnTypes['activate']) => ,
sortable: true,
- width: '57px',
+ width: '65px',
},
{
actions,
- width: '32px',
+ width: '40px',
},
];
@@ -197,9 +232,11 @@ const AllRules = React.memo(() => {
status: 'Experimental',
},
method: 'Custom query',
- severity: 'Medium',
+ severity: 'Low',
lastCompletedRun: '2019-12-28 00:00:00.000-05:00',
- lastResponse: 'Success',
+ lastResponse: {
+ type: 'Success',
+ },
tags: ['attack.t1234', 'attack.t4321'],
activate: true,
},
@@ -213,7 +250,10 @@ const AllRules = React.memo(() => {
method: 'Custom query',
severity: 'Medium',
lastCompletedRun: '2019-12-28 00:00:00.000-05:00',
- lastResponse: 'Fail',
+ lastResponse: {
+ type: 'Fail',
+ message: 'Full fail message here.',
+ },
tags: 'attack.t1234',
activate: true,
},
@@ -225,18 +265,304 @@ const AllRules = React.memo(() => {
status: 'Experimental',
},
method: 'Custom query',
- severity: 'Medium',
- lastCompletedRun: '2019-12-28 00:00:00.000-05:00',
- lastResponse: 'Success',
+ severity: 'High',
tags: 'attack.t1234',
activate: false,
},
+ {
+ id: 4,
+ rule: {
+ href: '#/detection-engine/rules/rule-details',
+ name: 'Automated exfiltration',
+ status: 'Experimental',
+ },
+ method: 'Custom query',
+ severity: 'Critical',
+ lastCompletedRun: '2019-12-28 00:00:00.000-05:00',
+ lastResponse: {
+ type: 'Success',
+ },
+ tags: 'attack.t1234',
+ activate: true,
+ },
+ {
+ id: 5,
+ rule: {
+ href: '#/detection-engine/rules/rule-details',
+ name: 'Automated exfiltration',
+ status: 'Experimental',
+ },
+ method: 'Custom query',
+ severity: 'Critical',
+ lastCompletedRun: '2019-12-28 00:00:00.000-05:00',
+ lastResponse: {
+ type: 'Success',
+ },
+ tags: 'attack.t1234',
+ activate: true,
+ },
+ {
+ id: 6,
+ rule: {
+ href: '#/detection-engine/rules/rule-details',
+ name: 'Automated exfiltration',
+ status: 'Experimental',
+ },
+ method: 'Custom query',
+ severity: 'Critical',
+ lastCompletedRun: '2019-12-28 00:00:00.000-05:00',
+ lastResponse: {
+ type: 'Success',
+ },
+ tags: 'attack.t1234',
+ activate: true,
+ },
+ {
+ id: 7,
+ rule: {
+ href: '#/detection-engine/rules/rule-details',
+ name: 'Automated exfiltration',
+ status: 'Experimental',
+ },
+ method: 'Custom query',
+ severity: 'Critical',
+ lastCompletedRun: '2019-12-28 00:00:00.000-05:00',
+ lastResponse: {
+ type: 'Success',
+ },
+ tags: 'attack.t1234',
+ activate: true,
+ },
+ {
+ id: 8,
+ rule: {
+ href: '#/detection-engine/rules/rule-details',
+ name: 'Automated exfiltration',
+ status: 'Experimental',
+ },
+ method: 'Custom query',
+ severity: 'Critical',
+ lastCompletedRun: '2019-12-28 00:00:00.000-05:00',
+ lastResponse: {
+ type: 'Success',
+ },
+ tags: 'attack.t1234',
+ activate: true,
+ },
+ {
+ id: 9,
+ rule: {
+ href: '#/detection-engine/rules/rule-details',
+ name: 'Automated exfiltration',
+ status: 'Experimental',
+ },
+ method: 'Custom query',
+ severity: 'Critical',
+ lastCompletedRun: '2019-12-28 00:00:00.000-05:00',
+ lastResponse: {
+ type: 'Success',
+ },
+ tags: 'attack.t1234',
+ activate: true,
+ },
+ {
+ id: 10,
+ rule: {
+ href: '#/detection-engine/rules/rule-details',
+ name: 'Automated exfiltration',
+ status: 'Experimental',
+ },
+ method: 'Custom query',
+ severity: 'Critical',
+ lastCompletedRun: '2019-12-28 00:00:00.000-05:00',
+ lastResponse: {
+ type: 'Success',
+ },
+ tags: 'attack.t1234',
+ activate: true,
+ },
+ {
+ id: 11,
+ rule: {
+ href: '#/detection-engine/rules/rule-details',
+ name: 'Automated exfiltration',
+ status: 'Experimental',
+ },
+ method: 'Custom query',
+ severity: 'Critical',
+ lastCompletedRun: '2019-12-28 00:00:00.000-05:00',
+ lastResponse: {
+ type: 'Success',
+ },
+ tags: 'attack.t1234',
+ activate: true,
+ },
+ {
+ id: 12,
+ rule: {
+ href: '#/detection-engine/rules/rule-details',
+ name: 'Automated exfiltration',
+ status: 'Experimental',
+ },
+ method: 'Custom query',
+ severity: 'Critical',
+ lastCompletedRun: '2019-12-28 00:00:00.000-05:00',
+ lastResponse: {
+ type: 'Success',
+ },
+ tags: 'attack.t1234',
+ activate: true,
+ },
+ {
+ id: 13,
+ rule: {
+ href: '#/detection-engine/rules/rule-details',
+ name: 'Automated exfiltration',
+ status: 'Experimental',
+ },
+ method: 'Custom query',
+ severity: 'Critical',
+ lastCompletedRun: '2019-12-28 00:00:00.000-05:00',
+ lastResponse: {
+ type: 'Success',
+ },
+ tags: 'attack.t1234',
+ activate: true,
+ },
+ {
+ id: 14,
+ rule: {
+ href: '#/detection-engine/rules/rule-details',
+ name: 'Automated exfiltration',
+ status: 'Experimental',
+ },
+ method: 'Custom query',
+ severity: 'Critical',
+ lastCompletedRun: '2019-12-28 00:00:00.000-05:00',
+ lastResponse: {
+ type: 'Success',
+ },
+ tags: 'attack.t1234',
+ activate: true,
+ },
+ {
+ id: 15,
+ rule: {
+ href: '#/detection-engine/rules/rule-details',
+ name: 'Automated exfiltration',
+ status: 'Experimental',
+ },
+ method: 'Custom query',
+ severity: 'Critical',
+ lastCompletedRun: '2019-12-28 00:00:00.000-05:00',
+ lastResponse: {
+ type: 'Success',
+ },
+ tags: 'attack.t1234',
+ activate: true,
+ },
+ {
+ id: 16,
+ rule: {
+ href: '#/detection-engine/rules/rule-details',
+ name: 'Automated exfiltration',
+ status: 'Experimental',
+ },
+ method: 'Custom query',
+ severity: 'Critical',
+ lastCompletedRun: '2019-12-28 00:00:00.000-05:00',
+ lastResponse: {
+ type: 'Success',
+ },
+ tags: 'attack.t1234',
+ activate: true,
+ },
+ {
+ id: 17,
+ rule: {
+ href: '#/detection-engine/rules/rule-details',
+ name: 'Automated exfiltration',
+ status: 'Experimental',
+ },
+ method: 'Custom query',
+ severity: 'Critical',
+ lastCompletedRun: '2019-12-28 00:00:00.000-05:00',
+ lastResponse: {
+ type: 'Success',
+ },
+ tags: 'attack.t1234',
+ activate: true,
+ },
+ {
+ id: 18,
+ rule: {
+ href: '#/detection-engine/rules/rule-details',
+ name: 'Automated exfiltration',
+ status: 'Experimental',
+ },
+ method: 'Custom query',
+ severity: 'Critical',
+ lastCompletedRun: '2019-12-28 00:00:00.000-05:00',
+ lastResponse: {
+ type: 'Success',
+ },
+ tags: 'attack.t1234',
+ activate: true,
+ },
+ {
+ id: 19,
+ rule: {
+ href: '#/detection-engine/rules/rule-details',
+ name: 'Automated exfiltration',
+ status: 'Experimental',
+ },
+ method: 'Custom query',
+ severity: 'Critical',
+ lastCompletedRun: '2019-12-28 00:00:00.000-05:00',
+ lastResponse: {
+ type: 'Success',
+ },
+ tags: 'attack.t1234',
+ activate: true,
+ },
+ {
+ id: 20,
+ rule: {
+ href: '#/detection-engine/rules/rule-details',
+ name: 'Automated exfiltration',
+ status: 'Experimental',
+ },
+ method: 'Custom query',
+ severity: 'Critical',
+ lastCompletedRun: '2019-12-28 00:00:00.000-05:00',
+ lastResponse: {
+ type: 'Success',
+ },
+ tags: 'attack.t1234',
+ activate: true,
+ },
+ {
+ id: 21,
+ rule: {
+ href: '#/detection-engine/rules/rule-details',
+ name: 'Automated exfiltration',
+ status: 'Experimental',
+ },
+ method: 'Custom query',
+ severity: 'Critical',
+ lastCompletedRun: '2019-12-28 00:00:00.000-05:00',
+ lastResponse: {
+ type: 'Success',
+ },
+ tags: 'attack.t1234',
+ activate: true,
+ },
];
const [itemsTotalState, setItemsTotalState] = useState(sampleTableData.length);
const [pageState, setPageState] = useState({ index: 0, size: 20 });
const [selectedState, setSelectedState] = useState([]);
- const [sortState, setSortState] = useState({ field: 'ran', direction: 'desc' });
+ const [sortState, setSortState] = useState({ field: 'rule', direction: 'asc' });
return (
<>
@@ -273,7 +599,7 @@ const AllRules = React.memo(() => {
{
direction: string;
}
+ // const actions = [
+ // {
+ // render: (item: ColumnTypes) => {
+ // if (item.status === 'Running') {
+ // return {'Stop'};
+ // } else if (item.status === 'Stopped') {
+ // return {'Resume'};
+ // } else {
+ // return <>{''}>;
+ // }
+ // },
+ // },
+ // ];
+
const actions = [
{
- render: (item: ColumnTypes) => {
- if (item.status === 'Running') {
- return {'Stop'};
- } else if (item.status === 'Stopped') {
- return {'Resume'};
- } else {
- return <>{''}>;
- }
- },
+ available: (item: ColumnTypes) => item.status === 'Running',
+ description: 'Stop',
+ icon: 'stop',
+ isPrimary: true,
+ name: 'Stop',
+ onClick: () => {},
+ type: 'icon',
+ },
+ {
+ available: (item: ColumnTypes) => item.status === 'Stopped',
+ description: 'Resume',
+ icon: 'play',
+ isPrimary: true,
+ name: 'Resume',
+ onClick: () => {},
+ type: 'icon',
},
];
+ // Michael: Are we able to do custom, in-table-header filters, as shown in my wireframes?
const columns = [
{
field: 'rule',
@@ -383,7 +731,7 @@ const ActivityMonitor = React.memo(() => {
<>
{value === 'Fail' ? (
- {value}
+ {value}
) : (
{value}
@@ -396,7 +744,7 @@ const ActivityMonitor = React.memo(() => {
},
{
actions,
- width: '70px',
+ width: '40px',
},
];
@@ -664,8 +1012,8 @@ const ActivityMonitor = React.memo(() => {
Date: Tue, 29 Oct 2019 14:00:03 -0400
Subject: [PATCH 34/57] rough out rule details
---
.../detection_engine/detection_engine.tsx | 4 +-
.../detection_engine/rule_details/index.tsx | 496 +++++++++++++++++-
.../pages/detection_engine/rules/index.tsx | 5 +-
3 files changed, 496 insertions(+), 9 deletions(-)
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
index be85a616df9c4..273b962d6cac9 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
@@ -87,7 +87,7 @@ const OpenSignals = React.memo(() => {
- {/* Open signals datagrid here. Talk to Chandler Prall about possibility of early access. If not possible, use basic table. */}
+ {/* Michael: Open signals datagrid here. Talk to Chandler Prall about possibility of early access. If not possible, use basic table. */}
>
);
});
@@ -117,7 +117,7 @@ const ClosedSignals = React.memo(() => {
- {/* Closed signals datagrid here. Talk to Chandler Prall about possibility of early access. If not possible, use basic table. */}
+ {/* Michael: Closed signals datagrid here. Talk to Chandler Prall about possibility of early access. If not possible, use basic table. */}
>
);
});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.tsx
index 3e2f59da5fcdb..89fd4bd3fd6fc 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.tsx
@@ -4,16 +4,469 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { EuiButton, EuiButtonIcon, EuiFlexGroup, EuiFlexItem, EuiSwitch } from '@elastic/eui';
-import React from 'react';
+import euiLightVars from '@elastic/eui/dist/eui_theme_light.json';
+import {
+ EuiBadge,
+ EuiBasicTable,
+ EuiButton,
+ EuiButtonIcon,
+ EuiFieldSearch,
+ EuiFilterButton,
+ EuiFilterGroup,
+ EuiFlexGroup,
+ EuiFlexItem,
+ EuiHealth,
+ EuiIconTip,
+ EuiLink,
+ EuiPanel,
+ EuiSpacer,
+ EuiSwitch,
+ EuiTabbedContent,
+ EuiTextColor,
+} from '@elastic/eui';
+import moment from 'moment';
+import React, { useState } from 'react';
import { StickyContainer } from 'react-sticky';
+import { getEmptyTagValue } from '../../../components/empty_value';
import { FiltersGlobal } from '../../../components/filters_global';
import { HeaderPage } from '../../../components/header_page';
+import { HeaderSection } from '../../../components/header_section';
+import {
+ UtilityBar,
+ UtilityBarAction,
+ UtilityBarGroup,
+ UtilityBarSection,
+ UtilityBarText,
+} from '../../../components/utility_bar';
import { SpyRoute } from '../../../utils/route/spy_routes';
import { DetectionEngineKql } from '../kql';
import * as i18n from './translations';
+// Michael: Will need to change this to get the current datetime format from Kibana settings.
+const dateTimeFormat = (value: string) => {
+ return moment(value).format('M/D/YYYY, h:mm A');
+};
+
+const OpenSignals = React.memo(() => {
+ return (
+ <>
+
+
+
+ {'Showing: 439 signals'}
+
+
+
+ {'Selected: 20 signals'}
+
+ {'Batch actions context menu here.'}}
+ >
+ {'Batch actions'}
+
+
+
+ {'Select all signals on all pages'}
+
+
+
+
+ {'Clear 7 filters'}
+
+ {'Clear aggregation'}
+
+
+
+
+
+ {'Customize columns context menu here.'}}
+ >
+ {'Customize columns'}
+
+
+ {'Aggregate data'}
+
+
+
+
+ {/* Michael: Open signals datagrid here. Talk to Chandler Prall about possibility of early access. If not possible, use basic table. */}
+ >
+ );
+});
+
+const ClosedSignals = React.memo(() => {
+ return (
+ <>
+
+
+
+ {'Showing: 439 signals'}
+
+
+
+
+
+ {'Customize columns context menu here.'}}
+ >
+ {'Customize columns'}
+
+
+ {'Aggregate data'}
+
+
+
+
+ {/* Michael: Closed signals datagrid here. Talk to Chandler Prall about possibility of early access. If not possible, use basic table. */}
+ >
+ );
+});
+
+const Signals = React.memo(() => {
+ const filterGroupOptions = ['open', 'closed'];
+ const [filterGroupState, setFilterGroupState] = useState(filterGroupOptions[0]);
+
+ return (
+ <>
+
+
+
+
+
+ setFilterGroupState(filterGroupOptions[0])}
+ withNext
+ >
+ {'Open signals'}
+
+
+ setFilterGroupState(filterGroupOptions[1])}
+ >
+ {'Closed signals'}
+
+
+
+
+ {filterGroupState === filterGroupOptions[0] ? : }
+
+ >
+ );
+});
+Signals.displayName = 'Signals';
+
+const ActivityMonitor = React.memo(() => {
+ interface ColumnTypes {
+ id: number;
+ ran: string;
+ lookedBackTo: string;
+ status: string;
+ response: string | undefined;
+ }
+
+ interface PageTypes {
+ index: number;
+ size: number;
+ }
+
+ interface SortTypes {
+ field: string;
+ direction: string;
+ }
+
+ const actions = [
+ {
+ available: (item: ColumnTypes) => item.status === 'Running',
+ description: 'Stop',
+ icon: 'stop',
+ isPrimary: true,
+ name: 'Stop',
+ onClick: () => {},
+ type: 'icon',
+ },
+ {
+ available: (item: ColumnTypes) => item.status === 'Stopped',
+ description: 'Resume',
+ icon: 'play',
+ isPrimary: true,
+ name: 'Resume',
+ onClick: () => {},
+ type: 'icon',
+ },
+ ];
+
+ // Michael: Are we able to do custom, in-table-header filters, as shown in my wireframes?
+ const columns = [
+ {
+ field: 'ran',
+ name: 'Ran',
+ render: (value: ColumnTypes['ran']) => ,
+ sortable: true,
+ truncateText: true,
+ },
+ {
+ field: 'lookedBackTo',
+ name: 'Looked back to',
+ render: (value: ColumnTypes['lookedBackTo']) => (
+
+ ),
+ sortable: true,
+ truncateText: true,
+ },
+ {
+ field: 'status',
+ name: 'Status',
+ sortable: true,
+ truncateText: true,
+ },
+ {
+ field: 'response',
+ name: 'Response',
+ render: (value: ColumnTypes['response']) => {
+ return value === undefined ? (
+ getEmptyTagValue()
+ ) : (
+ <>
+ {value === 'Fail' ? (
+
+ {value}
+
+ ) : (
+ {value}
+ )}
+ >
+ );
+ },
+ sortable: true,
+ truncateText: true,
+ },
+ {
+ actions,
+ width: '40px',
+ },
+ ];
+
+ const sampleTableData = [
+ {
+ id: 1,
+ ran: '2019-12-28 00:00:00.000-05:00',
+ lookedBackTo: '2019-12-28 00:00:00.000-05:00',
+ status: 'Running',
+ },
+ {
+ id: 2,
+ ran: '2019-12-28 00:00:00.000-05:00',
+ lookedBackTo: '2019-12-28 00:00:00.000-05:00',
+ status: 'Stopped',
+ },
+ {
+ id: 3,
+ ran: '2019-12-28 00:00:00.000-05:00',
+ lookedBackTo: '2019-12-28 00:00:00.000-05:00',
+ status: 'Completed',
+ response: 'Fail',
+ },
+ {
+ id: 4,
+ ran: '2019-12-28 00:00:00.000-05:00',
+ lookedBackTo: '2019-12-28 00:00:00.000-05:00',
+ status: 'Completed',
+ response: 'Success',
+ },
+ {
+ id: 5,
+ ran: '2019-12-28 00:00:00.000-05:00',
+ lookedBackTo: '2019-12-28 00:00:00.000-05:00',
+ status: 'Completed',
+ response: 'Success',
+ },
+ {
+ id: 6,
+ ran: '2019-12-28 00:00:00.000-05:00',
+ lookedBackTo: '2019-12-28 00:00:00.000-05:00',
+ status: 'Completed',
+ response: 'Success',
+ },
+ {
+ id: 7,
+ ran: '2019-12-28 00:00:00.000-05:00',
+ lookedBackTo: '2019-12-28 00:00:00.000-05:00',
+ status: 'Completed',
+ response: 'Success',
+ },
+ {
+ id: 8,
+ ran: '2019-12-28 00:00:00.000-05:00',
+ lookedBackTo: '2019-12-28 00:00:00.000-05:00',
+ status: 'Completed',
+ response: 'Success',
+ },
+ {
+ id: 9,
+ ran: '2019-12-28 00:00:00.000-05:00',
+ lookedBackTo: '2019-12-28 00:00:00.000-05:00',
+ status: 'Completed',
+ response: 'Success',
+ },
+ {
+ id: 10,
+ ran: '2019-12-28 00:00:00.000-05:00',
+ lookedBackTo: '2019-12-28 00:00:00.000-05:00',
+ status: 'Completed',
+ response: 'Success',
+ },
+ {
+ id: 11,
+ ran: '2019-12-28 00:00:00.000-05:00',
+ lookedBackTo: '2019-12-28 00:00:00.000-05:00',
+ status: 'Completed',
+ response: 'Success',
+ },
+ {
+ id: 12,
+ ran: '2019-12-28 00:00:00.000-05:00',
+ lookedBackTo: '2019-12-28 00:00:00.000-05:00',
+ status: 'Completed',
+ response: 'Success',
+ },
+ {
+ id: 13,
+ ran: '2019-12-28 00:00:00.000-05:00',
+ lookedBackTo: '2019-12-28 00:00:00.000-05:00',
+ status: 'Completed',
+ response: 'Success',
+ },
+ {
+ id: 14,
+ ran: '2019-12-28 00:00:00.000-05:00',
+ lookedBackTo: '2019-12-28 00:00:00.000-05:00',
+ status: 'Completed',
+ response: 'Success',
+ },
+ {
+ id: 15,
+ ran: '2019-12-28 00:00:00.000-05:00',
+ lookedBackTo: '2019-12-28 00:00:00.000-05:00',
+ status: 'Completed',
+ response: 'Success',
+ },
+ {
+ id: 16,
+ ran: '2019-12-28 00:00:00.000-05:00',
+ lookedBackTo: '2019-12-28 00:00:00.000-05:00',
+ status: 'Completed',
+ response: 'Success',
+ },
+ {
+ id: 17,
+ ran: '2019-12-28 00:00:00.000-05:00',
+ lookedBackTo: '2019-12-28 00:00:00.000-05:00',
+ status: 'Completed',
+ response: 'Success',
+ },
+ {
+ id: 18,
+ ran: '2019-12-28 00:00:00.000-05:00',
+ lookedBackTo: '2019-12-28 00:00:00.000-05:00',
+ status: 'Completed',
+ response: 'Success',
+ },
+ {
+ id: 19,
+ ran: '2019-12-28 00:00:00.000-05:00',
+ lookedBackTo: '2019-12-28 00:00:00.000-05:00',
+ status: 'Completed',
+ response: 'Success',
+ },
+ {
+ id: 20,
+ ran: '2019-12-28 00:00:00.000-05:00',
+ lookedBackTo: '2019-12-28 00:00:00.000-05:00',
+ status: 'Completed',
+ response: 'Success',
+ },
+ {
+ id: 21,
+ ran: '2019-12-28 00:00:00.000-05:00',
+ lookedBackTo: '2019-12-28 00:00:00.000-05:00',
+ status: 'Completed',
+ response: 'Success',
+ },
+ ];
+
+ const [itemsTotalState, setItemsTotalState] = useState(sampleTableData.length);
+ const [pageState, setPageState] = useState({ index: 0, size: 20 });
+ const [selectedState, setSelectedState] = useState([]);
+ const [sortState, setSortState] = useState({ field: 'ran', direction: 'desc' });
+
+ return (
+ <>
+
+
+
+
+
+
+
+
+ {'Showing: 39 activites'}
+
+
+
+ {'Selected: 2 activities'}
+
+ {'Stop selected'}
+
+
+
+ {'Clear 7 filters'}
+
+
+
+
+ {
+ setPageState(page);
+ setSortState(sort);
+ }}
+ pagination={{
+ pageIndex: pageState.index,
+ pageSize: pageState.size,
+ totalItemCount: itemsTotalState,
+ pageSizeOptions: [5, 10, 20],
+ }}
+ selection={{
+ selectable: (item: ColumnTypes) => item.status !== 'Completed',
+ selectableMessage: (selectable: boolean) =>
+ selectable ? undefined : 'Completed runs cannot be acted upon',
+ onSelectionChange: (selectedItems: ColumnTypes[]) => {
+ setSelectedState(selectedItems);
+ },
+ }}
+ sorting={{
+ sort: sortState,
+ }}
+ />
+
+ >
+ );
+});
+ActivityMonitor.displayName = 'ActivityMonitor';
+
export const RuleDetailsComponent = React.memo(() => {
return (
<>
@@ -48,10 +501,47 @@ export const RuleDetailsComponent = React.memo(() => {
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ,
+ },
+ {
+ id: 'tabActivityMonitor',
+ name: 'Activity monitor',
+ content: ,
+ },
+ ]}
+ />
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
index e6f01dead9a79..8b3a21ada9c2b 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
@@ -9,8 +9,6 @@ import {
EuiBadge,
EuiBasicTable,
EuiButton,
- EuiButtonIcon,
- EuiCheckbox,
EuiFieldSearch,
EuiFlexGroup,
EuiFlexItem,
@@ -25,12 +23,11 @@ import {
} from '@elastic/eui';
import moment from 'moment';
import React, { useState } from 'react';
-import styled, { css } from 'styled-components';
import { getEmptyTagValue } from '../../../components/empty_value';
import { HeaderPage } from '../../../components/header_page';
import { HeaderSection } from '../../../components/header_section';
-import { LinkIcon } from '../../../components/link_icon';
+// import { LinkIcon } from '../../../components/link_icon';
import {
UtilityBar,
UtilityBarAction,
From 0f645e60bc4e3e0b0a8c847d82649ad89a525e3f Mon Sep 17 00:00:00 2001
From: Michael Marcialis
Date: Tue, 29 Oct 2019 14:25:26 -0400
Subject: [PATCH 35/57] move chart to separate comp
---
.../histogram_signals/index.test.tsx | 27 ++++++
.../histogram_signals/index.tsx | 87 +++++++++++++++++++
.../histogram_signals/translations.ts | 11 +++
.../detection_engine/detection_engine.tsx | 73 +---------------
.../detection_engine/rule_details/index.tsx | 32 +++++--
5 files changed, 154 insertions(+), 76 deletions(-)
create mode 100644 x-pack/legacy/plugins/siem/public/components/page/detection_engine/histogram_signals/index.test.tsx
create mode 100644 x-pack/legacy/plugins/siem/public/components/page/detection_engine/histogram_signals/index.tsx
create mode 100644 x-pack/legacy/plugins/siem/public/components/page/detection_engine/histogram_signals/translations.ts
diff --git a/x-pack/legacy/plugins/siem/public/components/page/detection_engine/histogram_signals/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/page/detection_engine/histogram_signals/index.test.tsx
new file mode 100644
index 0000000000000..932c8770edba7
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/components/page/detection_engine/histogram_signals/index.test.tsx
@@ -0,0 +1,27 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { shallow } from 'enzyme';
+import toJson from 'enzyme-to-json';
+import React from 'react';
+
+import '../../mock/ui_settings';
+import { TestProviders } from '../../../../mock';
+import { HistogramSignals } from './index';
+
+jest.mock('../../../../lib/settings/use_kibana_ui_setting');
+
+describe('HistogramSignals', () => {
+ test('it renders', () => {
+ const wrapper = shallow(
+
+
+
+ );
+
+ expect(toJson(wrapper)).toMatchSnapshot();
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/components/page/detection_engine/histogram_signals/index.tsx b/x-pack/legacy/plugins/siem/public/components/page/detection_engine/histogram_signals/index.tsx
new file mode 100644
index 0000000000000..29a979f626755
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/components/page/detection_engine/histogram_signals/index.tsx
@@ -0,0 +1,87 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import {
+ Axis,
+ Chart,
+ HistogramBarSeries,
+ Settings,
+ getAxisId,
+ getSpecId,
+ niceTimeFormatByDay,
+ timeFormatter,
+} from '@elastic/charts';
+import React from 'react';
+import { npStart } from 'ui/new_platform';
+
+import * as i18n from './translations';
+
+export const HistogramSignals = React.memo(() => {
+ const sampleChartData = [
+ { x: 1571090784000, y: 2, a: 'a' },
+ { x: 1571090784000, y: 2, b: 'b' },
+ { x: 1571093484000, y: 7, a: 'a' },
+ { x: 1571096184000, y: 3, a: 'a' },
+ { x: 1571098884000, y: 2, a: 'a' },
+ { x: 1571101584000, y: 7, a: 'a' },
+ { x: 1571104284000, y: 3, a: 'a' },
+ { x: 1571106984000, y: 2, a: 'a' },
+ { x: 1571109684000, y: 7, a: 'a' },
+ { x: 1571112384000, y: 3, a: 'a' },
+ { x: 1571115084000, y: 2, a: 'a' },
+ { x: 1571117784000, y: 7, a: 'a' },
+ { x: 1571120484000, y: 3, a: 'a' },
+ { x: 1571123184000, y: 2, a: 'a' },
+ { x: 1571125884000, y: 7, a: 'a' },
+ { x: 1571128584000, y: 3, a: 'a' },
+ { x: 1571131284000, y: 2, a: 'a' },
+ { x: 1571133984000, y: 7, a: 'a' },
+ { x: 1571136684000, y: 3, a: 'a' },
+ { x: 1571139384000, y: 2, a: 'a' },
+ { x: 1571142084000, y: 7, a: 'a' },
+ { x: 1571144784000, y: 3, a: 'a' },
+ { x: 1571147484000, y: 2, a: 'a' },
+ { x: 1571150184000, y: 7, a: 'a' },
+ { x: 1571152884000, y: 3, a: 'a' },
+ { x: 1571155584000, y: 2, a: 'a' },
+ { x: 1571158284000, y: 7, a: 'a' },
+ { x: 1571160984000, y: 3, a: 'a' },
+ { x: 1571163684000, y: 2, a: 'a' },
+ { x: 1571166384000, y: 7, a: 'a' },
+ { x: 1571169084000, y: 3, a: 'a' },
+ { x: 1571171784000, y: 2, a: 'a' },
+ { x: 1571174484000, y: 7, a: 'a' },
+ ];
+
+ return (
+
+
+
+
+
+
+
+
+
+ );
+});
+HistogramSignals.displayName = 'HistogramSignals';
diff --git a/x-pack/legacy/plugins/siem/public/components/page/detection_engine/histogram_signals/translations.ts b/x-pack/legacy/plugins/siem/public/components/page/detection_engine/histogram_signals/translations.ts
new file mode 100644
index 0000000000000..2b20c726d4b3f
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/components/page/detection_engine/histogram_signals/translations.ts
@@ -0,0 +1,11 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { i18n } from '@kbn/i18n';
+
+export const PAGE_TITLE = i18n.translate('xpack.siem.detectionEngine.rules.pageTitle', {
+ defaultMessage: 'Rules',
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
index 273b962d6cac9..a544a5f4d7d0c 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
@@ -4,16 +4,6 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import {
- Axis,
- Chart,
- HistogramBarSeries,
- Settings,
- getAxisId,
- getSpecId,
- niceTimeFormatByDay,
- timeFormatter,
-} from '@elastic/charts';
import {
EuiButton,
EuiFilterButton,
@@ -24,11 +14,11 @@ import {
} from '@elastic/eui';
import React, { useState } from 'react';
import { StickyContainer } from 'react-sticky';
-import { npStart } from 'ui/new_platform';
import { FiltersGlobal } from '../../components/filters_global';
import { HeaderPage } from '../../components/header_page';
import { HeaderSection } from '../../components/header_section';
+import { HistogramSignals } from '../../components/page/detection_engine/histogram_signals';
import {
UtilityBar,
UtilityBarAction,
@@ -135,41 +125,6 @@ export const DetectionEngineComponent = React.memo(() => {
{ text: 'Top source IPs', value: 'source_ips' },
{ text: 'Top users', value: 'users' },
];
- const sampleChartData = [
- { x: 1571090784000, y: 2, a: 'a' },
- { x: 1571090784000, y: 2, b: 'b' },
- { x: 1571093484000, y: 7, a: 'a' },
- { x: 1571096184000, y: 3, a: 'a' },
- { x: 1571098884000, y: 2, a: 'a' },
- { x: 1571101584000, y: 7, a: 'a' },
- { x: 1571104284000, y: 3, a: 'a' },
- { x: 1571106984000, y: 2, a: 'a' },
- { x: 1571109684000, y: 7, a: 'a' },
- { x: 1571112384000, y: 3, a: 'a' },
- { x: 1571115084000, y: 2, a: 'a' },
- { x: 1571117784000, y: 7, a: 'a' },
- { x: 1571120484000, y: 3, a: 'a' },
- { x: 1571123184000, y: 2, a: 'a' },
- { x: 1571125884000, y: 7, a: 'a' },
- { x: 1571128584000, y: 3, a: 'a' },
- { x: 1571131284000, y: 2, a: 'a' },
- { x: 1571133984000, y: 7, a: 'a' },
- { x: 1571136684000, y: 3, a: 'a' },
- { x: 1571139384000, y: 2, a: 'a' },
- { x: 1571142084000, y: 7, a: 'a' },
- { x: 1571144784000, y: 3, a: 'a' },
- { x: 1571147484000, y: 2, a: 'a' },
- { x: 1571150184000, y: 7, a: 'a' },
- { x: 1571152884000, y: 3, a: 'a' },
- { x: 1571155584000, y: 2, a: 'a' },
- { x: 1571158284000, y: 7, a: 'a' },
- { x: 1571160984000, y: 3, a: 'a' },
- { x: 1571163684000, y: 2, a: 'a' },
- { x: 1571166384000, y: 7, a: 'a' },
- { x: 1571169084000, y: 3, a: 'a' },
- { x: 1571171784000, y: 2, a: 'a' },
- { x: 1571174484000, y: 7, a: 'a' },
- ];
const filterGroupOptions = ['open', 'closed'];
const [filterGroupState, setFilterGroupState] = useState(filterGroupOptions[0]);
@@ -196,31 +151,7 @@ export const DetectionEngineComponent = React.memo(() => {
/>
-
-
-
-
-
-
-
-
-
+
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.tsx
index 89fd4bd3fd6fc..9c956bf85cdeb 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.tsx
@@ -4,21 +4,17 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import euiLightVars from '@elastic/eui/dist/eui_theme_light.json';
import {
- EuiBadge,
EuiBasicTable,
EuiButton,
EuiButtonIcon,
- EuiFieldSearch,
EuiFilterButton,
EuiFilterGroup,
EuiFlexGroup,
EuiFlexItem,
- EuiHealth,
EuiIconTip,
- EuiLink,
EuiPanel,
+ EuiSelect,
EuiSpacer,
EuiSwitch,
EuiTabbedContent,
@@ -32,6 +28,7 @@ import { getEmptyTagValue } from '../../../components/empty_value';
import { FiltersGlobal } from '../../../components/filters_global';
import { HeaderPage } from '../../../components/header_page';
import { HeaderSection } from '../../../components/header_section';
+import { HistogramSignals } from '../../../components/page/detection_engine/histogram_signals';
import {
UtilityBar,
UtilityBarAction,
@@ -131,6 +128,17 @@ const ClosedSignals = React.memo(() => {
});
const Signals = React.memo(() => {
+ const sampleChartOptions = [
+ { text: 'Risk scores', value: 'risk_scores' },
+ { text: 'Severities', value: 'severities' },
+ { text: 'Top destination IPs', value: 'destination_ips' },
+ { text: 'Top event actions', value: 'event_actions' },
+ { text: 'Top event categories', value: 'event_categories' },
+ { text: 'Top host names', value: 'host_names' },
+ { text: 'Top source IPs', value: 'source_ips' },
+ { text: 'Top users', value: 'users' },
+ ];
+
const filterGroupOptions = ['open', 'closed'];
const [filterGroupState, setFilterGroupState] = useState(filterGroupOptions[0]);
@@ -138,6 +146,20 @@ const Signals = React.memo(() => {
<>
+
+
+
+
+
+
+
+
+
+
From d047711c2e1cdf0c3614466314761e74ebc5fa4d Mon Sep 17 00:00:00 2001
From: Michael Marcialis
Date: Tue, 29 Oct 2019 14:31:25 -0400
Subject: [PATCH 36/57] update supplement layout
---
.../detection_engine/rule_details/index.tsx | 26 +++++++++++--------
1 file changed, 15 insertions(+), 11 deletions(-)
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.tsx
index 9c956bf85cdeb..a3e3b99a9546f 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.tsx
@@ -508,22 +508,26 @@ export const RuleDetailsComponent = React.memo(() => {
subtitle2="Last signal: 23 minutes ago"
title="Automated exfiltration"
>
-
+
-
- {'Edit rule settings'}
-
-
-
-
-
+
+
+
+ {'Edit rule settings'}
+
+
+
+
+
+
+
From a24e05c7902a6296835789dda791fdc872334836 Mon Sep 17 00:00:00 2001
From: Michael Marcialis
Date: Tue, 29 Oct 2019 14:38:53 -0400
Subject: [PATCH 37/57] example rule fail
---
.../pages/detection_engine/rule_details/index.tsx | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.tsx
index a3e3b99a9546f..00222ccff843e 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.tsx
@@ -8,6 +8,7 @@ import {
EuiBasicTable,
EuiButton,
EuiButtonIcon,
+ EuiCallOut,
EuiFilterButton,
EuiFilterGroup,
EuiFlexGroup,
@@ -161,7 +162,7 @@ const Signals = React.memo(() => {
-
+
{
+
+ {'Full fail message here.'}
+
+
+
+
From 518ef61f10ee3b07e6f21369f8d73c9404c4902f Mon Sep 17 00:00:00 2001
From: Michael Marcialis
Date: Tue, 29 Oct 2019 15:10:14 -0400
Subject: [PATCH 38/57] switch to new discover-style search
---
.../detection_engine/detection_engine.tsx | 111 ++++++-----
.../public/pages/detection_engine/kql.tsx | 15 --
.../detection_engine/rule_details/index.tsx | 183 ++++++++++--------
3 files changed, 160 insertions(+), 149 deletions(-)
delete mode 100644 x-pack/legacy/plugins/siem/public/pages/detection_engine/kql.tsx
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
index a544a5f4d7d0c..0cfb9233b20e1 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
@@ -19,6 +19,7 @@ import { FiltersGlobal } from '../../components/filters_global';
import { HeaderPage } from '../../components/header_page';
import { HeaderSection } from '../../components/header_section';
import { HistogramSignals } from '../../components/page/detection_engine/histogram_signals';
+import { SiemSearchBar } from '../../components/search_bar';
import {
UtilityBar,
UtilityBarAction,
@@ -26,8 +27,8 @@ import {
UtilityBarSection,
UtilityBarText,
} from '../../components/utility_bar';
+import { indicesExistOrDataTemporarilyUnavailable, WithSource } from '../../containers/source';
import { SpyRoute } from '../../utils/route/spy_routes';
-import { DetectionEngineKql } from './kql';
import * as i18n from './translations';
const OpenSignals = React.memo(() => {
@@ -131,54 +132,66 @@ export const DetectionEngineComponent = React.memo(() => {
return (
<>
-
-
-
-
-
-
-
- {i18n.BUTTON_MANAGE_RULES}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- setFilterGroupState(filterGroupOptions[0])}
- withNext
- >
- {'Open signals'}
-
-
- setFilterGroupState(filterGroupOptions[1])}
- >
- {'Closed signals'}
-
-
-
-
- {filterGroupState === filterGroupOptions[0] ? : }
-
-
+
+ {({ indicesExist, indexPattern }) => {
+ return indicesExistOrDataTemporarilyUnavailable(indicesExist) ? (
+
+
+
+
+
+
+
+ {i18n.BUTTON_MANAGE_RULES}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ setFilterGroupState(filterGroupOptions[0])}
+ withNext
+ >
+ {'Open signals'}
+
+
+ setFilterGroupState(filterGroupOptions[1])}
+ >
+ {'Closed signals'}
+
+
+
+
+ {filterGroupState === filterGroupOptions[0] ? : }
+
+
+ ) : (
+ <>
+
+
+ {/* */}
+ >
+ );
+ }}
+
>
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/kql.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/kql.tsx
deleted file mode 100644
index 9a9a4713bbd7c..0000000000000
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/kql.tsx
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import { EuiFieldSearch } from '@elastic/eui';
-import React from 'react';
-
-import * as i18n from './translations';
-
-export const DetectionEngineKql = React.memo(() => (
-
-));
-DetectionEngineKql.displayName = 'DetectionEngineKql';
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.tsx
index 00222ccff843e..1a9a1f2c9c2eb 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.tsx
@@ -30,6 +30,7 @@ import { FiltersGlobal } from '../../../components/filters_global';
import { HeaderPage } from '../../../components/header_page';
import { HeaderSection } from '../../../components/header_section';
import { HistogramSignals } from '../../../components/page/detection_engine/histogram_signals';
+import { SiemSearchBar } from '../../../components/search_bar';
import {
UtilityBar,
UtilityBarAction,
@@ -37,8 +38,8 @@ import {
UtilityBarSection,
UtilityBarText,
} from '../../../components/utility_bar';
+import { indicesExistOrDataTemporarilyUnavailable, WithSource } from '../../../containers/source';
import { SpyRoute } from '../../../utils/route/spy_routes';
-import { DetectionEngineKql } from '../kql';
import * as i18n from './translations';
// Michael: Will need to change this to get the current datetime format from Kibana settings.
@@ -493,94 +494,106 @@ ActivityMonitor.displayName = 'ActivityMonitor';
export const RuleDetailsComponent = React.memo(() => {
return (
<>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {'Edit rule settings'}
-
+
+ {({ indicesExist, indexPattern }) => {
+ return indicesExistOrDataTemporarilyUnavailable(indicesExist) ? (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {'Edit rule settings'}
+
+
+
+
+
+
+
+
+
+
+
+
+ {'Full fail message here.'}
+
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
- {'Full fail message here.'}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ,
- },
- {
- id: 'tabActivityMonitor',
- name: 'Activity monitor',
- content: ,
- },
- ]}
- />
-
+
+
+
+ ,
+ },
+ {
+ id: 'tabActivityMonitor',
+ name: 'Activity monitor',
+ content: ,
+ },
+ ]}
+ />
+
+ ) : (
+ <>
+
+
+ {/* */}
+ >
+ );
+ }}
+
>
From ed17347a1dac5d92cb306a38d25354e0d154bb1d Mon Sep 17 00:00:00 2001
From: Michael Marcialis
Date: Wed, 30 Oct 2019 10:53:49 -0400
Subject: [PATCH 39/57] add ProgressInline comp
---
.../public/components/header_page/index.tsx | 8 +--
.../components/header_section/index.tsx | 2 +-
.../histogram_signals/index.tsx | 2 -
.../histogram_signals/translations.ts | 11 ----
.../__snapshots__/index.test.tsx.snap | 9 +++
.../components/progress_inline/index.test.tsx | 29 ++++++++++
.../components/progress_inline/index.tsx | 57 +++++++++++++++++++
.../public/components/subtitle/index.test.tsx | 44 +++++++++++---
.../siem/public/components/subtitle/index.tsx | 54 ++++++++++++------
.../detection_engine/rule_details/index.tsx | 15 +++--
10 files changed, 186 insertions(+), 45 deletions(-)
delete mode 100644 x-pack/legacy/plugins/siem/public/components/page/detection_engine/histogram_signals/translations.ts
create mode 100644 x-pack/legacy/plugins/siem/public/components/progress_inline/__snapshots__/index.test.tsx.snap
create mode 100644 x-pack/legacy/plugins/siem/public/components/progress_inline/index.test.tsx
create mode 100644 x-pack/legacy/plugins/siem/public/components/progress_inline/index.tsx
diff --git a/x-pack/legacy/plugins/siem/public/components/header_page/index.tsx b/x-pack/legacy/plugins/siem/public/components/header_page/index.tsx
index 9ce16ebd40257..bc6e5c699257d 100644
--- a/x-pack/legacy/plugins/siem/public/components/header_page/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/header_page/index.tsx
@@ -73,8 +73,8 @@ export interface HeaderPageProps extends HeaderProps {
badgeOptions?: BadgeOptions;
children?: React.ReactNode;
draggableArguments?: DraggableArguments;
- subtitle?: SubtitleProps['text'];
- subtitle2?: SubtitleProps['text'];
+ subtitle?: SubtitleProps['items'];
+ subtitle2?: SubtitleProps['items'];
title: string | React.ReactNode;
}
@@ -130,8 +130,8 @@ export const HeaderPage = React.memo(
- {subtitle && }
- {subtitle2 && }
+ {subtitle && }
+ {subtitle2 && }
{children && (
diff --git a/x-pack/legacy/plugins/siem/public/components/header_section/index.tsx b/x-pack/legacy/plugins/siem/public/components/header_section/index.tsx
index 888c77987a94f..c615186e81ada 100644
--- a/x-pack/legacy/plugins/siem/public/components/header_section/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/header_section/index.tsx
@@ -60,7 +60,7 @@ export const HeaderSection = React.memo(
- {subtitle && }
+ {subtitle && }
{id && (
diff --git a/x-pack/legacy/plugins/siem/public/components/page/detection_engine/histogram_signals/index.tsx b/x-pack/legacy/plugins/siem/public/components/page/detection_engine/histogram_signals/index.tsx
index 29a979f626755..fa26664930fe5 100644
--- a/x-pack/legacy/plugins/siem/public/components/page/detection_engine/histogram_signals/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/page/detection_engine/histogram_signals/index.tsx
@@ -17,8 +17,6 @@ import {
import React from 'react';
import { npStart } from 'ui/new_platform';
-import * as i18n from './translations';
-
export const HistogramSignals = React.memo(() => {
const sampleChartData = [
{ x: 1571090784000, y: 2, a: 'a' },
diff --git a/x-pack/legacy/plugins/siem/public/components/page/detection_engine/histogram_signals/translations.ts b/x-pack/legacy/plugins/siem/public/components/page/detection_engine/histogram_signals/translations.ts
deleted file mode 100644
index 2b20c726d4b3f..0000000000000
--- a/x-pack/legacy/plugins/siem/public/components/page/detection_engine/histogram_signals/translations.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import { i18n } from '@kbn/i18n';
-
-export const PAGE_TITLE = i18n.translate('xpack.siem.detectionEngine.rules.pageTitle', {
- defaultMessage: 'Rules',
-});
diff --git a/x-pack/legacy/plugins/siem/public/components/progress_inline/__snapshots__/index.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/progress_inline/__snapshots__/index.test.tsx.snap
new file mode 100644
index 0000000000000..ecd2b15a841f6
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/components/progress_inline/__snapshots__/index.test.tsx.snap
@@ -0,0 +1,9 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`HeaderSection it renders 1`] = `
+
+
+
+`;
diff --git a/x-pack/legacy/plugins/siem/public/components/progress_inline/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/progress_inline/index.test.tsx
new file mode 100644
index 0000000000000..269bcebdae01a
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/components/progress_inline/index.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;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { shallow } from 'enzyme';
+import toJson from 'enzyme-to-json';
+import React from 'react';
+
+import { TestProviders } from '../../mock';
+import '../../mock/ui_settings';
+import { ProgressInline } from './index';
+
+jest.mock('../../lib/settings/use_kibana_ui_setting');
+
+describe('ProgressInline', () => {
+ test('it renders', () => {
+ const wrapper = shallow(
+
+
+ {'Test progress'}
+
+
+ );
+
+ expect(toJson(wrapper)).toMatchSnapshot();
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/components/progress_inline/index.tsx b/x-pack/legacy/plugins/siem/public/components/progress_inline/index.tsx
new file mode 100644
index 0000000000000..f7f6fbf6a0414
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/components/progress_inline/index.tsx
@@ -0,0 +1,57 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { EuiProgress } from '@elastic/eui';
+import React from 'react';
+import styled, { css } from 'styled-components';
+
+const Wrapper = styled.dl`
+ ${({ theme }) => css`
+ align-items: center;
+ display: inline-flex;
+
+ & > * {
+ color: ${theme.eui.textColors.subdued};
+ font-size: ${theme.eui.euiFontSizeXS};
+ line-height: ${theme.eui.euiLineHeight};
+
+ & + * {
+ margin-left: 8px;
+ }
+ }
+
+ .siemProgressInline__bar {
+ width: 100px;
+ }
+ `}
+`;
+Wrapper.displayName = 'Wrapper';
+
+export interface ProgressInlineProps {
+ children: string;
+ current: number;
+ max: number;
+ unit: string;
+}
+
+export const ProgressInline = React.memo(
+ ({ children, current, max, unit }) => (
+
+ {children}
+
+
+
+
+
+
+ {current.toLocaleString()}
+ {'/'}
+ {max.toLocaleString()} {unit}
+
+
+ )
+);
+ProgressInline.displayName = 'ProgressInline';
diff --git a/x-pack/legacy/plugins/siem/public/components/subtitle/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/subtitle/index.test.tsx
index 5c7bdbfe0309c..b5441591e1b7a 100644
--- a/x-pack/legacy/plugins/siem/public/components/subtitle/index.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/subtitle/index.test.tsx
@@ -18,30 +18,60 @@ describe('Subtitle', () => {
test('it renders', () => {
const wrapper = shallow(
-
+
);
expect(toJson(wrapper)).toMatchSnapshot();
});
- test('it renders one subtitle item', () => {
+ test('it renders one subtitle string item', () => {
const wrapper = mount(
-
+
);
- expect(wrapper.find('p').length).toEqual(1);
+ expect(wrapper.find('.siemSubtitle__item--text').length).toEqual(1);
});
- test('it renders multiple subtitle items', () => {
+ test('it renders multiple subtitle string items', () => {
const wrapper = mount(
-
+
);
- expect(wrapper.find('p').length).toEqual(2);
+ expect(wrapper.find('.siemSubtitle__item--text').length).toEqual(2);
+ });
+
+ test('it renders one subtitle React.ReactNode item', () => {
+ const wrapper = mount(
+
+
+
+ );
+
+ expect(wrapper.find('.siemSubtitle__item--node').length).toEqual(1);
+ });
+
+ test('it renders multiple subtitle React.ReactNode items', () => {
+ const wrapper = mount(
+
+
+
+ );
+
+ expect(wrapper.find('.siemSubtitle__item--node').length).toEqual(2);
+ });
+
+ test('it renders multiple subtitle items of mixed type', () => {
+ const wrapper = mount(
+
+ {'Test subtitle 2'}]} />
+
+ );
+
+ expect(wrapper.find('.siemSubtitle__item').length).toEqual(2);
});
});
diff --git a/x-pack/legacy/plugins/siem/public/components/subtitle/index.tsx b/x-pack/legacy/plugins/siem/public/components/subtitle/index.tsx
index 10ec003baedc9..8e7931dd03458 100644
--- a/x-pack/legacy/plugins/siem/public/components/subtitle/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/subtitle/index.tsx
@@ -7,17 +7,11 @@
import React from 'react';
import styled, { css } from 'styled-components';
-const SubtitleWrapper = styled.div.attrs({
- className: 'siemSubtitle',
-})`
+const Wrapper = styled.div`
${({ theme }) => css`
margin-top: ${theme.eui.euiSizeS};
- p {
- color: ${theme.eui.textColors.subdued};
- font-size: ${theme.eui.euiFontSizeXS};
- line-height: ${theme.eui.euiLineHeight};
-
+ .siemSubtitle__item {
@media only screen and (min-width: ${theme.eui.euiBreakpoints.s}) {
display: inline-block;
margin-right: ${theme.eui.euiSize};
@@ -27,23 +21,51 @@ const SubtitleWrapper = styled.div.attrs({
}
}
}
+
+ .siemSubtitle__item--text {
+ color: ${theme.eui.textColors.subdued};
+ font-size: ${theme.eui.euiFontSizeXS};
+ line-height: ${theme.eui.euiLineHeight};
+ }
`}
`;
-SubtitleWrapper.displayName = 'SubtitleWrapper';
+Wrapper.displayName = 'Wrapper';
+
+interface SubtitleItemProps {
+ children: string | React.ReactNode;
+ key?: number;
+}
+
+const SubtitleItem = React.memo(({ children, key }) => {
+ if (typeof children === 'string') {
+ return (
+
+ {children}
+
+ );
+ } else {
+ return (
+
+ {children}
+
+ );
+ }
+});
+SubtitleItem.displayName = 'SubtitleItem';
export interface SubtitleProps {
- text: string | string[] | React.ReactNode;
+ items: string | React.ReactNode | Array;
}
-export const Subtitle = React.memo(({ text }) => {
+export const Subtitle = React.memo(({ items }) => {
return (
-
- {Array.isArray(text) ? (
- (text as string[]).map((textItem, i) => {textItem}
)
+
+ {Array.isArray(items) ? (
+ items.map((item, i) => {item})
) : (
- {text}
+ {items}
)}
-
+
);
});
Subtitle.displayName = 'Subtitle';
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.tsx
index 1a9a1f2c9c2eb..86f3d113fc1e7 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.tsx
@@ -15,6 +15,7 @@ import {
EuiFlexItem,
EuiIconTip,
EuiPanel,
+ EuiProgress,
EuiSelect,
EuiSpacer,
EuiSwitch,
@@ -30,6 +31,7 @@ import { FiltersGlobal } from '../../../components/filters_global';
import { HeaderPage } from '../../../components/header_page';
import { HeaderSection } from '../../../components/header_section';
import { HistogramSignals } from '../../../components/page/detection_engine/histogram_signals';
+import { ProgressInline } from '../../../components/progress_inline';
import { SiemSearchBar } from '../../../components/search_bar';
import {
UtilityBar,
@@ -510,7 +512,12 @@ export const RuleDetailsComponent = React.memo(() => {
'Created by: mmarcialis on 12/28/2019, 12:00 PM',
'Updated by: agoldstein on 12/28/2019, 12:00 PM',
]}
- subtitle2="Last signal: 23 minutes ago"
+ subtitle2={[
+ 'Last signal: 23 minutes ago',
+
+ {'Status: Running'}
+ ,
+ ]}
title="Automated exfiltration"
>
@@ -549,19 +556,19 @@ export const RuleDetailsComponent = React.memo(() => {
-
+
-
+
-
+
From 8b468f58a5824a19f6c25c6880419146dedb1232 Mon Sep 17 00:00:00 2001
From: Michael Marcialis
Date: Wed, 30 Oct 2019 11:03:12 -0400
Subject: [PATCH 40/57] update unit tests and snapshots
---
.../__snapshots__/index.test.tsx.snap | 7 +++++++
.../histogram_signals/index.test.tsx | 2 +-
.../__snapshots__/index.test.tsx.snap | 12 ++++++++----
.../subtitle/__snapshots__/index.test.tsx.snap | 2 +-
.../siem/public/components/subtitle/index.test.tsx | 4 ++--
5 files changed, 19 insertions(+), 8 deletions(-)
create mode 100644 x-pack/legacy/plugins/siem/public/components/page/detection_engine/histogram_signals/__snapshots__/index.test.tsx.snap
diff --git a/x-pack/legacy/plugins/siem/public/components/page/detection_engine/histogram_signals/__snapshots__/index.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/page/detection_engine/histogram_signals/__snapshots__/index.test.tsx.snap
new file mode 100644
index 0000000000000..caf4334cacf57
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/components/page/detection_engine/histogram_signals/__snapshots__/index.test.tsx.snap
@@ -0,0 +1,7 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`HistogramSignals it renders 1`] = `
+
+
+
+`;
diff --git a/x-pack/legacy/plugins/siem/public/components/page/detection_engine/histogram_signals/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/page/detection_engine/histogram_signals/index.test.tsx
index 932c8770edba7..2412d05f3f47d 100644
--- a/x-pack/legacy/plugins/siem/public/components/page/detection_engine/histogram_signals/index.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/page/detection_engine/histogram_signals/index.test.tsx
@@ -8,7 +8,7 @@ import { shallow } from 'enzyme';
import toJson from 'enzyme-to-json';
import React from 'react';
-import '../../mock/ui_settings';
+import '../../../../mock/ui_settings';
import { TestProviders } from '../../../../mock';
import { HistogramSignals } from './index';
diff --git a/x-pack/legacy/plugins/siem/public/components/progress_inline/__snapshots__/index.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/progress_inline/__snapshots__/index.test.tsx.snap
index ecd2b15a841f6..c62712e6cfe59 100644
--- a/x-pack/legacy/plugins/siem/public/components/progress_inline/__snapshots__/index.test.tsx.snap
+++ b/x-pack/legacy/plugins/siem/public/components/progress_inline/__snapshots__/index.test.tsx.snap
@@ -1,9 +1,13 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`HeaderSection it renders 1`] = `
+exports[`ProgressInline it renders 1`] = `
-
+
+ Test progress
+
`;
diff --git a/x-pack/legacy/plugins/siem/public/components/subtitle/__snapshots__/index.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/subtitle/__snapshots__/index.test.tsx.snap
index fad93ad853a37..2522d4d1de084 100644
--- a/x-pack/legacy/plugins/siem/public/components/subtitle/__snapshots__/index.test.tsx.snap
+++ b/x-pack/legacy/plugins/siem/public/components/subtitle/__snapshots__/index.test.tsx.snap
@@ -3,7 +3,7 @@
exports[`Subtitle it renders 1`] = `
`;
diff --git a/x-pack/legacy/plugins/siem/public/components/subtitle/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/subtitle/index.test.tsx
index b5441591e1b7a..77506f8a466a5 100644
--- a/x-pack/legacy/plugins/siem/public/components/subtitle/index.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/subtitle/index.test.tsx
@@ -48,7 +48,7 @@ describe('Subtitle', () => {
test('it renders one subtitle React.ReactNode item', () => {
const wrapper = mount(
-
+ {'Test subtitle'}} />
);
@@ -58,7 +58,7 @@ describe('Subtitle', () => {
test('it renders multiple subtitle React.ReactNode items', () => {
const wrapper = mount(
-
+ {'Test subtitle 1'}, {'Test subtitle 2'}]} />
);
From 3ffc87a98ba3ceac04d0b4ed65fcb7bc73028764 Mon Sep 17 00:00:00 2001
From: Michael Marcialis
Date: Wed, 30 Oct 2019 11:32:36 -0400
Subject: [PATCH 41/57] cleanup
---
.../plugins/siem/public/pages/home/index.tsx | 22 +++++++++----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/x-pack/legacy/plugins/siem/public/pages/home/index.tsx b/x-pack/legacy/plugins/siem/public/pages/home/index.tsx
index a1348c50a31b8..ff3c9e1a18414 100644
--- a/x-pack/legacy/plugins/siem/public/pages/home/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/home/index.tsx
@@ -100,27 +100,27 @@ export const HomePage = pure(() => (
-
+
}
/>
(
-
+ render={({ location, match }) => (
+
)}
/>
(
-
+ render={({ location, match }) => (
+
)}
/>
(
-
+ render={({ location, match }) => (
+
)}
/>
(
(
-
+ render={({ location, match }) => (
+
)}
/>
(
-
+ render={({ location, match }) => (
+
)}
/>
From bd86c0e7636295ff2ce02cd02775d694ceea88bd Mon Sep 17 00:00:00 2001
From: Michael Marcialis
Date: Wed, 30 Oct 2019 12:48:49 -0400
Subject: [PATCH 42/57] correct merge weirdness
---
.../public/components/link_to/link_to.tsx | 25 ++++++++-----------
1 file changed, 10 insertions(+), 15 deletions(-)
diff --git a/x-pack/legacy/plugins/siem/public/components/link_to/link_to.tsx b/x-pack/legacy/plugins/siem/public/components/link_to/link_to.tsx
index cc029e487be52..0125b52e3ad33 100644
--- a/x-pack/legacy/plugins/siem/public/components/link_to/link_to.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/link_to/link_to.tsx
@@ -29,35 +29,34 @@ interface LinkToPageProps {
export const LinkToPage = pure(({ match }) => (
-
+
(({ match }) => (
path={`${match.url}/:pageName(${SiemPageName.detectionEngine})/rules/rule-details/edit-rule`}
/>
-
From 1f1a153952db8ac30cce23c5566850397d8405f3 Mon Sep 17 00:00:00 2001
From: Michael Marcialis
Date: Wed, 30 Oct 2019 16:36:39 -0400
Subject: [PATCH 43/57] move text styles to all subtitle items
---
.../siem/public/components/progress_inline/index.tsx | 10 ++--------
.../plugins/siem/public/components/subtitle/index.tsx | 10 ++++------
2 files changed, 6 insertions(+), 14 deletions(-)
diff --git a/x-pack/legacy/plugins/siem/public/components/progress_inline/index.tsx b/x-pack/legacy/plugins/siem/public/components/progress_inline/index.tsx
index f7f6fbf6a0414..90eca051e3d11 100644
--- a/x-pack/legacy/plugins/siem/public/components/progress_inline/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/progress_inline/index.tsx
@@ -13,14 +13,8 @@ const Wrapper = styled.dl`
align-items: center;
display: inline-flex;
- & > * {
- color: ${theme.eui.textColors.subdued};
- font-size: ${theme.eui.euiFontSizeXS};
- line-height: ${theme.eui.euiLineHeight};
-
- & + * {
- margin-left: 8px;
- }
+ & > * + * {
+ margin-left: ${theme.eui.euiSizeS};
}
.siemProgressInline__bar {
diff --git a/x-pack/legacy/plugins/siem/public/components/subtitle/index.tsx b/x-pack/legacy/plugins/siem/public/components/subtitle/index.tsx
index 8e7931dd03458..08f1905537ddf 100644
--- a/x-pack/legacy/plugins/siem/public/components/subtitle/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/subtitle/index.tsx
@@ -12,6 +12,10 @@ const Wrapper = styled.div`
margin-top: ${theme.eui.euiSizeS};
.siemSubtitle__item {
+ color: ${theme.eui.textColors.subdued};
+ font-size: ${theme.eui.euiFontSizeXS};
+ line-height: ${theme.eui.euiLineHeight};
+
@media only screen and (min-width: ${theme.eui.euiBreakpoints.s}) {
display: inline-block;
margin-right: ${theme.eui.euiSize};
@@ -21,12 +25,6 @@ const Wrapper = styled.div`
}
}
}
-
- .siemSubtitle__item--text {
- color: ${theme.eui.textColors.subdued};
- font-size: ${theme.eui.euiFontSizeXS};
- line-height: ${theme.eui.euiLineHeight};
- }
`}
`;
Wrapper.displayName = 'Wrapper';
From a7ed912a6df9ca60dbd049731186adca46060992 Mon Sep 17 00:00:00 2001
From: Michael Marcialis
Date: Wed, 30 Oct 2019 18:27:07 -0400
Subject: [PATCH 44/57] correct invalid nav markup; update tests; cleanup
---
.../public/components/header_global/index.tsx | 4 +-
.../public/components/navigation/index.tsx | 33 ++++-----
.../navigation/tab_navigation/index.test.tsx | 12 ++--
.../navigation/tab_navigation/index.tsx | 68 +++++--------------
.../public/components/navigation/types.ts | 1 -
.../siem/public/pages/hosts/details/index.tsx | 8 +--
.../plugins/siem/public/pages/hosts/hosts.tsx | 8 +--
.../siem/public/pages/network/network.tsx | 6 +-
8 files changed, 46 insertions(+), 94 deletions(-)
diff --git a/x-pack/legacy/plugins/siem/public/components/header_global/index.tsx b/x-pack/legacy/plugins/siem/public/components/header_global/index.tsx
index 113b2494c44d1..d3e2d948fa992 100644
--- a/x-pack/legacy/plugins/siem/public/components/header_global/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/header_global/index.tsx
@@ -47,8 +47,8 @@ export const HeaderGlobal = React.memo(({ offsetRight }) => (
-
-
+
+
diff --git a/x-pack/legacy/plugins/siem/public/components/navigation/index.tsx b/x-pack/legacy/plugins/siem/public/components/navigation/index.tsx
index a45da9b6a9112..7209be4d715f3 100644
--- a/x-pack/legacy/plugins/siem/public/components/navigation/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/navigation/index.tsx
@@ -6,17 +6,16 @@
import { isEqual } from 'lodash/fp';
import React, { useEffect } from 'react';
-import { compose } from 'redux';
import { connect } from 'react-redux';
+import { compose } from 'redux';
import { RouteSpyState } from '../../utils/route/types';
import { useRouteSpy } from '../../utils/route/use_route_spy';
-
+import { makeMapStateToProps } from '../url_state/helpers';
import { setBreadcrumbs } from './breadcrumbs';
import { TabNavigation } from './tab_navigation';
import { TabNavigationProps } from './tab_navigation/types';
import { SiemNavigationComponentProps } from './types';
-import { makeMapStateToProps } from '../url_state/helpers';
export const SiemNavigationComponent = React.memo(
({
@@ -29,7 +28,6 @@ export const SiemNavigationComponent = React.memo
-
-
+
);
},
(prevProps, nextProps) => {
diff --git a/x-pack/legacy/plugins/siem/public/components/navigation/tab_navigation/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/navigation/tab_navigation/index.test.tsx
index f58519dc0e4c5..c2156bd6c046c 100644
--- a/x-pack/legacy/plugins/siem/public/components/navigation/tab_navigation/index.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/navigation/tab_navigation/index.test.tsx
@@ -7,14 +7,14 @@
import { mount, shallow } from 'enzyme';
import * as React from 'react';
-import { TabNavigation } from './';
-import { TabNavigationProps } from './types';
import { navTabs } from '../../../pages/home/home_navigations';
import { SiemPageName } from '../../../pages/home/types';
-import { HostsTableType } from '../../../store/hosts/model';
import { navTabsHostDetails } from '../../../pages/hosts/details/nav_tabs';
-import { CONSTANTS } from '../../url_state/constants';
+import { HostsTableType } from '../../../store/hosts/model';
import { RouteSpyState } from '../../../utils/route/types';
+import { CONSTANTS } from '../../url_state/constants';
+import { TabNavigation } from './';
+import { TabNavigationProps } from './types';
describe('Tab Navigation', () => {
const pageName = SiemPageName.hosts;
@@ -78,7 +78,7 @@ describe('Tab Navigation', () => {
});
test('it carries the url state in the link', () => {
const wrapper = shallow();
- const firstTab = wrapper.find('[data-test-subj="navigation-link-network"]');
+ const firstTab = wrapper.find('[data-test-subj="navigation-network"]');
expect(firstTab.props().href).toBe(
"#/link-to/network?query=(language:kuery,query:'host.name:%22siem-es%22')&timerange=(global:(linkTo:!(timeline),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)),timeline:(linkTo:!(global),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)))"
);
@@ -147,7 +147,7 @@ describe('Tab Navigation', () => {
test('it carries the url state in the link', () => {
const wrapper = shallow();
const firstTab = wrapper.find(
- `[data-test-subj="navigation-link-${HostsTableType.authentications}"]`
+ `[data-test-subj="navigation-${HostsTableType.authentications}"]`
);
expect(firstTab.props().href).toBe(
`#/${pageName}/${hostName}/${HostsTableType.authentications}?query=(language:kuery,query:'host.name:%22siem-es%22')&timerange=(global:(linkTo:!(timeline),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)),timeline:(linkTo:!(global),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)))`
diff --git a/x-pack/legacy/plugins/siem/public/components/navigation/tab_navigation/index.tsx b/x-pack/legacy/plugins/siem/public/components/navigation/tab_navigation/index.tsx
index 3e3c02a1abfa4..27d10cb02a856 100644
--- a/x-pack/legacy/plugins/siem/public/components/navigation/tab_navigation/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/navigation/tab_navigation/index.tsx
@@ -3,40 +3,17 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
-import { EuiTab, EuiTabs, EuiLink } from '@elastic/eui';
+import { EuiTab, EuiTabs } from '@elastic/eui';
import { getOr } from 'lodash/fp';
-
import React, { useEffect, useState } from 'react';
-import styled from 'styled-components';
-import classnames from 'classnames';
import { trackUiAction as track, METRIC_TYPE, TELEMETRY_EVENT } from '../../../lib/track_usage';
import { getSearch } from '../helpers';
import { TabNavigationProps } from './types';
-const TabContainer = styled.div`
- .euiLink {
- color: inherit !important;
-
- &:focus {
- outline: 0;
- background: none;
- }
-
- .euiTab.euiTab-isSelected {
- cursor: pointer;
- }
- }
-
- &.showBorder {
- padding: 8px 8px 0;
- }
-`;
-
-TabContainer.displayName = 'TabContainer';
-
export const TabNavigation = React.memo(props => {
- const { display = 'condensed', navTabs, pageName, showBorder, tabName } = props;
+ const { display, navTabs, pageName, tabName } = props;
+
const mapLocationToTab = (): string => {
return getOr(
'',
@@ -44,6 +21,7 @@ export const TabNavigation = React.memo(props => {
Object.values(navTabs).find(item => tabName === item.id || pageName === item.id)
);
};
+
const [selectedTabId, setSelectedTabId] = useState(mapLocationToTab());
useEffect(() => {
const currentTabSelected = mapLocationToTab();
@@ -57,31 +35,21 @@ export const TabNavigation = React.memo(props => {
const renderTabs = (): JSX.Element[] =>
Object.values(navTabs).map(tab => (
- {
+ track(METRIC_TYPE.CLICK, `${TELEMETRY_EVENT.TAB_CLICKED}${tab.id}`);
+ }}
>
-
- {
- track(METRIC_TYPE.CLICK, `${TELEMETRY_EVENT.TAB_CLICKED}${tab.id}`);
- }}
- >
- {tab.name}
-
-
-
+ {tab.name}
+
));
- return (
-
- {renderTabs()}
-
- );
+
+ return {renderTabs()};
});
+TabNavigation.displayName = 'TabNavigation';
diff --git a/x-pack/legacy/plugins/siem/public/components/navigation/types.ts b/x-pack/legacy/plugins/siem/public/components/navigation/types.ts
index 2918a19df52fd..a8e16c82fbf80 100644
--- a/x-pack/legacy/plugins/siem/public/components/navigation/types.ts
+++ b/x-pack/legacy/plugins/siem/public/components/navigation/types.ts
@@ -9,7 +9,6 @@ import { UrlStateType } from '../url_state/constants';
export interface SiemNavigationComponentProps {
display?: 'default' | 'condensed';
navTabs: Record;
- showBorder?: boolean;
}
export type SearchNavTab = NavTab | { urlKey: UrlStateType; isDetailPage: boolean };
diff --git a/x-pack/legacy/plugins/siem/public/pages/hosts/details/index.tsx b/x-pack/legacy/plugins/siem/public/pages/hosts/details/index.tsx
index ec18450312852..e7c5209369519 100644
--- a/x-pack/legacy/plugins/siem/public/pages/hosts/details/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/hosts/details/index.tsx
@@ -13,7 +13,6 @@ import { compose } from 'redux';
import { FiltersGlobal } from '../../../components/filters_global';
import { HeaderPage } from '../../../components/header_page';
-import { KpiHostDetailsQuery } from '../../../containers/kpi_host_details';
import { LastEventTime } from '../../../components/last_event_time';
import { AnomalyTableProvider } from '../../../components/ml/anomaly/anomaly_table_provider';
import { hostToCriteria } from '../../../components/ml/criteria/host_to_criteria';
@@ -26,16 +25,17 @@ import { HostOverview } from '../../../components/page/hosts/host_overview';
import { manageQuery } from '../../../components/page/manage_query';
import { SiemSearchBar } from '../../../components/search_bar';
import { HostOverviewByNameQuery } from '../../../containers/hosts/overview';
+import { KpiHostDetailsQuery } from '../../../containers/kpi_host_details';
import { indicesExistOrDataTemporarilyUnavailable, WithSource } from '../../../containers/source';
import { LastEventIndexKey } from '../../../graphql/types';
import { useKibanaCore } from '../../../lib/compose/kibana_core';
import { convertToBuildEsQuery } from '../../../lib/keury';
import { inputsSelectors, State } from '../../../store';
-import { setAbsoluteRangeDatePicker as dispatchAbsoluteRangeDatePicker } from '../../../store/inputs/actions';
import { setHostDetailsTablesActivePageToZero as dispatchHostDetailsTablesActivePageToZero } from '../../../store/hosts/actions';
+import { setAbsoluteRangeDatePicker as dispatchAbsoluteRangeDatePicker } from '../../../store/inputs/actions';
import { SpyRoute } from '../../../utils/route/spy_routes';
-import { HostDetailsTabs } from './details_tabs';
import { HostsEmptyPage } from '../hosts_empty_page';
+import { HostDetailsTabs } from './details_tabs';
import { navTabsHostDetails } from './nav_tabs';
import { HostDetailsComponentProps, HostDetailsProps } from './types';
import { type } from './utils';
@@ -179,8 +179,6 @@ const HostDetailsComponent = React.memo(
diff --git a/x-pack/legacy/plugins/siem/public/pages/hosts/hosts.tsx b/x-pack/legacy/plugins/siem/public/pages/hosts/hosts.tsx
index a43d36d538c96..65d12697fbb63 100644
--- a/x-pack/legacy/plugins/siem/public/pages/hosts/hosts.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/hosts/hosts.tsx
@@ -7,9 +7,9 @@
import { EuiSpacer } from '@elastic/eui';
import { getEsQueryConfig } from '@kbn/es-query';
import * as React from 'react';
-import { compose } from 'redux';
import { connect } from 'react-redux';
import { StickyContainer } from 'react-sticky';
+import { compose } from 'redux';
import { FiltersGlobal } from '../../components/filters_global';
import { HeaderPage } from '../../components/header_page';
@@ -100,11 +100,7 @@ const HostsComponent = React.memo(
-
+
diff --git a/x-pack/legacy/plugins/siem/public/pages/network/network.tsx b/x-pack/legacy/plugins/siem/public/pages/network/network.tsx
index c6baf432a7b67..24f54184ba1ca 100644
--- a/x-pack/legacy/plugins/siem/public/pages/network/network.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/network/network.tsx
@@ -108,11 +108,7 @@ const NetworkComponent = React.memo(
<>
-
+
From 8b918414261dbdaabfeb16ad79a20eef6a5804e0 Mon Sep 17 00:00:00 2001
From: Michael Marcialis
Date: Thu, 31 Oct 2019 11:36:51 -0400
Subject: [PATCH 45/57] fix console errors
---
.../siem/public/components/subtitle/index.tsx | 15 +++------------
.../pages/detection_engine/detection_engine.tsx | 1 +
.../detection_engine/rule_details/index.tsx | 4 ++--
.../pages/detection_engine/rules/index.tsx | 16 +++++++++++++---
4 files changed, 19 insertions(+), 17 deletions(-)
diff --git a/x-pack/legacy/plugins/siem/public/components/subtitle/index.tsx b/x-pack/legacy/plugins/siem/public/components/subtitle/index.tsx
index 08f1905537ddf..123e14d239182 100644
--- a/x-pack/legacy/plugins/siem/public/components/subtitle/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/subtitle/index.tsx
@@ -31,22 +31,13 @@ Wrapper.displayName = 'Wrapper';
interface SubtitleItemProps {
children: string | React.ReactNode;
- key?: number;
}
-const SubtitleItem = React.memo(({ children, key }) => {
+const SubtitleItem = React.memo(({ children }) => {
if (typeof children === 'string') {
- return (
-
- {children}
-
- );
+ return {children}
;
} else {
- return (
-
- {children}
-
- );
+ return {children}
;
}
});
SubtitleItem.displayName = 'SubtitleItem';
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
index 0cfb9233b20e1..ed367a8b6b2df 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
@@ -150,6 +150,7 @@ export const DetectionEngineComponent = React.memo(() => {
{}}
prepend="Stack by"
value={sampleChartOptions[0].value}
/>
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.tsx
index 86f3d113fc1e7..31978113f42b8 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.tsx
@@ -15,7 +15,6 @@ import {
EuiFlexItem,
EuiIconTip,
EuiPanel,
- EuiProgress,
EuiSelect,
EuiSpacer,
EuiSwitch,
@@ -154,6 +153,7 @@ const Signals = React.memo(() => {
{}}
prepend="Stack by"
value={sampleChartOptions[0].value}
/>
@@ -522,7 +522,7 @@ export const RuleDetailsComponent = React.memo(() => {
>
-
+ {}} />
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
index 8b3a21ada9c2b..e594326c72802 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
@@ -193,8 +193,10 @@ const AllRules = React.memo(() => {
{typeof value !== 'string' ? (
<>
- {value.map(tag => (
-
{tag}
+ {value.map((tag, i) => (
+
+ {tag}
+
))}
>
) : (
@@ -210,7 +212,15 @@ const AllRules = React.memo(() => {
align: 'center',
field: 'activate',
name: 'Activate',
- render: (value: ColumnTypes['activate']) =>
,
+ render: (value: ColumnTypes['activate']) => (
+ // Michael: Errors occur when attempting to use "showLabel" prop. Likely need to wait for styled-components upgrade before uncommenting.
+
{}}
+ // showLabel={false}
+ />
+ ),
sortable: true,
width: '65px',
},
From 3557f1fdcc42182dd1a8e3cd1a50e7d1b2722a73 Mon Sep 17 00:00:00 2001
From: Michael Marcialis
Date: Thu, 31 Oct 2019 14:57:25 -0400
Subject: [PATCH 46/57] add empty page
---
.../detection_engine/detection_engine.tsx | 3 +-
.../detection_engine_empty_page.tsx | 29 +++++++++++++++
.../detection_engine/rule_details/index.tsx | 36 ++++++++++++++++++-
.../pages/detection_engine/rules/index.tsx | 2 +-
.../pages/detection_engine/translations.ts | 27 +++++++++-----
5 files changed, 86 insertions(+), 11 deletions(-)
create mode 100644 x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine_empty_page.tsx
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
index ed367a8b6b2df..981812c69fbd7 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
@@ -29,6 +29,7 @@ import {
} from '../../components/utility_bar';
import { indicesExistOrDataTemporarilyUnavailable, WithSource } from '../../containers/source';
import { SpyRoute } from '../../utils/route/spy_routes';
+import { DetectionEngineEmptyPage } from './detection_engine_empty_page';
import * as i18n from './translations';
const OpenSignals = React.memo(() => {
@@ -188,7 +189,7 @@ export const DetectionEngineComponent = React.memo(() => {
<>
- {/* */}
+
>
);
}}
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine_empty_page.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine_empty_page.tsx
new file mode 100644
index 0000000000000..cb3e690615395
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine_empty_page.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;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import React from 'react';
+import chrome from 'ui/chrome';
+import { documentationLinks } from 'ui/documentation_links';
+
+import { EmptyPage } from '../../components/empty_page';
+import * as i18n from './translations';
+
+const basePath = chrome.getBasePath();
+
+export const DetectionEngineEmptyPage = React.memo(() => (
+
+));
+DetectionEngineEmptyPage.displayName = 'DetectionEngineEmptyPage';
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.tsx
index 31978113f42b8..b3df33557c084 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.tsx
@@ -11,6 +11,7 @@ import {
EuiCallOut,
EuiFilterButton,
EuiFilterGroup,
+ EuiFlexGrid,
EuiFlexGroup,
EuiFlexItem,
EuiIconTip,
@@ -41,6 +42,7 @@ import {
} from '../../../components/utility_bar';
import { indicesExistOrDataTemporarilyUnavailable, WithSource } from '../../../containers/source';
import { SpyRoute } from '../../../utils/route/spy_routes';
+import { DetectionEngineEmptyPage } from '../detection_engine_empty_page';
import * as i18n from './translations';
// Michael: Will need to change this to get the current datetime format from Kibana settings.
@@ -565,6 +567,38 @@ export const RuleDetailsComponent = React.memo(() => {
+
+ {/* {'Description'}
*/}
+
+ {/*
+
+ {'Description'}
+
+
+
+ {'Severity'}
+
+
+
+ {'Risk score boost'}
+
+
+
+ {'References'}
+
+
+
+ {'False positives'}
+
+
+
+ {'Mitre ATT&CK types'}
+
+
+
+ {'Tags'}
+
+ */}
@@ -596,7 +630,7 @@ export const RuleDetailsComponent = React.memo(() => {
<>
- {/* */}
+
>
);
}}
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
index e594326c72802..bfe1fb2a104fe 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
@@ -213,7 +213,7 @@ const AllRules = React.memo(() => {
field: 'activate',
name: 'Activate',
render: (value: ColumnTypes['activate']) => (
- // Michael: Errors occur when attempting to use "showLabel" prop. Likely need to wait for styled-components upgrade before uncommenting.
+ // Michael: Uncomment props below when EUI 14.9.0 is added to Kibana.
Date: Thu, 31 Oct 2019 15:14:26 -0400
Subject: [PATCH 47/57] change to EuiButtonEmpty in HeaderGlobal
---
.../public/components/header_global/index.tsx | 8 ++--
.../components/ml_popover/ml_popover.tsx | 37 ++++++++++---------
2 files changed, 23 insertions(+), 22 deletions(-)
diff --git a/x-pack/legacy/plugins/siem/public/components/header_global/index.tsx b/x-pack/legacy/plugins/siem/public/components/header_global/index.tsx
index d3e2d948fa992..5db897bb86683 100644
--- a/x-pack/legacy/plugins/siem/public/components/header_global/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/header_global/index.tsx
@@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { EuiFlexGroup, EuiFlexItem, EuiIcon, EuiLink, EuiButton } from '@elastic/eui';
+import { EuiButtonEmpty, EuiFlexGroup, EuiFlexItem, EuiIcon, EuiLink } from '@elastic/eui';
import React from 'react';
import styled, { css } from 'styled-components';
@@ -54,19 +54,19 @@ export const HeaderGlobal = React.memo(({ offsetRight }) => (
-
+
-
{i18n.BUTTON_ADD_DATA}
-
+
diff --git a/x-pack/legacy/plugins/siem/public/components/ml_popover/ml_popover.tsx b/x-pack/legacy/plugins/siem/public/components/ml_popover/ml_popover.tsx
index 4dcdd282a12a8..0b33ab83d2a47 100644
--- a/x-pack/legacy/plugins/siem/public/components/ml_popover/ml_popover.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/ml_popover/ml_popover.tsx
@@ -4,29 +4,30 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { EuiButton, EuiCallOut, EuiPopover, EuiPopoverTitle, EuiSpacer } from '@elastic/eui';
+import { EuiButtonEmpty, EuiCallOut, EuiPopover, EuiPopoverTitle, EuiSpacer } from '@elastic/eui';
+import { FormattedMessage } from '@kbn/i18n/react';
+import moment from 'moment';
import React, { useContext, useReducer, useState } from 'react';
import styled from 'styled-components';
-import moment from 'moment';
-import { FormattedMessage } from '@kbn/i18n/react';
import { DOC_LINK_VERSION, ELASTIC_WEBSITE_URL } from 'ui/documentation_links';
-import * as i18n from './translations';
-import { JobsFilters, JobSummary, SiemJob } from './types';
+
+import { DEFAULT_KBN_VERSION } from '../../../common/constants';
+import { useKibanaUiSetting } from '../../lib/settings/use_kibana_ui_setting';
+import { METRIC_TYPE, TELEMETRY_EVENT, trackUiAction as track } from '../../lib/track_usage';
+import { errorToToaster } from '../ml/api/error_to_toaster';
import { hasMlAdminPermissions } from '../ml/permissions/has_ml_admin_permissions';
import { MlCapabilitiesContext } from '../ml/permissions/ml_capabilities_provider';
-import { JobsTable } from './jobs_table/jobs_table';
+import { useStateToaster } from '../toasters';
import { setupMlJob, startDatafeeds, stopDatafeeds } from './api';
-import { UpgradeContents } from './upgrade_contents';
+import { filterJobs } from './helpers';
+import { useSiemJobs } from './hooks/use_siem_jobs';
import { JobsTableFilters } from './jobs_table/filters/jobs_table_filters';
+import { JobsTable } from './jobs_table/jobs_table';
import { ShowingCount } from './jobs_table/showing_count';
import { PopoverDescription } from './popover_description';
-import { useStateToaster } from '../toasters';
-import { errorToToaster } from '../ml/api/error_to_toaster';
-import { METRIC_TYPE, TELEMETRY_EVENT, trackUiAction as track } from '../../lib/track_usage';
-import { useSiemJobs } from './hooks/use_siem_jobs';
-import { filterJobs } from './helpers';
-import { useKibanaUiSetting } from '../../lib/settings/use_kibana_ui_setting';
-import { DEFAULT_KBN_VERSION } from '../../../common/constants';
+import * as i18n from './translations';
+import { JobsFilters, JobSummary, SiemJob } from './types';
+import { UpgradeContents } from './upgrade_contents';
const PopoverContentsDiv = styled.div`
max-width: 684px;
@@ -161,14 +162,14 @@ export const MlPopover = React.memo(() => {
anchorPosition="downRight"
id="integrations-popover"
button={
- setIsPopoverOpen(!isPopoverOpen)}
>
{i18n.ANOMALY_DETECTION}
-
+
}
isOpen={isPopoverOpen}
closePopover={() => setIsPopoverOpen(!isPopoverOpen)}
@@ -183,7 +184,7 @@ export const MlPopover = React.memo(() => {
anchorPosition="downRight"
id="integrations-popover"
button={
- {
}}
>
{i18n.ANOMALY_DETECTION}
-
+
}
isOpen={isPopoverOpen}
closePopover={() => setIsPopoverOpen(!isPopoverOpen)}
From 93be3cce42713aa2e8ed73e2c6aa216c65b9221e Mon Sep 17 00:00:00 2001
From: Michael Marcialis
Date: Thu, 31 Oct 2019 15:23:57 -0400
Subject: [PATCH 48/57] overflow popover
---
.../detection_engine/rule_details/index.tsx | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.tsx
index b3df33557c084..112ef5bf46afd 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.tsx
@@ -16,6 +16,7 @@ import {
EuiFlexItem,
EuiIconTip,
EuiPanel,
+ EuiPopover,
EuiSelect,
EuiSpacer,
EuiSwitch,
@@ -496,6 +497,8 @@ const ActivityMonitor = React.memo(() => {
ActivityMonitor.displayName = 'ActivityMonitor';
export const RuleDetailsComponent = React.memo(() => {
+ const [popoverState, setPopoverState] = useState(false);
+
return (
<>
@@ -539,7 +542,19 @@ export const RuleDetailsComponent = React.memo(() => {
-
+ setPopoverState(!popoverState)}
+ />
+ }
+ closePopover={() => setPopoverState(false)}
+ isOpen={popoverState}
+ >
+ {'Overflow context menu here.'}
+
From 9b3d06cfcbfea794604a1c2c168f3190b673c0a2 Mon Sep 17 00:00:00 2001
From: Michael Marcialis
Date: Thu, 31 Oct 2019 15:49:36 -0400
Subject: [PATCH 49/57] rough out edit layout
---
.../detection_engine/edit_rule/index.tsx | 96 ++++++++++++++++++-
1 file changed, 91 insertions(+), 5 deletions(-)
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/edit_rule/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/edit_rule/index.tsx
index 86708a8544a79..4763f656826b5 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/edit_rule/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/edit_rule/index.tsx
@@ -4,13 +4,54 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { EuiButton } from '@elastic/eui';
+import {
+ EuiButton,
+ EuiFlexGroup,
+ EuiFlexItem,
+ EuiPanel,
+ EuiSpacer,
+ EuiTabbedContent,
+} from '@elastic/eui';
import React from 'react';
import { HeaderPage } from '../../../components/header_page';
+import { HeaderSection } from '../../../components/header_section';
import { SpyRoute } from '../../../utils/route/spy_routes';
import * as i18n from './translations';
+const Define = React.memo(() => (
+ <>
+
+
+
+
+
+ >
+));
+Define.displayName = 'Define';
+
+const About = React.memo(() => (
+ <>
+
+
+
+
+
+ >
+));
+About.displayName = 'About';
+
+const Schedule = React.memo(() => (
+ <>
+
+
+
+
+
+ >
+));
+Schedule.displayName = 'Schedule';
+
export const EditRuleComponent = React.memo(() => {
return (
<>
@@ -19,14 +60,59 @@ export const EditRuleComponent = React.memo(() => {
href: '#detection-engine/rules/rule-details',
text: 'Back to automated exfiltration',
}}
- border
title={i18n.PAGE_TITLE}
>
-
- {'Save changes'}
-
+
+
+
+ {'Cancel'}
+
+
+
+
+
+ {'Save changes'}
+
+
+
+ ,
+ },
+ {
+ id: 'tabAbout',
+ name: 'About',
+ content: ,
+ },
+ {
+ id: 'tabSchedule',
+ name: 'Schedule',
+ content: ,
+ },
+ ]}
+ />
+
+
+
+
+
+
+ {'Cancel'}
+
+
+
+
+
+ {'Save changes'}
+
+
+
+
>
);
From d6a42124525e9df7699972600291acf22289f7a6 Mon Sep 17 00:00:00 2001
From: Michael Marcialis
Date: Fri, 1 Nov 2019 12:35:33 -0400
Subject: [PATCH 50/57] new WrapperPage comp POC
---
.../filters_global/filters_global.tsx | 4 +-
.../public/components/header_global/index.tsx | 2 +-
.../public/components/header_page/index.tsx | 2 +-
.../__snapshots__/index.test.tsx.snap | 9 +
.../components/wrapper_page/index.test.tsx | 194 ++++++++++++
.../public/components/wrapper_page/index.tsx | 59 ++++
.../legacy/plugins/siem/public/pages/404.tsx | 6 +-
.../detection_engine/create_rule/index.tsx | 13 +-
.../detection_engine/detection_engine.tsx | 93 +++---
.../detection_engine/edit_rule/index.tsx | 98 +++---
.../detection_engine/rule_details/index.tsx | 205 +++++++------
.../pages/detection_engine/rules/index.tsx | 86 +++---
.../plugins/siem/public/pages/home/index.tsx | 112 ++++---
.../siem/public/pages/hosts/details/index.tsx | 186 +++++------
.../plugins/siem/public/pages/hosts/hosts.tsx | 103 ++++---
.../public/pages/network/ip_details/index.tsx | 289 +++++++++---------
.../siem/public/pages/network/network.tsx | 135 ++++----
.../siem/public/pages/overview/overview.tsx | 75 ++---
.../public/pages/timelines/timelines_page.tsx | 24 +-
19 files changed, 986 insertions(+), 709 deletions(-)
create mode 100644 x-pack/legacy/plugins/siem/public/components/wrapper_page/__snapshots__/index.test.tsx.snap
create mode 100644 x-pack/legacy/plugins/siem/public/components/wrapper_page/index.test.tsx
create mode 100644 x-pack/legacy/plugins/siem/public/components/wrapper_page/index.tsx
diff --git a/x-pack/legacy/plugins/siem/public/components/filters_global/filters_global.tsx b/x-pack/legacy/plugins/siem/public/components/filters_global/filters_global.tsx
index ddcfa86e42b05..90e83fadef48d 100644
--- a/x-pack/legacy/plugins/siem/public/components/filters_global/filters_global.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/filters_global/filters_global.tsx
@@ -22,8 +22,8 @@ const Aside = styled.aside<{ isSticky?: boolean }>`
z-index: ${props.theme.eui.euiZNavigation};
background: ${props.theme.eui.euiColorEmptyShade};
border-bottom: ${props.theme.eui.euiBorderThin};
- box-sizing: content-box;
- margin: 0 -${gutterTimeline} 0 -${props.theme.eui.euiSizeL};
+ // box-sizing: content-box;
+ // margin: 0 -${gutterTimeline} 0 -${props.theme.eui.euiSizeL};
padding: ${props.theme.eui.euiSize} ${gutterTimeline} ${props.theme.eui.euiSize} ${
props.theme.eui.euiSizeL
};
diff --git a/x-pack/legacy/plugins/siem/public/components/header_global/index.tsx b/x-pack/legacy/plugins/siem/public/components/header_global/index.tsx
index 5db897bb86683..e92bc7cd6a91f 100644
--- a/x-pack/legacy/plugins/siem/public/components/header_global/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/header_global/index.tsx
@@ -24,7 +24,7 @@ const Header = styled.header.attrs({
${({ offsetRight, theme }) => css`
background: ${theme.eui.euiColorEmptyShade};
border-bottom: ${theme.eui.euiBorderThin};
- margin: 0 -${offsetRight ? offsetRight : theme.eui.euiSizeL} 0 -${theme.eui.euiSizeL};
+ // margin: 0 -${offsetRight ? offsetRight : theme.eui.euiSizeL} 0 -${theme.eui.euiSizeL};
padding: ${theme.eui.paddingSizes.m} ${offsetRight ? offsetRight : theme.eui.paddingSizes.l}
${theme.eui.paddingSizes.m} ${theme.eui.paddingSizes.l};
`}
diff --git a/x-pack/legacy/plugins/siem/public/components/header_page/index.tsx b/x-pack/legacy/plugins/siem/public/components/header_page/index.tsx
index bc6e5c699257d..4db2a35c600e9 100644
--- a/x-pack/legacy/plugins/siem/public/components/header_page/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/header_page/index.tsx
@@ -20,7 +20,7 @@ const Header = styled.header.attrs({
className: 'siemHeaderPage',
})`
${({ border, theme }) => css`
- margin: ${theme.eui.euiSizeL} 0;
+ margin-bottom: ${theme.eui.euiSizeL};
${border &&
css`
diff --git a/x-pack/legacy/plugins/siem/public/components/wrapper_page/__snapshots__/index.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/wrapper_page/__snapshots__/index.test.tsx.snap
new file mode 100644
index 0000000000000..ecd2b15a841f6
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/components/wrapper_page/__snapshots__/index.test.tsx.snap
@@ -0,0 +1,9 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`HeaderSection it renders 1`] = `
+
+
+
+`;
diff --git a/x-pack/legacy/plugins/siem/public/components/wrapper_page/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/wrapper_page/index.test.tsx
new file mode 100644
index 0000000000000..fffeece818d13
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/components/wrapper_page/index.test.tsx
@@ -0,0 +1,194 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import euiDarkVars from '@elastic/eui/dist/eui_theme_dark.json';
+import { mount, shallow } from 'enzyme';
+import toJson from 'enzyme-to-json';
+import 'jest-styled-components';
+import React from 'react';
+
+import { TestProviders } from '../../mock';
+import '../../mock/ui_settings';
+import { HeaderSection } from './index';
+
+jest.mock('../../lib/settings/use_kibana_ui_setting');
+
+describe('HeaderSection', () => {
+ test('it renders', () => {
+ const wrapper = shallow(
+
+
+
+ );
+
+ expect(toJson(wrapper)).toMatchSnapshot();
+ });
+
+ test('it renders the title', () => {
+ const wrapper = mount(
+
+
+
+ );
+
+ expect(
+ wrapper
+ .find('[data-test-subj="header-section-title"]')
+ .first()
+ .exists()
+ ).toBe(true);
+ });
+
+ test('it renders the subtitle when provided', () => {
+ const wrapper = mount(
+
+
+
+ );
+
+ expect(
+ wrapper
+ .find('[data-test-subj="header-section-subtitle"]')
+ .first()
+ .exists()
+ ).toBe(true);
+ });
+
+ test('it DOES NOT render the subtitle when not provided', () => {
+ const wrapper = mount(
+
+
+
+ );
+
+ expect(
+ wrapper
+ .find('[data-test-subj="header-section-subtitle"]')
+ .first()
+ .exists()
+ ).toBe(false);
+ });
+
+ test('it renders a transparent inspect button when showInspect is false', () => {
+ const wrapper = mount(
+
+
+
+ );
+
+ expect(
+ wrapper
+ .find('[data-test-subj="transparent-inspect-container"]')
+ .first()
+ .exists()
+ ).toBe(true);
+ });
+
+ test('it renders an opaque inspect button when showInspect is true', () => {
+ const wrapper = mount(
+
+
+
+ );
+
+ expect(
+ wrapper
+ .find('[data-test-subj="opaque-inspect-container"]')
+ .first()
+ .exists()
+ ).toBe(true);
+ });
+
+ test('it renders supplements when children provided', () => {
+ const wrapper = mount(
+
+
+ {'Test children'}
+
+
+ );
+
+ expect(
+ wrapper
+ .find('[data-test-subj="header-section-supplements"]')
+ .first()
+ .exists()
+ ).toBe(true);
+ });
+
+ test('it DOES NOT render supplements when children not provided', () => {
+ const wrapper = mount(
+
+
+
+ );
+
+ expect(
+ wrapper
+ .find('[data-test-subj="header-section-supplements"]')
+ .first()
+ .exists()
+ ).toBe(false);
+ });
+
+ test('it applies border styles when border is true', () => {
+ const wrapper = mount(
+
+
+
+ );
+ const siemHeaderSection = wrapper.find('.siemHeaderSection').first();
+
+ expect(siemHeaderSection).toHaveStyleRule('border-bottom', euiDarkVars.euiBorderThin);
+ expect(siemHeaderSection).toHaveStyleRule('padding-bottom', euiDarkVars.paddingSizes.l);
+ });
+
+ test('it DOES NOT apply border styles when border is false', () => {
+ const wrapper = mount(
+
+
+
+ );
+ const siemHeaderSection = wrapper.find('.siemHeaderSection').first();
+
+ expect(siemHeaderSection).not.toHaveStyleRule('border-bottom', euiDarkVars.euiBorderThin);
+ expect(siemHeaderSection).not.toHaveStyleRule('padding-bottom', euiDarkVars.paddingSizes.l);
+ });
+
+ test('it splits the title and supplement areas evenly when split is true', () => {
+ const wrapper = mount(
+
+
+ {'Test children'}
+
+
+ );
+
+ expect(
+ wrapper
+ .find('.euiFlexItem--flexGrowZero[data-test-subj="header-section-supplements"]')
+ .first()
+ .exists()
+ ).toBe(false);
+ });
+
+ test('it DOES NOT split the title and supplement areas evenly when split is false', () => {
+ const wrapper = mount(
+
+
+ {'Test children'}
+
+
+ );
+
+ expect(
+ wrapper
+ .find('.euiFlexItem--flexGrowZero[data-test-subj="header-section-supplements"]')
+ .first()
+ .exists()
+ ).toBe(true);
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/components/wrapper_page/index.tsx b/x-pack/legacy/plugins/siem/public/components/wrapper_page/index.tsx
new file mode 100644
index 0000000000000..473d1cbacfdeb
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/components/wrapper_page/index.tsx
@@ -0,0 +1,59 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import classNames from 'classnames';
+import React from 'react';
+import styled, { css } from 'styled-components';
+
+const Wrapper = styled.div`
+ ${({ theme }) => css`
+ padding: ${theme.eui.paddingSizes.l} 70px ${theme.eui.paddingSizes.l}
+ ${theme.eui.paddingSizes.l};
+
+ &.siemWrapperPage--restrictWidthDefault,
+ &.siemWrapperPage--restrictWidthCustom {
+ box-sizing: content-box;
+ margin: 0 auto;
+ }
+
+ &.siemWrapperPage--restrictWidthDefault {
+ max-width: 1000px;
+ }
+ `}
+`;
+Wrapper.displayName = 'Wrapper';
+
+export interface WrapperPageProps {
+ children: React.ReactNode;
+ className?: string;
+ restrictWidth?: boolean | number | string;
+ style?: Record;
+}
+
+export const WrapperPage = React.memo(
+ ({ children, className, restrictWidth, style }) => {
+ const classes = classNames(className, {
+ siemWrapperPage: true,
+ 'siemWrapperPage--restrictWidthDefault':
+ restrictWidth && typeof restrictWidth === 'boolean' && restrictWidth === true,
+ 'siemWrapperPage--restrictWidthCustom': restrictWidth && typeof restrictWidth !== 'boolean',
+ });
+
+ let customStyle: WrapperPageProps['style'];
+
+ if (restrictWidth && typeof restrictWidth !== 'boolean') {
+ const value = typeof restrictWidth === 'number' ? `${restrictWidth}px` : restrictWidth;
+ customStyle = { ...style, maxWidth: value };
+ }
+
+ return (
+
+ {children}
+
+ );
+ }
+);
+WrapperPage.displayName = 'WrapperPage';
diff --git a/x-pack/legacy/plugins/siem/public/pages/404.tsx b/x-pack/legacy/plugins/siem/public/pages/404.tsx
index 58a3c904b89a0..aa091e541f244 100644
--- a/x-pack/legacy/plugins/siem/public/pages/404.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/404.tsx
@@ -8,13 +8,15 @@ import React from 'react';
import { pure } from 'recompose';
import { FormattedMessage } from '@kbn/i18n/react';
+import { WrapperPage } from '../components/wrapper_page';
+
export const NotFoundPage = pure(() => (
-
+
-
+
));
NotFoundPage.displayName = 'NotFoundPage';
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/create_rule/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/create_rule/index.tsx
index 5023d2cb58660..47a3527aff99c 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/create_rule/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/create_rule/index.tsx
@@ -7,17 +7,20 @@
import React from 'react';
import { HeaderPage } from '../../../components/header_page';
+import { WrapperPage } from '../../../components/wrapper_page';
import { SpyRoute } from '../../../utils/route/spy_routes';
import * as i18n from './translations';
export const CreateRuleComponent = React.memo(() => {
return (
<>
-
+
+
+
>
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
index 981812c69fbd7..d872e7b602316 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
@@ -27,6 +27,7 @@ import {
UtilityBarSection,
UtilityBarText,
} from '../../components/utility_bar';
+import { WrapperPage } from '../../components/wrapper_page';
import { indicesExistOrDataTemporarilyUnavailable, WithSource } from '../../containers/source';
import { SpyRoute } from '../../utils/route/spy_routes';
import { DetectionEngineEmptyPage } from './detection_engine_empty_page';
@@ -141,56 +142,58 @@ export const DetectionEngineComponent = React.memo(() => {
-
-
- {i18n.BUTTON_MANAGE_RULES}
-
-
-
-
-
- {}}
- prepend="Stack by"
- value={sampleChartOptions[0].value}
- />
-
-
-
-
-
-
-
-
-
-
- setFilterGroupState(filterGroupOptions[0])}
- withNext
- >
- {'Open signals'}
-
-
- setFilterGroupState(filterGroupOptions[1])}
- >
- {'Closed signals'}
-
-
-
-
- {filterGroupState === filterGroupOptions[0] ? : }
-
+
+
+
+ {i18n.BUTTON_MANAGE_RULES}
+
+
+
+
+
+ {}}
+ prepend="Stack by"
+ value={sampleChartOptions[0].value}
+ />
+
+
+
+
+
+
+
+
+
+
+ setFilterGroupState(filterGroupOptions[0])}
+ withNext
+ >
+ {'Open signals'}
+
+
+ setFilterGroupState(filterGroupOptions[1])}
+ >
+ {'Closed signals'}
+
+
+
+
+ {filterGroupState === filterGroupOptions[0] ? : }
+
+
) : (
- <>
+
- >
+
);
}}
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/edit_rule/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/edit_rule/index.tsx
index 4763f656826b5..9b8607fdc7685 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/edit_rule/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/edit_rule/index.tsx
@@ -16,6 +16,7 @@ import React from 'react';
import { HeaderPage } from '../../../components/header_page';
import { HeaderSection } from '../../../components/header_section';
+import { WrapperPage } from '../../../components/wrapper_page';
import { SpyRoute } from '../../../utils/route/spy_routes';
import * as i18n from './translations';
@@ -55,14 +56,57 @@ Schedule.displayName = 'Schedule';
export const EditRuleComponent = React.memo(() => {
return (
<>
-
-
+
+
+
+
+
+ {'Cancel'}
+
+
+
+
+
+ {'Save changes'}
+
+
+
+
+
+ ,
+ },
+ {
+ id: 'tabAbout',
+ name: 'About',
+ content: ,
+ },
+ {
+ id: 'tabSchedule',
+ name: 'Schedule',
+ content: ,
+ },
+ ]}
+ />
+
+
+
+
{'Cancel'}
@@ -75,43 +119,7 @@ export const EditRuleComponent = React.memo(() => {
-
-
- ,
- },
- {
- id: 'tabAbout',
- name: 'About',
- content: ,
- },
- {
- id: 'tabSchedule',
- name: 'Schedule',
- content: ,
- },
- ]}
- />
-
-
-
-
-
-
- {'Cancel'}
-
-
-
-
-
- {'Save changes'}
-
-
-
+
>
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.tsx
index 112ef5bf46afd..192814e8a35e5 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.tsx
@@ -41,6 +41,7 @@ import {
UtilityBarSection,
UtilityBarText,
} from '../../../components/utility_bar';
+import { WrapperPage } from '../../../components/wrapper_page';
import { indicesExistOrDataTemporarilyUnavailable, WithSource } from '../../../containers/source';
import { SpyRoute } from '../../../utils/route/spy_routes';
import { DetectionEngineEmptyPage } from '../detection_engine_empty_page';
@@ -509,83 +510,84 @@ export const RuleDetailsComponent = React.memo(() => {
-
- {'Status: Running'}
- ,
- ]}
- title="Automated exfiltration"
- >
-
-
- {}} />
+
+
+ {'Status: Running'}
+ ,
+ ]}
+ title="Automated exfiltration"
+ >
+
+
+ {}} />
+
+
+
+
+
+
+ {'Edit rule settings'}
+
+
+
+
+ setPopoverState(!popoverState)}
+ />
+ }
+ closePopover={() => setPopoverState(false)}
+ isOpen={popoverState}
+ >
+ {'Overflow context menu here.'}
+
+
+
+
+
+
+
+
+ {'Full fail message here.'}
+
+
+
+
+
+
+
+
+
-
-
-
-
- {'Edit rule settings'}
-
-
-
-
- setPopoverState(!popoverState)}
- />
- }
- closePopover={() => setPopoverState(false)}
- isOpen={popoverState}
- >
- {'Overflow context menu here.'}
-
-
-
-
-
-
-
-
- {'Full fail message here.'}
-
-
-
+
+
+
-
-
-
-
-
-
+ {/* {'Description'}
*/}
-
-
-
-
- {/* {'Description'}
*/}
-
- {/*
+ {/*
{'Description'}
@@ -614,39 +616,40 @@ export const RuleDetailsComponent = React.memo(() => {
{'Tags'}
*/}
-
-
-
-
-
-
-
-
-
-
-
-
- ,
- },
- {
- id: 'tabActivityMonitor',
- name: 'Activity monitor',
- content: ,
- },
- ]}
- />
+
+
+
+
+
+
+
+
+
+
+
+
+ ,
+ },
+ {
+ id: 'tabActivityMonitor',
+ name: 'Activity monitor',
+ content: ,
+ },
+ ]}
+ />
+
) : (
- <>
+
- >
+
);
}}
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
index bfe1fb2a104fe..e4be8fe81c2ea 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
@@ -27,7 +27,6 @@ import React, { useState } from 'react';
import { getEmptyTagValue } from '../../../components/empty_value';
import { HeaderPage } from '../../../components/header_page';
import { HeaderSection } from '../../../components/header_section';
-// import { LinkIcon } from '../../../components/link_icon';
import {
UtilityBar,
UtilityBarAction,
@@ -35,6 +34,7 @@ import {
UtilityBarSection,
UtilityBarText,
} from '../../../components/utility_bar';
+import { WrapperPage } from '../../../components/wrapper_page';
import { SpyRoute } from '../../../utils/route/spy_routes';
import * as i18n from './translations';
@@ -606,8 +606,6 @@ const AllRules = React.memo(() => {
{
direction: string;
}
- // const actions = [
- // {
- // render: (item: ColumnTypes) => {
- // if (item.status === 'Running') {
- // return {'Stop'};
- // } else if (item.status === 'Stopped') {
- // return {'Resume'};
- // } else {
- // return <>{''}>;
- // }
- // },
- // },
- // ];
-
const actions = [
{
available: (item: ColumnTypes) => item.status === 'Running',
@@ -1019,8 +1003,6 @@ const ActivityMonitor = React.memo(() => {
{
return (
<>
-
-
-
-
- {'Import rule…'}
-
-
+
+
+
+
+
+ {'Import rule…'}
+
+
-
-
- {'Add new rule'}
-
-
-
-
+
+
+ {'Add new rule'}
+
+
+
+
- ,
- },
- {
- id: 'tabActivityMonitor',
- name: 'Activity monitor',
- content: ,
- },
- ]}
- />
+ ,
+ },
+ {
+ id: 'tabActivityMonitor',
+ name: 'Activity monitor',
+ content: ,
+ },
+ ]}
+ />
+
>
diff --git a/x-pack/legacy/plugins/siem/public/pages/home/index.tsx b/x-pack/legacy/plugins/siem/public/pages/home/index.tsx
index ff3c9e1a18414..71683bd578b98 100644
--- a/x-pack/legacy/plugins/siem/public/pages/home/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/home/index.tsx
@@ -4,10 +4,8 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { EuiPage, EuiPageBody } from '@elastic/eui';
import * as React from 'react';
import { Redirect, Route, Switch } from 'react-router-dom';
-import { pure } from 'recompose';
import styled from 'styled-components';
import { AutoSizer } from '../../components/auto_sizer';
@@ -46,13 +44,6 @@ WrappedByAutoSizer.displayName = 'WrappedByAutoSizer';
const gutterTimeline = '70px'; // Temporary until timeline is moved - MichaelMarcialis
-const Page = styled(EuiPage)`
- ${({ theme }) => `
- padding: 0 ${gutterTimeline} ${theme.eui.paddingSizes.l} ${theme.eui.paddingSizes.l};
- `}
-`;
-Page.displayName = 'Page';
-
const usersViewing = ['elastic']; // TODO: get the users viewing this timeline from Elasticsearch (persistance)
/** the global Kibana navigation at the top of every page */
@@ -66,12 +57,13 @@ const calculateFlyoutHeight = ({
windowHeight: number;
}): number => Math.max(0, windowHeight - globalHeaderSize);
-export const HomePage = pure(() => (
+export const HomePage = React.memo(() => (
{({ measureRef, windowMeasurement: { height: windowHeight = 0 } }) => (
-
-
+
+
+
{({ browserFields, indexPattern }) => (
@@ -96,61 +88,59 @@ export const HomePage = pure(() => (
/>
-
-
-
-
-
- }
- />
- (
-
- )}
- />
- (
-
- )}
- />
- (
-
- )}
- />
- }
- />
-
- (
-
- )}
- />
- (
-
- )}
- />
-
-
-
+
+
+ }
+ />
+ (
+
+ )}
+ />
+ (
+
+ )}
+ />
+ (
+
+ )}
+ />
+ }
+ />
+
+ (
+
+ )}
+ />
+ (
+
+ )}
+ />
+
+
)}
-
+
+
+
+
)}
));
-
HomePage.displayName = 'HomePage';
diff --git a/x-pack/legacy/plugins/siem/public/pages/hosts/details/index.tsx b/x-pack/legacy/plugins/siem/public/pages/hosts/details/index.tsx
index e7c5209369519..80a3d318ea476 100644
--- a/x-pack/legacy/plugins/siem/public/pages/hosts/details/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/hosts/details/index.tsx
@@ -24,6 +24,7 @@ import { KpiHostsComponent } from '../../../components/page/hosts';
import { HostOverview } from '../../../components/page/hosts/host_overview';
import { manageQuery } from '../../../components/page/manage_query';
import { SiemSearchBar } from '../../../components/search_bar';
+import { WrapperPage } from '../../../components/wrapper_page';
import { HostOverviewByNameQuery } from '../../../containers/hosts/overview';
import { KpiHostDetailsQuery } from '../../../containers/kpi_host_details';
import { indicesExistOrDataTemporarilyUnavailable, WithSource } from '../../../containers/source';
@@ -101,108 +102,113 @@ const HostDetailsComponent = React.memo(
-
- }
- title={detailName}
- />
+
+
+ }
+ title={detailName}
+ />
-
- {({ hostOverview, loading, id, inspect, refetch }) => (
-
- {({ isLoadingAnomaliesData, anomaliesData }) => (
- {
- const fromTo = scoreIntervalToDateTime(score, interval);
- setAbsoluteRangeDatePicker({
- id: 'global',
- from: fromTo.from,
- to: fromTo.to,
- });
- }}
- />
- )}
-
- )}
-
+
+ {({ hostOverview, loading, id, inspect, refetch }) => (
+
+ {({ isLoadingAnomaliesData, anomaliesData }) => (
+ {
+ const fromTo = scoreIntervalToDateTime(score, interval);
+ setAbsoluteRangeDatePicker({
+ id: 'global',
+ from: fromTo.from,
+ to: fromTo.to,
+ });
+ }}
+ />
+ )}
+
+ )}
+
-
+
-
- {({ kpiHostDetails, id, inspect, loading, refetch }) => (
- {
- setAbsoluteRangeDatePicker({ id: 'global', from: min, to: max });
- }}
- />
- )}
-
+
+ {({ kpiHostDetails, id, inspect, loading, refetch }) => (
+ {
+ setAbsoluteRangeDatePicker({ id: 'global', from: min, to: max });
+ }}
+ />
+ )}
+
-
+
-
+
-
+
-
+
+
) : (
- <>
+
- >
+
);
}}
diff --git a/x-pack/legacy/plugins/siem/public/pages/hosts/hosts.tsx b/x-pack/legacy/plugins/siem/public/pages/hosts/hosts.tsx
index 65d12697fbb63..a838a40996452 100644
--- a/x-pack/legacy/plugins/siem/public/pages/hosts/hosts.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/hosts/hosts.tsx
@@ -20,6 +20,7 @@ import { SiemNavigation } from '../../components/navigation';
import { KpiHostsComponent } from '../../components/page/hosts';
import { manageQuery } from '../../components/page/manage_query';
import { SiemSearchBar } from '../../components/search_bar';
+import { WrapperPage } from '../../components/wrapper_page';
import { GlobalTimeArgs } from '../../containers/global_time';
import { KpiHostsQuery } from '../../containers/kpi_hosts';
import { indicesExistOrDataTemporarilyUnavailable, WithSource } from '../../containers/source';
@@ -68,61 +69,63 @@ const HostsComponent = React.memo(
- }
- title={i18n.PAGE_TITLE}
- />
-
-
- {({ kpiHosts, loading, id, inspect, refetch }) => (
- {
- setAbsoluteRangeDatePicker({ id: 'global', from: min, to: max });
- }}
- />
- )}
-
-
-
-
-
-
-
-
-
+
+ }
+ title={i18n.PAGE_TITLE}
+ />
+
+
+ {({ kpiHosts, loading, id, inspect, refetch }) => (
+ {
+ setAbsoluteRangeDatePicker({ id: 'global', from: min, to: max });
+ }}
+ />
+ )}
+
+
+
+
+
+
+
+
+
+
) : (
- <>
+
- >
+
);
}}
diff --git a/x-pack/legacy/plugins/siem/public/pages/network/ip_details/index.tsx b/x-pack/legacy/plugins/siem/public/pages/network/ip_details/index.tsx
index a4ace6cb51141..1b39b0ae096ec 100644
--- a/x-pack/legacy/plugins/siem/public/pages/network/ip_details/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/network/ip_details/index.tsx
@@ -21,6 +21,7 @@ import { manageQuery } from '../../../components/page/manage_query';
import { FlowTargetSelectConnected } from '../../../components/page/network/flow_target_select_connected';
import { IpOverview } from '../../../components/page/network/ip_overview';
import { SiemSearchBar } from '../../../components/search_bar';
+import { WrapperPage } from '../../../components/wrapper_page';
import { IpOverviewQuery } from '../../../containers/ip_overview';
import { indicesExistOrDataTemporarilyUnavailable, WithSource } from '../../../containers/source';
import { FlowTargetSourceDest, LastEventIndexKey } from '../../../graphql/types';
@@ -90,167 +91,169 @@ export const IPDetailsComponent = React.memo(
- }
- title={ip}
- >
-
-
+
+ }
+ title={ip}
+ >
+
+
-
- {({ id, inspect, ipOverviewData, loading, refetch }) => (
-
- {({ isLoadingAnomaliesData, anomaliesData }) => (
- {
- const fromTo = scoreIntervalToDateTime(score, interval);
- setAbsoluteRangeDatePicker({
- id: 'global',
- from: fromTo.from,
- to: fromTo.to,
- });
- }}
- />
- )}
-
- )}
-
+
+ {({ id, inspect, ipOverviewData, loading, refetch }) => (
+
+ {({ isLoadingAnomaliesData, anomaliesData }) => (
+ {
+ const fromTo = scoreIntervalToDateTime(score, interval);
+ setAbsoluteRangeDatePicker({
+ id: 'global',
+ from: fromTo.from,
+ to: fromTo.to,
+ });
+ }}
+ />
+ )}
+
+ )}
+
-
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
+
-
+
-
+
-
+
-
+
-
+
+
) : (
- <>
+
- >
+
);
}}
diff --git a/x-pack/legacy/plugins/siem/public/pages/network/network.tsx b/x-pack/legacy/plugins/siem/public/pages/network/network.tsx
index 24f54184ba1ca..d135a797567fa 100644
--- a/x-pack/legacy/plugins/siem/public/pages/network/network.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/network/network.tsx
@@ -18,6 +18,7 @@ import { SiemNavigation } from '../../components/navigation';
import { manageQuery } from '../../components/page/manage_query';
import { KpiNetworkComponent } from '../../components/page/network';
import { SiemSearchBar } from '../../components/search_bar';
+import { WrapperPage } from '../../components/wrapper_page';
import { KpiNetworkQuery } from '../../containers/kpi_network';
import { indicesExistOrDataTemporarilyUnavailable, WithSource } from '../../containers/source';
import { LastEventIndexKey } from '../../graphql/types';
@@ -64,77 +65,79 @@ const NetworkComponent = React.memo(
- }
- title={i18n.PAGE_TITLE}
- />
-
-
-
-
-
-
- {({ kpiNetwork, loading, id, inspect, refetch }) => (
- {
- setAbsoluteRangeDatePicker({ id: 'global', from: min, to: max });
- }}
- />
+
+ }
+ title={i18n.PAGE_TITLE}
+ />
+
+
+
+
+
+
+ {({ kpiNetwork, loading, id, inspect, refetch }) => (
+ {
+ setAbsoluteRangeDatePicker({ id: 'global', from: min, to: max });
+ }}
+ />
+ )}
+
+
+ {capabilitiesFetched && !isInitializing ? (
+ <>
+
+
+
+
+
+
+
+ >
+ ) : (
+
)}
-
-
- {capabilitiesFetched && !isInitializing ? (
- <>
-
-
-
-
-
-
-
- >
- ) : (
-
- )}
-
-
+
+
+
) : (
- <>
+
- >
+
);
}}
diff --git a/x-pack/legacy/plugins/siem/public/pages/overview/overview.tsx b/x-pack/legacy/plugins/siem/public/pages/overview/overview.tsx
index f94e460eef4b9..d13cc45562039 100644
--- a/x-pack/legacy/plugins/siem/public/pages/overview/overview.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/overview/overview.tsx
@@ -14,13 +14,12 @@ import { documentationLinks } from 'ui/documentation_links';
import { HeaderPage } from '../../components/header_page';
import { OverviewHost } from '../../components/page/overview/overview_host';
import { OverviewNetwork } from '../../components/page/overview/overview_network';
+import { WrapperPage } from '../../components/wrapper_page';
import { GlobalTime } from '../../containers/global_time';
-
import { Summary } from './summary';
import { EmptyPage } from '../../components/empty_page';
import { WithSource, indicesExistOrDataTemporarilyUnavailable } from '../../containers/source';
import { SpyRoute } from '../../utils/route/spy_routes';
-
import * as i18n from './translations';
const basePath = chrome.getBasePath();
@@ -32,40 +31,46 @@ export const OverviewComponent = pure(() => {
return (
<>
-
+
+
-
- {({ indicesExist }) =>
- indicesExistOrDataTemporarilyUnavailable(indicesExist) ? (
-
- {({ setQuery }) => (
-
-
-
-
-
- )}
-
- ) : (
-
- )
- }
-
+
+ {({ indicesExist }) =>
+ indicesExistOrDataTemporarilyUnavailable(indicesExist) ? (
+
+ {({ setQuery }) => (
+
+
+
+
+
+ )}
+
+ ) : (
+
+ )
+ }
+
+
>
);
diff --git a/x-pack/legacy/plugins/siem/public/pages/timelines/timelines_page.tsx b/x-pack/legacy/plugins/siem/public/pages/timelines/timelines_page.tsx
index c4791cbda3396..4431beaa704b5 100644
--- a/x-pack/legacy/plugins/siem/public/pages/timelines/timelines_page.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/timelines/timelines_page.tsx
@@ -10,8 +10,8 @@ import styled from 'styled-components';
import { HeaderPage } from '../../components/header_page';
import { StatefulOpenTimeline } from '../../components/open_timeline';
+import { WrapperPage } from '../../components/wrapper_page';
import { SpyRoute } from '../../utils/route/spy_routes';
-
import * as i18n from './translations';
const TimelinesContainer = styled.div`
@@ -30,16 +30,18 @@ export const DEFAULT_SEARCH_RESULTS_PER_PAGE = 10;
export const TimelinesPage = React.memo(({ apolloClient }) => (
<>
-
-
-
-
-
+
+
+
+
+
+
+
>
));
From 9a61c884dbd94083345727f2dabd63a0f22f71bf Mon Sep 17 00:00:00 2001
From: Michael Marcialis
Date: Fri, 1 Nov 2019 12:47:10 -0400
Subject: [PATCH 51/57] cleanup
---
x-pack/legacy/plugins/siem/public/pages/404.tsx | 4 +---
.../siem/public/pages/hosts/details/index.tsx | 3 +++
.../plugins/siem/public/pages/hosts/hosts.tsx | 1 +
.../public/pages/network/ip_details/index.tsx | 15 ++++++++-------
.../plugins/siem/public/pages/network/network.tsx | 4 +++-
.../siem/public/pages/overview/overview.tsx | 9 ++++-----
.../public/pages/timelines/timelines_page.tsx | 2 +-
7 files changed, 21 insertions(+), 17 deletions(-)
diff --git a/x-pack/legacy/plugins/siem/public/pages/404.tsx b/x-pack/legacy/plugins/siem/public/pages/404.tsx
index aa091e541f244..37049033a6b0a 100644
--- a/x-pack/legacy/plugins/siem/public/pages/404.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/404.tsx
@@ -5,12 +5,11 @@
*/
import React from 'react';
-import { pure } from 'recompose';
import { FormattedMessage } from '@kbn/i18n/react';
import { WrapperPage } from '../components/wrapper_page';
-export const NotFoundPage = pure(() => (
+export const NotFoundPage = React.memo(() => (
(
/>
));
-
NotFoundPage.displayName = 'NotFoundPage';
diff --git a/x-pack/legacy/plugins/siem/public/pages/hosts/details/index.tsx b/x-pack/legacy/plugins/siem/public/pages/hosts/details/index.tsx
index 80a3d318ea476..2cb193fb47c6b 100644
--- a/x-pack/legacy/plugins/siem/public/pages/hosts/details/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/hosts/details/index.tsx
@@ -63,6 +63,7 @@ const HostDetailsComponent = React.memo(
}, [detailName]);
const capabilities = useContext(MlCapabilitiesContext);
const core = useKibanaCore();
+
return (
<>
@@ -96,6 +97,7 @@ const HostDetailsComponent = React.memo(
...filters,
],
});
+
return indicesExistOrDataTemporarilyUnavailable(indicesExist) ? (
@@ -212,6 +214,7 @@ const HostDetailsComponent = React.memo(
);
}}
+
>
);
diff --git a/x-pack/legacy/plugins/siem/public/pages/hosts/hosts.tsx b/x-pack/legacy/plugins/siem/public/pages/hosts/hosts.tsx
index a838a40996452..1dc21c9d0284f 100644
--- a/x-pack/legacy/plugins/siem/public/pages/hosts/hosts.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/hosts/hosts.tsx
@@ -129,6 +129,7 @@ const HostsComponent = React.memo(
);
}}
+
>
);
diff --git a/x-pack/legacy/plugins/siem/public/pages/network/ip_details/index.tsx b/x-pack/legacy/plugins/siem/public/pages/network/ip_details/index.tsx
index 1b39b0ae096ec..ff03f84089e61 100644
--- a/x-pack/legacy/plugins/siem/public/pages/network/ip_details/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/network/ip_details/index.tsx
@@ -25,6 +25,7 @@ import { WrapperPage } from '../../../components/wrapper_page';
import { IpOverviewQuery } from '../../../containers/ip_overview';
import { indicesExistOrDataTemporarilyUnavailable, WithSource } from '../../../containers/source';
import { FlowTargetSourceDest, LastEventIndexKey } from '../../../graphql/types';
+import { useKibanaCore } from '../../../lib/compose/kibana_core';
import { decodeIpv6 } from '../../../lib/helpers';
import { convertToBuildEsQuery } from '../../../lib/keury';
import { ConditionalFlexGroup } from '../../../pages/network/navigation/conditional_flex_group';
@@ -33,14 +34,13 @@ import { setAbsoluteRangeDatePicker as dispatchAbsoluteRangeDatePicker } from '.
import { setIpDetailsTablesActivePageToZero as dispatchIpDetailsTablesActivePageToZero } from '../../../store/network/actions';
import { SpyRoute } from '../../../utils/route/spy_routes';
import { NetworkEmptyPage } from '../network_empty_page';
-
-import { IPDetailsComponentProps } from './types';
-export { getBreadcrumbs } from './utils';
+import { NetworkTopCountriesQueryTable } from './network_top_countries_query_table';
+import { NetworkTopNFlowQueryTable } from './network_top_n_flow_query_table';
import { TlsQueryTable } from './tls_query_table';
+import { IPDetailsComponentProps } from './types';
import { UsersQueryTable } from './users_query_table';
-import { NetworkTopNFlowQueryTable } from './network_top_n_flow_query_table';
-import { NetworkTopCountriesQueryTable } from './network_top_countries_query_table';
-import { useKibanaCore } from '../../../lib/compose/kibana_core';
+
+export { getBreadcrumbs } from './utils';
const IpOverviewManage = manageQuery(IpOverview);
@@ -85,6 +85,7 @@ export const IPDetailsComponent = React.memo(
queries: [query],
filters,
});
+
return indicesExistOrDataTemporarilyUnavailable(indicesExist) ? (
@@ -257,12 +258,12 @@ export const IPDetailsComponent = React.memo(
);
}}
+
>
);
}
);
-
IPDetailsComponent.displayName = 'IPDetailsComponent';
const makeMapStateToProps = () => {
diff --git a/x-pack/legacy/plugins/siem/public/pages/network/network.tsx b/x-pack/legacy/plugins/siem/public/pages/network/network.tsx
index d135a797567fa..6b4c54737eb10 100644
--- a/x-pack/legacy/plugins/siem/public/pages/network/network.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/network/network.tsx
@@ -49,6 +49,7 @@ const NetworkComponent = React.memo(
capabilitiesFetched,
}) => {
const core = useKibanaCore();
+
return (
<>
@@ -59,6 +60,7 @@ const NetworkComponent = React.memo(
queries: [query],
filters,
});
+
return indicesExistOrDataTemporarilyUnavailable(indicesExist) ? (
@@ -141,12 +143,12 @@ const NetworkComponent = React.memo(
);
}}
+
>
);
}
);
-
NetworkComponent.displayName = 'NetworkComponent';
const makeMapStateToProps = () => {
diff --git a/x-pack/legacy/plugins/siem/public/pages/overview/overview.tsx b/x-pack/legacy/plugins/siem/public/pages/overview/overview.tsx
index d13cc45562039..de976b1a5c5a3 100644
--- a/x-pack/legacy/plugins/siem/public/pages/overview/overview.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/overview/overview.tsx
@@ -7,24 +7,23 @@
import { EuiFlexGroup } from '@elastic/eui';
import moment from 'moment';
import React from 'react';
-import { pure } from 'recompose';
import chrome from 'ui/chrome';
import { documentationLinks } from 'ui/documentation_links';
+import { EmptyPage } from '../../components/empty_page';
import { HeaderPage } from '../../components/header_page';
import { OverviewHost } from '../../components/page/overview/overview_host';
import { OverviewNetwork } from '../../components/page/overview/overview_network';
import { WrapperPage } from '../../components/wrapper_page';
import { GlobalTime } from '../../containers/global_time';
-import { Summary } from './summary';
-import { EmptyPage } from '../../components/empty_page';
import { WithSource, indicesExistOrDataTemporarilyUnavailable } from '../../containers/source';
import { SpyRoute } from '../../utils/route/spy_routes';
+import { Summary } from './summary';
import * as i18n from './translations';
const basePath = chrome.getBasePath();
-export const OverviewComponent = pure(() => {
+export const OverviewComponent = React.memo(() => {
const dateEnd = Date.now();
const dateRange = moment.duration(24, 'hours').asMilliseconds();
const dateStart = dateEnd - dateRange;
@@ -71,9 +70,9 @@ export const OverviewComponent = pure(() => {
}
+
>
);
});
-
OverviewComponent.displayName = 'OverviewComponent';
diff --git a/x-pack/legacy/plugins/siem/public/pages/timelines/timelines_page.tsx b/x-pack/legacy/plugins/siem/public/pages/timelines/timelines_page.tsx
index 4431beaa704b5..93c8397e21431 100644
--- a/x-pack/legacy/plugins/siem/public/pages/timelines/timelines_page.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/timelines/timelines_page.tsx
@@ -17,7 +17,6 @@ import * as i18n from './translations';
const TimelinesContainer = styled.div`
width: 100%:
`;
-
TimelinesContainer.displayName = 'TimelinesContainer';
interface TimelinesProps {
@@ -42,6 +41,7 @@ export const TimelinesPage = React.memo(({ apolloClient }) => (
/>
+
>
));
From 8348b745a63ad68007b3d8904c667c51a4653291 Mon Sep 17 00:00:00 2001
From: Michael Marcialis
Date: Fri, 1 Nov 2019 13:10:00 -0400
Subject: [PATCH 52/57] var for timeline gutter
---
.../filters_global/filters_global.tsx | 21 +++++++---------
.../public/components/header_global/index.tsx | 24 +++++++------------
.../public/components/wrapper_page/index.tsx | 4 +++-
.../plugins/siem/public/lib/helpers/index.tsx | 6 +++++
.../plugins/siem/public/pages/home/index.tsx | 4 +---
5 files changed, 28 insertions(+), 31 deletions(-)
diff --git a/x-pack/legacy/plugins/siem/public/components/filters_global/filters_global.tsx b/x-pack/legacy/plugins/siem/public/components/filters_global/filters_global.tsx
index 90e83fadef48d..892c160d054bd 100644
--- a/x-pack/legacy/plugins/siem/public/components/filters_global/filters_global.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/filters_global/filters_global.tsx
@@ -10,23 +10,22 @@ import { Sticky } from 'react-sticky';
import { pure } from 'recompose';
import styled, { css } from 'styled-components';
+import { gutterTimeline } from '../../lib/helpers';
+
const offsetChrome = 49;
-const gutterTimeline = '70px'; // Temporary until timeline is moved - MichaelMarcialis
const disableSticky = 'screen and (max-width: ' + euiLightVars.euiBreakpoints.s + ')';
const disableStickyMq = window.matchMedia(disableSticky);
-const Aside = styled.aside<{ isSticky?: boolean }>`
+const Wrapper = styled.aside<{ isSticky?: boolean }>`
${props => css`
position: relative;
z-index: ${props.theme.eui.euiZNavigation};
background: ${props.theme.eui.euiColorEmptyShade};
border-bottom: ${props.theme.eui.euiBorderThin};
- // box-sizing: content-box;
- // margin: 0 -${gutterTimeline} 0 -${props.theme.eui.euiSizeL};
- padding: ${props.theme.eui.euiSize} ${gutterTimeline} ${props.theme.eui.euiSize} ${
- props.theme.eui.euiSizeL
- };
+ padding: ${props.theme.eui.paddingSizes.m} ${gutterTimeline} ${
+ props.theme.eui.paddingSizes.m
+ } ${props.theme.eui.paddingSizes.l};
${props.isSticky &&
`
@@ -39,8 +38,7 @@ const Aside = styled.aside<{ isSticky?: boolean }>`
}
`}
`;
-
-Aside.displayName = 'Aside';
+Wrapper.displayName = 'Wrapper';
export interface FiltersGlobalProps {
children: React.ReactNode;
@@ -49,11 +47,10 @@ export interface FiltersGlobalProps {
export const FiltersGlobal = pure(({ children }) => (
{({ style, isSticky }) => (
-
+
)}
));
-
FiltersGlobal.displayName = 'FiltersGlobal';
diff --git a/x-pack/legacy/plugins/siem/public/components/header_global/index.tsx b/x-pack/legacy/plugins/siem/public/components/header_global/index.tsx
index e92bc7cd6a91f..347382898f1ad 100644
--- a/x-pack/legacy/plugins/siem/public/components/header_global/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/header_global/index.tsx
@@ -8,36 +8,30 @@ import { EuiButtonEmpty, EuiFlexGroup, EuiFlexItem, EuiIcon, EuiLink } from '@el
import React from 'react';
import styled, { css } from 'styled-components';
+import { gutterTimeline } from '../../lib/helpers';
import { navTabs } from '../../pages/home/home_navigations';
import { getOverviewUrl } from '../link_to';
import { MlPopover } from '../ml_popover/ml_popover';
import { SiemNavigation } from '../navigation';
import * as i18n from './translations';
-interface HeaderProps {
- offsetRight?: string;
-}
-
-const Header = styled.header.attrs({
- className: 'siemHeaderGlobal',
-})`
- ${({ offsetRight, theme }) => css`
+const Wrapper = styled.header`
+ ${({ theme }) => css`
background: ${theme.eui.euiColorEmptyShade};
border-bottom: ${theme.eui.euiBorderThin};
- // margin: 0 -${offsetRight ? offsetRight : theme.eui.euiSizeL} 0 -${theme.eui.euiSizeL};
- padding: ${theme.eui.paddingSizes.m} ${offsetRight ? offsetRight : theme.eui.paddingSizes.l}
- ${theme.eui.paddingSizes.m} ${theme.eui.paddingSizes.l};
+ padding: ${theme.eui.paddingSizes.m} ${gutterTimeline} ${theme.eui.paddingSizes.m}
+ ${theme.eui.paddingSizes.l};
`}
`;
-Header.displayName = 'Header';
+Wrapper.displayName = 'Wrapper';
const FlexItem = styled(EuiFlexItem)`
min-width: 0;
`;
FlexItem.displayName = 'FlexItem';
-export const HeaderGlobal = React.memo(({ offsetRight }) => (
-
+export const HeaderGlobal = React.memo(() => (
+
@@ -71,6 +65,6 @@ export const HeaderGlobal = React.memo(({ offsetRight }) => (
-
+
));
HeaderGlobal.displayName = 'HeaderGlobal';
diff --git a/x-pack/legacy/plugins/siem/public/components/wrapper_page/index.tsx b/x-pack/legacy/plugins/siem/public/components/wrapper_page/index.tsx
index 473d1cbacfdeb..5998aa527206e 100644
--- a/x-pack/legacy/plugins/siem/public/components/wrapper_page/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/wrapper_page/index.tsx
@@ -8,9 +8,11 @@ import classNames from 'classnames';
import React from 'react';
import styled, { css } from 'styled-components';
+import { gutterTimeline } from '../../lib/helpers';
+
const Wrapper = styled.div`
${({ theme }) => css`
- padding: ${theme.eui.paddingSizes.l} 70px ${theme.eui.paddingSizes.l}
+ padding: ${theme.eui.paddingSizes.l} ${gutterTimeline} ${theme.eui.paddingSizes.l}
${theme.eui.paddingSizes.l};
&.siemWrapperPage--restrictWidthDefault,
diff --git a/x-pack/legacy/plugins/siem/public/lib/helpers/index.tsx b/x-pack/legacy/plugins/siem/public/lib/helpers/index.tsx
index 659ecbadc34d2..5706dcc50ed25 100644
--- a/x-pack/legacy/plugins/siem/public/lib/helpers/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/lib/helpers/index.tsx
@@ -42,3 +42,9 @@ export const assertUnreachable = (
): never => {
throw new Error(`${message}: ${x}`);
};
+
+/**
+ * Global variables
+ */
+
+export const gutterTimeline = '70px'; // Michael: Temporary until timeline is moved.
diff --git a/x-pack/legacy/plugins/siem/public/pages/home/index.tsx b/x-pack/legacy/plugins/siem/public/pages/home/index.tsx
index 71683bd578b98..f1e7684545664 100644
--- a/x-pack/legacy/plugins/siem/public/pages/home/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/home/index.tsx
@@ -42,8 +42,6 @@ const WrappedByAutoSizer = styled.div`
`;
WrappedByAutoSizer.displayName = 'WrappedByAutoSizer';
-const gutterTimeline = '70px'; // Temporary until timeline is moved - MichaelMarcialis
-
const usersViewing = ['elastic']; // TODO: get the users viewing this timeline from Elasticsearch (persistance)
/** the global Kibana navigation at the top of every page */
@@ -61,7 +59,7 @@ export const HomePage = React.memo(() => (
{({ measureRef, windowMeasurement: { height: windowHeight = 0 } }) => (
-
+
From 914786a504c82cbc6f053f6b1b98fdb8d4aa4668 Mon Sep 17 00:00:00 2001
From: Michael Marcialis
Date: Fri, 1 Nov 2019 13:49:08 -0400
Subject: [PATCH 53/57] tests and snapshots update
---
.../components/header_global/index.test.tsx | 37 +--
.../__snapshots__/index.test.tsx.snap | 46 +++-
.../components/wrapper_page/index.test.tsx | 211 ++++--------------
3 files changed, 85 insertions(+), 209 deletions(-)
diff --git a/x-pack/legacy/plugins/siem/public/components/header_global/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/header_global/index.test.tsx
index 01abc73b18181..ebd1da634ed1a 100644
--- a/x-pack/legacy/plugins/siem/public/components/header_global/index.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/header_global/index.test.tsx
@@ -4,10 +4,8 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import euiDarkVars from '@elastic/eui/dist/eui_theme_dark.json';
-import { mount, shallow } from 'enzyme';
+import { shallow } from 'enzyme';
import toJson from 'enzyme-to-json';
-import 'jest-styled-components';
import React from 'react';
import { TestProviders } from '../../mock';
@@ -33,37 +31,4 @@ describe('HeaderGlobal', () => {
expect(toJson(wrapper)).toMatchSnapshot();
});
-
- test('it applies offset styles when offsetRight is provided', () => {
- const wrapper = mount(
-
-
-
- );
- const siemHeaderGlobal = wrapper.find('.siemHeaderGlobal').first();
-
- expect(siemHeaderGlobal).toHaveStyleRule('margin', `0 -100px 0 -${euiDarkVars.euiSizeL}`);
- expect(siemHeaderGlobal).toHaveStyleRule(
- 'padding',
- `${euiDarkVars.paddingSizes.m} 100px ${euiDarkVars.paddingSizes.m} ${euiDarkVars.paddingSizes.l}`
- );
- });
-
- test('it DOES NOT apply offset styles when offsetRight is not provided', () => {
- const wrapper = mount(
-
-
-
- );
- const siemHeaderGlobal = wrapper.find('.siemHeaderGlobal').first();
-
- expect(siemHeaderGlobal).toHaveStyleRule(
- 'margin',
- `0 -${euiDarkVars.euiSizeL} 0 -${euiDarkVars.euiSizeL}`
- );
- expect(siemHeaderGlobal).toHaveStyleRule(
- 'padding',
- `${euiDarkVars.paddingSizes.m} ${euiDarkVars.paddingSizes.l} ${euiDarkVars.paddingSizes.m} ${euiDarkVars.paddingSizes.l}`
- );
- });
});
diff --git a/x-pack/legacy/plugins/siem/public/components/wrapper_page/__snapshots__/index.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/wrapper_page/__snapshots__/index.test.tsx.snap
index ecd2b15a841f6..e5311bfb050a3 100644
--- a/x-pack/legacy/plugins/siem/public/components/wrapper_page/__snapshots__/index.test.tsx.snap
+++ b/x-pack/legacy/plugins/siem/public/components/wrapper_page/__snapshots__/index.test.tsx.snap
@@ -1,9 +1,47 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`HeaderSection it renders 1`] = `
+exports[`WrapperPage it renders 1`] = `
-
+
+
+ Test page
+
+
+
+`;
+
+exports[`WrapperPage restrict width custom max width when restrictWidth is number 1`] = `
+
+
+
+ Test page
+
+
+
+`;
+
+exports[`WrapperPage restrict width custom max width when restrictWidth is string 1`] = `
+
+
+
+ Test page
+
+
+
+`;
+
+exports[`WrapperPage restrict width default max width when restrictWidth is true 1`] = `
+
+
+
+ Test page
+
+
`;
diff --git a/x-pack/legacy/plugins/siem/public/components/wrapper_page/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/wrapper_page/index.test.tsx
index fffeece818d13..95e80e8b9e5de 100644
--- a/x-pack/legacy/plugins/siem/public/components/wrapper_page/index.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/wrapper_page/index.test.tsx
@@ -4,191 +4,64 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import euiDarkVars from '@elastic/eui/dist/eui_theme_dark.json';
-import { mount, shallow } from 'enzyme';
+import { shallow } from 'enzyme';
import toJson from 'enzyme-to-json';
-import 'jest-styled-components';
import React from 'react';
import { TestProviders } from '../../mock';
import '../../mock/ui_settings';
-import { HeaderSection } from './index';
+import { WrapperPage } from './index';
jest.mock('../../lib/settings/use_kibana_ui_setting');
-describe('HeaderSection', () => {
+describe('WrapperPage', () => {
test('it renders', () => {
const wrapper = shallow(
-
+
+ {'Test page'}
+
);
expect(toJson(wrapper)).toMatchSnapshot();
});
- test('it renders the title', () => {
- const wrapper = mount(
-
-
-
- );
-
- expect(
- wrapper
- .find('[data-test-subj="header-section-title"]')
- .first()
- .exists()
- ).toBe(true);
- });
-
- test('it renders the subtitle when provided', () => {
- const wrapper = mount(
-
-
-
- );
-
- expect(
- wrapper
- .find('[data-test-subj="header-section-subtitle"]')
- .first()
- .exists()
- ).toBe(true);
- });
-
- test('it DOES NOT render the subtitle when not provided', () => {
- const wrapper = mount(
-
-
-
- );
-
- expect(
- wrapper
- .find('[data-test-subj="header-section-subtitle"]')
- .first()
- .exists()
- ).toBe(false);
- });
-
- test('it renders a transparent inspect button when showInspect is false', () => {
- const wrapper = mount(
-
-
-
- );
-
- expect(
- wrapper
- .find('[data-test-subj="transparent-inspect-container"]')
- .first()
- .exists()
- ).toBe(true);
- });
-
- test('it renders an opaque inspect button when showInspect is true', () => {
- const wrapper = mount(
-
-
-
- );
-
- expect(
- wrapper
- .find('[data-test-subj="opaque-inspect-container"]')
- .first()
- .exists()
- ).toBe(true);
- });
-
- test('it renders supplements when children provided', () => {
- const wrapper = mount(
-
-
- {'Test children'}
-
-
- );
-
- expect(
- wrapper
- .find('[data-test-subj="header-section-supplements"]')
- .first()
- .exists()
- ).toBe(true);
- });
-
- test('it DOES NOT render supplements when children not provided', () => {
- const wrapper = mount(
-
-
-
- );
-
- expect(
- wrapper
- .find('[data-test-subj="header-section-supplements"]')
- .first()
- .exists()
- ).toBe(false);
- });
-
- test('it applies border styles when border is true', () => {
- const wrapper = mount(
-
-
-
- );
- const siemHeaderSection = wrapper.find('.siemHeaderSection').first();
-
- expect(siemHeaderSection).toHaveStyleRule('border-bottom', euiDarkVars.euiBorderThin);
- expect(siemHeaderSection).toHaveStyleRule('padding-bottom', euiDarkVars.paddingSizes.l);
- });
-
- test('it DOES NOT apply border styles when border is false', () => {
- const wrapper = mount(
-
-
-
- );
- const siemHeaderSection = wrapper.find('.siemHeaderSection').first();
-
- expect(siemHeaderSection).not.toHaveStyleRule('border-bottom', euiDarkVars.euiBorderThin);
- expect(siemHeaderSection).not.toHaveStyleRule('padding-bottom', euiDarkVars.paddingSizes.l);
- });
-
- test('it splits the title and supplement areas evenly when split is true', () => {
- const wrapper = mount(
-
-
- {'Test children'}
-
-
- );
-
- expect(
- wrapper
- .find('.euiFlexItem--flexGrowZero[data-test-subj="header-section-supplements"]')
- .first()
- .exists()
- ).toBe(false);
- });
-
- test('it DOES NOT split the title and supplement areas evenly when split is false', () => {
- const wrapper = mount(
-
-
- {'Test children'}
-
-
- );
-
- expect(
- wrapper
- .find('.euiFlexItem--flexGrowZero[data-test-subj="header-section-supplements"]')
- .first()
- .exists()
- ).toBe(true);
+ describe('restrict width', () => {
+ test('default max width when restrictWidth is true', () => {
+ const wrapper = shallow(
+
+
+ {'Test page'}
+
+
+ );
+
+ expect(toJson(wrapper)).toMatchSnapshot();
+ });
+
+ test('custom max width when restrictWidth is number', () => {
+ const wrapper = shallow(
+
+
+ {'Test page'}
+
+
+ );
+
+ expect(toJson(wrapper)).toMatchSnapshot();
+ });
+
+ test('custom max width when restrictWidth is string', () => {
+ const wrapper = shallow(
+
+
+ {'Test page'}
+
+
+ );
+
+ expect(toJson(wrapper)).toMatchSnapshot();
+ });
});
});
From 66d21136d32670a4ae65d7c50e1fc0ae3af21e6e Mon Sep 17 00:00:00 2001
From: Xavier Mouligneau <189600+XavierM@users.noreply.github.com>
Date: Tue, 12 Nov 2019 11:42:15 -0500
Subject: [PATCH 54/57] fix type + review + re-arrange code
---
.../integration/lib/navigation/selectors.ts | 8 ++---
.../__snapshots__/utility_bar.test.tsx.snap | 0
.../utility_bar_action.test.tsx.snap | 0
.../utility_bar_group.test.tsx.snap | 0
.../utility_bar_section.test.tsx.snap | 0
.../utility_bar_text.test.tsx.snap | 0
.../utility_bar/index.ts | 0
.../utility_bar/styles.tsx | 0
.../utility_bar/utility_bar.test.tsx | 10 +++---
.../utility_bar/utility_bar.tsx | 0
.../utility_bar/utility_bar_action.test.tsx | 4 +--
.../utility_bar/utility_bar_action.tsx | 2 +-
.../utility_bar/utility_bar_group.test.tsx | 4 +--
.../utility_bar/utility_bar_group.tsx | 0
.../utility_bar/utility_bar_section.test.tsx | 4 +--
.../utility_bar/utility_bar_section.tsx | 0
.../utility_bar/utility_bar_text.test.tsx | 4 +--
.../utility_bar/utility_bar_text.tsx | 0
.../components/header_section/index.tsx | 4 +--
.../components/navigation/index.test.tsx | 33 ++++++++++++-------
.../detection_engine/detection_engine.tsx | 2 +-
.../detection_engine/rule_details/index.tsx | 9 +++--
.../pages/detection_engine/rules/index.tsx | 14 ++++----
23 files changed, 54 insertions(+), 44 deletions(-)
rename x-pack/legacy/plugins/siem/public/components/{ => detection_engine}/utility_bar/__snapshots__/utility_bar.test.tsx.snap (100%)
rename x-pack/legacy/plugins/siem/public/components/{ => detection_engine}/utility_bar/__snapshots__/utility_bar_action.test.tsx.snap (100%)
rename x-pack/legacy/plugins/siem/public/components/{ => detection_engine}/utility_bar/__snapshots__/utility_bar_group.test.tsx.snap (100%)
rename x-pack/legacy/plugins/siem/public/components/{ => detection_engine}/utility_bar/__snapshots__/utility_bar_section.test.tsx.snap (100%)
rename x-pack/legacy/plugins/siem/public/components/{ => detection_engine}/utility_bar/__snapshots__/utility_bar_text.test.tsx.snap (100%)
rename x-pack/legacy/plugins/siem/public/components/{ => detection_engine}/utility_bar/index.ts (100%)
rename x-pack/legacy/plugins/siem/public/components/{ => detection_engine}/utility_bar/styles.tsx (100%)
rename x-pack/legacy/plugins/siem/public/components/{ => detection_engine}/utility_bar/utility_bar.test.tsx (90%)
rename x-pack/legacy/plugins/siem/public/components/{ => detection_engine}/utility_bar/utility_bar.tsx (100%)
rename x-pack/legacy/plugins/siem/public/components/{ => detection_engine}/utility_bar/utility_bar_action.test.tsx (93%)
rename x-pack/legacy/plugins/siem/public/components/{ => detection_engine}/utility_bar/utility_bar_action.tsx (96%)
rename x-pack/legacy/plugins/siem/public/components/{ => detection_engine}/utility_bar/utility_bar_group.test.tsx (90%)
rename x-pack/legacy/plugins/siem/public/components/{ => detection_engine}/utility_bar/utility_bar_group.tsx (100%)
rename x-pack/legacy/plugins/siem/public/components/{ => detection_engine}/utility_bar/utility_bar_section.test.tsx (91%)
rename x-pack/legacy/plugins/siem/public/components/{ => detection_engine}/utility_bar/utility_bar_section.tsx (100%)
rename x-pack/legacy/plugins/siem/public/components/{ => detection_engine}/utility_bar/utility_bar_text.test.tsx (89%)
rename x-pack/legacy/plugins/siem/public/components/{ => detection_engine}/utility_bar/utility_bar_text.tsx (100%)
diff --git a/x-pack/legacy/plugins/siem/cypress/integration/lib/navigation/selectors.ts b/x-pack/legacy/plugins/siem/cypress/integration/lib/navigation/selectors.ts
index 08bf4cebedc9c..0d5f40ae53966 100644
--- a/x-pack/legacy/plugins/siem/cypress/integration/lib/navigation/selectors.ts
+++ b/x-pack/legacy/plugins/siem/cypress/integration/lib/navigation/selectors.ts
@@ -5,16 +5,16 @@
*/
/** Top-level (global) navigation link to the `Hosts` page */
-export const NAVIGATION_HOSTS = '[data-test-subj="navigation-link-hosts"]';
+export const NAVIGATION_HOSTS = '[data-test-subj="navigation-hosts"]';
/** Top-level (global) navigation link to the `Network` page */
-export const NAVIGATION_NETWORK = '[data-test-subj="navigation-link-network"]';
+export const NAVIGATION_NETWORK = '[data-test-subj="navigation-network"]';
/** Top-level (global) navigation link to the `Overview` page */
-export const NAVIGATION_OVERVIEW = '[data-test-subj="navigation-link-overview"]';
+export const NAVIGATION_OVERVIEW = '[data-test-subj="navigation-overview"]';
/** Top-level (global) navigation link to the `Timelines` page */
-export const NAVIGATION_TIMELINES = '[data-test-subj="navigation-link-timelines"]';
+export const NAVIGATION_TIMELINES = '[data-test-subj="navigation-timelines"]';
export const HOSTS_PAGE_TABS = {
allHosts: '[data-test-subj="navigation-allHosts"]',
diff --git a/x-pack/legacy/plugins/siem/public/components/utility_bar/__snapshots__/utility_bar.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/__snapshots__/utility_bar.test.tsx.snap
similarity index 100%
rename from x-pack/legacy/plugins/siem/public/components/utility_bar/__snapshots__/utility_bar.test.tsx.snap
rename to x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/__snapshots__/utility_bar.test.tsx.snap
diff --git a/x-pack/legacy/plugins/siem/public/components/utility_bar/__snapshots__/utility_bar_action.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/__snapshots__/utility_bar_action.test.tsx.snap
similarity index 100%
rename from x-pack/legacy/plugins/siem/public/components/utility_bar/__snapshots__/utility_bar_action.test.tsx.snap
rename to x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/__snapshots__/utility_bar_action.test.tsx.snap
diff --git a/x-pack/legacy/plugins/siem/public/components/utility_bar/__snapshots__/utility_bar_group.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/__snapshots__/utility_bar_group.test.tsx.snap
similarity index 100%
rename from x-pack/legacy/plugins/siem/public/components/utility_bar/__snapshots__/utility_bar_group.test.tsx.snap
rename to x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/__snapshots__/utility_bar_group.test.tsx.snap
diff --git a/x-pack/legacy/plugins/siem/public/components/utility_bar/__snapshots__/utility_bar_section.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/__snapshots__/utility_bar_section.test.tsx.snap
similarity index 100%
rename from x-pack/legacy/plugins/siem/public/components/utility_bar/__snapshots__/utility_bar_section.test.tsx.snap
rename to x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/__snapshots__/utility_bar_section.test.tsx.snap
diff --git a/x-pack/legacy/plugins/siem/public/components/utility_bar/__snapshots__/utility_bar_text.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/__snapshots__/utility_bar_text.test.tsx.snap
similarity index 100%
rename from x-pack/legacy/plugins/siem/public/components/utility_bar/__snapshots__/utility_bar_text.test.tsx.snap
rename to x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/__snapshots__/utility_bar_text.test.tsx.snap
diff --git a/x-pack/legacy/plugins/siem/public/components/utility_bar/index.ts b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/index.ts
similarity index 100%
rename from x-pack/legacy/plugins/siem/public/components/utility_bar/index.ts
rename to x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/index.ts
diff --git a/x-pack/legacy/plugins/siem/public/components/utility_bar/styles.tsx b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/styles.tsx
similarity index 100%
rename from x-pack/legacy/plugins/siem/public/components/utility_bar/styles.tsx
rename to x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/styles.tsx
diff --git a/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar.test.tsx b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar.test.tsx
similarity index 90%
rename from x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar.test.tsx
rename to x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar.test.tsx
index a0f684b90ea79..a07face9c1690 100644
--- a/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar.test.tsx
@@ -10,8 +10,8 @@ import toJson from 'enzyme-to-json';
import 'jest-styled-components';
import React from 'react';
-import '../../mock/ui_settings';
-import { TestProviders } from '../../mock';
+import '../../../mock/ui_settings';
+import { TestProviders } from '../../../mock';
import {
UtilityBar,
UtilityBarAction,
@@ -33,7 +33,7 @@ describe('UtilityBar', () => {
- {'Test popover'}}>
+ {'Test popover'}}>
{'Test action'}
@@ -61,7 +61,7 @@ describe('UtilityBar', () => {
- {'Test popover'}}>
+ {'Test popover'}}>
{'Test action'}
@@ -91,7 +91,7 @@ describe('UtilityBar', () => {
- {'Test popover'}}>
+ {'Test popover'}}>
{'Test action'}
diff --git a/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar.tsx b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar.tsx
similarity index 100%
rename from x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar.tsx
rename to x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar.tsx
diff --git a/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_action.test.tsx b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_action.test.tsx
similarity index 93%
rename from x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_action.test.tsx
rename to x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_action.test.tsx
index b25aa7d4933ec..d9cbf3704b270 100644
--- a/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_action.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_action.test.tsx
@@ -9,8 +9,8 @@ import toJson from 'enzyme-to-json';
import 'jest-styled-components';
import React from 'react';
-import '../../mock/ui_settings';
-import { TestProviders } from '../../mock';
+import '../../../mock/ui_settings';
+import { TestProviders } from '../../../mock';
import { UtilityBarAction } from './index';
jest.mock('../../lib/settings/use_kibana_ui_setting');
diff --git a/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_action.tsx b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_action.tsx
similarity index 96%
rename from x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_action.tsx
rename to x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_action.tsx
index 65002e30edb5e..ae4362bdbcd7b 100644
--- a/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_action.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_action.tsx
@@ -7,7 +7,7 @@
import { EuiPopover } from '@elastic/eui';
import React, { useState } from 'react';
-import { LinkIcon, LinkIconProps } from '../link_icon';
+import { LinkIcon, LinkIconProps } from '../../link_icon';
import { BarAction } from './styles';
const Popover = React.memo(
diff --git a/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_group.test.tsx b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_group.test.tsx
similarity index 90%
rename from x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_group.test.tsx
rename to x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_group.test.tsx
index 3fa42a690d588..a4856b83d04fb 100644
--- a/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_group.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_group.test.tsx
@@ -8,8 +8,8 @@ import { shallow } from 'enzyme';
import toJson from 'enzyme-to-json';
import React from 'react';
-import '../../mock/ui_settings';
-import { TestProviders } from '../../mock';
+import '../../../mock/ui_settings';
+import { TestProviders } from '../../../mock';
import { UtilityBarGroup, UtilityBarText } from './index';
jest.mock('../../lib/settings/use_kibana_ui_setting');
diff --git a/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_group.tsx b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_group.tsx
similarity index 100%
rename from x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_group.tsx
rename to x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_group.tsx
diff --git a/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_section.test.tsx b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_section.test.tsx
similarity index 91%
rename from x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_section.test.tsx
rename to x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_section.test.tsx
index 90837f2e4cc03..c69522e5ea18e 100644
--- a/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_section.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_section.test.tsx
@@ -8,8 +8,8 @@ import { shallow } from 'enzyme';
import toJson from 'enzyme-to-json';
import React from 'react';
-import '../../mock/ui_settings';
-import { TestProviders } from '../../mock';
+import '../../../mock/ui_settings';
+import { TestProviders } from '../../../mock';
import { UtilityBarGroup, UtilityBarSection, UtilityBarText } from './index';
jest.mock('../../lib/settings/use_kibana_ui_setting');
diff --git a/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_section.tsx b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_section.tsx
similarity index 100%
rename from x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_section.tsx
rename to x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_section.tsx
diff --git a/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_text.test.tsx b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_text.test.tsx
similarity index 89%
rename from x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_text.test.tsx
rename to x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_text.test.tsx
index 71afd2230e2f6..d43d34fbd0b6b 100644
--- a/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_text.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_text.test.tsx
@@ -8,8 +8,8 @@ import { shallow } from 'enzyme';
import toJson from 'enzyme-to-json';
import React from 'react';
-import '../../mock/ui_settings';
-import { TestProviders } from '../../mock';
+import '../../../mock/ui_settings';
+import { TestProviders } from '../../../mock';
import { UtilityBarText } from './index';
jest.mock('../../lib/settings/use_kibana_ui_setting');
diff --git a/x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_text.tsx b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_text.tsx
similarity index 100%
rename from x-pack/legacy/plugins/siem/public/components/utility_bar/utility_bar_text.tsx
rename to x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_text.tsx
diff --git a/x-pack/legacy/plugins/siem/public/components/header_section/index.tsx b/x-pack/legacy/plugins/siem/public/components/header_section/index.tsx
index c615186e81ada..e46ae55a57a45 100644
--- a/x-pack/legacy/plugins/siem/public/components/header_section/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/header_section/index.tsx
@@ -9,7 +9,7 @@ import React from 'react';
import styled, { css } from 'styled-components';
import { InspectButton } from '../inspect';
-import { Subtitle, SubtitleProps } from '../subtitle';
+import { Subtitle } from '../subtitle';
interface HeaderProps {
border?: boolean;
@@ -35,7 +35,7 @@ export interface HeaderSectionProps extends HeaderProps {
children?: React.ReactNode;
id?: string;
split?: boolean;
- subtitle?: SubtitleProps['text'];
+ subtitle?: string | React.ReactNode;
showInspect?: boolean;
title: string | React.ReactNode;
tooltip?: string;
diff --git a/x-pack/legacy/plugins/siem/public/components/navigation/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/navigation/index.test.tsx
index cf519da617183..97cf9522f488f 100644
--- a/x-pack/legacy/plugins/siem/public/components/navigation/index.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/navigation/index.test.tsx
@@ -61,6 +61,13 @@ describe('SIEM Navigation', () => {
expect(setBreadcrumbs).toHaveBeenNthCalledWith(1, {
detailName: undefined,
navTabs: {
+ 'detection-engine': {
+ disabled: false,
+ href: '#/link-to/detection-engine',
+ id: 'detection-engine',
+ name: 'Detection engine',
+ urlKey: 'detection-engine',
+ },
hosts: {
disabled: false,
href: '#/link-to/hosts',
@@ -132,9 +139,17 @@ describe('SIEM Navigation', () => {
tabName: undefined,
});
wrapper.update();
- expect(setBreadcrumbs).toHaveBeenNthCalledWith(2, {
+ expect(setBreadcrumbs).toHaveBeenNthCalledWith(1, {
detailName: undefined,
+ filters: [],
navTabs: {
+ 'detection-engine': {
+ disabled: false,
+ href: '#/link-to/detection-engine',
+ id: 'detection-engine',
+ name: 'Detection engine',
+ urlKey: 'detection-engine',
+ },
hosts: {
disabled: false,
href: '#/link-to/hosts',
@@ -164,17 +179,13 @@ describe('SIEM Navigation', () => {
urlKey: 'timeline',
},
},
- pageName: 'network',
- pathName: '/network',
- search: '',
- tabName: undefined,
- query: { query: '', language: 'kuery' },
- filters: [],
+ pageName: 'hosts',
+ pathName: '/hosts',
+ query: { language: 'kuery', query: '' },
savedQuery: undefined,
- timeline: {
- id: '',
- isOpen: false,
- },
+ search: '',
+ tabName: 'authentications',
+ timeline: { id: '', isOpen: false },
timerange: {
global: {
linkTo: ['timeline'],
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
index d872e7b602316..9b63a6e160e42 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx
@@ -26,7 +26,7 @@ import {
UtilityBarGroup,
UtilityBarSection,
UtilityBarText,
-} from '../../components/utility_bar';
+} from '../../components/detection_engine/utility_bar';
import { WrapperPage } from '../../components/wrapper_page';
import { indicesExistOrDataTemporarilyUnavailable, WithSource } from '../../containers/source';
import { SpyRoute } from '../../utils/route/spy_routes';
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.tsx
index 192814e8a35e5..da3e5fb2083dd 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.tsx
@@ -11,7 +11,6 @@ import {
EuiCallOut,
EuiFilterButton,
EuiFilterGroup,
- EuiFlexGrid,
EuiFlexGroup,
EuiFlexItem,
EuiIconTip,
@@ -40,7 +39,7 @@ import {
UtilityBarGroup,
UtilityBarSection,
UtilityBarText,
-} from '../../../components/utility_bar';
+} from '../../../components/detection_engine/utility_bar';
import { WrapperPage } from '../../../components/wrapper_page';
import { indicesExistOrDataTemporarilyUnavailable, WithSource } from '../../../containers/source';
import { SpyRoute } from '../../../utils/route/spy_routes';
@@ -434,9 +433,9 @@ const ActivityMonitor = React.memo(() => {
},
];
- const [itemsTotalState, setItemsTotalState] = useState(sampleTableData.length);
+ const [itemsTotalState] = useState(sampleTableData.length);
const [pageState, setPageState] = useState({ index: 0, size: 20 });
- const [selectedState, setSelectedState] = useState([]);
+ // const [selectedState, setSelectedState] = useState([]);
const [sortState, setSortState] = useState({ field: 'ran', direction: 'desc' });
return (
@@ -484,7 +483,7 @@ const ActivityMonitor = React.memo(() => {
selectableMessage: (selectable: boolean) =>
selectable ? undefined : 'Completed runs cannot be acted upon',
onSelectionChange: (selectedItems: ColumnTypes[]) => {
- setSelectedState(selectedItems);
+ // setSelectedState(selectedItems);
},
}}
sorting={{
diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
index e4be8fe81c2ea..a046d7eaefb15 100644
--- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx
@@ -33,7 +33,7 @@ import {
UtilityBarGroup,
UtilityBarSection,
UtilityBarText,
-} from '../../../components/utility_bar';
+} from '../../../components/detection_engine/utility_bar';
import { WrapperPage } from '../../../components/wrapper_page';
import { SpyRoute } from '../../../utils/route/spy_routes';
import * as i18n from './translations';
@@ -566,9 +566,9 @@ const AllRules = React.memo(() => {
},
];
- const [itemsTotalState, setItemsTotalState] = useState(sampleTableData.length);
+ const [itemsTotalState] = useState(sampleTableData.length);
const [pageState, setPageState] = useState({ index: 0, size: 20 });
- const [selectedState, setSelectedState] = useState([]);
+ // const [selectedState, setSelectedState] = useState([]);
const [sortState, setSortState] = useState({ field: 'rule', direction: 'asc' });
return (
@@ -622,7 +622,7 @@ const AllRules = React.memo(() => {
selection={{
selectable: () => true,
onSelectionChange: (selectedItems: ColumnTypes[]) => {
- setSelectedState(selectedItems);
+ // setSelectedState(selectedItems);
},
}}
sorting={{
@@ -971,9 +971,9 @@ const ActivityMonitor = React.memo(() => {
},
];
- const [itemsTotalState, setItemsTotalState] = useState(sampleTableData.length);
+ const [itemsTotalState] = useState(sampleTableData.length);
const [pageState, setPageState] = useState({ index: 0, size: 20 });
- const [selectedState, setSelectedState] = useState([]);
+ // const [selectedState, setSelectedState] = useState([]);
const [sortState, setSortState] = useState({ field: 'ran', direction: 'desc' });
return (
@@ -1021,7 +1021,7 @@ const ActivityMonitor = React.memo(() => {
selectableMessage: (selectable: boolean) =>
selectable ? undefined : 'Completed runs cannot be acted upon',
onSelectionChange: (selectedItems: ColumnTypes[]) => {
- setSelectedState(selectedItems);
+ // setSelectedState(selectedItems);
},
}}
sorting={{
From 33da413ce0fffb16ab7b1266e24b92901fd53e51 Mon Sep 17 00:00:00 2001
From: Xavier Mouligneau <189600+XavierM@users.noreply.github.com>
Date: Tue, 12 Nov 2019 12:16:35 -0500
Subject: [PATCH 55/57] adding feature flag + fix route issue
---
.../public/components/header_global/index.tsx | 16 ++++++++++++++--
x-pack/legacy/plugins/siem/public/pages/404.tsx | 3 ++-
.../plugins/siem/public/pages/home/index.tsx | 3 ++-
3 files changed, 18 insertions(+), 4 deletions(-)
diff --git a/x-pack/legacy/plugins/siem/public/components/header_global/index.tsx b/x-pack/legacy/plugins/siem/public/components/header_global/index.tsx
index 347382898f1ad..168cacf3e97e1 100644
--- a/x-pack/legacy/plugins/siem/public/components/header_global/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/header_global/index.tsx
@@ -5,11 +5,13 @@
*/
import { EuiButtonEmpty, EuiFlexGroup, EuiFlexItem, EuiIcon, EuiLink } from '@elastic/eui';
+import { pickBy } from 'lodash/fp';
import React from 'react';
import styled, { css } from 'styled-components';
import { gutterTimeline } from '../../lib/helpers';
import { navTabs } from '../../pages/home/home_navigations';
+import { SiemPageName } from '../../pages/home/types';
import { getOverviewUrl } from '../link_to';
import { MlPopover } from '../ml_popover/ml_popover';
import { SiemNavigation } from '../navigation';
@@ -30,7 +32,10 @@ const FlexItem = styled(EuiFlexItem)`
`;
FlexItem.displayName = 'FlexItem';
-export const HeaderGlobal = React.memo(() => (
+interface HeaderGlobalProps {
+ hideDetectionEngine?: boolean;
+}
+export const HeaderGlobal = React.memo(({ hideDetectionEngine = true }) => (
@@ -42,7 +47,14 @@ export const HeaderGlobal = React.memo(() => (
-
+ key !== SiemPageName.detectionEngine, navTabs)
+ : navTabs
+ }
+ />
diff --git a/x-pack/legacy/plugins/siem/public/pages/404.tsx b/x-pack/legacy/plugins/siem/public/pages/404.tsx
index 37049033a6b0a..f806a5a7fcdd3 100644
--- a/x-pack/legacy/plugins/siem/public/pages/404.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/404.tsx
@@ -5,11 +5,12 @@
*/
import React from 'react';
+import { pure } from 'recompose';
import { FormattedMessage } from '@kbn/i18n/react';
import { WrapperPage } from '../components/wrapper_page';
-export const NotFoundPage = React.memo(() => (
+export const NotFoundPage = pure(() => (
Math.max(0, windowHeight - globalHeaderSize);
-export const HomePage = React.memo(() => (
+export const HomePage = pure(() => (
{({ measureRef, windowMeasurement: { height: windowHeight = 0 } }) => (
From a5c50d8e2c3bef1478555ec24c15bc9559dd0599 Mon Sep 17 00:00:00 2001
From: Xavier Mouligneau <189600+XavierM@users.noreply.github.com>
Date: Tue, 12 Nov 2019 14:32:19 -0500
Subject: [PATCH 56/57] fix type with unit test
---
.../utility_bar/__snapshots__/utility_bar.test.tsx.snap | 1 +
.../detection_engine/utility_bar/utility_bar.test.tsx | 2 +-
.../detection_engine/utility_bar/utility_bar_action.test.tsx | 2 +-
.../detection_engine/utility_bar/utility_bar_group.test.tsx | 2 +-
.../detection_engine/utility_bar/utility_bar_section.test.tsx | 2 +-
.../detection_engine/utility_bar/utility_bar_text.test.tsx | 2 +-
.../public/components/link_to/redirect_to_detection_engine.tsx | 3 ++-
7 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/__snapshots__/utility_bar.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/__snapshots__/utility_bar.test.tsx.snap
index 66ad764ff445c..1f892acef7ef3 100644
--- a/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/__snapshots__/utility_bar.test.tsx.snap
+++ b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/__snapshots__/utility_bar.test.tsx.snap
@@ -11,6 +11,7 @@ exports[`UtilityBar it renders 1`] = `
Test popover
diff --git a/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar.test.tsx b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar.test.tsx
index a07face9c1690..bf13a503838cf 100644
--- a/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar.test.tsx
@@ -20,7 +20,7 @@ import {
UtilityBarText,
} from './index';
-jest.mock('../../lib/settings/use_kibana_ui_setting');
+jest.mock('../../../lib/settings/use_kibana_ui_setting');
describe('UtilityBar', () => {
test('it renders', () => {
diff --git a/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_action.test.tsx b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_action.test.tsx
index d9cbf3704b270..7a1c35183e503 100644
--- a/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_action.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_action.test.tsx
@@ -13,7 +13,7 @@ import '../../../mock/ui_settings';
import { TestProviders } from '../../../mock';
import { UtilityBarAction } from './index';
-jest.mock('../../lib/settings/use_kibana_ui_setting');
+jest.mock('../../../lib/settings/use_kibana_ui_setting');
describe('UtilityBarAction', () => {
test('it renders', () => {
diff --git a/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_group.test.tsx b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_group.test.tsx
index a4856b83d04fb..84ad96c5a1e5e 100644
--- a/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_group.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_group.test.tsx
@@ -12,7 +12,7 @@ import '../../../mock/ui_settings';
import { TestProviders } from '../../../mock';
import { UtilityBarGroup, UtilityBarText } from './index';
-jest.mock('../../lib/settings/use_kibana_ui_setting');
+jest.mock('../../../lib/settings/use_kibana_ui_setting');
describe('UtilityBarGroup', () => {
test('it renders', () => {
diff --git a/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_section.test.tsx b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_section.test.tsx
index c69522e5ea18e..2dfc1d3b8d193 100644
--- a/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_section.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_section.test.tsx
@@ -12,7 +12,7 @@ import '../../../mock/ui_settings';
import { TestProviders } from '../../../mock';
import { UtilityBarGroup, UtilityBarSection, UtilityBarText } from './index';
-jest.mock('../../lib/settings/use_kibana_ui_setting');
+jest.mock('../../../lib/settings/use_kibana_ui_setting');
describe('UtilityBarSection', () => {
test('it renders', () => {
diff --git a/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_text.test.tsx b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_text.test.tsx
index d43d34fbd0b6b..0743e5cab02b4 100644
--- a/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_text.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_text.test.tsx
@@ -12,7 +12,7 @@ import '../../../mock/ui_settings';
import { TestProviders } from '../../../mock';
import { UtilityBarText } from './index';
-jest.mock('../../lib/settings/use_kibana_ui_setting');
+jest.mock('../../../lib/settings/use_kibana_ui_setting');
describe('UtilityBarText', () => {
test('it renders', () => {
diff --git a/x-pack/legacy/plugins/siem/public/components/link_to/redirect_to_detection_engine.tsx b/x-pack/legacy/plugins/siem/public/components/link_to/redirect_to_detection_engine.tsx
index 6999fec2f00f8..74aec076ec4d5 100644
--- a/x-pack/legacy/plugins/siem/public/components/link_to/redirect_to_detection_engine.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/link_to/redirect_to_detection_engine.tsx
@@ -5,7 +5,8 @@
*/
import React from 'react';
-import { RouteComponentProps } from 'react-router';
+import { RouteComponentProps } from 'react-router-dom';
+
import { RedirectWrapper } from './redirect_wrapper';
export type DetectionEngineComponentProps = RouteComponentProps<{
From b20ef37471ba0e2c05297aa3b68b7fd63bc885de Mon Sep 17 00:00:00 2001
From: Garrett Spong
Date: Tue, 12 Nov 2019 14:27:10 -0700
Subject: [PATCH 57/57] Removing unused translation
---
x-pack/plugins/translations/translations/ja-JP.json | 1 -
x-pack/plugins/translations/translations/zh-CN.json | 1 -
2 files changed, 2 deletions(-)
diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json
index 07076a7fa461d..76932fe420444 100644
--- a/x-pack/plugins/translations/translations/ja-JP.json
+++ b/x-pack/plugins/translations/translations/ja-JP.json
@@ -8871,7 +8871,6 @@
"xpack.siem.formatted.duration.noDurationTooltip": "期間がありません",
"xpack.siem.formatted.duration.zeroNanosecondsTooltip": "0ナノ秒",
"xpack.siem.formattedDuration.tooltipLabel": "生",
- "xpack.siem.global.addData": "データの投入",
"xpack.siem.headerPage.pageSubtitle": "前回のイベント: {beat}",
"xpack.siem.host.details.architectureLabel": "アーキテクチャー",
"xpack.siem.host.details.firstSeenTitle": "初回の認識",
diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json
index 61421acb7dc4a..dfbeaa0e2e1c7 100644
--- a/x-pack/plugins/translations/translations/zh-CN.json
+++ b/x-pack/plugins/translations/translations/zh-CN.json
@@ -9026,7 +9026,6 @@
"xpack.siem.formatted.duration.noDurationTooltip": "无持续时间",
"xpack.siem.formatted.duration.zeroNanosecondsTooltip": "零纳秒",
"xpack.siem.formattedDuration.tooltipLabel": "原始",
- "xpack.siem.global.addData": "添加数据",
"xpack.siem.headerPage.pageSubtitle": "最后事件:{beat}",
"xpack.siem.host.details.architectureLabel": "架构",
"xpack.siem.host.details.firstSeenTitle": "首次看到时间",