Commit f93e3b03 authored by ReemyHasan's avatar ReemyHasan

Update Socket feature and add Notification

parent b2fb1362
This diff was suppressed by a .gitattributes entry.
......@@ -16,6 +16,7 @@
"@types/react": "18.2.7",
"@types/react-dom": "18.2.4",
"antd": "^5.5.2",
"axios": "^1.4.0",
"chart.js": "^4.3.0",
"clsx": "^1.2.1",
"eslint": "8.41.0",
......
......@@ -11,12 +11,22 @@ import "@/../shared-library/globals.css";
import AuthContextProvider from "@/src/context/auth-context";
import useTranslation from "next-translate/useTranslation";
import { TranslationFiles } from "@/src/data/core";
import websocket from "../src/features/web-socket";
import DataContext from "../src/context/trap-context";
const inter = Inter({ subsets: ["latin"] });
export default function App({ Component, pageProps }: AppProps) {
const router = useRouter();
const { t } = useTranslation(TranslationFiles.COMMON);
const [data, setData] = React.useState([]);
const [new_val, setNewVal] = React.useState(null);
const contextValue = React.useMemo(() => ({ data, setData, websocket,new_val,setNewVal }), [
data,
setData,
websocket,
new_val,
setNewVal
]);
React.useEffect(() => {
if (router.pathname === "/") {
router.push("/dashboard");
......@@ -46,10 +56,12 @@ export default function App({ Component, pageProps }: AppProps) {
},
}}
>
<AuthContextProvider>
{/*// @ts-ignore*/}
<Component {...pageProps} />
</AuthContextProvider>
<DataContext.Provider value={contextValue}>
<AuthContextProvider>
{/*// @ts-ignore*/}
<Component {...pageProps} />
</AuthContextProvider>
</DataContext.Provider>
</ANTDConfigProvider>
</main>
</Fragment>
......
import * as React from "react";
import Head from "next/head";
import AppLayout from "@/src/components/layout";
import { UserCard, FaultChart } from "@/src/features/dashboard";
// import { UserCard, FaultChart } from "@/src/features/dashboard";
import ChartComponent from "@/src/features/dashboard/chart";
import { Fragment } from "react";
import useTranslation from "next-translate/useTranslation";
......@@ -18,11 +18,8 @@ export default function Dashboard() {
</Head>
<AppLayout>
<main className={`app-main-container`}>
<div className={"page-header"}>{t("dashboard")}</div>
<div className={"page-header"}>{t("")}</div>
<Row gutter={56}>
<UserCard userNumber={userNumber} />
<FaultChart />
<ChartComponent />
</Row>
</main>
</AppLayout>
......
......@@ -3,8 +3,15 @@ import { List, Dropdown, Menu, Row, Col, Badge } from "antd";
import BellIcon from "@/src/components/assets/custom-ant-icons/bell-icon";
import useTranslation from "next-translate/useTranslation";
import { TranslationFiles } from "@/src/data/core";
const AppNotifications = () => {
const { t } = useTranslation(TranslationFiles.COMMON);
import { useRouter } from "next/router";
import FmsButton from "../../../../../../../shared-library/src/buttons/fms-button";
type AppNotificationsProps = {
data: Array<any>;
setData: Function;
};
const AppNotifications = ({ data, setData }: AppNotificationsProps) => {
const { t } = useTranslation(TranslationFiles.COMMON);
const router = useRouter();
const menu = (
<Menu className="notify-header-message">
<Menu.Item className="header">
......@@ -17,14 +24,37 @@ const AppNotifications = () => {
</Menu.Item>
<List
className="notify-list scrollRow"
dataSource={[]}
renderItem={(item: any) => {
return "";
}}
dataSource={data.slice(-3)}
renderItem={(item: any) => (
<List.Item>
<div className={`severity-${item.severity}`}>{item.severity}</div>
<div>{item.agentAddress}</div>
{/* Add more properties as required */}
</List.Item>
)}
/>
<Menu.Item onClick={() => {}}>
<p className="seeNotifications">{t("see-more")}</p>
</Menu.Item>
<Row gutter={12}>
{" "}
<Col>
<FmsButton
// className="seeNotifications"
size={"small"}
type = "traity"
onClick={() => {
setData([]);
router.push("/traps");
}}
>
{t("see-more")}
</FmsButton>
</Col>
<Col>
<FmsButton size={"small"} type = "traity" onClick={() => setData([])}>
{t("confirm")}
</FmsButton>
</Col>
</Row>
</Menu>
);
......@@ -36,7 +66,11 @@ const AppNotifications = () => {
trigger={["click"]}
>
<a className="notify-link" onClick={(e) => e.preventDefault()}>
<Badge count={0} size="small">
<Badge
count={data.length}
size="small"
style={{ backgroundColor: "red" }}
>
<span className="notify-icon">
<BellIcon />
</span>
......
import React from "react";
import React, { useEffect, useContext,useRef } from "react";
import { Layout, Row, Col } from "antd";
import AppLanguageSwitcher from "./app-language-switcher";
import AppNotifications from "./app-notifications";
import UserInfo from "./user-info";
import MenuIcon from "@/src/components/assets/custom-ant-icons/menu-icon";
import DataContext from "../../../../context/trap-context";
const { Header } = Layout;
type AppHeaderProps = {
toggleCollapse: Function;
};
const AppHeader = ({ toggleCollapse }: AppHeaderProps) => {
export default function AppHeader({ toggleCollapse }: AppHeaderProps) {
const { data, setData, websocket, setNewVal } = useContext(DataContext);
useEffect(() => {
if (!websocket) {
return;
}
websocket.onmessage = function (event:any) {
const message = JSON.parse(event.data);
console.log(message);
if (message.new_val != null) {
const newData = message.new_val;
const transformedData = {
flag:'0',
id: newData.id,
timestamp: newData.timestamp,
agentAddress: newData.agentAddress,
severity: newData.severity,
specificTrap: newData.specificTrap,
genericTrap: newData.genericTrap,
variableBindings: newData.variableBindings,
};
setNewVal(transformedData);
setData((prevData: any) => [...prevData, newData]);
}
else{
setNewVal({id:message.old_val.id,flag:-1,});
}
};
return () => {
// if (websocket) {
// websocket.close();
// }
};
}, []);
return (
<Header className="app-header-mini-sidebar">
<Row justify={"space-between"} align={"middle"} className={"fullContent"}>
......@@ -26,7 +63,7 @@ const AppHeader = ({ toggleCollapse }: AppHeaderProps) => {
<AppLanguageSwitcher />
</Col>
<Col className={"app-notifications"}>
<AppNotifications />
<AppNotifications data={data} setData={setData} />
</Col>
<Col className={"app-user-info"}>
<UserInfo />
......@@ -36,6 +73,6 @@ const AppHeader = ({ toggleCollapse }: AppHeaderProps) => {
</Row>
</Header>
);
};
}
export default AppHeader;
// export default AppHeader;
import { createContext } from "react";
const DataContext = createContext({
data: [],
setData: () => {},
websocket: null,
new_val:null,
setNewVal: (newVal:any) => {},
});
export default DataContext;
\ No newline at end of file
......@@ -3,18 +3,18 @@ import { Card, Col } from "antd";
import styles from "./index.module.css";
import PieChartComponent from "./pie-chart";
export const UserCard = ({ userNumber }) => (
<Col span={12}>
<PieChartComponent />
</Col>
);
// export const UserCard = ({ userNumber }) => (
// <Col span={12}>
// <PieChartComponent />
// </Col>
// );
export const FaultChart = () => (
<Col>
<Card title="Alarms" className={styles.dashboardChartsContainer}>
<p>HI</p>
</Card>
</Col>
// export const FaultChart = () => (
// <Col>
// <Card title="Alarms" className={styles.dashboardChartsContainer}>
// <p>HI</p>
// </Card>
// </Col>
);
......@@ -91,7 +91,7 @@ export function getColumns(setModalProps:any) {
dataIndex: "severity",
key: "severity",
resizable: true,
render: (text:any) => <Col className={`severity-${text}`}>{text.toUpperCase()}</Col>,
render: (text:any) => <Col className={`severity-${text}`}>{text}</Col>,
sorter: (a:any, b:any) => a.severity.localeCompare(b.severity),
sortDirections: ['descend', 'ascend'],
filterDropdown: ({ setSelectedKeys, selectedKeys, confirm }:any) => (
......
import * as React from "react";
import { useState, useEffect } from "react";
import { useState, useEffect, useContext } from "react";
import useTranslation from "next-translate/useTranslation";
import { TranslationFiles } from "@/src/data/core";
import FmsTable from "../../../../shared-library/src/tables/fms-table";
import { getColumns } from "./columns";
import DataContext from "@/src/context/trap-context";
import { DataSource } from "./data-source";
import ShowDetailsPopup from "./show-details-popup";
import axios from "axios";
import { Spin } from "antd";
export default function ShowTraps() {
const { t } = useTranslation(TranslationFiles.COMMON);
const [modalProps, setModalProps] = useState({ isOpen: false, variableBinding: null });
const [data, setData] = useState([]);
let socket: WebSocket | null = null;
const [modalProps, setModalProps] = useState({
isOpen: false,
variableBinding: null,
});
const { data, new_val, setNewVal } = useContext(DataContext);
const [data1, setData1] = useState([]);
const [loading, setLoading] = useState(false);
useEffect(() => {
setLoading(true);
const fetchData = async () => {
axios
.get("http://192.168.93.198:6647/api/rethink/data")
.then((res: any) => {
if (res.data) {
// console.log(res.data);
const transformedData = res.data.map((item: any) => ({
id: item.id,
timestamp: item.timestamp,
agentAddress: item.agentAddress,
severity: item.severity,
specificTrap: item.specificTrap,
genericTrap: item.genericTrap,
variableBindings: item.variableBindings,
}));
setData1(transformedData);
// console.log(data1);
if(new_val!=null){
if (new_val.flag == '0') {
// const transformedData2 =data.map((newData:any)=>({
// id: newData.id,
// timestamp: newData.timestamp,
// agentAddress: newData.agentAddress,
// severity: newData.severity,
// specificTrap: newData.specificTrap,
// genericTrap: newData.genericTrap,
// variableBindings: newData.variableBindings,
// }))
console.log(new_val);
setData1((prevData:any) => [...prevData, new_val]);
setNewVal(null);
// transformedData2.forEach((item:any) => {
// setData1((prevData:any) => [...prevData, item]);
// });
}
else if (new_val.flag==-1){
setData1((prevData:any) => prevData.filter((item:any) => item.id !== new_val.id));
}
}
}
else {
alert("Error");
}
})
.catch((err: any) => console.log(err));
};
fetchData();
setLoading(false);
}, [new_val]);
// useEffect(() => {
// if (!websocket) {
// return;
// }
function getWebSocket() {
if (!socket) {
socket = new WebSocket("ws://192.168.26.46:6647/fms-websocket");
socket.onopen = function () {
console.log("Connected to WebSocket server");
};
socket.onmessage = function (event) {
const message = JSON.parse(event.data);
// websocket.onmessage = function (event) {
// const message = JSON.parse(event.data);
const newData = message.new_val;
const transformedData = {
id: newData.id,
agentAddress: newData.agentAddress,
timestamp: newData.timestamp,
severity: newData.severity,
specificTrap: newData.specificTrap,
genericTrap: newData.genericTrap,
variableBindings: newData.variableBindings,
};
// console.log(transformedData);
setData((prevData: any) => [...prevData, transformedData]);
};
socket.onclose = function () {
console.log("Disconnected from WebSocket server");
socket = null;
};
}
return socket;
}
// const newData = message.new_val;
// const transformedData = {
// id: newData.id,
// agentAddress: newData.agentAddress,
// timestamp: newData.timestamp,
// severity: newData.severity,
// specificTrap: newData.specificTrap,
// genericTrap: newData.genericTrap,
// variableBindings: newData.variableBindings,
// };
// setData((prevData: any) => [...prevData, transformedData]);
// };
useEffect(() => {
const socket = getWebSocket();
return () => {
socket.close();
};
}, []);
// }, [websocket]);
return (
<div>
<FmsTable
title={t("traps")}
columns={getColumns(setModalProps)}
data={data}
t={t}
setData={setData}
/>
<ShowDetailsPopup
modalProps={modalProps}
setModalProps={setModalProps}
/>
<Spin spinning={loading}>
<FmsTable
title={t("traps")}
columns={getColumns(setModalProps)}
data={data1}
t={t}
setData={setData1}
/>
<ShowDetailsPopup
modalProps={modalProps}
setModalProps={setModalProps}
/>
</Spin>
</div>
);
}
import React, {useState, useEffect} from "react";
import { Modal } from "antd";
import { Col, Modal, Row } from "antd";
import useTranslation from "next-translate/useTranslation";
import { TranslationFiles } from "@/src/data/core";
......@@ -28,7 +28,7 @@ export default function ShowDetailsPopup({ modalProps, setModalProps }: Props) {
{variableBinding &&
variableBinding.map((item: any, index: number) => (
<div key={index}>
<span>{item.oid}</span>: <span>{item.value}</span>
<Row gutter={12}><Col span={32}>{item.oid}</Col>: <Col span={32}>{item.value}</Col></Row>
</div>
))}
</div>
......
const websocket = new WebSocket("ws://192.168.26.46:6647/fms-websocket");
let websocket: WebSocket | null = new WebSocket("ws://192.168.93.198:6647/fms-websocket");
websocket.onopen = function () {
console.log("Connected to WebSocket server");
......@@ -6,6 +6,8 @@ websocket.onopen = function () {
websocket.onclose = function () {
console.log("Disconnected from WebSocket server");
websocket = null;
};
export default websocket;
\ No newline at end of file
......@@ -2133,6 +2133,7 @@ __metadata:
"@types/react-dom": 18.2.4
"@types/testing-library__jest-dom": ^5.14.6
antd: ^5.5.2
axios: ^1.4.0
chart.js: ^4.3.0
clsx: ^1.2.1
eslint: 8.41.0
......@@ -4463,6 +4464,17 @@ __metadata:
languageName: node
linkType: hard
"axios@npm:^1.4.0":
version: 1.4.0
resolution: "axios@npm:1.4.0"
dependencies:
follow-redirects: ^1.15.0
form-data: ^4.0.0
proxy-from-env: ^1.1.0
checksum: 7fb6a4313bae7f45e89d62c70a800913c303df653f19eafec88e56cea2e3821066b8409bc68be1930ecca80e861c52aa787659df0ffec6ad4d451c7816b9386b
languageName: node
linkType: hard
"axobject-query@npm:^3.1.1":
version: 3.2.1
resolution: "axobject-query@npm:3.2.1"
......@@ -6732,6 +6744,16 @@ __metadata:
languageName: unknown
linkType: soft
"follow-redirects@npm:^1.15.0":
version: 1.15.2
resolution: "follow-redirects@npm:1.15.2"
peerDependenciesMeta:
debug:
optional: true
checksum: faa66059b66358ba65c234c2f2a37fcec029dc22775f35d9ad6abac56003268baf41e55f9ee645957b32c7d9f62baf1f0b906e68267276f54ec4b4c597c2b190
languageName: node
linkType: hard
"for-each@npm:^0.3.3":
version: 0.3.3
resolution: "for-each@npm:0.3.3"
......@@ -10275,7 +10297,7 @@ __metadata:
languageName: node
linkType: hard
"proxy-from-env@npm:^1.0.0":
"proxy-from-env@npm:^1.0.0, proxy-from-env@npm:^1.1.0":
version: 1.1.0
resolution: "proxy-from-env@npm:1.1.0"
checksum: ed7fcc2ba0a33404958e34d95d18638249a68c430e30fcb6c478497d72739ba64ce9810a24f53a7d921d0c065e5b78e3822759800698167256b04659366ca4d4
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment