Skip to content

Commit

Permalink
Merge branch 'master' into eui/28
Browse files Browse the repository at this point in the history
  • Loading branch information
elasticmachine authored Aug 26, 2020
2 parents be22a9b + 1ca7651 commit 5502061
Show file tree
Hide file tree
Showing 21 changed files with 456 additions and 709 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
EuiCheckbox,
EuiSpacer,
EuiFormRow,
EuiCallOut,
EuiText,
} from '@elastic/eui';
import { Status } from '../../../../../common/detection_engine/schemas/common/schemas';
Expand All @@ -27,15 +28,13 @@ import {
ExceptionListType,
} from '../../../../../public/lists_plugin_deps';
import * as i18n from './translations';
import * as sharedI18n from '../translations';
import { TimelineNonEcsData, Ecs } from '../../../../graphql/types';
import { useAppToasts } from '../../../hooks/use_app_toasts';
import { useKibana } from '../../../lib/kibana';
import { ExceptionBuilderComponent } from '../builder';
import { Loader } from '../../loader';
import { useAddOrUpdateException } from '../use_add_exception';
import { useSignalIndex } from '../../../../detections/containers/detection_engine/alerts/use_signal_index';
import { useRuleAsync } from '../../../../detections/containers/detection_engine/rules/use_rule_async';
import { useFetchOrCreateRuleExceptionList } from '../use_fetch_or_create_rule_exception_list';
import { AddExceptionComments } from '../add_exception_comments';
import {
Expand All @@ -47,7 +46,6 @@ import {
entryHasNonEcsType,
getMappedNonEcsValue,
} from '../helpers';
import { ErrorInfo, ErrorCallout } from '../error_callout';
import { useFetchIndexPatterns } from '../../../../detections/containers/detection_engine/rules';

export interface AddExceptionModalBaseProps {
Expand Down Expand Up @@ -109,14 +107,13 @@ export const AddExceptionModal = memo(function AddExceptionModal({
}: AddExceptionModalProps) {
const { http } = useKibana().services;
const [comment, setComment] = useState('');
const { rule: maybeRule } = useRuleAsync(ruleId);
const [shouldCloseAlert, setShouldCloseAlert] = useState(false);
const [shouldBulkCloseAlert, setShouldBulkCloseAlert] = useState(false);
const [shouldDisableBulkClose, setShouldDisableBulkClose] = useState(false);
const [exceptionItemsToAdd, setExceptionItemsToAdd] = useState<
Array<ExceptionListItemSchema | CreateExceptionListItemSchema>
>([]);
const [fetchOrCreateListError, setFetchOrCreateListError] = useState<ErrorInfo | null>(null);
const [fetchOrCreateListError, setFetchOrCreateListError] = useState(false);
const { addError, addSuccess } = useAppToasts();
const { loading: isSignalIndexLoading, signalIndexName } = useSignalIndex();
const [
Expand Down Expand Up @@ -167,41 +164,17 @@ export const AddExceptionModal = memo(function AddExceptionModal({
},
[onRuleChange]
);

const handleDissasociationSuccess = useCallback(
(id: string): void => {
handleRuleChange(true);
addSuccess(sharedI18n.DISSASOCIATE_LIST_SUCCESS(id));
onCancel();
},
[handleRuleChange, addSuccess, onCancel]
);

const handleDissasociationError = useCallback(
(error: Error): void => {
addError(error, { title: sharedI18n.DISSASOCIATE_EXCEPTION_LIST_ERROR });
onCancel();
},
[addError, onCancel]
);

const handleFetchOrCreateExceptionListError = useCallback(
(error: Error, statusCode: number | null, message: string | null) => {
setFetchOrCreateListError({
reason: error.message,
code: statusCode,
details: message,
listListId: null,
});
const onFetchOrCreateExceptionListError = useCallback(
(error: Error) => {
setFetchOrCreateListError(true);
},
[setFetchOrCreateListError]
);

const [isLoadingExceptionList, ruleExceptionList] = useFetchOrCreateRuleExceptionList({
http,
ruleId,
exceptionListType,
onError: handleFetchOrCreateExceptionListError,
onError: onFetchOrCreateExceptionListError,
onSuccess: handleRuleChange,
});

Expand Down Expand Up @@ -306,9 +279,7 @@ export const AddExceptionModal = memo(function AddExceptionModal({
]);

const isSubmitButtonDisabled = useMemo(
() =>
fetchOrCreateListError != null ||
exceptionItemsToAdd.every((item) => item.entries.length === 0),
() => fetchOrCreateListError || exceptionItemsToAdd.every((item) => item.entries.length === 0),
[fetchOrCreateListError, exceptionItemsToAdd]
);

Expand All @@ -324,27 +295,19 @@ export const AddExceptionModal = memo(function AddExceptionModal({
</ModalHeaderSubtitle>
</ModalHeader>

{fetchOrCreateListError != null && (
<EuiModalFooter>
<ErrorCallout
http={http}
errorInfo={fetchOrCreateListError}
rule={maybeRule}
onCancel={onCancel}
onSuccess={handleDissasociationSuccess}
onError={handleDissasociationError}
data-test-subj="addExceptionModalErrorCallout"
/>
</EuiModalFooter>
{fetchOrCreateListError === true && (
<EuiCallOut title={i18n.ADD_EXCEPTION_FETCH_ERROR_TITLE} color="danger" iconType="alert">
<p>{i18n.ADD_EXCEPTION_FETCH_ERROR}</p>
</EuiCallOut>
)}
{fetchOrCreateListError == null &&
{fetchOrCreateListError === false &&
(isLoadingExceptionList ||
isIndexPatternLoading ||
isSignalIndexLoading ||
isSignalIndexPatternLoading) && (
<Loader data-test-subj="loadingAddExceptionModal" size="xl" />
)}
{fetchOrCreateListError == null &&
{fetchOrCreateListError === false &&
!isSignalIndexLoading &&
!isSignalIndexPatternLoading &&
!isLoadingExceptionList &&
Expand Down Expand Up @@ -414,21 +377,20 @@ export const AddExceptionModal = memo(function AddExceptionModal({
</ModalBodySection>
</>
)}
{fetchOrCreateListError == null && (
<EuiModalFooter>
<EuiButtonEmpty onClick={onCancel}>{i18n.CANCEL}</EuiButtonEmpty>

<EuiButton
data-test-subj="add-exception-confirm-button"
onClick={onAddExceptionConfirm}
isLoading={addExceptionIsLoading}
isDisabled={isSubmitButtonDisabled}
fill
>
{i18n.ADD_EXCEPTION}
</EuiButton>
</EuiModalFooter>
)}
<EuiModalFooter>
<EuiButtonEmpty onClick={onCancel}>{i18n.CANCEL}</EuiButtonEmpty>

<EuiButton
data-test-subj="add-exception-confirm-button"
onClick={onAddExceptionConfirm}
isLoading={addExceptionIsLoading}
isDisabled={isSubmitButtonDisabled}
fill
>
{i18n.ADD_EXCEPTION}
</EuiButton>
</EuiModalFooter>
</Modal>
</EuiOverlayMask>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,6 @@ describe('When the edit exception modal is opened', () => {
<ThemeProvider theme={() => ({ eui: euiLightVars, darkMode: false })}>
<EditExceptionModal
ruleIndices={[]}
ruleId="123"
ruleName={ruleName}
exceptionListType={'endpoint'}
onCancel={jest.fn()}
Expand Down Expand Up @@ -106,7 +105,6 @@ describe('When the edit exception modal is opened', () => {
<ThemeProvider theme={() => ({ eui: euiLightVars, darkMode: false })}>
<EditExceptionModal
ruleIndices={['filebeat-*']}
ruleId="123"
ruleName={ruleName}
exceptionListType={'endpoint'}
onCancel={jest.fn()}
Expand Down Expand Up @@ -149,7 +147,6 @@ describe('When the edit exception modal is opened', () => {
<ThemeProvider theme={() => ({ eui: euiLightVars, darkMode: false })}>
<EditExceptionModal
ruleIndices={['filebeat-*']}
ruleId="123"
ruleName={ruleName}
exceptionListType={'endpoint'}
onCancel={jest.fn()}
Expand Down Expand Up @@ -193,7 +190,6 @@ describe('When the edit exception modal is opened', () => {
<ThemeProvider theme={() => ({ eui: euiLightVars, darkMode: false })}>
<EditExceptionModal
ruleIndices={['filebeat-*']}
ruleId="123"
ruleName={ruleName}
exceptionListType={'detection'}
onCancel={jest.fn()}
Expand Down Expand Up @@ -233,7 +229,6 @@ describe('When the edit exception modal is opened', () => {
<ThemeProvider theme={() => ({ eui: euiLightVars, darkMode: false })}>
<EditExceptionModal
ruleIndices={['filebeat-*']}
ruleId="123"
ruleName={ruleName}
exceptionListType={'detection'}
onCancel={jest.fn()}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,12 @@ import {
} from '@elastic/eui';
import { useFetchIndexPatterns } from '../../../../detections/containers/detection_engine/rules';
import { useSignalIndex } from '../../../../detections/containers/detection_engine/alerts/use_signal_index';
import { useRuleAsync } from '../../../../detections/containers/detection_engine/rules/use_rule_async';
import {
ExceptionListItemSchema,
CreateExceptionListItemSchema,
ExceptionListType,
} from '../../../../../public/lists_plugin_deps';
import * as i18n from './translations';
import * as sharedI18n from '../translations';
import { useKibana } from '../../../lib/kibana';
import { useAppToasts } from '../../../hooks/use_app_toasts';
import { ExceptionBuilderComponent } from '../builder';
Expand All @@ -45,17 +43,14 @@ import {
lowercaseHashValues,
} from '../helpers';
import { Loader } from '../../loader';
import { ErrorInfo, ErrorCallout } from '../error_callout';

interface EditExceptionModalProps {
ruleName: string;
ruleId: string;
ruleIndices: string[];
exceptionItem: ExceptionListItemSchema;
exceptionListType: ExceptionListType;
onCancel: () => void;
onConfirm: () => void;
onRuleChange?: () => void;
}

const Modal = styled(EuiModal)`
Expand Down Expand Up @@ -88,18 +83,14 @@ const ModalBodySection = styled.section`

export const EditExceptionModal = memo(function EditExceptionModal({
ruleName,
ruleId,
ruleIndices,
exceptionItem,
exceptionListType,
onCancel,
onConfirm,
onRuleChange,
}: EditExceptionModalProps) {
const { http } = useKibana().services;
const [comment, setComment] = useState('');
const { rule: maybeRule } = useRuleAsync(ruleId);
const [updateError, setUpdateError] = useState<ErrorInfo | null>(null);
const [hasVersionConflict, setHasVersionConflict] = useState(false);
const [shouldBulkCloseAlert, setShouldBulkCloseAlert] = useState(false);
const [shouldDisableBulkClose, setShouldDisableBulkClose] = useState(false);
Expand All @@ -117,53 +108,27 @@ export const EditExceptionModal = memo(function EditExceptionModal({
'rules'
);

const handleExceptionUpdateError = useCallback(
(error: Error, statusCode: number | null, message: string | null) => {
const onError = useCallback(
(error) => {
if (error.message.includes('Conflict')) {
setHasVersionConflict(true);
} else {
setUpdateError({
reason: error.message,
code: statusCode,
details: message,
listListId: exceptionItem.list_id,
});
addError(error, { title: i18n.EDIT_EXCEPTION_ERROR });
onCancel();
}
},
[setUpdateError, setHasVersionConflict, exceptionItem.list_id]
);

const handleDissasociationSuccess = useCallback(
(id: string): void => {
addSuccess(sharedI18n.DISSASOCIATE_LIST_SUCCESS(id));

if (onRuleChange) {
onRuleChange();
}

onCancel();
},
[addSuccess, onCancel, onRuleChange]
);

const handleDissasociationError = useCallback(
(error: Error): void => {
addError(error, { title: sharedI18n.DISSASOCIATE_EXCEPTION_LIST_ERROR });
onCancel();
},
[addError, onCancel]
);

const handleExceptionUpdateSuccess = useCallback((): void => {
const onSuccess = useCallback(() => {
addSuccess(i18n.EDIT_EXCEPTION_SUCCESS);
onConfirm();
}, [addSuccess, onConfirm]);

const [{ isLoading: addExceptionIsLoading }, addOrUpdateExceptionItems] = useAddOrUpdateException(
{
http,
onSuccess: handleExceptionUpdateSuccess,
onError: handleExceptionUpdateError,
onSuccess,
onError,
}
);

Expand Down Expand Up @@ -257,9 +222,11 @@ export const EditExceptionModal = memo(function EditExceptionModal({
{ruleName}
</ModalHeaderSubtitle>
</ModalHeader>

{(addExceptionIsLoading || isIndexPatternLoading || isSignalIndexLoading) && (
<Loader data-test-subj="loadingEditExceptionModal" size="xl" />
)}

{!isSignalIndexLoading && !addExceptionIsLoading && !isIndexPatternLoading && (
<>
<ModalBodySection className="builder-section">
Expand Down Expand Up @@ -313,40 +280,28 @@ export const EditExceptionModal = memo(function EditExceptionModal({
</ModalBodySection>
</>
)}
{updateError != null && (
<ModalBodySection>
<ErrorCallout
http={http}
errorInfo={updateError}
rule={maybeRule}
onCancel={onCancel}
onSuccess={handleDissasociationSuccess}
onError={handleDissasociationError}
/>
</ModalBodySection>
)}

{hasVersionConflict && (
<ModalBodySection>
<EuiCallOut title={i18n.VERSION_CONFLICT_ERROR_TITLE} color="danger" iconType="alert">
<p>{i18n.VERSION_CONFLICT_ERROR_DESCRIPTION}</p>
</EuiCallOut>
</ModalBodySection>
)}
{updateError == null && (
<EuiModalFooter>
<EuiButtonEmpty onClick={onCancel}>{i18n.CANCEL}</EuiButtonEmpty>

<EuiButton
data-test-subj="edit-exception-confirm-button"
onClick={onEditExceptionConfirm}
isLoading={addExceptionIsLoading}
isDisabled={isSubmitButtonDisabled}
fill
>
{i18n.EDIT_EXCEPTION_SAVE_BUTTON}
</EuiButton>
</EuiModalFooter>
)}
<EuiModalFooter>
<EuiButtonEmpty onClick={onCancel}>{i18n.CANCEL}</EuiButtonEmpty>

<EuiButton
data-test-subj="edit-exception-confirm-button"
onClick={onEditExceptionConfirm}
isLoading={addExceptionIsLoading}
isDisabled={isSubmitButtonDisabled}
fill
>
{i18n.EDIT_EXCEPTION_SAVE_BUTTON}
</EuiButton>
</EuiModalFooter>
</Modal>
</EuiOverlayMask>
);
Expand Down
Loading

0 comments on commit 5502061

Please sign in to comment.