mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
[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:
parent
3a14752dad
commit
ebb31d249f
213 changed files with 1873 additions and 6579 deletions
|
@ -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/,
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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": "フィールド",
|
||||
|
|
|
@ -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": "字段",
|
||||
|
|
|
@ -19,12 +19,10 @@ export interface DeprecatedRowRenderer {
|
|||
renderRow: ({
|
||||
contextId,
|
||||
data,
|
||||
isDraggable,
|
||||
scopeId,
|
||||
}: {
|
||||
contextId?: string;
|
||||
data: Ecs;
|
||||
isDraggable: boolean;
|
||||
scopeId: string;
|
||||
}) => React.ReactNode;
|
||||
}
|
||||
|
|
|
@ -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[];
|
||||
|
|
|
@ -14,12 +14,10 @@ export interface RowRenderer {
|
|||
renderRow: ({
|
||||
contextId,
|
||||
data,
|
||||
isDraggable,
|
||||
scopeId,
|
||||
}: {
|
||||
contextId?: string;
|
||||
data: Ecs;
|
||||
isDraggable: boolean;
|
||||
scopeId: string;
|
||||
}) => React.ReactNode;
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@ interface HostPanelProps extends Record<string, unknown> {
|
|||
contextID: string;
|
||||
scopeId: string;
|
||||
hostName: string;
|
||||
isDraggable?: boolean;
|
||||
}
|
||||
|
||||
interface HostPanelExpandableFlyoutProps extends FlyoutPanelProps {
|
||||
|
|
|
@ -58,7 +58,6 @@ export const getFieldMarkdownRenderer = (disableActions: boolean) => {
|
|||
eventId=""
|
||||
iconType={icon}
|
||||
isAggregatable={false}
|
||||
isDraggable={false}
|
||||
field={name}
|
||||
value={value}
|
||||
>
|
||||
|
|
|
@ -71,7 +71,6 @@ const DraggableLegendItemComponent: React.FC<{
|
|||
field={field}
|
||||
hideTopN={true}
|
||||
id={dataProviderId}
|
||||
isDraggable={false}
|
||||
scopeId={scopeId}
|
||||
value={value}
|
||||
>
|
||||
|
|
|
@ -17,7 +17,6 @@ exports[`DraggableWrapper rendering it renders against the snapshot 1`] = `
|
|||
},
|
||||
}
|
||||
}
|
||||
isDraggable={true}
|
||||
render={[Function]}
|
||||
/>
|
||||
`;
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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',
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -39,7 +39,6 @@ exports[`draggables rendering it renders the default DefaultDraggable 1`] = `
|
|||
fieldType=""
|
||||
hideTopN={false}
|
||||
isAggregatable={false}
|
||||
isDraggable={true}
|
||||
render={[Function]}
|
||||
/>
|
||||
`;
|
||||
|
|
|
@ -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';
|
|
@ -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',
|
||||
});
|
|
@ -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', () => {
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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}`}
|
||||
|
|
|
@ -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}`}
|
||||
|
|
|
@ -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}`}
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
}, []);
|
||||
|
||||
|
|
|
@ -43,7 +43,6 @@ describe('RenderCellValue', () => {
|
|||
eventId,
|
||||
header,
|
||||
isDetails: false,
|
||||
isDraggable: true,
|
||||
isExpandable: false,
|
||||
isExpanded: false,
|
||||
linkValues,
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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,
|
||||
},
|
||||
];
|
|
@ -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 };
|
|
@ -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,
|
||||
});
|
||||
});
|
||||
});
|
|
@ -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}
|
||||
/>
|
||||
);
|
||||
}
|
||||
};
|
|
@ -52,7 +52,6 @@ describe('RenderCellValue', () => {
|
|||
eventId,
|
||||
header,
|
||||
isDetails: false,
|
||||
isDraggable: false,
|
||||
isExpandable: false,
|
||||
isExpanded: false,
|
||||
linkValues,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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(),
|
||||
},
|
||||
],
|
||||
[
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
/>
|
||||
`;
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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)}
|
||||
/>
|
||||
|
|
|
@ -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', () => {
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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>
|
||||
));
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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'
|
||||
);
|
||||
});
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -40,7 +40,6 @@ export const AlertReason: React.FC = () => {
|
|||
? renderer.renderRow({
|
||||
contextId: 'event-details',
|
||||
data: dataAsNestedObject,
|
||||
isDraggable: false,
|
||||
scopeId,
|
||||
})
|
||||
: null,
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -38,7 +38,6 @@ export const EventRenderer: FC = () => {
|
|||
? renderer.renderRow({
|
||||
contextId: 'event-details',
|
||||
data: dataAsNestedObject,
|
||||
isDraggable: false,
|
||||
scopeId,
|
||||
})
|
||||
: null,
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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)}
|
||||
|
|
|
@ -18,7 +18,6 @@ const mockProps: HostPreviewPanelFooterProps = {
|
|||
hostName: 'test',
|
||||
contextID: 'test-host-panel',
|
||||
scopeId: 'test-scope-id',
|
||||
isDraggable: false,
|
||||
};
|
||||
|
||||
describe('<HostPreviewPanelFooter />', () => {
|
||||
|
|
|
@ -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'}>
|
||||
|
|
|
@ -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={() => {}}
|
||||
|
|
|
@ -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}
|
||||
/>
|
||||
|
|
|
@ -99,7 +99,6 @@ describe('useNavigateToHostDetails', () => {
|
|||
contextID: mockProps.contextID,
|
||||
scopeId: mockProps.scopeId,
|
||||
hostName: mockProps.hostName,
|
||||
isDraggable: undefined,
|
||||
},
|
||||
},
|
||||
left: {
|
||||
|
|
|
@ -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,
|
||||
]
|
||||
);
|
||||
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
|
|
@ -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} />
|
||||
)}
|
||||
</>
|
||||
);
|
||||
|
|
|
@ -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}
|
||||
/>
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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}
|
||||
/>
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -37,7 +37,6 @@ const testFieldWithPreview: EntityTableRow<BasicEntityData> = {
|
|||
const mockProps = {
|
||||
contextID: 'testContextID',
|
||||
scopeId: 'testScopeId',
|
||||
isDraggable: false,
|
||||
data: { isLoading: false },
|
||||
entityFields: [testField],
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -16,7 +16,6 @@ describe('ObservedHost', () => {
|
|||
observedData: mockObservedHostData,
|
||||
contextID: '',
|
||||
scopeId: '',
|
||||
isDraggable: false,
|
||||
queryId: 'TEST_QUERY_ID',
|
||||
observedFields: [],
|
||||
};
|
||||
|
|
|
@ -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}
|
||||
/>
|
||||
|
|
|
@ -18,7 +18,6 @@ const mockProps: UserPreviewPanelFooterProps = {
|
|||
userName: 'test',
|
||||
contextID: 'test-user-panel',
|
||||
scopeId: 'test-scope-id',
|
||||
isDraggable: false,
|
||||
};
|
||||
|
||||
describe('<UserPreviewPanelFooter />', () => {
|
||||
|
|
|
@ -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'}>
|
||||
|
|
|
@ -18,7 +18,6 @@ describe('ManagedUser', () => {
|
|||
managedUser: mockManagedUserData,
|
||||
contextID: '',
|
||||
scopeId: '',
|
||||
isDraggable: false,
|
||||
openDetailsPanel: () => {},
|
||||
isLinkEnabled: true,
|
||||
};
|
||||
|
|
|
@ -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 (
|
||||
|
|
|
@ -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={() => {}}
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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,
|
||||
]
|
||||
);
|
||||
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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} />
|
||||
)}
|
||||
</>
|
||||
);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -69,7 +69,6 @@ describe('getCellRendererForGivenRecord', () => {
|
|||
expect(getByTestId('mocked-default-cell-render')).toBeVisible();
|
||||
expect(mockDefaultCellRenderer).toHaveBeenCalledWith(
|
||||
{
|
||||
isDraggable: false,
|
||||
isTimeline: false,
|
||||
isDetails: false,
|
||||
data: [
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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 (
|
||||
<>
|
||||
|
|
|
@ -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 (
|
||||
<>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
);
|
||||
|
|
|
@ -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"
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -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>
|
||||
|
|
|
@ -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', () => {
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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
Loading…
Add table
Add a link
Reference in a new issue