feat: add confirmation dialog for imports (#11983)

* feat: add confirmation dialog for imports

* Small fixes

* Clean return
This commit is contained in:
Beto Dealmeida
2020-12-11 17:23:43 -08:00
committed by GitHub
parent 696308715d
commit 9277a54a12
7 changed files with 129 additions and 37 deletions

View File

@@ -34,6 +34,7 @@ const requiredProps = {
resourceLabel: 'database',
icon: <StyledIcon name="database" />,
passwordsNeededMessage: 'Passwords are needed',
confirmOverwriteMessage: 'Database exists',
addDangerToast: () => {},
addSuccessToast: () => {},
onModelImport: () => {},

View File

@@ -102,6 +102,7 @@ export interface ImportModelsModalProps {
resourceLabel: string;
icon: React.ReactNode;
passwordsNeededMessage: string;
confirmOverwriteMessage: string;
addDangerToast: (msg: string) => void;
addSuccessToast: (msg: string) => void;
onModelImport: () => void;
@@ -116,6 +117,7 @@ const ImportModelsModal: FunctionComponent<ImportModelsModalProps> = ({
resourceLabel,
icon,
passwordsNeededMessage,
confirmOverwriteMessage,
addDangerToast,
addSuccessToast,
onModelImport,
@@ -124,9 +126,14 @@ const ImportModelsModal: FunctionComponent<ImportModelsModalProps> = ({
passwordFields = [],
setPasswordFields = () => {},
}) => {
const [uploadFile, setUploadFile] = useState<File | null>(null);
const [isHidden, setIsHidden] = useState<boolean>(true);
const [uploadFile, setUploadFile] = useState<File | null>(null);
const [passwords, setPasswords] = useState<Record<string, string>>({});
const [needsOverwriteConfirm, setNeedsOverwriteConfirm] = useState<boolean>(
false,
);
const [confirmedOverwrite, setConfirmedOverwrite] = useState<boolean>(false);
const fileInputRef = useRef<HTMLInputElement>(null);
const clearModal = () => {
@@ -144,7 +151,7 @@ const ImportModelsModal: FunctionComponent<ImportModelsModalProps> = ({
};
const {
state: { passwordsNeeded },
state: { alreadyExists, passwordsNeeded },
importResource,
} = useImportResource(resourceName, resourceLabel, handleErrorMsg);
@@ -152,6 +159,10 @@ const ImportModelsModal: FunctionComponent<ImportModelsModalProps> = ({
setPasswordFields(passwordsNeeded);
}, [passwordsNeeded, setPasswordFields]);
useEffect(() => {
setNeedsOverwriteConfirm(alreadyExists.length > 0);
}, [alreadyExists]);
// Functions
const hide = () => {
setIsHidden(true);
@@ -163,7 +174,7 @@ const ImportModelsModal: FunctionComponent<ImportModelsModalProps> = ({
return;
}
importResource(uploadFile, passwords).then(result => {
importResource(uploadFile, passwords, confirmedOverwrite).then(result => {
if (result) {
addSuccessToast(t('The import was successful'));
clearModal();
@@ -177,6 +188,11 @@ const ImportModelsModal: FunctionComponent<ImportModelsModalProps> = ({
setUploadFile((files && files[0]) || null);
};
const confirmOverwrite = (event: React.ChangeEvent<HTMLInputElement>) => {
const targetValue = (event.currentTarget?.value as string) ?? '';
setConfirmedOverwrite(targetValue.toUpperCase() === t('OVERWRITE'));
};
const renderPasswordFields = () => {
if (passwordFields.length === 0) {
return null;
@@ -209,6 +225,31 @@ const ImportModelsModal: FunctionComponent<ImportModelsModalProps> = ({
);
};
const renderOverwriteConfirmation = () => {
if (alreadyExists.length === 0) {
return null;
}
return (
<>
<StyledInputContainer>
<div>{confirmOverwriteMessage}</div>
<div className="control-label">
<label htmlFor="overwrite">
{t('Type "%s" to confirm', t('OVERWRITE'))}
</label>
</div>
<input
data-test="overwrite-modal-input"
id="overwrite"
type="text"
onChange={confirmOverwrite}
/>
</StyledInputContainer>
</>
);
};
// Show/hide
if (isHidden && show) {
setIsHidden(false);
@@ -218,10 +259,13 @@ const ImportModelsModal: FunctionComponent<ImportModelsModalProps> = ({
<Modal
name="model"
className="import-model-modal"
disablePrimaryButton={uploadFile === null}
disablePrimaryButton={
uploadFile === null || (needsOverwriteConfirm && !confirmedOverwrite)
}
onHandledPrimaryAction={onUpload}
onHide={hide}
primaryButtonName={t('Import')}
primaryButtonName={needsOverwriteConfirm ? t('Overwrite') : t('Import')}
primaryButtonType={needsOverwriteConfirm ? 'danger' : 'primary'}
width="750px"
show={show}
title={
@@ -249,6 +293,7 @@ const ImportModelsModal: FunctionComponent<ImportModelsModalProps> = ({
/>
</StyledInputContainer>
{renderPasswordFields()}
{renderOverwriteConfirmation()}
</Modal>
);
};