Skip to content

Commit

Permalink
[SIEM] [Cases] Delete, comment, and reducer updates (elastic#59616) (e…
Browse files Browse the repository at this point in the history
  • Loading branch information
stephmilovic authored Mar 12, 2020
1 parent 59cc93c commit 8b174fe
Show file tree
Hide file tree
Showing 26 changed files with 523 additions and 201 deletions.
8 changes: 8 additions & 0 deletions x-pack/legacy/plugins/siem/public/containers/case/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,3 +119,11 @@ export const patchComment = async (
);
return convertToCamelCase<CommentResponse, Comment>(decodeCommentResponse(response));
};

export const deleteCases = async (caseIds: string[]): Promise<boolean> => {
const response = await KibanaServices.get().http.fetch<string>(`${CASES_URL}`, {
method: 'DELETE',
query: { ids: JSON.stringify(caseIds) },
});
return response === 'true' ? true : false;
};
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,3 @@
export const CASES_URL = `/api/cases`;
export const DEFAULT_TABLE_ACTIVE_PAGE = 1;
export const DEFAULT_TABLE_LIMIT = 5;
export const FETCH_FAILURE = 'FETCH_FAILURE';
export const FETCH_INIT = 'FETCH_INIT';
export const FETCH_SUCCESS = 'FETCH_SUCCESS';
export const POST_NEW_CASE = 'POST_NEW_CASE';
export const POST_NEW_COMMENT = 'POST_NEW_COMMENT';
export const UPDATE_FILTER_OPTIONS = 'UPDATE_FILTER_OPTIONS';
export const UPDATE_TABLE_SELECTIONS = 'UPDATE_TABLE_SELECTIONS';
export const UPDATE_QUERY_PARAMS = 'UPDATE_QUERY_PARAMS';
1 change: 1 addition & 0 deletions x-pack/legacy/plugins/siem/public/containers/case/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export interface Comment {
export interface Case {
id: string;
comments: Comment[];
commentIds: string[];
createdAt: string;
createdBy: ElasticUser;
description: string;
Expand Down
121 changes: 121 additions & 0 deletions x-pack/legacy/plugins/siem/public/containers/case/use_delete_cases.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import { useCallback, useReducer } from 'react';
import { errorToToaster, useStateToaster } from '../../components/toasters';
import * as i18n from './translations';
import { deleteCases } from './api';

interface DeleteState {
isDisplayConfirmDeleteModal: boolean;
isDeleted: boolean;
isLoading: boolean;
isError: boolean;
}
type Action =
| { type: 'DISPLAY_MODAL'; payload: boolean }
| { type: 'FETCH_INIT' }
| { type: 'FETCH_SUCCESS'; payload: boolean }
| { type: 'FETCH_FAILURE' }
| { type: 'RESET_IS_DELETED' };

const dataFetchReducer = (state: DeleteState, action: Action): DeleteState => {
switch (action.type) {
case 'DISPLAY_MODAL':
return {
...state,
isDisplayConfirmDeleteModal: action.payload,
};
case 'FETCH_INIT':
return {
...state,
isLoading: true,
isError: false,
};
case 'FETCH_SUCCESS':
return {
...state,
isLoading: false,
isError: false,
isDeleted: action.payload,
};
case 'FETCH_FAILURE':
return {
...state,
isLoading: false,
isError: true,
};
case 'RESET_IS_DELETED':
return {
...state,
isDeleted: false,
};
default:
return state;
}
};
interface UseDeleteCase extends DeleteState {
dispatchResetIsDeleted: () => void;
handleOnDeleteConfirm: (caseIds: string[]) => void;
handleToggleModal: () => void;
}

export const useDeleteCases = (): UseDeleteCase => {
const [state, dispatch] = useReducer(dataFetchReducer, {
isDisplayConfirmDeleteModal: false,
isLoading: false,
isError: false,
isDeleted: false,
});
const [, dispatchToaster] = useStateToaster();

const dispatchDeleteCases = useCallback((caseIds: string[]) => {
let cancel = false;
const deleteData = async () => {
try {
dispatch({ type: 'FETCH_INIT' });
await deleteCases(caseIds);
if (!cancel) {
dispatch({ type: 'FETCH_SUCCESS', payload: true });
}
} catch (error) {
if (!cancel) {
errorToToaster({
title: i18n.ERROR_TITLE,
error: error.body && error.body.message ? new Error(error.body.message) : error,
dispatchToaster,
});
dispatch({ type: 'FETCH_FAILURE' });
}
}
};
deleteData();
return () => {
cancel = true;
};
}, []);

const dispatchToggleDeleteModal = useCallback(() => {
dispatch({ type: 'DISPLAY_MODAL', payload: !state.isDisplayConfirmDeleteModal });
}, [state.isDisplayConfirmDeleteModal]);

const dispatchResetIsDeleted = useCallback(() => {
dispatch({ type: 'RESET_IS_DELETED' });
}, [state.isDisplayConfirmDeleteModal]);

const handleOnDeleteConfirm = useCallback(
caseIds => {
dispatchDeleteCases(caseIds);
dispatchToggleDeleteModal();
},
[state.isDisplayConfirmDeleteModal]
);
const handleToggleModal = useCallback(() => {
dispatchToggleDeleteModal();
}, [state.isDisplayConfirmDeleteModal]);

return { ...state, dispatchResetIsDeleted, handleOnDeleteConfirm, handleToggleModal };
};
32 changes: 16 additions & 16 deletions x-pack/legacy/plugins/siem/public/containers/case/use_get_case.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@
import { useEffect, useReducer } from 'react';

import { Case } from './types';
import { FETCH_INIT, FETCH_FAILURE, FETCH_SUCCESS } from './constants';
import { getTypedPayload } from './utils';
import * as i18n from './translations';
import { errorToToaster, useStateToaster } from '../../components/toasters';
import { getCase } from './api';
Expand All @@ -18,40 +16,42 @@ interface CaseState {
isLoading: boolean;
isError: boolean;
}
interface Action {
type: string;
payload?: Case;
}

type Action =
| { type: 'FETCH_INIT' }
| { type: 'FETCH_SUCCESS'; payload: Case }
| { type: 'FETCH_FAILURE' };

const dataFetchReducer = (state: CaseState, action: Action): CaseState => {
switch (action.type) {
case FETCH_INIT:
case 'FETCH_INIT':
return {
...state,
isLoading: true,
isError: false,
};
case FETCH_SUCCESS:
case 'FETCH_SUCCESS':
return {
...state,
isLoading: false,
isError: false,
data: getTypedPayload<Case>(action.payload),
data: action.payload,
};
case FETCH_FAILURE:
case 'FETCH_FAILURE':
return {
...state,
isLoading: false,
isError: true,
};
default:
throw new Error();
return state;
}
};
const initialData: Case = {
id: '',
createdAt: '',
comments: [],
commentIds: [],
createdBy: {
username: '',
},
Expand All @@ -63,7 +63,7 @@ const initialData: Case = {
version: '',
};

export const useGetCase = (caseId: string): [CaseState] => {
export const useGetCase = (caseId: string): CaseState => {
const [state, dispatch] = useReducer(dataFetchReducer, {
isLoading: true,
isError: false,
Expand All @@ -74,11 +74,11 @@ export const useGetCase = (caseId: string): [CaseState] => {
const callFetch = () => {
let didCancel = false;
const fetchData = async () => {
dispatch({ type: FETCH_INIT });
dispatch({ type: 'FETCH_INIT' });
try {
const response = await getCase(caseId);
if (!didCancel) {
dispatch({ type: FETCH_SUCCESS, payload: response });
dispatch({ type: 'FETCH_SUCCESS', payload: response });
}
} catch (error) {
if (!didCancel) {
Expand All @@ -87,7 +87,7 @@ export const useGetCase = (caseId: string): [CaseState] => {
error: error.body && error.body.message ? new Error(error.body.message) : error,
dispatchToaster,
});
dispatch({ type: FETCH_FAILURE });
dispatch({ type: 'FETCH_FAILURE' });
}
}
};
Expand All @@ -100,5 +100,5 @@ export const useGetCase = (caseId: string): [CaseState] => {
useEffect(() => {
callFetch();
}, [caseId]);
return [state];
return state;
};
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ const dataFetchReducer = (state: UseGetCasesState, action: Action): UseGetCasesS
selectedCases: action.payload,
};
default:
throw new Error();
return state;
}
};

Expand All @@ -109,6 +109,7 @@ const initialData: AllCases = {
interface UseGetCases extends UseGetCasesState {
dispatchUpdateCaseProperty: ({ updateKey, updateValue, caseId, version }: UpdateCase) => void;
getCaseCount: (caseState: keyof CaseCount) => void;
refetchCases: (filters: FilterOptions, queryParams: QueryParams) => void;
setFilters: (filters: FilterOptions) => void;
setQueryParams: (queryParams: QueryParams) => void;
setSelectedCases: (mySelectedCases: Case[]) => void;
Expand Down Expand Up @@ -245,10 +246,17 @@ export const useGetCases = (): UseGetCases => {
[state.filterOptions, state.queryParams]
);

const refetchCases = useCallback(() => {
fetchCases(state.filterOptions, state.queryParams);
getCaseCount('open');
getCaseCount('closed');
}, [state.filterOptions, state.queryParams]);

return {
...state,
dispatchUpdateCaseProperty,
getCaseCount,
refetchCases,
setFilters,
setQueryParams,
setSelectedCases,
Expand Down
34 changes: 16 additions & 18 deletions x-pack/legacy/plugins/siem/public/containers/case/use_get_tags.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,63 +8,61 @@ import { useEffect, useReducer } from 'react';

import { errorToToaster, useStateToaster } from '../../components/toasters';
import { getTags } from './api';
import { FETCH_FAILURE, FETCH_INIT, FETCH_SUCCESS } from './constants';
import * as i18n from './translations';

interface TagsState {
data: string[];
tags: string[];
isLoading: boolean;
isError: boolean;
}
interface Action {
type: string;
payload?: string[];
}
type Action =
| { type: 'FETCH_INIT' }
| { type: 'FETCH_SUCCESS'; payload: string[] }
| { type: 'FETCH_FAILURE' };

const dataFetchReducer = (state: TagsState, action: Action): TagsState => {
switch (action.type) {
case FETCH_INIT:
case 'FETCH_INIT':
return {
...state,
isLoading: true,
isError: false,
};
case FETCH_SUCCESS:
const getTypedPayload = (a: Action['payload']) => a as string[];
case 'FETCH_SUCCESS':
return {
...state,
isLoading: false,
isError: false,
data: getTypedPayload(action.payload),
tags: action.payload,
};
case FETCH_FAILURE:
case 'FETCH_FAILURE':
return {
...state,
isLoading: false,
isError: true,
};
default:
throw new Error();
return state;
}
};
const initialData: string[] = [];

export const useGetTags = (): [TagsState] => {
export const useGetTags = (): TagsState => {
const [state, dispatch] = useReducer(dataFetchReducer, {
isLoading: false,
isError: false,
data: initialData,
tags: initialData,
});
const [, dispatchToaster] = useStateToaster();

useEffect(() => {
let didCancel = false;
const fetchData = async () => {
dispatch({ type: FETCH_INIT });
dispatch({ type: 'FETCH_INIT' });
try {
const response = await getTags();
if (!didCancel) {
dispatch({ type: FETCH_SUCCESS, payload: response });
dispatch({ type: 'FETCH_SUCCESS', payload: response });
}
} catch (error) {
if (!didCancel) {
Expand All @@ -73,7 +71,7 @@ export const useGetTags = (): [TagsState] => {
error: error.body && error.body.message ? new Error(error.body.message) : error,
dispatchToaster,
});
dispatch({ type: FETCH_FAILURE });
dispatch({ type: 'FETCH_FAILURE' });
}
}
};
Expand All @@ -82,5 +80,5 @@ export const useGetTags = (): [TagsState] => {
didCancel = true;
};
}, []);
return [state];
return state;
};
Loading

0 comments on commit 8b174fe

Please sign in to comment.