fix(striker-ui): add purge file confirm dialog

main
Tsu-ba-me 3 years ago
parent 9ec5b4398c
commit 24442d524b
  1. 68
      striker-ui/components/ConfirmDialog.tsx
  2. 50
      striker-ui/components/Files/FileEditForm.tsx

@ -0,0 +1,68 @@
import { MouseEventHandler } from 'react';
import { Box, ButtonProps, Dialog, DialogProps } from '@mui/material';
import ContainedButton from './ContainedButton';
import { Panel, PanelHeader } from './Panels';
import { BodyText, HeaderText } from './Text';
type ConfirmDialogProps = {
actionCancelText?: string;
actionProceedText: string;
contentText: string;
dialogProps: DialogProps;
onCancel: MouseEventHandler<HTMLButtonElement>;
onProceed: MouseEventHandler<HTMLButtonElement>;
proceedButtonProps?: ButtonProps;
titleText: string;
};
const CONFIRM_DIALOG_DEFAULT_PROPS = {
actionCancelText: 'Cancel',
proceedButtonProps: { sx: undefined },
};
const ConfirmDialog = (
{
actionCancelText,
actionProceedText,
contentText,
dialogProps: { open },
onCancel,
onProceed,
proceedButtonProps,
titleText,
}: ConfirmDialogProps = CONFIRM_DIALOG_DEFAULT_PROPS as ConfirmDialogProps,
): JSX.Element => {
const { sx: proceedButtonSx } =
proceedButtonProps ?? CONFIRM_DIALOG_DEFAULT_PROPS.proceedButtonProps;
return (
<Dialog {...{ open }} PaperComponent={Panel}>
<PanelHeader>
<HeaderText text={titleText} />
</PanelHeader>
<BodyText sx={{ marginBottom: '1em' }} text={contentText} />
<Box
sx={{
display: 'flex',
flexDirection: 'row',
justifyContent: 'flex-end',
width: '100%',
'& > :not(:first-child)': {
marginLeft: '.5em',
},
}}
>
<ContainedButton onClick={onCancel}>{actionCancelText}</ContainedButton>
<ContainedButton sx={proceedButtonSx} onClick={onProceed}>
{actionProceedText}
</ContainedButton>
</Box>
</Dialog>
);
};
ConfirmDialog.defaultProps = CONFIRM_DIALOG_DEFAULT_PROPS;
export default ConfirmDialog;

@ -9,6 +9,7 @@ import { Box, Checkbox, checkboxClasses } from '@mui/material';
import API_BASE_URL from '../../lib/consts/API_BASE_URL'; import API_BASE_URL from '../../lib/consts/API_BASE_URL';
import { GREY, RED, TEXT } from '../../lib/consts/DEFAULT_THEME'; import { GREY, RED, TEXT } from '../../lib/consts/DEFAULT_THEME';
import ConfirmDialog from '../ConfirmDialog';
import ContainedButton from '../ContainedButton'; import ContainedButton from '../ContainedButton';
import FileInfo from './FileInfo'; import FileInfo from './FileInfo';
import Spinner from '../Spinner'; import Spinner from '../Spinner';
@ -29,6 +30,16 @@ const FileEditForm = ({ filesOverview }: FileEditProps): JSX.Element => {
const [filesToEdit, setFilesToEdit] = useState<FileToEdit[]>([]); const [filesToEdit, setFilesToEdit] = useState<FileToEdit[]>([]);
const [isLoadingFilesToEdit, setIsLoadingFilesToEdit] = const [isLoadingFilesToEdit, setIsLoadingFilesToEdit] =
useState<boolean>(false); useState<boolean>(false);
const [isOpenPurgeConfirmDialog, setIsOpenConfirmPurgeDialog] =
useState<boolean>(false);
const [selectedFilesCount, setSelectedFilesCount] = useState<number>(0);
const purgeButtonStyleOverride = {
backgroundColor: RED,
color: TEXT,
'&:hover': { backgroundColor: RED },
};
const generateFileInfoChangeHandler = const generateFileInfoChangeHandler =
(fileIndex: number): FileInfoChangeHandler => (fileIndex: number): FileInfoChangeHandler =>
@ -70,6 +81,8 @@ const FileEditForm = ({ filesOverview }: FileEditProps): JSX.Element => {
}; };
const purgeFiles: MouseEventHandler<HTMLButtonElement> = () => { const purgeFiles: MouseEventHandler<HTMLButtonElement> = () => {
setIsOpenConfirmPurgeDialog(false);
filesToEdit filesToEdit
.filter(({ isSelected }) => isSelected) .filter(({ isSelected }) => isSelected)
.forEach(({ fileUUID }) => { .forEach(({ fileUUID }) => {
@ -77,6 +90,26 @@ const FileEditForm = ({ filesOverview }: FileEditProps): JSX.Element => {
}); });
}; };
const cancelPurge: MouseEventHandler<HTMLButtonElement> = () => {
setIsOpenConfirmPurgeDialog(false);
};
const confirmPurge: MouseEventHandler<HTMLButtonElement> = () => {
// We need this local variable because setState functions are async; the
// changes won't reflect until the next render cycle.
// In this case, the user would have to click on the purge button twice to
// trigger the confirmation dialog without using this local variable.
const localSelectedFilesCount = filesToEdit.filter(
({ isSelected }) => isSelected,
).length;
setSelectedFilesCount(localSelectedFilesCount);
if (localSelectedFilesCount > 0) {
setIsOpenConfirmPurgeDialog(true);
}
};
useEffect(() => { useEffect(() => {
setIsLoadingFilesToEdit(true); setIsLoadingFilesToEdit(true);
@ -182,12 +215,8 @@ const FileEditForm = ({ filesOverview }: FileEditProps): JSX.Element => {
}} }}
> >
<ContainedButton <ContainedButton
onClick={purgeFiles} onClick={confirmPurge}
sx={{ sx={purgeButtonStyleOverride}
backgroundColor: RED,
color: TEXT,
'&:hover': { backgroundColor: RED },
}}
> >
Purge Purge
</ContainedButton> </ContainedButton>
@ -195,6 +224,15 @@ const FileEditForm = ({ filesOverview }: FileEditProps): JSX.Element => {
</Box> </Box>
)} )}
</Box> </Box>
<ConfirmDialog
actionProceedText="Purge"
contentText={`${selectedFilesCount} files will be removed from the system. You cannot undo this purge.`}
dialogProps={{ open: isOpenPurgeConfirmDialog }}
onCancel={cancelPurge}
onProceed={purgeFiles}
proceedButtonProps={{ sx: purgeButtonStyleOverride }}
titleText={`Are you sure you want to purge ${selectedFilesCount} selected files? `}
/>
</form> </form>
)} )}
</> </>

Loading…
Cancel
Save