Skip to content

Commit

Permalink
[Security solution] Guided onboarding, alerts & cases (#143598)
Browse files Browse the repository at this point in the history
  • Loading branch information
stephmilovic authored Oct 27, 2022
1 parent 4bd8693 commit fd1ad82
Show file tree
Hide file tree
Showing 31 changed files with 1,048 additions and 552 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,24 @@ describe('CreateCaseFlyout', () => {
});
expect(onClose).toBeCalled();
});

it('renders headerContent when passed', async () => {
const headerContent = <p data-test-subj="testing123" />;
const { getByTestId } = mockedContext.render(
<CreateCaseFlyout {...defaultProps} headerContent={headerContent} />
);

await act(async () => {
expect(getByTestId('testing123')).toBeTruthy();
expect(getByTestId('create-case-flyout-header').children.length).toEqual(2);
});
});

it('does not render headerContent when undefined', async () => {
const { getByTestId } = mockedContext.render(<CreateCaseFlyout {...defaultProps} />);

await act(async () => {
expect(getByTestId('create-case-flyout-header').children.length).toEqual(1);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export interface CreateCaseFlyoutProps {
onClose?: () => void;
onSuccess?: (theCase: Case) => Promise<void>;
attachments?: CaseAttachmentsWithoutOwner;
headerContent?: React.ReactNode;
}

const StyledFlyout = styled(EuiFlyout)`
Expand Down Expand Up @@ -71,9 +72,10 @@ const FormWrapper = styled.div`
`;

export const CreateCaseFlyout = React.memo<CreateCaseFlyoutProps>(
({ afterCaseCreated, onClose, onSuccess, attachments }) => {
({ afterCaseCreated, onClose, onSuccess, attachments, headerContent }) => {
const handleCancel = onClose || function () {};
const handleOnSuccess = onSuccess || async function () {};

return (
<QueryClientProvider client={casesQueryClient}>
<GlobalStyle />
Expand All @@ -83,10 +85,11 @@ export const CreateCaseFlyout = React.memo<CreateCaseFlyoutProps>(
// maskProps is needed in order to apply the z-index to the parent overlay element, not to the flyout only
maskProps={{ className: maskOverlayClassName }}
>
<EuiFlyoutHeader hasBorder>
<EuiFlyoutHeader data-test-subj="create-case-flyout-header" hasBorder>
<EuiTitle size="m">
<h2>{i18n.CREATE_CASE_TITLE}</h2>
</EuiTitle>
{headerContent && headerContent}
</EuiFlyoutHeader>
<StyledEuiFlyoutBody>
<FormWrapper>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* 2.0.
*/

import type React from 'react';
import { useCallback } from 'react';
import type { CaseAttachmentsWithoutOwner } from '../../../types';
import { useCasesToast } from '../../../common/use_cases_toast';
Expand All @@ -29,12 +30,16 @@ export const useCasesAddToNewCaseFlyout = (props: AddToNewCaseFlyoutProps = {})
}, [dispatch]);

const openFlyout = useCallback(
({ attachments }: { attachments?: CaseAttachmentsWithoutOwner } = {}) => {
({
attachments,
headerContent,
}: { attachments?: CaseAttachmentsWithoutOwner; headerContent?: React.ReactNode } = {}) => {
dispatch({
type: CasesContextStoreActionsList.OPEN_CREATE_CASE_FLYOUT,
payload: {
...props,
attachments,
headerContent,
onClose: () => {
closeFlyout();
if (props.onClose) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@ export const allowedExperimentalValues = Object.freeze({
* Enables endpoint package level rbac
*/
endpointRbacEnabled: false,

/**
* Enables the Guided Onboarding tour in security
*/
guidedOnboarding: false,
});

type ExperimentalConfigKeys = Array<keyof ExperimentalFeatures>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

import { login, visit } from '../../tasks/login';
import { completeTour, goToNextStep, skipTour } from '../../tasks/guided_onboarding';
import { SECURITY_TOUR_ACTIVE_KEY } from '../../../public/common/components/guided_onboarding';
import { OVERVIEW_URL } from '../../urls/navigation';
import {
WELCOME_STEP,
Expand All @@ -21,11 +20,11 @@ before(() => {
login();
});

describe('Guided onboarding tour', () => {
// need to redo these tests for new implementation
describe.skip('Guided onboarding tour', () => {
describe('Tour is enabled', () => {
beforeEach(() => {
visit(OVERVIEW_URL);
window.localStorage.setItem(SECURITY_TOUR_ACTIVE_KEY, 'true');
});

it('can be completed', () => {
Expand Down
1 change: 1 addition & 0 deletions x-pack/plugins/security_solution/kibana.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"embeddable",
"eventLog",
"features",
"guidedOnboarding",
"inspector",
"kubernetesSecurity",
"lens",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
EuiHeaderSection,
EuiHeaderSectionItem,
} from '@elastic/eui';
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import React, { useEffect, useMemo, useState } from 'react';
import { useLocation } from 'react-router-dom';
import { createHtmlPortalNode, InPortal, OutPortal } from 'react-reverse-portal';
import { i18n } from '@kbn/i18n';
Expand All @@ -28,7 +28,6 @@ import { timelineDefaults } from '../../../timelines/store/timeline/defaults';
import { timelineSelectors } from '../../../timelines/store/timeline';
import { useShallowEqualSelector } from '../../../common/hooks/use_selector';
import { getScopeFromPath, showSourcererByPath } from '../../../common/containers/sourcerer';
import { useTourContext } from '../../../common/components/guided_onboarding';

const BUTTON_ADD_DATA = i18n.translate('xpack.securitySolution.globalHeader.buttonAddData', {
defaultMessage: 'Add integrations',
Expand Down Expand Up @@ -83,12 +82,6 @@ export const GlobalHeader = React.memo(
};
}, [portalNode, setHeaderActionMenu, theme.theme$]);

const { isTourShown, endTour } = useTourContext();
const closeOnboardingTourIfShown = useCallback(() => {
if (isTourShown) {
endTour();
}
}, [isTourShown, endTour]);
return (
<InPortal node={portalNode}>
<EuiHeaderSection side="right">
Expand All @@ -105,7 +98,6 @@ export const GlobalHeader = React.memo(
data-test-subj="add-data"
href={href}
iconType="indexOpen"
onClick={closeOnboardingTourIfShown}
>
{BUTTON_ADD_DATA}
</EuiHeaderLink>
Expand Down
2 changes: 1 addition & 1 deletion x-pack/plugins/security_solution/public/app/home/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { useUpgradeSecurityPackages } from '../../common/hooks/use_upgrade_secur
import { GlobalHeader } from './global_header';
import { ConsoleManager } from '../../management/components/console/components/console_manager';

import { TourContextProvider } from '../../common/components/guided_onboarding';
import { TourContextProvider } from '../../common/components/guided_onboarding_tour';

import { useUrlState } from '../../common/hooks/use_url_state';
import { useUpdateBrowserTitle } from '../../common/hooks/use_update_browser_title';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,22 @@

import type { EuiTabbedContentTab } from '@elastic/eui';
import {
EuiHorizontalRule,
EuiTabbedContent,
EuiSpacer,
EuiLoadingContent,
EuiNotificationBadge,
EuiFlexGroup,
EuiFlexItem,
EuiHorizontalRule,
EuiLoadingContent,
EuiLoadingSpinner,
EuiNotificationBadge,
EuiSpacer,
EuiTabbedContent,
} from '@elastic/eui';
import React, { useCallback, useMemo, useState } from 'react';
import styled from 'styled-components';
import { isEmpty } from 'lodash';

import { GuidedOnboardingTourStep } from '../guided_onboarding_tour/tour_step';
import { isDetectionsAlertsTable } from '../top_n/helpers';
import { getTourAnchor, SecurityStepId } from '../guided_onboarding_tour/tour_config';
import type { AlertRawEventData } from './osquery_tab';
import { useOsqueryTab } from './osquery_tab';
import { EventFieldsBrowser } from './event_fields_browser';
Expand Down Expand Up @@ -179,6 +182,8 @@ const EventDetailsComponent: React.FC<Props> = ({
[detailsEcsData]
);

const isTourAnchor = useMemo(() => isDetectionsAlertsTable(scopeId), [scopeId]);

const showThreatSummary = useMemo(() => {
const hasEnrichments = enrichmentCount > 0;
const hasRiskInfoWithLicense = isLicenseValid && (hostRisk || userRisk);
Expand Down Expand Up @@ -401,14 +406,26 @@ const EventDetailsComponent: React.FC<Props> = ({
[tabs, selectedTabId]
);

const tourAnchor = useMemo(
() => (isTourAnchor ? { 'tour-step': getTourAnchor(3, SecurityStepId.alertsCases) } : {}),
[isTourAnchor]
);

return (
<StyledEuiTabbedContent
data-test-subj="eventDetails"
tabs={tabs}
selectedTab={selectedTab}
onTabClick={handleTabClick}
key="event-summary-tabs"
/>
<GuidedOnboardingTourStep
isTourAnchor={isTourAnchor}
step={3}
stepId={SecurityStepId.alertsCases}
>
<StyledEuiTabbedContent
{...tourAnchor}
data-test-subj="eventDetails"
tabs={tabs}
selectedTab={selectedTab}
onTabClick={handleTabClick}
key="event-summary-tabs"
/>
</GuidedOnboardingTourStep>
);
};
EventDetailsComponent.displayName = 'EventDetailsComponent';
Expand Down

This file was deleted.

Loading

0 comments on commit fd1ad82

Please sign in to comment.