diff --git a/package-lock.json b/package-lock.json index e8165d0c..056dce4d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "vrt-frontend", - "version": "1.4.0", + "version": "1.6.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -9463,6 +9463,15 @@ "sort-keys": "^1.0.0" } }, + "notistack": { + "version": "0.9.17", + "resolved": "https://registry.npmjs.org/notistack/-/notistack-0.9.17.tgz", + "integrity": "sha512-nypTN6sEe+q98wMaxF/UwatA1yAq948+bZOo9JKYR+tU65DW0ipWyx8DseJ3UJYvb6VDD+Fqo83qwayQ46bEEA==", + "requires": { + "clsx": "^1.1.0", + "hoist-non-react-statics": "^3.3.0" + } + }, "npm-run-path": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", diff --git a/package.json b/package.json index 584584ea..f81fc370 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "@testing-library/user-event": "^7.2.1", "konva": "^4.2.2", "material-ui-popup-state": "^1.6.1", + "notistack": "^0.9.17", "qs": "^6.9.4", "react": "^16.13.1", "react-debounce-input": "^3.2.2", diff --git a/src/App.jsx b/src/App.jsx index 00482241..a5c1b08d 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,4 +1,5 @@ import React from "react"; +import { SnackbarProvider } from 'notistack'; import "./App.css"; import Header from "./components/Header"; import { @@ -12,20 +13,22 @@ import { SocketProvider } from "./contexts/socket.context"; function App() { return ( -
- - - - - -
- - - - - - -
+ +
+ + + + + +
+ + + + + + +
+
); } diff --git a/src/components/BuildList.tsx b/src/components/BuildList.tsx index be953f5c..04186446 100644 --- a/src/components/BuildList.tsx +++ b/src/components/BuildList.tsx @@ -23,6 +23,7 @@ import { import { BuildStatusChip } from "./BuildStatusChip"; import { SkeletonList } from "./SkeletonList"; import { formatDateTime } from "../_helpers/format.helper"; +import { useSnackbar } from "notistack"; const useStyles = makeStyles((theme: Theme) => createStyles({ @@ -42,6 +43,7 @@ const BuildList: FunctionComponent = () => { const history = useHistory(); const { buildList, selectedBuildId, loading } = useBuildState(); const buildDispatch = useBuildDispatch(); + const { enqueueSnackbar } = useSnackbar(); return ( @@ -98,7 +100,17 @@ const BuildList: FunctionComponent = () => { > { - deleteBuild(buildDispatch, build.id); + deleteBuild(buildDispatch, build.id) + .then((b) => + enqueueSnackbar(`${b.id} removed`, { + variant: "success", + }) + ) + .catch((err) => + enqueueSnackbar(err, { + variant: "error", + }) + ); }} > diff --git a/src/components/LoginForm.tsx b/src/components/LoginForm.tsx index b1c41a85..be94d224 100644 --- a/src/components/LoginForm.tsx +++ b/src/components/LoginForm.tsx @@ -11,15 +11,21 @@ import { } from "@material-ui/core"; import { useAuthDispatch, login } from "../contexts"; import { routes } from "../constants"; +import { useSnackbar } from "notistack"; const LoginForm = () => { + const { enqueueSnackbar } = useSnackbar(); const [email, setEmail] = useState(""); const [password, setPassword] = useState(""); const dispatch = useAuthDispatch(); const handleSubmit = (event: FormEvent) => { event.preventDefault(); - login(dispatch, email, password); + login(dispatch, email, password).catch((err) => + enqueueSnackbar(err, { + variant: "error", + }) + ); }; return ( diff --git a/src/components/RegisterForm.tsx b/src/components/RegisterForm.tsx index 50830347..99cb3f77 100644 --- a/src/components/RegisterForm.tsx +++ b/src/components/RegisterForm.tsx @@ -9,8 +9,10 @@ import { } from "@material-ui/core"; import { useAuthDispatch, login } from "../contexts"; import { usersService } from "../services"; +import { useSnackbar } from "notistack"; const RegisterForm = () => { + const { enqueueSnackbar } = useSnackbar(); const [email, setEmail] = useState(""); const [firstName, setFirstName] = useState(""); const [lastName, setLastName] = useState(""); @@ -21,7 +23,12 @@ const RegisterForm = () => { event.preventDefault(); usersService .register(firstName, lastName, email, password) - .then(() => login(dispatch, email, password)); + .then(() => login(dispatch, email, password)) + .catch((err) => + enqueueSnackbar(err, { + variant: "error", + }) + ); }; return ( diff --git a/src/components/TestDetailsModal.tsx b/src/components/TestDetailsModal.tsx index 380a0f10..5b7d4a2a 100644 --- a/src/components/TestDetailsModal.tsx +++ b/src/components/TestDetailsModal.tsx @@ -40,6 +40,7 @@ import { routes } from "../constants"; import { useTestRunDispatch, updateTestRun, selectTestRun } from "../contexts"; import { DrawArea } from "./DrawArea"; import { CommentsPopper } from "./CommentsPopper"; +import { useSnackbar } from "notistack"; const useStyles = makeStyles((theme) => ({ imageContainer: { @@ -57,6 +58,7 @@ const TestDetailsModal: React.FunctionComponent<{ }> = ({ testRun }) => { const classes = useStyles(); const history = useHistory(); + const { enqueueSnackbar } = useSnackbar(); const testRunDispatch = useTestRunDispatch(); const stageWidth = (window.innerWidth / 2) * 0.9; @@ -177,6 +179,16 @@ const TestDetailsModal: React.FunctionComponent<{ .then((testRun) => { updateTestRun(testRunDispatch, testRun); }) + .then(() => + enqueueSnackbar("Approved", { + variant: "success", + }) + ) + .catch((err) => + enqueueSnackbar(err, { + variant: "error", + }) + ) } > Approve @@ -186,9 +198,21 @@ const TestDetailsModal: React.FunctionComponent<{