Skip to content

Commit

Permalink
[Security Solution] [Sourcerer] Bug fixes for hanging load and modifi…
Browse files Browse the repository at this point in the history
…ed label (elastic#120814)
  • Loading branch information
stephmilovic authored and TinLe committed Dec 22, 2021
1 parent 94aaa8d commit a9591f5
Show file tree
Hide file tree
Showing 10 changed files with 307 additions and 119 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,33 +6,28 @@
*/

import {
EuiButton,
EuiCallOut,
EuiCheckbox,
EuiComboBox,
EuiFlexGroup,
EuiFlexItem,
EuiForm,
EuiOutsideClickDetector,
EuiPopover,
EuiPopoverTitle,
EuiSpacer,
EuiSuperSelect,
} from '@elastic/eui';
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import React, { ChangeEventHandler, useCallback, useEffect, useMemo, useState } from 'react';
import { useDispatch } from 'react-redux';

import * as i18n from './translations';
import { sourcererActions, sourcererModel, sourcererSelectors } from '../../store/sourcerer';
import { useDeepEqualSelector } from '../../hooks/use_selector';
import { SourcererScopeName } from '../../store/sourcerer/model';
import { usePickIndexPatterns } from './use_pick_index_patterns';
import { FormRow, PopoverContent, ResetButton, StyledButton, StyledFormRow } from './helpers';
import { FormRow, PopoverContent, StyledButton, StyledFormRow } from './helpers';
import { TemporarySourcerer } from './temporary';
import { UpdateDefaultDataViewModal } from './update_default_data_view_modal';
import { useSourcererDataView } from '../../containers/sourcerer';
import { useUpdateDataView } from './use_update_data_view';
import { Trigger } from './trigger';
import { AlertsCheckbox, SaveButtons, SourcererCallout } from './sub_components';

interface SourcererComponentProps {
scope: sourcererModel.SourcererScopeName;
Expand Down Expand Up @@ -91,11 +86,12 @@ export const Sourcerer = React.memo<SourcererComponentProps>(({ scope: scopeId }
kibanaDataViews,
missingPatterns,
scopeId,
selectedDataViewId,
selectedPatterns,
signalIndexName,
});

const onCheckboxChanged = useCallback(
const onCheckboxChanged: ChangeEventHandler<HTMLInputElement> = useCallback(
(e) => {
setIsOnlyDetectionAlertsChecked(e.target.checked);
setDataViewId(defaultDataView.id);
Expand Down Expand Up @@ -251,49 +247,35 @@ export const Sourcerer = React.memo<SourcererComponentProps>(({ scope: scopeId }
<EuiPopoverTitle data-test-subj="sourcerer-title">
<>{i18n.SELECT_DATA_VIEW}</>
</EuiPopoverTitle>
{isOnlyDetectionAlerts && (
<EuiCallOut
data-test-subj="sourcerer-callout"
iconType="iInCircle"
size="s"
title={isTimelineSourcerer ? i18n.CALL_OUT_TIMELINE_TITLE : i18n.CALL_OUT_TITLE}
/>
)}
<SourcererCallout
isOnlyDetectionAlerts={isOnlyDetectionAlerts}
title={isTimelineSourcerer ? i18n.CALL_OUT_TIMELINE_TITLE : i18n.CALL_OUT_TITLE}
/>
<EuiSpacer size="s" />
{isModified === 'deprecated' || isModified === 'missingPatterns' ? (
<>
<TemporarySourcerer
activePatterns={activePatterns}
indicesExist={indicesExist}
isModified={isModified}
missingPatterns={missingPatterns}
onClick={resetDataSources}
onClose={setPopoverIsOpenCb}
onUpdate={isModified === 'deprecated' ? onUpdateDeprecated : onUpdateDataView}
selectedPatterns={selectedPatterns}
/>
<UpdateDefaultDataViewModal
isShowing={isShowingUpdateModal}
missingPatterns={missingPatterns}
onClose={() => setIsShowingUpdateModal(false)}
onContinue={onContinueUpdateDeprecated}
onUpdate={onUpdateDataView}
/>
</>
{(dataViewId === null && isModified === 'deprecated') ||
isModified === 'missingPatterns' ? (
<TemporarySourcerer
activePatterns={activePatterns}
indicesExist={indicesExist}
isModified={isModified}
isShowingUpdateModal={isShowingUpdateModal}
missingPatterns={missingPatterns}
onContinueWithoutUpdate={onContinueUpdateDeprecated}
onDismiss={setPopoverIsOpenCb}
onDismissModal={() => setIsShowingUpdateModal(false)}
onReset={resetDataSources}
onUpdateStepOne={isModified === 'deprecated' ? onUpdateDeprecated : onUpdateDataView}
onUpdateStepTwo={onUpdateDataView}
selectedPatterns={selectedPatterns}
/>
) : (
<EuiForm component="form">
<>
{isTimelineSourcerer && (
<StyledFormRow>
<EuiCheckbox
checked={isOnlyDetectionAlertsChecked}
data-test-subj="sourcerer-alert-only-checkbox"
id="sourcerer-alert-only-checkbox"
label={i18n.ALERTS_CHECKBOX_LABEL}
onChange={onCheckboxChanged}
/>
</StyledFormRow>
)}
<AlertsCheckbox
isShow={isTimelineSourcerer}
checked={isOnlyDetectionAlertsChecked}
onChange={onCheckboxChanged}
/>
{dataViewId && (
<StyledFormRow label={i18n.INDEX_PATTERNS_CHOOSE_DATA_VIEW_LABEL}>
<EuiSuperSelect
Expand Down Expand Up @@ -335,35 +317,12 @@ export const Sourcerer = React.memo<SourcererComponentProps>(({ scope: scopeId }
/>
</FormRow>

{!isDetectionsSourcerer && (
<StyledFormRow>
<EuiFlexGroup alignItems="center" justifyContent="flexEnd">
<EuiFlexItem grow={false}>
<ResetButton
aria-label={i18n.INDEX_PATTERNS_RESET}
data-test-subj="sourcerer-reset"
flush="left"
onClick={resetDataSources}
title={i18n.INDEX_PATTERNS_RESET}
>
{i18n.INDEX_PATTERNS_RESET}
</ResetButton>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiButton
onClick={handleSaveIndices}
disabled={selectedOptions.length === 0}
data-test-subj="sourcerer-save"
fill
fullWidth
size="s"
>
{i18n.SAVE_INDEX_PATTERNS}
</EuiButton>
</EuiFlexItem>
</EuiFlexGroup>
</StyledFormRow>
)}
<SaveButtons
disableSave={selectedOptions.length === 0}
isShow={!isDetectionsSourcerer}
onReset={resetDataSources}
onSave={handleSaveIndices}
/>
</>
<EuiSpacer size="s" />
</EuiForm>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/*
* 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, { ChangeEventHandler } from 'react';
import { EuiButton, EuiCallOut, EuiCheckbox, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
import { ResetButton, StyledFormRow } from './helpers';
import * as i18n from './translations';

interface SourcererCalloutProps {
isOnlyDetectionAlerts: boolean;
title: string;
}

export const SourcererCallout = React.memo<SourcererCalloutProps>(
({ isOnlyDetectionAlerts, title }) =>
isOnlyDetectionAlerts ? (
<EuiCallOut data-test-subj="sourcerer-callout" iconType="iInCircle" size="s" title={title} />
) : null
);

SourcererCallout.displayName = 'SourcererCallout';

interface AlertsCheckboxProps {
checked: boolean;
isShow: boolean;
onChange: ChangeEventHandler<HTMLInputElement>;
}

export const AlertsCheckbox = React.memo<AlertsCheckboxProps>(({ onChange, checked, isShow }) =>
isShow ? (
<StyledFormRow>
<EuiCheckbox
checked={checked}
data-test-subj="sourcerer-alert-only-checkbox"
id="sourcerer-alert-only-checkbox"
label={i18n.ALERTS_CHECKBOX_LABEL}
onChange={onChange}
/>
</StyledFormRow>
) : null
);

AlertsCheckbox.displayName = 'AlertsCheckbox';

interface SaveButtonsProps {
disableSave: boolean;
isShow: boolean;
onReset: () => void;
onSave: () => void;
}

export const SaveButtons = React.memo<SaveButtonsProps>(
({ disableSave, isShow, onReset, onSave }) =>
isShow ? (
<StyledFormRow>
<EuiFlexGroup alignItems="center" justifyContent="flexEnd">
<EuiFlexItem grow={false}>
<ResetButton
aria-label={i18n.INDEX_PATTERNS_RESET}
data-test-subj="sourcerer-reset"
flush="left"
onClick={onReset}
title={i18n.INDEX_PATTERNS_RESET}
>
{i18n.INDEX_PATTERNS_RESET}
</ResetButton>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiButton
onClick={onSave}
disabled={disableSave}
data-test-subj="sourcerer-save"
fill
fullWidth
size="s"
>
{i18n.SAVE_INDEX_PATTERNS}
</EuiButton>
</EuiFlexItem>
</EuiFlexGroup>
</StyledFormRow>
) : null
);

SaveButtons.displayName = 'SaveButtons';
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,15 @@ import {
import React, { useMemo } from 'react';
import * as i18n from './translations';
import { Blockquote, ResetButton } from './helpers';
import { UpdateDefaultDataViewModal } from './update_default_data_view_modal';

interface Props {
activePatterns?: string[];
indicesExist: boolean;
isModified: 'deprecated' | 'missingPatterns';
missingPatterns: string[];
onClick: () => void;
onClose: () => void;
onDismiss: () => void;
onReset: () => void;
onUpdate: () => void;
selectedPatterns: string[];
}
Expand All @@ -44,13 +45,13 @@ const translations = {
},
};

export const TemporarySourcerer = React.memo<Props>(
export const TemporarySourcererComp = React.memo<Props>(
({
activePatterns,
indicesExist,
isModified,
onClose,
onClick,
onDismiss,
onReset,
onUpdate,
selectedPatterns,
missingPatterns,
Expand Down Expand Up @@ -141,7 +142,7 @@ export const TemporarySourcerer = React.memo<Props>(
id="xpack.securitySolution.indexPatterns.toggleToNewSourcerer"
defaultMessage="We have preserved your timeline by creating a temporary data view. If you'd like to modify your data, we can recreate your temporary data view with the new data view selector. You can also manually select a data view {link}."
values={{
link: <EuiLink onClick={onClick}>{i18n.TOGGLE_TO_NEW_SOURCERER}</EuiLink>,
link: <EuiLink onClick={onReset}>{i18n.TOGGLE_TO_NEW_SOURCERER}</EuiLink>,
}}
/>
)}
Expand All @@ -158,7 +159,7 @@ export const TemporarySourcerer = React.memo<Props>(
id="xpack.securitySolution.indexPatterns.missingPatterns.description"
defaultMessage="We have preserved your timeline by creating a temporary data view. If you'd like to modify your data, we can add the missing index patterns to the Security Data View. You can also manually select a data view {link}."
values={{
link: <EuiLink onClick={onClick}>{i18n.TOGGLE_TO_NEW_SOURCERER}</EuiLink>,
link: <EuiLink onClick={onReset}>{i18n.TOGGLE_TO_NEW_SOURCERER}</EuiLink>,
}}
/>
</>
Expand All @@ -172,7 +173,7 @@ export const TemporarySourcerer = React.memo<Props>(
aria-label={i18n.INDEX_PATTERNS_CLOSE}
data-test-subj="sourcerer-deprecated-close"
flush="left"
onClick={onClose}
onClick={onDismiss}
title={i18n.INDEX_PATTERNS_CLOSE}
>
{i18n.INDEX_PATTERNS_CLOSE}
Expand All @@ -185,4 +186,58 @@ export const TemporarySourcerer = React.memo<Props>(
}
);

TemporarySourcererComp.displayName = 'TemporarySourcererComp';

interface TemporarySourcererProps {
activePatterns?: string[];
indicesExist: boolean;
isModified: 'deprecated' | 'missingPatterns';
isShowingUpdateModal: boolean;
missingPatterns: string[];
onContinueWithoutUpdate: () => void;
onDismiss: () => void;
onDismissModal: () => void;
onReset: () => void;
onUpdateStepOne: () => void;
onUpdateStepTwo: () => void;
selectedPatterns: string[];
}

export const TemporarySourcerer = React.memo<TemporarySourcererProps>(
({
activePatterns,
indicesExist,
isModified,
missingPatterns,
onContinueWithoutUpdate,
onDismiss,
onReset,
onUpdateStepOne,
onUpdateStepTwo,
selectedPatterns,
isShowingUpdateModal,
onDismissModal,
}) => (
<>
<TemporarySourcererComp
activePatterns={activePatterns}
indicesExist={indicesExist}
isModified={isModified}
missingPatterns={missingPatterns}
onDismiss={onDismiss}
onReset={onReset}
onUpdate={onUpdateStepOne}
selectedPatterns={selectedPatterns}
/>
<UpdateDefaultDataViewModal
isShowing={isShowingUpdateModal}
missingPatterns={missingPatterns}
onDismissModal={onDismissModal}
onContinue={onContinueWithoutUpdate}
onUpdate={onUpdateStepTwo}
/>
</>
)
);

TemporarySourcerer.displayName = 'TemporarySourcerer';
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import { Blockquote, ResetButton } from './helpers';
interface Props {
isShowing: boolean;
missingPatterns: string[];
onClose: () => void;
onDismissModal: () => void;
onContinue: () => void;
onUpdate: () => void;
}
Expand All @@ -41,9 +41,9 @@ const MyEuiModal = styled(EuiModal)`
`;

export const UpdateDefaultDataViewModal = React.memo<Props>(
({ isShowing, onClose, onContinue, onUpdate, missingPatterns }) =>
({ isShowing, onDismissModal, onContinue, onUpdate, missingPatterns }) =>
isShowing ? (
<MyEuiModal onClose={onClose} data-test-subj="sourcerer-update-data-view-modal">
<MyEuiModal onClose={onDismissModal} data-test-subj="sourcerer-update-data-view-modal">
<EuiModalHeader>
<EuiModalHeaderTitle>
<h1>{i18n.UPDATE_SECURITY_DATA_VIEW}</h1>
Expand Down
Loading

0 comments on commit a9591f5

Please sign in to comment.