Added new implementation for error handling (#901)

Now errors will display detailed information, modal box errors will prioritize detailed errors
This commit is contained in:
Alex
2021-07-28 01:27:27 -05:00
committed by GitHub
parent 87917e618c
commit 13844e10f8
33 changed files with 370 additions and 67 deletions

View File

@@ -1,25 +1,25 @@
{
"files": {
"main.css": "/static/css/main.8cfac526.chunk.css",
"main.js": "/static/js/main.926c7b22.chunk.js",
"main.js.map": "/static/js/main.926c7b22.chunk.js.map",
"main.js": "/static/js/main.6ca7d2e8.chunk.js",
"main.js.map": "/static/js/main.6ca7d2e8.chunk.js.map",
"runtime-main.js": "/static/js/runtime-main.43a31377.js",
"runtime-main.js.map": "/static/js/runtime-main.43a31377.js.map",
"static/css/2.60e04a19.chunk.css": "/static/css/2.60e04a19.chunk.css",
"static/js/2.1bafa615.chunk.js": "/static/js/2.1bafa615.chunk.js",
"static/js/2.1bafa615.chunk.js.map": "/static/js/2.1bafa615.chunk.js.map",
"static/js/2.da0353b6.chunk.js": "/static/js/2.da0353b6.chunk.js",
"static/js/2.da0353b6.chunk.js.map": "/static/js/2.da0353b6.chunk.js.map",
"index.html": "/index.html",
"static/css/2.60e04a19.chunk.css.map": "/static/css/2.60e04a19.chunk.css.map",
"static/css/main.8cfac526.chunk.css.map": "/static/css/main.8cfac526.chunk.css.map",
"static/js/2.1bafa615.chunk.js.LICENSE.txt": "/static/js/2.1bafa615.chunk.js.LICENSE.txt",
"static/js/2.da0353b6.chunk.js.LICENSE.txt": "/static/js/2.da0353b6.chunk.js.LICENSE.txt",
"static/media/minio_console_logo.0837460e.svg": "/static/media/minio_console_logo.0837460e.svg",
"static/media/minio_operator_logo.1312b7c9.svg": "/static/media/minio_operator_logo.1312b7c9.svg"
},
"entrypoints": [
"static/js/runtime-main.43a31377.js",
"static/css/2.60e04a19.chunk.css",
"static/js/2.1bafa615.chunk.js",
"static/js/2.da0353b6.chunk.js",
"static/css/main.8cfac526.chunk.css",
"static/js/main.926c7b22.chunk.js"
"static/js/main.6ca7d2e8.chunk.js"
]
}

View File

@@ -1 +1 @@
<!doctype html><html lang="en"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="MinIO Console"/><link href="https://fonts.googleapis.com/css2?family=Lato:wght@400;500;700;900&display=swap" rel="stylesheet"/><link href="/styles/root-styles.css" rel="stylesheet"/><link rel="apple-touch-icon" sizes="180x180" href="/apple-icon-180x180.png"/><link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png"/><link rel="icon" type="image/png" sizes="96x96" href="/favicon-96x96.png"/><link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"/><link rel="manifest" href="/manifest.json"/><link rel="mask-icon" href="/safari-pinned-tab.svg" color="#3a4e54"/><title>MinIO Console</title><link href="/static/css/2.60e04a19.chunk.css" rel="stylesheet"><link href="/static/css/main.8cfac526.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"><div id="loader-block"><svg class="loader-svg-container" viewBox="22 22 44 44"><circle class="loader-style MuiCircularProgress-circle MuiCircularProgress-circleIndeterminate" cx="44" cy="44" r="20.2" fill="none" stroke-width="3.6"></circle></svg></div></div><script>!function(e){function r(r){for(var n,l,i=r[0],a=r[1],p=r[2],c=0,s=[];c<i.length;c++)l=i[c],Object.prototype.hasOwnProperty.call(o,l)&&o[l]&&s.push(o[l][0]),o[l]=0;for(n in a)Object.prototype.hasOwnProperty.call(a,n)&&(e[n]=a[n]);for(f&&f(r);s.length;)s.shift()();return u.push.apply(u,p||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,i=1;i<t.length;i++){var a=t[i];0!==o[a]&&(n=!1)}n&&(u.splice(r--,1),e=l(l.s=t[0]))}return e}var n={},o={1:0},u=[];function l(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,l),t.l=!0,t.exports}l.m=e,l.c=n,l.d=function(e,r,t){l.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},l.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},l.t=function(e,r){if(1&r&&(e=l(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(l.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)l.d(t,n,function(r){return e[r]}.bind(null,n));return t},l.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return l.d(r,"a",r),r},l.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},l.p="/";var i=this["webpackJsonpportal-ui"]=this["webpackJsonpportal-ui"]||[],a=i.push.bind(i);i.push=r,i=i.slice();for(var p=0;p<i.length;p++)r(i[p]);var f=a;t()}([])</script><script src="/static/js/2.1bafa615.chunk.js"></script><script src="/static/js/main.926c7b22.chunk.js"></script></body></html>
<!doctype html><html lang="en"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="MinIO Console"/><link href="https://fonts.googleapis.com/css2?family=Lato:wght@400;500;700;900&display=swap" rel="stylesheet"/><link href="/styles/root-styles.css" rel="stylesheet"/><link rel="apple-touch-icon" sizes="180x180" href="/apple-icon-180x180.png"/><link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png"/><link rel="icon" type="image/png" sizes="96x96" href="/favicon-96x96.png"/><link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"/><link rel="manifest" href="/manifest.json"/><link rel="mask-icon" href="/safari-pinned-tab.svg" color="#3a4e54"/><title>MinIO Console</title><link href="/static/css/2.60e04a19.chunk.css" rel="stylesheet"><link href="/static/css/main.8cfac526.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"><div id="loader-block"><svg class="loader-svg-container" viewBox="22 22 44 44"><circle class="loader-style MuiCircularProgress-circle MuiCircularProgress-circleIndeterminate" cx="44" cy="44" r="20.2" fill="none" stroke-width="3.6"></circle></svg></div></div><script>!function(e){function r(r){for(var n,l,i=r[0],a=r[1],p=r[2],c=0,s=[];c<i.length;c++)l=i[c],Object.prototype.hasOwnProperty.call(o,l)&&o[l]&&s.push(o[l][0]),o[l]=0;for(n in a)Object.prototype.hasOwnProperty.call(a,n)&&(e[n]=a[n]);for(f&&f(r);s.length;)s.shift()();return u.push.apply(u,p||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,i=1;i<t.length;i++){var a=t[i];0!==o[a]&&(n=!1)}n&&(u.splice(r--,1),e=l(l.s=t[0]))}return e}var n={},o={1:0},u=[];function l(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,l),t.l=!0,t.exports}l.m=e,l.c=n,l.d=function(e,r,t){l.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},l.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},l.t=function(e,r){if(1&r&&(e=l(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(l.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)l.d(t,n,function(r){return e[r]}.bind(null,n));return t},l.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return l.d(r,"a",r),r},l.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},l.p="/";var i=this["webpackJsonpportal-ui"]=this["webpackJsonpportal-ui"]||[],a=i.push.bind(i);i.push=r,i=i.slice();for(var p=0;p<i.length;p++)r(i[p]);var f=a;t()}([])</script><script src="/static/js/2.da0353b6.chunk.js"></script><script src="/static/js/main.6ca7d2e8.chunk.js"></script></body></html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -14,6 +14,7 @@
// 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 { ErrorResponseHandler } from "./common/types";
import {
MENU_OPEN,
OPERATOR_MODE,
@@ -85,7 +86,7 @@ export const setSnackBarMessage = (message: string) => {
};
};
export const setErrorSnackMessage = (message: string) => {
export const setErrorSnackMessage = (message: ErrorResponseHandler) => {
return {
type: SET_ERROR_SNACK_MESSAGE,
message,
@@ -99,7 +100,7 @@ export const setModalSnackMessage = (message: string) => {
};
};
export const setModalErrorSnackMessage = (message: string) => {
export const setModalErrorSnackMessage = (message: ErrorResponseHandler) => {
return {
type: SET_MODAL_ERROR_MESSAGE,
message,

View File

@@ -18,6 +18,7 @@ import request from "superagent";
import get from "lodash/get";
import { clearSession } from "../utils";
import { baseUrl } from "../../history";
import { ErrorResponseHandler } from "../types";
export class API {
invoke(method: string, url: string, data?: object) {
@@ -42,11 +43,24 @@ export class API {
const errMessage = get(
err.response,
"body.message",
err.status.toString()
`Error ${err.status.toString()}`
);
const throwMessage =
let detailedMessage = get(err.response, "body.detailedMessage", "");
if (errMessage === detailedMessage) {
detailedMessage = "";
}
const capMessage =
errMessage.charAt(0).toUpperCase() + errMessage.slice(1);
const capDetailed =
detailedMessage.charAt(0).toUpperCase() + detailedMessage.slice(1);
const throwMessage: ErrorResponseHandler = {
errorMessage: capMessage,
detailedError: capDetailed,
};
return Promise.reject(throwMessage);
} else {

View File

@@ -378,3 +378,8 @@ export interface AffinityConfiguration {
nodeSelectorLabels?: ILabelKeyPair[];
withPodAntiAffinity?: boolean;
}
export interface ErrorResponseHandler {
errorMessage: string;
detailedError: string;
}

View File

@@ -93,22 +93,38 @@ export function systemReducer(
case SET_SNACK_BAR_MESSAGE:
return {
...state,
snackBar: { message: action.message, type: "message" },
snackBar: {
message: action.message,
detailedErrorMsg: "",
type: "message",
},
};
case SET_ERROR_SNACK_MESSAGE:
return {
...state,
snackBar: { message: action.message, type: "error" },
snackBar: {
message: action.message.errorMessage,
detailedErrorMsg: action.message.detailedError,
type: "error",
},
};
case SET_SNACK_MODAL_MESSAGE:
return {
...state,
modalSnackBar: { message: action.message, type: "message" },
modalSnackBar: {
message: action.message,
detailedErrorMsg: "",
type: "message",
},
};
case SET_MODAL_ERROR_MESSAGE:
return {
...state,
modalSnackBar: { message: action.message, type: "error" },
modalSnackBar: {
message: action.message.errorMessage,
detailedErrorMsg: action.message.detailedError,
type: "error",
},
};
case SET_SERVER_DIAG_STAT:
return {

View File

@@ -27,8 +27,8 @@ import {
modalBasic,
} from "../Common/FormComponents/common/styleLibrary";
import { ChangePasswordRequest } from "../Buckets/types";
import api from "../../../common/api";
import { setModalErrorSnackMessage } from "../../../actions";
import api from "../../../common/api";
const styles = (theme: Theme) =>
createStyles({
@@ -62,12 +62,18 @@ const ChangePassword = ({
event.preventDefault();
if (newPassword !== reNewPassword) {
setModalErrorSnackMessage("New passwords don't match");
setModalErrorSnackMessage({
errorMessage: "New passwords don't match",
detailedError: "",
});
return;
}
if (newPassword.length < 8) {
setModalErrorSnackMessage("Passwords must be at least 8 characters long");
setModalErrorSnackMessage({
errorMessage: "Passwords must be at least 8 characters long",
detailedError: "",
});
return;
}

View File

@@ -68,13 +68,10 @@ const ChangeUserPassword = ({
setLoading(true);
if (newPassword.length < 8) {
setModalErrorSnackMessage("Passwords must be at least 8 characters long");
setLoading(false);
return;
}
if (newPassword.length < 8) {
setModalErrorSnackMessage("Passwords must be at least 8 characters long");
setModalErrorSnackMessage({
errorMessage: "Passwords must be at least 8 characters long",
detailedError: "",
});
setLoading(false);
return;
}

View File

@@ -129,7 +129,10 @@ const AddReplicationModal = ({
setAddLoading(false);
if (itemVal.errorString && itemVal.errorString !== "") {
setModalErrorSnackMessage(itemVal.errorString);
setModalErrorSnackMessage({
errorMessage: itemVal.errorString,
detailedError: "",
});
return;
}
@@ -137,7 +140,10 @@ const AddReplicationModal = ({
return;
}
setModalErrorSnackMessage("No changes applied");
setModalErrorSnackMessage({
errorMessage: "No changes applied",
detailedError: "",
});
})
.catch((err) => {
setAddLoading(false);

View File

@@ -75,7 +75,6 @@ import {
} from "../../../../../../actions";
import { BucketVersioning } from "../../../types";
import RewindEnable from "./RewindEnable";
import FileCopyIcon from "@material-ui/icons/FileCopy";
import DeleteIcon from "@material-ui/icons/Delete";
import DeleteMultipleObjects from "./DeleteMultipleObjects";

View File

@@ -93,9 +93,10 @@ const ShareFile = ({
const versID = distributedSetup ? dataObject.version_id : "null";
if (diffDate < 0) {
setModalErrorSnackMessage(
"Selected date must be greater than current time."
);
setModalErrorSnackMessage({
errorMessage: "Selected date must be greater than current time.",
detailedError: "",
});
setShareURL("");
setIsLoadingFile(false);
@@ -103,9 +104,10 @@ const ShareFile = ({
}
if (diffDate > 604800000) {
setModalErrorSnackMessage(
"You can share a file only for less than 7 days."
);
setModalErrorSnackMessage({
errorMessage: "You can share a file only for less than 7 days.",
detailedError: "",
});
setShareURL("");
setIsLoadingFile(false);

View File

@@ -0,0 +1,223 @@
// 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";
interface IMainErrorProps {
classes: any;
snackBar: snackBarMessage;
displayErrorMessage: typeof setErrorSnackMessage;
}
const styles = (theme: Theme) =>
createStyles({
mainErrorContainer: {
position: "absolute",
width: "100%",
backgroundColor: "#fff",
border: "#C72C48 1px solid",
borderLeftWidth: 12,
borderRadius: 3,
zIndex: 1000,
padding: "10px 15px",
maxWidth: 600,
left: "50%",
transform: "translateX(-50%)",
marginTop: 15,
opacity: 0,
transitionDuration: "0.2s",
},
mainErrorShow: {
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,
},
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 MainError = ({
classes,
snackBar,
displayErrorMessage,
}: IMainErrorProps) => {
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 (snackBar.message !== "" && snackBar.type === "error") {
//Error message received, we trigger the animation
setDisplayErrorMsg(true);
startHideTimer(closeErrorMessage);
}
}, [closeErrorMessage, snackBar.message, snackBar.type]);
const detailsToggle = () => {
setDetailsOpen(!detailsOpen);
};
const message = get(snackBar, "message", "");
const messageDetails = get(snackBar, "detailedErrorMsg", "");
if (snackBar.type !== "error" || message === "") {
return null;
}
return (
<Fragment>
<div
className={`${classes.mainErrorContainer} ${
displayErrorMsg ? classes.mainErrorShow : ""
}`}
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}>Error</span>
</div>
<div className={classes.simpleError}>{message}</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) => ({
snackBar: state.system.snackBar,
});
const mapDispatchToProps = {
displayErrorMessage: setErrorSnackMessage,
};
const connector = connect(mapState, mapDispatchToProps);
export default connector(withStyles(styles)(MainError));

View File

@@ -144,6 +144,18 @@ const ModalWrapper = ({
}
: { maxWidth: "md" as const, fullWidth: true };
let message = "";
if (modalSnackMessage) {
message = modalSnackMessage.detailedErrorMsg;
if (
modalSnackMessage.detailedErrorMsg === "" ||
modalSnackMessage.detailedErrorMsg.length < 5
) {
message = modalSnackMessage.message;
}
}
return (
<Dialog
open={modalOpen}
@@ -159,7 +171,7 @@ const ModalWrapper = ({
onClose={() => {
closeSnackBar();
}}
message={modalSnackMessage ? modalSnackMessage.message : ""}
message={message}
ContentProps={{
className: `${classes.snackBar} ${
modalSnackMessage && modalSnackMessage.type === "error"

View File

@@ -115,9 +115,10 @@ const UpdateTierCredentialsModal = ({
setModalErrorSnackMessage(err);
});
} else {
setModalErrorSnackMessage(
"There was an error retrieving tier information"
);
setModalErrorSnackMessage({
errorMessage: "There was an error retrieving tier information",
detailedError: "",
});
}
};

View File

@@ -59,6 +59,7 @@ import Storage from "./Storage/Storage";
import PodDetails from "./Tenants/TenantDetails/pods/PodDetails";
import Metrics from "./Dashboard/Metrics";
import Hop from "./Tenants/TenantDetails/hop/Hop";
import MainError from "./Common/MainError/MainError";
const drawerWidth = 245;
@@ -410,7 +411,9 @@ const Console = ({
return;
}
// Open SnackBar
setOpenSnackbar(true);
if (snackBarMessage.type !== "error") {
setOpenSnackbar(true);
}
}, [snackBarMessage]);
const location = useLocation();
@@ -474,6 +477,7 @@ const Console = ({
value={loadingProgress}
/>
)}
<MainError />
<div className={classes.snackDiv}>
<Snackbar
open={openSnackbar}

View File

@@ -211,9 +211,11 @@ const PrDashboard = ({
const widgetsWithValue = getWidgetsWithValue(res.widgets);
setPanelInformation(widgetsWithValue);
} else {
displayErrorMessage(
"Widget information could not be retrieved at this time. Please try again"
);
displayErrorMessage({
errorMessage:
"Widget information could not be retrieved at this time. Please try again",
detailedError: "",
});
}
setLoading(false);

View File

@@ -14,17 +14,16 @@
// 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 } from "react";
import React, { Fragment, useState } from "react";
import { connect } from "react-redux";
import PageHeader from "../Common/PageHeader/PageHeader";
import { Grid, LinearProgress } from "@material-ui/core";
import { Grid } from "@material-ui/core";
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
import Tab from "@material-ui/core/Tab";
import Tabs from "@material-ui/core/Tabs";
import { containerForHeader } from "../Common/FormComponents/common/styleLibrary";
import ErrorLogs from "./ErrorLogs/ErrorLogs";
import LogsSearchMain from "./LogSearch/LogsSearchMain";
import api from "../../../common/api";
import { AppState } from "../../../store";
interface ILogsMainProps {

View File

@@ -152,10 +152,10 @@ const NameTenant = ({
});
})
.catch((err: any) => {
console.error(err);
setModalErrorSnackMessage(
"Error validating if namespace already has tenants"
);
setModalErrorSnackMessage({
errorMessage: "Error validating if namespace already has tenants",
detailedError: err.detailedError,
});
});
}, [
namespace,

View File

@@ -68,7 +68,10 @@ const DeleteTenant = ({
const removeRecord = () => {
if (retypeTenant !== selectedTenant.name) {
setErrorSnackMessage("Tenant name is not correct");
setErrorSnackMessage({
errorMessage: "Tenant name is incorrect",
detailedError: "",
});
return;
}
setDeleteLoading(true);

View File

@@ -68,7 +68,10 @@ const DeletePod = ({
const removeRecord = () => {
if (retypePod !== selectedPod.name) {
setErrorSnackMessage("Tenant name is not correct");
setErrorSnackMessage({
errorMessage: "Tenant name is incorrect",
detailedError: "",
});
return;
}
setDeleteLoading(true);

View File

@@ -99,7 +99,10 @@ const PodsSummary = ({ match, history, loadingTenant }: IPodsSummary) => {
setLoadingPods(false);
})
.catch((err) => {
setErrorSnackMessage("Error loading pods");
setErrorSnackMessage({
errorMessage: "Error loading pods",
detailedError: err.detailedError,
});
});
}
}, [loadingPods, tenantName, tenantNamespace]);

View File

@@ -99,7 +99,10 @@ const AddUser = ({
event.preventDefault();
if (secretKey.length < 8) {
setModalErrorSnackMessage("Passwords must be at least 8 characters long");
setModalErrorSnackMessage({
errorMessage: "Passwords must be at least 8 characters long",
detailedError: "",
});
setAddLoading(false);
return;
}

View File

@@ -79,9 +79,10 @@ const BulkAddToGroup = ({
});
} else {
isSaving(false);
setModalErrorSnackMessage(
"You need to select at least one group to assign"
);
setModalErrorSnackMessage({
errorMessage: "You need to select at least one group to assign",
detailedError: "",
});
}
}
}, [

View File

@@ -12,10 +12,13 @@
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
import { ErrorResponseHandler } from "./common/types";
// along with this program. If not, see <http://www.gnu.org/licenses/>.
export interface snackBarMessage {
message: string;
detailedErrorMsg?: string;
detailedErrorMsg: string;
type: "message" | "error";
}
@@ -88,7 +91,7 @@ interface SetSnackBarMessage {
interface SetErrorSnackMessage {
type: typeof SET_ERROR_SNACK_MESSAGE;
message: string;
message: ErrorResponseHandler;
}
interface SetModalSnackMessage {
@@ -98,7 +101,7 @@ interface SetModalSnackMessage {
interface SetModalErrorMessage {
type: typeof SET_MODAL_ERROR_MESSAGE;
message: string;
message: ErrorResponseHandler;
}
interface SetDistributedSetup {