[Security Solution] - Bug fixes (#92294)

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Michael Olorunnisola 2021-03-02 08:37:30 -05:00 committed by GitHub
parent 16a3780021
commit 3c4a3b833e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 888 additions and 138 deletions

View file

@ -14,13 +14,11 @@ import { DescriptionListStyled } from '../../../common/components/page';
export const OverviewDescriptionList = ({
dataTestSubj,
descriptionList,
isInDetailsSidePanel = false,
}: {
dataTestSubj?: string;
descriptionList: DescriptionList[];
isInDetailsSidePanel: boolean;
}) => (
<EuiFlexItem grow={!isInDetailsSidePanel}>
<EuiFlexItem grow={true}>
<DescriptionListStyled data-test-subj={dataTestSubj} listItems={descriptionList} />
</EuiFlexItem>
);

View file

@ -144,11 +144,7 @@ export const IpOverview = React.memo<IpOverviewProps>(
<InspectButton queryId={id} title={i18n.INSPECT_TITLE} inspectIndex={0} />
)}
{descriptionLists.map((descriptionList, index) => (
<OverviewDescriptionList
descriptionList={descriptionList}
isInDetailsSidePanel={isInDetailsSidePanel}
key={index}
/>
<OverviewDescriptionList descriptionList={descriptionList} key={index} />
))}
{loading && (

View file

@ -20,79 +20,73 @@ import * as i18n from './translations';
interface Props {
contextID?: string;
data: EndpointFields | null;
isInDetailsSidePanel?: boolean;
}
export const EndpointOverview = React.memo<Props>(
({ contextID, data, isInDetailsSidePanel = false }) => {
const getDefaultRenderer = useCallback(
(fieldName: string, fieldData: EndpointFields, attrName: string) => (
<DefaultFieldRenderer
rowItems={[getOr('', fieldName, fieldData)]}
attrName={attrName}
idPrefix={contextID ? `endpoint-overview-${contextID}` : 'endpoint-overview'}
/>
),
[contextID]
);
const descriptionLists: Readonly<DescriptionList[][]> = useMemo(
() => [
[
{
title: i18n.ENDPOINT_POLICY,
description:
data != null && data.endpointPolicy != null
? data.endpointPolicy
: getEmptyTagValue(),
},
],
[
{
title: i18n.POLICY_STATUS,
description:
data != null && data.policyStatus != null ? (
<EuiHealth
aria-label={data.policyStatus}
color={
data.policyStatus === HostPolicyResponseActionStatus.failure
? 'danger'
: data.policyStatus
}
>
{data.policyStatus}
</EuiHealth>
) : (
getEmptyTagValue()
),
},
],
[
{
title: i18n.SENSORVERSION,
description:
data != null && data.sensorVersion != null
? getDefaultRenderer('sensorVersion', data, 'agent.version')
: getEmptyTagValue(),
},
],
[], // needs 4 columns for design
export const EndpointOverview = React.memo<Props>(({ contextID, data }) => {
const getDefaultRenderer = useCallback(
(fieldName: string, fieldData: EndpointFields, attrName: string) => (
<DefaultFieldRenderer
rowItems={[getOr('', fieldName, fieldData)]}
attrName={attrName}
idPrefix={contextID ? `endpoint-overview-${contextID}` : 'endpoint-overview'}
/>
),
[contextID]
);
const descriptionLists: Readonly<DescriptionList[][]> = useMemo(
() => [
[
{
title: i18n.ENDPOINT_POLICY,
description:
data != null && data.endpointPolicy != null ? data.endpointPolicy : getEmptyTagValue(),
},
],
[data, getDefaultRenderer]
);
[
{
title: i18n.POLICY_STATUS,
description:
data != null && data.policyStatus != null ? (
<EuiHealth
aria-label={data.policyStatus}
color={
data.policyStatus === HostPolicyResponseActionStatus.failure
? 'danger'
: data.policyStatus
}
>
{data.policyStatus}
</EuiHealth>
) : (
getEmptyTagValue()
),
},
],
[
{
title: i18n.SENSORVERSION,
description:
data != null && data.sensorVersion != null
? getDefaultRenderer('sensorVersion', data, 'agent.version')
: getEmptyTagValue(),
},
],
[], // needs 4 columns for design
],
[data, getDefaultRenderer]
);
return (
<>
{descriptionLists.map((descriptionList, index) => (
<OverviewDescriptionList
dataTestSubj="endpoint-overview"
descriptionList={descriptionList}
isInDetailsSidePanel={isInDetailsSidePanel}
key={index}
/>
))}
</>
);
}
);
return (
<>
{descriptionLists.map((descriptionList, index) => (
<OverviewDescriptionList
dataTestSubj="endpoint-overview"
descriptionList={descriptionList}
key={index}
/>
))}
</>
);
});
EndpointOverview.displayName = 'EndpointOverview';

View file

@ -207,11 +207,7 @@ export const HostOverview = React.memo<HostSummaryProps>(
<InspectButton queryId={id} title={i18n.INSPECT_TITLE} inspectIndex={0} />
)}
{descriptionLists.map((descriptionList, index) => (
<OverviewDescriptionList
descriptionList={descriptionList}
isInDetailsSidePanel={isInDetailsSidePanel}
key={index}
/>
<OverviewDescriptionList descriptionList={descriptionList} key={index} />
))}
{loading && (
@ -229,11 +225,7 @@ export const HostOverview = React.memo<HostSummaryProps>(
<>
<EuiHorizontalRule />
<OverviewWrapper direction={isInDetailsSidePanel ? 'column' : 'row'}>
<EndpointOverview
contextID={contextID}
data={data.endpoint}
isInDetailsSidePanel={isInDetailsSidePanel}
/>
<EndpointOverview contextID={contextID} data={data.endpoint} />
{loading && (
<Loader

View file

@ -49,7 +49,7 @@ export const ResolverNoProcessEvents = () => (
</EuiText>
<EuiSpacer size="m" />
<StyledEuiCodeBlock language="html" paddingSize="s" isCopyable>
{"event.category: 'process'"}
{'event.category: "process"'}
</StyledEuiCodeBlock>
</StyledEuiFlexGroup>
);

View file

@ -24,9 +24,9 @@ exports[`Details Panel Component DetailsPanel: rendering it should not render th
exports[`Details Panel Component DetailsPanel:EventDetails: rendering it should render the Details Panel when the panelView is set and the associated params are set 1`] = `
.c0 {
-webkit-flex: 0;
-ms-flex: 0;
flex: 0;
-webkit-flex: 0 1 auto;
-ms-flex: 0 1 auto;
flex: 0 1 auto;
}
<DetailsPanel
@ -237,9 +237,9 @@ exports[`Details Panel Component DetailsPanel:EventDetails: rendering it should
exports[`Details Panel Component DetailsPanel:EventDetails: rendering it should render the Event Details view of the Details Panel in the flyout when the panelView is eventDetail and the eventId is set 1`] = `
Array [
.c1 {
-webkit-flex: 0;
-ms-flex: 0;
flex: 0;
-webkit-flex: 0 1 auto;
-ms-flex: 0 1 auto;
flex: 0 1 auto;
}
.c2 .euiFlyoutBody__overflow {
@ -268,13 +268,13 @@ Array [
<Styled(EuiFlyout)
data-test-subj="timeline:details-panel:flyout"
onClose={[Function]}
size="s"
size="m"
>
<EuiFlyout
className="c0"
data-test-subj="timeline:details-panel:flyout"
onClose={[Function]}
size="s"
size="m"
>
<EuiWindowEvent
event="keydown"
@ -287,7 +287,7 @@ Array [
data-eui="EuiFocusTrap"
>
<div
className="euiFlyout euiFlyout--small euiFlyout--paddingLarge c0"
className="euiFlyout euiFlyout--medium euiFlyout--paddingLarge c0"
data-test-subj="timeline:details-panel:flyout"
role="dialog"
tabIndex={0}
@ -509,9 +509,9 @@ Array [
</EuiFlyout>
</Styled(EuiFlyout)>,
.c1 {
-webkit-flex: 0;
-ms-flex: 0;
flex: 0;
-webkit-flex: 0 1 auto;
-ms-flex: 0 1 auto;
flex: 0 1 auto;
}
.c2 .euiFlyoutBody__overflow {
@ -541,7 +541,7 @@ Array [
className="c0"
data-test-subj="timeline:details-panel:flyout"
onClose={[Function]}
size="s"
size="m"
>
<EuiWindowEvent
event="keydown"
@ -554,7 +554,7 @@ Array [
data-eui="EuiFocusTrap"
>
<div
className="euiFlyout euiFlyout--small euiFlyout--paddingLarge c0"
className="euiFlyout euiFlyout--medium euiFlyout--paddingLarge c0"
data-test-subj="timeline:details-panel:flyout"
role="dialog"
tabIndex={0}
@ -775,9 +775,9 @@ Array [
</EuiFocusTrap>
</EuiFlyout>,
.c1 {
-webkit-flex: 0;
-ms-flex: 0;
flex: 0;
-webkit-flex: 0 1 auto;
-ms-flex: 0 1 auto;
flex: 0 1 auto;
}
.c2 .euiFlyoutBody__overflow {
@ -804,7 +804,7 @@ Array [
}
<div
className="euiFlyout euiFlyout--small euiFlyout--paddingLarge c0"
className="euiFlyout euiFlyout--medium euiFlyout--paddingLarge c0"
data-test-subj="timeline:details-panel:flyout"
role="dialog"
tabIndex={0}

View file

@ -51,7 +51,7 @@ interface ExpandableEventTitleProps {
}
const StyledEuiFlexGroup = styled(EuiFlexGroup)`
flex: 0;
flex: 0 1 auto;
`;
const StyledFlexGroup = styled(EuiFlexGroup)`

View file

@ -0,0 +1,669 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Expandable Host Component ExpandableHostDetails: rendering it should render the HostOverview of the ExpandableHostDetails 1`] = `
<ExpandableHostDetails
contextID="text-context"
hostName="testHostName"
>
<Connect(HostOverviewByNameComponentQuery)
endDate="2020-07-08T08:20:18.966Z"
hostName="testHostName"
indexNames={
Array [
"IShouldBeUsed",
]
}
skip={false}
sourceId="default"
startDate="2020-07-07T08:20:18.966Z"
>
<HostOverviewByNameComponentQuery
dispatch={[Function]}
endDate="2020-07-08T08:20:18.966Z"
hostName="testHostName"
indexNames={
Array [
"IShouldBeUsed",
]
}
isInspected={false}
skip={false}
sourceId="default"
startDate="2020-07-07T08:20:18.966Z"
>
<Query
fetchPolicy="cache-and-network"
notifyOnNetworkStatusChange={true}
query={
Object {
"definitions": Array [
Object {
"directives": Array [],
"kind": "OperationDefinition",
"name": Object {
"kind": "Name",
"value": "GetHostOverviewQuery",
},
"operation": "query",
"selectionSet": Object {
"kind": "SelectionSet",
"selections": Array [
Object {
"alias": undefined,
"arguments": Array [
Object {
"kind": "Argument",
"name": Object {
"kind": "Name",
"value": "id",
},
"value": Object {
"kind": "Variable",
"name": Object {
"kind": "Name",
"value": "sourceId",
},
},
},
],
"directives": Array [],
"kind": "Field",
"name": Object {
"kind": "Name",
"value": "source",
},
"selectionSet": Object {
"kind": "SelectionSet",
"selections": Array [
Object {
"alias": undefined,
"arguments": Array [],
"directives": Array [],
"kind": "Field",
"name": Object {
"kind": "Name",
"value": "id",
},
"selectionSet": undefined,
},
Object {
"alias": undefined,
"arguments": Array [
Object {
"kind": "Argument",
"name": Object {
"kind": "Name",
"value": "hostName",
},
"value": Object {
"kind": "Variable",
"name": Object {
"kind": "Name",
"value": "hostName",
},
},
},
Object {
"kind": "Argument",
"name": Object {
"kind": "Name",
"value": "timerange",
},
"value": Object {
"kind": "Variable",
"name": Object {
"kind": "Name",
"value": "timerange",
},
},
},
Object {
"kind": "Argument",
"name": Object {
"kind": "Name",
"value": "defaultIndex",
},
"value": Object {
"kind": "Variable",
"name": Object {
"kind": "Name",
"value": "defaultIndex",
},
},
},
],
"directives": Array [],
"kind": "Field",
"name": Object {
"kind": "Name",
"value": "HostOverview",
},
"selectionSet": Object {
"kind": "SelectionSet",
"selections": Array [
Object {
"alias": undefined,
"arguments": Array [],
"directives": Array [],
"kind": "Field",
"name": Object {
"kind": "Name",
"value": "_id",
},
"selectionSet": undefined,
},
Object {
"alias": undefined,
"arguments": Array [],
"directives": Array [],
"kind": "Field",
"name": Object {
"kind": "Name",
"value": "agent",
},
"selectionSet": Object {
"kind": "SelectionSet",
"selections": Array [
Object {
"alias": undefined,
"arguments": Array [],
"directives": Array [],
"kind": "Field",
"name": Object {
"kind": "Name",
"value": "id",
},
"selectionSet": undefined,
},
],
},
},
Object {
"alias": undefined,
"arguments": Array [],
"directives": Array [],
"kind": "Field",
"name": Object {
"kind": "Name",
"value": "host",
},
"selectionSet": Object {
"kind": "SelectionSet",
"selections": Array [
Object {
"alias": undefined,
"arguments": Array [],
"directives": Array [],
"kind": "Field",
"name": Object {
"kind": "Name",
"value": "architecture",
},
"selectionSet": undefined,
},
Object {
"alias": undefined,
"arguments": Array [],
"directives": Array [],
"kind": "Field",
"name": Object {
"kind": "Name",
"value": "id",
},
"selectionSet": undefined,
},
Object {
"alias": undefined,
"arguments": Array [],
"directives": Array [],
"kind": "Field",
"name": Object {
"kind": "Name",
"value": "ip",
},
"selectionSet": undefined,
},
Object {
"alias": undefined,
"arguments": Array [],
"directives": Array [],
"kind": "Field",
"name": Object {
"kind": "Name",
"value": "mac",
},
"selectionSet": undefined,
},
Object {
"alias": undefined,
"arguments": Array [],
"directives": Array [],
"kind": "Field",
"name": Object {
"kind": "Name",
"value": "name",
},
"selectionSet": undefined,
},
Object {
"alias": undefined,
"arguments": Array [],
"directives": Array [],
"kind": "Field",
"name": Object {
"kind": "Name",
"value": "os",
},
"selectionSet": Object {
"kind": "SelectionSet",
"selections": Array [
Object {
"alias": undefined,
"arguments": Array [],
"directives": Array [],
"kind": "Field",
"name": Object {
"kind": "Name",
"value": "family",
},
"selectionSet": undefined,
},
Object {
"alias": undefined,
"arguments": Array [],
"directives": Array [],
"kind": "Field",
"name": Object {
"kind": "Name",
"value": "name",
},
"selectionSet": undefined,
},
Object {
"alias": undefined,
"arguments": Array [],
"directives": Array [],
"kind": "Field",
"name": Object {
"kind": "Name",
"value": "platform",
},
"selectionSet": undefined,
},
Object {
"alias": undefined,
"arguments": Array [],
"directives": Array [],
"kind": "Field",
"name": Object {
"kind": "Name",
"value": "version",
},
"selectionSet": undefined,
},
],
},
},
Object {
"alias": undefined,
"arguments": Array [],
"directives": Array [],
"kind": "Field",
"name": Object {
"kind": "Name",
"value": "type",
},
"selectionSet": undefined,
},
],
},
},
Object {
"alias": undefined,
"arguments": Array [],
"directives": Array [],
"kind": "Field",
"name": Object {
"kind": "Name",
"value": "cloud",
},
"selectionSet": Object {
"kind": "SelectionSet",
"selections": Array [
Object {
"alias": undefined,
"arguments": Array [],
"directives": Array [],
"kind": "Field",
"name": Object {
"kind": "Name",
"value": "instance",
},
"selectionSet": Object {
"kind": "SelectionSet",
"selections": Array [
Object {
"alias": undefined,
"arguments": Array [],
"directives": Array [],
"kind": "Field",
"name": Object {
"kind": "Name",
"value": "id",
},
"selectionSet": undefined,
},
],
},
},
Object {
"alias": undefined,
"arguments": Array [],
"directives": Array [],
"kind": "Field",
"name": Object {
"kind": "Name",
"value": "machine",
},
"selectionSet": Object {
"kind": "SelectionSet",
"selections": Array [
Object {
"alias": undefined,
"arguments": Array [],
"directives": Array [],
"kind": "Field",
"name": Object {
"kind": "Name",
"value": "type",
},
"selectionSet": undefined,
},
],
},
},
Object {
"alias": undefined,
"arguments": Array [],
"directives": Array [],
"kind": "Field",
"name": Object {
"kind": "Name",
"value": "provider",
},
"selectionSet": undefined,
},
Object {
"alias": undefined,
"arguments": Array [],
"directives": Array [],
"kind": "Field",
"name": Object {
"kind": "Name",
"value": "region",
},
"selectionSet": undefined,
},
],
},
},
Object {
"alias": undefined,
"arguments": Array [],
"directives": Array [
Object {
"arguments": Array [
Object {
"kind": "Argument",
"name": Object {
"kind": "Name",
"value": "if",
},
"value": Object {
"kind": "Variable",
"name": Object {
"kind": "Name",
"value": "inspect",
},
},
},
],
"kind": "Directive",
"name": Object {
"kind": "Name",
"value": "include",
},
},
],
"kind": "Field",
"name": Object {
"kind": "Name",
"value": "inspect",
},
"selectionSet": Object {
"kind": "SelectionSet",
"selections": Array [
Object {
"alias": undefined,
"arguments": Array [],
"directives": Array [],
"kind": "Field",
"name": Object {
"kind": "Name",
"value": "dsl",
},
"selectionSet": undefined,
},
Object {
"alias": undefined,
"arguments": Array [],
"directives": Array [],
"kind": "Field",
"name": Object {
"kind": "Name",
"value": "response",
},
"selectionSet": undefined,
},
],
},
},
Object {
"alias": undefined,
"arguments": Array [],
"directives": Array [],
"kind": "Field",
"name": Object {
"kind": "Name",
"value": "endpoint",
},
"selectionSet": Object {
"kind": "SelectionSet",
"selections": Array [
Object {
"alias": undefined,
"arguments": Array [],
"directives": Array [],
"kind": "Field",
"name": Object {
"kind": "Name",
"value": "endpointPolicy",
},
"selectionSet": undefined,
},
Object {
"alias": undefined,
"arguments": Array [],
"directives": Array [],
"kind": "Field",
"name": Object {
"kind": "Name",
"value": "policyStatus",
},
"selectionSet": undefined,
},
Object {
"alias": undefined,
"arguments": Array [],
"directives": Array [],
"kind": "Field",
"name": Object {
"kind": "Name",
"value": "sensorVersion",
},
"selectionSet": undefined,
},
],
},
},
],
},
},
],
},
},
],
},
"variableDefinitions": Array [
Object {
"defaultValue": undefined,
"kind": "VariableDefinition",
"type": Object {
"kind": "NonNullType",
"type": Object {
"kind": "NamedType",
"name": Object {
"kind": "Name",
"value": "ID",
},
},
},
"variable": Object {
"kind": "Variable",
"name": Object {
"kind": "Name",
"value": "sourceId",
},
},
},
Object {
"defaultValue": undefined,
"kind": "VariableDefinition",
"type": Object {
"kind": "NonNullType",
"type": Object {
"kind": "NamedType",
"name": Object {
"kind": "Name",
"value": "String",
},
},
},
"variable": Object {
"kind": "Variable",
"name": Object {
"kind": "Name",
"value": "hostName",
},
},
},
Object {
"defaultValue": undefined,
"kind": "VariableDefinition",
"type": Object {
"kind": "NonNullType",
"type": Object {
"kind": "NamedType",
"name": Object {
"kind": "Name",
"value": "TimerangeInput",
},
},
},
"variable": Object {
"kind": "Variable",
"name": Object {
"kind": "Name",
"value": "timerange",
},
},
},
Object {
"defaultValue": undefined,
"kind": "VariableDefinition",
"type": Object {
"kind": "NonNullType",
"type": Object {
"kind": "ListType",
"type": Object {
"kind": "NonNullType",
"type": Object {
"kind": "NamedType",
"name": Object {
"kind": "Name",
"value": "String",
},
},
},
},
},
"variable": Object {
"kind": "Variable",
"name": Object {
"kind": "Name",
"value": "defaultIndex",
},
},
},
Object {
"defaultValue": undefined,
"kind": "VariableDefinition",
"type": Object {
"kind": "NonNullType",
"type": Object {
"kind": "NamedType",
"name": Object {
"kind": "Name",
"value": "Boolean",
},
},
},
"variable": Object {
"kind": "Variable",
"name": Object {
"kind": "Name",
"value": "inspect",
},
},
},
],
},
],
"kind": "Document",
"loc": Object {
"end": 930,
"start": 0,
},
}
}
skip={false}
variables={
Object {
"defaultIndex": Array [
"IShouldBeUsed",
],
"hostName": "testHostName",
"inspect": false,
"sourceId": "default",
"timerange": Object {
"from": "2020-07-07T08:20:18.966Z",
"interval": "12h",
"to": "2020-07-08T08:20:18.966Z",
},
}
}
/>
</HostOverviewByNameComponentQuery>
</Connect(HostOverviewByNameComponentQuery)>
</ExpandableHostDetails>
`;

View file

@ -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
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { mount } from 'enzyme';
import React from 'react';
import '../../../../common/mock/match_media';
import {
apolloClientObservable,
mockGlobalState,
TestProviders,
SUB_PLUGINS_REDUCER,
kibanaObservable,
createSecuritySolutionStorageMock,
} from '../../../../common/mock';
import { createStore, State } from '../../../../common/store';
import { ExpandableHostDetails } from './expandable_host';
jest.mock('react-apollo', () => {
const original = jest.requireActual('react-apollo');
return {
...original,
// eslint-disable-next-line react/display-name
Query: () => <></>,
};
});
describe('Expandable Host Component', () => {
const state: State = {
...mockGlobalState,
sourcerer: {
...mockGlobalState.sourcerer,
configIndexPatterns: ['IShouldBeUsed'],
},
};
const { storage } = createSecuritySolutionStorageMock();
const store = createStore(
state,
SUB_PLUGINS_REDUCER,
apolloClientObservable,
kibanaObservable,
storage
);
const mockProps = {
contextID: 'text-context',
hostName: 'testHostName',
};
describe('ExpandableHostDetails: rendering', () => {
test('it should render the HostOverview of the ExpandableHostDetails', () => {
const wrapper = mount(
<TestProviders store={store}>
<ExpandableHostDetails {...mockProps} />
</TestProviders>
);
expect(wrapper.find('ExpandableHostDetails')).toMatchSnapshot();
});
test('it should render the HostOverview of the ExpandableHostDetails with the correct indices', () => {
const wrapper = mount(
<TestProviders store={store}>
<ExpandableHostDetails {...mockProps} />
</TestProviders>
);
expect(wrapper.find('HostOverviewByNameComponentQuery').prop('indexNames')).toStrictEqual([
'IShouldBeUsed',
]);
});
});
});

View file

@ -5,10 +5,11 @@
* 2.0.
*/
import React from 'react';
import React, { useMemo } from 'react';
import styled from 'styled-components';
import { i18n } from '@kbn/i18n';
import { EuiTitle } from '@elastic/eui';
import { sourcererSelectors } from '../../../../common/store/sourcerer';
import { HostDetailsLink } from '../../../../common/components/links';
import { useGlobalTime } from '../../../../common/containers/use_global_time';
import { useSourcererScope } from '../../../../common/containers/sourcerer';
@ -19,6 +20,7 @@ import { AnomalyTableProvider } from '../../../../common/components/ml/anomaly/a
import { hostToCriteria } from '../../../../common/components/ml/criteria/host_to_criteria';
import { scoreIntervalToDateTime } from '../../../../common/components/ml/score/score_interval_to_datetime';
import { HostOverviewByNameQuery } from '../../../../hosts/containers/hosts/details';
import { useDeepEqualSelector } from '../../../../common/hooks/use_selector';
interface ExpandableHostProps {
hostName: string;
@ -54,10 +56,25 @@ export const ExpandableHostDetails = ({
hostName,
}: ExpandableHostProps & { contextID: string }) => {
const { to, from, isInitializing } = useGlobalTime();
const { docValueFields, selectedPatterns } = useSourcererScope();
const { docValueFields } = useSourcererScope();
/*
Normally `selectedPatterns` from useSourcerScope would be where we obtain the indices,
but those indices are only loaded when viewing the pages where the sourcerer is initialized (i.e. Hosts and Overview)
When a user goes directly to the detections page, the patterns have not been loaded yet
as that information isn't used for the detections page. With this details component being accessible
from the detections page, the decision was made to get all existing index names to account for this.
Otherwise, an empty array is defaulted for the `indexNames` in the query which leads to inconsistencies in the data returned
(i.e. extraneous endpoint data is retrieved from the backend leading to endpoint data not being returned)
*/
const allExistingIndexNamesSelector = useMemo(
() => sourcererSelectors.getAllExistingIndexNamesSelector(),
[]
);
const allPatterns = useDeepEqualSelector<string[]>(allExistingIndexNamesSelector);
return (
<HostOverviewByNameQuery
indexNames={selectedPatterns}
indexNames={allPatterns}
sourceId="default"
hostName={hostName}
skip={isInitializing}
@ -80,7 +97,7 @@ export const ExpandableHostDetails = ({
data={hostOverview as HostItem}
anomaliesData={anomaliesData}
isLoadingAnomaliesData={isLoadingAnomaliesData}
indexNames={selectedPatterns}
indexNames={allPatterns}
loading={loading}
startDate={from}
endDate={to}

View file

@ -35,25 +35,26 @@ const StyledEuiFlyoutBody = styled(EuiFlyoutBody)`
flex: 1;
overflow-x: hidden;
overflow-y: scroll;
padding: ${({ theme }) => `${theme.eui.paddingSizes.xs} ${theme.eui.paddingSizes.m} 64px`};
margin-bottom: ${({ theme }) => `${theme.eui.paddingSizes.l}`};
padding: ${({ theme }) => `${theme.eui.paddingSizes.xs} ${theme.eui.paddingSizes.m} 0px`};
}
}
`;
const StyledEuiFlexGroup = styled(EuiFlexGroup)`
flex: 0;
`;
const StyledEuiFlexItem = styled(EuiFlexItem)`
&.euiFlexItem {
flex: 1 0 0;
overflow-y: scroll;
overflow-x: hidden;
}
flex: 1 0 auto;
`;
const StyledEuiFlexButtonWrapper = styled(EuiFlexItem)`
align-self: flex-start;
flex: 1 0 auto;
`;
const StyledPanelContent = styled.div`
display: block;
height: 100%;
overflow-y: scroll;
overflow-x: hidden;
`;
interface HostDetailsProps {
@ -107,9 +108,9 @@ export const HostDetailsPanel: React.FC<HostDetailsProps> = React.memo(
<ExpandableHostDetailsPageLink hostName={hostName} />
</StyledEuiFlexButtonWrapper>
<EuiSpacer size="m" />
<StyledEuiFlexItem grow={true}>
<StyledPanelContent>
<ExpandableHostDetails contextID={contextID} hostName={hostName} />
</StyledEuiFlexItem>
</StyledPanelContent>
</>
);
}

View file

@ -7,7 +7,7 @@
import React, { useCallback, useMemo } from 'react';
import { useDispatch } from 'react-redux';
import { EuiFlyout } from '@elastic/eui';
import { EuiFlyout, EuiFlyoutProps } from '@elastic/eui';
import styled from 'styled-components';
import { timelineActions, timelineSelectors } from '../../store/timeline';
import { timelineDefaults } from '../../store/timeline/defaults';
@ -69,9 +69,10 @@ export const DetailsPanel = React.memo(
if (!currentTabDetail?.panelView) return null;
let visiblePanel = null; // store in variable to make return statement more readable
let panelSize: EuiFlyoutProps['size'] = 's';
const contextID = `${timelineId}-${activeTab}`;
if (currentTabDetail?.panelView === 'eventDetail' && currentTabDetail?.params?.eventId) {
panelSize = 'm';
visiblePanel = (
<EventDetailsPanel
browserFields={browserFields}
@ -108,7 +109,11 @@ export const DetailsPanel = React.memo(
}
return isFlyoutView ? (
<StyledEuiFlyout data-test-subj="timeline:details-panel:flyout" size="s" onClose={closePanel}>
<StyledEuiFlyout
data-test-subj="timeline:details-panel:flyout"
size={panelSize}
onClose={closePanel}
>
{visiblePanel}
</StyledEuiFlyout>
) : (

View file

@ -42,19 +42,19 @@ const StyledEuiFlyoutBody = styled(EuiFlyoutBody)`
`;
const StyledEuiFlexGroup = styled(EuiFlexGroup)`
flex: 0;
`;
const StyledEuiFlexItem = styled(EuiFlexItem)`
&.euiFlexItem {
flex: 1 0 0;
overflow-y: scroll;
overflow-x: hidden;
}
flex: 1 0 auto;
`;
const StyledEuiFlexButtonWrapper = styled(EuiFlexItem)`
align-self: flex-start;
flex: 1 0 auto;
`;
const StyledPanelContent = styled.div`
display: block;
height: 100%;
overflow-y: scroll;
overflow-x: hidden;
`;
interface NetworkDetailsProps {
@ -104,9 +104,9 @@ export const NetworkDetailsPanel = React.memo(
<ExpandableNetworkDetailsPageLink expandedNetwork={expandedNetwork} />
</StyledEuiFlexButtonWrapper>
<EuiSpacer size="m" />
<StyledEuiFlexItem grow={true}>
<StyledPanelContent>
<ExpandableNetworkDetails contextID={contextID} expandedNetwork={expandedNetwork} />
</StyledEuiFlexItem>
</StyledPanelContent>
</>
);
}