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 @@ ...@@ -16,6 +16,7 @@
"@types/react": "18.2.7", "@types/react": "18.2.7",
"@types/react-dom": "18.2.4", "@types/react-dom": "18.2.4",
"antd": "^5.5.2", "antd": "^5.5.2",
"axios": "^1.4.0",
"chart.js": "^4.3.0", "chart.js": "^4.3.0",
"clsx": "^1.2.1", "clsx": "^1.2.1",
"eslint": "8.41.0", "eslint": "8.41.0",
......
...@@ -11,12 +11,22 @@ import "@/../shared-library/globals.css"; ...@@ -11,12 +11,22 @@ import "@/../shared-library/globals.css";
import AuthContextProvider from "@/src/context/auth-context"; import AuthContextProvider from "@/src/context/auth-context";
import useTranslation from "next-translate/useTranslation"; import useTranslation from "next-translate/useTranslation";
import { TranslationFiles } from "@/src/data/core"; 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"] }); const inter = Inter({ subsets: ["latin"] });
export default function App({ Component, pageProps }: AppProps) { export default function App({ Component, pageProps }: AppProps) {
const router = useRouter(); const router = useRouter();
const { t } = useTranslation(TranslationFiles.COMMON); 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(() => { React.useEffect(() => {
if (router.pathname === "/") { if (router.pathname === "/") {
router.push("/dashboard"); router.push("/dashboard");
...@@ -46,10 +56,12 @@ export default function App({ Component, pageProps }: AppProps) { ...@@ -46,10 +56,12 @@ export default function App({ Component, pageProps }: AppProps) {
}, },
}} }}
> >
<DataContext.Provider value={contextValue}>
<AuthContextProvider> <AuthContextProvider>
{/*// @ts-ignore*/} {/*// @ts-ignore*/}
<Component {...pageProps} /> <Component {...pageProps} />
</AuthContextProvider> </AuthContextProvider>
</DataContext.Provider>
</ANTDConfigProvider> </ANTDConfigProvider>
</main> </main>
</Fragment> </Fragment>
......
import * as React from "react"; import * as React from "react";
import Head from "next/head"; import Head from "next/head";
import AppLayout from "@/src/components/layout"; 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 ChartComponent from "@/src/features/dashboard/chart";
import { Fragment } from "react"; import { Fragment } from "react";
import useTranslation from "next-translate/useTranslation"; import useTranslation from "next-translate/useTranslation";
...@@ -18,11 +18,8 @@ export default function Dashboard() { ...@@ -18,11 +18,8 @@ export default function Dashboard() {
</Head> </Head>
<AppLayout> <AppLayout>
<main className={`app-main-container`}> <main className={`app-main-container`}>
<div className={"page-header"}>{t("dashboard")}</div> <div className={"page-header"}>{t("")}</div>
<Row gutter={56}> <Row gutter={56}>
<UserCard userNumber={userNumber} />
<FaultChart />
<ChartComponent />
</Row> </Row>
</main> </main>
</AppLayout> </AppLayout>
......
...@@ -3,8 +3,15 @@ import { List, Dropdown, Menu, Row, Col, Badge } from "antd"; ...@@ -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 BellIcon from "@/src/components/assets/custom-ant-icons/bell-icon";
import useTranslation from "next-translate/useTranslation"; import useTranslation from "next-translate/useTranslation";
import { TranslationFiles } from "@/src/data/core"; import { TranslationFiles } from "@/src/data/core";
const AppNotifications = () => { 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 { t } = useTranslation(TranslationFiles.COMMON);
const router = useRouter();
const menu = ( const menu = (
<Menu className="notify-header-message"> <Menu className="notify-header-message">
<Menu.Item className="header"> <Menu.Item className="header">
...@@ -17,14 +24,37 @@ const AppNotifications = () => { ...@@ -17,14 +24,37 @@ const AppNotifications = () => {
</Menu.Item> </Menu.Item>
<List <List
className="notify-list scrollRow" className="notify-list scrollRow"
dataSource={[]} dataSource={data.slice(-3)}
renderItem={(item: any) => { renderItem={(item: any) => (
return ""; <List.Item>
}} <div className={`severity-${item.severity}`}>{item.severity}</div>
<div>{item.agentAddress}</div>
{/* Add more properties as required */}
</List.Item>
)}
/> />
<Menu.Item onClick={() => {}}> <Row gutter={12}>
<p className="seeNotifications">{t("see-more")}</p> {" "}
</Menu.Item> <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> </Menu>
); );
...@@ -36,7 +66,11 @@ const AppNotifications = () => { ...@@ -36,7 +66,11 @@ const AppNotifications = () => {
trigger={["click"]} trigger={["click"]}
> >
<a className="notify-link" onClick={(e) => e.preventDefault()}> <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"> <span className="notify-icon">
<BellIcon /> <BellIcon />
</span> </span>
......
import React from "react"; import React, { useEffect, useContext,useRef } from "react";
import { Layout, Row, Col } from "antd"; import { Layout, Row, Col } from "antd";
import AppLanguageSwitcher from "./app-language-switcher"; import AppLanguageSwitcher from "./app-language-switcher";
import AppNotifications from "./app-notifications"; import AppNotifications from "./app-notifications";
import UserInfo from "./user-info"; import UserInfo from "./user-info";
import MenuIcon from "@/src/components/assets/custom-ant-icons/menu-icon"; import MenuIcon from "@/src/components/assets/custom-ant-icons/menu-icon";
import DataContext from "../../../../context/trap-context";
const { Header } = Layout; const { Header } = Layout;
type AppHeaderProps = { type AppHeaderProps = {
toggleCollapse: Function; 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 ( return (
<Header className="app-header-mini-sidebar"> <Header className="app-header-mini-sidebar">
<Row justify={"space-between"} align={"middle"} className={"fullContent"}> <Row justify={"space-between"} align={"middle"} className={"fullContent"}>
...@@ -26,7 +63,7 @@ const AppHeader = ({ toggleCollapse }: AppHeaderProps) => { ...@@ -26,7 +63,7 @@ const AppHeader = ({ toggleCollapse }: AppHeaderProps) => {
<AppLanguageSwitcher /> <AppLanguageSwitcher />
</Col> </Col>
<Col className={"app-notifications"}> <Col className={"app-notifications"}>
<AppNotifications /> <AppNotifications data={data} setData={setData} />
</Col> </Col>
<Col className={"app-user-info"}> <Col className={"app-user-info"}>
<UserInfo /> <UserInfo />
...@@ -36,6 +73,6 @@ const AppHeader = ({ toggleCollapse }: AppHeaderProps) => { ...@@ -36,6 +73,6 @@ const AppHeader = ({ toggleCollapse }: AppHeaderProps) => {
</Row> </Row>
</Header> </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"; ...@@ -3,18 +3,18 @@ import { Card, Col } from "antd";
import styles from "./index.module.css"; import styles from "./index.module.css";
import PieChartComponent from "./pie-chart"; import PieChartComponent from "./pie-chart";
export const UserCard = ({ userNumber }) => ( // export const UserCard = ({ userNumber }) => (
<Col span={12}> // <Col span={12}>
<PieChartComponent /> // <PieChartComponent />
</Col> // </Col>
); // );
export const FaultChart = () => ( // export const FaultChart = () => (
<Col> // <Col>
<Card title="Alarms" className={styles.dashboardChartsContainer}> // <Card title="Alarms" className={styles.dashboardChartsContainer}>
<p>HI</p> // <p>HI</p>
</Card> // </Card>
</Col> // </Col>
); );
...@@ -91,7 +91,7 @@ export function getColumns(setModalProps:any) { ...@@ -91,7 +91,7 @@ export function getColumns(setModalProps:any) {
dataIndex: "severity", dataIndex: "severity",
key: "severity", key: "severity",
resizable: true, 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), sorter: (a:any, b:any) => a.severity.localeCompare(b.severity),
sortDirections: ['descend', 'ascend'], sortDirections: ['descend', 'ascend'],
filterDropdown: ({ setSelectedKeys, selectedKeys, confirm }:any) => ( filterDropdown: ({ setSelectedKeys, selectedKeys, confirm }:any) => (
......
import * as React from "react"; import * as React from "react";
import { useState, useEffect } from "react"; import { useState, useEffect, useContext } from "react";
import useTranslation from "next-translate/useTranslation"; import useTranslation from "next-translate/useTranslation";
import { TranslationFiles } from "@/src/data/core"; import { TranslationFiles } from "@/src/data/core";
import FmsTable from "../../../../shared-library/src/tables/fms-table"; import FmsTable from "../../../../shared-library/src/tables/fms-table";
import { getColumns } from "./columns"; import { getColumns } from "./columns";
import DataContext from "@/src/context/trap-context";
import { DataSource } from "./data-source"; import { DataSource } from "./data-source";
import ShowDetailsPopup from "./show-details-popup"; import ShowDetailsPopup from "./show-details-popup";
import axios from "axios";
import { Spin } from "antd";
export default function ShowTraps() { export default function ShowTraps() {
const { t } = useTranslation(TranslationFiles.COMMON); const { t } = useTranslation(TranslationFiles.COMMON);
const [modalProps, setModalProps] = useState({ isOpen: false, variableBinding: null }); const [modalProps, setModalProps] = useState({
const [data, setData] = useState([]); isOpen: false,
let socket: WebSocket | null = null; 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,
function getWebSocket() { // }))
if (!socket) {
socket = new WebSocket("ws://192.168.26.46:6647/fms-websocket"); console.log(new_val);
socket.onopen = function () { setData1((prevData:any) => [...prevData, new_val]);
console.log("Connected to WebSocket server"); setNewVal(null);
}; // transformedData2.forEach((item:any) => {
socket.onmessage = function (event) { // setData1((prevData:any) => [...prevData, item]);
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; else if (new_val.flag==-1){
setData1((prevData:any) => prevData.filter((item:any) => item.id !== new_val.id));
} }
}
useEffect(() => { }
const socket = getWebSocket(); else {
return () => { alert("Error");
socket.close(); }
})
.catch((err: any) => console.log(err));
}; };
}, []); fetchData();
setLoading(false);
}, [new_val]);
// useEffect(() => {
// if (!websocket) {
// return;
// }
// 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,
// };
// setData((prevData: any) => [...prevData, transformedData]);
// };
// }, [websocket]);
return ( return (
<div> <div>
<Spin spinning={loading}>
<FmsTable <FmsTable
title={t("traps")} title={t("traps")}
columns={getColumns(setModalProps)} columns={getColumns(setModalProps)}
data={data} data={data1}
t={t} t={t}
setData={setData} setData={setData1}
/> />
<ShowDetailsPopup <ShowDetailsPopup
modalProps={modalProps} modalProps={modalProps}
setModalProps={setModalProps} setModalProps={setModalProps}
/> />
</Spin>
</div> </div>
); );
} }
import React, {useState, useEffect} from "react"; import React, {useState, useEffect} from "react";
import { Modal } from "antd"; import { Col, Modal, Row } from "antd";
import useTranslation from "next-translate/useTranslation"; import useTranslation from "next-translate/useTranslation";
import { TranslationFiles } from "@/src/data/core"; import { TranslationFiles } from "@/src/data/core";
...@@ -28,7 +28,7 @@ export default function ShowDetailsPopup({ modalProps, setModalProps }: Props) { ...@@ -28,7 +28,7 @@ export default function ShowDetailsPopup({ modalProps, setModalProps }: Props) {
{variableBinding && {variableBinding &&
variableBinding.map((item: any, index: number) => ( variableBinding.map((item: any, index: number) => (
<div key={index}> <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>
))} ))}
</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 () { websocket.onopen = function () {
console.log("Connected to WebSocket server"); console.log("Connected to WebSocket server");
...@@ -6,6 +6,8 @@ websocket.onopen = function () { ...@@ -6,6 +6,8 @@ websocket.onopen = function () {
websocket.onclose = function () { websocket.onclose = function () {
console.log("Disconnected from WebSocket server"); console.log("Disconnected from WebSocket server");
websocket = null;
}; };
export default websocket; export default websocket;
\ No newline at end of file
...@@ -2133,6 +2133,7 @@ __metadata: ...@@ -2133,6 +2133,7 @@ __metadata:
"@types/react-dom": 18.2.4 "@types/react-dom": 18.2.4
"@types/testing-library__jest-dom": ^5.14.6 "@types/testing-library__jest-dom": ^5.14.6
antd: ^5.5.2 antd: ^5.5.2
axios: ^1.4.0
chart.js: ^4.3.0 chart.js: ^4.3.0
clsx: ^1.2.1 clsx: ^1.2.1
eslint: 8.41.0 eslint: 8.41.0
...@@ -4463,6 +4464,17 @@ __metadata: ...@@ -4463,6 +4464,17 @@ __metadata:
languageName: node languageName: node
linkType: hard 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": "axobject-query@npm:^3.1.1":
version: 3.2.1 version: 3.2.1
resolution: "axobject-query@npm:3.2.1" resolution: "axobject-query@npm:3.2.1"
...@@ -6732,6 +6744,16 @@ __metadata: ...@@ -6732,6 +6744,16 @@ __metadata:
languageName: unknown languageName: unknown
linkType: soft 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": "for-each@npm:^0.3.3":
version: 0.3.3 version: 0.3.3
resolution: "for-each@npm:0.3.3" resolution: "for-each@npm:0.3.3"
...@@ -10275,7 +10297,7 @@ __metadata: ...@@ -10275,7 +10297,7 @@ __metadata:
languageName: node languageName: node
linkType: hard 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 version: 1.1.0
resolution: "proxy-from-env@npm:1.1.0" resolution: "proxy-from-env@npm:1.1.0"
checksum: ed7fcc2ba0a33404958e34d95d18638249a68c430e30fcb6c478497d72739ba64ce9810a24f53a7d921d0c065e5b78e3822759800698167256b04659366ca4d4 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