Skip to content

Commit

Permalink
Enhance cases bulk deletion action dialog message (#101403)
Browse files Browse the repository at this point in the history
Differentiate the dialog message on the deletion of one item from the deletion of multiple items.
Simplifies CasesTableUtilityBar by handling the selection of multiple and single cases in the same way.
  • Loading branch information
machadoum committed Jun 16, 2021
1 parent aa97040 commit 037d7ae
Show file tree
Hide file tree
Showing 9 changed files with 36 additions and 69 deletions.
2 changes: 1 addition & 1 deletion x-pack/plugins/cases/common/ui/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ export interface ActionLicense {
export interface DeleteCase {
id: string;
type: CaseType | null;
title?: string;
title: string;
}

export interface FieldMappings {
Expand Down
12 changes: 5 additions & 7 deletions x-pack/plugins/cases/public/common/translations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,11 @@ export const CANCEL = i18n.translate('xpack.cases.caseView.cancel', {
defaultMessage: 'Cancel',
});

export const DELETE_CASE = i18n.translate('xpack.cases.confirmDeleteCase.deleteCase', {
defaultMessage: 'Delete case',
});

export const DELETE_CASES = i18n.translate('xpack.cases.confirmDeleteCase.deleteCases', {
defaultMessage: 'Delete cases',
});
export const DELETE_CASE = (quantity: number = 1) =>
i18n.translate('xpack.cases.confirmDeleteCase.deleteCase', {
values: { quantity },
defaultMessage: `Delete {quantity, plural, =1 {case} other {cases}}`,
});

export const NAME = i18n.translate('xpack.cases.caseView.name', {
defaultMessage: 'Name',
Expand Down
4 changes: 2 additions & 2 deletions x-pack/plugins/cases/public/components/all_cases/actions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,9 @@ export const getActions = ({
makeInProgressAction,
closeCaseAction,
{
description: i18n.DELETE_CASE,
description: i18n.DELETE_CASE(),
icon: 'trash',
name: i18n.DELETE_CASE,
name: i18n.DELETE_CASE(),
onClick: deleteCaseOnClick,
type: 'icon',
'data-test-subj': 'action-delete',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,6 @@ export const useCasesColumns = ({
<ConfirmDeleteCaseModal
caseTitle={deleteThisCase.title}
isModalVisible={isDisplayConfirmDeleteModal}
isPlural={false}
onCancel={handleToggleModal}
onConfirm={handleOnDeleteConfirm.bind(null, [deleteThisCase])}
/>
Expand Down
33 changes: 9 additions & 24 deletions x-pack/plugins/cases/public/components/all_cases/utility_bar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,8 @@ export const CasesTableUtilityBar: FunctionComponent<Props> = ({
refreshCases,
selectedCases,
}) => {
const [deleteBulk, setDeleteBulk] = useState<DeleteCase[]>([]);
const [deleteThisCase, setDeleteThisCase] = useState<DeleteCase>({
title: '',
id: '',
type: null,
});
const [deleteCases, setDeleteCases] = useState<DeleteCase[]>([]);

// Delete case
const {
dispatchResetIsDeleted,
Expand Down Expand Up @@ -86,24 +82,15 @@ export const CasesTableUtilityBar: FunctionComponent<Props> = ({
const toggleBulkDeleteModal = useCallback(
(cases: Case[]) => {
handleToggleModal();
if (cases.length === 1) {
const singleCase = cases[0];
if (singleCase) {
return setDeleteThisCase({
id: singleCase.id,
title: singleCase.title,
type: singleCase.type,
});
}
}

const convertToDeleteCases: DeleteCase[] = cases.map(({ id, title, type }) => ({
id,
title,
type,
}));
setDeleteBulk(convertToDeleteCases);
setDeleteCases(convertToDeleteCases);
},
[setDeleteBulk, handleToggleModal]
[setDeleteCases, handleToggleModal]
);

const handleUpdateCaseStatus = useCallback(
Expand All @@ -128,6 +115,7 @@ export const CasesTableUtilityBar: FunctionComponent<Props> = ({
),
[selectedCases, filterOptions.status, toggleBulkDeleteModal, handleUpdateCaseStatus]
);

return (
<UtilityBar border>
<UtilityBarSection>
Expand Down Expand Up @@ -159,14 +147,11 @@ export const CasesTableUtilityBar: FunctionComponent<Props> = ({
</UtilityBarGroup>
</UtilityBarSection>
<ConfirmDeleteCaseModal
caseTitle={deleteThisCase.title}
caseTitle={deleteCases[0]?.title ?? ''}
isModalVisible={isDisplayConfirmDeleteModal}
isPlural={deleteBulk.length > 0}
caseQuantity={deleteCases.length}
onCancel={handleToggleModal}
onConfirm={handleOnDeleteConfirm.bind(
null,
deleteBulk.length > 0 ? deleteBulk : [deleteThisCase]
)}
onConfirm={handleOnDeleteConfirm.bind(null, deleteCases)}
/>
</UtilityBar>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ const ActionsComponent: React.FC<CaseViewActions> = ({
{
disabled,
iconType: 'trash',
label: i18n.DELETE_CASE,
label: i18n.DELETE_CASE(),
onClick: handleToggleModal,
},
...(currentExternalIncident != null && !isEmpty(currentExternalIncident?.externalUrl)
Expand All @@ -67,7 +67,6 @@ const ActionsComponent: React.FC<CaseViewActions> = ({
<ConfirmDeleteCaseModal
caseTitle={caseData.title}
isModalVisible={isDisplayConfirmDeleteModal}
isPlural={false}
onCancel={handleToggleModal}
onConfirm={handleOnDeleteConfirm.bind(null, [
{ id: caseData.id, title: caseData.title, type: caseData.type },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,17 @@ import { EuiConfirmModal } from '@elastic/eui';
import * as i18n from './translations';

interface ConfirmDeleteCaseModalProps {
caseTitle?: string;
caseTitle: string;
isModalVisible: boolean;
isPlural: boolean;
caseQuantity?: number;
onCancel: () => void;
onConfirm: () => void;
}

const ConfirmDeleteCaseModalComp: React.FC<ConfirmDeleteCaseModalProps> = ({
caseTitle,
isModalVisible,
isPlural,
caseQuantity = 1,
onCancel,
onConfirm,
}) => {
Expand All @@ -31,20 +31,14 @@ const ConfirmDeleteCaseModalComp: React.FC<ConfirmDeleteCaseModalProps> = ({
<EuiConfirmModal
buttonColor="danger"
cancelButtonText={i18n.CANCEL}
confirmButtonText={isPlural ? i18n.DELETE_CASES : i18n.DELETE_CASE}
confirmButtonText={i18n.DELETE_CASE(caseQuantity)}
data-test-subj="confirm-delete-case-modal"
defaultFocusedButton="confirm"
onCancel={onCancel}
onConfirm={onConfirm}
title={
isPlural
? i18n.DELETE_SELECTED_CASES
: caseTitle == null
? i18n.DELETE_THIS_CASE
: i18n.DELETE_TITLE(caseTitle)
}
title={i18n.DELETE_SELECTED_CASES(caseQuantity, caseTitle)}
>
{isPlural ? i18n.CONFIRM_QUESTION_PLURAL : i18n.CONFIRM_QUESTION}
{i18n.CONFIRM_QUESTION(caseQuantity)}
</EuiConfirmModal>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,15 @@ export const DELETE_TITLE = (caseTitle: string) =>
defaultMessage: 'Delete "{caseTitle}"',
});

export const DELETE_THIS_CASE = (caseTitle: string) =>
i18n.translate('xpack.cases.confirmDeleteCase.deleteThisCase', {
defaultMessage: 'Delete this case',
export const DELETE_SELECTED_CASES = (quantity: number, title: string) =>
i18n.translate('xpack.cases.confirmDeleteCase.selectedCases', {
values: { quantity, title },
defaultMessage: 'Delete "{quantity, plural, =1 {{title}} other {Selected {quantity} cases}}"',
});

export const CONFIRM_QUESTION = i18n.translate('xpack.cases.confirmDeleteCase.confirmQuestion', {
defaultMessage:
'By deleting this case, all related case data will be permanently removed and you will no longer be able to push data to an external incident management system. Are you sure you wish to proceed?',
});
export const DELETE_SELECTED_CASES = i18n.translate('xpack.cases.confirmDeleteCase.selectedCases', {
defaultMessage: 'Delete selected cases',
});

export const CONFIRM_QUESTION_PLURAL = i18n.translate(
'xpack.cases.confirmDeleteCase.confirmQuestionPlural',
{
export const CONFIRM_QUESTION = (quantity: number) =>
i18n.translate('xpack.cases.confirmDeleteCase.confirmQuestion', {
values: { quantity },
defaultMessage:
'By deleting these cases, all related case data will be permanently removed and you will no longer be able to push data to an external incident management system. Are you sure you wish to proceed?',
}
);
'By deleting {quantity, plural, =1 {this case} other {these cases}}, all related case data will be permanently removed and you will no longer be able to push data to an external incident management system. Are you sure you wish to proceed?',
});
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ jest.mock('../common/lib/kibana');
describe('useDeleteCases', () => {
const abortCtrl = new AbortController();
const deleteObj = [
{ id: '1', type: CaseType.individual },
{ id: '2', type: CaseType.individual },
{ id: '3', type: CaseType.individual },
{ id: '1', type: CaseType.individual, title: 'case 1' },
{ id: '2', type: CaseType.individual, title: 'case 2' },
{ id: '3', type: CaseType.individual, title: 'case 3' },
];
const deleteArr = ['1', '2', '3'];
it('init', async () => {
Expand Down

0 comments on commit 037d7ae

Please sign in to comment.