[Security Solution] remove isDraggable props + various related cleanups (#207959)

## Summary

This PR removes the `isDraggable` prop throughout Security Solution.
Unless I'm mistaken, this property isn't necessary anymore, as we do not
use those draggable elements anymore. From what I could see, we had its
value set to `false` everywhere.

This lead to a lot of files impacted, but most of them have only a
couple of lines changed. In some files though, removing the
`isDraggable` prop allowed to remove more code than became obsolete.

**No UI changes should have been introduced in this PR!**

### What this PR does

- removes `isDraggable` everywhere
- performs the extra small cleanup when obvious
- updates all corresponding unit e2e and tests

### What this PR does

- rename files or component names to limit the already extensive impact
of the code change
This commit is contained in:
Philippe Oberti 2025-02-06 22:56:09 +01:00 committed by GitHub
parent 3a14752dad
commit ebb31d249f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
213 changed files with 1873 additions and 6579 deletions

View file

@ -190,8 +190,6 @@ module.exports = {
/x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]common[\/\\]components[\/\\]drag_and_drop[\/\\]draggable_wrapper.tsx/,
/x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]common[\/\\]components[\/\\]drag_and_drop[\/\\]droppable_wrapper.tsx/,
/x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]common[\/\\]components[\/\\]drag_and_drop[\/\\]provider_container.tsx/,
/x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]common[\/\\]components[\/\\]draggables[\/\\]field_badge[\/\\]index.tsx/,
/x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]common[\/\\]components[\/\\]draggables[\/\\]index.tsx/,
/x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]common[\/\\]components[\/\\]empty_page[\/\\]index.tsx/,
/x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]common[\/\\]components[\/\\]empty_value[\/\\]empty_value.test.tsx/,
/x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]common[\/\\]components[\/\\]empty_value[\/\\]index.tsx/,

View file

@ -36409,9 +36409,6 @@
"xpack.securitySolution.dragAndDrop.copyToClipboardTooltip": "Copier dans le Presse-papiers",
"xpack.securitySolution.dragAndDrop.draggableKeyboardInstructionsNotDraggingScreenReaderOnly": "Appuyez sur Entrée pour accéder aux options ou sur la barre d'espace pour commencer le glisser-déposer.",
"xpack.securitySolution.dragAndDrop.fieldLabel": "Champ",
"xpack.securitySolution.draggables.field.categoryLabel": "Catégorie",
"xpack.securitySolution.draggables.field.fieldLabel": "Champ",
"xpack.securitySolution.draggables.field.typeLabel": "Type",
"xpack.securitySolution.editDataProvider.doesNotExistLabel": "n'existe pas",
"xpack.securitySolution.editDataProvider.existsLabel": "existe",
"xpack.securitySolution.editDataProvider.fieldLabel": "Champ",

View file

@ -36269,9 +36269,6 @@
"xpack.securitySolution.dragAndDrop.copyToClipboardTooltip": "クリップボードにコピー",
"xpack.securitySolution.dragAndDrop.draggableKeyboardInstructionsNotDraggingScreenReaderOnly": "オプションは Enter キーを押します。ドラッグを開始するには、スペースを押します。",
"xpack.securitySolution.dragAndDrop.fieldLabel": "フィールド",
"xpack.securitySolution.draggables.field.categoryLabel": "カテゴリー",
"xpack.securitySolution.draggables.field.fieldLabel": "フィールド",
"xpack.securitySolution.draggables.field.typeLabel": "型",
"xpack.securitySolution.editDataProvider.doesNotExistLabel": "存在しない",
"xpack.securitySolution.editDataProvider.existsLabel": "存在する",
"xpack.securitySolution.editDataProvider.fieldLabel": "フィールド",

View file

@ -35728,9 +35728,6 @@
"xpack.securitySolution.dragAndDrop.copyToClipboardTooltip": "复制到剪贴板",
"xpack.securitySolution.dragAndDrop.draggableKeyboardInstructionsNotDraggingScreenReaderOnly": "按 enter 键可显示选项,或按空格键开始拖动。",
"xpack.securitySolution.dragAndDrop.fieldLabel": "字段",
"xpack.securitySolution.draggables.field.categoryLabel": "类别",
"xpack.securitySolution.draggables.field.fieldLabel": "字段",
"xpack.securitySolution.draggables.field.typeLabel": "类型",
"xpack.securitySolution.editDataProvider.doesNotExistLabel": "不存在",
"xpack.securitySolution.editDataProvider.existsLabel": "存在",
"xpack.securitySolution.editDataProvider.fieldLabel": "字段",

View file

@ -19,12 +19,10 @@ export interface DeprecatedRowRenderer {
renderRow: ({
contextId,
data,
isDraggable,
scopeId,
}: {
contextId?: string;
data: Ecs;
isDraggable: boolean;
scopeId: string;
}) => React.ReactNode;
}

View file

@ -23,7 +23,6 @@ export type CellValueElementProps = EuiDataGridCellValueElementProps & {
ecsData?: Ecs;
eventId: string; // _id
header: ColumnHeaderOptions;
isDraggable: boolean;
isTimeline?: boolean; // Default cell renderer is used for both the alert table and timeline. This allows us to cheaply separate concerns
linkValues: string[] | undefined;
rowRenderers?: RowRenderer[];

View file

@ -14,12 +14,10 @@ export interface RowRenderer {
renderRow: ({
contextId,
data,
isDraggable,
scopeId,
}: {
contextId?: string;
data: Ecs;
isDraggable: boolean;
scopeId: string;
}) => React.ReactNode;
}

View file

@ -14,7 +14,6 @@ interface HostPanelProps extends Record<string, unknown> {
contextID: string;
scopeId: string;
hostName: string;
isDraggable?: boolean;
}
interface HostPanelExpandableFlyoutProps extends FlyoutPanelProps {

View file

@ -58,7 +58,6 @@ export const getFieldMarkdownRenderer = (disableActions: boolean) => {
eventId=""
iconType={icon}
isAggregatable={false}
isDraggable={false}
field={name}
value={value}
>

View file

@ -71,7 +71,6 @@ const DraggableLegendItemComponent: React.FC<{
field={field}
hideTopN={true}
id={dataProviderId}
isDraggable={false}
scopeId={scopeId}
value={value}
>

View file

@ -17,7 +17,6 @@ exports[`DraggableWrapper rendering it renders against the snapshot 1`] = `
},
}
}
isDraggable={true}
render={[Function]}
/>
`;

View file

@ -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
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
// https://github.com/DefinitelyTyped/DefinitelyTyped/pull/40309
import type { MovementMode, DraggableId } from '@hello-pangea/dnd';
export interface BeforeCapture {
draggableId: DraggableId;
mode: MovementMode;
}

View file

@ -15,12 +15,7 @@ import { TestProviders } from '../../mock';
import { mockDataProviders } from '../../../timelines/components/timeline/data_providers/mock/mock_data_providers';
import { ROW_RENDERER_BROWSER_EXAMPLE_TIMELINE_ID } from '../../../timelines/components/row_renderers_browser/constants';
import { DragDropContextWrapper } from './drag_drop_context_wrapper';
import {
ConditionalPortal,
disableHoverActions,
DraggableWrapper,
getStyle,
} from './draggable_wrapper';
import { disableHoverActions, DraggableWrapper, getStyle } from './draggable_wrapper';
import { useMountAppended } from '../../utils/use_mount_appended';
import { TimelineId } from '../../../../common/types';
import { TableId } from '@kbn/securitysolution-data-table';
@ -85,11 +80,7 @@ describe('DraggableWrapper', () => {
const wrapper = shallow(
<TestProviders>
<DragDropContextWrapper browserFields={mockBrowserFields}>
<DraggableWrapper
dataProvider={dataProvider}
isDraggable={true}
render={() => message}
/>
<DraggableWrapper dataProvider={dataProvider} render={() => message} />
</DragDropContextWrapper>
</TestProviders>
);
@ -101,11 +92,7 @@ describe('DraggableWrapper', () => {
const wrapper = mount(
<TestProviders>
<DragDropContextWrapper browserFields={mockBrowserFields}>
<DraggableWrapper
dataProvider={dataProvider}
isDraggable={true}
render={() => message}
/>
<DraggableWrapper dataProvider={dataProvider} render={() => message} />
</DragDropContextWrapper>
</TestProviders>
);
@ -115,14 +102,11 @@ describe('DraggableWrapper', () => {
scopeIdsWithHoverActions.forEach((scopeId) => {
test(`it renders hover actions (by default) when 'isDraggable' is false and timelineId is '${scopeId}'`, async () => {
const isDraggable = false;
const { queryByTestId } = render(
<TestProviders>
<DragDropContextWrapper browserFields={mockBrowserFields}>
<DraggableWrapper
dataProvider={dataProvider}
isDraggable={isDraggable}
render={() => message}
scopeId={scopeId}
/>
@ -136,14 +120,11 @@ describe('DraggableWrapper', () => {
scopeIdsNoHoverActions.forEach((scopeId) => {
test(`it does NOT render hover actions when 'isDraggable' is false and timelineId is '${scopeId}'`, async () => {
const isDraggable = false;
const { queryByTestId } = render(
<TestProviders>
<DragDropContextWrapper browserFields={mockBrowserFields}>
<DraggableWrapper
dataProvider={dataProvider}
isDraggable={isDraggable}
render={() => message}
scopeId={scopeId}
/>
@ -161,30 +142,19 @@ describe('DraggableWrapper', () => {
const wrapper = mount(
<TestProviders>
<DragDropContextWrapper browserFields={mockBrowserFields}>
<DraggableWrapper
dataProvider={dataProvider}
isDraggable={true}
render={() => message}
truncate
/>
<DraggableWrapper dataProvider={dataProvider} render={() => message} truncate />
</DragDropContextWrapper>
</TestProviders>
);
expect(wrapper.find('[data-test-subj="draggable-truncatable-content"]').exists()).toEqual(
true
);
expect(wrapper.find('[data-test-subj="render-truncatable-content"]').exists()).toEqual(true);
});
test('it does NOT apply text truncation styling when truncate is NOT specified', () => {
const wrapper = mount(
<TestProviders>
<DragDropContextWrapper browserFields={mockBrowserFields}>
<DraggableWrapper
dataProvider={dataProvider}
isDraggable={true}
render={() => message}
/>
<DraggableWrapper dataProvider={dataProvider} render={() => message} />
</DragDropContextWrapper>
</TestProviders>
);
@ -197,21 +167,6 @@ describe('DraggableWrapper', () => {
});
describe('ConditionalPortal', () => {
const mount = useMountAppended();
const props = {
registerProvider: jest.fn(),
};
it('calls registerProvider when isDragging', () => {
mount(
<ConditionalPortal {...props}>
<div />
</ConditionalPortal>
);
expect(props.registerProvider.mock.calls.length).toEqual(1);
});
describe('getStyle', () => {
const style: DraggingStyle = {
boxSizing: 'border-box',

View file

@ -5,80 +5,20 @@
* 2.0.
*/
import { EuiScreenReaderOnly } from '@elastic/eui';
import { DRAGGABLE_KEYBOARD_WRAPPER_CLASS_NAME } from '@kbn/securitysolution-t-grid';
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import React, { useMemo } from 'react';
import type {
DraggableProvided,
DraggableStateSnapshot,
DraggingStyle,
DroppableProvided,
NotDraggingStyle,
} from '@hello-pangea/dnd';
import { Draggable, Droppable } from '@hello-pangea/dnd';
import { useDispatch } from 'react-redux';
import styled from 'styled-components';
import { TableId } from '@kbn/securitysolution-data-table';
import { dragAndDropActions } from '../../store/drag_and_drop';
import type { DataProvider } from '../../../timelines/components/timeline/data_providers/data_provider';
import { ROW_RENDERER_BROWSER_EXAMPLE_TIMELINE_ID } from '../../../timelines/components/row_renderers_browser/constants';
import { TruncatableText } from '../truncatable_text';
import { CellActionsWrapper } from './cell_actions_wrapper';
import { getDraggableId, getDroppableId } from './helpers';
import { ProviderContainer } from './provider_container';
import * as i18n from './translations';
// As right now, we do not know what we want there, we will keep it as a placeholder
export const DragEffects = styled.div``;
DragEffects.displayName = 'DragEffects';
/**
* Wraps the `@hello-pangea/dnd` error boundary. See also:
* https://github.com/atlassian/react-beautiful-dnd/blob/v12.0.0/docs/guides/setup-problem-detection-and-error-recovery.md
*
* NOTE: This extends from `PureComponent` because, at the time of this
* writing, there's no hook equivalent for `componentDidCatch`, per
* https://reactjs.org/docs/hooks-faq.html#do-hooks-cover-all-use-cases-for-classes
*/
class DragDropErrorBoundary extends React.PureComponent<React.PropsWithChildren<{}>> {
componentDidCatch() {
this.forceUpdate(); // required for recovery
}
render() {
return this.props.children;
}
}
interface WrapperProps {
disabled: boolean;
}
const Wrapper = styled.div<WrapperProps>`
display: inline-block;
max-width: 100%;
[data-rbd-placeholder-context-id] {
display: none !important;
}
${({ disabled }) =>
disabled &&
`
[data-rbd-draggable-id]:hover,
.euiBadge:hover,
.euiBadge__text:hover {
cursor: default;
}
`}
`;
Wrapper.displayName = 'Wrapper';
import { getDraggableId } from './helpers';
export const ProviderContentWrapper = styled.span`
> span.euiToolTipAnchor {
@ -101,7 +41,6 @@ export interface DraggableWrapperProps {
fieldType?: string;
isAggregatable?: boolean;
hideTopN?: boolean;
isDraggable?: boolean;
render: RenderFunctionProp;
scopeId?: string;
truncate?: boolean;
@ -129,145 +68,8 @@ export const getStyle = (
};
};
const DraggableOnWrapper: React.FC<DraggableWrapperProps> = React.memo(
({ dataProvider, render, scopeId, truncate, hideTopN }) => {
const [providerRegistered, setProviderRegistered] = useState(false);
const isDisabled = dataProvider.id.includes(`-${ROW_RENDERER_BROWSER_EXAMPLE_TIMELINE_ID}-`);
const dispatch = useDispatch();
const registerProvider = useCallback(() => {
if (!isDisabled) {
dispatch(dragAndDropActions.registerProvider({ provider: dataProvider }));
setProviderRegistered(true);
}
}, [isDisabled, dispatch, dataProvider]);
const unRegisterProvider = useCallback(
() =>
providerRegistered &&
dispatch(dragAndDropActions.unRegisterProvider({ id: dataProvider.id })),
[providerRegistered, dispatch, dataProvider.id]
);
useEffect(
() => () => {
unRegisterProvider();
},
[unRegisterProvider]
);
const RenderClone = useCallback(
(provided: DraggableProvided, snapshot: DraggableStateSnapshot) => (
<ConditionalPortal registerProvider={registerProvider}>
<div
{...provided.draggableProps}
{...provided.dragHandleProps}
style={getStyle(provided.draggableProps.style, snapshot)}
ref={provided.innerRef}
data-test-subj="providerContainer"
tabIndex={-1}
>
<ProviderContentWrapper
data-test-subj={`draggable-content-${dataProvider.queryMatch.field}`}
>
{render(dataProvider, provided, snapshot)}
</ProviderContentWrapper>
</div>
</ConditionalPortal>
),
[dataProvider, registerProvider, render]
);
const DraggableContent = useCallback(
(provided: DraggableProvided, snapshot: DraggableStateSnapshot) => (
<ProviderContainer
{...provided.draggableProps}
{...provided.dragHandleProps}
ref={(e: HTMLDivElement) => {
provided.innerRef(e);
}}
data-test-subj="providerContainer"
isDragging={snapshot.isDragging}
registerProvider={registerProvider}
tabIndex={-1}
>
<EuiScreenReaderOnly data-test-subj="screenReaderOnlyField">
<p>{dataProvider.queryMatch.field}</p>
</EuiScreenReaderOnly>
{truncate && !snapshot.isDragging ? (
<TruncatableText data-test-subj="draggable-truncatable-content">
{render(dataProvider, provided, snapshot)}
</TruncatableText>
) : (
<ProviderContentWrapper
data-test-subj={`draggable-content-${dataProvider.queryMatch.field}`}
>
{render(dataProvider, provided, snapshot)}
</ProviderContentWrapper>
)}
{!snapshot.isDragging && (
<EuiScreenReaderOnly data-test-subj="draggableKeyboardInstructionsNotDragging">
<p>{i18n.DRAGGABLE_KEYBOARD_INSTRUCTIONS_NOT_DRAGGING_SCREEN_READER_ONLY}</p>
</EuiScreenReaderOnly>
)}
</ProviderContainer>
),
[dataProvider, registerProvider, render, truncate]
);
const DroppableContent = useCallback(
(droppableProvided: DroppableProvided) => (
<div ref={droppableProvided.innerRef} {...droppableProvided.droppableProps}>
<div
className={DRAGGABLE_KEYBOARD_WRAPPER_CLASS_NAME}
data-test-subj="draggableWrapperKeyboardHandler"
role="button"
tabIndex={0}
>
<Draggable
draggableId={getDraggableId(dataProvider.id)}
index={0}
key={getDraggableId(dataProvider.id)}
isDragDisabled={isDisabled}
>
{DraggableContent}
</Draggable>
</div>
{droppableProvided.placeholder}
</div>
),
[DraggableContent, dataProvider.id, isDisabled]
);
const content = useMemo(
() => (
<Wrapper data-test-subj="draggableWrapperDiv" disabled={isDisabled}>
<DragDropErrorBoundary>
<Droppable
isDropDisabled={true}
droppableId={getDroppableId(dataProvider.id)}
renderClone={RenderClone}
>
{DroppableContent}
</Droppable>
</DragDropErrorBoundary>
</Wrapper>
),
[DroppableContent, RenderClone, dataProvider.id, isDisabled]
);
if (isDisabled) return <>{content}</>;
return (
<CellActionsWrapper dataProvider={dataProvider} scopeId={scopeId} hideTopN={hideTopN}>
{content}
</CellActionsWrapper>
);
}
);
DraggableOnWrapper.displayName = 'DraggableOnWrapper';
export const DraggableWrapper: React.FC<DraggableWrapperProps> = React.memo(
({ dataProvider, isDraggable = false, render, scopeId, truncate, hideTopN }) => {
({ dataProvider, render, scopeId, truncate, hideTopN }) => {
const content = useMemo(
() => (
<div tabIndex={-1} data-provider-id={getDraggableId(dataProvider.id)}>
@ -305,47 +107,14 @@ export const DraggableWrapper: React.FC<DraggableWrapperProps> = React.memo(
[dataProvider, render, truncate]
);
if (!isDraggable) {
if (disableHoverActions(scopeId)) {
return <>{content}</>;
}
return (
<CellActionsWrapper dataProvider={dataProvider} scopeId={scopeId} hideTopN={hideTopN}>
{content}
</CellActionsWrapper>
);
if (disableHoverActions(scopeId)) {
return <>{content}</>;
}
return (
<DraggableOnWrapper
dataProvider={dataProvider}
render={render}
scopeId={scopeId}
truncate={truncate}
/>
<CellActionsWrapper dataProvider={dataProvider} scopeId={scopeId} hideTopN={hideTopN}>
{content}
</CellActionsWrapper>
);
}
);
DraggableWrapper.displayName = 'DraggableWrapper';
/**
* Conditionally wraps children in an EuiPortal to ensure drag offsets are correct when dragging
* from containers that have css transforms
*
* See: https://github.com/atlassian/react-beautiful-dnd/issues/499
*/
interface ConditionalPortalProps {
children: React.ReactNode;
registerProvider: () => void;
}
export const ConditionalPortal = React.memo<ConditionalPortalProps>(
({ children, registerProvider }) => {
useEffect(() => {
registerProvider();
}, [registerProvider]);
return <>{children}</>;
}
);
ConditionalPortal.displayName = 'ConditionalPortal';

View file

@ -24,11 +24,13 @@ const ReactDndDropTarget = styled.div<{ isDraggingOver: boolean; height: string
transition: background-color 0.7s ease;
width: 100%;
height: ${({ height }) => height};
.flyout-overlay {
.euiPanel {
background-color: ${(props) => props.theme.eui.euiFormBackgroundColor};
}
}
${(props) =>
props.isDraggingOver
? `
@ -80,6 +82,7 @@ const ReactDndDropTarget = styled.div<{ isDraggingOver: boolean; height: string
.drop-and-provider-timeline {
display: none;
}
& + div {
/* Override dragNdrop beautiful so we do not have our droppable moving around for no good reason */
display: none !important;

View file

@ -39,7 +39,6 @@ exports[`draggables rendering it renders the default DefaultDraggable 1`] = `
fieldType=""
hideTopN={false}
isAggregatable={false}
isDraggable={true}
render={[Function]}
/>
`;

View file

@ -1,48 +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
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { rgba } from 'polished';
import React from 'react';
import styled from 'styled-components';
interface WidthProp {
width?: number;
}
const Field = styled.div.attrs<WidthProp>(({ width }) => {
if (width) {
return {
style: {
width: `${width}px`,
},
};
}
})<WidthProp>`
background-color: ${({ theme }) => theme.eui.euiColorEmptyShade};
border: ${({ theme }) => theme.eui.euiBorderThin};
box-shadow: 0 2px 2px -1px ${({ theme }) => rgba(theme.eui.euiColorMediumShade, 0.3)},
0 1px 5px -2px ${({ theme }) => rgba(theme.eui.euiColorMediumShade, 0.3)};
font-size: ${({ theme }) => theme.eui.euiFontSizeXS};
font-weight: ${({ theme }) => theme.eui.euiFontWeightSemiBold};
line-height: ${({ theme }) => theme.eui.euiLineHeight};
padding: ${({ theme }) => theme.eui.euiSizeXS};
`;
Field.displayName = 'Field';
/**
* Renders a field (e.g. `event.action`) as a draggable badge
*/
export const DraggableFieldBadge = React.memo<{ fieldId: string; fieldWidth?: number }>(
({ fieldId, fieldWidth }) => (
<Field data-test-subj="field" width={fieldWidth}>
{fieldId}
</Field>
)
);
DraggableFieldBadge.displayName = 'DraggableFieldBadge';

View file

@ -1,20 +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
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { i18n } from '@kbn/i18n';
export const CATEGORY = i18n.translate('xpack.securitySolution.draggables.field.categoryLabel', {
defaultMessage: 'Category',
});
export const FIELD = i18n.translate('xpack.securitySolution.draggables.field.fieldLabel', {
defaultMessage: 'Field',
});
export const TYPE = i18n.translate('xpack.securitySolution.draggables.field.typeLabel', {
defaultMessage: 'Type',
});

View file

@ -8,8 +8,6 @@
import { shallow } from 'enzyme';
import React from 'react';
import { EuiToolTip } from '@elastic/eui';
import { DRAGGABLE_KEYBOARD_INSTRUCTIONS_NOT_DRAGGING_SCREEN_READER_ONLY } from '../drag_and_drop/translations';
import { TestProviders } from '../../mock';
import { getEmptyString } from '../empty_value';
import { useMountAppended } from '../../utils/use_mount_appended';
@ -112,9 +110,7 @@ describe('draggables', () => {
<DefaultDraggable id="draggable-id" field={field} value={value} />
</TestProviders>
);
expect(wrapper.text()).toEqual(
`${field}${value}${DRAGGABLE_KEYBOARD_INSTRUCTIONS_NOT_DRAGGING_SCREEN_READER_ONLY}`
);
expect(wrapper.text()).toEqual(value);
});
test('it returns null if value is undefined', () => {
@ -206,9 +202,7 @@ describe('draggables', () => {
/>
</TestProviders>
);
expect(wrapper.text()).toEqual(
`some-fieldsome value${DRAGGABLE_KEYBOARD_INSTRUCTIONS_NOT_DRAGGING_SCREEN_READER_ONLY}`
);
expect(wrapper.text()).toEqual('some value');
});
test('it returns null if value is undefined', () => {
@ -249,9 +243,7 @@ describe('draggables', () => {
/>
</TestProviders>
);
expect(wrapper.text()).toEqual(
`some-field${getEmptyString()}${DRAGGABLE_KEYBOARD_INSTRUCTIONS_NOT_DRAGGING_SCREEN_READER_ONLY}`
);
expect(wrapper.text()).toEqual(getEmptyString());
});
test('it renders a tooltip with the field name if a tooltip is not explicitly provided', () => {

View file

@ -5,23 +5,21 @@
* 2.0.
*/
import { EuiBadge, EuiToolTip } from '@elastic/eui';
import type { IconType, ToolTipPositions } from '@elastic/eui';
import { EuiBadge, EuiToolTip } from '@elastic/eui';
import React, { useCallback, useMemo } from 'react';
import styled from 'styled-components';
import styled from '@emotion/styled';
import type { DraggableWrapperProps } from '../drag_and_drop/draggable_wrapper';
import { DragEffects, DraggableWrapper } from '../drag_and_drop/draggable_wrapper';
import { DraggableWrapper } from '../drag_and_drop/draggable_wrapper';
import { escapeDataProviderId } from '../drag_and_drop/helpers';
import { getEmptyStringTag } from '../empty_value';
import type { DataProvider } from '../../../timelines/components/timeline/data_providers/data_provider';
import { IS_OPERATOR } from '../../../timelines/components/timeline/data_providers/data_provider';
import { Provider } from '../../../timelines/components/timeline/data_providers/provider';
export interface DefaultDraggableType {
hideTopN?: boolean;
id: string;
isDraggable?: boolean;
fieldType?: string;
isAggregatable?: boolean;
field: string;
@ -87,7 +85,6 @@ Content.displayName = 'Content';
* that's only displayed when the specified value is non-`null`.
*
* @param id - a unique draggable id, which typically follows the format `${contextId}-${eventId}-${field}-${value}`
* @param isDraggable - optional prop to disable drag & drop and it will defaulted to true
* @param field - the name of the field, e.g. `network.transport`
* @param value - value of the field e.g. `tcp`
* @param name - defaulting to `field`, this optional human readable name is used by the `DataProvider` that represents the data
@ -102,7 +99,6 @@ export const DefaultDraggable = React.memo<DefaultDraggableType>(
({
hideTopN = false,
id,
isDraggable = true,
field,
fieldType = '',
isAggregatable = false,
@ -133,21 +129,16 @@ export const DefaultDraggable = React.memo<DefaultDraggableType>(
);
const renderCallback = useCallback<DraggableWrapperProps['render']>(
(dataProvider, _, snapshot) =>
snapshot.isDragging ? (
<DragEffects>
<Provider dataProvider={dataProvider} />
</DragEffects>
) : (
<Content
field={field}
tooltipContent={tooltipContent}
tooltipPosition={tooltipPosition}
value={value}
>
{children}
</Content>
),
() => (
<Content
field={field}
tooltipContent={tooltipContent}
tooltipPosition={tooltipPosition}
value={value}
>
{children}
</Content>
),
[children, field, tooltipContent, tooltipPosition, value]
);
@ -159,7 +150,6 @@ export const DefaultDraggable = React.memo<DefaultDraggableType>(
fieldType={fieldType}
isAggregatable={isAggregatable}
hideTopN={hideTopN}
isDraggable={isDraggable}
render={renderCallback}
scopeId={scopeId}
truncate={truncate}
@ -180,7 +170,6 @@ export type BadgeDraggableType = Omit<DefaultDraggableType, 'id'> & {
contextId: string;
eventId: string;
iconType?: IconType;
color?: string;
};
/**
@ -191,9 +180,7 @@ export type BadgeDraggableType = Omit<DefaultDraggableType, 'id'> & {
* @param field - the name of the field, e.g. `network.transport`
* @param value - value of the field e.g. `tcp`
* @param iconType -the (optional) type of icon e.g. `snowflake` to display on the badge
* @param isDraggable
* @param name - defaulting to `field`, this optional human readable name is used by the `DataProvider` that represents the data
* @param color - defaults to `hollow`, optionally overwrite the color of the badge icon
* @param children - defaults to displaying `value`, this allows an arbitrary visualization to be displayed in lieu of the default behavior
* @param tooltipContent - defaults to displaying `field`, pass `null` to
* prevent a tooltip from being displayed, or pass arbitrary content
@ -205,11 +192,9 @@ const DraggableBadgeComponent: React.FC<BadgeDraggableType> = ({
field,
value,
iconType,
isDraggable,
isAggregatable,
fieldType,
name,
color = 'hollow',
children,
scopeId,
tooltipContent,
@ -218,7 +203,6 @@ const DraggableBadgeComponent: React.FC<BadgeDraggableType> = ({
value != null ? (
<DefaultDraggable
id={`draggable-badge-default-draggable-${contextId}-${eventId}-${field}-${value}`}
isDraggable={isDraggable}
isAggregatable={isAggregatable}
fieldType={fieldType}
field={field}
@ -228,7 +212,7 @@ const DraggableBadgeComponent: React.FC<BadgeDraggableType> = ({
tooltipContent={tooltipContent}
queryValue={queryValue}
>
<Badge iconType={iconType} color={color} title="">
<Badge iconType={iconType} color="hollow" title="">
{children ? children : value !== '' ? value : getEmptyStringTag()}
</Badge>
</DefaultDraggable>

View file

@ -39,7 +39,6 @@ const COLUMNS: Array<EuiBasicTableColumn<AlertsByRuleData>> = [
render: (rule: string) => (
<EuiText size="xs" className="eui-textTruncate">
<DefaultDraggable
isDraggable={false}
field={ALERT_RULE_NAME}
hideTopN={true}
id={`alert-detection-draggable-${rule}`}

View file

@ -100,7 +100,6 @@ export const AlertsProgressBar: React.FC<AlertsProcessBarProps> = ({
const labelWithHoverActions = (key: string) => {
return (
<DefaultDraggable
isDraggable={false}
field={groupBySelection}
hideTopN={true}
id={`top-alerts-${key}`}

View file

@ -29,7 +29,6 @@ export const useGetSeverityTableColumns = (): Array<EuiBasicTableColumn<Severity
render: (severity: Severity) => (
<EuiHealth color={severityColors[severity]} textSize="xs">
<DefaultDraggable
isDraggable={false}
field={ALERT_SEVERITY}
hideTopN
id={`alert-severity-draggable-${severity}`}

View file

@ -9,7 +9,7 @@ import type { EuiDataGridRowHeightsOptions, EuiDataGridStyle } from '@elastic/eu
import { EuiFlexGroup } from '@elastic/eui';
import type { Filter } from '@kbn/es-query';
import type { FC } from 'react';
import React, { useRef, useEffect, useState, useCallback, useMemo } from 'react';
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import type { AlertsTableStateProps } from '@kbn/triggers-actions-ui-plugin/public/application/sections/alerts_table/alerts_table_state';
import type { Alert } from '@kbn/triggers-actions-ui-plugin/public/types';
import { ALERT_BUILDING_BLOCK_TYPE, AlertConsumers } from '@kbn/rule-data-utils';
@ -35,6 +35,7 @@ import {
useSessionView,
useSessionViewNavigation,
} from '../../../timelines/components/timeline/tabs/session/use_session_view';
import type { State } from '../../../common/store';
import { inputsSelectors } from '../../../common/store';
import { combineQueries } from '../../../common/lib/kuery';
import { useInvalidFilterQuery } from '../../../common/hooks/use_invalid_filter_query';
@ -46,7 +47,6 @@ import { useDeepEqualSelector, useShallowEqualSelector } from '../../../common/h
import { getColumns } from '../../configurations/security_solution_detections';
import { buildTimeRangeFilter } from './helpers';
import { eventsViewerSelector } from '../../../common/components/events_viewer/selectors';
import type { State } from '../../../common/store';
import * as i18n from './translations';
import { eventRenderedViewColumns } from '../../configurations/security_solution_detections/columns';
import { getAlertsDefaultModel } from './default_config';
@ -79,24 +79,30 @@ const EuiDataGridContainer = styled.div<GridContainerProps>`
}};
}
}
div .euiDataGridRowCell {
display: flex;
align-items: center;
}
div .euiDataGridRowCell > [data-focus-lock-disabled] {
display: flex;
align-items: center;
flex-grow: 1;
width: 100%;
}
div .euiDataGridRowCell__content {
flex-grow: 1;
}
div .siemEventsTable__trSupplement--summary {
display: block;
}
width: 100%;
`;
interface DetectionEngineAlertTableProps {
configId: string;
inputFilters: Filter[];
@ -265,7 +271,6 @@ export const AlertsTableComponent: FC<DetectionEngineAlertTableProps> = ({
rowRenderers: defaultRowRenderers,
isDetails: false,
truncate: true,
isDraggable: false,
};
}, []);

View file

@ -43,7 +43,6 @@ describe('RenderCellValue', () => {
eventId,
header,
isDetails: false,
isDraggable: true,
isExpandable: false,
isExpanded: false,
linkValues,

View file

@ -35,7 +35,6 @@ export const RenderCellValue: React.FC<
eventId,
header,
isDetails,
isDraggable,
isExpandable,
isExpanded,
linkValues,
@ -79,7 +78,6 @@ export const RenderCellValue: React.FC<
eventId={eventId}
header={header}
isDetails={isDetails}
isDraggable={isDraggable}
isExpandable={isExpandable}
isExpanded={isExpanded}
linkValues={linkValues}

View file

@ -1,45 +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
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import type { EuiDataGridColumn } from '@elastic/eui';
import type { ColumnHeaderOptions } from '../../../../../common/types';
import { defaultColumnHeaderType } from '../../../../timelines/components/timeline/body/column_headers/default_headers';
import { DEFAULT_DATE_COLUMN_MIN_WIDTH } from '../../../../timelines/components/timeline/body/constants';
import * as i18n from '../../../components/alerts_table/translations';
/**
* columns implements a subset of `EuiDataGrid`'s `EuiDataGridColumn` interface,
* plus additional TGrid column properties
*/
export const columns: Array<
Pick<EuiDataGridColumn, 'display' | 'displayAsText' | 'id' | 'initialWidth'> & ColumnHeaderOptions
> = [
{
columnHeaderType: defaultColumnHeaderType,
id: '@timestamp',
initialWidth: DEFAULT_DATE_COLUMN_MIN_WIDTH + 5,
},
{
columnHeaderType: defaultColumnHeaderType,
id: 'kibana.alert.rule.name',
displayAsText: i18n.ALERTS_HEADERS_RULE_NAME,
linkField: 'kibana.alert.rule.uuid',
initialWidth: 212,
},
{
columnHeaderType: defaultColumnHeaderType,
id: 'kibana.alert.severity',
displayAsText: i18n.ALERTS_HEADERS_SEVERITY,
initialWidth: 104,
},
{
columnHeaderType: defaultColumnHeaderType,
id: 'kibana.alert.reason',
displayAsText: i18n.ALERTS_HEADERS_REASON,
},
];

View file

@ -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
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { columns } from './columns';
import { RenderCellValue } from './render_cell_value';
export { columns, RenderCellValue };

View file

@ -1,94 +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
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { mount } from 'enzyme';
import { cloneDeep } from 'lodash/fp';
import React from 'react';
import { mockBrowserFields } from '../../../../common/containers/source/mock';
import { DragDropContextWrapper } from '../../../../common/components/drag_and_drop/drag_drop_context_wrapper';
import { defaultHeaders, mockTimelineData, TestProviders } from '../../../../common/mock';
import type { TimelineNonEcsData } from '../../../../../common/search_strategy/timeline';
import type { CellValueElementProps } from '../../../../timelines/components/timeline/cell_rendering';
import { DefaultCellRenderer } from '../../../../timelines/components/timeline/cell_rendering/default_cell_renderer';
import { RenderCellValue } from '.';
import type { ColumnHeaderOptions } from '../../../../../common/types';
jest.mock('../../../../common/lib/kibana');
describe('RenderCellValue', () => {
const columnId = '@timestamp';
const eventId = '_id-123';
const linkValues = ['foo', 'bar', '@baz'];
const rowIndex = 5;
const scopeId = 'table-test';
let data: TimelineNonEcsData[];
let header: ColumnHeaderOptions;
let props: CellValueElementProps;
beforeEach(() => {
data = cloneDeep(mockTimelineData[0].data);
header = cloneDeep(defaultHeaders[0]);
props = {
columnId,
data,
eventId,
header,
isDetails: false,
isDraggable: false,
isExpandable: false,
isExpanded: false,
linkValues,
rowIndex,
colIndex: 0,
setCellProps: jest.fn(),
scopeId,
};
});
test('it renders a custom severity', () => {
const wrapper = mount(
<TestProviders>
<DragDropContextWrapper browserFields={mockBrowserFields}>
<RenderCellValue {...props} columnId="signal.rule.severity" />
</DragDropContextWrapper>
</TestProviders>
);
expect(wrapper.find('[data-test-subj="custom-severity"]').exists()).toBe(true);
});
test('it renders a custom reason', () => {
const wrapper = mount(
<TestProviders>
<DragDropContextWrapper browserFields={mockBrowserFields}>
<RenderCellValue {...props} columnId="signal.reason" />
</DragDropContextWrapper>
</TestProviders>
);
expect(wrapper.find('[data-test-subj="custom-reason"]').exists()).toBe(true);
});
test('it forwards the `CellValueElementProps` to the `DefaultCellRenderer` for any other field', () => {
const aRandomFieldName = 'a.random.field.name';
const wrapper = mount(
<TestProviders>
<DragDropContextWrapper browserFields={mockBrowserFields}>
<RenderCellValue {...props} columnId={aRandomFieldName} />
</DragDropContextWrapper>
</TestProviders>
);
expect(wrapper.find(DefaultCellRenderer).first().props()).toEqual({
...props,
columnId: aRandomFieldName,
});
});
});

View file

@ -1,87 +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
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import type { EuiDataGridCellValueElementProps } from '@elastic/eui';
import { ALERT_SEVERITY, ALERT_REASON } from '@kbn/rule-data-utils';
import React from 'react';
import { useGetMappedNonEcsValue } from '../../../../common/utils/get_mapped_non_ecs_value';
import { DefaultDraggable } from '../../../../common/components/draggables';
import { TruncatableText } from '../../../../common/components/truncatable_text';
import { Severity } from '../../../components/severity';
import type { CellValueElementProps } from '../../../../timelines/components/timeline/cell_rendering';
import { DefaultCellRenderer } from '../../../../timelines/components/timeline/cell_rendering/default_cell_renderer';
const reason =
'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.';
/**
* This implementation of `EuiDataGrid`'s `renderCellValue`
* accepts `EuiDataGridCellValueElementProps`, plus `data`
* from the TGrid
*/
export const RenderCellValue: React.FC<
EuiDataGridCellValueElementProps & CellValueElementProps
> = ({
columnId,
data,
eventId,
header,
isDetails,
isExpandable,
isExpanded,
linkValues,
rowIndex,
colIndex,
setCellProps,
key,
scopeId,
}) => {
const value =
useGetMappedNonEcsValue({
data,
fieldName: columnId,
})?.reduce((x) => x[0]) ?? '';
const draggableId = `${key}-${eventId}-${columnId}-${value}`;
switch (columnId) {
case 'signal.rule.severity':
case ALERT_SEVERITY:
return (
<DefaultDraggable
data-test-subj="custom-severity"
field={columnId}
id={draggableId}
value={value}
scopeId={scopeId}
>
<Severity severity={value} />
</DefaultDraggable>
);
case 'signal.reason':
case ALERT_REASON:
return <TruncatableText data-test-subj="custom-reason">{reason}</TruncatableText>;
default:
return (
<DefaultCellRenderer
columnId={columnId}
data={data}
eventId={eventId}
header={header}
isDetails={isDetails}
isDraggable={false}
isExpandable={isExpandable}
isExpanded={isExpanded}
linkValues={linkValues}
rowIndex={rowIndex}
colIndex={colIndex}
setCellProps={setCellProps}
scopeId={scopeId}
/>
);
}
};

View file

@ -52,7 +52,6 @@ describe('RenderCellValue', () => {
eventId,
header,
isDetails: false,
isDraggable: false,
isExpandable: false,
isExpanded: false,
linkValues,

View file

@ -5,13 +5,13 @@
* 2.0.
*/
import { EuiIcon, EuiToolTip, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
import type { EuiDataGridCellProps } from '@elastic/eui';
import React, { useMemo, memo } from 'react';
import { EuiFlexGroup, EuiFlexItem, EuiIcon, EuiToolTip } from '@elastic/eui';
import React, { memo, useMemo } from 'react';
import { find, getOr } from 'lodash/fp';
import type { TimelineNonEcsData } from '@kbn/timelines-plugin/common';
import { tableDefaults, dataTableSelectors } from '@kbn/securitysolution-data-table';
import type { TableId } from '@kbn/securitysolution-data-table';
import { dataTableSelectors, tableDefaults } from '@kbn/securitysolution-data-table';
import { useLicense } from '../../../common/hooks/use_license';
import { useDeepEqualSelector } from '../../../common/hooks/use_selector';
import { defaultRowRenderers } from '../../../timelines/components/timeline/body/renderers';
@ -51,7 +51,6 @@ export const RenderCellValue: React.FC<NonNullable<EuiDataGridCellProps['cellCon
rowRenderers,
isDetails,
isExpandable,
isDraggable = false,
isExpanded,
colIndex,
eventId,
@ -135,7 +134,6 @@ export const RenderCellValue: React.FC<NonNullable<EuiDataGridCellProps['cellCon
eventId={eventId}
header={myHeader}
isDetails={isDetails}
isDraggable={isDraggable}
isExpandable={isExpandable}
isExpanded={isExpanded}
linkValues={linkValues ?? localLinkValues}
@ -161,7 +159,6 @@ export const RenderCellValue: React.FC<NonNullable<EuiDataGridCellProps['cellCon
finalData,
eventId,
isDetails,
isDraggable,
isExpandable,
isExpanded,
linkValues,

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import { euiLightVars as lightTheme, euiDarkVars as darkTheme } from '@kbn/ui-theme';
import { euiDarkVars as darkTheme, euiLightVars as lightTheme } from '@kbn/ui-theme';
import React from 'react';
import type { DescriptionList } from '../../../../../common/utility_types';
@ -47,7 +47,6 @@ export interface IpOverviewProps {
flowTarget: FlowTargetSourceDest;
id: string;
ip: string;
isDraggable?: boolean;
isInDetailsSidePanel: boolean;
isLoadingAnomaliesData: boolean;
loading: boolean;
@ -64,7 +63,6 @@ export const IpOverview = React.memo<IpOverviewProps>(
id,
ip,
data,
isDraggable = false,
isInDetailsSidePanel = false, // Rather than duplicate the component, alter the structure based on it's location
loading,
flowTarget,
@ -86,14 +84,13 @@ export const IpOverview = React.memo<IpOverviewProps>(
description: locationRenderer(
[`${flowTarget}.geo.city_name`, `${flowTarget}.geo.region_name`],
data,
contextID,
isDraggable
contextID
),
},
{
title: i18n.AUTONOMOUS_SYSTEM,
description: typeData
? autonomousSystemRenderer(typeData.autonomousSystem, flowTarget, contextID, isDraggable)
? autonomousSystemRenderer(typeData.autonomousSystem, flowTarget, contextID)
: getEmptyTagValue(),
},
];
@ -148,15 +145,13 @@ export const IpOverview = React.memo<IpOverviewProps>(
title: i18n.HOST_ID,
description:
typeData && data.host
? hostIdRenderer({ host: data.host, isDraggable, ipFilter: ip, contextID })
? hostIdRenderer({ host: data.host, ipFilter: ip, contextID })
: getEmptyTagValue(),
},
{
title: i18n.HOST_NAME,
description:
typeData && data.host
? hostNameRenderer(data.host, ip, contextID, isDraggable)
: getEmptyTagValue(),
typeData && data.host ? hostNameRenderer(data.host, ip, contextID) : getEmptyTagValue(),
},
],
[

View file

@ -60,14 +60,12 @@ export const DirectionBadge = React.memo<{
contextId: string;
direction?: string | null;
eventId: string;
isDraggable?: boolean;
}>(({ contextId, eventId, direction, isDraggable }) => (
}>(({ contextId, eventId, direction }) => (
<DraggableBadge
contextId={contextId}
eventId={eventId}
field={NETWORK_DIRECTION_FIELD_NAME}
iconType={getDirectionIcon(direction)}
isDraggable={isDraggable}
value={direction}
isAggregatable={true}
fieldType="keyword"

View file

@ -45,15 +45,15 @@ describe('Port', () => {
expect(wrapper.find('[data-test-subj="formatted-ip"]').first().text()).toEqual('10.1.2.3');
});
test('it dispalys a button which opens the network/ip side panel', () => {
test('it displays a button which opens the network/ip side panel', () => {
const wrapper = mount(
<TestProviders>
<Ip contextId="test" eventId="abcd" fieldName="destination.ip" value="10.1.2.3" />
</TestProviders>
);
expect(
wrapper.find('[data-test-subj="draggable-truncatable-content"]').find('a').first().text()
).toEqual('10.1.2.3');
expect(wrapper.find('[data-test-subj="network-details"]').find('a').first().text()).toEqual(
'10.1.2.3'
);
});
});

View file

@ -22,15 +22,13 @@ export const Ip = React.memo<{
contextId: string;
eventId: string;
fieldName: string;
isDraggable?: boolean;
value?: string | null;
}>(({ contextId, eventId, fieldName, isDraggable, value }) => (
}>(({ contextId, eventId, fieldName, value }) => (
<FormattedFieldValue
contextId={contextId}
data-test-subj="formatted-ip"
eventId={eventId}
fieldName={fieldName}
isDraggable={isDraggable}
fieldType={IP_FIELD_TYPE}
value={value}
truncate

View file

@ -1,16 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Port renders correctly against snapshot 1`] = `
<DefaultDraggable
data-test-subj="port"
field="destination.port"
id="port-default-draggable-test-abcd-destination.port-443"
isDraggable={true}
tooltipContent="destination.port"
value="443"
>
<PortOrServiceNameLink
portOrServiceName="443"
/>
</DefaultDraggable>
<PortOrServiceNameLink
portOrServiceName="443"
/>
`;

View file

@ -28,46 +28,28 @@ describe('Port', () => {
const mount = useMountAppended();
test('renders correctly against snapshot', () => {
const wrapper = shallow(
<Port
contextId="test"
eventId="abcd"
fieldName="destination.port"
isDraggable={true}
value="443"
/>
);
const wrapper = shallow(<Port value="443" />);
expect(wrapper).toMatchSnapshot();
});
test('it renders the port', () => {
const wrapper = mount(
<TestProviders>
<Port
contextId="test"
eventId="abcd"
fieldName="destination.port"
isDraggable={true}
value="443"
/>
<Port value="443" />
</TestProviders>
);
expect(
removeExternalLinkText(wrapper.find('[data-test-subj="port"]').first().text())
removeExternalLinkText(
wrapper.find('[data-test-subj="port-or-service-name-link"]').first().text()
)
).toContain('443');
});
test('it hyperlinks links destination.port to an external service that describes the purpose of the port', () => {
const wrapper = mount(
<TestProviders>
<Port
contextId="test"
eventId="abcd"
fieldName="destination.port"
isDraggable={true}
value="443"
/>
<Port value="443" />
</TestProviders>
);
@ -77,20 +59,4 @@ describe('Port', () => {
'https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml?search=443'
);
});
test('it renders only one external link icon', () => {
const wrapper = mount(
<TestProviders>
<Port
contextId="test"
eventId="abcd"
fieldName="destination.port"
isDraggable={true}
value="443"
/>
</TestProviders>
);
expect(wrapper.find('span [data-euiicon-type="popout"]').length).toBe(1);
});
});

View file

@ -7,57 +7,19 @@
import type { EuiButtonEmpty, EuiButtonIcon } from '@elastic/eui';
import React from 'react';
import { DefaultDraggable } from '../../../../common/components/draggables';
import { getEmptyValue } from '../../../../common/components/empty_value';
import { PortOrServiceNameLink } from '../../../../common/components/links';
export const Port = React.memo<{
contextId: string;
Component?: typeof EuiButtonEmpty | typeof EuiButtonIcon;
eventId: string;
fieldName: string;
fieldType?: string;
isAggregatable?: boolean;
isDraggable?: boolean;
title?: string;
value: string | undefined | null;
}>(
({
Component,
contextId,
eventId,
fieldName,
fieldType,
isAggregatable,
isDraggable,
title,
value,
}) =>
isDraggable ? (
<DefaultDraggable
data-test-subj="port"
field={fieldName}
fieldType={fieldType}
isAggregatable={isAggregatable}
id={`port-default-draggable-${contextId}-${eventId}-${fieldName}-${value}`}
isDraggable={isDraggable}
tooltipContent={fieldName}
value={value}
>
<PortOrServiceNameLink
portOrServiceName={value || getEmptyValue()}
Component={Component}
title={title}
/>
</DefaultDraggable>
) : (
<PortOrServiceNameLink
portOrServiceName={value || getEmptyValue()}
Component={Component}
title={title}
/>
)
);
}>(({ Component, title, value }) => (
<PortOrServiceNameLink
portOrServiceName={value || getEmptyValue()}
Component={Component}
title={title}
/>
));
Port.displayName = 'Port';

View file

@ -73,9 +73,8 @@ const GeoFieldValues = React.memo<{
contextId: string;
eventId: string;
fieldName: string;
isDraggable?: boolean;
values?: string[] | null;
}>(({ contextId, eventId, fieldName, isDraggable, values }) =>
}>(({ contextId, eventId, fieldName, values }) =>
values != null ? (
<>
{uniq(values).map((value) => (
@ -93,7 +92,6 @@ const GeoFieldValues = React.memo<{
data-test-subj={fieldName}
field={fieldName}
id={`geo-field-values-default-draggable-${contextId}-${eventId}-${fieldName}-${value}`}
isDraggable={isDraggable}
tooltipContent={fieldName}
value={value}
/>
@ -116,7 +114,7 @@ GeoFieldValues.displayName = 'GeoFieldValues';
* - `source|destination.geo.city_name`
*/
export const GeoFields = React.memo<GeoFieldsProps>((props) => {
const { contextId, eventId, isDraggable, type } = props;
const { contextId, eventId, type } = props;
const propNameToFieldName = getGeoFieldPropNameToFieldNameMap(type);
return (
@ -126,7 +124,6 @@ export const GeoFields = React.memo<GeoFieldsProps>((props) => {
contextId={contextId}
eventId={eventId}
fieldName={geo.fieldName}
isDraggable={isDraggable}
key={geo.fieldName}
values={get(geo.prop, props)}
/>

View file

@ -152,7 +152,7 @@ describe('SourceDestination', () => {
test('it renders destination.geo.continent_name', () => {
render(<TestProviders>{getSourceDestinationInstance()}</TestProviders>);
expect(screen.getByTestId('draggable-content-destination.geo.continent_name').textContent).toBe(
expect(screen.getByTestId('render-content-destination.geo.continent_name').textContent).toBe(
'North America'
);
});
@ -160,7 +160,7 @@ describe('SourceDestination', () => {
test('it renders destination.geo.country_name', () => {
render(<TestProviders>{getSourceDestinationInstance()}</TestProviders>);
expect(screen.getByTestId('draggable-content-destination.geo.country_name').textContent).toBe(
expect(screen.getByTestId('render-content-destination.geo.country_name').textContent).toBe(
'United States'
);
});
@ -168,15 +168,15 @@ describe('SourceDestination', () => {
test('it renders destination.geo.country_iso_code', () => {
render(<TestProviders>{getSourceDestinationInstance()}</TestProviders>);
expect(
screen.getByTestId('draggable-content-destination.geo.country_iso_code').textContent
).toBe('US');
expect(screen.getByTestId('render-content-destination.geo.country_iso_code').textContent).toBe(
'US'
);
});
test('it renders destination.geo.region_name', () => {
render(<TestProviders>{getSourceDestinationInstance()}</TestProviders>);
expect(screen.getByTestId('draggable-content-destination.geo.region_name').textContent).toBe(
expect(screen.getByTestId('render-content-destination.geo.region_name').textContent).toBe(
'New York'
);
});
@ -184,7 +184,7 @@ describe('SourceDestination', () => {
test('it renders destination.geo.city_name', () => {
render(<TestProviders>{getSourceDestinationInstance()}</TestProviders>);
expect(screen.getByTestId('draggable-content-destination.geo.city_name').textContent).toBe(
expect(screen.getByTestId('render-content-destination.geo.city_name').textContent).toBe(
'New York'
);
});
@ -269,7 +269,7 @@ describe('SourceDestination', () => {
test('it renders source.geo.continent_name', () => {
render(<TestProviders>{getSourceDestinationInstance()}</TestProviders>);
expect(screen.getByTestId('draggable-content-source.geo.continent_name').textContent).toBe(
expect(screen.getByTestId('render-content-source.geo.continent_name').textContent).toBe(
'North America'
);
});
@ -277,7 +277,7 @@ describe('SourceDestination', () => {
test('it renders source.geo.country_name', () => {
render(<TestProviders>{getSourceDestinationInstance()}</TestProviders>);
expect(screen.getByTestId('draggable-content-source.geo.country_name').textContent).toBe(
expect(screen.getByTestId('render-content-source.geo.country_name').textContent).toBe(
'United States'
);
});
@ -285,25 +285,19 @@ describe('SourceDestination', () => {
test('it renders source.geo.country_iso_code', () => {
render(<TestProviders>{getSourceDestinationInstance()}</TestProviders>);
expect(screen.getByTestId('draggable-content-source.geo.country_iso_code').textContent).toBe(
'US'
);
expect(screen.getByTestId('render-content-source.geo.country_iso_code').textContent).toBe('US');
});
test('it renders source.geo.region_name', () => {
render(<TestProviders>{getSourceDestinationInstance()}</TestProviders>);
expect(screen.getByTestId('draggable-content-source.geo.region_name').textContent).toBe(
'Georgia'
);
expect(screen.getByTestId('render-content-source.geo.region_name').textContent).toBe('Georgia');
});
test('it renders source.geo.city_name', () => {
render(<TestProviders>{getSourceDestinationInstance()}</TestProviders>);
expect(screen.getByTestId('draggable-content-source.geo.city_name').textContent).toBe(
'Atlanta'
);
expect(screen.getByTestId('render-content-source.geo.city_name').textContent).toBe('Atlanta');
});
test('it renders the source ip and port, separated with a colon', () => {

View file

@ -36,7 +36,6 @@ export const SourceDestination = React.memo<SourceDestinationProps>(
destinationPackets,
destinationPort,
eventId,
isDraggable,
networkBytes,
networkCommunityId,
networkDirection,
@ -62,7 +61,6 @@ export const SourceDestination = React.memo<SourceDestinationProps>(
contextId={contextId}
direction={networkDirection}
eventId={eventId}
isDraggable={isDraggable}
protocol={networkProtocol}
transport={transport}
/>
@ -81,7 +79,6 @@ export const SourceDestination = React.memo<SourceDestinationProps>(
destinationPackets={destinationPackets}
destinationPort={destinationPort}
eventId={eventId}
isDraggable={isDraggable}
sourceBytes={sourceBytes}
sourceGeoContinentName={sourceGeoContinentName}
sourceGeoCountryName={sourceGeoCountryName}

View file

@ -23,26 +23,15 @@ IpPortSeparator.displayName = 'IpPortSeparator';
* a port is specified
*/
const PortWithSeparator = React.memo<{
contextId: string;
eventId: string;
isDraggable?: boolean;
port?: string | null;
portFieldName: string;
}>(({ contextId, eventId, isDraggable, port, portFieldName }) => {
}>(({ port }) => {
return port != null ? (
<EuiFlexGroup gutterSize="none">
<EuiFlexItem grow={false}>
<IpPortSeparator data-test-subj="ip-port-separator">{':'}</IpPortSeparator>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<Port
contextId={contextId}
data-test-subj="port"
eventId={eventId}
fieldName={portFieldName}
isDraggable={isDraggable}
value={port}
/>
<Port data-test-subj="port" value={port} />
</EuiFlexItem>
</EuiFlexGroup>
) : null;
@ -59,10 +48,8 @@ export const IpWithPort = React.memo<{
eventId: string;
ip?: string | null;
ipFieldName: string;
isDraggable?: boolean;
port?: string | null;
portFieldName: string;
}>(({ contextId, eventId, ip, ipFieldName, isDraggable, port, portFieldName }) => (
}>(({ contextId, eventId, ip, ipFieldName, port }) => (
<EuiFlexGroup gutterSize="none">
<EuiFlexItem grow={false}>
<Ip
@ -70,18 +57,11 @@ export const IpWithPort = React.memo<{
data-test-subj="ip"
eventId={eventId}
fieldName={ipFieldName}
isDraggable={isDraggable}
value={ip}
/>
</EuiFlexItem>
<EuiFlexItem>
<PortWithSeparator
contextId={contextId}
eventId={eventId}
isDraggable={isDraggable}
port={port}
portFieldName={portFieldName}
/>
<PortWithSeparator port={port} />
</EuiFlexItem>
</EuiFlexGroup>
));

View file

@ -45,124 +45,101 @@ export const Network = React.memo<{
contextId: string;
direction?: string[] | null;
eventId: string;
isDraggable?: boolean;
packets?: string[] | null;
protocol?: string[] | null;
transport?: string[] | null;
}>(
({
bytes,
communityId,
contextId,
direction,
eventId,
isDraggable,
packets,
protocol,
transport,
}) => (
<EuiFlexGroup alignItems="center" justifyContent="center" gutterSize="none">
{direction != null
? uniq(direction).map((dir) => (
<EuiFlexItemMarginRight grow={false} key={dir}>
<DirectionBadge
contextId={contextId}
direction={dir}
eventId={eventId}
isDraggable={isDraggable}
/>
</EuiFlexItemMarginRight>
))
: null}
}>(({ bytes, communityId, contextId, direction, eventId, packets, protocol, transport }) => (
<EuiFlexGroup alignItems="center" justifyContent="center" gutterSize="none">
{direction != null
? uniq(direction).map((dir) => (
<EuiFlexItemMarginRight grow={false} key={dir}>
<DirectionBadge contextId={contextId} direction={dir} eventId={eventId} />
</EuiFlexItemMarginRight>
))
: null}
{protocol != null
? uniq(protocol).map((proto) => (
<EuiFlexItemMarginRight grow={false} key={proto}>
<DraggableBadge
contextId={contextId}
eventId={eventId}
field={NETWORK_PROTOCOL_FIELD_NAME}
isDraggable={isDraggable}
value={proto}
isAggregatable={true}
fieldType="keyword"
/>
</EuiFlexItemMarginRight>
))
: null}
{protocol != null
? uniq(protocol).map((proto) => (
<EuiFlexItemMarginRight grow={false} key={proto}>
<DraggableBadge
contextId={contextId}
eventId={eventId}
field={NETWORK_PROTOCOL_FIELD_NAME}
value={proto}
isAggregatable={true}
fieldType="keyword"
/>
</EuiFlexItemMarginRight>
))
: null}
{bytes != null
? uniq(bytes).map((b) =>
!isNaN(Number(b)) ? (
<EuiFlexItemMarginRight grow={false} key={b}>
<DefaultDraggable
field={NETWORK_BYTES_FIELD_NAME}
id={`network-default-draggable-${contextId}-${eventId}-${NETWORK_BYTES_FIELD_NAME}-${b}`}
isDraggable={isDraggable}
value={b}
>
<Stats size="xs">
<span>
<PreferenceFormattedBytes value={b} />
</span>
</Stats>
</DefaultDraggable>
</EuiFlexItemMarginRight>
) : null
)
: null}
{packets != null
? uniq(packets).map((p) => (
<EuiFlexItemMarginRight grow={false} key={p}>
{bytes != null
? uniq(bytes).map((b) =>
!isNaN(Number(b)) ? (
<EuiFlexItemMarginRight grow={false} key={b}>
<DefaultDraggable
field={NETWORK_PACKETS_FIELD_NAME}
id={`network-default-draggable-${contextId}-${eventId}-${NETWORK_PACKETS_FIELD_NAME}-${p}`}
isDraggable={isDraggable}
value={p}
field={NETWORK_BYTES_FIELD_NAME}
id={`network-default-draggable-${contextId}-${eventId}-${NETWORK_BYTES_FIELD_NAME}-${b}`}
value={b}
>
<Stats size="xs">
<span>{`${p} ${i18n.PACKETS}`}</span>
<span>
<PreferenceFormattedBytes value={b} />
</span>
</Stats>
</DefaultDraggable>
</EuiFlexItemMarginRight>
))
: null}
) : null
)
: null}
{transport != null
? uniq(transport).map((trans) => (
<EuiFlexItemMarginRight grow={false} key={trans}>
<DraggableBadge
contextId={contextId}
data-test-subj="network-transport"
eventId={eventId}
field={NETWORK_TRANSPORT_FIELD_NAME}
isDraggable={isDraggable}
value={trans}
isAggregatable={true}
fieldType="keyword"
/>
</EuiFlexItemMarginRight>
))
: null}
{packets != null
? uniq(packets).map((p) => (
<EuiFlexItemMarginRight grow={false} key={p}>
<DefaultDraggable
field={NETWORK_PACKETS_FIELD_NAME}
id={`network-default-draggable-${contextId}-${eventId}-${NETWORK_PACKETS_FIELD_NAME}-${p}`}
value={p}
>
<Stats size="xs">
<span>{`${p} ${i18n.PACKETS}`}</span>
</Stats>
</DefaultDraggable>
</EuiFlexItemMarginRight>
))
: null}
{communityId != null
? uniq(communityId).map((trans) => (
<EuiFlexItem grow={false} key={trans}>
<DraggableBadge
contextId={contextId}
eventId={eventId}
field={NETWORK_COMMUNITY_ID_FIELD_NAME}
isDraggable={isDraggable}
value={trans}
isAggregatable={true}
fieldType="keyword"
/>
</EuiFlexItem>
))
: null}
</EuiFlexGroup>
)
);
{transport != null
? uniq(transport).map((trans) => (
<EuiFlexItemMarginRight grow={false} key={trans}>
<DraggableBadge
contextId={contextId}
data-test-subj="network-transport"
eventId={eventId}
field={NETWORK_TRANSPORT_FIELD_NAME}
value={trans}
isAggregatable={true}
fieldType="keyword"
/>
</EuiFlexItemMarginRight>
))
: null}
{communityId != null
? uniq(communityId).map((trans) => (
<EuiFlexItem grow={false} key={trans}>
<DraggableBadge
contextId={contextId}
eventId={eventId}
field={NETWORK_COMMUNITY_ID_FIELD_NAME}
value={trans}
isAggregatable={true}
fieldType="keyword"
/>
</EuiFlexItem>
))
: null}
</EuiFlexGroup>
));
Network.displayName = 'Network';

View file

@ -56,11 +56,10 @@ Data.displayName = 'Data';
const SourceArrow = React.memo<{
contextId: string;
eventId: string;
isDraggable?: boolean;
sourceBytes: string | undefined;
sourceBytesPercent: number | undefined;
sourcePackets: string | undefined;
}>(({ contextId, eventId, isDraggable, sourceBytes, sourceBytesPercent, sourcePackets }) => {
}>(({ contextId, eventId, sourceBytes, sourceBytesPercent, sourcePackets }) => {
const sourceArrowHeight =
sourceBytesPercent != null
? getArrowHeightFromPercent(sourceBytesPercent)
@ -77,7 +76,6 @@ const SourceArrow = React.memo<{
<DefaultDraggable
field={SOURCE_BYTES_FIELD_NAME}
id={`source-arrow-default-draggable-${contextId}-${eventId}-${SOURCE_BYTES_FIELD_NAME}-${sourceBytes}`}
isDraggable={isDraggable}
value={sourceBytes}
>
<Data size="xs">
@ -101,7 +99,6 @@ const SourceArrow = React.memo<{
<DefaultDraggable
field={SOURCE_PACKETS_FIELD_NAME}
id={`source-arrow-default-draggable-${contextId}-${eventId}-${SOURCE_PACKETS_FIELD_NAME}-${sourcePackets}`}
isDraggable={isDraggable}
value={sourcePackets}
>
<Data size="xs">
@ -134,77 +131,65 @@ const DestinationArrow = React.memo<{
destinationBytesPercent: number | undefined;
destinationPackets: string | undefined;
eventId: string;
isDraggable?: boolean;
}>(
({
contextId,
destinationBytes,
destinationBytesPercent,
destinationPackets,
eventId,
isDraggable,
}) => {
const destinationArrowHeight =
destinationBytesPercent != null
? getArrowHeightFromPercent(destinationBytesPercent)
: DEFAULT_ARROW_HEIGHT;
}>(({ contextId, destinationBytes, destinationBytesPercent, destinationPackets, eventId }) => {
const destinationArrowHeight =
destinationBytesPercent != null
? getArrowHeightFromPercent(destinationBytesPercent)
: DEFAULT_ARROW_HEIGHT;
return (
<EuiFlexGroup alignItems="center" gutterSize="none" justifyContent="center">
return (
<EuiFlexGroup alignItems="center" gutterSize="none" justifyContent="center">
<EuiFlexItem grow={false}>
<ArrowHead direction="arrowLeft" />
</EuiFlexItem>
<EuiFlexItem grow={false}>
<ArrowBody height={destinationArrowHeight ?? 0} />
</EuiFlexItem>
{destinationBytes != null && !isNaN(Number(destinationBytes)) ? (
<EuiFlexItem grow={false}>
<ArrowHead direction="arrowLeft" />
<DefaultDraggable
field={DESTINATION_BYTES_FIELD_NAME}
id={`destination-arrow-default-draggable-${contextId}-${eventId}-${DESTINATION_BYTES_FIELD_NAME}-${destinationBytes}`}
value={destinationBytes}
>
<Data size="xs">
{destinationBytesPercent != null ? (
<Percent>{`(${numeral(destinationBytesPercent).format('0.00')}%)`}</Percent>
) : null}
<span>
<PreferenceFormattedBytes value={destinationBytes} />
</span>
</Data>
</DefaultDraggable>
</EuiFlexItem>
) : null}
<EuiFlexItem grow={false}>
<ArrowBody height={destinationArrowHeight ?? 0} />
</EuiFlexItem>
{destinationPackets != null && !isNaN(Number(destinationPackets)) ? (
<EuiFlexItem grow={false}>
<ArrowBody height={destinationArrowHeight ?? 0} />
<DefaultDraggable
field={DESTINATION_PACKETS_FIELD_NAME}
id={`destination-arrow-default-draggable-${contextId}-${eventId}-${DESTINATION_PACKETS_FIELD_NAME}-${destinationPackets}`}
value={destinationPackets}
>
<Data size="xs">
<span>{`${numeral(destinationPackets).format('0,0')} ${i18n.PACKETS}`}</span>
</Data>
</DefaultDraggable>
</EuiFlexItem>
) : null}
{destinationBytes != null && !isNaN(Number(destinationBytes)) ? (
<EuiFlexItem grow={false}>
<DefaultDraggable
field={DESTINATION_BYTES_FIELD_NAME}
id={`destination-arrow-default-draggable-${contextId}-${eventId}-${DESTINATION_BYTES_FIELD_NAME}-${destinationBytes}`}
isDraggable={isDraggable}
value={destinationBytes}
>
<Data size="xs">
{destinationBytesPercent != null ? (
<Percent>{`(${numeral(destinationBytesPercent).format('0.00')}%)`}</Percent>
) : null}
<span>
<PreferenceFormattedBytes value={destinationBytes} />
</span>
</Data>
</DefaultDraggable>
</EuiFlexItem>
) : null}
<EuiFlexItem grow={false}>
<ArrowBody height={destinationArrowHeight ?? 0} />
</EuiFlexItem>
{destinationPackets != null && !isNaN(Number(destinationPackets)) ? (
<EuiFlexItem grow={false}>
<DefaultDraggable
field={DESTINATION_PACKETS_FIELD_NAME}
id={`destination-arrow-default-draggable-${contextId}-${eventId}-${DESTINATION_PACKETS_FIELD_NAME}-${destinationPackets}`}
isDraggable={isDraggable}
value={destinationPackets}
>
<Data size="xs">
<span>{`${numeral(destinationPackets).format('0,0')} ${i18n.PACKETS}`}</span>
</Data>
</DefaultDraggable>
</EuiFlexItem>
) : null}
<EuiFlexItem grow={false}>
<ArrowBody height={destinationArrowHeight ?? 0} />
</EuiFlexItem>
</EuiFlexGroup>
);
}
);
<EuiFlexItem grow={false}>
<ArrowBody height={destinationArrowHeight ?? 0} />
</EuiFlexItem>
</EuiFlexGroup>
);
});
DestinationArrow.displayName = 'DestinationArrow';
@ -217,78 +202,65 @@ export const SourceDestinationArrows = React.memo<{
destinationBytes?: string[] | null;
destinationPackets?: string[] | null;
eventId: string;
isDraggable?: boolean;
sourceBytes?: string[] | null;
sourcePackets?: string[] | null;
}>(
({
contextId,
destinationBytes,
destinationPackets,
eventId,
isDraggable,
sourceBytes,
sourcePackets,
}) => {
const maybeSourceBytes =
sourceBytes != null && hasOneValue(sourceBytes) ? sourceBytes[0] : undefined;
}>(({ contextId, destinationBytes, destinationPackets, eventId, sourceBytes, sourcePackets }) => {
const maybeSourceBytes =
sourceBytes != null && hasOneValue(sourceBytes) ? sourceBytes[0] : undefined;
const maybeSourcePackets =
sourcePackets != null && hasOneValue(sourcePackets) ? sourcePackets[0] : undefined;
const maybeSourcePackets =
sourcePackets != null && hasOneValue(sourcePackets) ? sourcePackets[0] : undefined;
const maybeDestinationBytes =
destinationBytes != null && hasOneValue(destinationBytes) ? destinationBytes[0] : undefined;
const maybeDestinationBytes =
destinationBytes != null && hasOneValue(destinationBytes) ? destinationBytes[0] : undefined;
const maybeDestinationPackets =
destinationPackets != null && hasOneValue(destinationPackets)
? destinationPackets[0]
: undefined;
const maybeDestinationPackets =
destinationPackets != null && hasOneValue(destinationPackets)
? destinationPackets[0]
: undefined;
const maybeSourceBytesPercent =
maybeSourceBytes != null && maybeDestinationBytes != null
? getPercent({
numerator: Number(maybeSourceBytes),
denominator: Number(maybeSourceBytes) + Number(maybeDestinationBytes),
})
: undefined;
const maybeSourceBytesPercent =
maybeSourceBytes != null && maybeDestinationBytes != null
? getPercent({
numerator: Number(maybeSourceBytes),
denominator: Number(maybeSourceBytes) + Number(maybeDestinationBytes),
})
: undefined;
const maybeDestinationBytesPercent =
maybeSourceBytesPercent != null ? 100 - maybeSourceBytesPercent : undefined;
const maybeDestinationBytesPercent =
maybeSourceBytesPercent != null ? 100 - maybeSourceBytesPercent : undefined;
return (
<SourceDestinationArrowsContainer
alignItems="center"
justifyContent="center"
direction="column"
gutterSize="none"
>
{maybeSourceBytes != null ? (
<EuiFlexItem grow={false}>
<SourceArrow
contextId={contextId}
eventId={eventId}
isDraggable={isDraggable}
sourceBytes={maybeSourceBytes}
sourcePackets={maybeSourcePackets}
sourceBytesPercent={maybeSourceBytesPercent}
/>
</EuiFlexItem>
) : null}
{maybeDestinationBytes != null ? (
<EuiFlexItem grow={false}>
<DestinationArrow
contextId={contextId}
destinationBytes={maybeDestinationBytes}
destinationPackets={maybeDestinationPackets}
destinationBytesPercent={maybeDestinationBytesPercent}
eventId={eventId}
isDraggable={isDraggable}
/>
</EuiFlexItem>
) : null}
</SourceDestinationArrowsContainer>
);
}
);
return (
<SourceDestinationArrowsContainer
alignItems="center"
justifyContent="center"
direction="column"
gutterSize="none"
>
{maybeSourceBytes != null ? (
<EuiFlexItem grow={false}>
<SourceArrow
contextId={contextId}
eventId={eventId}
sourceBytes={maybeSourceBytes}
sourcePackets={maybeSourcePackets}
sourceBytesPercent={maybeSourceBytesPercent}
/>
</EuiFlexItem>
) : null}
{maybeDestinationBytes != null ? (
<EuiFlexItem grow={false}>
<DestinationArrow
contextId={contextId}
destinationBytes={maybeDestinationBytes}
destinationPackets={maybeDestinationPackets}
destinationBytesPercent={maybeDestinationBytesPercent}
eventId={eventId}
/>
</EuiFlexItem>
) : null}
</SourceDestinationArrowsContainer>
);
});
SourceDestinationArrows.displayName = 'SourceDestinationArrows';

View file

@ -940,7 +940,6 @@ describe('SourceDestinationIp', () => {
destinationIp={asArrayIfExists(get(DESTINATION_IP_FIELD_NAME, getMockNetflowData()))}
destinationPort={asArrayIfExists(get(DESTINATION_PORT_FIELD_NAME, getMockNetflowData()))}
eventId={get(ID_FIELD_NAME, getMockNetflowData())}
isDraggable={true}
sourceGeoContinentName={asArrayIfExists(
get(SOURCE_GEO_CONTINENT_NAME_FIELD_NAME, getMockNetflowData())
)}
@ -990,7 +989,6 @@ describe('SourceDestinationIp', () => {
destinationIp={asArrayIfExists(get(DESTINATION_IP_FIELD_NAME, getMockNetflowData()))}
destinationPort={asArrayIfExists(get(DESTINATION_PORT_FIELD_NAME, getMockNetflowData()))}
eventId={get(ID_FIELD_NAME, getMockNetflowData())}
isDraggable={true}
sourceGeoContinentName={asArrayIfExists(
get(SOURCE_GEO_CONTINENT_NAME_FIELD_NAME, getMockNetflowData())
)}
@ -1040,7 +1038,6 @@ describe('SourceDestinationIp', () => {
destinationIp={asArrayIfExists(get(DESTINATION_IP_FIELD_NAME, getMockNetflowData()))}
destinationPort={asArrayIfExists(get(DESTINATION_PORT_FIELD_NAME, getMockNetflowData()))}
eventId={get(ID_FIELD_NAME, getMockNetflowData())}
isDraggable={true}
sourceGeoContinentName={asArrayIfExists(
get(SOURCE_GEO_CONTINENT_NAME_FIELD_NAME, getMockNetflowData())
)}
@ -1091,7 +1088,6 @@ describe('SourceDestinationIp', () => {
destinationIp={undefined}
destinationPort={asArrayIfExists(get(DESTINATION_PORT_FIELD_NAME, getMockNetflowData()))}
eventId={get(ID_FIELD_NAME, getMockNetflowData())}
isDraggable={true}
sourceGeoContinentName={asArrayIfExists(
get(SOURCE_GEO_CONTINENT_NAME_FIELD_NAME, getMockNetflowData())
)}
@ -1241,7 +1237,6 @@ describe('SourceDestinationIp', () => {
destinationIp={asArrayIfExists(get(DESTINATION_IP_FIELD_NAME, getMockNetflowData()))}
destinationPort={asArrayIfExists(get(DESTINATION_PORT_FIELD_NAME, getMockNetflowData()))}
eventId={get(ID_FIELD_NAME, getMockNetflowData())}
isDraggable={true}
sourceGeoContinentName={asArrayIfExists(
get(SOURCE_GEO_CONTINENT_NAME_FIELD_NAME, getMockNetflowData())
)}
@ -1264,7 +1259,7 @@ describe('SourceDestinationIp', () => {
</TestProviders>
);
expect(screen.getByTestId('draggable-content-source.geo.continent_name').textContent).toBe(
expect(screen.getByTestId('render-content-source.geo.continent_name').textContent).toBe(
'North America'
);
});

View file

@ -12,7 +12,6 @@ import deepEqual from 'fast-deep-equal';
import { DESTINATION_IP_FIELD_NAME, SOURCE_IP_FIELD_NAME } from '../ip';
import { Port } from '../port';
import { DESTINATION_PORT_FIELD_NAME, SOURCE_PORT_FIELD_NAME } from '../port/helpers';
import * as i18n from '../../../../timelines/components/timeline/body/renderers/translations';
import { GeoFields } from './geo_fields';
@ -89,67 +88,52 @@ const IpAdressesWithPorts = React.memo<{
destinationIp?: string[] | null;
destinationPort?: Array<number | string | null> | null;
eventId: string;
isDraggable?: boolean;
sourceIp?: string[] | null;
sourcePort?: Array<number | string | null> | null;
type: SourceDestinationType;
}>(
({
contextId,
destinationIp,
destinationPort,
eventId,
isDraggable,
sourceIp,
sourcePort,
type,
}) => {
const ip = type === 'source' ? sourceIp : destinationIp;
const ipFieldName = type === 'source' ? SOURCE_IP_FIELD_NAME : DESTINATION_IP_FIELD_NAME;
const port = type === 'source' ? sourcePort : destinationPort;
const portFieldName = type === 'source' ? SOURCE_PORT_FIELD_NAME : DESTINATION_PORT_FIELD_NAME;
}>(({ contextId, destinationIp, destinationPort, eventId, sourceIp, sourcePort, type }) => {
const ip = type === 'source' ? sourceIp : destinationIp;
const ipFieldName = type === 'source' ? SOURCE_IP_FIELD_NAME : DESTINATION_IP_FIELD_NAME;
const port = type === 'source' ? sourcePort : destinationPort;
if (ip == null) {
return null; // if ip is not populated as an array, ports will be ignored
}
// IMPORTANT: The ip and port arrays are parallel arrays; the port at
// index `i` corresponds with the ip address at index `i`. We must
// preserve the relationships between the parallel arrays:
const ipPortPairs: IpPortPair[] =
port != null && ip.length === port.length
? ip.map((address, i) => ({
ip: address,
port: port[i] != null ? `${port[i]}` : null, // use the corresponding port in the parallel array
}))
: ip.map((address) => ({
ip: address,
port: null, // drop the port, because the length of the parallel ip and port arrays is different
}));
return (
<EuiFlexGroup gutterSize="none">
{uniqWith(deepEqual, ipPortPairs).map(
(ipPortPair) =>
ipPortPair.ip != null && (
<EuiFlexItem grow={false} key={ipPortPair.ip}>
<IpWithPort
contextId={contextId}
data-test-subj={`${type}-ip-and-port`}
eventId={eventId}
ip={ipPortPair.ip}
ipFieldName={ipFieldName}
isDraggable={isDraggable}
port={ipPortPair.port}
portFieldName={portFieldName}
/>
</EuiFlexItem>
)
)}
</EuiFlexGroup>
);
if (ip == null) {
return null; // if ip is not populated as an array, ports will be ignored
}
);
// IMPORTANT: The ip and port arrays are parallel arrays; the port at
// index `i` corresponds with the ip address at index `i`. We must
// preserve the relationships between the parallel arrays:
const ipPortPairs: IpPortPair[] =
port != null && ip.length === port.length
? ip.map((address, i) => ({
ip: address,
port: port[i] != null ? `${port[i]}` : null, // use the corresponding port in the parallel array
}))
: ip.map((address) => ({
ip: address,
port: null, // drop the port, because the length of the parallel ip and port arrays is different
}));
return (
<EuiFlexGroup gutterSize="none">
{uniqWith(deepEqual, ipPortPairs).map(
(ipPortPair) =>
ipPortPair.ip != null && (
<EuiFlexItem grow={false} key={ipPortPair.ip}>
<IpWithPort
contextId={contextId}
data-test-subj={`${type}-ip-and-port`}
eventId={eventId}
ip={ipPortPair.ip}
ipFieldName={ipFieldName}
port={ipPortPair.port}
/>
</EuiFlexItem>
)
)}
</EuiFlexGroup>
);
});
IpAdressesWithPorts.displayName = 'IpAdressesWithPorts';
@ -173,7 +157,6 @@ export const SourceDestinationIp = React.memo<SourceDestinationIpProps>(
destinationIp,
destinationPort,
eventId,
isDraggable,
sourceGeoContinentName,
sourceGeoCountryName,
sourceGeoCountryIsoCode,
@ -204,7 +187,6 @@ export const SourceDestinationIp = React.memo<SourceDestinationIpProps>(
destinationIp={destinationIp}
destinationPort={destinationPort}
eventId={eventId}
isDraggable={isDraggable}
sourceIp={sourceIp}
sourcePort={sourcePort}
type={type}
@ -213,14 +195,7 @@ export const SourceDestinationIp = React.memo<SourceDestinationIpProps>(
<EuiFlexGroup gutterSize="none">
{getPorts({ destinationPort, sourcePort, type }).map((port, i) => (
<EuiFlexItem key={`port-${port}-${i}`} grow={false}>
<Port
contextId={contextId}
data-test-subj="port"
eventId={eventId}
fieldName={`${type}.port`}
isDraggable={isDraggable}
value={port}
/>
<Port data-test-subj="port" value={port} />
</EuiFlexItem>
))}
</EuiFlexGroup>
@ -235,7 +210,6 @@ export const SourceDestinationIp = React.memo<SourceDestinationIpProps>(
destinationGeoRegionName={destinationGeoRegionName}
destinationGeoCityName={destinationGeoCityName}
eventId={eventId}
isDraggable={isDraggable}
sourceGeoContinentName={sourceGeoContinentName}
sourceGeoCountryName={sourceGeoCountryName}
sourceGeoCountryIsoCode={sourceGeoCountryIsoCode}

View file

@ -32,7 +32,6 @@ export const SourceDestinationWithArrows = React.memo<SourceDestinationWithArrow
destinationPackets,
destinationPort,
eventId,
isDraggable,
sourceBytes,
sourceGeoContinentName,
sourceGeoCountryName,
@ -55,7 +54,6 @@ export const SourceDestinationWithArrows = React.memo<SourceDestinationWithArrow
destinationIp={destinationIp}
destinationPort={destinationPort}
eventId={eventId}
isDraggable={isDraggable}
sourceGeoContinentName={sourceGeoContinentName}
sourceGeoCountryName={sourceGeoCountryName}
sourceGeoCountryIsoCode={sourceGeoCountryIsoCode}
@ -72,7 +70,6 @@ export const SourceDestinationWithArrows = React.memo<SourceDestinationWithArrow
destinationBytes={destinationBytes}
destinationPackets={destinationPackets}
eventId={eventId}
isDraggable={isDraggable}
sourceBytes={sourceBytes}
sourcePackets={sourcePackets}
/>
@ -88,7 +85,6 @@ export const SourceDestinationWithArrows = React.memo<SourceDestinationWithArrow
destinationIp={destinationIp}
destinationPort={destinationPort}
eventId={eventId}
isDraggable={isDraggable}
sourceGeoContinentName={sourceGeoContinentName}
sourceGeoCountryName={sourceGeoCountryName}
sourceGeoCountryIsoCode={sourceGeoCountryIsoCode}

View file

@ -15,7 +15,6 @@ export interface GeoFieldsProps {
destinationGeoRegionName?: string[] | null;
destinationGeoCityName?: string[] | null;
eventId: string;
isDraggable?: boolean;
sourceGeoContinentName?: string[] | null;
sourceGeoCountryName?: string[] | null;
sourceGeoCountryIsoCode?: string[] | null;
@ -38,7 +37,6 @@ export interface SourceDestinationProps {
destinationPort?: string[] | null;
direction?: string[] | null;
eventId: string;
isDraggable?: boolean;
networkBytes?: string[] | null;
networkCommunityId?: string[] | null;
networkDirection?: string[] | null;
@ -65,7 +63,6 @@ export interface SourceDestinationIpProps {
destinationIp?: string[] | null;
destinationPort?: Array<number | string | null> | null;
eventId: string;
isDraggable?: boolean;
sourceGeoContinentName?: string[] | null;
sourceGeoCountryName?: string[] | null;
sourceGeoCountryIsoCode?: string[] | null;
@ -88,7 +85,6 @@ export interface SourceDestinationWithArrowsProps {
destinationPackets?: string[] | null;
destinationPort?: string[] | null;
eventId: string;
isDraggable?: boolean;
sourceBytes?: string[] | null;
sourceGeoContinentName?: string[] | null;
sourceGeoCountryName?: string[] | null;

View file

@ -40,7 +40,6 @@ export const AlertReason: React.FC = () => {
? renderer.renderRow({
contextId: 'event-details',
data: dataAsNestedObject,
isDraggable: false,
scopeId,
})
: null,

View file

@ -8,20 +8,20 @@
import React, { useCallback, useMemo } from 'react';
import { useDispatch } from 'react-redux';
import { v4 as uuid } from 'uuid';
import type { EuiBasicTableColumn } from '@elastic/eui';
import {
EuiTitle,
EuiSpacer,
EuiInMemoryTable,
EuiText,
EuiFlexGrid,
EuiFlexGroup,
EuiFlexItem,
EuiToolTip,
EuiIcon,
EuiPanel,
EuiHorizontalRule,
EuiFlexGrid,
EuiIcon,
EuiInMemoryTable,
EuiPanel,
EuiSpacer,
EuiText,
EuiTitle,
EuiToolTip,
} from '@elastic/eui';
import type { EuiBasicTableColumn } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n-react';
import { i18n } from '@kbn/i18n';
import { useExpandableFlyoutApi } from '@kbn/expandable-flyout';
@ -51,17 +51,17 @@ import { useHostRelatedUsers } from '../../../../common/containers/related_entit
import { useMlCapabilities } from '../../../../common/components/ml/hooks/use_ml_capabilities';
import { getEmptyTagValue } from '../../../../common/components/empty_value';
import {
HOST_DETAILS_TEST_ID,
HOST_DETAILS_RELATED_USERS_TABLE_TEST_ID,
HOST_DETAILS_RELATED_USERS_LINK_TEST_ID,
HOST_DETAILS_RELATED_USERS_IP_LINK_TEST_ID,
HOST_DETAILS_ALERT_COUNT_TEST_ID,
HOST_DETAILS_MISCONFIGURATIONS_TEST_ID,
HOST_DETAILS_RELATED_USERS_IP_LINK_TEST_ID,
HOST_DETAILS_RELATED_USERS_LINK_TEST_ID,
HOST_DETAILS_RELATED_USERS_TABLE_TEST_ID,
HOST_DETAILS_TEST_ID,
HOST_DETAILS_VULNERABILITIES_TEST_ID,
} from './test_ids';
import {
USER_NAME_FIELD_NAME,
HOST_IP_FIELD_NAME,
USER_NAME_FIELD_NAME,
} from '../../../../timelines/components/timeline/body/renderers/constants';
import { useKibana } from '../../../../common/lib/kibana';
import { ENTITY_RISK_LEVEL } from '../../../../entity_analytics/components/risk_score/translations';
@ -201,7 +201,6 @@ export const HostDetails: React.FC<HostDetailsProps> = ({ hostName, timestamp, s
rowItems={ips}
attrName={HOST_IP_FIELD_NAME}
idPrefix={''}
isDraggable={false}
render={(ip) =>
ip == null ? (
getEmptyTagValue()

View file

@ -8,20 +8,20 @@
import React, { useCallback, useMemo } from 'react';
import { useDispatch } from 'react-redux';
import { v4 as uuid } from 'uuid';
import type { EuiBasicTableColumn } from '@elastic/eui';
import {
EuiTitle,
EuiSpacer,
EuiInMemoryTable,
EuiText,
EuiIcon,
EuiFlexGrid,
EuiFlexGroup,
EuiFlexItem,
EuiToolTip,
EuiPanel,
EuiHorizontalRule,
EuiFlexGrid,
EuiIcon,
EuiInMemoryTable,
EuiPanel,
EuiSpacer,
EuiText,
EuiTitle,
EuiToolTip,
} from '@elastic/eui';
import type { EuiBasicTableColumn } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n-react';
import { i18n } from '@kbn/i18n';
import { useExpandableFlyoutApi } from '@kbn/expandable-flyout';
@ -48,16 +48,16 @@ import { useUserRelatedHosts } from '../../../../common/containers/related_entit
import { useMlCapabilities } from '../../../../common/components/ml/hooks/use_ml_capabilities';
import { getEmptyTagValue } from '../../../../common/components/empty_value';
import {
USER_DETAILS_ALERT_COUNT_TEST_ID,
USER_DETAILS_MISCONFIGURATIONS_TEST_ID,
USER_DETAILS_RELATED_HOSTS_IP_LINK_TEST_ID,
USER_DETAILS_RELATED_HOSTS_LINK_TEST_ID,
USER_DETAILS_RELATED_HOSTS_TABLE_TEST_ID,
USER_DETAILS_TEST_ID,
USER_DETAILS_RELATED_HOSTS_LINK_TEST_ID,
USER_DETAILS_RELATED_HOSTS_IP_LINK_TEST_ID,
USER_DETAILS_MISCONFIGURATIONS_TEST_ID,
USER_DETAILS_ALERT_COUNT_TEST_ID,
} from './test_ids';
import {
HOST_NAME_FIELD_NAME,
HOST_IP_FIELD_NAME,
HOST_NAME_FIELD_NAME,
} from '../../../../timelines/components/timeline/body/renderers/constants';
import { useKibana } from '../../../../common/lib/kibana';
import { ENTITY_RISK_LEVEL } from '../../../../entity_analytics/components/risk_score/translations';
@ -197,7 +197,6 @@ export const UserDetails: React.FC<UserDetailsProps> = ({ userName, timestamp, s
rowItems={ips}
attrName={HOST_IP_FIELD_NAME}
idPrefix={''}
isDraggable={false}
render={(ip) =>
ip == null ? (
getEmptyTagValue()

View file

@ -38,7 +38,6 @@ export const EventRenderer: FC = () => {
? renderer.renderRow({
contextId: 'event-details',
data: dataAsNestedObject,
isDraggable: false,
scopeId,
})
: null,

View file

@ -88,7 +88,6 @@ export const StatusPopoverButton = memo(
linkValue={enrichedFieldInfo.linkValue}
fieldType={enrichedFieldInfo.data.type}
fieldFormat={getFieldFormat(enrichedFieldInfo.data)}
isDraggable={false}
truncate={false}
isButton={statusPopoverVisible}
onClick={statusPopoverVisible ? togglePopover : undefined}

View file

@ -108,7 +108,6 @@ export const TableFieldValueCell = memo(
fieldFromBrowserField={fieldFromBrowserField}
fieldType={data.type}
isAggregatable={fieldFromBrowserField.aggregatable}
isDraggable={false}
isObjectArray={data.isObjectArray}
value={value}
linkValue={getLinkValue && getLinkValue(data.field)}

View file

@ -18,7 +18,6 @@ const mockProps: HostPreviewPanelFooterProps = {
hostName: 'test',
contextID: 'test-host-panel',
scopeId: 'test-scope-id',
isDraggable: false,
};
describe('<HostPreviewPanelFooter />', () => {

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import { EuiLink, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
import { EuiFlexGroup, EuiFlexItem, EuiLink } from '@elastic/eui';
import React, { useCallback } from 'react';
import { i18n } from '@kbn/i18n';
import { useExpandableFlyoutApi } from '@kbn/expandable-flyout';
@ -16,14 +16,12 @@ export interface HostPreviewPanelFooterProps {
contextID: string;
scopeId: string;
hostName: string;
isDraggable?: boolean;
}
export const HostPreviewPanelFooter = ({
contextID,
scopeId,
hostName,
isDraggable,
}: HostPreviewPanelFooterProps) => {
const { openFlyout } = useExpandableFlyoutApi();
@ -35,11 +33,10 @@ export const HostPreviewPanelFooter = ({
contextID,
hostName,
scopeId,
isDraggable,
},
},
});
}, [openFlyout, hostName, contextID, isDraggable, scopeId]);
}, [openFlyout, hostName, contextID, scopeId]);
return (
<FlyoutFooter data-test-subj={'host-preview-footer'}>

View file

@ -32,7 +32,6 @@ storiesOf('Components/HostPanelContent', module)
riskScoreState={riskScoreData}
contextID={'test-host-details'}
scopeId={'test-scopeId'}
isDraggable={false}
openDetailsPanel={() => {}}
hostName={'test-host-name'}
onAssetCriticalityChange={() => {}}
@ -58,7 +57,6 @@ storiesOf('Components/HostPanelContent', module)
riskScoreState={riskScoreData}
contextID={'test-host-details'}
scopeId={'test-scopeId'}
isDraggable={false}
openDetailsPanel={() => {}}
hostName={'test-host-name'}
onAssetCriticalityChange={() => {}}
@ -84,7 +82,6 @@ storiesOf('Components/HostPanelContent', module)
riskScoreState={riskScoreData}
contextID={'test-host-details'}
scopeId={'test-scopeId'}
isDraggable={false}
openDetailsPanel={() => {}}
hostName={'test-host-name'}
onAssetCriticalityChange={() => {}}

View file

@ -25,7 +25,6 @@ interface HostPanelContentProps {
riskScoreState: RiskScoreState<EntityType.host>;
contextID: string;
scopeId: string;
isDraggable: boolean;
openDetailsPanel: (path: EntityDetailsPath) => void;
hostName: string;
onAssetCriticalityChange: () => void;
@ -41,7 +40,6 @@ export const HostPanelContent = ({
recalculatingScore,
contextID,
scopeId,
isDraggable,
openDetailsPanel,
onAssetCriticalityChange,
isPreviewMode,
@ -80,7 +78,6 @@ export const HostPanelContent = ({
observedData={observedHost}
contextID={contextID}
scopeId={scopeId}
isDraggable={isDraggable}
observedFields={observedFields}
queryId={HOST_PANEL_OBSERVED_HOST_QUERY_ID}
/>

View file

@ -99,7 +99,6 @@ describe('useNavigateToHostDetails', () => {
contextID: mockProps.contextID,
scopeId: mockProps.scopeId,
hostName: mockProps.hostName,
isDraggable: undefined,
},
},
left: {

View file

@ -24,7 +24,6 @@ interface UseNavigateToHostDetailsParams {
hasNonClosedAlerts: boolean;
isPreviewMode?: boolean;
contextID: string;
isDraggable?: boolean;
}
interface UseNavigateToHostDetailsResult {
@ -41,7 +40,6 @@ export const useNavigateToHostDetails = ({
hasNonClosedAlerts,
isPreviewMode,
contextID,
isDraggable,
}: UseNavigateToHostDetailsParams): UseNavigateToHostDetailsResult => {
const { telemetry } = useKibana().services;
const { openLeftPanel, openFlyout } = useExpandableFlyoutApi();
@ -78,7 +76,6 @@ export const useNavigateToHostDetails = ({
contextID,
scopeId,
hostName,
isDraggable,
},
};
@ -103,7 +100,6 @@ export const useNavigateToHostDetails = ({
hasVulnerabilitiesFindings,
hasNonClosedAlerts,
contextID,
isDraggable,
]
);

View file

@ -10,14 +10,14 @@ import React from 'react';
import { TestProviders } from '../../../common/mock';
import { mockHostRiskScoreState, mockObservedHostData } from '../mocks';
import type {
FlyoutPanelProps,
ExpandableFlyoutState,
ExpandableFlyoutApi,
ExpandableFlyoutState,
FlyoutPanelProps,
} from '@kbn/expandable-flyout';
import {
useExpandableFlyoutApi,
useExpandableFlyoutState,
useExpandableFlyoutHistory,
useExpandableFlyoutState,
} from '@kbn/expandable-flyout';
import type { HostPanelProps } from '.';
import { HostPanel } from '.';
@ -26,7 +26,6 @@ const mockProps: HostPanelProps = {
hostName: 'test',
contextID: 'test-host -panel',
scopeId: 'test-scope-id',
isDraggable: false,
isPreviewMode: false,
};

View file

@ -39,7 +39,6 @@ export interface HostPanelProps extends Record<string, unknown> {
contextID: string;
scopeId: string;
hostName: string;
isDraggable?: boolean;
isPreviewMode?: boolean;
}
@ -57,13 +56,7 @@ const FIRST_RECORD_PAGINATION = {
querySize: 1,
};
export const HostPanel = ({
contextID,
scopeId,
hostName,
isDraggable,
isPreviewMode,
}: HostPanelProps) => {
export const HostPanel = ({ contextID, scopeId, hostName, isPreviewMode }: HostPanelProps) => {
const { to, from, isInitializing, setQuery, deleteQuery } = useGlobalTime();
const hostNameFilterQuery = useMemo(
() => (hostName ? buildHostNamesFilter([hostName]) : undefined),
@ -123,7 +116,6 @@ export const HostPanel = ({
hasNonClosedAlerts,
isPreviewMode,
contextID,
isDraggable,
});
const openDefaultPanel = useCallback(
@ -179,7 +171,6 @@ export const HostPanel = ({
riskScoreState={riskScoreState}
contextID={contextID}
scopeId={scopeId}
isDraggable={!!isDraggable}
openDetailsPanel={openDetailsPanel}
isLinkEnabled={isLinkEnabled}
recalculatingScore={recalculatingScore}
@ -187,12 +178,7 @@ export const HostPanel = ({
isPreviewMode={isPreviewMode}
/>
{isPreviewMode && (
<HostPreviewPanelFooter
hostName={hostName}
contextID={contextID}
scopeId={scopeId}
isDraggable={!!isDraggable}
/>
<HostPreviewPanelFooter hostName={hostName} contextID={contextID} scopeId={scopeId} />
)}
</>
);

View file

@ -29,7 +29,6 @@ interface ServicePanelContentProps {
recalculatingScore: boolean;
contextID: string;
scopeId: string;
isDraggable: boolean;
onAssetCriticalityChange: () => void;
openDetailsPanel: (path: EntityDetailsPath) => void;
isPreviewMode?: boolean;
@ -43,7 +42,6 @@ export const ServicePanelContent = ({
recalculatingScore,
contextID,
scopeId,
isDraggable,
openDetailsPanel,
onAssetCriticalityChange,
isPreviewMode,
@ -75,7 +73,6 @@ export const ServicePanelContent = ({
observedData={observedService}
contextID={contextID}
scopeId={scopeId}
isDraggable={isDraggable}
observedFields={observedFields}
queryId={OBSERVED_SERVICE_QUERY_ID}
/>

View file

@ -19,7 +19,6 @@ interface UseNavigateToServiceDetailsParams {
email?: string[];
scopeId: string;
contextID: string;
isDraggable?: boolean;
isRiskScoreExist: boolean;
isPreviewMode?: boolean;
}
@ -39,7 +38,6 @@ export const useNavigateToServiceDetails = ({
serviceName,
scopeId,
contextID,
isDraggable,
isRiskScoreExist,
isPreviewMode,
}: UseNavigateToServiceDetailsParams): UseNavigateToServiceDetailsResult => {
@ -75,7 +73,6 @@ export const useNavigateToServiceDetails = ({
contextID,
serviceName,
scopeId,
isDraggable,
},
};
@ -89,7 +86,6 @@ export const useNavigateToServiceDetails = ({
},
[
contextID,
isDraggable,
isNewNavigationEnabled,
isPreviewMode,
isRiskScoreExist,

View file

@ -11,14 +11,14 @@ import { TestProviders } from '../../../common/mock';
import type { ServicePanelProps } from '.';
import { ServicePanel } from '.';
import type {
FlyoutPanelProps,
ExpandableFlyoutState,
ExpandableFlyoutApi,
ExpandableFlyoutState,
FlyoutPanelProps,
} from '@kbn/expandable-flyout';
import {
useExpandableFlyoutApi,
useExpandableFlyoutState,
useExpandableFlyoutHistory,
useExpandableFlyoutState,
} from '@kbn/expandable-flyout';
import { mockObservedService } from './mocks';
import { mockServiceRiskScoreState } from '../mocks';
@ -27,7 +27,6 @@ const mockProps: ServicePanelProps = {
serviceName: 'test',
contextID: 'test-service-panel',
scopeId: 'test-scope-id',
isDraggable: false,
};
jest.mock('../../../common/components/visualization_actions/visualization_embeddable');

View file

@ -30,7 +30,6 @@ export interface ServicePanelProps extends Record<string, unknown> {
contextID: string;
scopeId: string;
serviceName: string;
isDraggable?: boolean;
}
export interface ServicePanelExpandableFlyoutProps extends FlyoutPanelProps {
@ -44,12 +43,7 @@ const FIRST_RECORD_PAGINATION = {
querySize: 1,
};
export const ServicePanel = ({
contextID,
scopeId,
serviceName,
isDraggable,
}: ServicePanelProps) => {
export const ServicePanel = ({ contextID, scopeId, serviceName }: ServicePanelProps) => {
const serviceNameFilterQuery = useMemo(
() => (serviceName ? buildEntityNameFilter(EntityType.service, [serviceName]) : undefined),
[serviceName]
@ -94,7 +88,6 @@ export const ServicePanel = ({
serviceName,
scopeId,
contextID,
isDraggable,
isRiskScoreExist,
});
@ -126,7 +119,6 @@ export const ServicePanel = ({
onAssetCriticalityChange={calculateEntityRiskScore}
contextID={contextID}
scopeId={scopeId}
isDraggable={!!isDraggable}
openDetailsPanel={openDetailsPanel}
isLinkEnabled={isLinkEnabled}
/>

View file

@ -17,7 +17,6 @@ import { hasPreview, PreviewLink } from '../../../../shared/components/preview_l
export const getEntityTableColumns = <T extends BasicEntityData>(
contextID: string,
scopeId: string,
isDraggable: boolean,
data: T
): EntityTableColumns<T> => [
{
@ -61,7 +60,6 @@ export const getEntityTableColumns = <T extends BasicEntityData>(
rowItems={values}
attrName={field}
idPrefix={contextID ? `entityTable-${contextID}` : 'entityTable'}
isDraggable={isDraggable}
scopeId={scopeId}
render={showPreviewLink ? renderPreviewLink : renderField}
data-test-subj="entity-table-value"

View file

@ -37,7 +37,6 @@ const testFieldWithPreview: EntityTableRow<BasicEntityData> = {
const mockProps = {
contextID: 'testContextID',
scopeId: 'testScopeId',
isDraggable: false,
data: { isLoading: false },
entityFields: [testField],
};

View file

@ -13,7 +13,6 @@ import type { BasicEntityData, EntityTableRows } from './types';
interface EntityTableProps<T extends BasicEntityData> {
contextID: string;
scopeId: string;
isDraggable: boolean;
data: T;
entityFields: EntityTableRows<T>;
}
@ -21,7 +20,6 @@ interface EntityTableProps<T extends BasicEntityData> {
export const EntityTable = <T extends BasicEntityData>({
contextID,
scopeId,
isDraggable,
data,
entityFields,
}: EntityTableProps<T>) => {
@ -31,8 +29,8 @@ export const EntityTable = <T extends BasicEntityData>({
);
const entityTableColumns = useMemo(
() => getEntityTableColumns<T>(contextID, scopeId, isDraggable, data),
[contextID, scopeId, isDraggable, data]
() => getEntityTableColumns<T>(contextID, scopeId, data),
[contextID, scopeId, data]
);
return (
<BasicTable

View file

@ -16,7 +16,6 @@ describe('ObservedHost', () => {
observedData: mockObservedHostData,
contextID: '',
scopeId: '',
isDraggable: false,
queryId: 'TEST_QUERY_ID',
observedFields: [],
};

View file

@ -21,14 +21,12 @@ export const ObservedEntity = <T,>({
observedData,
contextID,
scopeId,
isDraggable,
observedFields,
queryId,
}: {
observedData: ObservedEntityData<T>;
contextID: string;
scopeId: string;
isDraggable: boolean;
observedFields: EntityTableRows<ObservedEntityData<T>>;
queryId: string;
}) => {
@ -109,7 +107,6 @@ export const ObservedEntity = <T,>({
<EntityTable
contextID={contextID}
scopeId={scopeId}
isDraggable={isDraggable}
data={observedData}
entityFields={observedFields}
/>

View file

@ -18,7 +18,6 @@ const mockProps: UserPreviewPanelFooterProps = {
userName: 'test',
contextID: 'test-user-panel',
scopeId: 'test-scope-id',
isDraggable: false,
};
describe('<UserPreviewPanelFooter />', () => {

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import { EuiLink, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
import { EuiFlexGroup, EuiFlexItem, EuiLink } from '@elastic/eui';
import React, { useCallback } from 'react';
import { i18n } from '@kbn/i18n';
import { useExpandableFlyoutApi } from '@kbn/expandable-flyout';
@ -16,14 +16,12 @@ export interface UserPreviewPanelFooterProps {
contextID: string;
scopeId: string;
userName: string;
isDraggable?: boolean;
}
export const UserPreviewPanelFooter = ({
contextID,
scopeId,
userName,
isDraggable,
}: UserPreviewPanelFooterProps) => {
const { openFlyout } = useExpandableFlyoutApi();
@ -35,11 +33,10 @@ export const UserPreviewPanelFooter = ({
contextID,
userName,
scopeId,
isDraggable,
},
},
});
}, [openFlyout, userName, contextID, isDraggable, scopeId]);
}, [openFlyout, userName, contextID, scopeId]);
return (
<FlyoutFooter data-test-subj={'user-preview-footer'}>

View file

@ -18,7 +18,6 @@ describe('ManagedUser', () => {
managedUser: mockManagedUserData,
contextID: '',
scopeId: '',
isDraggable: false,
openDetailsPanel: () => {},
isLinkEnabled: true,
};

View file

@ -6,13 +6,13 @@
*/
import {
EuiButton,
EuiSpacer,
EuiAccordion,
EuiTitle,
EuiPanel,
EuiEmptyPrompt,
EuiButton,
EuiCallOut,
EuiEmptyPrompt,
EuiPanel,
EuiSpacer,
EuiTitle,
} from '@elastic/eui';
import React, { useMemo } from 'react';
@ -42,14 +42,12 @@ const accordionStyle = css`
export const ManagedUser = ({
managedUser,
contextID,
isDraggable,
openDetailsPanel,
isPreviewMode,
isLinkEnabled,
}: {
managedUser: ManagedUserData;
contextID: string;
isDraggable: boolean;
openDetailsPanel: (path: EntityDetailsPath) => void;
isPreviewMode?: boolean;
isLinkEnabled: boolean;
@ -135,7 +133,6 @@ export const ManagedUser = ({
isPreviewMode={isPreviewMode}
>
<ManagedUserTable
isDraggable={isDraggable}
contextID={contextID}
managedUser={entraManagedUser.fields}
tableType={UserAssetTableType.assetEntra}
@ -155,7 +152,6 @@ export const ManagedUser = ({
isPreviewMode={isPreviewMode}
>
<ManagedUserTable
isDraggable={isDraggable}
contextID={contextID}
managedUser={oktaManagedUser.fields}
tableType={UserAssetTableType.assetOkta}
@ -175,18 +171,13 @@ export const ManagedUser = ({
export const ManagedUserTable = ({
managedUser,
contextID,
isDraggable,
tableType,
}: {
managedUser: ManagedUserFields;
contextID: string;
isDraggable: boolean;
tableType: UserAssetTableType;
}) => {
const managedUserTableColumns = useMemo(
() => getManagedUserTableColumns(contextID, isDraggable),
[isDraggable, contextID]
);
const managedUserTableColumns = useMemo(() => getManagedUserTableColumns(contextID), [contextID]);
const managedItems = useManagedUserItems(tableType, managedUser);
return (

View file

@ -33,7 +33,6 @@ storiesOf('Components/UserPanelContent', module)
riskScoreState={riskScoreData}
contextID={'test-user-details'}
scopeId={'test-scopeId'}
isDraggable={false}
openDetailsPanel={() => {}}
userName={'test-user-name'}
onAssetCriticalityChange={() => {}}
@ -52,7 +51,6 @@ storiesOf('Components/UserPanelContent', module)
riskScoreState={riskScoreData}
contextID={'test-user-details'}
scopeId={'test-scopeId'}
isDraggable={false}
openDetailsPanel={() => {}}
userName={'test-user-name'}
onAssetCriticalityChange={() => {}}
@ -71,7 +69,6 @@ storiesOf('Components/UserPanelContent', module)
riskScoreState={riskScoreData}
contextID={'test-user-details'}
scopeId={'test-scopeId'}
isDraggable={false}
openDetailsPanel={() => {}}
userName={'test-user-name'}
onAssetCriticalityChange={() => {}}
@ -110,7 +107,6 @@ storiesOf('Components/UserPanelContent', module)
riskScoreState={riskScoreData}
contextID={'test-user-details'}
scopeId={'test-scopeId'}
isDraggable={false}
openDetailsPanel={() => {}}
userName={'test-user-name'}
onAssetCriticalityChange={() => {}}
@ -153,7 +149,6 @@ storiesOf('Components/UserPanelContent', module)
riskScoreState={riskScoreData}
contextID={'test-user-details'}
scopeId={'test-scopeId'}
isDraggable={false}
openDetailsPanel={() => {}}
userName={'test-user-name'}
onAssetCriticalityChange={() => {}}

View file

@ -34,7 +34,6 @@ interface UserPanelContentProps {
recalculatingScore: boolean;
contextID: string;
scopeId: string;
isDraggable: boolean;
onAssetCriticalityChange: () => void;
openDetailsPanel: (path: EntityDetailsPath) => void;
isPreviewMode?: boolean;
@ -49,7 +48,6 @@ export const UserPanelContent = ({
recalculatingScore,
contextID,
scopeId,
isDraggable,
openDetailsPanel,
onAssetCriticalityChange,
isPreviewMode,
@ -89,7 +87,6 @@ export const UserPanelContent = ({
observedData={observedUser}
contextID={contextID}
scopeId={scopeId}
isDraggable={isDraggable}
observedFields={observedFields}
queryId={OBSERVED_USER_QUERY_ID}
/>
@ -98,7 +95,6 @@ export const UserPanelContent = ({
<ManagedUser
managedUser={managedUser}
contextID={contextID}
isDraggable={isDraggable}
openDetailsPanel={openDetailsPanel}
isPreviewMode={isPreviewMode}
isLinkEnabled={isLinkEnabled}

View file

@ -19,7 +19,6 @@ interface UseNavigateToUserDetailsParams {
email?: string[];
scopeId: string;
contextID: string;
isDraggable?: boolean;
isRiskScoreExist: boolean;
hasMisconfigurationFindings: boolean;
hasNonClosedAlerts: boolean;
@ -42,7 +41,6 @@ export const useNavigateToUserDetails = ({
email,
scopeId,
contextID,
isDraggable,
isRiskScoreExist,
hasMisconfigurationFindings,
hasNonClosedAlerts,
@ -83,7 +81,6 @@ export const useNavigateToUserDetails = ({
contextID,
userName,
scopeId,
isDraggable,
},
};
@ -109,7 +106,6 @@ export const useNavigateToUserDetails = ({
isPreviewMode,
openFlyout,
contextID,
isDraggable,
]
);

View file

@ -11,14 +11,14 @@ import { TestProviders } from '../../../common/mock';
import type { UserPanelProps } from '.';
import { UserPanel } from '.';
import type {
FlyoutPanelProps,
ExpandableFlyoutState,
ExpandableFlyoutApi,
ExpandableFlyoutState,
FlyoutPanelProps,
} from '@kbn/expandable-flyout';
import {
useExpandableFlyoutApi,
useExpandableFlyoutState,
useExpandableFlyoutHistory,
useExpandableFlyoutState,
} from '@kbn/expandable-flyout';
import { mockManagedUserData, mockObservedUser } from './mocks';
import { mockRiskScoreState } from '../../shared/mocks';
@ -27,7 +27,6 @@ const mockProps: UserPanelProps = {
userName: 'test',
contextID: 'test-user-panel',
scopeId: 'test-scope-id',
isDraggable: false,
};
jest.mock('../../../common/components/visualization_actions/visualization_embeddable');

View file

@ -38,7 +38,6 @@ export interface UserPanelProps extends Record<string, unknown> {
contextID: string;
scopeId: string;
userName: string;
isDraggable?: boolean;
isPreviewMode?: boolean;
}
@ -54,13 +53,7 @@ const FIRST_RECORD_PAGINATION = {
querySize: 1,
};
export const UserPanel = ({
contextID,
scopeId,
userName,
isDraggable,
isPreviewMode,
}: UserPanelProps) => {
export const UserPanel = ({ contextID, scopeId, userName, isPreviewMode }: UserPanelProps) => {
const userNameFilterQuery = useMemo(
() => (userName ? buildUserNamesFilter([userName]) : undefined),
[userName]
@ -120,7 +113,6 @@ export const UserPanel = ({
email,
scopeId,
contextID,
isDraggable,
isRiskScoreExist,
hasMisconfigurationFindings,
hasNonClosedAlerts,
@ -186,18 +178,12 @@ export const UserPanel = ({
onAssetCriticalityChange={calculateEntityRiskScore}
contextID={contextID}
scopeId={scopeId}
isDraggable={!!isDraggable}
openDetailsPanel={openDetailsPanel}
isPreviewMode={isPreviewMode}
isLinkEnabled={isLinkEnabled}
/>
{isPreviewMode && (
<UserPreviewPanelFooter
userName={userName}
contextID={contextID}
scopeId={scopeId}
isDraggable={!!isDraggable}
/>
<UserPreviewPanelFooter userName={userName} contextID={contextID} scopeId={scopeId} />
)}
</>
);

View file

@ -34,10 +34,7 @@ const fieldColumn: EuiBasicTableColumn<ManagedUserTable> = {
render: (label: string, { field }) => <FieldColumn label={label} field={field ?? ''} />,
};
export const getManagedUserTableColumns = (
contextID: string,
isDraggable: boolean
): ManagedUsersTableColumns => [
export const getManagedUserTableColumns = (contextID: string): ManagedUsersTableColumns => [
fieldColumn,
{
name: i18n.VALUES_COLUMN_TITLE,
@ -48,7 +45,6 @@ export const getManagedUserTableColumns = (
rowItems={value.map(() => value.toString())}
attrName={field}
idPrefix={contextID ? `managedUser-${contextID}` : 'managedUser'}
isDraggable={isDraggable}
/>
) : (
defaultToEmptyTag(value)

View file

@ -42,11 +42,7 @@ export interface NetworkDetailsProps {
/**
* Component rendering all the network details for the expandable flyout
*/
export const NetworkDetails = ({
ip,
flowTarget,
isDraggable,
}: NetworkDetailsProps & { isDraggable?: boolean }) => {
export const NetworkDetails = ({ ip, flowTarget }: NetworkDetailsProps) => {
const dispatch = useDispatch();
const { to, from, isInitializing } = useGlobalTime();
const getGlobalQuerySelector = useMemo(() => inputsSelectors.globalQuerySelector(), []);
@ -113,7 +109,6 @@ export const NetworkDetails = ({
loading={loading}
isInDetailsSidePanel
isLoadingAnomaliesData={isLoadingAnomaliesData}
isDraggable={isDraggable}
type={type}
flowTarget={flowTarget}
startDate={from}

View file

@ -69,7 +69,6 @@ describe('getCellRendererForGivenRecord', () => {
expect(getByTestId('mocked-default-cell-render')).toBeVisible();
expect(mockDefaultCellRenderer).toHaveBeenCalledWith(
{
isDraggable: false,
isTimeline: false,
isDetails: false,
data: [

View file

@ -52,7 +52,6 @@ export const getCellRendererForGivenRecord: SecuritySolutionRowCellRendererGette
eventId={props.row.id}
header={header}
isDetails={props.isDetails}
isDraggable={false}
isTimeline={false}
linkValues={undefined}
rowRenderers={undefined}

View file

@ -45,7 +45,6 @@ interface HostSummaryProps {
scopeId?: string;
data: HostItem;
id: string;
isDraggable?: boolean;
isInDetailsSidePanel: boolean;
loading: boolean;
isLoadingAnomaliesData: boolean;
@ -73,7 +72,6 @@ export const HostOverview = React.memo<HostSummaryProps>(
data,
endDate,
id,
isDraggable = false,
isInDetailsSidePanel = false, // Rather than duplicate the component, alter the structure based on it's location
isLoadingAnomaliesData,
indexNames,
@ -121,11 +119,10 @@ export const HostOverview = React.memo<HostSummaryProps>(
rowItems={getOr([], fieldName, fieldData)}
attrName={fieldName}
idPrefix={contextID ? `host-overview-${contextID}` : 'host-overview'}
isDraggable={isDraggable}
scopeId={scopeId}
/>
),
[contextID, isDraggable, scopeId]
[contextID, scopeId]
);
const [hostRiskScore, hostRiskLevel] = useMemo(() => {
@ -179,7 +176,7 @@ export const HostOverview = React.memo<HostSummaryProps>(
title: i18n.HOST_ID,
description:
data && data.host
? hostIdRenderer({ host: data.host, isDraggable, noLink: true })
? hostIdRenderer({ host: data.host, noLink: true })
: getEmptyTagValue(),
},
{
@ -205,7 +202,7 @@ export const HostOverview = React.memo<HostSummaryProps>(
),
},
],
[data, indexNames, hostName, isDraggable]
[data, indexNames, hostName]
);
const firstColumn = useMemo(
() =>
@ -251,7 +248,6 @@ export const HostOverview = React.memo<HostSummaryProps>(
attrName={'host.ip'}
idPrefix={contextID ? `host-overview-${contextID}` : 'host-overview'}
scopeId={scopeId}
isDraggable={isDraggable}
render={(ip) => (ip != null ? <NetworkDetailsLink ip={ip} /> : getEmptyTagValue())}
/>
),
@ -287,7 +283,7 @@ export const HostOverview = React.memo<HostSummaryProps>(
},
],
],
[contextID, scopeId, data, firstColumn, getDefaultRenderer, isDraggable]
[contextID, scopeId, data, firstColumn, getDefaultRenderer]
);
return (
<>

View file

@ -46,7 +46,6 @@ export interface UserSummaryProps {
scopeId?: string;
data: UserItem;
id: string;
isDraggable?: boolean;
isInDetailsSidePanel: boolean;
loading: boolean;
isLoadingAnomaliesData: boolean;
@ -73,7 +72,6 @@ export const UserOverview = React.memo<UserSummaryProps>(
scopeId,
data,
id,
isDraggable = false,
isInDetailsSidePanel = false, // Rather than duplicate the component, alter the structure based on it's location
isLoadingAnomaliesData,
loading,
@ -122,11 +120,10 @@ export const UserOverview = React.memo<UserSummaryProps>(
rowItems={getOr([], fieldName, fieldData)}
attrName={fieldName}
idPrefix={contextID ? `user-overview-${contextID}` : 'user-overview'}
isDraggable={isDraggable}
scopeId={scopeId}
/>
),
[contextID, isDraggable, scopeId]
[contextID, scopeId]
);
const [userRiskScore, userRiskLevel] = useMemo(() => {
@ -266,23 +263,13 @@ export const UserOverview = React.memo<UserSummaryProps>(
attrName={'host.ip'}
idPrefix={contextID ? `user-overview-${contextID}` : 'user-overview'}
scopeId={scopeId}
isDraggable={isDraggable}
render={(ip) => (ip != null ? <NetworkDetailsLink ip={ip} /> : getEmptyTagValue())}
/>
),
},
],
],
[
data,
indexPatterns,
getDefaultRenderer,
contextID,
scopeId,
isDraggable,
userName,
firstColumn,
]
[data, indexPatterns, getDefaultRenderer, contextID, scopeId, userName, firstColumn]
);
return (
<>

View file

@ -40,9 +40,8 @@ export const CertificateFingerprint = React.memo<{
certificateType: CertificateType;
contextId: string;
fieldName: string;
isDraggable?: boolean;
value?: string | null;
}>(({ eventId, certificateType, contextId, fieldName, isDraggable, value }) => {
}>(({ eventId, certificateType, contextId, fieldName, value }) => {
return (
<DraggableBadge
contextId={contextId}
@ -50,7 +49,6 @@ export const CertificateFingerprint = React.memo<{
eventId={eventId}
field={fieldName}
iconType="snowflake"
isDraggable={isDraggable}
tooltipContent={
<EuiText size="xs">
<span>{fieldName}</span>

View file

@ -19,15 +19,7 @@ describe('Duration', () => {
test('it renders the expected formatted duration', () => {
render(
<TestProviders>
<Duration
contextId="test"
eventId="abc"
fieldName="event.duration"
isDraggable={true}
isAggregatable={true}
fieldType={'keyword'}
value={`${ONE_MILLISECOND_AS_NANOSECONDS}`}
/>
<Duration fieldName="event.duration" value={`${ONE_MILLISECOND_AS_NANOSECONDS}`} />
</TestProviders>
);
expect(screen.getByText('1ms')).toBeInTheDocument();

View file

@ -6,8 +6,6 @@
*/
import React from 'react';
import { DefaultDraggable } from '../../../common/components/draggables';
import { FormattedDuration } from '../formatted_duration';
export const EVENT_DURATION_FIELD_NAME = 'event.duration';
@ -17,29 +15,10 @@ export const EVENT_DURATION_FIELD_NAME = 'event.duration';
* duration of time, (e.g. `event.duration`)
*/
export const Duration = React.memo<{
contextId: string;
eventId: string;
fieldName: string;
fieldType: string;
isAggregatable: boolean;
isDraggable: boolean;
value?: string | null;
}>(({ contextId, eventId, fieldName, fieldType, isAggregatable, isDraggable, value }) =>
isDraggable ? (
<DefaultDraggable
id={`duration-default-draggable-${contextId}-${eventId}-${fieldName}-${value}`}
fieldType={fieldType}
isAggregatable={isAggregatable}
isDraggable={isDraggable}
field={fieldName}
tooltipContent={null}
value={value}
>
<FormattedDuration maybeDurationNanoseconds={value} tooltipTitle={fieldName} />
</DefaultDraggable>
) : (
<FormattedDuration maybeDurationNanoseconds={value} tooltipTitle={fieldName} />
)
);
}>(({ fieldName, value }) => (
<FormattedDuration maybeDurationNanoseconds={value} tooltipTitle={fieldName} />
));
Duration.displayName = 'Duration';

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import { EuiFlexGroup, EuiFlexItem, EuiButtonEmpty, EuiPopover } from '@elastic/eui';
import { EuiButtonEmpty, EuiFlexGroup, EuiFlexItem, EuiPopover } from '@elastic/eui';
import React, { useCallback, useMemo, useState } from 'react';
import { FormattedMessage } from '@kbn/i18n-react';
import { Spacer } from '../../../../common/components/page';
@ -18,15 +18,12 @@ interface DefaultFieldRendererProps {
attrName: string;
displayCount?: number;
idPrefix: string;
isDraggable?: boolean;
moreMaxHeight?: string;
render?: (item: string) => React.ReactNode;
rowItems: string[] | null | undefined;
scopeId?: string;
}
export const IpOverviewId = 'ip-overview';
/** The default max-height of the popover used to show "+n More" items (e.g. `+9 More`) */
export const DEFAULT_MORE_MAX_HEIGHT = '200px';
@ -34,7 +31,6 @@ export const DefaultFieldRendererComponent: React.FC<DefaultFieldRendererProps>
attrName,
displayCount = 1,
idPrefix,
isDraggable = false,
moreMaxHeight = DEFAULT_MORE_MAX_HEIGHT,
render,
rowItems,
@ -56,7 +52,6 @@ export const DefaultFieldRendererComponent: React.FC<DefaultFieldRendererProps>
{typeof rowItem === 'string' && (
<DefaultDraggable
id={id}
isDraggable={isDraggable}
field={attrName}
value={rowItem}
isAggregatable={true}

View file

@ -25,8 +25,7 @@ export const IpOverviewId = 'ip-overview';
export const locationRenderer = (
fieldNames: string[],
data: NetworkDetailsStrategyResponse['networkDetails'],
contextID?: string,
isDraggable?: boolean
contextID?: string
): React.ReactElement =>
fieldNames.length > 0 && fieldNames.every((fieldName) => getOr(null, fieldName, data)) ? (
<EuiFlexGroup alignItems="center" gutterSize="none">
@ -40,7 +39,6 @@ export const locationRenderer = (
id={`location-renderer-default-draggable-${IpOverviewId}-${
contextID ? `${contextID}-` : ''
}${fieldName}`}
isDraggable={isDraggable ?? false}
field={fieldName}
value={locationValue}
isAggregatable={true}
@ -58,8 +56,7 @@ export const locationRenderer = (
export const autonomousSystemRenderer = (
as: AutonomousSystem,
flowTarget: FlowTarget | FlowTargetSourceDest,
contextID?: string,
isDraggable?: boolean
contextID?: string
): React.ReactElement =>
as && as.organization && as.organization.name && as.number ? (
<EuiFlexGroup alignItems="center" gutterSize="none">
@ -68,7 +65,6 @@ export const autonomousSystemRenderer = (
id={`autonomous-system-renderer-default-draggable-${IpOverviewId}-${
contextID ? `${contextID}-` : ''
}${flowTarget}.as.organization.name`}
isDraggable={isDraggable ?? false}
field={`${flowTarget}.as.organization.name`}
value={as.organization.name}
/>
@ -79,7 +75,6 @@ export const autonomousSystemRenderer = (
id={`autonomous-system-renderer-default-draggable-${IpOverviewId}-${
contextID ? `${contextID}-` : ''
}${flowTarget}.as.number`}
isDraggable={false}
field={`${flowTarget}.as.number`}
value={`${as.number}`}
isAggregatable={true}
@ -95,14 +90,12 @@ interface HostIdRendererTypes {
contextID?: string;
host: HostEcs;
ipFilter?: string;
isDraggable?: boolean;
noLink?: boolean;
}
export const hostIdRenderer = ({
contextID,
host,
isDraggable = false,
ipFilter,
noLink,
}: HostIdRendererTypes): React.ReactElement =>
@ -113,7 +106,6 @@ export const hostIdRenderer = ({
id={`host-id-renderer-default-draggable-${IpOverviewId}-${
contextID ? `${contextID}-` : ''
}host-id`}
isDraggable={isDraggable}
field="host.id"
value={host.id[0]}
isAggregatable={true}
@ -136,8 +128,7 @@ export const hostIdRenderer = ({
export const hostNameRenderer = (
host?: HostEcs,
ipFilter?: string,
contextID?: string,
isDraggable?: boolean
contextID?: string
): React.ReactElement =>
host &&
host.name &&
@ -148,7 +139,6 @@ export const hostNameRenderer = (
id={`host-name-renderer-default-draggable-${IpOverviewId}-${
contextID ? `${contextID}-` : ''
}host-name`}
isDraggable={isDraggable ?? false}
field={'host.name'}
value={host.name[0]}
isAggregatable={true}

View file

@ -63,7 +63,6 @@ describe('FormattedIp', () => {
eventId: 'test-event-id',
isAggregatable: true,
fieldType: 'ip',
isDraggable: false,
fieldName: 'host.ip',
};
@ -77,20 +76,6 @@ describe('FormattedIp', () => {
expect(screen.getByText(props.value)).toBeInTheDocument();
});
test('should render DraggableWrapper if isDraggable is true', () => {
const testProps = {
...props,
isDraggable: true,
};
render(
<TestProviders>
<FormattedIp {...testProps} />
</TestProviders>
);
expect(screen.getByTestId('DraggableWrapper')).toBeInTheDocument();
});
test('if enableIpDetailsFlyout, should open NetworkDetails expandable flyout', async () => {
const context = {
enableHostDetailsFlyout: true,

View file

@ -6,39 +6,16 @@
*/
import { isArray, isEmpty, isString, uniq } from 'lodash/fp';
import type { ComponentProps } from 'react';
import React, { useCallback, useMemo, useContext } from 'react';
import React, { useCallback, useContext, useMemo } from 'react';
import deepEqual from 'fast-deep-equal';
import type { EuiButtonEmpty, EuiButtonIcon } from '@elastic/eui';
import { useExpandableFlyoutApi } from '@kbn/expandable-flyout';
import { StatefulEventContext } from '../../../common/components/events_viewer/stateful_event_context';
import { FlowTargetSourceDest } from '../../../../common/search_strategy/security_solution/network';
import {
DragEffects,
DraggableWrapper,
} from '../../../common/components/drag_and_drop/draggable_wrapper';
import { escapeDataProviderId } from '../../../common/components/drag_and_drop/helpers';
import { getOrEmptyTagFromValue } from '../../../common/components/empty_value';
import { parseQueryValue } from '../timeline/body/renderers/parse_query_value';
import type { DataProvider } from '../timeline/data_providers/data_provider';
import { IS_OPERATOR } from '../timeline/data_providers/data_provider';
import { Provider } from '../timeline/data_providers/provider';
import { NetworkDetailsLink } from '../../../common/components/links';
import { NetworkPanelKey } from '../../../flyout/network_details';
const getUniqueId = ({
contextId,
eventId,
fieldName,
address,
}: {
contextId: string;
eventId: string;
fieldName: string;
address: string | object | null | undefined;
}) => `formatted-ip-data-provider-${contextId}-${fieldName}-${address}-${eventId}`;
const tryStringify = (value: string | object | null | undefined): string => {
try {
return JSON.stringify(value);
@ -47,65 +24,9 @@ const tryStringify = (value: string | object | null | undefined): string => {
}
};
const getDataProvider = ({
contextId,
eventId,
fieldName,
address,
}: {
contextId: string;
eventId: string;
fieldName: string;
address: string | object | null | undefined;
}): DataProvider => ({
enabled: true,
id: escapeDataProviderId(getUniqueId({ contextId, eventId, fieldName, address })),
name: `${fieldName}: ${parseQueryValue(address)}`,
queryMatch: {
field: fieldName,
value: parseQueryValue(address),
operator: IS_OPERATOR,
},
excluded: false,
kqlQuery: '',
and: [],
});
const NonDecoratedIpComponent: React.FC<{
contextId: string;
eventId: string;
fieldName: string;
fieldType: string;
isAggregatable: boolean;
isDraggable: boolean;
truncate?: boolean;
value: string | object | null | undefined;
}> = ({
contextId,
eventId,
fieldName,
fieldType,
isAggregatable,
isDraggable,
truncate,
value,
}) => {
const key = useMemo(
() =>
`non-decorated-ip-draggable-wrapper-${getUniqueId({
contextId,
eventId,
fieldName,
address: value,
})}`,
[contextId, eventId, fieldName, value]
);
const dataProviderProp = useMemo(
() => getDataProvider({ contextId, eventId, fieldName, address: value }),
[contextId, eventId, fieldName, value]
);
}> = ({ value }) => {
const content = useMemo(
() =>
typeof value !== 'object'
@ -114,33 +35,7 @@ const NonDecoratedIpComponent: React.FC<{
[value]
);
const render: ComponentProps<typeof DraggableWrapper>['render'] = useCallback(
(dataProvider: DataProvider, _, snapshot) =>
snapshot.isDragging ? (
<DragEffects>
<Provider dataProvider={dataProvider} />
</DragEffects>
) : (
content
),
[content]
);
if (!isDraggable) {
return content;
}
return (
<DraggableWrapper
dataProvider={dataProviderProp}
fieldType={fieldType}
isAggregatable={isAggregatable}
isDraggable={isDraggable}
key={key}
render={render}
truncate={truncate}
/>
);
return content;
};
const NonDecoratedIp = React.memo(NonDecoratedIpComponent);
@ -152,31 +47,13 @@ interface AddressLinksItemProps extends Omit<AddressLinksProps, 'addresses'> {
const AddressLinksItemComponent: React.FC<AddressLinksItemProps> = ({
address,
Component,
contextId,
eventId,
fieldName,
fieldType,
isAggregatable,
isButton,
isDraggable,
onClick,
truncate,
title,
}) => {
const { openFlyout } = useExpandableFlyoutApi();
const key = `address-links-draggable-wrapper-${getUniqueId({
contextId,
eventId,
fieldName,
address,
})}`;
const dataProviderProp = useMemo(
() => getDataProvider({ contextId, eventId, fieldName, address }),
[address, contextId, eventId, fieldName]
);
const eventContext = useContext(StatefulEventContext);
const isInTimelineContext =
address && eventContext?.enableIpDetailsFlyout && eventContext?.timelineID;
@ -229,33 +106,7 @@ const AddressLinksItemComponent: React.FC<AddressLinksItemProps> = ({
[Component, address, isButton, isInTimelineContext, openNetworkDetailsSidePanel, title]
);
const render: ComponentProps<typeof DraggableWrapper>['render'] = useCallback(
(_props, _provided, snapshot) =>
snapshot.isDragging ? (
<DragEffects>
<Provider dataProvider={dataProviderProp} />
</DragEffects>
) : (
content
),
[dataProviderProp, content]
);
if (!isDraggable) {
return content;
}
return (
<DraggableWrapper
dataProvider={dataProviderProp}
isDraggable={isDraggable}
fieldType={fieldType}
isAggregatable={isAggregatable}
key={key}
render={render}
truncate={truncate}
/>
);
return content;
};
const AddressLinksItem = React.memo(AddressLinksItemComponent);
@ -263,30 +114,18 @@ const AddressLinksItem = React.memo(AddressLinksItemComponent);
interface AddressLinksProps {
addresses: string[];
Component?: typeof EuiButtonEmpty | typeof EuiButtonIcon;
contextId: string;
eventId: string;
fieldName: string;
fieldType: string;
isAggregatable: boolean;
isButton?: boolean;
isDraggable: boolean;
onClick?: () => void;
truncate?: boolean;
title?: string;
}
const AddressLinksComponent: React.FC<AddressLinksProps> = ({
addresses,
Component,
contextId,
eventId,
fieldName,
fieldType,
isAggregatable,
isButton,
isDraggable,
onClick,
truncate,
title,
}) => {
const uniqAddresses = useMemo(() => uniq(addresses), [addresses]);
@ -298,32 +137,13 @@ const AddressLinksComponent: React.FC<AddressLinksProps> = ({
key={address}
address={address}
Component={Component}
contextId={contextId}
eventId={eventId}
fieldName={fieldName}
fieldType={fieldType}
isAggregatable={isAggregatable}
isButton={isButton}
isDraggable={isDraggable}
onClick={onClick}
truncate={truncate}
title={title}
/>
)),
[
Component,
contextId,
eventId,
fieldName,
fieldType,
isAggregatable,
isButton,
isDraggable,
onClick,
title,
truncate,
uniqAddresses,
]
[Component, fieldName, isButton, onClick, title, uniqAddresses]
);
return <>{content}</>;
@ -332,43 +152,18 @@ const AddressLinksComponent: React.FC<AddressLinksProps> = ({
const AddressLinks = React.memo(
AddressLinksComponent,
(prevProps, nextProps) =>
prevProps.contextId === nextProps.contextId &&
prevProps.eventId === nextProps.eventId &&
prevProps.fieldName === nextProps.fieldName &&
prevProps.isAggregatable === nextProps.isAggregatable &&
prevProps.fieldType === nextProps.fieldType &&
prevProps.isDraggable === nextProps.isDraggable &&
prevProps.truncate === nextProps.truncate &&
deepEqual(prevProps.addresses, nextProps.addresses)
);
const FormattedIpComponent: React.FC<{
Component?: typeof EuiButtonEmpty | typeof EuiButtonIcon;
contextId: string;
eventId: string;
fieldName: string;
fieldType: string;
isAggregatable: boolean;
isButton?: boolean;
isDraggable: boolean;
onClick?: () => void;
title?: string;
truncate?: boolean;
value: string | object | null | undefined;
}> = ({
Component,
contextId,
eventId,
fieldName,
fieldType,
isAggregatable,
isDraggable,
isButton,
onClick,
title,
truncate,
value,
}) => {
}> = ({ Component, fieldName, isButton, onClick, title, value }) => {
if (isString(value) && !isEmpty(value)) {
try {
const addresses = JSON.parse(value);
@ -377,16 +172,10 @@ const FormattedIpComponent: React.FC<{
<AddressLinks
addresses={addresses}
Component={Component}
contextId={contextId}
eventId={eventId}
fieldName={fieldName}
fieldType={fieldType}
isAggregatable={isAggregatable}
isButton={isButton}
isDraggable={isDraggable}
onClick={onClick}
title={title}
truncate={truncate}
/>
);
}
@ -399,43 +188,19 @@ const FormattedIpComponent: React.FC<{
<AddressLinks
addresses={[value]}
Component={Component}
contextId={contextId}
eventId={eventId}
isButton={isButton}
isDraggable={isDraggable}
onClick={onClick}
fieldName={fieldName}
fieldType={fieldType}
isAggregatable={isAggregatable}
truncate={truncate}
title={title}
/>
);
} else {
return (
<NonDecoratedIp
contextId={contextId}
eventId={eventId}
fieldName={fieldName}
fieldType={fieldType}
isAggregatable={isAggregatable}
isDraggable={isDraggable}
truncate={truncate}
value={value}
/>
);
return <NonDecoratedIp value={value} />;
}
};
export const FormattedIp = React.memo(
FormattedIpComponent,
(prevProps, nextProps) =>
prevProps.contextId === nextProps.contextId &&
prevProps.eventId === nextProps.eventId &&
prevProps.fieldName === nextProps.fieldName &&
prevProps.isAggregatable === nextProps.isAggregatable &&
prevProps.fieldType === nextProps.fieldType &&
prevProps.isDraggable === nextProps.isDraggable &&
prevProps.truncate === nextProps.truncate &&
deepEqual(prevProps.value, nextProps.value)
prevProps.fieldName === nextProps.fieldName && deepEqual(prevProps.value, nextProps.value)
);

View file

@ -30,16 +30,14 @@ export const Ja3Fingerprint = React.memo<{
eventId: string;
contextId: string;
fieldName: string;
isDraggable?: boolean;
value?: string | null;
}>(({ contextId, eventId, fieldName, isDraggable, value }) => (
}>(({ contextId, eventId, fieldName, value }) => (
<DraggableBadge
contextId={contextId}
data-test-subj="ja3-hash"
eventId={eventId}
field={fieldName}
iconType="snowflake"
isDraggable={isDraggable}
value={value}
isAggregatable={true}
fieldType="keyword"

View file

@ -23,7 +23,6 @@ import { JA3_HASH_FIELD_NAME, Ja3Fingerprint } from '../../ja3_fingerprint';
export const Fingerprints = React.memo<{
contextId: string;
eventId: string;
isDraggable?: boolean;
tlsClientCertificateFingerprintSha1?: string[] | null;
tlsFingerprintsJa3Hash?: string[] | null;
tlsServerCertificateFingerprintSha1?: string[] | null;
@ -31,7 +30,6 @@ export const Fingerprints = React.memo<{
({
contextId,
eventId,
isDraggable,
tlsClientCertificateFingerprintSha1,
tlsFingerprintsJa3Hash,
tlsServerCertificateFingerprintSha1,
@ -50,7 +48,6 @@ export const Fingerprints = React.memo<{
eventId={eventId}
fieldName={JA3_HASH_FIELD_NAME}
contextId={contextId}
isDraggable={isDraggable}
value={ja3}
/>
</EuiFlexItem>
@ -64,7 +61,6 @@ export const Fingerprints = React.memo<{
certificateType="client"
contextId={contextId}
fieldName={TLS_CLIENT_CERTIFICATE_FINGERPRINT_SHA1_FIELD_NAME}
isDraggable={isDraggable}
value={clientCert}
/>
</EuiFlexItem>
@ -78,7 +74,6 @@ export const Fingerprints = React.memo<{
certificateType="server"
contextId={contextId}
fieldName={TLS_SERVER_CERTIFICATE_FINGERPRINT_SHA1_FIELD_NAME}
isDraggable={isDraggable}
value={serverCert}
/>
</EuiFlexItem>

View file

@ -8,7 +8,6 @@
import { get } from 'lodash/fp';
import React from 'react';
import { render, screen, within } from '@testing-library/react';
import { asArrayIfExists } from '../../../common/lib/helpers';
import { TestProviders } from '../../../common/mock/test_providers';
import {
@ -45,7 +44,6 @@ import {
SOURCE_PACKETS_FIELD_NAME,
} from '../../../explore/network/components/source_destination/source_destination_arrows';
import * as i18n from '../timeline/body/renderers/translations';
import { Netflow } from '.';
import {
EVENT_END_FIELD_NAME,
@ -54,8 +52,8 @@ import {
import { PROCESS_NAME_FIELD_NAME, USER_NAME_FIELD_NAME } from './netflow_columns/user_process';
import {
NETWORK_BYTES_FIELD_NAME,
NETWORK_DIRECTION_FIELD_NAME,
NETWORK_COMMUNITY_ID_FIELD_NAME,
NETWORK_DIRECTION_FIELD_NAME,
NETWORK_PACKETS_FIELD_NAME,
NETWORK_PROTOCOL_FIELD_NAME,
NETWORK_TRANSPORT_FIELD_NAME,
@ -156,7 +154,7 @@ describe('Netflow', () => {
test('it renders destination.geo.continent_name', () => {
render(<TestProviders>{getNetflowInstance()}</TestProviders>);
expect(screen.getByTestId('draggable-content-destination.geo.continent_name').textContent).toBe(
expect(screen.getByTestId('render-content-destination.geo.continent_name').textContent).toBe(
'North America'
);
});
@ -164,7 +162,7 @@ describe('Netflow', () => {
test('it renders destination.geo.country_name', () => {
render(<TestProviders>{getNetflowInstance()}</TestProviders>);
expect(screen.getByTestId('draggable-content-destination.geo.country_name').textContent).toBe(
expect(screen.getByTestId('render-content-destination.geo.country_name').textContent).toBe(
'United States'
);
});
@ -172,15 +170,15 @@ describe('Netflow', () => {
test('it renders destination.geo.country_iso_code', () => {
render(<TestProviders>{getNetflowInstance()}</TestProviders>);
expect(
screen.getByTestId('draggable-content-destination.geo.country_iso_code').textContent
).toBe('US');
expect(screen.getByTestId('render-content-destination.geo.country_iso_code').textContent).toBe(
'US'
);
});
test('it renders destination.geo.region_name', () => {
render(<TestProviders>{getNetflowInstance()}</TestProviders>);
expect(screen.getByTestId('draggable-content-destination.geo.region_name').textContent).toBe(
expect(screen.getByTestId('render-content-destination.geo.region_name').textContent).toBe(
'New York'
);
});
@ -188,7 +186,7 @@ describe('Netflow', () => {
test('it renders destination.geo.city_name', () => {
render(<TestProviders>{getNetflowInstance()}</TestProviders>);
expect(screen.getByTestId('draggable-content-destination.geo.city_name').textContent).toBe(
expect(screen.getByTestId('render-content-destination.geo.city_name').textContent).toBe(
'New York'
);
});
@ -225,7 +223,7 @@ describe('Netflow', () => {
test('it renders event.end', () => {
render(<TestProviders>{getNetflowInstance()}</TestProviders>);
expect(screen.getByTestId('draggable-content-event.end').textContent).toBe(
expect(screen.getByTestId('render-content-event.end').textContent).toBe(
'Nov 12, 2018 @ 19:03:25.936'
);
});
@ -233,7 +231,7 @@ describe('Netflow', () => {
test('it renders event.start', () => {
render(<TestProviders>{getNetflowInstance()}</TestProviders>);
expect(screen.getByTestId('draggable-content-event.start').textContent).toBe(
expect(screen.getByTestId('render-content-event.start').textContent).toBe(
'Nov 12, 2018 @ 19:03:25.836'
);
});
@ -289,7 +287,7 @@ describe('Netflow', () => {
test('it renders source.geo.continent_name', () => {
render(<TestProviders>{getNetflowInstance()}</TestProviders>);
expect(screen.getByTestId('draggable-content-source.geo.continent_name').textContent).toBe(
expect(screen.getByTestId('render-content-source.geo.continent_name').textContent).toBe(
'North America'
);
});
@ -297,7 +295,7 @@ describe('Netflow', () => {
test('it renders source.geo.country_name', () => {
render(<TestProviders>{getNetflowInstance()}</TestProviders>);
expect(screen.getByTestId('draggable-content-source.geo.country_name').textContent).toBe(
expect(screen.getByTestId('render-content-source.geo.country_name').textContent).toBe(
'United States'
);
});
@ -305,25 +303,19 @@ describe('Netflow', () => {
test('it renders source.geo.country_iso_code', () => {
render(<TestProviders>{getNetflowInstance()}</TestProviders>);
expect(screen.getByTestId('draggable-content-source.geo.country_iso_code').textContent).toBe(
'US'
);
expect(screen.getByTestId('render-content-source.geo.country_iso_code').textContent).toBe('US');
});
test('it renders source.geo.region_name', () => {
render(<TestProviders>{getNetflowInstance()}</TestProviders>);
expect(screen.getByTestId('draggable-content-source.geo.region_name').textContent).toBe(
'Georgia'
);
expect(screen.getByTestId('render-content-source.geo.region_name').textContent).toBe('Georgia');
});
test('it renders source.geo.city_name', () => {
render(<TestProviders>{getNetflowInstance()}</TestProviders>);
expect(screen.getByTestId('draggable-content-source.geo.city_name').textContent).toBe(
'Atlanta'
);
expect(screen.getByTestId('render-content-source.geo.city_name').textContent).toBe('Atlanta');
});
test('it renders the source ip and port, separated with a colon', () => {

View file

@ -37,7 +37,6 @@ export const Netflow = React.memo<NetflowProps>(
eventId,
eventEnd,
eventStart,
isDraggable,
networkBytes,
networkCommunityId,
networkDirection,
@ -83,7 +82,6 @@ export const Netflow = React.memo<NetflowProps>(
eventId={eventId}
eventEnd={eventEnd}
eventStart={eventStart}
isDraggable={isDraggable}
networkBytes={networkBytes}
networkCommunityId={networkCommunityId}
networkDirection={networkDirection}
@ -107,7 +105,6 @@ export const Netflow = React.memo<NetflowProps>(
<Fingerprints
contextId={contextId}
eventId={eventId}
isDraggable={isDraggable}
tlsClientCertificateFingerprintSha1={tlsClientCertificateFingerprintSha1}
tlsFingerprintsJa3Hash={tlsFingerprintsJa3Hash}
tlsServerCertificateFingerprintSha1={tlsServerCertificateFingerprintSha1}

View file

@ -38,8 +38,7 @@ export const DurationEventStartEnd = React.memo<{
eventId: string;
eventEnd?: string[] | null;
eventStart?: string[] | null;
isDraggable?: boolean;
}>(({ contextId, eventDuration, eventId, eventEnd, eventStart, isDraggable }) => (
}>(({ contextId, eventDuration, eventId, eventEnd, eventStart }) => (
<EuiFlexGroup
alignItems="flexStart"
data-test-subj="duration-and-start-group"
@ -53,7 +52,6 @@ export const DurationEventStartEnd = React.memo<{
<DefaultDraggable
field={EVENT_DURATION_FIELD_NAME}
id={`duration-event-start-end-default-draggable-${contextId}-${eventId}-${EVENT_DURATION_FIELD_NAME}-${duration}`}
isDraggable={isDraggable}
// @ts-expect-error
name={name}
tooltipContent={null}
@ -76,7 +74,6 @@ export const DurationEventStartEnd = React.memo<{
<DefaultDraggable
field={EVENT_START_FIELD_NAME}
id={`duration-event-start-end-default-draggable-${contextId}-${eventId}-${EVENT_START_FIELD_NAME}-${start}`}
isDraggable={isDraggable}
tooltipContent={null}
value={start}
>
@ -94,7 +91,6 @@ export const DurationEventStartEnd = React.memo<{
<DefaultDraggable
field={EVENT_END_FIELD_NAME}
id={`duration-event-start-end-default-draggable-${contextId}-${eventId}-${EVENT_END_FIELD_NAME}-${end}`}
isDraggable={isDraggable}
tooltipContent={null}
value={end}
>

Some files were not shown because too many files have changed in this diff Show more