Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Comment thread
jonwalstedt marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { ACTION_INVESTIGATE_IN_TIMELINE } from '../../../../detections/component
import { getDataProvider } from '../../../../common/components/event_details/use_action_cell_data_provider';
import { AlertPreviewButton } from '../../../shared/components/alert_preview_button';
import { PreviewLink } from '../../../shared/components/preview_link';
import { FlyoutMissingAlertsPrivilege } from '../../../shared/components/flyout_missing_alerts_privilege';
import { FlyoutMissingAlertsPrivilege } from '../../../../flyout_v2/document/components/flyout_missing_alerts_privilege';

export const TIMESTAMP_DATE_FORMAT = 'MMM D, YYYY @ HH:mm:ss.SSS';
const dataProviderLimit = 5;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { DEFAULT_ALERTS_INDEX } from '../../../../common/constants';
import { useEventDetails } from './hooks/use_event_details';
import { FlyoutError } from '../../shared/components/flyout_error';
import { FlyoutLoading } from '../../shared/components/flyout_loading';
import { FlyoutMissingAlertsPrivilege } from '../../shared/components/flyout_missing_alerts_privilege';
import { FlyoutMissingAlertsPrivilege } from '../../../flyout_v2/document/components/flyout_missing_alerts_privilege';
import type { SearchHit } from '../../../../common/search_strategy';
import { useBasicDataFromDetailsData } from './hooks/use_basic_data_from_details_data';
import type { DocumentDetailsProps } from './types';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ export const FLYOUT_LINK_TEST_ID = `${PREFIX}Link` as const;

export const FLYOUT_ERROR_TEST_ID = `${PREFIX}Error` as const;
export const FLYOUT_LOADING_TEST_ID = `${PREFIX}Loading` as const;
export const FLYOUT_MISSING_ALERTS_PRIVILEGE_TEST_ID = `${PREFIX}MissingAlertsPrivilege` as const;

/* Header Navigation */

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,14 @@
* 2.0.
*/

import React from 'react';

import React, { memo } from 'react';
import type { DocLinks } from '@kbn/doc-links';
import { i18n } from '@kbn/i18n';
import { FLYOUT_MISSING_ALERTS_PRIVILEGE_TEST_ID } from './test_ids';
import { NoPrivileges } from '../../../common/components/no_privileges';

const alertDetailsPageName = i18n.translate(
'xpack.securitySolution.flyout.shared.alertDetailsPageName',
'xpack.securitySolution.flyout.document.alertDetailsPageName',
{
defaultMessage: 'Alert details',
}
Expand All @@ -23,12 +22,12 @@ const docLinkSelector = (links: DocLinks) => links.siem.detectionsReq;
/**
* Shown in the alert flyout when the user lacks the Alerts feature (securitySolutionAlertsV1) read privilege
*/
export const FlyoutMissingAlertsPrivilege: React.FC = () => {
return (
<NoPrivileges
pageName={alertDetailsPageName}
docLinkSelector={docLinkSelector}
data-test-subj={FLYOUT_MISSING_ALERTS_PRIVILEGE_TEST_ID}
/>
);
};
export const FlyoutMissingAlertsPrivilege = memo(() => (
<NoPrivileges
pageName={alertDetailsPageName}
docLinkSelector={docLinkSelector}
data-test-subj={FLYOUT_MISSING_ALERTS_PRIVILEGE_TEST_ID}
/>
));

FlyoutMissingAlertsPrivilege.displayName = 'FlyoutMissingAlertsPrivilege';
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

import { PREFIX } from '../../../flyout/shared/test_ids';

export const FLYOUT_MISSING_ALERTS_PRIVILEGE_TEST_ID = `${PREFIX}MissingAlertsPrivilege` as const;

/* Header */

export const HEADER_TITLE_TEST_ID = `${PREFIX}AlertTitle` as const;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { EVENT_KIND } from '@kbn/rule-data-utils';
import type { CellActionRenderer } from '../shared/components/cell_actions';
import { useAlertsPrivileges } from '../../detections/containers/detection_engine/alerts/use_alerts_privileges';
import { FlyoutLoading } from '../../flyout/shared/components/flyout_loading';
import { FlyoutMissingAlertsPrivilege } from '../../flyout/shared/components/flyout_missing_alerts_privilege';
import { FlyoutMissingAlertsPrivilege } from './components/flyout_missing_alerts_privilege';
import { useDataView } from '../../data_view_manager/hooks/use_data_view';
import { PageScope } from '../../data_view_manager/constants';
import { EventKind } from './constants/event_kinds';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,15 @@
import React from 'react';
import { render } from '@testing-library/react';
import type { DataTableRecord } from '@kbn/discover-utils';
import { useAlertsPrivileges } from '../../../detections/containers/detection_engine/alerts/use_alerts_privileges';
import { OverviewTab } from './overview_tab';
import { TestProviders } from '../../../common/mock';
import { useAlertsPrivileges } from '../../detections/containers/detection_engine/alerts/use_alerts_privileges';
import { DocumentFlyout } from '.';
import { TestProviders } from '../../common/mock';

jest.mock('../../../detections/containers/detection_engine/alerts/use_alerts_privileges');
jest.mock('../../detections/containers/detection_engine/alerts/use_alerts_privileges');
jest.mock('./header', () => ({ Header: () => <div data-test-subj="mock-header" /> }));
jest.mock('./tabs/overview_tab', () => ({
OverviewTab: () => <div data-test-subj="mock-overview-tab" />,
}));

const createAlertHit = (): DataTableRecord =>
({
Expand All @@ -22,18 +26,17 @@ const createAlertHit = (): DataTableRecord =>
isAnchor: false,
} as DataTableRecord);

describe('<OverviewTab />', () => {
describe('<DocumentFlyout />', () => {
beforeEach(() => {
jest.clearAllMocks();
});

it('renders FlyoutMissingAlertsPrivilege when document is an alert and user lacks alerts read privilege', () => {
(useAlertsPrivileges as jest.Mock).mockReturnValue({ hasAlertsRead: false, loading: false });
const alertHit = createAlertHit();

const { getByTestId } = render(
<TestProviders>
<OverviewTab hit={alertHit} renderCellActions={jest.fn()} />
<DocumentFlyout hit={createAlertHit()} renderCellActions={jest.fn()} />
</TestProviders>
);

Expand All @@ -42,11 +45,10 @@ describe('<OverviewTab />', () => {

it('renders loading while alerts privileges are loading for an alert', () => {
(useAlertsPrivileges as jest.Mock).mockReturnValue({ hasAlertsRead: false, loading: true });
const alertHit = createAlertHit();

const { getByTestId, queryByTestId } = render(
<TestProviders>
<OverviewTab hit={alertHit} renderCellActions={jest.fn()} />
<DocumentFlyout hit={createAlertHit()} renderCellActions={jest.fn()} />
</TestProviders>
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,16 @@
* 2.0.
*/

import type { FC } from 'react';
import React, { memo } from 'react';
import React, { memo, useMemo } from 'react';
import { EuiFlyoutBody, EuiFlyoutHeader } from '@elastic/eui';
import type { DataTableRecord } from '@kbn/discover-utils';
import { getFieldValue } from '@kbn/discover-utils';
import { EVENT_KIND } from '@kbn/rule-data-utils';
import type { CellActionRenderer } from '../shared/components/cell_actions';
import { useAlertsPrivileges } from '../../detections/containers/detection_engine/alerts/use_alerts_privileges';
import { FlyoutLoading } from '../../flyout/shared/components/flyout_loading';
import { FlyoutMissingAlertsPrivilege } from './components/flyout_missing_alerts_privilege';
import { EventKind } from './constants/event_kinds';
import { Header } from './header';
import { OverviewTab } from './tabs/overview_tab';

Expand All @@ -27,7 +32,23 @@ export interface DocumentFlyoutProps {
/**
* Content for the document flyout, combining the header and overview tab.
*/
export const DocumentFlyout: FC<DocumentFlyoutProps> = memo(({ hit, renderCellActions }) => {
export const DocumentFlyout = memo(({ hit, renderCellActions }: DocumentFlyoutProps) => {
const isAlert = useMemo(
() => (getFieldValue(hit, EVENT_KIND) as string) === EventKind.signal,
[hit]
);

const { hasAlertsRead, loading } = useAlertsPrivileges();
const missingAlertsPrivilege = !loading && !hasAlertsRead && isAlert;

if (isAlert && loading) {
return <FlyoutLoading data-test-subj="document-overview-loading" />;
}

if (missingAlertsPrivilege) {
return <FlyoutMissingAlertsPrivilege />;
}

return (
<>
<EuiFlyoutHeader>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,14 @@
* 2.0.
*/

import React, { memo, useMemo } from 'react';
import React, { memo } from 'react';
import { EuiHorizontalRule } from '@elastic/eui';
import type { DataTableRecord } from '@kbn/discover-utils';
import { getFieldValue } from '@kbn/discover-utils';
import { EVENT_KIND } from '@kbn/rule-data-utils';
import type { CellActionRenderer } from '../../shared/components/cell_actions';
import { AboutSection } from '../components/about_section';
import { InsightsSection } from '../components/insights_section';
import { InvestigationSection } from '../components/investigation_section';
import { VisualizationsSection } from '../components/visualizations_section';
import { FlyoutMissingAlertsPrivilege } from '../../../flyout/shared/components/flyout_missing_alerts_privilege';
import { FlyoutLoading } from '../../../flyout/shared/components/flyout_loading';
import { useAlertsPrivileges } from '../../../detections/containers/detection_engine/alerts/use_alerts_privileges';
import { EventKind } from '../constants/event_kinds';

export interface OverviewTabProps {
/**
Expand All @@ -34,34 +28,16 @@ export interface OverviewTabProps {
/**
* Overview view displayed in the document details expandable flyout right section
*/
export const OverviewTab = memo(({ hit, renderCellActions }: OverviewTabProps) => {
const isAlert = useMemo(
() => (getFieldValue(hit, EVENT_KIND) as string) === EventKind.signal,
[hit]
);

const { hasAlertsRead, loading } = useAlertsPrivileges();
const missingAlertsPrivilege = !loading && !hasAlertsRead && isAlert;

if (isAlert && loading) {
return <FlyoutLoading data-test-subj="document-overview-loading" />;
}

if (missingAlertsPrivilege) {
return <FlyoutMissingAlertsPrivilege />;
}

return (
<>
<AboutSection hit={hit} />
<EuiHorizontalRule margin="m" />
<InvestigationSection hit={hit} renderCellActions={renderCellActions} />
<EuiHorizontalRule margin="m" />
<VisualizationsSection hit={hit} renderCellActions={renderCellActions} />
<EuiHorizontalRule margin="m" />
<InsightsSection hit={hit} />
</>
);
});
export const OverviewTab = memo(({ hit, renderCellActions }: OverviewTabProps) => (
<>
<AboutSection hit={hit} />
<EuiHorizontalRule margin="m" />
<InvestigationSection hit={hit} renderCellActions={renderCellActions} />
<EuiHorizontalRule margin="m" />
<VisualizationsSection hit={hit} renderCellActions={renderCellActions} />
<EuiHorizontalRule margin="m" />
<InsightsSection hit={hit} />
</>
));

OverviewTab.displayName = 'OverviewTab';
Loading