Changed error modal snackbar (#1093)

Changed error modal snackbar to use a simplified style of global error snackbar. also fixed an issue where error was persistent if you closed the modalbox with an error present

Signed-off-by: Benjamin Perez <benjamin@bexsoft.net>

Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
This commit is contained in:
Alex
2021-09-30 11:25:34 -05:00
committed by GitHub
parent dfca19092a
commit 7a864d2631
2 changed files with 257 additions and 1 deletions

View File

@@ -0,0 +1,248 @@
// This file is part of MinIO Console Server
// Copyright (c) 2021 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// This file is part of MinIO Console Server
// Copyright (c) 2021 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React, { Fragment, useState, useEffect, useCallback } from "react";
import { connect } from "react-redux";
import get from "lodash/get";
import ArrowRightIcon from "@material-ui/icons/ArrowRight";
import ErrorOutlineIcon from "@material-ui/icons/ErrorOutline";
import CloseIcon from "@material-ui/icons/Close";
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
import { AppState } from "../../../../../store";
import { setErrorSnackMessage } from "../../../../../actions";
import { snackBarMessage } from "../../../../../types";
import {
setModalErrorSnackMessage,
setModalSnackMessage,
} from "../../../../../actions";
interface ImodalErrorProps {
customStyle?: any;
classes: any;
modalSnackMessage: snackBarMessage;
displayErrorMessage: typeof setErrorSnackMessage;
}
const styles = (theme: Theme) =>
createStyles({
modalErrorContainer: {
position: "absolute",
marginTop: 10,
width: "80%",
backgroundColor: "#fff",
border: "#C72C48 1px solid",
borderLeftWidth: 12,
borderRadius: 3,
zIndex: 1000,
padding: "10px 15px",
left: "50%",
transform: "translateX(-50%)",
opacity: 0,
transitionDuration: "0.2s",
},
modalErrorShow: {
opacity: 1,
},
closeButton: {
position: "absolute",
right: 5,
fontSize: "small",
border: 0,
backgroundColor: "#fff",
cursor: "pointer",
},
errorTitle: {
display: "flex",
alignItems: "center",
},
errorLabel: {
color: "#000",
fontSize: 18,
fontWeight: 500,
marginLeft: 5,
marginRight: 25,
},
messageIcon: {
color: "#C72C48",
display: "flex",
"& svg": {
width: 32,
height: 32,
},
},
simpleError: {
marginTop: 5,
padding: "2px 5px",
fontSize: 16,
color: "#000",
},
detailsButton: {
color: "#9C9C9C",
display: "flex",
alignItems: "center",
border: 0,
backgroundColor: "transparent",
paddingLeft: 5,
fontSize: 14,
transformDuration: "0.3s",
cursor: "pointer",
},
extraDetailsContainer: {
fontStyle: "italic",
color: "#9C9C9C",
lineHeight: 0,
padding: "0 10px",
transition: "all .2s ease-in-out",
overflow: "hidden",
},
extraDetailsOpen: {
lineHeight: 1,
padding: "3px 10px",
},
arrowElement: {
marginLeft: -5,
},
arrowOpen: {
transform: "rotateZ(90deg)",
transformDuration: "0.3s",
},
});
var timerI: any;
const startHideTimer = (callbackFunction: () => void) => {
timerI = setInterval(callbackFunction, 10000);
};
const stopHideTimer = () => {
clearInterval(timerI);
};
const ModalError = ({
classes,
modalSnackMessage,
displayErrorMessage,
customStyle,
}: ImodalErrorProps) => {
const [detailsOpen, setDetailsOpen] = useState<boolean>(false);
const [displayErrorMsg, setDisplayErrorMsg] = useState<boolean>(false);
const closeErrorMessage = useCallback(() => {
setDisplayErrorMsg(false);
}, []);
useEffect(() => {
if (!displayErrorMsg) {
displayErrorMessage({ detailedError: "", errorMessage: "" });
setDetailsOpen(false);
//clearInterval(timerI);
}
}, [displayErrorMessage, displayErrorMsg]);
useEffect(() => {
if (
modalSnackMessage.message !== "" &&
modalSnackMessage.type === "error"
) {
//Error message received, we trigger the animation
setDisplayErrorMsg(true);
//startHideTimer(closeErrorMessage);
}
}, [closeErrorMessage, modalSnackMessage.message, modalSnackMessage.type]);
const detailsToggle = () => {
setDetailsOpen(!detailsOpen);
};
const message = get(modalSnackMessage, "message", "");
const messageDetails = get(modalSnackMessage, "detailedErrorMsg", "");
if (modalSnackMessage.type !== "error" || message === "") {
return null;
}
return (
<Fragment>
<div
className={`${classes.modalErrorContainer} ${
displayErrorMsg ? classes.modalErrorShow : ""
}`}
style={customStyle}
onMouseOver={stopHideTimer}
onMouseLeave={() => startHideTimer(closeErrorMessage)}
>
<button className={classes.closeButton} onClick={closeErrorMessage}>
<CloseIcon />
</button>
<div className={classes.errorTitle}>
<span className={classes.messageIcon}>
<ErrorOutlineIcon />
</span>
<span className={classes.errorLabel}>{message}</span>
</div>
{messageDetails !== "" && (
<Fragment>
<div className={classes.detailsContainerLink}>
<button className={classes.detailsButton} onClick={detailsToggle}>
Details
<ArrowRightIcon
className={`${classes.arrowElement} ${
detailsOpen ? classes.arrowOpen : ""
}`}
/>
</button>
</div>
<div
className={`${classes.extraDetailsContainer} ${
detailsOpen ? classes.extraDetailsOpen : ""
}`}
>
{messageDetails}
</div>
</Fragment>
)}
</div>
</Fragment>
);
};
const mapState = (state: AppState) => ({
modalSnackMessage: state.system.modalSnackBar,
});
const mapDispatchToProps = {
displayErrorMessage: setModalErrorSnackMessage,
};
const connector = connect(mapState, mapDispatchToProps);
export default connector(withStyles(styles)(ModalError));

View File

@@ -23,6 +23,7 @@ import { snackBarCommon } from "../FormComponents/common/styleLibrary";
import { AppState } from "../../../../store";
import { snackBarMessage } from "../../../../types";
import { setModalSnackMessage } from "../../../../actions";
import ModalError from "../FormComponents/ModalError/ModalError";
interface IModalProps {
classes: any;
@@ -124,6 +125,10 @@ const ModalWrapper = ({
}: IModalProps) => {
const [openSnackbar, setOpenSnackbar] = useState<boolean>(false);
useEffect(() => {
setModalSnackMessage("");
}, [setModalSnackMessage]);
useEffect(() => {
if (modalSnackMessage) {
if (modalSnackMessage.message === "") {
@@ -131,7 +136,9 @@ const ModalWrapper = ({
return;
}
// Open SnackBar
setOpenSnackbar(true);
if(modalSnackMessage.type !== "error") {
setOpenSnackbar(true);
}
}
}, [modalSnackMessage]);
@@ -169,6 +176,7 @@ const ModalWrapper = ({
{...customSize}
>
<div className={classes.dialogContainer}>
<ModalError />
<Snackbar
open={openSnackbar}
className={classes.snackBarModal}