Skip to content

Commit

Permalink
implemented don't ask again checkbox on each deletion dialog, forgot …
Browse files Browse the repository at this point in the history
…to implement this on the AllArchivesView, will do tests after and fix UI for AutomatedRule dialog where the two checkboxes look weird together
  • Loading branch information
maxcao13 committed Jun 25, 2022
1 parent c66d1ba commit bd049e1
Show file tree
Hide file tree
Showing 10 changed files with 301 additions and 111 deletions.
25 changes: 17 additions & 8 deletions src/app/Events/EventTemplates.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,13 @@ import { NotificationCategory } from '@app/Shared/Services/NotificationChannel.s
import { NO_TARGET } from '@app/Shared/Services/Target.service';
import { useSubscriptions } from '@app/utils/useSubscriptions';
import { ActionGroup, Button, FileUpload, Form, FormGroup, Modal, ModalVariant, Toolbar, ToolbarContent, ToolbarGroup, ToolbarItem, TextInput } from '@patternfly/react-core';
import { PlusIcon, UploadIcon } from '@patternfly/react-icons';
import { UploadIcon } from '@patternfly/react-icons';
import { Table, TableBody, TableHeader, TableVariant, IAction, IRowData, IExtraData, ISortBy, SortByDirection, sortable } from '@patternfly/react-table';
import { useHistory } from 'react-router-dom';
import { concatMap, filter, first } from 'rxjs/operators';
import { LoadingView } from '@app/LoadingView/LoadingView';
import { ErrorView } from '@app/ErrorView/ErrorView';
import { DeleteWarningEnum } from '@app/Modal/DeleteWarningTypes';
import { DeleteWarningType } from '@app/Modal/DeleteWarningUtils';
import { DeleteWarningModal } from '@app/Modal/DeleteWarningModal';

export const EventTemplates = () => {
Expand Down Expand Up @@ -197,7 +197,7 @@ export const EventTemplates = () => {
title: 'Delete',
onClick: (event, rowId, rowData) => {
setRowDeleteData(rowData);
setWarningModalOpen(true);
handleDeleteButton();
},
}
]);
Expand Down Expand Up @@ -256,6 +256,15 @@ export const EventTemplates = () => {
setSortBy({ index, direction });
};

const handleDeleteButton = () => {
if (context.settings.deletionDialogsEnabledFor(DeleteWarningType.DeleteEventTemplates)) {
setWarningModalOpen(true);
}
else {
handleDelete(rowDeleteData)
}
}

const toolbar: JSX.Element = (<>
<Toolbar id="event-templates-toolbar">
<ToolbarContent>
Expand All @@ -272,13 +281,13 @@ export const EventTemplates = () => {
</ToolbarItem>
</ToolbarGroup>
<DeleteWarningModal
warningType={DeleteWarningEnum.DeleteEventTemplates}
warningType={DeleteWarningType.DeleteEventTemplates}
items={[rowDeleteData[0]]}
visible={warningModalOpen}
onAccept={() => handleDelete(rowDeleteData)}
visible={warningModalOpen}
onAccept={() => handleDelete(rowDeleteData)}
onClose={() => setWarningModalOpen(false)}
/>
</ToolbarContent>
setShowDialog={() => {context.settings.setDeletionDialogsEnabledFor(DeleteWarningType.DeleteEventTemplates, false)}}/>
</ToolbarContent>
</Toolbar>
</>);

Expand Down
63 changes: 27 additions & 36 deletions src/app/Modal/DeleteWarningModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,65 +36,51 @@
* SOFTWARE.
*/
import * as React from 'react';
import { Modal, ModalVariant, Button, Title, TitleSizes, Checkbox, Stack, Split, ModalBoxBody } from '@patternfly/react-core';
import { Modal, ModalVariant, Button, Title, TitleSizes, Checkbox, Stack, Split, } from '@patternfly/react-core';
import WarningTriangleIcon from '@patternfly/react-icons/dist/esm/icons/warning-triangle-icon';
import { DeleteActiveRecordings, DeleteArchivedRecordings, DeleteEventTemplates, DeleteAutomatedRules, DeleteJMXCredentials, DeleteWarningType, DeleteWarningEnum, DeleteUndefined } from './DeleteWarningTypes';
import { DeleteAutomatedRules, DeleteWarningType, getFromWarningMap } from './DeleteWarningUtils';
import { useState } from 'react';

export interface DeleteWarningProps {
warningType: DeleteWarningEnum;
warningType: DeleteWarningType;
items?: Array<string>;
visible: boolean;
onAccept: () => void;
onClose: () => void;
setShowDialog: () => void;
checkbox?: boolean;
setCheckbox?: React.Dispatch<React.SetStateAction<boolean>>;
}

const delMap : DeleteWarningType[] = [
DeleteActiveRecordings,
DeleteArchivedRecordings,
DeleteAutomatedRules,
DeleteEventTemplates,
DeleteJMXCredentials
];
export const DeleteWarningModal = ({ warningType , items, visible, onAccept, onClose, setShowDialog, checkbox, setCheckbox}: DeleteWarningProps): JSX.Element => {
const [doNotAsk, setDoNotAsk] = useState(false);
const realWarningType = getFromWarningMap(warningType);

function getFromWarningMap(warning: DeleteWarningEnum) : DeleteWarningType {
const wt = delMap.find(t => t.id === warning);
return (wt === undefined) ? DeleteUndefined : wt;
}

export const DeleteWarningModal = ({ warningType , items, visible, onAccept, onClose, checkbox, setCheckbox}: DeleteWarningProps): JSX.Element => {
const realWarningType : DeleteWarningType = getFromWarningMap(warningType);

const description = `${realWarningType.description}${(typeof items === 'undefined' || items.length <= 1) ? "":"s"}: [${items?.join(", ")}] ?`

const footer = (
<Title headingLevel="h4" size={TitleSizes.md}>
<WarningTriangleIcon />
<span className="pf-u-pl-sm">This cannot be undone.</span>
</Title>
);
const description = `${realWarningType?.description}${(typeof items === 'undefined' || items.length <= 1) ? "":"s"}: [${items?.join(", ")}] ?`

const onAcceptClose = () => {
onAccept();
onClose();
console.log(doNotAsk)
if (doNotAsk) {
setShowDialog();
}
}

return (
<Modal
isOpen={visible}
aria-label={realWarningType.ariaLabel}
variant={ModalVariant.small}
title={realWarningType?.title}
description={description}
aria-label={realWarningType?.ariaLabel}
titleIconVariant="warning"
showClose={true}
variant={ModalVariant.small}
isOpen={visible}
showClose
onClose={onClose}
title={realWarningType.title}
description={description}
hasNoBodyWrapper={realWarningType !== DeleteAutomatedRules}
actions={[
<Stack hasGutter={true}>
<Split>
<Button variant="danger" onClick={onAcceptClose}>
<Stack hasGutter key="modal-footer-stack">
<Split key="modal-footer-split">
<Button variant="danger" onClick={() => onAcceptClose()}>
Delete
</Button>
<Button variant="link" onClick={onClose}>
Expand All @@ -115,6 +101,11 @@ export const DeleteWarningModal = ({ warningType , items, visible, onAccept, onC
isChecked={checkbox}
onChange={(checked) => setCheckbox(checked)}
/>}
<Checkbox id="do-not-ask-enabled"
label="Don't ask me again"
isChecked={doNotAsk}
onChange={(checked) => setDoNotAsk(checked)}
/>
</Modal>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -35,60 +35,65 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
export enum DeleteWarningEnum {
DeleteActiveRecordings,
DeleteArchivedRecordings,
DeleteAutomatedRules,
DeleteEventTemplates,
DeleteJMXCredentials,
DeleteUndefined
export enum DeleteWarningType {
DeleteActiveRecordings='DeleteActiveRecordings',
DeleteArchivedRecordings='DeleteArchivedRecordings',
DeleteAutomatedRules='DeleteAutomatedRules',
DeleteEventTemplates='DeleteEventTemplates',
DeleteJMXCredentials='DeleteJMXCredentials',
}

export interface DeleteWarningType {
id: DeleteWarningEnum;
export interface DeleteWarning {
id: DeleteWarningType;
title: string;
description: string;
ariaLabel: string;
}

export const DeleteActiveRecordings: DeleteWarningType = {
id: DeleteWarningEnum.DeleteActiveRecordings,
export const DeleteActiveRecordings: DeleteWarning = {
id: DeleteWarningType.DeleteActiveRecordings,
title: 'Delete Active Recording',
description: `Delete Active Recording`,
ariaLabel: "Recording delete warning"
}

export const DeleteArchivedRecordings: DeleteWarningType = {
id: DeleteWarningEnum.DeleteArchivedRecordings,
export const DeleteArchivedRecordings: DeleteWarning = {
id: DeleteWarningType.DeleteArchivedRecordings,
title: 'Delete Archived Recording',
description: `Delete Archived Recording`,
ariaLabel: "Recording delete warning"
}

export const DeleteAutomatedRules: DeleteWarningType = {
id: DeleteWarningEnum.DeleteAutomatedRules,
export const DeleteAutomatedRules: DeleteWarning = {
id: DeleteWarningType.DeleteAutomatedRules,
title: 'Delete Automated Rule',
description: `Delete Automated Rule`,
ariaLabel: "Automated rule delete warning"
}

export const DeleteEventTemplates: DeleteWarningType = {
id: DeleteWarningEnum.DeleteEventTemplates,
export const DeleteEventTemplates: DeleteWarning = {
id: DeleteWarningType.DeleteEventTemplates,
title: 'Delete Event Template',
description: `Delete Event Template`,
ariaLabel: "Event template delete warning"
}

export const DeleteJMXCredentials: DeleteWarningType = {
id: DeleteWarningEnum.DeleteJMXCredentials,
export const DeleteJMXCredentials: DeleteWarning = {
id: DeleteWarningType.DeleteJMXCredentials,
title: 'Delete JMX Credentials',
description: `Delete JMX Credentials for target`,
ariaLabel: "JMX Credential delete warning"
ariaLabel: "JMX Credentials delete warning"
}

export const DeleteUndefined: DeleteWarningType = {
id: DeleteWarningEnum.DeleteUndefined,
title: 'Undefined',
description: 'Undefined',
ariaLabel: 'Undefined'
}
export const delMap : DeleteWarning[] = [
DeleteActiveRecordings,
DeleteArchivedRecordings,
DeleteAutomatedRules,
DeleteEventTemplates,
DeleteJMXCredentials
];

export const getFromWarningMap = (warning: DeleteWarningType): DeleteWarning | undefined => {
const wt = delMap.find(t => t.id === warning);
return wt;
}
26 changes: 18 additions & 8 deletions src/app/Recordings/ActiveRecordingsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ import { RecordingLabelsPanel } from './RecordingLabelsPanel';
import { RecordingsTable } from './RecordingsTable';
import { ReportFrame } from './ReportFrame';
import { DeleteWarningModal } from '../Modal/DeleteWarningModal';
import { DeleteWarningEnum } from '@app/Modal/DeleteWarningTypes';
import { DeleteWarningType } from '@app/Modal/DeleteWarningUtils';

export interface ActiveRecordingsTableProps {
archiveEnabled: boolean;
Expand All @@ -69,7 +69,7 @@ export const ActiveRecordingsTable: React.FunctionComponent<ActiveRecordingsTabl
const [checkedIndices, setCheckedIndices] = React.useState([] as number[]);
const [expandedRows, setExpandedRows] = React.useState([] as string[]);
const [showDetailsPanel, setShowDetailsPanel] = React.useState(false);
const [showWarningModal, setShowWarningModal] = React.useState(false);
const [warningModalOpen, setWarningModalOpen] = React.useState(false);
const [isLoading, setIsLoading] = React.useState(false);
const [errorMessage, setErrorMessage] = React.useState('');
const { url } = useRouteMatch();
Expand Down Expand Up @@ -427,6 +427,15 @@ export const ActiveRecordingsTable: React.FunctionComponent<ActiveRecordingsTabl
setExpandedRows(expandedRows => idx >= 0 ? [...expandedRows.slice(0, idx), ...expandedRows.slice(idx + 1, expandedRows.length)] : [...expandedRows, id]);
};

const handleDeleteButton = () => {
if (context.settings.deletionDialogsEnabledFor(DeleteWarningType.DeleteActiveRecordings)) {
setWarningModalOpen(true);
}
else {
handleDeleteRecordings();
}
}

const RecordingsToolbar = () => {
const isStopDisabled = React.useMemo(() => {
if (!checkedIndices.length) {
Expand All @@ -453,7 +462,7 @@ export const ActiveRecordingsTable: React.FunctionComponent<ActiveRecordingsTabl
<Button key="stop" variant="tertiary" onClick={handleStopRecordings} isDisabled={isStopDisabled}>Stop</Button>
));
arr.push((
<Button key="delete" variant="danger" onClick={() => setShowWarningModal(true)} isDisabled={!checkedIndices.length}>Delete</Button>
<Button key="delete" variant="danger" onClick={handleDeleteButton} isDisabled={!checkedIndices.length}>Delete</Button>
));
return <>
{
Expand All @@ -469,11 +478,12 @@ export const ActiveRecordingsTable: React.FunctionComponent<ActiveRecordingsTabl
const deleteActiveWarningModal = React.useMemo(() => {
const filtered = recordings.filter((r: ActiveRecording, idx: number) => checkedIndices.includes(idx));
return <DeleteWarningModal
warningType={DeleteWarningEnum.DeleteActiveRecordings}
items={filtered.map((r) => `${r.name}`)}
visible={showWarningModal}
onAccept={handleDeleteRecordings}
onClose={() => {setShowWarningModal(false)}}
warningType={DeleteWarningType.DeleteActiveRecordings}
items={filtered.map((r) => `${r.name}`)}
visible={warningModalOpen}
onAccept={handleDeleteRecordings}
onClose={() => { setWarningModalOpen(false); } }
setShowDialog={() => {context.settings.setDeletionDialogsEnabledFor(DeleteWarningType.DeleteActiveRecordings, false)}}
/>
}, [recordings, checkedIndices]);

Expand Down
28 changes: 19 additions & 9 deletions src/app/Recordings/ArchivedRecordingsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ import { parseLabels } from '@app/RecordingMetadata/RecordingLabel';
import { LabelCell } from '../RecordingMetadata/LabelCell';
import { RecordingLabelsPanel } from './RecordingLabelsPanel';
import { DeleteWarningModal } from '@app/Modal/DeleteWarningModal';
import { DeleteWarningEnum } from '@app/Modal/DeleteWarningTypes';
import { DeleteWarningType } from '@app/Modal/DeleteWarningUtils';

export interface ArchivedRecordingsTableProps { }

Expand All @@ -64,7 +64,7 @@ export const ArchivedRecordingsTable: React.FunctionComponent<ArchivedRecordings
const [checkedIndices, setCheckedIndices] = React.useState([] as number[]);
const [expandedRows, setExpandedRows] = React.useState([] as string[]);
const [showDetailsPanel, setShowDetailsPanel] = React.useState(false);
const [showWarningModal, setShowWarningModal] = React.useState(false);
const [warningModalOpen, setWarningModalOpen] = React.useState(false);
const [isLoading, setIsLoading] = React.useState(false);
const addSubscription = useSubscriptions();

Expand Down Expand Up @@ -303,16 +303,26 @@ export const ArchivedRecordingsTable: React.FunctionComponent<ArchivedRecordings
);
};

const handleDeleteButton = () => {
if (context.settings.deletionDialogsEnabledFor(DeleteWarningType.DeleteArchivedRecordings)) {
setWarningModalOpen(true);
}
else {
handleDeleteRecordings();
}
}

const RecordingsToolbar = () => {
const deleteArchivedWarningModal = React.useMemo(() => {
const filtered = recordings.filter((r: ArchivedRecording, idx: number) => checkedIndices.includes(idx));
return <DeleteWarningModal
warningType={DeleteWarningEnum.DeleteArchivedRecordings}
items={filtered.map((r) => `${r.name}`)}
visible={showWarningModal}
onAccept={handleDeleteRecordings}
onClose={() => {setShowWarningModal(false)}}
/>
warningType={DeleteWarningType.DeleteArchivedRecordings}
items={filtered.map((r) => `${r.name}`)}
visible={warningModalOpen}
onAccept={handleDeleteRecordings}
onClose={() => setWarningModalOpen(false)}
setShowDialog={() => {context.settings.setDeletionDialogsEnabledFor(DeleteWarningType.DeleteArchivedRecordings, false)}}
/>
}, [recordings, checkedIndices]);

return (
Expand All @@ -323,7 +333,7 @@ export const ArchivedRecordingsTable: React.FunctionComponent<ArchivedRecordings
<Button key="edit labels" variant="secondary" onClick={handleEditLabels} isDisabled={!checkedIndices.length}>Edit Labels</Button>
</ToolbarItem>
<ToolbarItem>
<Button variant="danger" onClick={() => setShowWarningModal(true)} isDisabled={!checkedIndices.length}>Delete</Button>
<Button variant="danger" onClick={handleDeleteButton} isDisabled={!checkedIndices.length}>Delete</Button>
</ToolbarItem>
</ToolbarGroup>
{ deleteArchivedWarningModal }
Expand Down
Loading

0 comments on commit bd049e1

Please sign in to comment.