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/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/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 (
)
}
-export default DashobardIcon
\ No newline at end of file
+export default DashboardIcon
\ No newline at end of file
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..47df9e5 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/Dashboard";
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/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/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/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
new file mode 100644
index 0000000..6e04a46
--- /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 [FileName, setFileName] = 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 (FileName !== "") {
+ const file = reverseFormatDate(FileName);
+ 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();
+ }, [FileName]);
+
+ 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);
+ setFileName(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
+
+
+
+
+ {/*
+
+ {autocompleteSuggestions.length > 0 && (
+
+ {autocompleteSuggestions.map((item) => (
+ - setSearchText(item.value)}>
+ {item.value}
+
+ ))}
+
+ )}
+ */}
+
+
+ {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/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
new file mode 100644
index 0000000..de82c96
--- /dev/null
+++ b/src/pages/monitoring/inbound/index.tsx
@@ -0,0 +1,318 @@
+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 [FileName, setFileName] = 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);
+ setInboundData(res["Inbound".trim()] || {});
+ } catch (error) {
+ console.error("Error toggling:", error);
+ }
+ } else if (FileName !== "") {
+ const file = reverseFormatDate(FileName);
+ 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();
+ }, [FileName]);
+
+ 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();
+ setFileName(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
+
+
+
+
+ {/*
+
+ {autocompleteSuggestions.length > 0 && (
+
+ {autocompleteSuggestions.map((item) => (
+ - setSearchText(item.value)}>
+ {item.value}
+
+ ))}
+
+ )}
+ */}
+
+
+ {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/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/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 (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {showDropdown &&
+ autocompleteSuggestions.length > 0 &&
+ searchText !== 0 && (
+
+ {autocompleteSuggestions.map((item) => (
+ - handleDropdownItemClick(item.value)}
+ >
+ {item.value}
+
+ ))}
+
+ )}
+
+
+
+
+
+
+
+ {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 (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {showDropdown &&
+ autocompleteSuggestions.length > 0 &&
+ searchText !== 0 && (
+
+ {autocompleteSuggestions.map((item) => (
+ - handleDropdownItemClick(item.value)}
+ >
+ {item.value}
+
+ ))}
+
+ )}
+
+
+
+
+
+
+
+ {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 (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {showDropdown &&
+ autocompleteSuggestions.length > 0 &&
+ searchText !== 0 && (
+
+ {autocompleteSuggestions.map((item) => (
+ - handleDropdownItemClick(item.value)}
+ >
+ {item.value}
+
+ ))}
+
+ )}
+
+
+
+
+
+
+
+ {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 (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {showDropdown &&
+ autocompleteSuggestions.length > 0 &&
+ searchText !== 0 && (
+
+ {autocompleteSuggestions.map((item) => (
+ - handleDropdownItemClick(item.value)}
+ >
+ {item.value}
+
+ ))}
+
+ )}
+
+
+
+
+
+
+
+ {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 (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {showDropdown &&
+ autocompleteSuggestions.length > 0 &&
+ searchText !== 0 && (
+
+ {autocompleteSuggestions.map((item) => (
+ - handleDropdownItemClick(item.value)}
+ >
+ {item.value}
+
+ ))}
+
+ )}
+
+
+
+
+
+
+
+ {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 (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {showDropdown &&
+ autocompleteSuggestions.length > 0 &&
+ searchText !== 0 && (
+
+ {autocompleteSuggestions.map((item) => (
+ - handleDropdownItemClick(item.value)}
+ >
+ {item.value}
+
+ ))}
+
+ )}
+
+
+
+
+
+
+
+ {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..9c13611
--- /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 [FileName, setFileName] = 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 (FileName !== "") {
+ const file = reverseFormatDate(FileName);
+ 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();
+ }, [FileName]);
+
+ 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);
+ setFileName(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
+
+
+
+
+ {/*
+
+ {autocompleteSuggestions.length > 0 && (
+
+ {autocompleteSuggestions.map((item) => (
+ - setSearchText(item.value)}>
+ {item.value}
+
+ ))}
+
+ )}
+ */}
+
+
+ {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..36c710b
--- /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 [FileName, setFileName] = 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 (FileName !== "") {
+ const file = reverseFormatDate(FileName);
+ 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();
+ }, [FileName]);
+
+ 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();
+ setFileName(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
+
+
+
+
+ {/*
+
+ {autocompleteSuggestions.length > 0 && (
+
+ {autocompleteSuggestions.map((item) => (
+ - setSearchText(item.value)}>
+ {item.value}
+
+ ))}
+
+ )}
+ */}
+
+
+ {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 3559055..762b0fb 100644
--- a/src/pages/monitoring/overview/index.tsx
+++ b/src/pages/monitoring/overview/index.tsx
@@ -1,78 +1,217 @@
-import React, { useEffect } from "react";
-import { MDBCard, MDBCardBody } from "mdb-react-ui-kit";
+import {
+ MDBCard,
+ MDBCardBody,
+ MDBCol,
+ MDBRow,
+ MDBBtn,
+ MDBSwitch,
+} from "mdb-react-ui-kit";
import "./style.css";
-import { useStore } from "../../../store";
+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";
-type Theme = "light" | "dark";
+interface OverviewHeaderProps extends React.HTMLAttributes {
+ theme: string;
+}
-export const Overview = () => {
- const store: any = useStore();
- const [theme, setTheme] = React.useState(store?.theme);
+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);
+ };
+
+ 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(() => {
- setTheme(store?.theme);
- }, [store?.theme]);
+ fetchData();
+ console.log(!selected || localStorage.getItem("file") == null);
+ }, []);
return (
-
-
-
-
- 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
-
-
-
-
-
-
-
- 50
- No. of Notifications opened by users
-
-
-
-
+
+
+
+
+ {dropdown && autocompleteSuggestions.length > 0 && (
+
+ {autocompleteSuggestions.map((item) => (
+ - handleAutocompleteItemClick(item.value)}
+ className={`${theme}-dropdown`}
+ >
+ {item.value}
+
+ ))}
+
+ )}
+
+
+
+ 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
+ )}
);
};
-
-// export default Overview;
diff --git a/src/pages/monitoring/overview/style.css b/src/pages/monitoring/overview/style.css
index e88ee7f..d269be9 100644
--- a/src/pages/monitoring/overview/style.css
+++ b/src/pages/monitoring/overview/style.css
@@ -1,15 +1,18 @@
.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;
+}
+
+.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..ee0c9d1
--- /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 [FileName, setFileName] = 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 (FileName !== "") {
+ const file = reverseFormatDate(FileName);
+ 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();
+ }, [FileName]);
+
+ 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();
+ setFileName(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
+
+
+
+
+ {/*
+
+ {autocompleteSuggestions.length > 0 && (
+
+ {autocompleteSuggestions.map((item) => (
+ - setSearchText(item.value)}>
+ {item.value}
+
+ ))}
+
+ )}
+ */}
+
+
+ {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..f375d5e
--- /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 [FileName, setFileName] = 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 (FileName !== "") {
+ const file = reverseFormatDate(FileName);
+ 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();
+ }, [FileName]);
+
+ 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);
+ setFileName(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
+
+
+
+
+ {/*
+
+ {autocompleteSuggestions.length > 0 && (
+
+ {autocompleteSuggestions.map((item) => (
+ - setSearchText(item.value)}>
+ {item.value}
+
+ ))}
+
+ )}
+ */}
+
+
+ {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
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