From a124a118b1f477a31454fa2994f324d7ea9e63c3 Mon Sep 17 00:00:00 2001 From: Kartik Gupta <84975264+kartik-gupta-ij@users.noreply.github.com> Date: Sat, 25 May 2024 23:42:12 +0530 Subject: [PATCH] feat: Add notifications for issues. (#183) * feat: Add notifications for issues count in MiniDrawer component * feat: add Notifications Modal * fmt * fix: immediate_choice option not working in some cases * fmt * refactor / redesign * success--->successfully * chore: Update Notifications component text to "Configuration Issues Detected" * chore: Update Notifications component text to "No notifications (issues)" * feat: delate all issues buttoon added --- src/components/Notifications.jsx | 351 +++++++++++++++++++++++++++++++ src/pages/Home.jsx | 2 + 2 files changed, 353 insertions(+) create mode 100644 src/components/Notifications.jsx diff --git a/src/components/Notifications.jsx b/src/components/Notifications.jsx new file mode 100644 index 00000000..76d9072e --- /dev/null +++ b/src/components/Notifications.jsx @@ -0,0 +1,351 @@ +import * as React from 'react'; +import { alpha, styled } from '@mui/material/styles'; +import NotificationsNoneRoundedIcon from '@mui/icons-material/NotificationsNoneRounded'; +import Tooltip from '@mui/material/Tooltip'; +import CircularProgress from '@mui/material/CircularProgress'; +import IconButton from '@mui/material/IconButton'; +import Badge from '@mui/material/Badge'; +import Typography from '@mui/material/Typography'; +import CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutline'; +import List from '@mui/material/List'; +import MuiListItem from '@mui/material/ListItem'; +import MuiDivider from '@mui/material/Divider'; +import axios from 'axios'; +import { CodeBlock } from './Common/CodeBlock'; +import { Box, Button, Chip, Drawer, useMediaQuery } from '@mui/material'; +import { requestFromCode } from './CodeEditorWindow/config/RequesFromCode'; +import { bigIntJSON } from '../common/bigIntJSON'; +import PropTypes from 'prop-types'; +import { Close } from '@mui/icons-material'; + +async function fetchNotifications() { + try { + const issues = await axios.get('/issues'); + return issues.data.result.issues; + } catch (error) { + console.log('error', error); + } +} + +async function deleteNotifications() { + try { + const res = await axios.delete('/issues'); + return res.data; + } catch (error) { + console.log('error', error); + return error; + } +} + +const ListItem = styled(MuiListItem)(({ theme }) => ({ + display: 'flex', + flexDirection: 'column', + background: alpha(theme.palette.info.main, 0.05), + borderColor: `${theme.palette.info.main} !important`, + borderRadius: '5px', + padding: theme.spacing(2), + marginBottom: theme.spacing(2), +})); + +const Loading = styled('div')(({ theme }) => ({ + display: 'flex', + justifyContent: 'center', + margin: theme.spacing(3, 0), +})); + +const Divider = styled(MuiDivider)(({ theme }) => ({ + margin: theme.spacing(1, 0), +})); + +export default function Notifications() { + const [open, setOpen] = React.useState(false); + const [tooltipOpen, setTooltipOpen] = React.useState(false); + const anchorRef = React.useRef(null); + const [issues, setIssues] = React.useState([]); + const [issuesCount, setIssuesCount] = React.useState(0); + const [loading, setLoading] = React.useState(true); + const matchesMdMedia = useMediaQuery('(max-width: 992px)'); + + React.useEffect(() => { + setLoading(true); + fetchNotifications().then((data) => { + setIssuesCount(data.length); + setIssues(data); + setLoading(false); + }); + }, []); + + const handleToggle = () => { + if (open) { + fetchNotifications().then((data) => { + setIssues(data); + setLoading(false); + }); + } + if (issuesCount > 0) { + setIssuesCount(0); + } + setOpen((prevOpen) => !prevOpen); + setTooltipOpen(false); + }; + + const handleDeleteAll = () => { + setLoading(true); + deleteNotifications().then(() => { + fetchNotifications().then((data) => { + setIssues(data); + setLoading(false); + }); + }); + }; + + return ( + + { + setTooltipOpen(!open); + }} + onClose={() => { + setTooltipOpen(false); + }} + > + + + + + + + +
+ + Notifications + + + + + + + Configuration Issues Detected + + {issues.length > 0 && ( + + )} + + + + {!loading ? ( + issues.length > 0 ? ( + issues.map((issue) => ( + + + + )) + ) : ( + + No notifications (issues) + + ) + ) : ( + + + + )} + +
+
+
+ ); +} + +function Notification({ issue }) { + const [result, setResult] = React.useState(null); + const [loading, setLoading] = React.useState(false); + const [error, setError] = React.useState(null); + + const handleRun = (code) => { + setLoading(true); + requestFromCode(code, false) + .then((res) => { + setResult(() => bigIntJSON.stringify(res, null, 2)); + setLoading(false); + }) + .catch((err) => { + setError(() => bigIntJSON.stringify(err, null, 2)); + setLoading(false); + }); + }; + + return ( + + {loading ? ( + + ) : result ? ( + + + + Success! Indexing successfully acknowledged. + + + ) : ( + + {error ? ( + + + Error + + + + ) : null} + ({ + display: 'inline-block', + color: theme.palette.info.main, + border: `1px solid ${theme.palette.info.main}`, + px: 0.5, + borderRadius: '5px', + my: 0.5, + })} + > + #{issue.id} + + + {issue.description} + + + {issue.solution && issue.solution.immediate && ( + + + + + + + + + )} + {issue.solution && issue.solution.immediate_choice && ( + + + Choose one of the following solutions: + + {issue.solution.immediate_choice.map((choice, index) => ( + + + + + + + + {index < issue.solution.immediate_choice.length - 1 ? ( + + + + ) : null} + + ))} + + )} + + {issue.timestamp && ( + + {new Date(issue.timestamp).toLocaleDateString('en-US', { + year: 'numeric', + month: 'long', + day: 'numeric', + hour: '2-digit', + minute: '2-digit', + })} + + )} + + )} + + ); +} + +Notification.propTypes = { + issue: PropTypes.any, +}; diff --git a/src/pages/Home.jsx b/src/pages/Home.jsx index b7757421..7d69d48f 100644 --- a/src/pages/Home.jsx +++ b/src/pages/Home.jsx @@ -12,6 +12,7 @@ import KeyIcon from '@mui/icons-material/Key'; import { useClient } from '../context/client-context'; import { Logo } from '../components/Logo'; import Sidebar from '../components/Sidebar/Sidebar'; +import Notifications from '../components/Notifications'; const DrawerHeader = styled('div')(({ theme }) => ({ display: 'flex', @@ -84,6 +85,7 @@ export default function MiniDrawer() { + {theme.palette.mode === 'dark' ? : }