From c10d2b5b2e39ee966beff9ab80c9b3ed214a9002 Mon Sep 17 00:00:00 2001 From: psankhe28 Date: Tue, 8 Aug 2023 11:13:02 +0530 Subject: [PATCH 01/13] Sidebar and overview --- src/components/sidebar/Badge.tsx | 2 +- src/components/sidebar/Menu.tsx | 73 ++++++++++++ src/components/sidebar/SidebarHeader.tsx | 28 +++-- src/components/sidebar/index.tsx | 138 ++++++++++------------- src/components/sidebar/style.css | 15 +++ src/pages/monitoring/overview/index.tsx | 85 +++++++++----- src/pages/monitoring/overview/style.css | 27 +++-- 7 files changed, 239 insertions(+), 129 deletions(-) create mode 100644 src/components/sidebar/Menu.tsx create mode 100644 src/components/sidebar/style.css diff --git a/src/components/sidebar/Badge.tsx b/src/components/sidebar/Badge.tsx index 4ed04db..b31266c 100644 --- a/src/components/sidebar/Badge.tsx +++ b/src/components/sidebar/Badge.tsx @@ -8,7 +8,7 @@ interface BadgeProps extends React.HTMLAttributes { } const StyledBadge = styled.div` - min-width: 18px; + min-width: 28px; min-height: 18px; display: flex; align-items: center; diff --git a/src/components/sidebar/Menu.tsx b/src/components/sidebar/Menu.tsx new file mode 100644 index 0000000..8e9040b --- /dev/null +++ b/src/components/sidebar/Menu.tsx @@ -0,0 +1,73 @@ +export const monitoringItemsConfig = [ + { + label: "Overview", + link: "/monitoring/overview", + }, + { + label: "Kafka Topics", + link: "/monitoring/kafka-topics", + }, + { + label: "UCI-API", + link: "/monitoring/uci-api", + }, + { + label: "Inbound", + link: "/monitoring/inbound", + }, + { + label: "Orchestrator", + link: "/monitoring/orchestrator", + }, + { + label: "Transformer", + link: "/monitoring/transformer", + }, + { + label: "Broadcast-Transformer", + link: "/monitoring/broadcast-transformer", + }, + { + label: "Outbound", + link: "/monitoring/outbound", + }, + { + label: "Transport-Socket", + link: "/monitoring/transport-socket", + } +]; + +export const logsItemsConfig = [ + { + label: "Kafka Topics", + link: "/monitoring/logs/kafka-topics", + }, + { + label: "UCI-API", + link: "/monitoring/logs/uci-api", + }, + { + label: "Inbound", + link: "/monitoring/logs/inbound", + }, + { + label: "Orchestrator", + link: "/monitoring/logs/orchestrator", + }, + { + label: "Transformer", + link: "/monitoring/logs/transformer", + }, + { + label: "Broadcast-Transformer", + link: "/monitoring/logs/broadcast-transformer", + }, + { + label: "Outbound", + link: "/monitoring/logs/outbound", + }, + { + label: "Transport-Socket", + link: "/monitoring/logs/transport-socket", + } +]; diff --git a/src/components/sidebar/SidebarHeader.tsx b/src/components/sidebar/SidebarHeader.tsx index 5d191d0..6350df1 100644 --- a/src/components/sidebar/SidebarHeader.tsx +++ b/src/components/sidebar/SidebarHeader.tsx @@ -1,13 +1,13 @@ import styled from "@emotion/styled"; import React from "react"; import { Typography } from "./Typography"; -import DehazeOutlinedIcon from '@mui/icons-material/DehazeOutlined'; -import CloseOutlinedIcon from '@mui/icons-material/CloseOutlined'; +import { MDBIcon } from "mdb-react-ui-kit"; + interface SidebarHeaderProps extends React.HTMLAttributes { children?: React.ReactNode; rtl: boolean; - collapsed:any; - handleCollapse:any + collapsed: boolean; + handleCollapse: Function; } const StyledSidebarHeader = styled.div` @@ -68,15 +68,27 @@ export const SidebarHeader: React.FC = ({
- {!collapsed?:} + {!collapsed ? ( + + ) : ( + + )}
- - + UCI Admin Dashboard -
); diff --git a/src/components/sidebar/index.tsx b/src/components/sidebar/index.tsx index 1d683b5..8d58d36 100644 --- a/src/components/sidebar/index.tsx +++ b/src/components/sidebar/index.tsx @@ -7,19 +7,20 @@ import { SubMenu, } from "react-pro-sidebar"; import { Link, useNavigate } from "react-router-dom"; -import React, { useCallback } from "react"; +import React, { useCallback, useState } from "react"; import { Switch } from "./Switch"; // import { PackageBadges } from './PackageBadges'; // import { Typography } from './Typography'; import { SidebarFooter } from "./SidebarFooter"; import { SidebarHeader } from "./SidebarHeader"; -import DashboardIcon from "../icons/Dashboard"; +import DashobardIcon from "../icons/Dashobard"; import AddIcon from "../icons/AddIcon"; import LogoutIcon from "../icons/LogoutIcon"; import ThemeIcon from "../icons/ThemeIcon"; import { useStore } from "../../store"; -import InsightsIcon from "@mui/icons-material/Insights"; -import CodeIcon from "@mui/icons-material/Code"; +import { MDBIcon } from "mdb-react-ui-kit"; +import { logsItemsConfig, monitoringItemsConfig } from "./Menu"; +import "./style.css"; interface SidebarProps extends React.HTMLAttributes { children?: React.ReactNode; @@ -48,6 +49,17 @@ const themes = { color: "#9fb6cf", }, }, + submenu: { + menuContent: "#000", + icon: "#0098e5", + hover: { + backgroundColor: "#c5e4ff", + color: "#44596e", + }, + disabled: { + color: "#9fb6cf", + }, + }, }, dark: { sidebar: { @@ -85,11 +97,11 @@ export const SidebarComponent: React.FC = ({ }) => { const store: any = useStore(); // const [collapsed, setCollapsed] = React.useState(false); - const [toggled, setToggled] = React.useState(false); - const [broken, setBroken] = React.useState(false); - const [rtl, setRtl] = React.useState(false); - const [hasImage, setHasImage] = React.useState(true); - const [theme, setTheme] = React.useState(store?.theme); + const [toggled, setToggled] = useState(false); + const [broken, setBroken] = useState(false); + const [rtl, setRtl] = useState(false); + const [hasImage, setHasImage] = useState(true); + const [theme, setTheme] = useState(store?.theme); // handle on RTL change event const handleRTLChange = (e: React.ChangeEvent) => { @@ -123,14 +135,15 @@ export const SidebarComponent: React.FC = ({ SubMenuExpandIcon: { color: "#b6b7b9", }, - subMenuContent: ({ level }) => ({ + subMenuContent: ({ level, active }) => ({ backgroundColor: level === 0 ? hexToRgba( - themes[theme].menu.menuContent, - hasImage && !collapsed ? 0.4 : 1 + themes[theme].sidebar.backgroundColor, + hasImage && !collapsed ? 0.8 : 1 ) - : "transparent", + : "#0b2948", + ...(active && { backgroundColor: "black" }), }), button: { [`&.${menuClasses.disabled}`]: { @@ -143,6 +156,13 @@ export const SidebarComponent: React.FC = ({ ), color: themes[theme].menu.hover.color, }, + "&:active": { + backgroundColor: "#fff", + }, + // [`&.active`]: { + // backgroundColor: "#fff", + // color: "#b6c8d9", + // }, }, label: ({ open }) => ({ fontWeight: open ? 600 : undefined, @@ -214,7 +234,7 @@ export const SidebarComponent: React.FC = ({ label="Charts" icon={} > - } component={}> + } component={}> Dashboard } component={}>Add Bot @@ -242,76 +262,40 @@ export const SidebarComponent: React.FC = ({ label="Dark theme" /> - } component={}> + } + active + component={} + > Dashboard - } component={}> + } + component={} + > Add Bot - }> - }> - Overview - - }> - Kafka Topics - - }> - UCI-API - - }> - Inbound - - }> - Orchestrator - - }> - Transformer - - } - > - Broadcast-Transformer - - }> - Outbound - - } - > - Transport-Socket - - }> - }> - UCI-API - - }> - Inbound - - } - > - Orchestrator - - } - > - Transformer - - - } - > - Broadcast-Transformer - - }> - Outbound - + } + > + {monitoringItemsConfig.map((item) => ( } + key={item.label} + component={} > - Transport-Socket + {item.label} + ))} + }> + {logsItemsConfig.map((item) => ( + } + > + {item.label} + + ))} diff --git a/src/components/sidebar/style.css b/src/components/sidebar/style.css new file mode 100644 index 0000000..8dd74d7 --- /dev/null +++ b/src/components/sidebar/style.css @@ -0,0 +1,15 @@ +/* This is for menu item */ +.pro-menu-item a.active { + color: aliceblue !important; /* put any color you want */ + font-weight: 500; +} + +/* This is for submenu item */ +.nav-member .react-slidedown .pro-menu-item a.active { + color: #003642; /* put any color you want */ + font-weight: 500; +} + +.ps-menu-button a:active { + background-color: aliceblue !important; +} diff --git a/src/pages/monitoring/overview/index.tsx b/src/pages/monitoring/overview/index.tsx index 3559055..6e09d86 100644 --- a/src/pages/monitoring/overview/index.tsx +++ b/src/pages/monitoring/overview/index.tsx @@ -1,30 +1,59 @@ -import React, { useEffect } from "react"; -import { MDBCard, MDBCardBody } from "mdb-react-ui-kit"; +import { MDBCard, MDBCardBody, MDBCol, MDBRow, MDBBtn } from "mdb-react-ui-kit"; import "./style.css"; -import { useStore } from "../../../store"; -type Theme = "light" | "dark"; +interface OverviewHeaderProps extends React.HTMLAttributes { + children?: React.ReactNode; + theme: string; +} +export const Overview: React.FC = ({ + children, + theme, + ...rest +}) => { + const handleFilterInputChange = ( + event: React.ChangeEvent + ) => { + const { value } = event.target; + console.log(value); + }; -export const Overview = () => { - const store: any = useStore(); - const [theme, setTheme] = React.useState(store?.theme); - - useEffect(() => { - setTheme(store?.theme); - }, [store?.theme]); + const handleFilterSubmit = (event: React.FormEvent) => { + event.preventDefault(); + console.log("Submit"); + }; return (
-
-
+ + +
+ + + Filter + +
+
+
+ +
80

No. of Notifications sent

-
-
+ +
65
@@ -33,26 +62,26 @@ export const Overview = () => {

-
-
+ +
50

No. of Notifications opened by users

-
-
-
-
+ + + +
80

No. of Notifications sent

-
-
+ +
65
@@ -61,18 +90,16 @@ export const Overview = () => {

-
-
+ +
50

No. of Notifications opened by users

-
-
+ +
); }; - -// export default Overview; diff --git a/src/pages/monitoring/overview/style.css b/src/pages/monitoring/overview/style.css index e88ee7f..9d5f368 100644 --- a/src/pages/monitoring/overview/style.css +++ b/src/pages/monitoring/overview/style.css @@ -1,15 +1,14 @@ .card-title { - font-size: 50px; - font-weight: bold; - text-align: center; - } - - .card-text { - text-align: center; - } - - .dark-card { - background-color: black; - color: black; - } - \ No newline at end of file + font-size: 50px; + font-weight: bold; + text-align: center; +} + +.card-text { + text-align: center; +} + +.dark-card { + background-color: black; + color: black; +} From 1dca36a2d3e8be7923ab52888754200b84ecfb41 Mon Sep 17 00:00:00 2001 From: Pratiksha Sankhe Date: Thu, 10 Aug 2023 14:20:07 +0530 Subject: [PATCH 02/13] Update index.tsx --- src/pages/monitoring/overview/index.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/pages/monitoring/overview/index.tsx b/src/pages/monitoring/overview/index.tsx index 6e09d86..8496b6b 100644 --- a/src/pages/monitoring/overview/index.tsx +++ b/src/pages/monitoring/overview/index.tsx @@ -14,12 +14,10 @@ export const Overview: React.FC = ({ event: React.ChangeEvent ) => { const { value } = event.target; - console.log(value); }; const handleFilterSubmit = (event: React.FormEvent) => { event.preventDefault(); - console.log("Submit"); }; return ( From 60cba91642c36c25133de532fd980aa9fd38977a Mon Sep 17 00:00:00 2001 From: psankhe28 Date: Mon, 4 Sep 2023 21:22:51 +0530 Subject: [PATCH 03/13] Final code --- package.json | 4 +- src/App.css | 39 +----- src/App.js | 148 ++++++++++++++++++++-- src/components/icons/Dashboard.tsx | 4 +- src/components/sidebar/Menu.tsx | 16 --- src/components/sidebar/SidebarHeader.tsx | 3 +- src/components/sidebar/index.tsx | 155 ++++++++--------------- src/components/sidebar/style.css | 17 +-- src/components/visualisation/bar.tsx | 6 +- src/components/visualisation/index.tsx | 4 +- src/components/visualisation/line.tsx | 35 +++++ src/components/visualisation/pie.tsx | 70 ++++++++++ src/hooks/useWindow.ts | 1 - src/index.css | 3 +- src/utils/functions.ts | 94 ++++++++++++++ 15 files changed, 411 insertions(+), 188 deletions(-) create mode 100644 src/components/visualisation/line.tsx create mode 100644 src/components/visualisation/pie.tsx create mode 100644 src/utils/functions.ts diff --git a/package.json b/package.json index 18f4bbe..3ec7207 100644 --- a/package.json +++ b/package.json @@ -6,8 +6,6 @@ "@emotion/react": "^11.11.1", "@emotion/styled": "^11.11.0", "@fortawesome/fontawesome-free": "^6.4.0", - "@mui/icons-material": "^5.14.0", - "@mui/material": "^5.14.0", "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", @@ -16,6 +14,7 @@ "@types/node": "^20.2.5", "@types/react": "^18.2.7", "@types/react-dom": "^18.2.4", + "ansi-to-react": "^6.1.6", "axios": "^1.4.0", "chart.js": "^4.3.0", "formik": "^2.4.1", @@ -26,6 +25,7 @@ "moment": "^2.29.4", "react": "^18.2.0", "react-datepicker": "^4.12.0", + "react-datetime-picker": "^5.5.1", "react-dom": "^18.2.0", "react-form-stepper": "^2.0.3", "react-fullscreen-loading": "^0.0.4", diff --git a/src/App.css b/src/App.css index 74b5e05..2c871ed 100644 --- a/src/App.css +++ b/src/App.css @@ -1,38 +1,3 @@ -.App { - text-align: center; -} - -.App-logo { - height: 40vmin; - pointer-events: none; -} - -@media (prefers-reduced-motion: no-preference) { - .App-logo { - animation: App-logo-spin infinite 20s linear; - } -} - -.App-header { - background-color: #282c34; - min-height: 100vh; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - font-size: calc(10px + 2vmin); - color: white; -} - -.App-link { - color: #61dafb; -} - -@keyframes App-logo-spin { - from { - transform: rotate(0deg); - } - to { - transform: rotate(360deg); - } +body .dark-mode { + --mdb-body-color: #fff !important; } diff --git a/src/App.js b/src/App.js index 212daac..bffba16 100644 --- a/src/App.js +++ b/src/App.js @@ -6,20 +6,29 @@ import { useNavigate, } from "react-router-dom"; import { Toaster } from "react-hot-toast"; - +import "./App.css"; import { SidebarComponent } from "./components/sidebar"; import { MDBCol, MDBRow } from "mdb-react-ui-kit"; -import { useContext, useMemo, useState, useEffect } from "react"; +import { useEffect, useMemo, useState } from "react"; import { AppContext } from "./provider/contextProvider"; -import { useAuthContext } from "./provider/authProvider"; import RequireAuth from "./hoc/requireAuth"; import Loader from "./components/fullscreenLoader"; import { useStore } from "./store"; -import { SuccessScreen, Dashboard, Login, Add } from "./pages"; +import { SuccessScreen, Dashboard, Login, Add, Overview } from "./pages"; import { history } from "./utils/history"; -import { useAuth } from "./hooks/useAuth"; -import { AuthContext } from "./provider/authProvider"; import useWindowSize from "./hooks/useWindow"; +import Uciapi from "./pages/monitoring/uci-api"; +import Inbound from "./pages/monitoring/inbound"; +import Orchestrator from "./pages/monitoring/orchestrator"; +import BroadcastTransformer from "./pages/monitoring/broadcast-transformer"; +import Outbound from "./pages/monitoring/outbound"; +import Transformer from "./pages/monitoring/transformer"; +import UCIAPIlogs from "./pages/monitoring/logs/uci-api"; +import InboundLogs from "./pages/monitoring/logs/inbound"; +import OrchestratorLogs from "./pages/monitoring/logs/orchestrator"; +import TransformerLogs from "./pages/monitoring/logs/transformer"; +import BroadcastTransformerLogs from "./pages/monitoring/logs/broadcast-transformer"; +import OutboundLogs from "./pages/monitoring/logs/outbound"; function App() { const [isLoading, setIsLoading] = useState(false); @@ -57,20 +66,21 @@ function App() { const user = useMemo(() => store.user, [store.user]); return ( -
+
<> {user && ( + {" "} )} - + {user ? ( } /> @@ -101,6 +111,126 @@ function App() { } /> + + + + } + /> + + + + } + /> + + + + } + /> + + + + } + /> + + + + } + /> + + + + } + /> + + + + } + /> + + + + } + /> + + + + } + /> + + + + } + /> + + + + } + /> + + + + } + /> + + + + } + /> + + + + } + /> + + + + } + /> @@ -133,4 +263,4 @@ function App() { ); } -export default App; +export default App; \ No newline at end of file diff --git a/src/components/icons/Dashboard.tsx b/src/components/icons/Dashboard.tsx index 43d4064..5e6483a 100644 --- a/src/components/icons/Dashboard.tsx +++ b/src/components/icons/Dashboard.tsx @@ -1,10 +1,10 @@ import React from 'react' //@ts-ignore import dashboard from '../../assets/images/dashboard.png'; -const DashobardIcon = () => { +const DashboardIcon = () => { return ( dashboard ) } -export default DashobardIcon \ No newline at end of file +export default DashboardIcon \ No newline at end of file diff --git a/src/components/sidebar/Menu.tsx b/src/components/sidebar/Menu.tsx index 8e9040b..6e64724 100644 --- a/src/components/sidebar/Menu.tsx +++ b/src/components/sidebar/Menu.tsx @@ -3,10 +3,6 @@ export const monitoringItemsConfig = [ label: "Overview", link: "/monitoring/overview", }, - { - label: "Kafka Topics", - link: "/monitoring/kafka-topics", - }, { label: "UCI-API", link: "/monitoring/uci-api", @@ -30,18 +26,10 @@ export const monitoringItemsConfig = [ { label: "Outbound", link: "/monitoring/outbound", - }, - { - label: "Transport-Socket", - link: "/monitoring/transport-socket", } ]; export const logsItemsConfig = [ - { - label: "Kafka Topics", - link: "/monitoring/logs/kafka-topics", - }, { label: "UCI-API", link: "/monitoring/logs/uci-api", @@ -65,9 +53,5 @@ export const logsItemsConfig = [ { label: "Outbound", link: "/monitoring/logs/outbound", - }, - { - label: "Transport-Socket", - link: "/monitoring/logs/transport-socket", } ]; diff --git a/src/components/sidebar/SidebarHeader.tsx b/src/components/sidebar/SidebarHeader.tsx index 6350df1..69ef8f9 100644 --- a/src/components/sidebar/SidebarHeader.tsx +++ b/src/components/sidebar/SidebarHeader.tsx @@ -80,11 +80,10 @@ export const SidebarHeader: React.FC = ({ fas icon="times" onClick={handleCollapse} - style={{ cursor: "pointer" }} + style={{ cursor: "pointer",textAlign:"center",marginRight:"7px" }} /> )}
- UCI Admin Dashboard diff --git a/src/components/sidebar/index.tsx b/src/components/sidebar/index.tsx index 8d58d36..bd47e03 100644 --- a/src/components/sidebar/index.tsx +++ b/src/components/sidebar/index.tsx @@ -6,14 +6,14 @@ import { MenuItemStyles, SubMenu, } from "react-pro-sidebar"; -import { Link, useNavigate } from "react-router-dom"; +import { Link, useNavigate, useLocation } from "react-router-dom"; import React, { useCallback, useState } from "react"; import { Switch } from "./Switch"; // import { PackageBadges } from './PackageBadges'; // import { Typography } from './Typography'; import { SidebarFooter } from "./SidebarFooter"; import { SidebarHeader } from "./SidebarHeader"; -import DashobardIcon from "../icons/Dashobard"; +import DashboardIcon from "../icons/Dashboard"; import AddIcon from "../icons/AddIcon"; import LogoutIcon from "../icons/LogoutIcon"; import ThemeIcon from "../icons/ThemeIcon"; @@ -48,6 +48,9 @@ const themes = { disabled: { color: "#9fb6cf", }, + active: { + backgroundColor: "#000", + }, }, submenu: { menuContent: "#000", @@ -59,6 +62,9 @@ const themes = { disabled: { color: "#9fb6cf", }, + active: { + backgroundColor: "#000", + }, }, }, dark: { @@ -77,6 +83,9 @@ const themes = { disabled: { color: "#3e5e7e", }, + active: { + backgroundColor: "#000", + }, }, }, }; @@ -102,6 +111,8 @@ export const SidebarComponent: React.FC = ({ const [rtl, setRtl] = useState(false); const [hasImage, setHasImage] = useState(true); const [theme, setTheme] = useState(store?.theme); + const location = useLocation(); + const navigate = useNavigate(); // handle on RTL change event const handleRTLChange = (e: React.ChangeEvent) => { @@ -115,7 +126,6 @@ export const SidebarComponent: React.FC = ({ localStorage.setItem("theme", store?.theme === "dark" ? "light" : "dark"); }; - const navigate = useNavigate(); // handle on image change event const handleImageChange = (e: React.ChangeEvent) => { setHasImage(e.target.checked); @@ -143,7 +153,10 @@ export const SidebarComponent: React.FC = ({ hasImage && !collapsed ? 0.8 : 1 ) : "#0b2948", - ...(active && { backgroundColor: "black" }), + ...(active && { + backgroundColor: "white !important", + color: "white", + }), }), button: { [`&.${menuClasses.disabled}`]: { @@ -156,13 +169,6 @@ export const SidebarComponent: React.FC = ({ ), color: themes[theme].menu.hover.color, }, - "&:active": { - backgroundColor: "#fff", - }, - // [`&.active`]: { - // backgroundColor: "#fff", - // color: "#b6c8d9", - // }, }, label: ({ open }) => ({ fontWeight: open ? 600 : undefined, @@ -219,42 +225,28 @@ export const SidebarComponent: React.FC = ({ style={{ marginBottom: "24px", marginTop: "16px" }} />
- {/*
- - General - -
*/} - - {/* - } - > - } component={}> - Dashboard - - } component={}>Add Bot - - - - */} - - {/*
- - Extra - -
*/} - - }> + {/* }> + + + } + component={} + > + Dashboard + + } + component={} + > + Add Bot + */} + } active={location.pathname === "/"}> = ({ /> } - active + icon={} + active={location.pathname === "/"} component={} + className={location.pathname === "/" ? "active-menu" : ""} > Dashboard } + active={location.pathname === "/add-bot"} component={} + className={ + location.pathname === "/add-bot" ? "active-menu" : "" + } > Add Bot @@ -283,6 +280,9 @@ export const SidebarComponent: React.FC = ({ } + className={ + location.pathname === item.link ? "active-menu" : "" + } > {item.label} @@ -292,6 +292,9 @@ export const SidebarComponent: React.FC = ({ } + className={ + location.pathname === item.link ? "active-menu" : "" + } > {item.label} @@ -299,7 +302,11 @@ export const SidebarComponent: React.FC = ({ - } onClick={onLogout}> + } + onClick={onLogout} + className={location.pathname === "/logout" ? "active-menu" : ""} + > Log Out @@ -307,56 +314,6 @@ export const SidebarComponent: React.FC = ({
- - {/*
-
-
- {broken && ( - - )} -
-
- - React Pro Sidebar - - - React Pro Sidebar provides a set of components for creating high level and - customizable side navigation - - -
- -
-
- setCollapsed(!collapsed)} - label="Collapse" - /> -
- -
- -
- -
- -
- -
- -
-
-
-
*/}
); }; diff --git a/src/components/sidebar/style.css b/src/components/sidebar/style.css index 8dd74d7..85f01e2 100644 --- a/src/components/sidebar/style.css +++ b/src/components/sidebar/style.css @@ -1,15 +1,4 @@ -/* This is for menu item */ -.pro-menu-item a.active { - color: aliceblue !important; /* put any color you want */ - font-weight: 500; -} - -/* This is for submenu item */ -.nav-member .react-slidedown .pro-menu-item a.active { - color: #003642; /* put any color you want */ - font-weight: 500; -} - -.ps-menu-button a:active { - background-color: aliceblue !important; +.active-menu{ + background: aliceblue; + color: black; } diff --git a/src/components/visualisation/bar.tsx b/src/components/visualisation/bar.tsx index 636ed39..27797db 100644 --- a/src/components/visualisation/bar.tsx +++ b/src/components/visualisation/bar.tsx @@ -1,8 +1,7 @@ -import React, { useEffect, useRef } from "react"; -// import Chart from "chart.js"; +import { useEffect, useRef } from "react"; import Chart from 'chart.js/auto'; -export const BarChart = ({ data }) => { +const BarChart = ({ data}) => { const chartRef = useRef(null); useEffect(() => { @@ -33,3 +32,4 @@ export const BarChart = ({ data }) => { return ; }; +export default BarChart; diff --git a/src/components/visualisation/index.tsx b/src/components/visualisation/index.tsx index 3e07c2a..b40ea06 100644 --- a/src/components/visualisation/index.tsx +++ b/src/components/visualisation/index.tsx @@ -1 +1,3 @@ -export * from './bar' \ No newline at end of file +export * from './bar' +export * from './line' +export * from './pie' \ No newline at end of file diff --git a/src/components/visualisation/line.tsx b/src/components/visualisation/line.tsx new file mode 100644 index 0000000..f8b0d2a --- /dev/null +++ b/src/components/visualisation/line.tsx @@ -0,0 +1,35 @@ +import { useEffect, useRef } from "react"; +import Chart from 'chart.js/auto'; + +const LineChart = ({ data }) => { + const chartRef = useRef(null); + + useEffect(() => { + const ctx = chartRef.current.getContext("2d"); + const chart = new Chart(ctx, { + type: "line", + data: data, + options: { + responsive: true, + scales: { + x: { + grid: { + display: false, + }, + }, + y: { + beginAtZero: true + }, + }, + }, + }); + + return () => { + chart.destroy(); + }; + }, [data]); + + return ; +}; + +export default LineChart; diff --git a/src/components/visualisation/pie.tsx b/src/components/visualisation/pie.tsx new file mode 100644 index 0000000..4ebb394 --- /dev/null +++ b/src/components/visualisation/pie.tsx @@ -0,0 +1,70 @@ +import React, { useEffect, useRef } from "react"; +import Chart from "chart.js/auto"; +import useWindowSize from "../../hooks/useWindow"; + +const generateRandomColor = () => { + const letters = "0123456789ABCDEF"; + let color = "#"; + for (let i = 0; i < 6; i++) { + color += letters[Math.floor(Math.random() * 16)]; + } + return color; +}; + +const PieChart = ({ data }) => { + const chartRef = useRef(null); + const { height } = useWindowSize(); + + useEffect(() => { + const dynamicColors = data?.labels?.map(() => generateRandomColor()); + + const ctx = chartRef.current.getContext("2d"); + const chart = new Chart(ctx, { + type: "pie", + data: { + labels: data?.labels, + datasets: [ + { + data: data?.datasets[0].data, + backgroundColor: dynamicColors, + }, + ], + }, + options: { + responsive: true, + plugins: { + tooltip: { + callbacks: { + label: (context) => { + const label = data?.labels[context.dataIndex]; + const value = data?.datasets[0].data[context.dataIndex]; + const total = data?.datasets[0].data.reduce((acc, curr) => acc + curr); + const percentage = ((value / total) * 100).toFixed(2); + return `${label}: ${value} (${percentage}%)`; + }, + }, + }, + }, + }, + }); + + return () => { + chart.destroy(); + }; + }, [data]); + + const chartContainerStyle = { + display: "flex", + justifyContent: "center", + alignItems: "center", + maxHeight: `${height - 100}px`, + }; + + return ( +
+ +
+ ); +}; + +export default PieChart; diff --git a/src/hooks/useWindow.ts b/src/hooks/useWindow.ts index 5d79395..f3fd8fa 100644 --- a/src/hooks/useWindow.ts +++ b/src/hooks/useWindow.ts @@ -16,7 +16,6 @@ const useWindowSize = () => { window.addEventListener("resize", handleResize); - // Cleanup the event listener on component unmount return () => { window.removeEventListener("resize", handleResize); }; diff --git a/src/index.css b/src/index.css index a67c038..c61aa09 100644 --- a/src/index.css +++ b/src/index.css @@ -25,6 +25,5 @@ code { .form-outline .form-control { background-color: white !important; } -.form-label { -} \ No newline at end of file + diff --git a/src/utils/functions.ts b/src/utils/functions.ts new file mode 100644 index 0000000..24a20ff --- /dev/null +++ b/src/utils/functions.ts @@ -0,0 +1,94 @@ +export function formatDate(input) { + const [seconds, minutes, hours, day, month, year] = input + .split("_") + .map(Number); + + const months = [ + "January", + "February", + "March", + "April", + "May", + "June", + "July", + "August", + "September", + "October", + "November", + "December", + ]; + + const formattedDate = new Date(year, month - 1, day, hours, minutes, seconds); + + const dayNumber = formattedDate.getDate(); + const monthName = months[formattedDate.getMonth()]; + const yearNumber = formattedDate.getFullYear(); + const hoursString = formattedDate.getHours().toString().padStart(2, "0"); + const minutesString = formattedDate.getMinutes().toString().padStart(2, "0"); + const secondsString = formattedDate.getSeconds().toString().padStart(2, "0"); + + const ordinalDay = + dayNumber + + (dayNumber === 1 || dayNumber === 21 || dayNumber === 31 + ? "st" + : dayNumber === 2 || dayNumber === 22 + ? "nd" + : dayNumber === 3 || dayNumber === 23 + ? "rd" + : "th"); + + return `${ordinalDay} ${monthName}, ${yearNumber} ${hoursString}:${minutesString}:${secondsString}`; +} + +export function convertToShortDate(input) { + var cleanedDate = input.replace(/(\d+)(st|nd|rd|th)/, "$1"); + + var dateObject = new Date(cleanedDate); + + var day = String(dateObject.getDate()).padStart(2, "0"); + var month = String(dateObject.getMonth() + 1).padStart(2, "0"); + var year = dateObject.getFullYear(); + var convertedFormat = day + "_" + month + "_" + year; + + return convertedFormat; +} + +export function reverseFormatDate(formattedDate) { + const parts = formattedDate.match(/(\d+)(?:st|nd|rd|th)\s+(\w+),\s+(\d+)\s+(\d+:\d+:\d+)/); + + if (!parts) { + return "Invalid date format"; + } + + const dayNumber = parts[1].padStart(2, "0"); + const monthName = parts[2]; + const yearNumber = parts[3]; + const time = parts[4]; + + const months = [ + "January", + "February", + "March", + "April", + "May", + "June", + "July", + "August", + "September", + "October", + "November", + "December", + ]; + + const month = (months.indexOf(monthName) + 1).toString().padStart(2, "0"); + + const [hours, minutes, seconds] = time.split(":").map(Number); + + const reversedFormat = `${seconds.toString().padStart(2, "0")}_${minutes.toString().padStart(2, "0")}_${hours.toString().padStart(2, "0")}_${dayNumber}_${month}_${yearNumber}`; + + return reversedFormat; +} + +export const formatNumberWithCommas = (number) => { + return number.toLocaleString("en-US"); +}; \ No newline at end of file From 81af669cce03f0a90032dd28b2c0bfa38ca1d12e Mon Sep 17 00:00:00 2001 From: Pratiksha Sankhe Date: Mon, 4 Sep 2023 21:31:49 +0530 Subject: [PATCH 04/13] Update SidebarHeader.tsx --- src/components/sidebar/SidebarHeader.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/sidebar/SidebarHeader.tsx b/src/components/sidebar/SidebarHeader.tsx index 69ef8f9..6350df1 100644 --- a/src/components/sidebar/SidebarHeader.tsx +++ b/src/components/sidebar/SidebarHeader.tsx @@ -80,10 +80,11 @@ export const SidebarHeader: React.FC = ({ fas icon="times" onClick={handleCollapse} - style={{ cursor: "pointer",textAlign:"center",marginRight:"7px" }} + style={{ cursor: "pointer" }} /> )} + UCI Admin Dashboard From aa1c43aa8016822c8e8dcc17d2b30523fc2d7324 Mon Sep 17 00:00:00 2001 From: Pratiksha Sankhe Date: Mon, 4 Sep 2023 21:33:35 +0530 Subject: [PATCH 05/13] Update Menu.tsx --- src/components/sidebar/Menu.tsx | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/components/sidebar/Menu.tsx b/src/components/sidebar/Menu.tsx index 6e64724..8e9040b 100644 --- a/src/components/sidebar/Menu.tsx +++ b/src/components/sidebar/Menu.tsx @@ -3,6 +3,10 @@ export const monitoringItemsConfig = [ label: "Overview", link: "/monitoring/overview", }, + { + label: "Kafka Topics", + link: "/monitoring/kafka-topics", + }, { label: "UCI-API", link: "/monitoring/uci-api", @@ -26,10 +30,18 @@ export const monitoringItemsConfig = [ { label: "Outbound", link: "/monitoring/outbound", + }, + { + label: "Transport-Socket", + link: "/monitoring/transport-socket", } ]; export const logsItemsConfig = [ + { + label: "Kafka Topics", + link: "/monitoring/logs/kafka-topics", + }, { label: "UCI-API", link: "/monitoring/logs/uci-api", @@ -53,5 +65,9 @@ export const logsItemsConfig = [ { label: "Outbound", link: "/monitoring/logs/outbound", + }, + { + label: "Transport-Socket", + link: "/monitoring/logs/transport-socket", } ]; From f185b7c16a22347b4666308e2b9aa0c76a9d86d6 Mon Sep 17 00:00:00 2001 From: Pratiksha Sankhe Date: Mon, 4 Sep 2023 21:34:07 +0530 Subject: [PATCH 06/13] Update index.tsx --- src/components/sidebar/index.tsx | 386 ++++++------------------------- 1 file changed, 70 insertions(+), 316 deletions(-) diff --git a/src/components/sidebar/index.tsx b/src/components/sidebar/index.tsx index bd47e03..8e9040b 100644 --- a/src/components/sidebar/index.tsx +++ b/src/components/sidebar/index.tsx @@ -1,319 +1,73 @@ -import { - Sidebar, - Menu, - MenuItem, - menuClasses, - MenuItemStyles, - SubMenu, -} from "react-pro-sidebar"; -import { Link, useNavigate, useLocation } from "react-router-dom"; -import React, { useCallback, useState } from "react"; -import { Switch } from "./Switch"; -// import { PackageBadges } from './PackageBadges'; -// import { Typography } from './Typography'; -import { SidebarFooter } from "./SidebarFooter"; -import { SidebarHeader } from "./SidebarHeader"; -import DashboardIcon from "../icons/Dashboard"; -import AddIcon from "../icons/AddIcon"; -import LogoutIcon from "../icons/LogoutIcon"; -import ThemeIcon from "../icons/ThemeIcon"; -import { useStore } from "../../store"; -import { MDBIcon } from "mdb-react-ui-kit"; -import { logsItemsConfig, monitoringItemsConfig } from "./Menu"; -import "./style.css"; - -interface SidebarProps extends React.HTMLAttributes { - children?: React.ReactNode; - collapsed: any; - handleCollapse: any; -} - -type Theme = "light" | "dark"; - -const themes = { - light: { - sidebar: { - // backgroundColor: '#ffffff', - backgroundColor: "#0b2948", - // color: '#607489', - color: "#8ba1b7", - }, - menu: { - menuContent: "#fbfcfd", - icon: "#0098e5", - hover: { - backgroundColor: "#c5e4ff", - color: "#44596e", - }, - disabled: { - color: "#9fb6cf", - }, - active: { - backgroundColor: "#000", - }, - }, - submenu: { - menuContent: "#000", - icon: "#0098e5", - hover: { - backgroundColor: "#c5e4ff", - color: "#44596e", - }, - disabled: { - color: "#9fb6cf", - }, - active: { - backgroundColor: "#000", - }, - }, +export const monitoringItemsConfig = [ + { + label: "Overview", + link: "/monitoring/overview", }, - dark: { - sidebar: { - // backgroundColor: '#0b2948', - backgroundColor: "#24292d", - color: "white", - }, - menu: { - menuContent: "#082440", - icon: "#59d0ff", - hover: { - backgroundColor: "#00458b", - color: "#b6c8d9", - }, - disabled: { - color: "#3e5e7e", - }, - active: { - backgroundColor: "#000", - }, - }, + { + label: "Kafka Topics", + link: "/monitoring/kafka-topics", }, -}; - -// hex to rgba converter -const hexToRgba = (hex: string, alpha: number) => { - const r = parseInt(hex.slice(1, 3), 16); - const g = parseInt(hex.slice(3, 5), 16); - const b = parseInt(hex.slice(5, 7), 16); - - return `rgba(${r}, ${g}, ${b}, ${alpha})`; -}; -export const SidebarComponent: React.FC = ({ - children, - collapsed, - handleCollapse, - ...rest -}) => { - const store: any = useStore(); - // const [collapsed, setCollapsed] = React.useState(false); - const [toggled, setToggled] = useState(false); - const [broken, setBroken] = useState(false); - const [rtl, setRtl] = useState(false); - const [hasImage, setHasImage] = useState(true); - const [theme, setTheme] = useState(store?.theme); - const location = useLocation(); - const navigate = useNavigate(); - - // handle on RTL change event - const handleRTLChange = (e: React.ChangeEvent) => { - setRtl(e.target.checked); - }; - - // handle on theme change event - const handleThemeChange = (e: React.ChangeEvent) => { - setTheme(e.target.checked ? "dark" : "light"); - store?.setTheme(store?.theme === "dark" ? "light" : "dark"); - localStorage.setItem("theme", store?.theme === "dark" ? "light" : "dark"); - }; - - // handle on image change event - const handleImageChange = (e: React.ChangeEvent) => { - setHasImage(e.target.checked); - }; - - const menuItemStyles: MenuItemStyles = { - root: { - fontSize: "14px", - fontWeight: 400, - }, - icon: { - color: themes[theme].menu.icon, - [`&.${menuClasses.disabled}`]: { - color: themes[theme].menu.disabled.color, - }, - }, - SubMenuExpandIcon: { - color: "#b6b7b9", - }, - subMenuContent: ({ level, active }) => ({ - backgroundColor: - level === 0 - ? hexToRgba( - themes[theme].sidebar.backgroundColor, - hasImage && !collapsed ? 0.8 : 1 - ) - : "#0b2948", - ...(active && { - backgroundColor: "white !important", - color: "white", - }), - }), - button: { - [`&.${menuClasses.disabled}`]: { - color: themes[theme].menu.disabled.color, - }, - "&:hover": { - backgroundColor: hexToRgba( - themes[theme].menu.hover.backgroundColor, - hasImage ? 0.8 : 1 - ), - color: themes[theme].menu.hover.color, - }, - }, - label: ({ open }) => ({ - fontWeight: open ? 600 : undefined, - }), - }; - - const onLogout = useCallback(() => { - store?.setUser(null); - localStorage.clear(); - setTimeout(() => { - navigate("/login"); - }, 10); - }, [navigate, store]); - - return ( -
- setToggled(false)} - customBreakPoint="sm" - onBreakPoint={setBroken} - image="https://user-images.githubusercontent.com/25878302/144499035-2911184c-76d3-4611-86e7-bc4e8ff84ff5.jpg" - rtl={rtl} - breakPoint="md" - backgroundColor={hexToRgba( - themes[theme].sidebar.backgroundColor, - hasImage ? 0.9 : 1 - )} - rootStyles={{ - color: themes[theme].sidebar.color, - width: "100%", - }} - > -
- -
- - {/* }> - - - } - component={} - > - Dashboard - - } - component={} - > - Add Bot - */} - } active={location.pathname === "/"}> - - - } - active={location.pathname === "/"} - component={} - className={location.pathname === "/" ? "active-menu" : ""} - > - Dashboard - - } - active={location.pathname === "/add-bot"} - component={} - className={ - location.pathname === "/add-bot" ? "active-menu" : "" - } - > - Add Bot - - } - > - {monitoringItemsConfig.map((item) => ( - } - className={ - location.pathname === item.link ? "active-menu" : "" - } - > - {item.label} - - ))} - }> - {logsItemsConfig.map((item) => ( - } - className={ - location.pathname === item.link ? "active-menu" : "" - } - > - {item.label} - - ))} - - + { + label: "UCI-API", + link: "/monitoring/uci-api", + }, + { + label: "Inbound", + link: "/monitoring/inbound", + }, + { + label: "Orchestrator", + link: "/monitoring/orchestrator", + }, + { + label: "Transformer", + link: "/monitoring/transformer", + }, + { + label: "Broadcast-Transformer", + link: "/monitoring/broadcast-transformer", + }, + { + label: "Outbound", + link: "/monitoring/outbound", + }, + { + label: "Transport-Socket", + link: "/monitoring/transport-socket", + } +]; - } - onClick={onLogout} - className={location.pathname === "/logout" ? "active-menu" : ""} - > - Log Out - - -
- -
-
-
- ); -}; +export const logsItemsConfig = [ + { + label: "Kafka Topics", + link: "/monitoring/logs/kafka-topics", + }, + { + label: "UCI-API", + link: "/monitoring/logs/uci-api", + }, + { + label: "Inbound", + link: "/monitoring/logs/inbound", + }, + { + label: "Orchestrator", + link: "/monitoring/logs/orchestrator", + }, + { + label: "Transformer", + link: "/monitoring/logs/transformer", + }, + { + label: "Broadcast-Transformer", + link: "/monitoring/logs/broadcast-transformer", + }, + { + label: "Outbound", + link: "/monitoring/logs/outbound", + }, + { + label: "Transport-Socket", + link: "/monitoring/logs/transport-socket", + } +]; From df0df5938c316a405f28914b2b7df35fb266945e Mon Sep 17 00:00:00 2001 From: Pratiksha Sankhe Date: Mon, 4 Sep 2023 21:35:44 +0530 Subject: [PATCH 07/13] Update index.tsx --- src/components/sidebar/index.tsx | 431 ++++++++++++++++++++++++++----- 1 file changed, 360 insertions(+), 71 deletions(-) diff --git a/src/components/sidebar/index.tsx b/src/components/sidebar/index.tsx index 8e9040b..8d58d36 100644 --- a/src/components/sidebar/index.tsx +++ b/src/components/sidebar/index.tsx @@ -1,73 +1,362 @@ -export const monitoringItemsConfig = [ - { - label: "Overview", - link: "/monitoring/overview", - }, - { - label: "Kafka Topics", - link: "/monitoring/kafka-topics", - }, - { - label: "UCI-API", - link: "/monitoring/uci-api", - }, - { - label: "Inbound", - link: "/monitoring/inbound", - }, - { - label: "Orchestrator", - link: "/monitoring/orchestrator", - }, - { - label: "Transformer", - link: "/monitoring/transformer", - }, - { - label: "Broadcast-Transformer", - link: "/monitoring/broadcast-transformer", - }, - { - label: "Outbound", - link: "/monitoring/outbound", - }, - { - label: "Transport-Socket", - link: "/monitoring/transport-socket", - } -]; - -export const logsItemsConfig = [ - { - label: "Kafka Topics", - link: "/monitoring/logs/kafka-topics", - }, - { - label: "UCI-API", - link: "/monitoring/logs/uci-api", - }, - { - label: "Inbound", - link: "/monitoring/logs/inbound", - }, - { - label: "Orchestrator", - link: "/monitoring/logs/orchestrator", - }, - { - label: "Transformer", - link: "/monitoring/logs/transformer", - }, - { - label: "Broadcast-Transformer", - link: "/monitoring/logs/broadcast-transformer", +import { + Sidebar, + Menu, + MenuItem, + menuClasses, + MenuItemStyles, + SubMenu, +} from "react-pro-sidebar"; +import { Link, useNavigate } from "react-router-dom"; +import React, { useCallback, useState } from "react"; +import { Switch } from "./Switch"; +// import { PackageBadges } from './PackageBadges'; +// import { Typography } from './Typography'; +import { SidebarFooter } from "./SidebarFooter"; +import { SidebarHeader } from "./SidebarHeader"; +import DashobardIcon from "../icons/Dashobard"; +import AddIcon from "../icons/AddIcon"; +import LogoutIcon from "../icons/LogoutIcon"; +import ThemeIcon from "../icons/ThemeIcon"; +import { useStore } from "../../store"; +import { MDBIcon } from "mdb-react-ui-kit"; +import { logsItemsConfig, monitoringItemsConfig } from "./Menu"; +import "./style.css"; + +interface SidebarProps extends React.HTMLAttributes { + children?: React.ReactNode; + collapsed: any; + handleCollapse: any; +} + +type Theme = "light" | "dark"; + +const themes = { + light: { + sidebar: { + // backgroundColor: '#ffffff', + backgroundColor: "#0b2948", + // color: '#607489', + color: "#8ba1b7", + }, + menu: { + menuContent: "#fbfcfd", + icon: "#0098e5", + hover: { + backgroundColor: "#c5e4ff", + color: "#44596e", + }, + disabled: { + color: "#9fb6cf", + }, + }, + submenu: { + menuContent: "#000", + icon: "#0098e5", + hover: { + backgroundColor: "#c5e4ff", + color: "#44596e", + }, + disabled: { + color: "#9fb6cf", + }, + }, }, - { - label: "Outbound", - link: "/monitoring/logs/outbound", + dark: { + sidebar: { + // backgroundColor: '#0b2948', + backgroundColor: "#24292d", + color: "white", + }, + menu: { + menuContent: "#082440", + icon: "#59d0ff", + hover: { + backgroundColor: "#00458b", + color: "#b6c8d9", + }, + disabled: { + color: "#3e5e7e", + }, + }, }, - { - label: "Transport-Socket", - link: "/monitoring/logs/transport-socket", - } -]; +}; + +// hex to rgba converter +const hexToRgba = (hex: string, alpha: number) => { + const r = parseInt(hex.slice(1, 3), 16); + const g = parseInt(hex.slice(3, 5), 16); + const b = parseInt(hex.slice(5, 7), 16); + + return `rgba(${r}, ${g}, ${b}, ${alpha})`; +}; +export const SidebarComponent: React.FC = ({ + children, + collapsed, + handleCollapse, + ...rest +}) => { + const store: any = useStore(); + // const [collapsed, setCollapsed] = React.useState(false); + const [toggled, setToggled] = useState(false); + const [broken, setBroken] = useState(false); + const [rtl, setRtl] = useState(false); + const [hasImage, setHasImage] = useState(true); + const [theme, setTheme] = useState(store?.theme); + + // handle on RTL change event + const handleRTLChange = (e: React.ChangeEvent) => { + setRtl(e.target.checked); + }; + + // handle on theme change event + const handleThemeChange = (e: React.ChangeEvent) => { + setTheme(e.target.checked ? "dark" : "light"); + store?.setTheme(store?.theme === "dark" ? "light" : "dark"); + localStorage.setItem("theme", store?.theme === "dark" ? "light" : "dark"); + }; + + const navigate = useNavigate(); + // handle on image change event + const handleImageChange = (e: React.ChangeEvent) => { + setHasImage(e.target.checked); + }; + + const menuItemStyles: MenuItemStyles = { + root: { + fontSize: "14px", + fontWeight: 400, + }, + icon: { + color: themes[theme].menu.icon, + [`&.${menuClasses.disabled}`]: { + color: themes[theme].menu.disabled.color, + }, + }, + SubMenuExpandIcon: { + color: "#b6b7b9", + }, + subMenuContent: ({ level, active }) => ({ + backgroundColor: + level === 0 + ? hexToRgba( + themes[theme].sidebar.backgroundColor, + hasImage && !collapsed ? 0.8 : 1 + ) + : "#0b2948", + ...(active && { backgroundColor: "black" }), + }), + button: { + [`&.${menuClasses.disabled}`]: { + color: themes[theme].menu.disabled.color, + }, + "&:hover": { + backgroundColor: hexToRgba( + themes[theme].menu.hover.backgroundColor, + hasImage ? 0.8 : 1 + ), + color: themes[theme].menu.hover.color, + }, + "&:active": { + backgroundColor: "#fff", + }, + // [`&.active`]: { + // backgroundColor: "#fff", + // color: "#b6c8d9", + // }, + }, + label: ({ open }) => ({ + fontWeight: open ? 600 : undefined, + }), + }; + + const onLogout = useCallback(() => { + store?.setUser(null); + localStorage.clear(); + setTimeout(() => { + navigate("/login"); + }, 10); + }, [navigate, store]); + + return ( +
+ setToggled(false)} + customBreakPoint="sm" + onBreakPoint={setBroken} + image="https://user-images.githubusercontent.com/25878302/144499035-2911184c-76d3-4611-86e7-bc4e8ff84ff5.jpg" + rtl={rtl} + breakPoint="md" + backgroundColor={hexToRgba( + themes[theme].sidebar.backgroundColor, + hasImage ? 0.9 : 1 + )} + rootStyles={{ + color: themes[theme].sidebar.color, + width: "100%", + }} + > +
+ +
+ {/*
+ + General + +
*/} + + {/* + } + > + } component={}> + Dashboard + + } component={}>Add Bot + + + + */} + + {/*
+ + Extra + +
*/} + + + }> + + + } + active + component={} + > + Dashboard + + } + component={} + > + Add Bot + + } + > + {monitoringItemsConfig.map((item) => ( + } + > + {item.label} + + ))} + }> + {logsItemsConfig.map((item) => ( + } + > + {item.label} + + ))} + + + + } onClick={onLogout}> + Log Out + + +
+ +
+
+ + {/*
+
+
+ {broken && ( + + )} +
+
+ + React Pro Sidebar + + + React Pro Sidebar provides a set of components for creating high level and + customizable side navigation + + +
+ +
+
+ setCollapsed(!collapsed)} + label="Collapse" + /> +
+ +
+ +
+ +
+ +
+ +
+ +
+
+
+
*/} +
+ ); +}; From 378ec87c71217d2d9559376f1f336f081d626828 Mon Sep 17 00:00:00 2001 From: Pratiksha Sankhe Date: Mon, 4 Sep 2023 21:36:11 +0530 Subject: [PATCH 08/13] Update style.css --- src/components/sidebar/style.css | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/components/sidebar/style.css b/src/components/sidebar/style.css index 85f01e2..8dd74d7 100644 --- a/src/components/sidebar/style.css +++ b/src/components/sidebar/style.css @@ -1,4 +1,15 @@ -.active-menu{ - background: aliceblue; - color: black; +/* This is for menu item */ +.pro-menu-item a.active { + color: aliceblue !important; /* put any color you want */ + font-weight: 500; +} + +/* This is for submenu item */ +.nav-member .react-slidedown .pro-menu-item a.active { + color: #003642; /* put any color you want */ + font-weight: 500; +} + +.ps-menu-button a:active { + background-color: aliceblue !important; } From a2655789cc64f155047f7e11eb198c4020b81ed6 Mon Sep 17 00:00:00 2001 From: Pratiksha Sankhe Date: Mon, 4 Sep 2023 21:37:15 +0530 Subject: [PATCH 09/13] Update Menu.tsx --- src/components/sidebar/Menu.tsx | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/components/sidebar/Menu.tsx b/src/components/sidebar/Menu.tsx index 8e9040b..afdc60e 100644 --- a/src/components/sidebar/Menu.tsx +++ b/src/components/sidebar/Menu.tsx @@ -3,10 +3,6 @@ export const monitoringItemsConfig = [ label: "Overview", link: "/monitoring/overview", }, - { - label: "Kafka Topics", - link: "/monitoring/kafka-topics", - }, { label: "UCI-API", link: "/monitoring/uci-api", @@ -38,10 +34,6 @@ export const monitoringItemsConfig = [ ]; export const logsItemsConfig = [ - { - label: "Kafka Topics", - link: "/monitoring/logs/kafka-topics", - }, { label: "UCI-API", link: "/monitoring/logs/uci-api", From 837907cde8dc1459defe0dfb864f7aae7f180ca1 Mon Sep 17 00:00:00 2001 From: Pratiksha Sankhe Date: Mon, 4 Sep 2023 21:38:07 +0530 Subject: [PATCH 10/13] Update Menu.tsx --- src/components/sidebar/Menu.tsx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/components/sidebar/Menu.tsx b/src/components/sidebar/Menu.tsx index afdc60e..8e9040b 100644 --- a/src/components/sidebar/Menu.tsx +++ b/src/components/sidebar/Menu.tsx @@ -3,6 +3,10 @@ export const monitoringItemsConfig = [ label: "Overview", link: "/monitoring/overview", }, + { + label: "Kafka Topics", + link: "/monitoring/kafka-topics", + }, { label: "UCI-API", link: "/monitoring/uci-api", @@ -34,6 +38,10 @@ export const monitoringItemsConfig = [ ]; export const logsItemsConfig = [ + { + label: "Kafka Topics", + link: "/monitoring/logs/kafka-topics", + }, { label: "UCI-API", link: "/monitoring/logs/uci-api", From 05ada04e30baf213c0839625b430beadaa3986b8 Mon Sep 17 00:00:00 2001 From: psankhe28 Date: Tue, 5 Sep 2023 18:18:20 +0530 Subject: [PATCH 11/13] Missing files added --- src/pages/dashboard/index.tsx | 1 + src/pages/index.tsx | 7 +- .../broadcast-transformer/index.tsx | 319 ++++++++++++++ .../broadcast-transformer/style.css | 25 ++ src/pages/monitoring/inbound/index.tsx | 322 ++++++++++++++ src/pages/monitoring/inbound/style.css | 25 ++ .../logs/broadcast-transformer/index.tsx | 400 ++++++++++++++++++ .../logs/broadcast-transformer/style.css | 59 +++ src/pages/monitoring/logs/inbound/index.tsx | 362 ++++++++++++++++ src/pages/monitoring/logs/inbound/style.css | 59 +++ .../monitoring/logs/orchestrator/index.tsx | 396 +++++++++++++++++ .../monitoring/logs/orchestrator/style.css | 59 +++ src/pages/monitoring/logs/outbound/index.tsx | 393 +++++++++++++++++ src/pages/monitoring/logs/outbound/style.css | 59 +++ .../monitoring/logs/transformer/index.tsx | 393 +++++++++++++++++ .../monitoring/logs/transformer/style.css | 59 +++ src/pages/monitoring/logs/uci-api/index.tsx | 397 +++++++++++++++++ src/pages/monitoring/logs/uci-api/style.css | 59 +++ src/pages/monitoring/orchestrator/index.tsx | 319 ++++++++++++++ src/pages/monitoring/orchestrator/style.css | 26 ++ src/pages/monitoring/outbound/index.tsx | 316 ++++++++++++++ src/pages/monitoring/outbound/style.css | 25 ++ src/pages/monitoring/overview/card.tsx | 40 ++ src/pages/monitoring/overview/index.tsx | 274 ++++++++---- src/pages/monitoring/overview/style.css | 4 + src/pages/monitoring/transformer/index.tsx | 317 ++++++++++++++ src/pages/monitoring/transformer/style.css | 25 ++ src/pages/monitoring/uci-api/index.tsx | 327 ++++++++++++++ src/pages/monitoring/uci-api/style.css | 25 ++ 29 files changed, 5011 insertions(+), 81 deletions(-) create mode 100644 src/pages/monitoring/broadcast-transformer/index.tsx create mode 100644 src/pages/monitoring/broadcast-transformer/style.css create mode 100644 src/pages/monitoring/inbound/index.tsx create mode 100644 src/pages/monitoring/inbound/style.css create mode 100644 src/pages/monitoring/logs/broadcast-transformer/index.tsx create mode 100644 src/pages/monitoring/logs/broadcast-transformer/style.css create mode 100644 src/pages/monitoring/logs/inbound/index.tsx create mode 100644 src/pages/monitoring/logs/inbound/style.css create mode 100644 src/pages/monitoring/logs/orchestrator/index.tsx create mode 100644 src/pages/monitoring/logs/orchestrator/style.css create mode 100644 src/pages/monitoring/logs/outbound/index.tsx create mode 100644 src/pages/monitoring/logs/outbound/style.css create mode 100644 src/pages/monitoring/logs/transformer/index.tsx create mode 100644 src/pages/monitoring/logs/transformer/style.css create mode 100644 src/pages/monitoring/logs/uci-api/index.tsx create mode 100644 src/pages/monitoring/logs/uci-api/style.css create mode 100644 src/pages/monitoring/orchestrator/index.tsx create mode 100644 src/pages/monitoring/orchestrator/style.css create mode 100644 src/pages/monitoring/outbound/index.tsx create mode 100644 src/pages/monitoring/outbound/style.css create mode 100644 src/pages/monitoring/overview/card.tsx create mode 100644 src/pages/monitoring/transformer/index.tsx create mode 100644 src/pages/monitoring/transformer/style.css create mode 100644 src/pages/monitoring/uci-api/index.tsx create mode 100644 src/pages/monitoring/uci-api/style.css diff --git a/src/pages/dashboard/index.tsx b/src/pages/dashboard/index.tsx index a3e57a0..8ab3c43 100644 --- a/src/pages/dashboard/index.tsx +++ b/src/pages/dashboard/index.tsx @@ -30,6 +30,7 @@ export const Dashboard = () => { .then((res) => { store?.stopLoading(); setBotList(res?.data?.result?.data); + console.log(botList); setTotalRecords(res?.data?.result?.totalCount || 0); if(searchText.length >0 ){ setPage(1); diff --git a/src/pages/index.tsx b/src/pages/index.tsx index edaba61..e116b75 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -3,4 +3,9 @@ export * from './dashboard'; export * from './login'; export * from './success'; export * from './monitoring/overview'; -export * from './monitoring/kafka'; \ No newline at end of file +export * from './monitoring/inbound'; +export * from './monitoring/broadcast-transformer'; +export * from './monitoring/orchestrator'; +export * from './monitoring/outbound'; +export * from './monitoring/transformer'; +export * from './monitoring/uci-api'; \ No newline at end of file diff --git a/src/pages/monitoring/broadcast-transformer/index.tsx b/src/pages/monitoring/broadcast-transformer/index.tsx new file mode 100644 index 0000000..c8d83f4 --- /dev/null +++ b/src/pages/monitoring/broadcast-transformer/index.tsx @@ -0,0 +1,319 @@ +import { + MDBBtn, + MDBCol, + MDBDropdown, + MDBDropdownItem, + MDBDropdownMenu, + MDBDropdownToggle, + MDBRow, +} from "mdb-react-ui-kit"; +import BarChart from "../../../components/visualisation/bar"; +import React, { useEffect, useState } from "react"; +import { useStore } from "../../../store"; +import { getBots } from "../../../api/getBots"; +import { toast } from "react-hot-toast"; +import "./style.css"; +import PieChart from "../../../components/visualisation/pie"; +import LineChart from "../../../components/visualisation/line"; +// import { formatDate, reverseFormatDate } from "../../../utils/functions"; +import { fetchRealtime } from "../../../api/fetchRealtimeData"; +import { getFilesData } from "../../../api/getFiles"; +import { convertToShortDate, formatDate, reverseFormatDate } from "../../../utils/functions"; + +interface AutocompleteItem { + value: string; +} + +interface BroadcastTransformerProps extends React.HTMLAttributes { + theme: string; +} + +export const BroadcastTransformer: React.FC = ({ theme }) => { + const [selectedChart, setSelectedChart] = useState("barchart"); + const [dropdownLabel, setDropdownLabel] = useState("Select Chart"); + const [searchText, setSearchText] = useState(""); + // const [autocompleteSuggestions, setAutocompleteSuggestions] = useState< + // AutocompleteItem[] + // >([]); + const [autocompleteSuggestionsFile, setAutocompleteSuggestionsFile] = + useState([]); + const [botList, setBotList] = useState([]); + const store: any = useStore(); + + const [selected, setSelected] = useState(""); + const [dropdown, setDropdown] = useState(true); + + const [BroadcastTransformerData, setBroadcastTransformerData] = useState([]); + + const [final, setFinal] = useState(""); + + const func = async () => { + if (localStorage.getItem("file")) { + const file = localStorage.getItem("file"); + const apiEndpoint = fetchRealtime(file); + try { + const response = await apiEndpoint; + const res = JSON.parse(response.data.result); + setBroadcastTransformerData(res["Broadcast Transformer".trim()] || {}); + } catch (error) { + console.error("Error toggling:", error); + } + } else if (final !== "") { + const file = reverseFormatDate(final); + localStorage.setItem("file", file); + + const shortDate = convertToShortDate(selected); + localStorage.setItem("shortDate", shortDate); + localStorage.setItem("data_time", selected); + + const apiEndpoint = fetchRealtime(file); + try { + const response = await apiEndpoint; + const res = JSON.parse(response.data.result); + setBroadcastTransformerData(res["Broadcast Transformer".trim()] || {}); + } catch (error) { + console.error("Error toggling:", error); + } + } + fetchBotData(); + }; + + useEffect(() => { + func(); + // fetchBotData(); + }, [final]); + + const dataBar = { + labels: Object.keys(BroadcastTransformerData), + datasets: [ + { + label: "Broadcast Transformer", + data: Object.values(BroadcastTransformerData).map(Number), + backgroundColor: "rgba(75, 192, 192, 0.6)", + }, + ], + }; + + const dataPie = { + labels: Object.keys(BroadcastTransformerData), + datasets: [ + { + label: "Broadcast Transformer", + data: Object.values(BroadcastTransformerData).map(Number), + }, + ], + }; + + const dataLine = { + labels: Object.keys(BroadcastTransformerData), + datasets: [ + { + label: "Broadcast Transformer", + data: Object.values(BroadcastTransformerData).map(Number), + backgroundColor: "rgba(75, 192, 192, 0.6)", + }, + ], + }; + + const handleChartChange = (value, label) => { + setSelectedChart(value); + setDropdownLabel(label); + }; + + let chartComponent; + if (selectedChart === "barchart") { + chartComponent = ; + } else if (selectedChart === "piechart") { + // chartComponent = ; + chartComponent = ; + } else if (selectedChart === "linechart") { + chartComponent = ; + } + + const fetchBotData = async () => { + store?.startLoading(); + const data = searchText.length > 0 ? { name: searchText } : {}; + try { + const res = await getBots(data); + store?.stopLoading(); + setBotList(res?.data?.result?.data.map((bot) => bot.name)); + } catch (err) { + store?.stopLoading(); + toast.error(err.message); + } + }; + + // const handleSearchInputChange = ( + // event: React.ChangeEvent + // ) => { + // const { value } = event.target; + // setSearchText(value); + + // const lowercasedValue = value.toLowerCase(); + // const suggestions: AutocompleteItem[] = botList.map((name) => ({ + // value: name, + // })); + + // setAutocompleteSuggestions( + // suggestions.filter((item) => + // item.value.toLowerCase().includes(lowercasedValue) + // ) + // ); + // }; + + // const handleSearchSubmit = (event: React.FormEvent) => { + // event.preventDefault(); + // }; + + const handleSearchSubmitFile = async ( + event: React.FormEvent + ) => { + event.preventDefault(); + setDropdown(false); + setFinal(selected); + + const shortDate = convertToShortDate(selected); + localStorage.setItem("shortDate", shortDate); + localStorage.setItem("data_time", selected); + + const file = reverseFormatDate(selected); + localStorage.setItem("file", file); + + func(); + }; + + const handleSearchInputChangeFile = async ( + event: React.ChangeEvent + ) => { + const { value } = event.target; + setSelected(value); + + const lowercasedValue = value.toLowerCase(); + const apiEndpoint = getFilesData(); + let data = []; + + try { + const response = await apiEndpoint; + data = response.data.result; + } catch (error) { + console.error("Error toggling:", error); + } + + const suggestions: AutocompleteItem[] = data.map((name) => ({ + value: formatDate(name), + })); + + setAutocompleteSuggestionsFile( + suggestions.filter((item) => + item.value.toLowerCase().includes(lowercasedValue) + ) + ); + setDropdown(true); + }; + + const handleAutocompleteItemClick = (value) => { + setSelected(value); + setDropdown(false); + }; + + return ( +
+ + + + + {dropdownLabel} + + + handleChartChange("barchart", "Bar Chart")} + style={{ cursor: "pointer" }} + > + Bar Chart + + handleChartChange("piechart", "Pie Chart")} + style={{ cursor: "pointer" }} + > + Pie Chart + + handleChartChange("linechart", "Line Chart")} + style={{ cursor: "pointer" }} + > + Line Chart + + + + + {/* +
+ + + Search + +
+ {autocompleteSuggestions.length > 0 && ( +
    + {autocompleteSuggestions.map((item) => ( +
  • setSearchText(item.value)}> + {item.value} +
  • + ))} +
+ )} +
*/} + +
+ + + Search + +
+ {dropdown && autocompleteSuggestionsFile.length > 0 && ( +
    + {autocompleteSuggestionsFile.map((item) => ( +
  • handleAutocompleteItemClick(item.value)} + > + {item.value} +
  • + ))} +
+ )} +
+
+ {chartComponent} +
+ ); +}; + +export default BroadcastTransformer; diff --git a/src/pages/monitoring/broadcast-transformer/style.css b/src/pages/monitoring/broadcast-transformer/style.css new file mode 100644 index 0000000..dc6b6c1 --- /dev/null +++ b/src/pages/monitoring/broadcast-transformer/style.css @@ -0,0 +1,25 @@ +/* Add a higher z-index to the autocomplete dropdown */ +.autocomplete-dropdown { + position: absolute; + z-index: 100; + background-color: #fff; + border: 1px solid #ccc; + padding: 5px; + list-style: none; + max-height: 150px; + max-width: inherit; + overflow-y: auto; +} + +.autocomplete-dropdown li { + cursor: pointer; + padding: 8px; +} + +.autocomplete-dropdown li:hover { + background-color: #f0f0f0; +} + +.dark-dropdown { + color: black ; +} \ No newline at end of file diff --git a/src/pages/monitoring/inbound/index.tsx b/src/pages/monitoring/inbound/index.tsx new file mode 100644 index 0000000..5cb7ec8 --- /dev/null +++ b/src/pages/monitoring/inbound/index.tsx @@ -0,0 +1,322 @@ +import { + MDBBtn, + MDBCol, + MDBDropdown, + MDBDropdownItem, + MDBDropdownMenu, + MDBDropdownToggle, + MDBRow, +} from "mdb-react-ui-kit"; +import BarChart from "../../../components/visualisation/bar"; +import React, { useEffect, useState } from "react"; +import { useStore } from "../../../store"; +import { getBots } from "../../../api/getBots"; +import { toast } from "react-hot-toast"; +import "./style.css"; +import PieChart from "../../../components/visualisation/pie"; +import LineChart from "../../../components/visualisation/line"; +// import { formatDate, reverseFormatDate } from "../../../utils/functions"; +import { fetchRealtime } from "../../../api/fetchRealtimeData"; +import { getFilesData } from "../../../api/getFiles"; +import { convertToShortDate, formatDate, reverseFormatDate } from "../../../utils/functions"; + +interface AutocompleteItem { + value: string; +} + +interface InboundProps extends React.HTMLAttributes { + theme: string; +} + +export const Inbound: React.FC = ({ theme }) => { + const [selectedChart, setSelectedChart] = useState("barchart"); + const [dropdownLabel, setDropdownLabel] = useState("Select Chart"); + const [searchText, setSearchText] = useState(""); + // const [autocompleteSuggestions, setAutocompleteSuggestions] = useState< + // AutocompleteItem[] + // >([]); + const [autocompleteSuggestionsFile, setAutocompleteSuggestionsFile] = + useState([]); + const [botList, setBotList] = useState([]); + const store: any = useStore(); + + const [selected, setSelected] = useState(""); + const [dropdown, setDropdown] = useState(true); + + const [InboundData, setInboundData] = useState([]); + + const [final, setFinal] = useState(""); + + const func = async () => { + if (localStorage.getItem("file")) { + const file = localStorage.getItem("file"); + console.log(file) + const apiEndpoint = fetchRealtime(file); + try { + const response = await apiEndpoint; + const res = JSON.parse(response.data.result); + setInboundData(res["Inbound".trim()] || {}); + console.log(res) + } catch (error) { + console.error("Error toggling:", error); + } + } else if (final !== "") { + console.log(final) + + const file = reverseFormatDate(final); + localStorage.setItem("file", file); + + const shortDate = convertToShortDate(selected); + localStorage.setItem("shortDate", shortDate); + localStorage.setItem("data_time", selected); + + const apiEndpoint = fetchRealtime(file); + try { + const response = await apiEndpoint; + const res = JSON.parse(response.data.result); + setInboundData(res["Inbound".trim()] || {}); + } catch (error) { + console.error("Error toggling:", error); + } + } + fetchBotData(); + }; + + useEffect(() => { + func(); + // fetchBotData(); + }, [final]); + + const dataBar = { + labels: Object.keys(InboundData), + datasets: [ + { + label: "Inbound", + data: Object.values(InboundData).map(Number), + backgroundColor: "rgba(75, 192, 192, 0.6)", + }, + ], + }; + + const dataPie = { + labels: Object.keys(InboundData), + datasets: [ + { + label: "Inbound", + data: Object.values(InboundData).map(Number), + }, + ], + }; + + const dataLine = { + labels: Object.keys(InboundData), + datasets: [ + { + label: "Inbound", + data: Object.values(InboundData).map(Number), + backgroundColor: "rgba(75, 192, 192, 0.6)", + }, + ], + }; + + const handleChartChange = (value, label) => { + setSelectedChart(value); + setDropdownLabel(label); + }; + + let chartComponent; + if (selectedChart === "barchart") { + chartComponent = ; + } else if (selectedChart === "piechart") { + // chartComponent = ; + chartComponent = ; + } else if (selectedChart === "linechart") { + chartComponent = ; + } + + const fetchBotData = async () => { + store?.startLoading(); + const data = searchText.length > 0 ? { name: searchText } : {}; + try { + const res = await getBots(data); + store?.stopLoading(); + setBotList(res?.data?.result?.data.map((bot) => bot.name)); + } catch (err) { + store?.stopLoading(); + toast.error(err.message); + } + }; + + // const handleSearchInputChange = ( + // event: React.ChangeEvent + // ) => { + // const { value } = event.target; + // setSearchText(value); + + // const lowercasedValue = value.toLowerCase(); + // const suggestions: AutocompleteItem[] = botList.map((name) => ({ + // value: name, + // })); + + // setAutocompleteSuggestions( + // suggestions.filter((item) => + // item.value.toLowerCase().includes(lowercasedValue) + // ) + // ); + // }; + + // const handleSearchSubmit = (event: React.FormEvent) => { + // event.preventDefault(); + // }; + + const handleSearchSubmitFile = async ( + event: React.FormEvent + ) => { + event.preventDefault(); + setFinal(selected); + + const shortDate = convertToShortDate(selected); + localStorage.setItem("shortDate", shortDate); + localStorage.setItem("data_time", selected); + + const file = reverseFormatDate(selected); + localStorage.setItem("file", file); + + func(); + }; + + const handleSearchInputChangeFile = async ( + event: React.ChangeEvent + ) => { + const { value } = event.target; + setSelected(value); + + const lowercasedValue = value.toLowerCase(); + const apiEndpoint = getFilesData(); + let data = []; + + try { + const response = await apiEndpoint; + data = response.data.result; + } catch (error) { + console.error("Error toggling:", error); + } + + const suggestions: AutocompleteItem[] = data.map((name) => ({ + value: formatDate(name), + })); + + setAutocompleteSuggestionsFile( + suggestions.filter((item) => + item.value.toLowerCase().includes(lowercasedValue) + ) + ); + setDropdown(true); + }; + + const handleAutocompleteItemClick = (value) => { + setSelected(value); + setDropdown(false); + }; + + return ( +
+ + + + + {dropdownLabel} + + + handleChartChange("barchart", "Bar Chart")} + style={{ cursor: "pointer" }} + > + Bar Chart + + handleChartChange("piechart", "Pie Chart")} + style={{ cursor: "pointer" }} + > + Pie Chart + + handleChartChange("linechart", "Line Chart")} + style={{ cursor: "pointer" }} + > + Line Chart + + + + + {/* +
+ + + Search + +
+ {autocompleteSuggestions.length > 0 && ( +
    + {autocompleteSuggestions.map((item) => ( +
  • setSearchText(item.value)}> + {item.value} +
  • + ))} +
+ )} +
*/} + +
+ + + Search + +
+ {dropdown && autocompleteSuggestionsFile.length > 0 && ( +
    + {autocompleteSuggestionsFile.map((item) => ( +
  • handleAutocompleteItemClick(item.value)} + > + {item.value} +
  • + ))} +
+ )} +
+
+ {chartComponent} +
+ ); +}; + +export default Inbound; diff --git a/src/pages/monitoring/inbound/style.css b/src/pages/monitoring/inbound/style.css new file mode 100644 index 0000000..dc6b6c1 --- /dev/null +++ b/src/pages/monitoring/inbound/style.css @@ -0,0 +1,25 @@ +/* Add a higher z-index to the autocomplete dropdown */ +.autocomplete-dropdown { + position: absolute; + z-index: 100; + background-color: #fff; + border: 1px solid #ccc; + padding: 5px; + list-style: none; + max-height: 150px; + max-width: inherit; + overflow-y: auto; +} + +.autocomplete-dropdown li { + cursor: pointer; + padding: 8px; +} + +.autocomplete-dropdown li:hover { + background-color: #f0f0f0; +} + +.dark-dropdown { + color: black ; +} \ No newline at end of file diff --git a/src/pages/monitoring/logs/broadcast-transformer/index.tsx b/src/pages/monitoring/logs/broadcast-transformer/index.tsx new file mode 100644 index 0000000..368c703 --- /dev/null +++ b/src/pages/monitoring/logs/broadcast-transformer/index.tsx @@ -0,0 +1,400 @@ +import React, { useEffect, useState } from "react"; +import { + MDBBtn, + MDBBtnGroup, + MDBCol, + MDBContainer, + MDBRow, +} from "mdb-react-ui-kit"; +import "./style.css"; +import Ansi from "ansi-to-react"; +import { useStore } from "../../../../store"; +import toast from "react-hot-toast"; +import { getFilesData } from "../../../../api/getFiles"; +import { downloadLogData } from "../../../../api/downloadLog"; +import { downloadErrLogData } from "../../../../api/downloadErrLog"; +import { fetchServiceData } from "../../../../api/fetchService"; +import { MDBIcon } from "mdb-react-ui-kit"; +import DateTimePicker from "react-datetime-picker"; +import "react-datetime-picker/dist/DateTimePicker.css"; +import "react-calendar/dist/Calendar.css"; +import "react-clock/dist/Clock.css"; + +interface DropdownItem { + value: number; +} + +interface BroadcastTransformerLogsProps + extends React.HTMLAttributes { + theme: string; +} + +export const BroadcastTransformerLogs: React.FC< + BroadcastTransformerLogsProps +> = ({ theme }) => { + const store: any = useStore(); + const [searchText, setSearchText] = useState(0); + const [filterText, setFilterText] = useState(""); + const [filter, setFilter] = useState(false); + const [autocompleteSuggestions, setAutocompleteSuggestions] = useState< + DropdownItem[] + >([]); + const [showDropdown, setShowDropdown] = useState(false); + const [messageLines, setMessageLines] = useState([]); + const [searchPerformed, setSearchPerformed] = useState(false); + const [activeButton, setActiveButton] = useState("normal"); + const [flag, setFlag] = useState(false); + const [isLoading, setIsLoading] = useState(false); + + const maxLines = process.env.REACT_APP_MAX_LINES + ? parseInt(process.env.REACT_APP_MAX_LINES) + : 5000; + + const [logdate, setLogDate] = useState(new Date()); + const [date, setDate] = useState(""); + + const [endDate, setEndDate] = useState(new Date()); + const [endDateFormatted, setEndDateFormatted] = useState(""); + + function formatDateTo_dd_mm_yyyy(inputDate) { + const date = new Date(inputDate); + + const day = String(date.getDate()).padStart(2, "0"); + const month = String(date.getMonth() + 1).padStart(2, "0"); + const year = date.getFullYear(); + + return `${day}_${month}_${year}`; + } + + const handleDateChange = (date: Date | null) => { + setLogDate(date); + if (date) { + // Format date as needed + let formattedDate = formatDateTo_dd_mm_yyyy(date); + setDate(formattedDate); + } else { + setDate(""); + } + }; + + const handleEndDateChange = (date: Date | null) => { + setEndDate(date); + if (date) { + // Format date as needed + let formattedDate = formatDateTo_dd_mm_yyyy(date); + setEndDateFormatted(formattedDate); + } else { + setEndDateFormatted(""); + } + }; + + const fetchMessageData = async () => { + setFlag(false); + setIsLoading(true); + try { + let logData = ""; + let responseType = activeButton === "normal" ? "logs" : "error"; + const response = await fetchServiceData( + "broadcast-transformer", + searchText, + date + ); + logData = response.data.result[responseType]; + const lines = logData.split("\n"); + setMessageLines(lines); + setFlag(true); + } catch (error) { + console.error("Error reading the file:", error); + } + setIsLoading(false); + }; + + const handleSearchInputChange = ( + event: React.ChangeEvent + ) => { + const { value } = event.target; + setSearchText(Number(value)); + + const data = [10, 100, 1000, 5000]; + const uniqueData = Array.from(new Set(data)); + + const suggestions: DropdownItem[] = uniqueData.map((val) => ({ + value: val, + })); + + setAutocompleteSuggestions(suggestions.filter((item) => item.value)); + setShowDropdown(true); + }; + + const handleFilterInputChange = ( + event: React.ChangeEvent + ) => { + const { value } = event.target; + setFilterText(value); + setFilter(true); + }; + + const handleSearchSubmit = (event: React.FormEvent) => { + event.preventDefault(); + setSearchPerformed(true); + setShowDropdown(false); + fetchMessageData(); + }; + + const handleFilterSubmit = (event: React.FormEvent) => { + event.preventDefault(); + fetchMessageData(); + }; + + const handleDropdownItemClick = (value: number) => { + setSearchText(value); + setShowDropdown(false); + }; + + const handleClick = (buttonName) => { + setActiveButton(buttonName); + fetchMessageData(); + }; + + const handleDownload = async (activeButton, date) => { + let response; + if (activeButton === "normal") { + response = await downloadLogData("broadcast-transformer", date); + } else { + response = await downloadErrLogData("broadcast-transformer", date); + } + const responseData = response.data; + console.log(responseData); + + const blob = new Blob([responseData], { type: "text/plain" }); + + const url = URL.createObjectURL(blob); + + const tempAnchor = document.createElement("a"); + tempAnchor.href = url; + const serviceName = "broadcast_transformer"; + const filename = `${serviceName}_${date}.txt`; + tempAnchor.download = filename; + document.body.appendChild(tempAnchor); + tempAnchor.click(); + + document.body.removeChild(tempAnchor); + + URL.revokeObjectURL(url); + }; + + useEffect(() => { + store?.startLoading(); + getFilesData() + .then((res) => { + store?.stopLoading(); + }) + .catch((err) => { + store?.stopLoading(); + toast.error(err.message); + }); + + if (activeButton) { + fetchMessageData(); + } + + if (maxLines <= searchText) { + handleDownload(activeButton, date); + } + }, [activeButton, date, maxLines, searchText]); + + return ( + +
+ + + + + + + + + + + + + + +
+ + + Search + +
+ {showDropdown && + autocompleteSuggestions.length > 0 && + searchText !== 0 && ( +
    + {autocompleteSuggestions.map((item) => ( +
  • handleDropdownItemClick(item.value)} + > + {item.value} +
  • + ))} +
+ )} +
+ +
+ + + Filter + +
+
+
+
+
+ {flag && searchPerformed && ( + + handleClick("normal")} + style={{ + backgroundColor: + activeButton === "normal" ? "#007BFF" : "#B0C4DE", + borderColor: "#007BFF", + }} + > + Normal Logs + + handleClick("err")} + style={{ + backgroundColor: activeButton === "err" ? "#007BFF" : "#B0C4DE", + borderColor: "#007BFF", + }} + > + Error + + + )} + {flag && searchPerformed && !isLoading && messageLines.length === 0 && ( +

+ No data available for selected date +

+ )} + + {!searchPerformed && ( +

Please select number of lines

+ )} + {searchPerformed && ( + + handleDownload(activeButton, date)} + style={{ + backgroundColor: "#007BFF", + borderColor: "#007BFF", + }} + > + Download + + + )} + {searchPerformed && maxLines > searchText && ( +
+ {searchPerformed && ( +
+ {!filter && + activeButton === "normal" && + messageLines.slice(0, searchText).map((line, index) => ( +

+ {line} +

+ ))} + {filter && + activeButton === "normal" && + messageLines + .slice(0, searchText) + .filter((line) => line.includes(filterText)) + .map((line, index) => ( +

+ {line} +

+ ))} + {!filter && + activeButton === "err" && + messageLines.slice(0, searchText).map((line, index) => ( +

+ {line} +

+ ))} + {filter && + activeButton === "err" && + messageLines + .slice(0, searchText) + .filter((line) => line.includes(filterText)) + .map((line, index) => ( +

+ {line} +

+ ))} +
+ )} +
+ )} + {searchPerformed && maxLines <= searchText && ( +
+

+ Too large to display! +

+
+ )} +
+ ); +}; + +export default BroadcastTransformerLogs; diff --git a/src/pages/monitoring/logs/broadcast-transformer/style.css b/src/pages/monitoring/logs/broadcast-transformer/style.css new file mode 100644 index 0000000..499654f --- /dev/null +++ b/src/pages/monitoring/logs/broadcast-transformer/style.css @@ -0,0 +1,59 @@ +.autocomplete-dropdown { + position: absolute; + z-index: 100; + background-color: #fff; + border: 1px solid #ccc; + padding: 5px; + list-style: none; + max-height: 150px; + min-width: 10%; + overflow-y: auto; +} + +.autocomplete-dropdown li { + cursor: pointer; + padding: 8px; +} + +.autocomplete-dropdown li:hover { + background-color: #f0f0f0; +} + +.highlight { + background-color: yellow; +} + +.date-picker-container { + z-index: 9999 !important; + position: relative; +} + +.date-picker { + padding: 5px; + width: 120px; + cursor: pointer; +} + +.light-icon { + position: absolute; + top: 50%; + left:-20px; + transform: translateY(-50%); + font-size: 18px; + color: #333; +} + +.dark-icon { + position: absolute; + top: 50%; + left:-20px; + transform: translateY(-50%); + font-size: 18px; + color: white; +} + +.dark-date-picker .react-datetime-picker__button svg, +.dark-date-picker .react-datetime-picker__button:after, +.dark-date-picker .react-datetime-picker__button:before { + background-color: white !important; +} diff --git a/src/pages/monitoring/logs/inbound/index.tsx b/src/pages/monitoring/logs/inbound/index.tsx new file mode 100644 index 0000000..d5752ff --- /dev/null +++ b/src/pages/monitoring/logs/inbound/index.tsx @@ -0,0 +1,362 @@ +import React, { useEffect, useState } from "react"; +import { + MDBBtn, + MDBBtnGroup, + MDBCol, + MDBContainer, + MDBRow, +} from "mdb-react-ui-kit"; +import "./style.css"; +import Ansi from "ansi-to-react"; +import { useStore } from "../../../../store"; +import toast from "react-hot-toast"; +import { getFilesData } from "../../../../api/getFiles"; +import { downloadLogData } from "../../../../api/downloadLog"; +import { downloadErrLogData } from "../../../../api/downloadErrLog"; +import { fetchServiceData } from "../../../../api/fetchService"; +import { MDBIcon } from "mdb-react-ui-kit"; +import DateTimePicker from "react-datetime-picker"; +import "react-datetime-picker/dist/DateTimePicker.css"; +import "react-calendar/dist/Calendar.css"; +import "react-clock/dist/Clock.css"; + +interface DropdownItem { + value: number; +} + +interface InboundLogsProps extends React.HTMLAttributes { + theme: string; +} + +export const InboundLogs: React.FC = ({ theme }) => { + const store: any = useStore(); + const [searchText, setSearchText] = useState(0); + const [filterText, setFilterText] = useState(""); + const [filter, setFilter] = useState(false); + const [autocompleteSuggestions, setAutocompleteSuggestions] = useState< + DropdownItem[] + >([]); + const [showDropdown, setShowDropdown] = useState(false); + const [messageLines, setMessageLines] = useState([]); + const [searchPerformed, setSearchPerformed] = useState(false); + const [activeButton, setActiveButton] = useState("normal"); + const [flag, setFlag] = useState(false); + const [isLoading, setIsLoading] = useState(false); + + const maxLines = process.env.REACT_APP_MAX_LINES + ? parseInt(process.env.REACT_APP_MAX_LINES) + : 5000; + + const [logdate, setLogDate] = useState(new Date()); + const [date, setDate] = useState(""); + + const [endDate, setEndDate] = useState(new Date()); + const [endDateFormatted, setEndDateFormatted] = useState(""); + + function formatDateTo_dd_mm_yyyy(inputDate) { + const date = new Date(inputDate); + + const day = String(date.getDate()).padStart(2, "0"); + const month = String(date.getMonth() + 1).padStart(2, "0"); + const year = date.getFullYear(); + + return `${day}_${month}_${year}`; + } + + const handleDateChange = (date: Date | null) => { + setLogDate(date); + if (date) { + // Format date as needed + let formattedDate = formatDateTo_dd_mm_yyyy(date); + setDate(formattedDate); + } else { + setDate(""); + } + }; + + const handleEndDateChange = (date: Date | null) => { + setEndDate(date); + if (date) { + // Format date as needed + let formattedDate = formatDateTo_dd_mm_yyyy(date); + setEndDateFormatted(formattedDate); + } else { + setEndDateFormatted(""); + } + }; + + const fetchMessageData = async () => { + setFlag(false); + setIsLoading(true); + try { + let logData = ""; + let responseType = activeButton === "normal" ? "logs" : "error"; + const response = await fetchServiceData("inbound", searchText, date); + logData = response.data.result[responseType]; + const lines = logData.split("\n"); + setMessageLines(lines); + setFlag(true); + } catch (error) { + console.error("Error reading the file:", error); + } + setIsLoading(false); + }; + + + const handleSearchInputChange = ( + event: React.ChangeEvent + ) => { + const { value } = event.target; + setSearchText(Number(value)); + + const data = [10, 100, 1000, 5000]; + const uniqueData = Array.from(new Set(data)); + + const suggestions: DropdownItem[] = uniqueData.map((val) => ({ + value: val, + })); + + setAutocompleteSuggestions(suggestions.filter((item) => item.value)); + setShowDropdown(true); + }; + + const handleFilterInputChange = ( + event: React.ChangeEvent + ) => { + const { value } = event.target; + setFilterText(value); + setFilter(true); + }; + + const handleSearchSubmit = (event: React.FormEvent) => { + event.preventDefault(); + setSearchPerformed(true); + setShowDropdown(false); + fetchMessageData(); + }; + + const handleFilterSubmit = (event: React.FormEvent) => { + event.preventDefault(); + fetchMessageData(); + }; + + const handleDropdownItemClick = (value: number) => { + setSearchText(value); + setShowDropdown(false); + }; + + const handleClick = (buttonName) => { + setActiveButton(buttonName); + fetchMessageData(); + }; + + const handleDownload = async (activeButton,date) => { + let response; + if (activeButton === "normal") { + response = await downloadLogData("inbound", date); + } else { + response = await downloadErrLogData("inbound", date); + } + const responseData = response.data; + console.log(responseData); + + const blob = new Blob([responseData], { type: "text/plain" }); + + const url = URL.createObjectURL(blob); + + const tempAnchor = document.createElement("a"); + tempAnchor.href = url; + const serviceName = "inbound"; + const filename = `${serviceName}_${date}.txt`; + tempAnchor.download = filename; + document.body.appendChild(tempAnchor); + tempAnchor.click(); + + document.body.removeChild(tempAnchor); + + URL.revokeObjectURL(url); + }; + + useEffect(() => { + store?.startLoading(); + getFilesData() + .then((res) => { + store?.stopLoading(); + }) + .catch((err) => { + store?.stopLoading(); + toast.error(err.message); + }); + + if (activeButton) { + fetchMessageData(); + } + + if (maxLines <= searchText) { + handleDownload(activeButton, date); + } + }, [activeButton, date,maxLines,searchText]); + + + return ( + +
+ + + + + + + + + + + + + + +
+ + + Search + +
+ {showDropdown && + autocompleteSuggestions.length > 0 && + searchText !== 0 && ( +
    + {autocompleteSuggestions.map((item) => ( +
  • handleDropdownItemClick(item.value)} + > + {item.value} +
  • + ))} +
+ )} +
+ +
+ + + Filter + +
+
+
+
+
+ {flag && searchPerformed && !isLoading && messageLines.length === 0 && ( +

+ No data available for selected date +

+ )} + + {!searchPerformed && ( +

Please select number of lines

+ )} + {searchPerformed && ( + + handleDownload(activeButton,date)} + style={{ + backgroundColor: "#007BFF", + borderColor: "#007BFF", + }} + > + Download + + + )} + {searchPerformed && maxLines > searchText && ( +
+ {searchPerformed && ( +
+ {!filter && + activeButton === "normal" && + messageLines.slice(0, searchText).map((line, index) => ( +

+ {line} +

+ ))} + {filter && + activeButton === "normal" && + messageLines + .slice(0, searchText) + .filter((line) => line.includes(filterText)) + .map((line, index) => ( +

+ {line} +

+ ))} + {!filter && + activeButton === "err" && + messageLines.slice(0, searchText).map((line, index) => ( +

+ {line} +

+ ))} + {filter && + activeButton === "err" && + messageLines + .slice(0, searchText) + .filter((line) => line.includes(filterText)) + .map((line, index) => ( +

+ {line} +

+ ))} +
+ )} +
+ )} + {searchPerformed && maxLines <= searchText && ( +
+

+ Too large to display! +

+
+ )} +
+ ); +}; + +export default InboundLogs; diff --git a/src/pages/monitoring/logs/inbound/style.css b/src/pages/monitoring/logs/inbound/style.css new file mode 100644 index 0000000..499654f --- /dev/null +++ b/src/pages/monitoring/logs/inbound/style.css @@ -0,0 +1,59 @@ +.autocomplete-dropdown { + position: absolute; + z-index: 100; + background-color: #fff; + border: 1px solid #ccc; + padding: 5px; + list-style: none; + max-height: 150px; + min-width: 10%; + overflow-y: auto; +} + +.autocomplete-dropdown li { + cursor: pointer; + padding: 8px; +} + +.autocomplete-dropdown li:hover { + background-color: #f0f0f0; +} + +.highlight { + background-color: yellow; +} + +.date-picker-container { + z-index: 9999 !important; + position: relative; +} + +.date-picker { + padding: 5px; + width: 120px; + cursor: pointer; +} + +.light-icon { + position: absolute; + top: 50%; + left:-20px; + transform: translateY(-50%); + font-size: 18px; + color: #333; +} + +.dark-icon { + position: absolute; + top: 50%; + left:-20px; + transform: translateY(-50%); + font-size: 18px; + color: white; +} + +.dark-date-picker .react-datetime-picker__button svg, +.dark-date-picker .react-datetime-picker__button:after, +.dark-date-picker .react-datetime-picker__button:before { + background-color: white !important; +} diff --git a/src/pages/monitoring/logs/orchestrator/index.tsx b/src/pages/monitoring/logs/orchestrator/index.tsx new file mode 100644 index 0000000..91612a4 --- /dev/null +++ b/src/pages/monitoring/logs/orchestrator/index.tsx @@ -0,0 +1,396 @@ +import React, { useEffect, useState } from "react"; +import { + MDBBtn, + MDBBtnGroup, + MDBCol, + MDBContainer, + MDBRow, +} from "mdb-react-ui-kit"; +import "./style.css"; +import Ansi from "ansi-to-react"; +import { useStore } from "../../../../store"; +import toast from "react-hot-toast"; +import { getFilesData } from "../../../../api/getFiles"; +import { downloadLogData } from "../../../../api/downloadLog"; +import { downloadErrLogData } from "../../../../api/downloadErrLog"; +import { fetchServiceData } from "../../../../api/fetchService"; +import { MDBIcon } from "mdb-react-ui-kit"; +import DateTimePicker from "react-datetime-picker"; +import "react-datetime-picker/dist/DateTimePicker.css"; +import "react-calendar/dist/Calendar.css"; +import "react-clock/dist/Clock.css"; + +interface DropdownItem { + value: number; +} + +interface OrchestratorLogsProps extends React.HTMLAttributes { + theme: string; +} + +export const OrchestratorLogs: React.FC = ({ + theme, +}) => { + const store: any = useStore(); + const [searchText, setSearchText] = useState(0); + const [filterText, setFilterText] = useState(""); + const [filter, setFilter] = useState(false); + const [autocompleteSuggestions, setAutocompleteSuggestions] = useState< + DropdownItem[] + >([]); + const [showDropdown, setShowDropdown] = useState(false); + const [messageLines, setMessageLines] = useState([]); + const [searchPerformed, setSearchPerformed] = useState(false); + const [activeButton, setActiveButton] = useState("normal"); + const [flag, setFlag] = useState(false); + const [isLoading, setIsLoading] = useState(false); + + const maxLines = process.env.REACT_APP_MAX_LINES + ? parseInt(process.env.REACT_APP_MAX_LINES) + : 5000; + + const [logdate, setLogDate] = useState(new Date()); + const [date, setDate] = useState(""); + + const [endDate, setEndDate] = useState(new Date()); + const [endDateFormatted, setEndDateFormatted] = useState(""); + + function formatDateTo_dd_mm_yyyy(inputDate) { + const date = new Date(inputDate); + + const day = String(date.getDate()).padStart(2, "0"); + const month = String(date.getMonth() + 1).padStart(2, "0"); + const year = date.getFullYear(); + + return `${day}_${month}_${year}`; + } + + const handleDateChange = (date: Date | null) => { + setLogDate(date); + if (date) { + // Format date as needed + let formattedDate = formatDateTo_dd_mm_yyyy(date); + setDate(formattedDate); + } else { + setDate(""); + } + }; + + const handleEndDateChange = (date: Date | null) => { + setEndDate(date); + if (date) { + // Format date as needed + let formattedDate = formatDateTo_dd_mm_yyyy(date); + setEndDateFormatted(formattedDate); + } else { + setEndDateFormatted(""); + } + }; + + const fetchMessageData = async () => { + setFlag(false); + setIsLoading(true); + try { + let logData = ""; + let responseType = activeButton === "normal" ? "logs" : "error"; + const response = await fetchServiceData("orchestrator", searchText, date); + logData = response.data.result[responseType]; + const lines = logData.split("\n"); + setMessageLines(lines); + setFlag(true); + } catch (error) { + console.error("Error reading the file:", error); + } + setIsLoading(false); + }; + + const handleSearchInputChange = ( + event: React.ChangeEvent + ) => { + const { value } = event.target; + setSearchText(Number(value)); + + const data = [10, 100, 1000, 5000]; + const uniqueData = Array.from(new Set(data)); + + const suggestions: DropdownItem[] = uniqueData.map((val) => ({ + value: val, + })); + + setAutocompleteSuggestions(suggestions.filter((item) => item.value)); + setShowDropdown(true); + }; + + const handleFilterInputChange = ( + event: React.ChangeEvent + ) => { + const { value } = event.target; + setFilterText(value); + setFilter(true); + }; + + const handleSearchSubmit = (event: React.FormEvent) => { + event.preventDefault(); + setSearchPerformed(true); + setShowDropdown(false); + fetchMessageData(); + }; + + const handleFilterSubmit = (event: React.FormEvent) => { + event.preventDefault(); + fetchMessageData(); + }; + + const handleDropdownItemClick = (value: number) => { + setSearchText(value); + setShowDropdown(false); + }; + + const handleClick = (buttonName) => { + setActiveButton(buttonName); + fetchMessageData(); + }; + + const handleDownload = async (activeButton, date) => { + let response; + if (activeButton === "normal") { + response = await downloadLogData("orchestrator", date); + } else { + response = await downloadErrLogData("orchestrator", date); + } + const responseData = response.data; + console.log(responseData); + + const blob = new Blob([responseData], { type: "text/plain" }); + + const url = URL.createObjectURL(blob); + + const tempAnchor = document.createElement("a"); + tempAnchor.href = url; + const serviceName = "orchestrator"; + const filename = `${serviceName}_${date}.txt`; + tempAnchor.download = filename; + document.body.appendChild(tempAnchor); + tempAnchor.click(); + + document.body.removeChild(tempAnchor); + + URL.revokeObjectURL(url); + }; + + useEffect(() => { + store?.startLoading(); + getFilesData() + .then((res) => { + store?.stopLoading(); + }) + .catch((err) => { + store?.stopLoading(); + toast.error(err.message); + }); + + if (activeButton) { + fetchMessageData(); + } + + if (maxLines <= searchText) { + handleDownload(activeButton, date); + } + }, [activeButton, date, maxLines, searchText]); + + return ( + +
+ + + + + + + + + + + + + + + +
+ + + Search + +
+ {showDropdown && + autocompleteSuggestions.length > 0 && + searchText !== 0 && ( +
    + {autocompleteSuggestions.map((item) => ( +
  • handleDropdownItemClick(item.value)} + > + {item.value} +
  • + ))} +
+ )} +
+ +
+ + + Filter + +
+
+
+
+
+ {flag && searchPerformed && ( + + handleClick("normal")} + style={{ + backgroundColor: + activeButton === "normal" ? "#007BFF" : "#B0C4DE", + borderColor: "#007BFF", + }} + > + Normal Logs + + handleClick("err")} + style={{ + backgroundColor: activeButton === "err" ? "#007BFF" : "#B0C4DE", + borderColor: "#007BFF", + }} + > + Error + + + )} + {flag && searchPerformed && !isLoading && messageLines.length === 0 && ( +

+ No data available for selected date +

+ )} + + {!searchPerformed && ( +

Please select number of lines

+ )} + {searchPerformed && ( + + handleDownload(activeButton, date)} + style={{ + backgroundColor: "#007BFF", + borderColor: "#007BFF", + }} + > + Download + + + )} + {searchPerformed && maxLines > searchText && ( +
+ {searchPerformed && ( +
+ {!filter && + activeButton === "normal" && + messageLines.slice(0, searchText).map((line, index) => ( +

+ {line} +

+ ))} + {filter && + activeButton === "normal" && + messageLines + .slice(0, searchText) + .filter((line) => line.includes(filterText)) + .map((line, index) => ( +

+ {line} +

+ ))} + {!filter && + activeButton === "err" && + messageLines.slice(0, searchText).map((line, index) => ( +

+ {line} +

+ ))} + {filter && + activeButton === "err" && + messageLines + .slice(0, searchText) + .filter((line) => line.includes(filterText)) + .map((line, index) => ( +

+ {line} +

+ ))} +
+ )} +
+ )} + {searchPerformed && maxLines <= searchText && ( +
+

+ Too large to display! +

+
+ )} +
+ ); +}; + +export default OrchestratorLogs; diff --git a/src/pages/monitoring/logs/orchestrator/style.css b/src/pages/monitoring/logs/orchestrator/style.css new file mode 100644 index 0000000..499654f --- /dev/null +++ b/src/pages/monitoring/logs/orchestrator/style.css @@ -0,0 +1,59 @@ +.autocomplete-dropdown { + position: absolute; + z-index: 100; + background-color: #fff; + border: 1px solid #ccc; + padding: 5px; + list-style: none; + max-height: 150px; + min-width: 10%; + overflow-y: auto; +} + +.autocomplete-dropdown li { + cursor: pointer; + padding: 8px; +} + +.autocomplete-dropdown li:hover { + background-color: #f0f0f0; +} + +.highlight { + background-color: yellow; +} + +.date-picker-container { + z-index: 9999 !important; + position: relative; +} + +.date-picker { + padding: 5px; + width: 120px; + cursor: pointer; +} + +.light-icon { + position: absolute; + top: 50%; + left:-20px; + transform: translateY(-50%); + font-size: 18px; + color: #333; +} + +.dark-icon { + position: absolute; + top: 50%; + left:-20px; + transform: translateY(-50%); + font-size: 18px; + color: white; +} + +.dark-date-picker .react-datetime-picker__button svg, +.dark-date-picker .react-datetime-picker__button:after, +.dark-date-picker .react-datetime-picker__button:before { + background-color: white !important; +} diff --git a/src/pages/monitoring/logs/outbound/index.tsx b/src/pages/monitoring/logs/outbound/index.tsx new file mode 100644 index 0000000..f0fc989 --- /dev/null +++ b/src/pages/monitoring/logs/outbound/index.tsx @@ -0,0 +1,393 @@ +import React, { useEffect, useState } from "react"; +import { + MDBBtn, + MDBBtnGroup, + MDBCol, + MDBContainer, + MDBRow, +} from "mdb-react-ui-kit"; +import "./style.css"; +import Ansi from "ansi-to-react"; +import { useStore } from "../../../../store"; +import toast from "react-hot-toast"; +import { getFilesData } from "../../../../api/getFiles"; +import { downloadLogData } from "../../../../api/downloadLog"; +import { downloadErrLogData } from "../../../../api/downloadErrLog"; +import { fetchServiceData } from "../../../../api/fetchService"; +import { MDBIcon } from "mdb-react-ui-kit"; +import DateTimePicker from "react-datetime-picker"; +import "react-datetime-picker/dist/DateTimePicker.css"; +import "react-calendar/dist/Calendar.css"; +import "react-clock/dist/Clock.css"; + +interface DropdownItem { + value: number; +} + +interface OutboundLogsProps extends React.HTMLAttributes { + theme: string; +} + +export const OutboundLogs: React.FC = ({ theme }) => { + const store: any = useStore(); + const [searchText, setSearchText] = useState(0); + const [filterText, setFilterText] = useState(""); + const [filter, setFilter] = useState(false); + const [autocompleteSuggestions, setAutocompleteSuggestions] = useState< + DropdownItem[] + >([]); + const [showDropdown, setShowDropdown] = useState(false); + const [messageLines, setMessageLines] = useState([]); + const [searchPerformed, setSearchPerformed] = useState(false); + const [activeButton, setActiveButton] = useState("normal"); + const [flag, setFlag] = useState(false); + const [isLoading, setIsLoading] = useState(false); + + const maxLines = process.env.REACT_APP_MAX_LINES + ? parseInt(process.env.REACT_APP_MAX_LINES) + : 5000; + + const [logdate, setLogDate] = useState(new Date()); + const [date, setDate] = useState(""); + + const [endDate, setEndDate] = useState(new Date()); + const [endDateFormatted, setEndDateFormatted] = useState(""); + + function formatDateTo_dd_mm_yyyy(inputDate) { + const date = new Date(inputDate); + + const day = String(date.getDate()).padStart(2, "0"); + const month = String(date.getMonth() + 1).padStart(2, "0"); + const year = date.getFullYear(); + + return `${day}_${month}_${year}`; + } + + const handleDateChange = (date: Date | null) => { + setLogDate(date); + if (date) { + // Format date as needed + let formattedDate = formatDateTo_dd_mm_yyyy(date); + setDate(formattedDate); + } else { + setDate(""); + } + }; + + const handleEndDateChange = (date: Date | null) => { + setEndDate(date); + if (date) { + // Format date as needed + let formattedDate = formatDateTo_dd_mm_yyyy(date); + setEndDateFormatted(formattedDate); + } else { + setEndDateFormatted(""); + } + }; + + const fetchMessageData = async () => { + setFlag(false); + setIsLoading(true); + try { + let logData = ""; + let responseType = activeButton === "normal" ? "logs" : "error"; + const response = await fetchServiceData("outbound", searchText, date); + logData = response.data.result[responseType]; + const lines = logData.split("\n"); + setMessageLines(lines); + setFlag(true); + } catch (error) { + console.error("Error reading the file:", error); + } + setIsLoading(false); + }; + + const handleSearchInputChange = ( + event: React.ChangeEvent + ) => { + const { value } = event.target; + setSearchText(Number(value)); + + const data = [10, 100, 1000, 5000]; + const uniqueData = Array.from(new Set(data)); + + const suggestions: DropdownItem[] = uniqueData.map((val) => ({ + value: val, + })); + + setAutocompleteSuggestions(suggestions.filter((item) => item.value)); + setShowDropdown(true); + }; + + const handleFilterInputChange = ( + event: React.ChangeEvent + ) => { + const { value } = event.target; + setFilterText(value); + setFilter(true); + }; + + const handleSearchSubmit = (event: React.FormEvent) => { + event.preventDefault(); + setSearchPerformed(true); + setShowDropdown(false); + fetchMessageData(); + }; + + const handleFilterSubmit = (event: React.FormEvent) => { + event.preventDefault(); + fetchMessageData(); + }; + + const handleDropdownItemClick = (value: number) => { + setSearchText(value); + setShowDropdown(false); + }; + + const handleClick = (buttonName) => { + setActiveButton(buttonName); + fetchMessageData(); + }; + + const handleDownload = async (activeButton, date) => { + let response; + if (activeButton === "normal") { + response = await downloadLogData("outbound", date); + } else { + response = await downloadErrLogData("outbound", date); + } + const responseData = response.data; + console.log(responseData); + + const blob = new Blob([responseData], { type: "text/plain" }); + + const url = URL.createObjectURL(blob); + + const tempAnchor = document.createElement("a"); + tempAnchor.href = url; + const serviceName = "outbound"; + const filename = `${serviceName}_${date}.txt`; + tempAnchor.download = filename; + document.body.appendChild(tempAnchor); + tempAnchor.click(); + + document.body.removeChild(tempAnchor); + + URL.revokeObjectURL(url); + }; + + useEffect(() => { + store?.startLoading(); + getFilesData() + .then((res) => { + store?.stopLoading(); + }) + .catch((err) => { + store?.stopLoading(); + toast.error(err.message); + }); + + if (activeButton) { + fetchMessageData(); + } + + if (maxLines <= searchText) { + handleDownload(activeButton, date); + } + }, [activeButton, date, maxLines, searchText]); + + return ( + +
+ + + + + + + + + + + + + + +
+ + + Search + +
+ {showDropdown && + autocompleteSuggestions.length > 0 && + searchText !== 0 && ( +
    + {autocompleteSuggestions.map((item) => ( +
  • handleDropdownItemClick(item.value)} + > + {item.value} +
  • + ))} +
+ )} +
+ +
+ + + Filter + +
+
+
+
+
+ {flag && searchPerformed && ( + + handleClick("normal")} + style={{ + backgroundColor: + activeButton === "normal" ? "#007BFF" : "#B0C4DE", + borderColor: "#007BFF", + }} + > + Normal Logs + + handleClick("err")} + style={{ + backgroundColor: activeButton === "err" ? "#007BFF" : "#B0C4DE", + borderColor: "#007BFF", + }} + > + Error + + + )} + {flag && searchPerformed && !isLoading && messageLines.length === 0 && ( +

+ No data available for selected date +

+ )} + + {!searchPerformed && ( +

Please select number of lines

+ )} + {searchPerformed && ( + + handleDownload(activeButton, date)} + style={{ + backgroundColor: "#007BFF", + borderColor: "#007BFF", + }} + > + Download + + + )} + {searchPerformed && maxLines > searchText && ( +
+ {searchPerformed && ( +
+ {!filter && + activeButton === "normal" && + messageLines.slice(0, searchText).map((line, index) => ( +

+ {line} +

+ ))} + {filter && + activeButton === "normal" && + messageLines + .slice(0, searchText) + .filter((line) => line.includes(filterText)) + .map((line, index) => ( +

+ {line} +

+ ))} + {!filter && + activeButton === "err" && + messageLines.slice(0, searchText).map((line, index) => ( +

+ {line} +

+ ))} + {filter && + activeButton === "err" && + messageLines + .slice(0, searchText) + .filter((line) => line.includes(filterText)) + .map((line, index) => ( +

+ {line} +

+ ))} +
+ )} +
+ )} + {searchPerformed && maxLines <= searchText && ( +
+

+ Too large to display! +

+
+ )} +
+ ); +}; + +export default OutboundLogs; diff --git a/src/pages/monitoring/logs/outbound/style.css b/src/pages/monitoring/logs/outbound/style.css new file mode 100644 index 0000000..499654f --- /dev/null +++ b/src/pages/monitoring/logs/outbound/style.css @@ -0,0 +1,59 @@ +.autocomplete-dropdown { + position: absolute; + z-index: 100; + background-color: #fff; + border: 1px solid #ccc; + padding: 5px; + list-style: none; + max-height: 150px; + min-width: 10%; + overflow-y: auto; +} + +.autocomplete-dropdown li { + cursor: pointer; + padding: 8px; +} + +.autocomplete-dropdown li:hover { + background-color: #f0f0f0; +} + +.highlight { + background-color: yellow; +} + +.date-picker-container { + z-index: 9999 !important; + position: relative; +} + +.date-picker { + padding: 5px; + width: 120px; + cursor: pointer; +} + +.light-icon { + position: absolute; + top: 50%; + left:-20px; + transform: translateY(-50%); + font-size: 18px; + color: #333; +} + +.dark-icon { + position: absolute; + top: 50%; + left:-20px; + transform: translateY(-50%); + font-size: 18px; + color: white; +} + +.dark-date-picker .react-datetime-picker__button svg, +.dark-date-picker .react-datetime-picker__button:after, +.dark-date-picker .react-datetime-picker__button:before { + background-color: white !important; +} diff --git a/src/pages/monitoring/logs/transformer/index.tsx b/src/pages/monitoring/logs/transformer/index.tsx new file mode 100644 index 0000000..0ecf531 --- /dev/null +++ b/src/pages/monitoring/logs/transformer/index.tsx @@ -0,0 +1,393 @@ +import React, { useEffect, useState } from "react"; +import { + MDBBtn, + MDBBtnGroup, + MDBCol, + MDBContainer, + MDBRow, +} from "mdb-react-ui-kit"; +import "./style.css"; +import Ansi from "ansi-to-react"; +import { useStore } from "../../../../store"; +import toast from "react-hot-toast"; +import { getFilesData } from "../../../../api/getFiles"; +import { downloadLogData } from "../../../../api/downloadLog"; +import { downloadErrLogData } from "../../../../api/downloadErrLog"; +import { fetchServiceData } from "../../../../api/fetchService"; +import { MDBIcon } from "mdb-react-ui-kit"; +import DateTimePicker from "react-datetime-picker"; +import "react-datetime-picker/dist/DateTimePicker.css"; +import "react-calendar/dist/Calendar.css"; +import "react-clock/dist/Clock.css"; + +interface DropdownItem { + value: number; +} + +interface TransformerLogsProps extends React.HTMLAttributes { + theme: string; +} + +export const TransformerLogs: React.FC = ({ theme }) => { + const store: any = useStore(); + const [searchText, setSearchText] = useState(0); + const [filterText, setFilterText] = useState(""); + const [filter, setFilter] = useState(false); + const [autocompleteSuggestions, setAutocompleteSuggestions] = useState< + DropdownItem[] + >([]); + const [showDropdown, setShowDropdown] = useState(false); + const [messageLines, setMessageLines] = useState([]); + const [searchPerformed, setSearchPerformed] = useState(false); + const [activeButton, setActiveButton] = useState("normal"); + const [flag, setFlag] = useState(false); + const [isLoading, setIsLoading] = useState(false); + + const maxLines = process.env.REACT_APP_MAX_LINES + ? parseInt(process.env.REACT_APP_MAX_LINES) + : 5000; + + const [logdate, setLogDate] = useState(new Date()); + const [date, setDate] = useState(""); + + const [endDate, setEndDate] = useState(new Date()); + const [endDateFormatted, setEndDateFormatted] = useState(""); + + function formatDateTo_dd_mm_yyyy(inputDate) { + const date = new Date(inputDate); + + const day = String(date.getDate()).padStart(2, "0"); + const month = String(date.getMonth() + 1).padStart(2, "0"); + const year = date.getFullYear(); + + return `${day}_${month}_${year}`; + } + + const handleDateChange = (date: Date | null) => { + setLogDate(date); + if (date) { + // Format date as needed + let formattedDate = formatDateTo_dd_mm_yyyy(date); + setDate(formattedDate); + } else { + setDate(""); + } + }; + + const handleEndDateChange = (date: Date | null) => { + setEndDate(date); + if (date) { + // Format date as needed + let formattedDate = formatDateTo_dd_mm_yyyy(date); + setEndDateFormatted(formattedDate); + } else { + setEndDateFormatted(""); + } + }; + + const fetchMessageData = async () => { + setFlag(false); + setIsLoading(true); + try { + let logData = ""; + let responseType = activeButton === "normal" ? "logs" : "error"; + const response = await fetchServiceData("transformer", searchText, date); + logData = response.data.result[responseType]; + const lines = logData.split("\n"); + setMessageLines(lines); + setFlag(true); + } catch (error) { + console.error("Error reading the file:", error); + } + setIsLoading(false); + }; + + const handleSearchInputChange = ( + event: React.ChangeEvent + ) => { + const { value } = event.target; + setSearchText(Number(value)); + + const data = [10, 100, 1000, 5000]; + const uniqueData = Array.from(new Set(data)); + + const suggestions: DropdownItem[] = uniqueData.map((val) => ({ + value: val, + })); + + setAutocompleteSuggestions(suggestions.filter((item) => item.value)); + setShowDropdown(true); + }; + + const handleFilterInputChange = ( + event: React.ChangeEvent + ) => { + const { value } = event.target; + setFilterText(value); + setFilter(true); + }; + + const handleSearchSubmit = (event: React.FormEvent) => { + event.preventDefault(); + setSearchPerformed(true); + setShowDropdown(false); + fetchMessageData(); + }; + + const handleFilterSubmit = (event: React.FormEvent) => { + event.preventDefault(); + fetchMessageData(); + }; + + const handleDropdownItemClick = (value: number) => { + setSearchText(value); + setShowDropdown(false); + }; + + const handleClick = (buttonName) => { + setActiveButton(buttonName); + fetchMessageData(); + }; + + const handleDownload = async (activeButton, date) => { + let response; + if (activeButton === "normal") { + response = await downloadLogData("transformer", date); + } else { + response = await downloadErrLogData("transformer", date); + } + const responseData = response.data; + console.log(responseData); + + const blob = new Blob([responseData], { type: "text/plain" }); + + const url = URL.createObjectURL(blob); + + const tempAnchor = document.createElement("a"); + tempAnchor.href = url; + const serviceName = "transformer"; + const filename = `${serviceName}_${date}.txt`; + tempAnchor.download = filename; + document.body.appendChild(tempAnchor); + tempAnchor.click(); + + document.body.removeChild(tempAnchor); + + URL.revokeObjectURL(url); + }; + + useEffect(() => { + store?.startLoading(); + getFilesData() + .then((res) => { + store?.stopLoading(); + }) + .catch((err) => { + store?.stopLoading(); + toast.error(err.message); + }); + + if (activeButton) { + fetchMessageData(); + } + + if (maxLines <= searchText) { + handleDownload(activeButton, date); + } + }, [activeButton, date, maxLines, searchText]); + + return ( + +
+ + + + + + + + + + + + + + +
+ + + Search + +
+ {showDropdown && + autocompleteSuggestions.length > 0 && + searchText !== 0 && ( +
    + {autocompleteSuggestions.map((item) => ( +
  • handleDropdownItemClick(item.value)} + > + {item.value} +
  • + ))} +
+ )} +
+ +
+ + + Filter + +
+
+
+
+
+ {flag && searchPerformed && ( + + handleClick("normal")} + style={{ + backgroundColor: + activeButton === "normal" ? "#007BFF" : "#B0C4DE", + borderColor: "#007BFF", + }} + > + Normal Logs + + handleClick("err")} + style={{ + backgroundColor: activeButton === "err" ? "#007BFF" : "#B0C4DE", + borderColor: "#007BFF", + }} + > + Error + + + )} + {flag && searchPerformed && !isLoading && messageLines.length === 0 && ( +

+ No data available for selected date +

+ )} + + {!searchPerformed && ( +

Please select number of lines

+ )} + {searchPerformed && ( + + handleDownload(activeButton, date)} + style={{ + backgroundColor: "#007BFF", + borderColor: "#007BFF", + }} + > + Download + + + )} + {searchPerformed && maxLines > searchText && ( +
+ {searchPerformed && ( +
+ {!filter && + activeButton === "normal" && + messageLines.slice(0, searchText).map((line, index) => ( +

+ {line} +

+ ))} + {filter && + activeButton === "normal" && + messageLines + .slice(0, searchText) + .filter((line) => line.includes(filterText)) + .map((line, index) => ( +

+ {line} +

+ ))} + {!filter && + activeButton === "err" && + messageLines.slice(0, searchText).map((line, index) => ( +

+ {line} +

+ ))} + {filter && + activeButton === "err" && + messageLines + .slice(0, searchText) + .filter((line) => line.includes(filterText)) + .map((line, index) => ( +

+ {line} +

+ ))} +
+ )} +
+ )} + {searchPerformed && maxLines <= searchText && ( +
+

+ Too large to display! +

+
+ )} +
+ ); +}; + +export default TransformerLogs; diff --git a/src/pages/monitoring/logs/transformer/style.css b/src/pages/monitoring/logs/transformer/style.css new file mode 100644 index 0000000..499654f --- /dev/null +++ b/src/pages/monitoring/logs/transformer/style.css @@ -0,0 +1,59 @@ +.autocomplete-dropdown { + position: absolute; + z-index: 100; + background-color: #fff; + border: 1px solid #ccc; + padding: 5px; + list-style: none; + max-height: 150px; + min-width: 10%; + overflow-y: auto; +} + +.autocomplete-dropdown li { + cursor: pointer; + padding: 8px; +} + +.autocomplete-dropdown li:hover { + background-color: #f0f0f0; +} + +.highlight { + background-color: yellow; +} + +.date-picker-container { + z-index: 9999 !important; + position: relative; +} + +.date-picker { + padding: 5px; + width: 120px; + cursor: pointer; +} + +.light-icon { + position: absolute; + top: 50%; + left:-20px; + transform: translateY(-50%); + font-size: 18px; + color: #333; +} + +.dark-icon { + position: absolute; + top: 50%; + left:-20px; + transform: translateY(-50%); + font-size: 18px; + color: white; +} + +.dark-date-picker .react-datetime-picker__button svg, +.dark-date-picker .react-datetime-picker__button:after, +.dark-date-picker .react-datetime-picker__button:before { + background-color: white !important; +} diff --git a/src/pages/monitoring/logs/uci-api/index.tsx b/src/pages/monitoring/logs/uci-api/index.tsx new file mode 100644 index 0000000..6c0d354 --- /dev/null +++ b/src/pages/monitoring/logs/uci-api/index.tsx @@ -0,0 +1,397 @@ +import React, { useEffect, useState } from "react"; +import { + MDBBtn, + MDBBtnGroup, + MDBCol, + MDBContainer, + MDBRow, +} from "mdb-react-ui-kit"; +import "./style.css"; +import Ansi from "ansi-to-react"; +import { useStore } from "../../../../store"; +import toast from "react-hot-toast"; +import { getFilesData } from "../../../../api/getFiles"; +import { downloadLogData } from "../../../../api/downloadLog"; +import { downloadErrLogData } from "../../../../api/downloadErrLog"; +import { fetchServiceData } from "../../../../api/fetchService"; +import { MDBIcon } from "mdb-react-ui-kit"; +import DateTimePicker from "react-datetime-picker"; +import "react-datetime-picker/dist/DateTimePicker.css"; +import "react-calendar/dist/Calendar.css"; +import "react-clock/dist/Clock.css"; + +interface DropdownItem { + value: number; +} + +interface UCIAPIlogsProps extends React.HTMLAttributes { + theme: string; +} + +export const UCIAPIlogs: React.FC = ({ theme }) => { + const store: any = useStore(); + const [searchText, setSearchText] = useState(0); + const [filterText, setFilterText] = useState(""); + const [filter, setFilter] = useState(false); + const [autocompleteSuggestions, setAutocompleteSuggestions] = useState< + DropdownItem[] + >([]); + const [showDropdown, setShowDropdown] = useState(false); + const [messageLines, setMessageLines] = useState([]); + const [searchPerformed, setSearchPerformed] = useState(false); + const [activeButton, setActiveButton] = useState("normal"); + const [flag, setFlag] = useState(false); + const [isLoading, setIsLoading] = useState(false); + + const maxLines = process.env.REACT_APP_MAX_LINES + ? parseInt(process.env.REACT_APP_MAX_LINES) + : 5000; + + const [logdate, setLogDate] = useState(new Date()); + const [date, setDate] = useState(""); + + const [endDate, setEndDate] = useState(new Date()); + const [endDateFormatted, setEndDateFormatted] = useState(""); + + function formatDateTo_dd_mm_yyyy(inputDate) { + const date = new Date(inputDate); + + const day = String(date.getDate()).padStart(2, "0"); + const month = String(date.getMonth() + 1).padStart(2, "0"); + const year = date.getFullYear(); + + return `${day}_${month}_${year}`; + } + + const handleDateChange = (date: Date | null) => { + setLogDate(date); + if (date) { + // Format date as needed + let formattedDate = formatDateTo_dd_mm_yyyy(date); + setDate(formattedDate); + } else { + setDate(""); + } + }; + + const handleEndDateChange = (date: Date | null) => { + setEndDate(date); + if (date) { + // Format date as needed + let formattedDate = formatDateTo_dd_mm_yyyy(date); + setEndDateFormatted(formattedDate); + } else { + setEndDateFormatted(""); + } + }; + + const fetchMessageData = async () => { + setFlag(false); + setIsLoading(true); + try { + let logData = ""; + let responseType = activeButton === "normal" ? "logs" : "error"; + console.log(date) + const response = await fetchServiceData("uci-apis", searchText, date); + logData = response.data.result[responseType]; + const lines = logData.split("\n"); + setMessageLines(lines); + setFlag(true); + } catch (error) { + console.error("Error reading the file:", error); + } + setIsLoading(false); + }; + + const handleSearchInputChange = ( + event: React.ChangeEvent + ) => { + const { value } = event.target; + setSearchText(Number(value)); + + const data = [10, 100, 1000, 5000]; + const uniqueData = Array.from(new Set(data)); + + const suggestions: DropdownItem[] = uniqueData.map((val) => ({ + value: val, + })); + + setAutocompleteSuggestions(suggestions.filter((item) => item.value)); + setShowDropdown(!value); + }; + + const handleFilterInputChange = ( + event: React.ChangeEvent + ) => { + const { value } = event.target; + setFilterText(value); + setFilter(true); + }; + + const handleSearchSubmit = (event: React.FormEvent) => { + event.preventDefault(); + setSearchPerformed(true); + setShowDropdown(false); + fetchMessageData(); + }; + + const handleFilterSubmit = (event: React.FormEvent) => { + event.preventDefault(); + fetchMessageData(); + }; + + const handleDropdownItemClick = (value: number) => { + setSearchText(value); + setShowDropdown(false); + }; + + const handleClick = (buttonName) => { + setActiveButton(buttonName); + setShowDropdown(false); + fetchMessageData(); + }; + + const handleDownload = async (activeButton, date) => { + let response; + if (activeButton === "normal") { + response = await downloadLogData("uci-apis", date); + } else { + response = await downloadErrLogData("uci-apis", date); + } + const responseData = response.data; + + const blob = new Blob([responseData], { type: "text/plain" }); + + const url = URL.createObjectURL(blob); + + const tempAnchor = document.createElement("a"); + tempAnchor.href = url; + const serviceName = "uci_api"; + const filename = `${serviceName}_${date}.txt`; + tempAnchor.download = filename; + document.body.appendChild(tempAnchor); + tempAnchor.click(); + + document.body.removeChild(tempAnchor); + + URL.revokeObjectURL(url); + }; + + useEffect(() => { + store?.startLoading(); + getFilesData() + .then((res) => { + store?.stopLoading(); + }) + .catch((err) => { + store?.stopLoading(); + toast.error(err.message); + }); + + if (activeButton) { + fetchMessageData(); + } + + if (maxLines <= searchText) { + handleDownload(activeButton, date); + } + }, [activeButton, date, maxLines, searchText]); + + return ( + +
+ + + + + + + + + + + + + + +
+ + + Search + +
+ {showDropdown && + autocompleteSuggestions.length > 0 && + searchText !== 0 && ( +
    + {autocompleteSuggestions.map((item) => ( +
  • handleDropdownItemClick(item.value)} + > + {item.value} +
  • + ))} +
+ )} +
+ +
+ + + Filter + +
+
+
+
+
+ {flag && searchPerformed && ( + + handleClick("normal")} + style={{ + backgroundColor: + activeButton === "normal" ? "#007BFF" : "#B0C4DE", + borderColor: "#007BFF", + }} + > + Normal Logs + + handleClick("err")} + style={{ + backgroundColor: activeButton === "err" ? "#007BFF" : "#B0C4DE", + borderColor: "#007BFF", + }} + > + Error + + + )} + {flag && searchPerformed && !isLoading && messageLines.length === 0 && ( +

+ No data available for selected date +

+ )} + + {!searchPerformed && ( +

Please select number of lines

+ )} + {searchPerformed && ( + + handleDownload(activeButton, date)} + style={{ + backgroundColor: "#007BFF", + borderColor: "#007BFF", + }} + > + Download + + + )} + {searchPerformed && maxLines > searchText && ( +
+ {searchPerformed && ( +
+ {!filter && + activeButton === "normal" && + messageLines.slice(0, searchText).map((line, index) => ( +

+ {line} +

+ ))} + {filter && + activeButton === "normal" && + messageLines + .slice(0, searchText) + .filter((line) => line.includes(filterText)) + .map((line, index) => ( +

+ {line} +

+ ))} + {!filter && + activeButton === "err" && + messageLines.slice(0, searchText).map((line, index) => ( +

+ {line} +

+ ))} + {filter && + activeButton === "err" && + messageLines + .slice(0, searchText) + .filter((line) => line.includes(filterText)) + .map((line, index) => ( +

+ {line} +

+ ))} +
+ )} +
+ )} + {searchPerformed && maxLines <= searchText && ( +
+

+ Too large to display! +

+
+ )} +
+ ); +}; + +export default UCIAPIlogs; diff --git a/src/pages/monitoring/logs/uci-api/style.css b/src/pages/monitoring/logs/uci-api/style.css new file mode 100644 index 0000000..e10503f --- /dev/null +++ b/src/pages/monitoring/logs/uci-api/style.css @@ -0,0 +1,59 @@ +.autocomplete-dropdown { + position: absolute; + z-index: 100; + background-color: #fff; + border: 1px solid #ccc; + padding: 5px; + list-style: none; + max-height: 150px; + min-width: 5%; + overflow-y: auto; +} + +.autocomplete-dropdown li { + cursor: pointer; + padding: 8px; +} + +.autocomplete-dropdown li:hover { + background-color: #f0f0f0; +} + +.highlight { + background-color: yellow; +} + +.date-picker-container { + z-index: 9999 !important; + position: relative; +} + +.date-picker { + padding: 5px; + width: 500px; + cursor: pointer; +} + +.light-icon { + position: absolute; + top: 50%; + left: -20px; + transform: translateY(-50%); + font-size: 18px; + color: #333; +} + +.dark-icon { + position: absolute; + top: 50%; + left: -20px; + transform: translateY(-50%); + font-size: 18px; + color: white; +} + +.dark-date-picker .react-datetime-picker__button svg, +.dark-date-picker .react-datetime-picker__button:after, +.dark-date-picker .react-datetime-picker__button:before { + background-color: white !important; +} diff --git a/src/pages/monitoring/orchestrator/index.tsx b/src/pages/monitoring/orchestrator/index.tsx new file mode 100644 index 0000000..193c4a2 --- /dev/null +++ b/src/pages/monitoring/orchestrator/index.tsx @@ -0,0 +1,319 @@ +import { + MDBBtn, + MDBCol, + MDBDropdown, + MDBDropdownItem, + MDBDropdownMenu, + MDBDropdownToggle, + MDBRow, +} from "mdb-react-ui-kit"; +import BarChart from "../../../components/visualisation/bar"; +import React, { useEffect, useState } from "react"; +import { useStore } from "../../../store"; +import { getBots } from "../../../api/getBots"; +import { toast } from "react-hot-toast"; +import "./style.css"; +import PieChart from "../../../components/visualisation/pie"; +import LineChart from "../../../components/visualisation/line"; +// import { formatDate, reverseFormatDate } from "../../../utils/functions"; +import { fetchRealtime } from "../../../api/fetchRealtimeData"; +import { getFilesData } from "../../../api/getFiles"; +import { convertToShortDate, formatDate, reverseFormatDate } from "../../../utils/functions"; + +interface AutocompleteItem { + value: string; +} + +interface OrchestratorProps extends React.HTMLAttributes { + theme: string; +} + +export const Orchestrator: React.FC = ({ theme }) => { + const [selectedChart, setSelectedChart] = useState("barchart"); + const [dropdownLabel, setDropdownLabel] = useState("Select Chart"); + const [searchText, setSearchText] = useState(""); + // const [autocompleteSuggestions, setAutocompleteSuggestions] = useState< + // AutocompleteItem[] + // >([]); + const [autocompleteSuggestionsFile, setAutocompleteSuggestionsFile] = + useState([]); + const [botList, setBotList] = useState([]); + const store: any = useStore(); + + const [selected, setSelected] = useState(""); + const [dropdown, setDropdown] = useState(true); + + const [OrchestratorData, setOrchestratorData] = useState([]); + + const [final, setFinal] = useState(""); + + const func = async () => { + if (localStorage.getItem("file")) { + const file = localStorage.getItem("file"); + const apiEndpoint = fetchRealtime(file); + try { + const response = await apiEndpoint; + const res = JSON.parse(response.data.result); + setOrchestratorData(res["Orchestrator".trim()] || {}); + } catch (error) { + console.error("Error toggling:", error); + } + } else if (final !== "") { + const file = reverseFormatDate(final); + localStorage.setItem("file", file); + + const shortDate = convertToShortDate(selected); + localStorage.setItem("shortDate", shortDate); + localStorage.setItem("data_time", selected); + + const apiEndpoint = fetchRealtime(file); + try { + const response = await apiEndpoint; + const res = JSON.parse(response.data.result); + setOrchestratorData(res["Orchestrator".trim()] || {}); + } catch (error) { + console.error("Error toggling:", error); + } + } + fetchBotData(); + }; + + useEffect(() => { + func(); + // fetchBotData(); + }, [final]); + + const dataBar = { + labels: Object.keys(OrchestratorData), + datasets: [ + { + label: "Orchestrator", + data: Object.values(OrchestratorData).map(Number), + backgroundColor: "rgba(75, 192, 192, 0.6)", + }, + ], + }; + + const dataPie = { + labels: Object.keys(OrchestratorData), + datasets: [ + { + label: "Orchestrator", + data: Object.values(OrchestratorData).map(Number), + }, + ], + }; + + const dataLine = { + labels: Object.keys(OrchestratorData), + datasets: [ + { + label: "Orchestrator", + data: Object.values(OrchestratorData).map(Number), + backgroundColor: "rgba(75, 192, 192, 0.6)", + }, + ], + }; + + const handleChartChange = (value, label) => { + setSelectedChart(value); + setDropdownLabel(label); + }; + + let chartComponent; + if (selectedChart === "barchart") { + chartComponent = ; + } else if (selectedChart === "piechart") { + // chartComponent = ; + chartComponent = ; + } else if (selectedChart === "linechart") { + chartComponent = ; + } + + const fetchBotData = async () => { + store?.startLoading(); + const data = searchText.length > 0 ? { name: searchText } : {}; + try { + const res = await getBots(data); + store?.stopLoading(); + setBotList(res?.data?.result?.data.map((bot) => bot.name)); + } catch (err) { + store?.stopLoading(); + toast.error(err.message); + } + }; + + // const handleSearchInputChange = ( + // event: React.ChangeEvent + // ) => { + // const { value } = event.target; + // setSearchText(value); + + // const lowercasedValue = value.toLowerCase(); + // const suggestions: AutocompleteItem[] = botList.map((name) => ({ + // value: name, + // })); + + // setAutocompleteSuggestions( + // suggestions.filter((item) => + // item.value.toLowerCase().includes(lowercasedValue) + // ) + // ); + // }; + + // const handleSearchSubmit = (event: React.FormEvent) => { + // event.preventDefault(); + // }; + + const handleSearchSubmitFile = async ( + event: React.FormEvent + ) => { + event.preventDefault(); + setDropdown(false); + setFinal(selected); + + const shortDate = convertToShortDate(selected); + localStorage.setItem("shortDate", shortDate); + localStorage.setItem("data_time", selected); + + const file = reverseFormatDate(selected); + localStorage.setItem("file", file); + + func(); + }; + + const handleSearchInputChangeFile = async ( + event: React.ChangeEvent + ) => { + const { value } = event.target; + setSelected(value); + + const lowercasedValue = value.toLowerCase(); + const apiEndpoint = getFilesData(); + let data = []; + + try { + const response = await apiEndpoint; + data = response.data.result; + } catch (error) { + console.error("Error toggling:", error); + } + + const suggestions: AutocompleteItem[] = data.map((name) => ({ + value: formatDate(name), + })); + + setAutocompleteSuggestionsFile( + suggestions.filter((item) => + item.value.toLowerCase().includes(lowercasedValue) + ) + ); + setDropdown(true); + }; + + const handleAutocompleteItemClick = (value) => { + setSelected(value); + setDropdown(false); + }; + + return ( +
+ + + + + {dropdownLabel} + + + handleChartChange("barchart", "Bar Chart")} + style={{ cursor: "pointer" }} + > + Bar Chart + + handleChartChange("piechart", "Pie Chart")} + style={{ cursor: "pointer" }} + > + Pie Chart + + handleChartChange("linechart", "Line Chart")} + style={{ cursor: "pointer" }} + > + Line Chart + + + + + {/* +
+ + + Search + +
+ {autocompleteSuggestions.length > 0 && ( +
    + {autocompleteSuggestions.map((item) => ( +
  • setSearchText(item.value)}> + {item.value} +
  • + ))} +
+ )} +
*/} + +
+ + + Search + +
+ {dropdown && autocompleteSuggestionsFile.length > 0 && ( +
    + {autocompleteSuggestionsFile.map((item) => ( +
  • handleAutocompleteItemClick(item.value)} + > + {item.value} +
  • + ))} +
+ )} +
+
+ {chartComponent} +
+ ); +}; + +export default Orchestrator; diff --git a/src/pages/monitoring/orchestrator/style.css b/src/pages/monitoring/orchestrator/style.css new file mode 100644 index 0000000..7b4f6f8 --- /dev/null +++ b/src/pages/monitoring/orchestrator/style.css @@ -0,0 +1,26 @@ +/* Add a higher z-index to the autocomplete dropdown */ +.autocomplete-dropdown { + position: absolute; + z-index: 100; + background-color: #fff; + border: 1px solid #ccc; + padding: 5px; + list-style: none; + max-height: 150px; + max-width: inherit; + overflow-y: auto; +} + +.autocomplete-dropdown li { + cursor: pointer; + padding: 8px; +} + +.autocomplete-dropdown li:hover { + background-color: #f0f0f0; +} + +.dark-dropdown { + color: black ; +} + diff --git a/src/pages/monitoring/outbound/index.tsx b/src/pages/monitoring/outbound/index.tsx new file mode 100644 index 0000000..8539d9f --- /dev/null +++ b/src/pages/monitoring/outbound/index.tsx @@ -0,0 +1,316 @@ +import { + MDBBtn, + MDBCol, + MDBDropdown, + MDBDropdownItem, + MDBDropdownMenu, + MDBDropdownToggle, + MDBRow, +} from "mdb-react-ui-kit"; +import BarChart from "../../../components/visualisation/bar"; +import React, { useEffect, useState } from "react"; +import { useStore } from "../../../store"; +import { getBots } from "../../../api/getBots"; +import { toast } from "react-hot-toast"; +import "./style.css"; +import PieChart from "../../../components/visualisation/pie"; +import LineChart from "../../../components/visualisation/line"; +import { fetchRealtime } from "../../../api/fetchRealtimeData"; +import { getFilesData } from "../../../api/getFiles"; +import { convertToShortDate, formatDate, reverseFormatDate } from "../../../utils/functions"; + +interface AutocompleteItem { + value: string; +} + +interface OutboundProps extends React.HTMLAttributes { + theme: string; +} + +export const Outbound: React.FC = ({ theme }) => { + const [selectedChart, setSelectedChart] = useState("barchart"); + const [dropdownLabel, setDropdownLabel] = useState("Select Chart"); + const [searchText, setSearchText] = useState(""); + // const [autocompleteSuggestions, setAutocompleteSuggestions] = useState< + // AutocompleteItem[] + // >([]); + const [autocompleteSuggestionsFile, setAutocompleteSuggestionsFile] = + useState([]); + const [botList, setBotList] = useState([]); + const store: any = useStore(); + + const [selected, setSelected] = useState(""); + const [dropdown, setDropdown] = useState(true); + + const [OutboundData, setOutboundData] = useState([]); + + const [final, setFinal] = useState(""); + + const func = async () => { + if (localStorage.getItem("file")) { + const file = localStorage.getItem("file"); + const apiEndpoint = fetchRealtime(file); + try { + const response = await apiEndpoint; + const res = JSON.parse(response.data.result); + setOutboundData(res["Outbound".trim()] || {}); + } catch (error) { + console.error("Error toggling:", error); + } + } else if (final !== "") { + const file = reverseFormatDate(final); + localStorage.setItem("file", file); + + const shortDate = convertToShortDate(selected); + localStorage.setItem("shortDate", shortDate); + localStorage.setItem("data_time", selected); + + const apiEndpoint = fetchRealtime(file); + try { + const response = await apiEndpoint; + const res = JSON.parse(response.data.result); + setOutboundData(res["Outbound".trim()] || {}); + } catch (error) { + console.error("Error toggling:", error); + } + } + fetchBotData(); + }; + + useEffect(() => { + func(); + // fetchBotData(); + }, [final]); + + const dataBar = { + labels: Object.keys(OutboundData), + datasets: [ + { + label: "Outbound", + data: Object.values(OutboundData).map(Number), + backgroundColor: "rgba(75, 192, 192, 0.6)", + }, + ], + }; + + const dataPie = { + labels: Object.keys(OutboundData), + datasets: [ + { + label: "Outbound", + data: Object.values(OutboundData).map(Number), + }, + ], + }; + + const dataLine = { + labels: Object.keys(OutboundData), + datasets: [ + { + label: "Outbound", + data: Object.values(OutboundData).map(Number), + backgroundColor: "rgba(75, 192, 192, 0.6)", + }, + ], + }; + + const handleChartChange = (value, label) => { + setSelectedChart(value); + setDropdownLabel(label); + }; + + let chartComponent; + if (selectedChart === "barchart") { + chartComponent = ; + } else if (selectedChart === "piechart") { + // chartComponent = ; + chartComponent = ; + } else if (selectedChart === "linechart") { + chartComponent = ; + } + + const fetchBotData = async () => { + store?.startLoading(); + const data = searchText.length > 0 ? { name: searchText } : {}; + try { + const res = await getBots(data); + store?.stopLoading(); + setBotList(res?.data?.result?.data.map((bot) => bot.name)); + } catch (err) { + store?.stopLoading(); + toast.error(err.message); + } + }; + + // const handleSearchInputChange = ( + // event: React.ChangeEvent + // ) => { + // const { value } = event.target; + // setSearchText(value); + + // const lowercasedValue = value.toLowerCase(); + // const suggestions: AutocompleteItem[] = botList.map((name) => ({ + // value: name, + // })); + + // setAutocompleteSuggestions( + // suggestions.filter((item) => + // item.value.toLowerCase().includes(lowercasedValue) + // ) + // ); + // }; + + // const handleSearchSubmit = (event: React.FormEvent) => { + // event.preventDefault(); + // }; + const handleSearchSubmitFile = async ( + event: React.FormEvent + ) => { + event.preventDefault(); + setFinal(selected); + + const shortDate = convertToShortDate(selected); + localStorage.setItem("shortDate", shortDate); + localStorage.setItem("data_time", selected); + + const file = reverseFormatDate(selected); + localStorage.setItem("file", file); + + func(); + }; + + const handleSearchInputChangeFile = async ( + event: React.ChangeEvent + ) => { + const { value } = event.target; + setSelected(value); + + const lowercasedValue = value.toLowerCase(); + const apiEndpoint = getFilesData(); + let data = []; + + try { + const response = await apiEndpoint; + data = response.data.result; + } catch (error) { + console.error("Error toggling:", error); + } + + const suggestions: AutocompleteItem[] = data.map((name) => ({ + value: formatDate(name), + })); + + setAutocompleteSuggestionsFile( + suggestions.filter((item) => + item.value.toLowerCase().includes(lowercasedValue) + ) + ); + setDropdown(true); + }; + + const handleAutocompleteItemClick = (value) => { + setSelected(value); + setDropdown(false); + }; + + return ( +
+ + + + + {dropdownLabel} + + + handleChartChange("barchart", "Bar Chart")} + style={{ cursor: "pointer" }} + > + Bar Chart + + handleChartChange("piechart", "Pie Chart")} + style={{ cursor: "pointer" }} + > + Pie Chart + + handleChartChange("linechart", "Line Chart")} + style={{ cursor: "pointer" }} + > + Line Chart + + + + + {/* +
+ + + Search + +
+ {autocompleteSuggestions.length > 0 && ( +
    + {autocompleteSuggestions.map((item) => ( +
  • setSearchText(item.value)}> + {item.value} +
  • + ))} +
+ )} +
*/} + +
+ + + Search + +
+ {dropdown && autocompleteSuggestionsFile.length > 0 && ( +
    + {autocompleteSuggestionsFile.map((item) => ( +
  • handleAutocompleteItemClick(item.value)} + > + {item.value} +
  • + ))} +
+ )} +
+
+ {chartComponent} +
+ ); +}; + +export default Outbound; diff --git a/src/pages/monitoring/outbound/style.css b/src/pages/monitoring/outbound/style.css new file mode 100644 index 0000000..dc6b6c1 --- /dev/null +++ b/src/pages/monitoring/outbound/style.css @@ -0,0 +1,25 @@ +/* Add a higher z-index to the autocomplete dropdown */ +.autocomplete-dropdown { + position: absolute; + z-index: 100; + background-color: #fff; + border: 1px solid #ccc; + padding: 5px; + list-style: none; + max-height: 150px; + max-width: inherit; + overflow-y: auto; +} + +.autocomplete-dropdown li { + cursor: pointer; + padding: 8px; +} + +.autocomplete-dropdown li:hover { + background-color: #f0f0f0; +} + +.dark-dropdown { + color: black ; +} \ No newline at end of file diff --git a/src/pages/monitoring/overview/card.tsx b/src/pages/monitoring/overview/card.tsx new file mode 100644 index 0000000..954e857 --- /dev/null +++ b/src/pages/monitoring/overview/card.tsx @@ -0,0 +1,40 @@ +import React from "react"; +import { + MDBCard, + MDBCardBody, + MDBCol, + MDBRow, +} from "mdb-react-ui-kit"; +import { formatNumberWithCommas } from "../../../utils/functions"; + +const OverviewComponent = ({ theme, jsonData }) => { + const data = jsonData; + + const renderDataCards = (data: { [key: string]: number }) => { + return Object.entries(data).map(([key, value]) => ( + + + +
{formatNumberWithCommas(value)}
+

{key}

+
+
+
+ )); + }; + + return ( +
+ + {Object.entries(data).map(([category, categoryData]) => ( + + {categoryData && + renderDataCards(categoryData as { [key: string]: number })} + + ))} + +
+ ); +}; + +export default OverviewComponent; diff --git a/src/pages/monitoring/overview/index.tsx b/src/pages/monitoring/overview/index.tsx index 8496b6b..762b0fb 100644 --- a/src/pages/monitoring/overview/index.tsx +++ b/src/pages/monitoring/overview/index.tsx @@ -1,103 +1,217 @@ -import { MDBCard, MDBCardBody, MDBCol, MDBRow, MDBBtn } from "mdb-react-ui-kit"; +import { + MDBCard, + MDBCardBody, + MDBCol, + MDBRow, + MDBBtn, + MDBSwitch, +} from "mdb-react-ui-kit"; import "./style.css"; +import { useEffect, useState } from "react"; +import { triggerRealtimeDataRes } from "../../../api/triggerRealtime"; +import { stopRealtime } from "../../../api/stopRealtimeData"; +import { getFilesData } from "../../../api/getFiles"; +import { fetchOverviewData } from "../../../api/fetchOverview"; +import { + convertToShortDate, + formatDate, + reverseFormatDate, +} from "../../../utils/functions"; +import OverviewComponent from "./card"; interface OverviewHeaderProps extends React.HTMLAttributes { - children?: React.ReactNode; theme: string; } -export const Overview: React.FC = ({ - children, - theme, - ...rest -}) => { - const handleFilterInputChange = ( + +interface AutocompleteItem { + value: string; +} + +export const Overview: React.FC = ({ theme }) => { + const [isRealtimeEnabled, setIsRealtimeEnabled] = useState(false); + const [autocompleteSuggestions, setAutocompleteSuggestions] = useState< + AutocompleteItem[] + >([]); + const [selected, setSelected] = useState(""); + const [dropdown, setDropdown] = useState(true); + const [flag, setFlag] = useState(false); + const [OverviewData, setOverviewData] = useState({}); + + const handleSearchInputChange = async ( event: React.ChangeEvent ) => { const { value } = event.target; + setSelected(value); + setFlag(false); + + const lowercasedValue = value.toLowerCase(); + const apiEndpoint = getFilesData(); + let data = []; + + try { + const response = await apiEndpoint; + data = response.data.result; + } catch (error) { + console.error("Error toggling:", error); + } + + const suggestions: AutocompleteItem[] = data.map((name) => ({ + value: formatDate(name), + })); + + setAutocompleteSuggestions( + suggestions.filter((item) => + item.value.toLowerCase().includes(lowercasedValue) + ) + ); + setDropdown(true); }; - const handleFilterSubmit = (event: React.FormEvent) => { + function isEmpty(value) { + if (Array.isArray(value)) { + return value.length === 0; + } else if (typeof value === "object") { + return isObjectEmpty(value); + } else { + return !value; + } + } + function isObjectEmpty(obj) { + for (const key in obj) { + if (Object.prototype.hasOwnProperty.call(obj, key)) { + if (typeof obj[key] === "object" && !isObjectEmpty(obj[key])) { + return false; + } + if (typeof obj[key] !== "object" || !isEmpty(obj[key])) { + return false; + } + } + } + return true; + } + const handleSearchSubmit = async ( + event: React.FormEvent + ) => { event.preventDefault(); + setDropdown(false); + setFlag(true); + const shortDate = convertToShortDate(selected); + localStorage.setItem("shortDate", shortDate); + localStorage.setItem("data_time", selected); + + const file = reverseFormatDate(selected); + localStorage.setItem("file", file); + + const f="56_22_20_12_08_2023"; + + // const apiEndpoint = fetchOverviewData(file); + const apiEndpoint = fetchOverviewData(f); + let res; + + try { + const response = await apiEndpoint; + res = response.data.result; + + const parsedData = JSON.parse(res); + + setOverviewData(parsedData); + } catch (error) { + console.error("Error toggling:", error); + } + setDropdown(false); }; + const handleAutocompleteItemClick = (value) => { + setSelected(value); + setDropdown(false); + }; + + const handleToggleChange = async () => { + setIsRealtimeEnabled(!isRealtimeEnabled); + const apiEndpoint = isRealtimeEnabled + ? triggerRealtimeDataRes() + : stopRealtime(); + + try { + const response = await apiEndpoint; + console.log("Toggle API Response:", response); + } catch (error) { + console.error("Error toggling:", error); + } + }; + + async function fetchData() { + if (localStorage.getItem("file")) { + const file = localStorage.getItem("file"); + const apiEndpoint = fetchOverviewData(file); + let res; + const response = await apiEndpoint; + res = response.data.result; + + const parsedData = JSON.parse(res); + + setOverviewData(parsedData); + } + } + + useEffect(() => { + fetchData(); + console.log(!selected || localStorage.getItem("file") == null); + }, []); + return (
-
- - - Filter - -
-
-
- - - - -
80
-

No. of Notifications sent

-
-
-
- - - -
65
-

- No. of Notifications received by users -

-
-
-
- - - -
50
-

No. of Notifications opened by users

-
-
-
-
- - - - -
80
-

No. of Notifications sent

-
-
-
- - - -
65
-

- No. of Notifications received by users -

-
-
+ +
+ + + Submit + +
+ {dropdown && autocompleteSuggestions.length > 0 && ( +
    + {autocompleteSuggestions.map((item) => ( +
  • handleAutocompleteItemClick(item.value)} + className={`${theme}-dropdown`} + > + {item.value} +
  • + ))} +
+ )} +
- - - -
50
-

No. of Notifications opened by users

-
-
+ + Toggle Realtime   +
+ {(selected || localStorage.getItem("file") != null || flag) && + isObjectEmpty(OverviewData) &&

No data available

} + {(selected || localStorage.getItem("file") != null) && ( + + )} + {!selected && localStorage.getItem("file") == null && ( +

Please enter a date

+ )}
); }; diff --git a/src/pages/monitoring/overview/style.css b/src/pages/monitoring/overview/style.css index 9d5f368..d269be9 100644 --- a/src/pages/monitoring/overview/style.css +++ b/src/pages/monitoring/overview/style.css @@ -12,3 +12,7 @@ background-color: black; color: black; } + +.dark-dropdown { + color: black ; +} \ No newline at end of file diff --git a/src/pages/monitoring/transformer/index.tsx b/src/pages/monitoring/transformer/index.tsx new file mode 100644 index 0000000..c5e6123 --- /dev/null +++ b/src/pages/monitoring/transformer/index.tsx @@ -0,0 +1,317 @@ +import { + MDBBtn, + MDBCol, + MDBDropdown, + MDBDropdownItem, + MDBDropdownMenu, + MDBDropdownToggle, + MDBRow, +} from "mdb-react-ui-kit"; +import BarChart from "../../../components/visualisation/bar"; +import React, { useEffect, useState } from "react"; +import { useStore } from "../../../store"; +import { getBots } from "../../../api/getBots"; +import { toast } from "react-hot-toast"; +import "./style.css"; +import PieChart from "../../../components/visualisation/pie"; +import LineChart from "../../../components/visualisation/line"; +// import { formatDate, reverseFormatDate } from "../../../utils/functions"; +import { fetchRealtime } from "../../../api/fetchRealtimeData"; +import { getFilesData } from "../../../api/getFiles"; +import { convertToShortDate, formatDate, reverseFormatDate } from "../../../utils/functions"; + +interface AutocompleteItem { + value: string; +} + +interface TransformerProps extends React.HTMLAttributes { + theme: string; +} + +export const Transformer: React.FC = ({ theme }) => { + const [selectedChart, setSelectedChart] = useState("barchart"); + const [dropdownLabel, setDropdownLabel] = useState("Select Chart"); + const [searchText, setSearchText] = useState(""); + // const [autocompleteSuggestions, setAutocompleteSuggestions] = useState< + // AutocompleteItem[] + // >([]); + const [autocompleteSuggestionsFile, setAutocompleteSuggestionsFile] = + useState([]); + const [botList, setBotList] = useState([]); + const store: any = useStore(); + + const [selected, setSelected] = useState(""); + const [dropdown, setDropdown] = useState(true); + + const [TransformerData, setTransformerData] = useState([]); + + const [final, setFinal] = useState(""); + + const func = async () => { + if (localStorage.getItem("file")) { + const file = localStorage.getItem("file"); + const apiEndpoint = fetchRealtime(file); + try { + const response = await apiEndpoint; + const res = JSON.parse(response.data.result); + setTransformerData(res["Transformer".trim()] || {}); + } catch (error) { + console.error("Error toggling:", error); + } + } else if (final !== "") { + const file = reverseFormatDate(final); + localStorage.setItem("file", file); + + const shortDate = convertToShortDate(selected); + localStorage.setItem("shortDate", shortDate); + localStorage.setItem("data_time", selected); + + const apiEndpoint = fetchRealtime(file); + try { + const response = await apiEndpoint; + const res = JSON.parse(response.data.result); + setTransformerData(res["Transformer".trim()] || {}); + } catch (error) { + console.error("Error toggling:", error); + } + } + fetchBotData(); + }; + + useEffect(() => { + func(); + // fetchBotData(); + }, [final]); + + const dataBar = { + labels: Object.keys(TransformerData), + datasets: [ + { + label: "Transformer", + data: Object.values(TransformerData).map(Number), + backgroundColor: "rgba(75, 192, 192, 0.6)", + }, + ], + }; + + const dataPie = { + labels: Object.keys(TransformerData), + datasets: [ + { + label: "Transformer", + data: Object.values(TransformerData).map(Number), + }, + ], + }; + + const dataLine = { + labels: Object.keys(TransformerData), + datasets: [ + { + label: "Transformer", + data: Object.values(TransformerData).map(Number), + backgroundColor: "rgba(75, 192, 192, 0.6)", + }, + ], + }; + + const handleChartChange = (value, label) => { + setSelectedChart(value); + setDropdownLabel(label); + }; + + let chartComponent; + if (selectedChart === "barchart") { + chartComponent = ; + } else if (selectedChart === "piechart") { + // chartComponent = ; + chartComponent = ; + } else if (selectedChart === "linechart") { + chartComponent = ; + } + + const fetchBotData = async () => { + store?.startLoading(); + const data = searchText.length > 0 ? { name: searchText } : {}; + try { + const res = await getBots(data); + store?.stopLoading(); + setBotList(res?.data?.result?.data.map((bot) => bot.name)); + } catch (err) { + store?.stopLoading(); + toast.error(err.message); + } + }; + + // const handleSearchInputChange = ( + // event: React.ChangeEvent + // ) => { + // const { value } = event.target; + // setSearchText(value); + + // const lowercasedValue = value.toLowerCase(); + // const suggestions: AutocompleteItem[] = botList.map((name) => ({ + // value: name, + // })); + + // setAutocompleteSuggestions( + // suggestions.filter((item) => + // item.value.toLowerCase().includes(lowercasedValue) + // ) + // ); + // }; + + // const handleSearchSubmit = (event: React.FormEvent) => { + // event.preventDefault(); + // }; + + const handleSearchSubmitFile = async ( + event: React.FormEvent + ) => { + event.preventDefault(); + setFinal(selected); + + const shortDate = convertToShortDate(selected); + localStorage.setItem("shortDate", shortDate); + localStorage.setItem("data_time", selected); + + const file = reverseFormatDate(selected); + localStorage.setItem("file", file); + + func(); + }; + + const handleSearchInputChangeFile = async ( + event: React.ChangeEvent + ) => { + const { value } = event.target; + setSelected(value); + + const lowercasedValue = value.toLowerCase(); + const apiEndpoint = getFilesData(); + let data = []; + + try { + const response = await apiEndpoint; + data = response.data.result; + } catch (error) { + console.error("Error toggling:", error); + } + + const suggestions: AutocompleteItem[] = data.map((name) => ({ + value: formatDate(name), + })); + + setAutocompleteSuggestionsFile( + suggestions.filter((item) => + item.value.toLowerCase().includes(lowercasedValue) + ) + ); + setDropdown(true); + }; + + const handleAutocompleteItemClick = (value) => { + setSelected(value); + setDropdown(false); + }; + return ( +
+ + + + + {dropdownLabel} + + + handleChartChange("barchart", "Bar Chart")} + style={{ cursor: "pointer" }} + > + Bar Chart + + handleChartChange("piechart", "Pie Chart")} + style={{ cursor: "pointer" }} + > + Pie Chart + + handleChartChange("linechart", "Line Chart")} + style={{ cursor: "pointer" }} + > + Line Chart + + + + + {/* +
+ + + Search + +
+ {autocompleteSuggestions.length > 0 && ( +
    + {autocompleteSuggestions.map((item) => ( +
  • setSearchText(item.value)}> + {item.value} +
  • + ))} +
+ )} +
*/} + +
+ + + Search + +
+ {dropdown && autocompleteSuggestionsFile.length > 0 && ( +
    + {autocompleteSuggestionsFile.map((item) => ( +
  • handleAutocompleteItemClick(item.value)} + > + {item.value} +
  • + ))} +
+ )} +
+
+ {chartComponent} +
+ ); +}; + +export default Transformer; diff --git a/src/pages/monitoring/transformer/style.css b/src/pages/monitoring/transformer/style.css new file mode 100644 index 0000000..5859a92 --- /dev/null +++ b/src/pages/monitoring/transformer/style.css @@ -0,0 +1,25 @@ +/* Add a higher z-index to the autocomplete dropdown */ +.autocomplete-dropdown { + position: absolute; + z-index: 100; + background-color: #fff; + border: 1px solid #ccc; + padding: 5px; + list-style: none; + max-height: 150px; + max-width: inherit; + overflow-y: auto; + } + + .autocomplete-dropdown li { + cursor: pointer; + padding: 8px; + } + + .autocomplete-dropdown li:hover { + background-color: #f0f0f0; + } + + .dark-dropdown { + color: black ; + } \ No newline at end of file diff --git a/src/pages/monitoring/uci-api/index.tsx b/src/pages/monitoring/uci-api/index.tsx new file mode 100644 index 0000000..2be600e --- /dev/null +++ b/src/pages/monitoring/uci-api/index.tsx @@ -0,0 +1,327 @@ +import { + MDBBtn, + MDBCol, + MDBDropdown, + MDBDropdownItem, + MDBDropdownMenu, + MDBDropdownToggle, + MDBRow, +} from "mdb-react-ui-kit"; +import BarChart from "../../../components/visualisation/bar"; +import React, { useEffect, useState } from "react"; +import { useStore } from "../../../store"; +import { getBots } from "../../../api/getBots"; +import { toast } from "react-hot-toast"; +import "./style.css"; +import PieChart from "../../../components/visualisation/pie"; +import LineChart from "../../../components/visualisation/line"; +// import { formatDate, reverseFormatDate } from "../../../utils/functions"; +import { fetchRealtime } from "../../../api/fetchRealtimeData"; +import { getFilesData } from "../../../api/getFiles"; +import { + convertToShortDate, + formatDate, + reverseFormatDate, +} from "../../../utils/functions"; + +interface AutocompleteItem { + value: string; +} + +interface UCIAPIProps extends React.HTMLAttributes { + theme: string; +} + +export const UCIAPI: React.FC = ({ theme }) => { + const [selectedChart, setSelectedChart] = useState("barchart"); + const [dropdownLabel, setDropdownLabel] = useState("Select Chart"); + const [searchText, setSearchText] = useState(""); + // const [autocompleteSuggestions, setAutocompleteSuggestions] = useState< + // AutocompleteItem[] + // >([]); + const [autocompleteSuggestionsFile, setAutocompleteSuggestionsFile] = + useState([]); + const [botList, setBotList] = useState([]); + const store: any = useStore(); + + const [selected, setSelected] = useState(""); + const [dropdown, setDropdown] = useState(true); + + const [uciApiData, setUciApiData] = useState([]); + + const [final, setFinal] = useState(""); + + const func = async () => { + if (localStorage.getItem("file")) { + const file = localStorage.getItem("file"); + const apiEndpoint = fetchRealtime(file); + try { + const response = await apiEndpoint; + const res = JSON.parse(response.data.result); + setUciApiData(res["uci-apis".trim()] || {}); + } catch (error) { + console.error("Error toggling:", error); + } + } else if (final !== "") { + const file = reverseFormatDate(final); + localStorage.setItem("file", file); + + const shortDate = convertToShortDate(selected); + localStorage.setItem("shortDate", shortDate); + localStorage.setItem("data_time", selected); + + const apiEndpoint = fetchRealtime(file); + try { + const response = await apiEndpoint; + const res = JSON.parse(response.data.result); + setUciApiData(res["uci-apis".trim()] || {}); + } catch (error) { + console.error("Error toggling:", error); + } + } + fetchBotData(); + }; + + useEffect(() => { + func(); + // fetchBotData(); + }, [final]); + + const dataBar = { + labels: Object.keys(uciApiData), + datasets: [ + { + label: "UCI APIS", + data: Object.values(uciApiData).map(Number), + backgroundColor: "rgba(75, 192, 192, 0.6)", + }, + ], + }; + + const dataPie = { + labels: Object.keys(uciApiData), + datasets: [ + { + label: "UCI APIS", + data: Object.values(uciApiData).map(Number), + }, + ], + }; + + const dataLine = { + labels: Object.keys(uciApiData), + datasets: [ + { + label: "UCI APIS", + data: Object.values(uciApiData).map(Number), + backgroundColor: "rgba(75, 192, 192, 0.6)", + }, + ], + }; + + const handleChartChange = (value, label) => { + setSelectedChart(value); + setDropdownLabel(label); + }; + + let chartComponent; + if (selectedChart === "barchart") { + chartComponent = ; + } else if (selectedChart === "piechart") { + // chartComponent = ; + chartComponent = ; + } else if (selectedChart === "linechart") { + chartComponent = ; + } + + const fetchBotData = async () => { + store?.startLoading(); + const data = searchText.length > 0 ? { name: searchText } : {}; + try { + const res = await getBots(data); + store?.stopLoading(); + setBotList(res?.data?.result?.data.map((bot) => bot.name)); + } catch (err) { + store?.stopLoading(); + toast.error(err.message); + } + }; + + // const handleSearchInputChange = ( + // event: React.ChangeEvent + // ) => { + // const { value } = event.target; + // setSearchText(value); + + // const lowercasedValue = value.toLowerCase(); + // const suggestions: AutocompleteItem[] = botList.map((name) => ({ + // value: name, + // })); + + // setAutocompleteSuggestions( + // suggestions.filter((item) => + // item.value.toLowerCase().includes(lowercasedValue) + // ) + // ); + // }; + + // const handleSearchSubmit = (event: React.FormEvent) => { + // event.preventDefault(); + // }; + + const handleSearchSubmitFile = async ( + event: React.FormEvent + ) => { + event.preventDefault(); + + const shortDate = convertToShortDate(selected); + localStorage.setItem("shortDate", shortDate); + localStorage.setItem("data_time", selected); + + const file = reverseFormatDate(selected); + localStorage.setItem("file", file); + + func(); + setDropdown(false); + }; + + const handleSearchInputChangeFile = async ( + event: React.ChangeEvent + ) => { + const { value } = event.target; + setSelected(value); + setFinal(selected); + + const lowercasedValue = value.toLowerCase(); + const apiEndpoint = getFilesData(); + let data = []; + + try { + const response = await apiEndpoint; + data = response.data.result; + } catch (error) { + console.error("Error toggling:", error); + } + + const suggestions: AutocompleteItem[] = data.map((name) => ({ + value: formatDate(name), + })); + + setAutocompleteSuggestionsFile( + suggestions.filter((item) => + item.value.toLowerCase().includes(lowercasedValue) + ) + ); + setDropdown(true); + }; + + const handleAutocompleteItemClick = (value) => { + setSelected(value); + setDropdown(false); + }; + + return ( +
+ + + + + {dropdownLabel} + + + handleChartChange("barchart", "Bar Chart")} + style={{ cursor: "pointer" }} + > + Bar Chart + + handleChartChange("piechart", "Pie Chart")} + style={{ cursor: "pointer" }} + > + Pie Chart + + handleChartChange("linechart", "Line Chart")} + style={{ cursor: "pointer" }} + > + Line Chart + + + + + {/* +
+ + + Search + +
+ {autocompleteSuggestions.length > 0 && ( +
    + {autocompleteSuggestions.map((item) => ( +
  • setSearchText(item.value)}> + {item.value} +
  • + ))} +
+ )} +
*/} + +
+ + + Search + +
+ {dropdown && autocompleteSuggestionsFile.length > 0 && ( +
    + {autocompleteSuggestionsFile.map((item) => ( +
  • handleAutocompleteItemClick(item.value)} + > + {item.value} +
  • + ))} +
+ )} +
+
+ {chartComponent} +
+ ); +}; + +export default UCIAPI; diff --git a/src/pages/monitoring/uci-api/style.css b/src/pages/monitoring/uci-api/style.css new file mode 100644 index 0000000..2af15c3 --- /dev/null +++ b/src/pages/monitoring/uci-api/style.css @@ -0,0 +1,25 @@ +/* Add a higher z-index to the autocomplete dropdown */ +.autocomplete-dropdown { + position: absolute; + z-index: 100; + background-color: #fff; + border: 1px solid #ccc; + padding: 5px; + list-style: none; + max-height: 150px; + max-width: inherit; + overflow-y: auto; +} + +.autocomplete-dropdown li { + cursor: pointer; + padding: 8px; +} + +.autocomplete-dropdown li:hover { + background-color: #f0f0f0; +} + +.dark-dropdown { + color: black !important; +} \ No newline at end of file From b81b0861fcab2272af414b3300313cda4f969949 Mon Sep 17 00:00:00 2001 From: psankhe28 Date: Tue, 5 Sep 2023 19:38:23 +0530 Subject: [PATCH 12/13] Fixed the naming convention of a state and added the missing apis --- src/api/downloadErrLog.ts | 17 ++++++++++ src/api/downloadLog.ts | 17 ++++++++++ src/api/fetchOverview.ts | 16 +++++++++ src/api/fetchRealtimeData.ts | 16 +++++++++ src/api/fetchService.ts | 18 ++++++++++ src/api/getFiles.ts | 12 +++++++ src/api/stopRealtimeData.ts | 13 ++++++++ src/api/triggerRealtime.ts | 12 +++++++ src/api/urls.ts | 16 +++++++++ src/pages/login/index.css | 0 .../broadcast-transformer/index.tsx | 10 +++--- src/pages/monitoring/dummy.json | 33 ------------------- src/pages/monitoring/inbound/index.tsx | 14 +++----- src/pages/monitoring/kafka/index.tsx | 21 ------------ src/pages/monitoring/orchestrator/index.tsx | 10 +++--- src/pages/monitoring/outbound/index.tsx | 10 +++--- src/pages/monitoring/transformer/index.tsx | 10 +++--- src/pages/monitoring/uci-api/index.tsx | 10 +++--- 18 files changed, 167 insertions(+), 88 deletions(-) create mode 100644 src/api/downloadErrLog.ts create mode 100644 src/api/downloadLog.ts create mode 100644 src/api/fetchOverview.ts create mode 100644 src/api/fetchRealtimeData.ts create mode 100644 src/api/fetchService.ts create mode 100644 src/api/getFiles.ts create mode 100644 src/api/stopRealtimeData.ts create mode 100644 src/api/triggerRealtime.ts delete mode 100644 src/pages/login/index.css delete mode 100644 src/pages/monitoring/dummy.json delete mode 100644 src/pages/monitoring/kafka/index.tsx diff --git a/src/api/downloadErrLog.ts b/src/api/downloadErrLog.ts new file mode 100644 index 0000000..a5edc06 --- /dev/null +++ b/src/api/downloadErrLog.ts @@ -0,0 +1,17 @@ +import axios from "axios"; +import { downloadErrLog } from "./urls"; +import { getDefaultHeaders } from "./utils"; + +export const downloadErrLogData = ( + service_name: string, + date:string +) => { + const url = downloadErrLog(service_name,date); + const config = { + headers: { + ...getDefaultHeaders() + }, + }; + + return axios.get(url, config); +}; diff --git a/src/api/downloadLog.ts b/src/api/downloadLog.ts new file mode 100644 index 0000000..0e23401 --- /dev/null +++ b/src/api/downloadLog.ts @@ -0,0 +1,17 @@ +import axios from "axios"; +import { downloadLog } from "./urls"; +import { getDefaultHeaders } from "./utils"; + +export const downloadLogData = ( + service_name: string, + date:string +) => { + const url = downloadLog(service_name,date); + const config = { + headers: { + ...getDefaultHeaders() + }, + }; + + return axios.get(url, config); +}; diff --git a/src/api/fetchOverview.ts b/src/api/fetchOverview.ts new file mode 100644 index 0000000..7b36a05 --- /dev/null +++ b/src/api/fetchOverview.ts @@ -0,0 +1,16 @@ +import axios from "axios"; +import { fetchOverview } from "./urls"; +import { getDefaultHeaders } from "./utils"; + +export const fetchOverviewData = ( + file: string +) => { + const url = fetchOverview(file); + const config = { + headers: { + ...getDefaultHeaders() + }, + }; + + return axios.get(url, config); +}; diff --git a/src/api/fetchRealtimeData.ts b/src/api/fetchRealtimeData.ts new file mode 100644 index 0000000..1b40e90 --- /dev/null +++ b/src/api/fetchRealtimeData.ts @@ -0,0 +1,16 @@ +import axios from "axios"; +import { fetchRealtimeData } from "./urls"; +import { getDefaultHeaders } from "./utils"; + +export const fetchRealtime = ( + file: string +) => { + const url = fetchRealtimeData(file); + const config = { + headers: { + ...getDefaultHeaders() + }, + }; + + return axios.get(url, config); +}; diff --git a/src/api/fetchService.ts b/src/api/fetchService.ts new file mode 100644 index 0000000..08b025e --- /dev/null +++ b/src/api/fetchService.ts @@ -0,0 +1,18 @@ +import axios from "axios"; +import { fetchService } from "./urls"; +import { getDefaultHeaders } from "./utils"; + +export const fetchServiceData = ( + service_name: string, + lines: number, + date: string +) => { + const url = fetchService(service_name, lines, date); + const config = { + headers: { + ...getDefaultHeaders() + }, + }; + + return axios.get(url, config); +}; diff --git a/src/api/getFiles.ts b/src/api/getFiles.ts new file mode 100644 index 0000000..3c6dcff --- /dev/null +++ b/src/api/getFiles.ts @@ -0,0 +1,12 @@ +import axios from "axios"; +import { getFiles } from "./urls"; +import { getDefaultHeaders } from "./utils"; + +export const getFilesData = () => { + const config = { + headers: { + ...getDefaultHeaders(), + }, + }; + return axios.get(getFiles, config); +}; diff --git a/src/api/stopRealtimeData.ts b/src/api/stopRealtimeData.ts new file mode 100644 index 0000000..a90972d --- /dev/null +++ b/src/api/stopRealtimeData.ts @@ -0,0 +1,13 @@ +import axios from "axios"; +import { stopRealtimeData } from "./urls"; +import { getDefaultHeaders } from "./utils"; + +export const stopRealtime = () => { + const config = { + headers: { + ...getDefaultHeaders(), + }, + }; + + return axios.post(stopRealtimeData,'', config); +}; diff --git a/src/api/triggerRealtime.ts b/src/api/triggerRealtime.ts new file mode 100644 index 0000000..00f8e82 --- /dev/null +++ b/src/api/triggerRealtime.ts @@ -0,0 +1,12 @@ +import axios from "axios"; +import { triggerRealtimeData } from "./urls"; +import { getDefaultHeaders } from "./utils"; + +export const triggerRealtimeDataRes = () => { + const config = { + headers: { + ...getDefaultHeaders(), + }, + }; + return axios.post(triggerRealtimeData, "", config); +}; diff --git a/src/api/urls.ts b/src/api/urls.ts index dd0125d..051a98c 100644 --- a/src/api/urls.ts +++ b/src/api/urls.ts @@ -20,4 +20,20 @@ export const addLogicUrl = `${process.env.REACT_APP_UCI_BASE_URL}/admin/conversa export const getBotByIdUrl =(id:string)=> `${process.env.REACT_APP_UCI_BASE_URL}/admin/bot/${id}`; +export const fetchService =(service_name:string,lines:number,date:string)=> `${process.env.REACT_APP_UCI_BASE_URL}/admin/monitoring/logs/${service_name}?lines=${lines}&date=${date}`; + +export const triggerRealtimeData =`${process.env.REACT_APP_UCI_BASE_URL}/admin/monitoring/realtime/start`; + +export const fetchRealtimeData =(file:string)=>`${process.env.REACT_APP_UCI_BASE_URL}/admin/monitoring/realtime?date=${file}`; + +export const stopRealtimeData =`${process.env.REACT_APP_UCI_BASE_URL}/admin/monitoring/realtime/stop`; + +export const getFiles =`${process.env.REACT_APP_UCI_BASE_URL}/admin/monitoring/realtime/available`; + +export const fetchOverview =(file:string)=>`${process.env.REACT_APP_UCI_BASE_URL}/admin/monitoring/overview?date=${file}`; + +export const downloadLog =(service_name:string,date:string)=>`${process.env.REACT_APP_UCI_BASE_URL}/admin/monitoring/logs/${service_name}/download/log?date=${date}`; + +export const downloadErrLog =(service_name:string,date:string)=>`${process.env.REACT_APP_UCI_BASE_URL}/admin/monitoring/logs/${service_name}/download/error?date=${date}`; + export const getSegmentCountUrl = (segment:string | number) => `${process.env.REACT_APP_nl_url}/segments/${segment}/mentors/count` \ No newline at end of file diff --git a/src/pages/login/index.css b/src/pages/login/index.css deleted file mode 100644 index e69de29..0000000 diff --git a/src/pages/monitoring/broadcast-transformer/index.tsx b/src/pages/monitoring/broadcast-transformer/index.tsx index c8d83f4..6e04a46 100644 --- a/src/pages/monitoring/broadcast-transformer/index.tsx +++ b/src/pages/monitoring/broadcast-transformer/index.tsx @@ -45,7 +45,7 @@ export const BroadcastTransformer: React.FC = ({ them const [BroadcastTransformerData, setBroadcastTransformerData] = useState([]); - const [final, setFinal] = useState(""); + const [FileName, setFileName] = useState(""); const func = async () => { if (localStorage.getItem("file")) { @@ -58,8 +58,8 @@ export const BroadcastTransformer: React.FC = ({ them } catch (error) { console.error("Error toggling:", error); } - } else if (final !== "") { - const file = reverseFormatDate(final); + } else if (FileName !== "") { + const file = reverseFormatDate(FileName); localStorage.setItem("file", file); const shortDate = convertToShortDate(selected); @@ -81,7 +81,7 @@ export const BroadcastTransformer: React.FC = ({ them useEffect(() => { func(); // fetchBotData(); - }, [final]); + }, [FileName]); const dataBar = { labels: Object.keys(BroadcastTransformerData), @@ -170,7 +170,7 @@ export const BroadcastTransformer: React.FC = ({ them ) => { event.preventDefault(); setDropdown(false); - setFinal(selected); + setFileName(selected); const shortDate = convertToShortDate(selected); localStorage.setItem("shortDate", shortDate); diff --git a/src/pages/monitoring/dummy.json b/src/pages/monitoring/dummy.json deleted file mode 100644 index 9b4ad95..0000000 --- a/src/pages/monitoring/dummy.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "Kafka Topics": { - "broadcast-transformer": "7", - "com.odk.transformer": "17", - "generic-transformer": "0", - "notification-outbound": "35", - "outbound": "17", - "inbound-processed": "24", - "process-outbound": "52", - "telemetry": "14", - "outbound-processed": "0" - }, - "UCI API": { - "ResolveUser": 1 - }, - "Inbound": { - "Data inserted in Cassandra": 1, - "Kafka topic push": 1 - }, - "Orchestrator": { - "Topic consumed from Kafka": 5, - "Notification pushed to Kafka": 5 - }, - "Broadcast Transformer": { - "Broadcast Processed": 5, - "Kafka Push to outbound": 5 - }, - "Outbound": { - "Saved data in cache": 5, - "Notification inserted in Cassandra": 5 - } - } - \ No newline at end of file diff --git a/src/pages/monitoring/inbound/index.tsx b/src/pages/monitoring/inbound/index.tsx index 5cb7ec8..de82c96 100644 --- a/src/pages/monitoring/inbound/index.tsx +++ b/src/pages/monitoring/inbound/index.tsx @@ -45,25 +45,21 @@ export const Inbound: React.FC = ({ theme }) => { const [InboundData, setInboundData] = useState([]); - const [final, setFinal] = useState(""); + const [FileName, setFileName] = useState(""); const func = async () => { if (localStorage.getItem("file")) { const file = localStorage.getItem("file"); - console.log(file) const apiEndpoint = fetchRealtime(file); try { const response = await apiEndpoint; const res = JSON.parse(response.data.result); setInboundData(res["Inbound".trim()] || {}); - console.log(res) } catch (error) { console.error("Error toggling:", error); } - } else if (final !== "") { - console.log(final) - - const file = reverseFormatDate(final); + } else if (FileName !== "") { + const file = reverseFormatDate(FileName); localStorage.setItem("file", file); const shortDate = convertToShortDate(selected); @@ -85,7 +81,7 @@ export const Inbound: React.FC = ({ theme }) => { useEffect(() => { func(); // fetchBotData(); - }, [final]); + }, [FileName]); const dataBar = { labels: Object.keys(InboundData), @@ -173,7 +169,7 @@ export const Inbound: React.FC = ({ theme }) => { event: React.FormEvent ) => { event.preventDefault(); - setFinal(selected); + setFileName(selected); const shortDate = convertToShortDate(selected); localStorage.setItem("shortDate", shortDate); diff --git a/src/pages/monitoring/kafka/index.tsx b/src/pages/monitoring/kafka/index.tsx deleted file mode 100644 index 557c9e7..0000000 --- a/src/pages/monitoring/kafka/index.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import {BarChart} from "../../../components"; -import jsonData from '../dummy.json'; - -const kafkaTopicsData = jsonData["Kafka Topics"]; - -const data = { - labels: Object.keys(kafkaTopicsData), - datasets: [ - { - label: "Kafka Topics", - data: Object.values(kafkaTopicsData).map(Number), - backgroundColor: "rgba(75, 192, 192, 0.6)", - }, - ], -}; - -const Kafka = () => { - return ; -}; - -export default Kafka; \ No newline at end of file diff --git a/src/pages/monitoring/orchestrator/index.tsx b/src/pages/monitoring/orchestrator/index.tsx index 193c4a2..9c13611 100644 --- a/src/pages/monitoring/orchestrator/index.tsx +++ b/src/pages/monitoring/orchestrator/index.tsx @@ -45,7 +45,7 @@ export const Orchestrator: React.FC = ({ theme }) => { const [OrchestratorData, setOrchestratorData] = useState([]); - const [final, setFinal] = useState(""); + const [FileName, setFileName] = useState(""); const func = async () => { if (localStorage.getItem("file")) { @@ -58,8 +58,8 @@ export const Orchestrator: React.FC = ({ theme }) => { } catch (error) { console.error("Error toggling:", error); } - } else if (final !== "") { - const file = reverseFormatDate(final); + } else if (FileName !== "") { + const file = reverseFormatDate(FileName); localStorage.setItem("file", file); const shortDate = convertToShortDate(selected); @@ -81,7 +81,7 @@ export const Orchestrator: React.FC = ({ theme }) => { useEffect(() => { func(); // fetchBotData(); - }, [final]); + }, [FileName]); const dataBar = { labels: Object.keys(OrchestratorData), @@ -170,7 +170,7 @@ export const Orchestrator: React.FC = ({ theme }) => { ) => { event.preventDefault(); setDropdown(false); - setFinal(selected); + setFileName(selected); const shortDate = convertToShortDate(selected); localStorage.setItem("shortDate", shortDate); diff --git a/src/pages/monitoring/outbound/index.tsx b/src/pages/monitoring/outbound/index.tsx index 8539d9f..36c710b 100644 --- a/src/pages/monitoring/outbound/index.tsx +++ b/src/pages/monitoring/outbound/index.tsx @@ -44,7 +44,7 @@ export const Outbound: React.FC = ({ theme }) => { const [OutboundData, setOutboundData] = useState([]); - const [final, setFinal] = useState(""); + const [FileName, setFileName] = useState(""); const func = async () => { if (localStorage.getItem("file")) { @@ -57,8 +57,8 @@ export const Outbound: React.FC = ({ theme }) => { } catch (error) { console.error("Error toggling:", error); } - } else if (final !== "") { - const file = reverseFormatDate(final); + } else if (FileName !== "") { + const file = reverseFormatDate(FileName); localStorage.setItem("file", file); const shortDate = convertToShortDate(selected); @@ -80,7 +80,7 @@ export const Outbound: React.FC = ({ theme }) => { useEffect(() => { func(); // fetchBotData(); - }, [final]); + }, [FileName]); const dataBar = { labels: Object.keys(OutboundData), @@ -167,7 +167,7 @@ export const Outbound: React.FC = ({ theme }) => { event: React.FormEvent ) => { event.preventDefault(); - setFinal(selected); + setFileName(selected); const shortDate = convertToShortDate(selected); localStorage.setItem("shortDate", shortDate); diff --git a/src/pages/monitoring/transformer/index.tsx b/src/pages/monitoring/transformer/index.tsx index c5e6123..ee0c9d1 100644 --- a/src/pages/monitoring/transformer/index.tsx +++ b/src/pages/monitoring/transformer/index.tsx @@ -45,7 +45,7 @@ export const Transformer: React.FC = ({ theme }) => { const [TransformerData, setTransformerData] = useState([]); - const [final, setFinal] = useState(""); + const [FileName, setFileName] = useState(""); const func = async () => { if (localStorage.getItem("file")) { @@ -58,8 +58,8 @@ export const Transformer: React.FC = ({ theme }) => { } catch (error) { console.error("Error toggling:", error); } - } else if (final !== "") { - const file = reverseFormatDate(final); + } else if (FileName !== "") { + const file = reverseFormatDate(FileName); localStorage.setItem("file", file); const shortDate = convertToShortDate(selected); @@ -81,7 +81,7 @@ export const Transformer: React.FC = ({ theme }) => { useEffect(() => { func(); // fetchBotData(); - }, [final]); + }, [FileName]); const dataBar = { labels: Object.keys(TransformerData), @@ -169,7 +169,7 @@ export const Transformer: React.FC = ({ theme }) => { event: React.FormEvent ) => { event.preventDefault(); - setFinal(selected); + setFileName(selected); const shortDate = convertToShortDate(selected); localStorage.setItem("shortDate", shortDate); diff --git a/src/pages/monitoring/uci-api/index.tsx b/src/pages/monitoring/uci-api/index.tsx index 2be600e..f375d5e 100644 --- a/src/pages/monitoring/uci-api/index.tsx +++ b/src/pages/monitoring/uci-api/index.tsx @@ -49,7 +49,7 @@ export const UCIAPI: React.FC = ({ theme }) => { const [uciApiData, setUciApiData] = useState([]); - const [final, setFinal] = useState(""); + const [FileName, setFileName] = useState(""); const func = async () => { if (localStorage.getItem("file")) { @@ -62,8 +62,8 @@ export const UCIAPI: React.FC = ({ theme }) => { } catch (error) { console.error("Error toggling:", error); } - } else if (final !== "") { - const file = reverseFormatDate(final); + } else if (FileName !== "") { + const file = reverseFormatDate(FileName); localStorage.setItem("file", file); const shortDate = convertToShortDate(selected); @@ -85,7 +85,7 @@ export const UCIAPI: React.FC = ({ theme }) => { useEffect(() => { func(); // fetchBotData(); - }, [final]); + }, [FileName]); const dataBar = { labels: Object.keys(uciApiData), @@ -190,7 +190,7 @@ export const UCIAPI: React.FC = ({ theme }) => { ) => { const { value } = event.target; setSelected(value); - setFinal(selected); + setFileName(selected); const lowercasedValue = value.toLowerCase(); const apiEndpoint = getFilesData(); From 1e7f7083b2106b19d87d8be512a8f7b76459d64a Mon Sep 17 00:00:00 2001 From: Pratiksha Sankhe Date: Wed, 6 Sep 2023 17:31:00 +0530 Subject: [PATCH 13/13] Update index.tsx --- src/components/sidebar/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/sidebar/index.tsx b/src/components/sidebar/index.tsx index 8d58d36..47df9e5 100644 --- a/src/components/sidebar/index.tsx +++ b/src/components/sidebar/index.tsx @@ -13,7 +13,7 @@ import { Switch } from "./Switch"; // import { Typography } from './Typography'; import { SidebarFooter } from "./SidebarFooter"; import { SidebarHeader } from "./SidebarHeader"; -import DashobardIcon from "../icons/Dashobard"; +import DashobardIcon from "../icons/Dashboard"; import AddIcon from "../icons/AddIcon"; import LogoutIcon from "../icons/LogoutIcon"; import ThemeIcon from "../icons/ThemeIcon";