mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[SECURITY SOLUTION] [RAC] bug actions padding (#109029)
* wip * match design for selecting grid view * wip to integrate event rendered view * wip * integration of the event rendered * fix perPage action on Euibasic table * Add bulding block background color to EventRenderedView * styling * remove header * fix types * fix unit tests * use memo for listProps * fix styling + add feature flag * review I * fix merge * change the gutter size * fix bugs * fix alert consumers Co-authored-by: Pablo Neves Machado <pablo.nevesmachado@elastic.co> Co-authored-by: Angela Chuang <yi-chun.chuang@elastic.co> Co-authored-by: Michael Olorunnisola <michael.olorunnisola@elastic.co>
This commit is contained in:
parent
2592e36c15
commit
e4bf6140fb
15 changed files with 50 additions and 47 deletions
|
@ -8,7 +8,6 @@
|
|||
import React, { useCallback, useRef, useState } from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { AlertConsumers } from '@kbn/rule-data-utils';
|
||||
|
||||
import {
|
||||
getCaseDetailsUrl,
|
||||
getCaseDetailsUrlWithCommentId,
|
||||
|
@ -34,7 +33,6 @@ import { SpyRoute } from '../../../common/utils/route/spy_routes';
|
|||
import * as timelineMarkdownPlugin from '../../../common/components/markdown_editor/plugins/timeline';
|
||||
import { CaseDetailsRefreshContext } from '../../../common/components/endpoint/host_isolation/endpoint_host_isolation_cases_context';
|
||||
import { getEndpointDetailsPath } from '../../../management/common/routing';
|
||||
import { EntityType } from '../../../../../timelines/common';
|
||||
|
||||
interface Props {
|
||||
caseId: string;
|
||||
|
@ -55,7 +53,7 @@ export interface CaseProps extends Props {
|
|||
updateCase: (newCase: Case) => void;
|
||||
}
|
||||
|
||||
const ALERT_CONSUMER: AlertConsumers[] = [AlertConsumers.SIEM];
|
||||
const SECURITY_SOLUTION_ALERT_CONSUMERS: AlertConsumers[] = [AlertConsumers.SIEM];
|
||||
|
||||
const TimelineDetailsPanel = ({ alertConsumers }: { alertConsumers?: AlertConsumers[] }) => {
|
||||
const { browserFields, docValueFields } = useSourcererScope(SourcererScopeName.detections);
|
||||
|
@ -65,7 +63,7 @@ const TimelineDetailsPanel = ({ alertConsumers }: { alertConsumers?: AlertConsum
|
|||
alertConsumers={alertConsumers}
|
||||
browserFields={browserFields}
|
||||
docValueFields={docValueFields}
|
||||
entityType={EntityType.ALERTS}
|
||||
entityType="alerts"
|
||||
isFlyoutView
|
||||
timelineId={TimelineId.casePage}
|
||||
/>
|
||||
|
@ -234,7 +232,7 @@ export const CaseView = React.memo(({ caseId, subCaseId, userCanCrud }: Props) =
|
|||
showAlertDetails,
|
||||
subCaseId,
|
||||
timelineIntegration: {
|
||||
alertConsumers: ALERT_CONSUMER,
|
||||
alertConsumers: SECURITY_SOLUTION_ALERT_CONSUMERS,
|
||||
editor_plugins: {
|
||||
parsingPlugin: timelineMarkdownPlugin.parser,
|
||||
processingPluginRenderer: timelineMarkdownPlugin.renderer,
|
||||
|
|
|
@ -20,6 +20,7 @@ import { useKibana } from '../../lib/kibana';
|
|||
import { SourcererScopeName } from '../../store/sourcerer/model';
|
||||
import { useIsExperimentalFeatureEnabled } from '../../hooks/use_experimental_features';
|
||||
import { DEFAULT_COLUMN_MIN_WIDTH } from '../../../timelines/components/timeline/body/constants';
|
||||
import type { EntityType } from '../../../../../timelines/common';
|
||||
|
||||
export interface OwnProps {
|
||||
end: string;
|
||||
|
@ -63,6 +64,7 @@ const defaultAlertsFilters: Filter[] = [
|
|||
interface Props {
|
||||
timelineId: TimelineIdLiteral;
|
||||
endDate: string;
|
||||
entityType?: EntityType;
|
||||
startDate: string;
|
||||
pageFilters?: Filter[];
|
||||
}
|
||||
|
@ -70,6 +72,7 @@ interface Props {
|
|||
const AlertsTableComponent: React.FC<Props> = ({
|
||||
timelineId,
|
||||
endDate,
|
||||
entityType = 'alerts',
|
||||
startDate,
|
||||
pageFilters = [],
|
||||
}) => {
|
||||
|
@ -107,7 +110,7 @@ const AlertsTableComponent: React.FC<Props> = ({
|
|||
defaultModel={alertsDefaultModel}
|
||||
defaultCellActions={defaultCellActions}
|
||||
end={endDate}
|
||||
entityType="alerts"
|
||||
entityType={entityType}
|
||||
id={timelineId}
|
||||
renderCellValue={DefaultCellRenderer}
|
||||
rowRenderers={defaultRowRenderers}
|
||||
|
|
|
@ -25,6 +25,7 @@ const AlertsViewComponent: React.FC<AlertsComponentsProps> = ({
|
|||
timelineId,
|
||||
deleteQuery,
|
||||
endDate,
|
||||
entityType,
|
||||
filterQuery,
|
||||
indexNames,
|
||||
pageFilters,
|
||||
|
@ -74,6 +75,7 @@ const AlertsViewComponent: React.FC<AlertsComponentsProps> = ({
|
|||
<AlertsTable
|
||||
timelineId={timelineId}
|
||||
endDate={endDate}
|
||||
entityType={entityType}
|
||||
startDate={startDate}
|
||||
pageFilters={pageFilters}
|
||||
/>
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
import { Filter } from '../../../../../../../src/plugins/data/public';
|
||||
import type { EntityType } from '../../../../../timelines/common';
|
||||
import { TimelineIdLiteral } from '../../../../common/types/timeline';
|
||||
import { HostsComponentsQueryProps } from '../../../hosts/pages/navigation/types';
|
||||
import { NetworkComponentQueryProps } from '../../../network/pages/navigation/types';
|
||||
|
@ -23,5 +24,6 @@ export interface AlertsComponentsProps
|
|||
stackByOptions?: MatrixHistogramOption[];
|
||||
defaultFilters?: Filter[];
|
||||
defaultStackByOption?: MatrixHistogramOption;
|
||||
entityType?: EntityType;
|
||||
indexNames: string[];
|
||||
}
|
||||
|
|
|
@ -11,7 +11,6 @@ import deepEqual from 'fast-deep-equal';
|
|||
import styled from 'styled-components';
|
||||
|
||||
import { isEmpty } from 'lodash/fp';
|
||||
import { AlertConsumers } from '@kbn/rule-data-utils';
|
||||
import { inputsModel, inputsSelectors, State } from '../../store';
|
||||
import { inputsActions } from '../../store/actions';
|
||||
import { ControlColumnProps, RowRenderer, TimelineId } from '../../../../common/types/timeline';
|
||||
|
@ -24,7 +23,7 @@ import { useGlobalFullScreen } from '../../containers/use_full_screen';
|
|||
import { useIsExperimentalFeatureEnabled } from '../../hooks/use_experimental_features';
|
||||
import { SourcererScopeName } from '../../store/sourcerer/model';
|
||||
import { useSourcererScope } from '../../containers/sourcerer';
|
||||
import { EntityType } from '../../../../../timelines/common';
|
||||
import type { EntityType } from '../../../../../timelines/common';
|
||||
import { TGridCellAction } from '../../../../../timelines/common/types';
|
||||
import { DetailsPanel } from '../../../timelines/components/side_panel';
|
||||
import { CellValueElementProps } from '../../../timelines/components/timeline/cell_rendering';
|
||||
|
@ -69,8 +68,6 @@ export interface OwnProps {
|
|||
|
||||
type Props = OwnProps & PropsFromRedux;
|
||||
|
||||
const alertConsumers: AlertConsumers[] = [AlertConsumers.SIEM];
|
||||
|
||||
/**
|
||||
* The stateful events viewer component is the highest level component that is utilized across the security_solution pages layer where
|
||||
* timeline is used BESIDES the flyout. The flyout makes use of the `EventsViewer` component which is a subcomponent here
|
||||
|
@ -219,9 +216,8 @@ const StatefulEventsViewerComponent: React.FC<Props> = ({
|
|||
</InspectButtonContainer>
|
||||
</FullScreenContainer>
|
||||
<DetailsPanel
|
||||
alertConsumers={alertConsumers}
|
||||
browserFields={browserFields}
|
||||
entityType={EntityType.ALERTS}
|
||||
entityType={entityType}
|
||||
docValueFields={docValueFields}
|
||||
isFlyoutView
|
||||
timelineId={id}
|
||||
|
|
|
@ -52,6 +52,7 @@ export const HostAlertsQueryTabBody = React.memo((alertsProps: AlertsComponentQu
|
|||
|
||||
return (
|
||||
<AlertsView
|
||||
entityType="events"
|
||||
timelineId={TimelineId.hostsPageExternalAlerts}
|
||||
{...rest}
|
||||
pageFilters={hostPageFilters}
|
||||
|
|
|
@ -65,6 +65,7 @@ export const filterNetworkData: Filter[] = [
|
|||
|
||||
export const NetworkAlertsQueryTabBody = React.memo((alertsProps: NetworkComponentQueryProps) => (
|
||||
<AlertsView
|
||||
entityType="events"
|
||||
timelineId={TimelineId.networkPageExternalAlerts}
|
||||
{...alertsProps}
|
||||
pageFilters={filterNetworkData}
|
||||
|
|
|
@ -68,11 +68,13 @@ interface EventDetailsPanelProps {
|
|||
timelineId: string;
|
||||
}
|
||||
|
||||
const SECURITY_SOLUTION_ALERT_CONSUMERS: AlertConsumers[] = [AlertConsumers.SIEM];
|
||||
|
||||
const EventDetailsPanelComponent: React.FC<EventDetailsPanelProps> = ({
|
||||
alertConsumers,
|
||||
alertConsumers = SECURITY_SOLUTION_ALERT_CONSUMERS, // Default to Security Solution so only other applications have to pass this in
|
||||
browserFields,
|
||||
docValueFields,
|
||||
entityType,
|
||||
entityType = 'events', // Default to events so only alerts have to pass entityType in
|
||||
expandedEvent,
|
||||
handleOnEventClosed,
|
||||
isFlyoutView,
|
||||
|
|
|
@ -13,7 +13,6 @@ import {
|
|||
EuiFlyoutFooter,
|
||||
EuiBadge,
|
||||
} from '@elastic/eui';
|
||||
import { AlertConsumers } from '@kbn/rule-data-utils';
|
||||
import { isEmpty } from 'lodash/fp';
|
||||
import React, { useEffect, useCallback } from 'react';
|
||||
import styled from 'styled-components';
|
||||
|
@ -152,8 +151,6 @@ export type Props = OwnProps & PropsFromRedux;
|
|||
|
||||
const NO_SORTING: Sort[] = [];
|
||||
|
||||
const alertConsumers: AlertConsumers[] = [AlertConsumers.SIEM];
|
||||
|
||||
export const EqlTabContentComponent: React.FC<Props> = ({
|
||||
activeTab,
|
||||
columns,
|
||||
|
@ -349,7 +346,6 @@ export const EqlTabContentComponent: React.FC<Props> = ({
|
|||
<VerticalRule />
|
||||
<ScrollableFlexItem grow={1}>
|
||||
<DetailsPanel
|
||||
alertConsumers={alertConsumers}
|
||||
browserFields={browserFields}
|
||||
docValueFields={docValueFields}
|
||||
tabType={TimelineTabs.eql}
|
||||
|
|
|
@ -16,7 +16,6 @@ import {
|
|||
EuiPanel,
|
||||
EuiHorizontalRule,
|
||||
} from '@elastic/eui';
|
||||
import { AlertConsumers } from '@kbn/rule-data-utils';
|
||||
|
||||
import React, { Fragment, useCallback, useMemo, useState } from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
@ -71,8 +70,6 @@ const Username = styled(EuiText)`
|
|||
font-weight: bold;
|
||||
`;
|
||||
|
||||
const alertConsumers: AlertConsumers[] = [AlertConsumers.SIEM];
|
||||
|
||||
interface UsernameWithAvatar {
|
||||
username: string;
|
||||
}
|
||||
|
@ -185,7 +182,6 @@ const NotesTabContentComponent: React.FC<NotesTabContentProps> = ({ timelineId }
|
|||
() =>
|
||||
expandedDetail[TimelineTabs.notes]?.panelView ? (
|
||||
<DetailsPanel
|
||||
alertConsumers={alertConsumers}
|
||||
browserFields={browserFields}
|
||||
docValueFields={docValueFields}
|
||||
handleOnPanelClosed={handleOnPanelClosed}
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
*/
|
||||
|
||||
import { EuiFlexGroup, EuiFlexItem, EuiFlyoutBody, EuiFlyoutFooter } from '@elastic/eui';
|
||||
import { AlertConsumers } from '@kbn/rule-data-utils';
|
||||
import { isEmpty } from 'lodash/fp';
|
||||
import React, { useMemo, useCallback } from 'react';
|
||||
import styled from 'styled-components';
|
||||
|
@ -89,8 +88,6 @@ const VerticalRule = styled.div`
|
|||
|
||||
VerticalRule.displayName = 'VerticalRule';
|
||||
|
||||
const alertConsumers: AlertConsumers[] = [AlertConsumers.SIEM];
|
||||
|
||||
interface OwnProps {
|
||||
renderCellValue: (props: CellValueElementProps) => React.ReactNode;
|
||||
rowRenderers: RowRenderer[];
|
||||
|
@ -269,7 +266,6 @@ export const PinnedTabContentComponent: React.FC<Props> = ({
|
|||
<VerticalRule />
|
||||
<ScrollableFlexItem grow={1}>
|
||||
<DetailsPanel
|
||||
alertConsumers={alertConsumers}
|
||||
browserFields={browserFields}
|
||||
docValueFields={docValueFields}
|
||||
handleOnPanelClosed={handleOnPanelClosed}
|
||||
|
|
|
@ -13,7 +13,6 @@ import {
|
|||
EuiFlyoutFooter,
|
||||
EuiBadge,
|
||||
} from '@elastic/eui';
|
||||
import { AlertConsumers } from '@kbn/rule-data-utils';
|
||||
import { isEmpty } from 'lodash/fp';
|
||||
import React, { useState, useMemo, useEffect, useCallback } from 'react';
|
||||
import styled from 'styled-components';
|
||||
|
@ -136,8 +135,6 @@ const EventsCountBadge = styled(EuiBadge)`
|
|||
margin-left: ${({ theme }) => theme.eui.paddingSizes.s};
|
||||
`;
|
||||
|
||||
const alertConsumers: AlertConsumers[] = [AlertConsumers.SIEM];
|
||||
|
||||
const isTimerangeSame = (prevProps: Props, nextProps: Props) =>
|
||||
prevProps.end === nextProps.end &&
|
||||
prevProps.start === nextProps.start &&
|
||||
|
@ -417,7 +414,6 @@ export const QueryTabContentComponent: React.FC<Props> = ({
|
|||
<VerticalRule />
|
||||
<ScrollableFlexItem grow={1}>
|
||||
<DetailsPanel
|
||||
alertConsumers={alertConsumers}
|
||||
browserFields={browserFields}
|
||||
docValueFields={docValueFields}
|
||||
handleOnPanelClosed={handleOnPanelClosed}
|
||||
|
|
|
@ -41,6 +41,14 @@ const EventRenderedFlexItem = styled(EuiFlexItem)`
|
|||
}
|
||||
`;
|
||||
|
||||
const ActionsContainer = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
div div:first-child div.siemEventsTable__tdContent {
|
||||
margin-left: ${({ theme }) => theme.eui.paddingSizes.m};
|
||||
}
|
||||
`;
|
||||
|
||||
// Fix typing issue with EuiBasicTable and styled
|
||||
type BasicTableType = ComponentType<EuiBasicTableProps<TimelineItem>>;
|
||||
|
||||
|
@ -113,25 +121,31 @@ const EventRenderedViewComponent = ({
|
|||
name: ActionTitle,
|
||||
truncateText: false,
|
||||
hideForMobile: false,
|
||||
// eslint-disable-next-line react/display-name
|
||||
render: (name: unknown, item: unknown) => {
|
||||
const alertId = get(item, '_id');
|
||||
const rowIndex = events.findIndex((evt) => evt._id === alertId);
|
||||
return leadingControlColumns.length > 0
|
||||
? leadingControlColumns.map((action) => {
|
||||
const getActions = action.rowCellRender as (
|
||||
props: EuiDataGridCellValueElementProps
|
||||
) => React.ReactNode;
|
||||
return getActions({
|
||||
columnId: 'actions',
|
||||
isDetails: false,
|
||||
isExpandable: false,
|
||||
isExpanded: false,
|
||||
rowIndex,
|
||||
setCellProps: () => null,
|
||||
});
|
||||
})
|
||||
: null;
|
||||
return (
|
||||
<ActionsContainer>
|
||||
{leadingControlColumns.length > 0
|
||||
? leadingControlColumns.map((action) => {
|
||||
const getActions = action.rowCellRender as (
|
||||
props: EuiDataGridCellValueElementProps
|
||||
) => React.ReactNode;
|
||||
return getActions({
|
||||
columnId: 'actions',
|
||||
isDetails: false,
|
||||
isExpandable: false,
|
||||
isExpanded: false,
|
||||
rowIndex,
|
||||
setCellProps: () => null,
|
||||
});
|
||||
})
|
||||
: null}
|
||||
</ActionsContainer>
|
||||
);
|
||||
},
|
||||
width: '120px',
|
||||
},
|
||||
{
|
||||
field: 'ecs.@timestamp',
|
||||
|
|
|
@ -142,7 +142,6 @@ const SummaryViewSelectorComponent = ({ viewSelected, onViewChange }: SummaryVie
|
|||
>
|
||||
<ContainerEuiSelectable>
|
||||
<EuiSelectable
|
||||
aria-label="Basic example"
|
||||
options={options}
|
||||
onChange={onChangeSelectable}
|
||||
renderOption={renderOption}
|
||||
|
|
|
@ -232,6 +232,7 @@ const TGridIntegratedComponent: React.FC<TGridIntegratedProps> = ({
|
|||
loading,
|
||||
{ events, loadPage, pageInfo, refetch, totalCount = 0, inspect },
|
||||
] = useTimelineEvents({
|
||||
// We rely on entityType to determine Events vs Alerts
|
||||
alertConsumers: SECURITY_ALERTS_CONSUMERS,
|
||||
docValueFields,
|
||||
entityType,
|
||||
|
@ -302,7 +303,7 @@ const TGridIntegratedComponent: React.FC<TGridIntegratedProps> = ({
|
|||
<UpdatedFlexItem grow={false} show={!loading}>
|
||||
{!resolverIsShowing(graphEventId) && additionalFilters}
|
||||
</UpdatedFlexItem>
|
||||
{tGridEventRenderedViewEnabled && (
|
||||
{tGridEventRenderedViewEnabled && entityType === 'alerts' && (
|
||||
<UpdatedFlexItem grow={false} show={!loading}>
|
||||
<SummaryViewSelector viewSelected={tableView} onViewChange={setTableView} />
|
||||
</UpdatedFlexItem>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue