Skip to content

Commit

Permalink
[Security Solution] tgrid cellActions enhancement (#113419)
Browse files Browse the repository at this point in the history
* Alerts cellAction enhancement

* styling

* fix types

* expandable topN

* fix types

* styling for filters

* styling

* rm getDefaultCellActions

* styling

* globalFilters for topN

* rm unused i18n keys

* unit test

* add i18n

* rename component

* fix types

* update i18n keys

* unit tests

* styling for reason row renderer

* rename file

* fix Circular Dependencies

* update wording/icons for show top N

* cell value text overflow

* reason in grid-view

* unit test

* default selected option for topN

* lint error

* configurable paddingSize and showLegend for topN

* update snapshot

* rename reason title

* fix cypress

* fix cypress

* fix unit tests

* fix default cell actions

* fix page crashing

* unit test

* add unit tests

* code review

* fix missing props

* fix expand ip button

Co-authored-by: Kibana Machine <[email protected]>
  • Loading branch information
angorayc and kibanamachine authored Oct 14, 2021
1 parent cdce98c commit 56a2e78
Show file tree
Hide file tree
Showing 55 changed files with 1,540 additions and 477 deletions.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import {
} from '../../../../timelines/components/timeline/body/renderers/constants';
import { BYTES_FORMAT } from '../../../../timelines/components/timeline/body/renderers/bytes';
import { EVENT_DURATION_FIELD_NAME } from '../../../../timelines/components/duration';
import { PORT_NAMES } from '../../../../network/components/port';
import { PORT_NAMES } from '../../../../network/components/port/helpers';
import { INDICATOR_REFERENCE } from '../../../../../common/cti/constants';
import { BrowserField } from '../../../containers/source';
import { DataProvider, IS_OPERATOR } from '../../../../../common/types';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,23 +92,27 @@ PreferenceFormattedP1DTDate.displayName = 'PreferenceFormattedP1DTDate';
* - a long representation of the date that includes the day of the week (e.g. Thursday, March 21, 2019 6:47pm)
* - the raw date value (e.g. 2019-03-22T00:47:46Z)
*/
export const FormattedDate = React.memo<{

interface FormattedDateProps {
className?: string;
fieldName: string;
value?: string | number | null;
className?: string;
}>(({ value, fieldName, className = '' }): JSX.Element => {
if (value == null) {
return getOrEmptyTagFromValue(value);
}
export const FormattedDate = React.memo<FormattedDateProps>(
({ value, fieldName, className = '' }): JSX.Element => {
if (value == null) {
return getOrEmptyTagFromValue(value);
}
const maybeDate = getMaybeDate(value);
return maybeDate.isValid() ? (
<LocalizedDateTooltip date={maybeDate.toDate()} fieldName={fieldName} className={className}>
<PreferenceFormattedDate value={maybeDate.toDate()} />
</LocalizedDateTooltip>
) : (
getOrEmptyTagFromValue(value)
);
}
const maybeDate = getMaybeDate(value);
return maybeDate.isValid() ? (
<LocalizedDateTooltip date={maybeDate.toDate()} fieldName={fieldName} className={className}>
<PreferenceFormattedDate value={maybeDate.toDate()} />
</LocalizedDateTooltip>
) : (
getOrEmptyTagFromValue(value)
);
});
);

FormattedDate.displayName = 'FormattedDate';

Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -68,20 +68,20 @@ const HeaderSectionComponent: React.FC<HeaderSectionProps> = ({
hideSubtitle = false,
}) => (
<Header data-test-subj="header-section" border={border} height={height}>
<EuiFlexGroup alignItems="center">
<EuiFlexGroup alignItems="center" gutterSize="none">
<EuiFlexItem grow={growLeftSplit}>
<EuiFlexGroup alignItems="center" responsive={false}>
<EuiFlexGroup alignItems="center" responsive={false} gutterSize="none">
<EuiFlexItem>
<EuiTitle size={titleSize}>
<h2 data-test-subj="header-section-title">
<h4 data-test-subj="header-section-title">
{title}
{tooltip && (
<>
{' '}
<EuiIconTip color="subdued" content={tooltip} size="l" type="iInCircle" />
</>
)}
</h2>
</h4>
</EuiTitle>

{!hideSubtitle && (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,33 +30,49 @@ const SHOW_TOP = (fieldName: string) =>
});

interface Props {
className?: string;
/** When `Component` is used with `EuiDataGrid`; the grid keeps a reference to `Component` for show / hide functionality.
* When `Component` is used with `EuiContextMenu`, we pass EuiContextMenuItem to render the right style.
*/
Component?: typeof EuiButtonEmpty | typeof EuiButtonIcon | typeof EuiContextMenuItem;
enablePopOver?: boolean;
field: string;
flush?: 'left' | 'right' | 'both';
globalFilters?: Filter[];
iconSide?: 'left' | 'right';
iconType?: string;
isExpandable?: boolean;
onClick: () => void;
onFilterAdded?: () => void;
ownFocus: boolean;
paddingSize?: 's' | 'm' | 'l' | 'none';
showTooltip?: boolean;
showTopN: boolean;
showLegend?: boolean;
timelineId?: string | null;
title?: string;
value?: string[] | string | null;
}

export const ShowTopNButton: React.FC<Props> = React.memo(
({
className,
Component,
enablePopOver,
field,
flush,
iconSide,
iconType,
isExpandable,
onClick,
onFilterAdded,
ownFocus,
paddingSize,
showLegend,
showTooltip = true,
showTopN,
timelineId,
title,
value,
globalFilters,
}) => {
Expand All @@ -70,31 +86,36 @@ export const ShowTopNButton: React.FC<Props> = React.memo(
? SourcererScopeName.detections
: SourcererScopeName.default;
const { browserFields, indexPattern } = useSourcererScope(activeScope);

const icon = iconType ?? 'visBarVertical';
const side = iconSide ?? 'left';
const buttonTitle = title ?? SHOW_TOP(field);
const basicButton = useMemo(
() =>
Component ? (
<Component
aria-label={SHOW_TOP(field)}
aria-label={buttonTitle}
className={className}
data-test-subj="show-top-field"
icon="visBarVertical"
iconType="visBarVertical"
icon={icon}
iconType={icon}
iconSide={side}
flush={flush}
onClick={onClick}
title={SHOW_TOP(field)}
title={buttonTitle}
>
{SHOW_TOP(field)}
{buttonTitle}
</Component>
) : (
<EuiButtonIcon
aria-label={SHOW_TOP(field)}
aria-label={buttonTitle}
className="securitySolution__hoverActionButton"
data-test-subj="show-top-field"
iconSize="s"
iconType="visBarVertical"
iconType={icon}
onClick={onClick}
/>
),
[Component, field, onClick]
[Component, buttonTitle, className, flush, icon, onClick, side]
);

const button = useMemo(
Expand All @@ -107,7 +128,7 @@ export const ShowTopNButton: React.FC<Props> = React.memo(
field,
value,
})}
content={SHOW_TOP(field)}
content={buttonTitle}
shortcut={SHOW_TOP_N_KEYBOARD_SHORTCUT}
showShortcut={ownFocus}
/>
Expand All @@ -118,7 +139,7 @@ export const ShowTopNButton: React.FC<Props> = React.memo(
) : (
basicButton
),
[basicButton, field, ownFocus, showTooltip, showTopN, value]
[basicButton, buttonTitle, field, ownFocus, showTooltip, showTopN, value]
);

const topNPannel = useMemo(
Expand All @@ -128,15 +149,37 @@ export const ShowTopNButton: React.FC<Props> = React.memo(
field={field}
indexPattern={indexPattern}
onFilterAdded={onFilterAdded}
paddingSize={paddingSize}
showLegend={showLegend}
timelineId={timelineId ?? undefined}
toggleTopN={onClick}
value={value}
globalFilters={globalFilters}
/>
),
[browserFields, field, indexPattern, onClick, onFilterAdded, timelineId, value, globalFilters]
[
browserFields,
field,
indexPattern,
onFilterAdded,
paddingSize,
showLegend,
timelineId,
onClick,
value,
globalFilters,
]
);

if (isExpandable) {
return (
<>
{basicButton}
{showTopN && topNPannel}
</>
);
}

return showTopN ? (
enablePopOver ? (
<EuiPopover
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
* 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 React, { SyntheticEvent } from 'react';
import {
EuiButton,
EuiButtonEmpty,
EuiButtonIcon,
EuiButtonProps,
EuiLink,
EuiLinkProps,
PropsForAnchor,
PropsForButton,
} from '@elastic/eui';
import styled from 'styled-components';

export const LinkButton: React.FC<PropsForButton<EuiButtonProps> | PropsForAnchor<EuiButtonProps>> =
({ children, ...props }) => <EuiButton {...props}>{children}</EuiButton>;

export const LinkAnchor: React.FC<EuiLinkProps> = ({ children, ...props }) => (
<EuiLink {...props}>{children}</EuiLink>
);

export const Comma = styled('span')`
margin-right: 5px;
margin-left: 5px;
&::after {
content: ' ,';
}
`;

Comma.displayName = 'Comma';

const GenericLinkButtonComponent: React.FC<{
children?: React.ReactNode;
/** `Component` is only used with `EuiDataGrid`; the grid keeps a reference to `Component` for show / hide functionality */
Component?: typeof EuiButtonEmpty | typeof EuiButtonIcon;
dataTestSubj?: string;
href: string;
onClick?: (e: SyntheticEvent) => void;
title?: string;
iconType?: string;
}> = ({ children, Component, dataTestSubj, href, onClick, title, iconType = 'expand' }) => {
return Component ? (
<Component
data-test-subj={dataTestSubj}
href={href}
iconType={iconType}
onClick={onClick}
title={title}
>
{title ?? children}
</Component>
) : (
<LinkButton data-test-subj={dataTestSubj} href={href} onClick={onClick}>
{title ?? children}
</LinkButton>
);
};

export const GenericLinkButton = React.memo(GenericLinkButtonComponent);

export const PortContainer = styled.div`
& svg {
position: relative;
top: -1px;
}
`;
Loading

0 comments on commit 56a2e78

Please sign in to comment.