generated from Luis/nextjs-python-web-template
removed unnecessary style file and ran nix fmt
This commit is contained in:
committed by
Sara Pervana
parent
7b2b675c2c
commit
1db032e932
@@ -1 +1 @@
|
|||||||
<script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>;
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import { useGetAllResolutions } from "@/api/resolution/resolution";
|
|||||||
import { mutate } from "swr";
|
import { mutate } from "swr";
|
||||||
|
|
||||||
export default function DLG() {
|
export default function DLG() {
|
||||||
|
|
||||||
const {
|
const {
|
||||||
data: resolutionData,
|
data: resolutionData,
|
||||||
isLoading: loadingResolutions,
|
isLoading: loadingResolutions,
|
||||||
|
|||||||
@@ -8,8 +8,10 @@ import dynamic from "next/dynamic";
|
|||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
import { mutate } from "swr";
|
import { mutate } from "swr";
|
||||||
|
|
||||||
const NoSSRSequenceDiagram = dynamic(() => import('../../components/sequence_diagram'), { ssr: false })
|
const NoSSRSequenceDiagram = dynamic(
|
||||||
|
() => import("../../components/sequence_diagram"),
|
||||||
|
{ ssr: false },
|
||||||
|
);
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
const { data } = useAppState();
|
const { data } = useAppState();
|
||||||
|
|||||||
@@ -51,7 +51,8 @@ export default function RootLayout({
|
|||||||
<meta name="description" content="Service Aware Networks" />
|
<meta name="description" content="Service Aware Networks" />
|
||||||
<link rel="icon" href="tub-favicon.ico" sizes="any" />
|
<link rel="icon" href="tub-favicon.ico" sizes="any" />
|
||||||
<script type="module">
|
<script type="module">
|
||||||
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs';
|
import mermaid from
|
||||||
|
'https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs';
|
||||||
</script>
|
</script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
|
||||||
<script
|
<script
|
||||||
@@ -81,7 +82,8 @@ export default function RootLayout({
|
|||||||
onClose={() => setShowSidebar(false)}
|
onClose={() => setShowSidebar(false)}
|
||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
className={tw`${!showSidebarDerived && translate
|
className={tw`${
|
||||||
|
!showSidebarDerived && translate
|
||||||
} flex h-full w-full flex-col overflow-y-scroll transition-[margin] duration-150 ease-in-out`}
|
} flex h-full w-full flex-col overflow-y-scroll transition-[margin] duration-150 ease-in-out`}
|
||||||
>
|
>
|
||||||
<div className="grid grid-cols-3">
|
<div className="grid grid-cols-3">
|
||||||
|
|||||||
@@ -1,23 +1,33 @@
|
|||||||
export const generateMermaidString = (data: any) => {
|
export const generateMermaidString = (data: any) => {
|
||||||
|
if (!data || data.length === 0) return "";
|
||||||
if (!data || data.length === 0)
|
|
||||||
return '';
|
|
||||||
|
|
||||||
// Extract unique participants
|
// Extract unique participants
|
||||||
const participants = Array.from(new Set(data.map((item: any) => item.src_did).concat(data.map((item: any) => item.des_did))));
|
const participants = Array.from(
|
||||||
|
new Set(
|
||||||
|
data
|
||||||
|
.map((item: any) => item.src_did)
|
||||||
|
.concat(data.map((item: any) => item.des_did)),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
// Begin the sequence diagram definition
|
// Begin the sequence diagram definition
|
||||||
let mermaidString = "sequenceDiagram\n";
|
let mermaidString = "sequenceDiagram\n";
|
||||||
|
|
||||||
// Add participants to the diagram
|
// Add participants to the diagram
|
||||||
participants.forEach((participant, index) => {
|
participants.forEach((participant, index) => {
|
||||||
mermaidString += ` participant ${String.fromCharCode(65 + index)} as ${participant}\n`;
|
mermaidString += ` participant ${String.fromCharCode(
|
||||||
|
65 + index,
|
||||||
|
)} as ${participant}\n`;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Add messages to the diagram
|
// Add messages to the diagram
|
||||||
data.forEach((item: any, index: number) => {
|
data.forEach((item: any, index: number) => {
|
||||||
const srcParticipant = String.fromCharCode(65 + participants.indexOf(item.src_did));
|
const srcParticipant = String.fromCharCode(
|
||||||
const desParticipant = String.fromCharCode(65 + participants.indexOf(item.des_did));
|
65 + participants.indexOf(item.src_did),
|
||||||
|
);
|
||||||
|
const desParticipant = String.fromCharCode(
|
||||||
|
65 + participants.indexOf(item.des_did),
|
||||||
|
);
|
||||||
const timestamp = new Date(item.timestamp * 1000).toLocaleString(); // Convert Unix timestamp to readable date
|
const timestamp = new Date(item.timestamp * 1000).toLocaleString(); // Convert Unix timestamp to readable date
|
||||||
const message = item.msg.text || `Event message ${index + 1}`;
|
const message = item.msg.text || `Event message ${index + 1}`;
|
||||||
|
|
||||||
@@ -40,94 +50,92 @@ export const generateMermaidString = (data: any) => {
|
|||||||
return mermaidString;
|
return mermaidString;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Dummy Data
|
// Dummy Data
|
||||||
|
|
||||||
export const dataFromBE = [
|
export const dataFromBE = [
|
||||||
{
|
{
|
||||||
"id": 12,
|
id: 12,
|
||||||
"timestamp": 1704892813,
|
timestamp: 1704892813,
|
||||||
"group": 0,
|
group: 0,
|
||||||
"group_id": 12,
|
group_id: 12,
|
||||||
// "group_name": "Data",
|
// "group_name": "Data",
|
||||||
"msg_type": 4,
|
msg_type: 4,
|
||||||
"src_did": "did:sov:test:121",
|
src_did: "did:sov:test:121",
|
||||||
// "src_name": "Entity A",
|
// "src_name": "Entity A",
|
||||||
"des_did": "did:sov:test:120",
|
des_did: "did:sov:test:120",
|
||||||
// "des_name": "Entity B",
|
// "des_name": "Entity B",
|
||||||
"msg": {
|
msg: {
|
||||||
text: 'Hello World'
|
text: "Hello World",
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 60,
|
id: 60,
|
||||||
"timestamp": 1704892823,
|
timestamp: 1704892823,
|
||||||
"group": 1,
|
group: 1,
|
||||||
"group_id": 19,
|
group_id: 19,
|
||||||
"msg_type": 4,
|
msg_type: 4,
|
||||||
"src_did": "did:sov:test:122",
|
src_did: "did:sov:test:122",
|
||||||
"des_did": "did:sov:test:121",
|
des_did: "did:sov:test:121",
|
||||||
"msg": {}
|
msg: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 30162,
|
id: 30162,
|
||||||
"timestamp": 1704892817,
|
timestamp: 1704892817,
|
||||||
"group": 1,
|
group: 1,
|
||||||
"group_id": 53,
|
group_id: 53,
|
||||||
"msg_type": 2,
|
msg_type: 2,
|
||||||
"src_did": "did:sov:test:121",
|
src_did: "did:sov:test:121",
|
||||||
"des_did": "did:sov:test:122",
|
des_did: "did:sov:test:122",
|
||||||
"msg": {}
|
msg: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 63043,
|
id: 63043,
|
||||||
"timestamp": 1704892809,
|
timestamp: 1704892809,
|
||||||
"group": 0,
|
group: 0,
|
||||||
"group_id": 12,
|
group_id: 12,
|
||||||
"msg_type": 3,
|
msg_type: 3,
|
||||||
"src_did": "did:sov:test:121",
|
src_did: "did:sov:test:121",
|
||||||
"des_did": "did:sov:test:120",
|
des_did: "did:sov:test:120",
|
||||||
"msg": {}
|
msg: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 66251,
|
id: 66251,
|
||||||
"timestamp": 1704892805,
|
timestamp: 1704892805,
|
||||||
"group": 0,
|
group: 0,
|
||||||
"group_id": 51,
|
group_id: 51,
|
||||||
"msg_type": 1,
|
msg_type: 1,
|
||||||
"src_did": "did:sov:test:120",
|
src_did: "did:sov:test:120",
|
||||||
"des_did": "did:sov:test:121",
|
des_did: "did:sov:test:121",
|
||||||
"msg": {}
|
msg: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 85434,
|
id: 85434,
|
||||||
"timestamp": 1704892807,
|
timestamp: 1704892807,
|
||||||
"group": 0,
|
group: 0,
|
||||||
"group_id": 51,
|
group_id: 51,
|
||||||
"msg_type": 2,
|
msg_type: 2,
|
||||||
"src_did": "did:sov:test:120",
|
src_did: "did:sov:test:120",
|
||||||
"des_did": "did:sov:test:121",
|
des_did: "did:sov:test:121",
|
||||||
"msg": {}
|
msg: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 124842,
|
id: 124842,
|
||||||
"timestamp": 1704892819,
|
timestamp: 1704892819,
|
||||||
"group": 1,
|
group: 1,
|
||||||
"group_id": 19,
|
group_id: 19,
|
||||||
"msg_type": 3,
|
msg_type: 3,
|
||||||
"src_did": "did:sov:test:122",
|
src_did: "did:sov:test:122",
|
||||||
"des_did": "did:sov:test:121",
|
des_did: "did:sov:test:121",
|
||||||
"msg": {}
|
msg: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 246326,
|
id: 246326,
|
||||||
"timestamp": 1704892815,
|
timestamp: 1704892815,
|
||||||
"group": 1,
|
group: 1,
|
||||||
"group_id": 53,
|
group_id: 53,
|
||||||
"msg_type": 1,
|
msg_type: 1,
|
||||||
"src_did": "did:sov:test:121",
|
src_did: "did:sov:test:121",
|
||||||
"des_did": "did:sov:test:122",
|
des_did: "did:sov:test:122",
|
||||||
"msg": {}
|
msg: {},
|
||||||
}
|
},
|
||||||
]
|
];
|
||||||
|
|||||||
@@ -1,23 +1,22 @@
|
|||||||
'use client';
|
"use client";
|
||||||
|
|
||||||
import { useRef, useEffect, useState } from 'react';
|
import { useRef, useEffect, useState } from "react";
|
||||||
import mermaid from 'mermaid';
|
import mermaid from "mermaid";
|
||||||
import { IconButton } from '@mui/material';
|
import { IconButton } from "@mui/material";
|
||||||
import RefreshIcon from '@mui/icons-material/Refresh';
|
import RefreshIcon from "@mui/icons-material/Refresh";
|
||||||
import ZoomInIcon from '@mui/icons-material/ZoomIn';
|
import ZoomInIcon from "@mui/icons-material/ZoomIn";
|
||||||
import ZoomOutIcon from '@mui/icons-material/ZoomOut';
|
import ZoomOutIcon from "@mui/icons-material/ZoomOut";
|
||||||
import FullscreenIcon from '@mui/icons-material/Fullscreen';
|
import FullscreenIcon from "@mui/icons-material/Fullscreen";
|
||||||
import DownloadIcon from '@mui/icons-material/Download';
|
import DownloadIcon from "@mui/icons-material/Download";
|
||||||
import ResetIcon from '@mui/icons-material/Autorenew';
|
import ResetIcon from "@mui/icons-material/Autorenew";
|
||||||
import Tooltip from '@mui/material/Tooltip';
|
import Tooltip from "@mui/material/Tooltip";
|
||||||
import { NoDataOverlay } from '../noDataOverlay';
|
import { NoDataOverlay } from "../noDataOverlay";
|
||||||
import { useGetAllEventmessages } from '@/api/eventmessages/eventmessages';
|
import { useGetAllEventmessages } from "@/api/eventmessages/eventmessages";
|
||||||
import { mutate } from 'swr';
|
import { mutate } from "swr";
|
||||||
import { LoadingOverlay } from '../join/loadingOverlay';
|
import { LoadingOverlay } from "../join/loadingOverlay";
|
||||||
import { generateMermaidString, dataFromBE } from './helpers';
|
import { generateMermaidString, dataFromBE } from "./helpers";
|
||||||
|
|
||||||
const SequenceDiagram = () => {
|
const SequenceDiagram = () => {
|
||||||
|
|
||||||
const {
|
const {
|
||||||
data: eventMessagesData,
|
data: eventMessagesData,
|
||||||
isLoading: loadingEventMessages,
|
isLoading: loadingEventMessages,
|
||||||
@@ -31,11 +30,10 @@ const SequenceDiagram = () => {
|
|||||||
const mermaidString = generateMermaidString(eventMessagesData?.data);
|
const mermaidString = generateMermaidString(eventMessagesData?.data);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
||||||
if (!loadingEventMessages && hasData)
|
if (!loadingEventMessages && hasData)
|
||||||
mermaid.initialize({
|
mermaid.initialize({
|
||||||
startOnLoad: false,
|
startOnLoad: false,
|
||||||
securityLevel: 'loose',
|
securityLevel: "loose",
|
||||||
sequence: {
|
sequence: {
|
||||||
mirrorActors: false,
|
mirrorActors: false,
|
||||||
},
|
},
|
||||||
@@ -49,17 +47,20 @@ const SequenceDiagram = () => {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (mermaidRef.current) {
|
if (mermaidRef.current) {
|
||||||
const svg = mermaidRef.current.querySelector('svg');
|
const svg = mermaidRef.current.querySelector("svg");
|
||||||
if (svg) {
|
if (svg) {
|
||||||
svg.style.transform = `scale(${scale})`;
|
svg.style.transform = `scale(${scale})`;
|
||||||
svg.style.transformOrigin = 'top left'; // Set transform origin to top left
|
svg.style.transformOrigin = "top left"; // Set transform origin to top left
|
||||||
mermaidRef.current.style.width = `${svg.getBoundingClientRect().width * scale}px`;
|
mermaidRef.current.style.width = `${
|
||||||
mermaidRef.current.style.height = `${svg.getBoundingClientRect().height * scale}px`;
|
svg.getBoundingClientRect().width * scale
|
||||||
|
}px`;
|
||||||
|
mermaidRef.current.style.height = `${
|
||||||
|
svg.getBoundingClientRect().height * scale
|
||||||
|
}px`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [scale]);
|
}, [scale]);
|
||||||
|
|
||||||
|
|
||||||
const onRefresh = () => {
|
const onRefresh = () => {
|
||||||
const eventMessagesKey =
|
const eventMessagesKey =
|
||||||
typeof eventMessagesKeyFunc === "function"
|
typeof eventMessagesKeyFunc === "function"
|
||||||
@@ -85,94 +86,96 @@ const SequenceDiagram = () => {
|
|||||||
|
|
||||||
const viewInFullScreen = () => {
|
const viewInFullScreen = () => {
|
||||||
if (mermaidRef.current) {
|
if (mermaidRef.current) {
|
||||||
const svg = mermaidRef.current.querySelector('svg');
|
const svg = mermaidRef.current.querySelector("svg");
|
||||||
const serializer = new XMLSerializer();
|
const serializer = new XMLSerializer();
|
||||||
const svgBlob = new Blob([serializer.serializeToString(svg)], {
|
const svgBlob = new Blob([serializer.serializeToString(svg)], {
|
||||||
type: 'image/svg+xml',
|
type: "image/svg+xml",
|
||||||
});
|
});
|
||||||
const url = URL.createObjectURL(svgBlob);
|
const url = URL.createObjectURL(svgBlob);
|
||||||
window.open(url, '_blank');
|
window.open(url, "_blank");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const downloadAsPng = () => {
|
const downloadAsPng = () => {
|
||||||
if (mermaidRef.current) {
|
if (mermaidRef.current) {
|
||||||
const svg = mermaidRef.current.querySelector('svg');
|
const svg = mermaidRef.current.querySelector("svg");
|
||||||
const svgData = new XMLSerializer().serializeToString(svg);
|
const svgData = new XMLSerializer().serializeToString(svg);
|
||||||
|
|
||||||
// Create a canvas element to convert SVG to PNG
|
// Create a canvas element to convert SVG to PNG
|
||||||
const canvas = document.createElement('canvas');
|
const canvas = document.createElement("canvas");
|
||||||
const svgSize = svg.getBoundingClientRect();
|
const svgSize = svg.getBoundingClientRect();
|
||||||
canvas.width = svgSize.width;
|
canvas.width = svgSize.width;
|
||||||
canvas.height = svgSize.height;
|
canvas.height = svgSize.height;
|
||||||
const ctx = canvas.getContext('2d');
|
const ctx = canvas.getContext("2d");
|
||||||
const img = document.createElement('img');
|
const img = document.createElement("img");
|
||||||
|
|
||||||
img.onload = () => {
|
img.onload = () => {
|
||||||
ctx?.drawImage(img, 0, 0);
|
ctx?.drawImage(img, 0, 0);
|
||||||
const pngData = canvas.toDataURL('image/png');
|
const pngData = canvas.toDataURL("image/png");
|
||||||
|
|
||||||
// Trigger download
|
// Trigger download
|
||||||
const link = document.createElement('a');
|
const link = document.createElement("a");
|
||||||
link.download = 'sequence-diagram.png';
|
link.download = "sequence-diagram.png";
|
||||||
link.href = pngData;
|
link.href = pngData;
|
||||||
link.click();
|
link.click();
|
||||||
};
|
};
|
||||||
|
|
||||||
img.src =
|
img.src =
|
||||||
'data:image/svg+xml;base64,' +
|
"data:image/svg+xml;base64," +
|
||||||
btoa(unescape(encodeURIComponent(svgData)));
|
btoa(unescape(encodeURIComponent(svgData)));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (loadingEventMessages)
|
if (loadingEventMessages)
|
||||||
return <LoadingOverlay title="Loading Diagram" subtitle="Please wait..." />
|
return <LoadingOverlay title="Loading Diagram" subtitle="Please wait..." />;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col items-end w-full">
|
<div className="flex flex-col items-end w-full">
|
||||||
{
|
{hasData ? (
|
||||||
hasData ? <>
|
<>
|
||||||
<div className='flex justify-end gap-2.5 mb-5 w-full'>
|
<div className="flex justify-end gap-2.5 mb-5 w-full">
|
||||||
<Tooltip placement='top' title='Refresh Diagram'>
|
<Tooltip placement="top" title="Refresh Diagram">
|
||||||
<IconButton color="default" onClick={onRefresh}>
|
<IconButton color="default" onClick={onRefresh}>
|
||||||
<RefreshIcon />
|
<RefreshIcon />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Tooltip title="Zoom In" placement='top'>
|
<Tooltip title="Zoom In" placement="top">
|
||||||
<IconButton color="primary" onClick={zoomIn}>
|
<IconButton color="primary" onClick={zoomIn}>
|
||||||
<ZoomInIcon />
|
<ZoomInIcon />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Tooltip title="Zoom Out" placement='top'>
|
<Tooltip title="Zoom Out" placement="top">
|
||||||
<IconButton color="primary" onClick={zoomOut}>
|
<IconButton color="primary" onClick={zoomOut}>
|
||||||
<ZoomOutIcon />
|
<ZoomOutIcon />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Tooltip title="Reset" placement='top'>
|
<Tooltip title="Reset" placement="top">
|
||||||
<IconButton color="primary" onClick={resetZoom}>
|
<IconButton color="primary" onClick={resetZoom}>
|
||||||
<ResetIcon />
|
<ResetIcon />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Tooltip title="View in Fullscreen" placement='top'>
|
<Tooltip title="View in Fullscreen" placement="top">
|
||||||
<IconButton color="primary" onClick={viewInFullScreen}>
|
<IconButton color="primary" onClick={viewInFullScreen}>
|
||||||
<FullscreenIcon />
|
<FullscreenIcon />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Tooltip title="Download as PNG" placement='top'>
|
<Tooltip title="Download as PNG" placement="top">
|
||||||
<IconButton color="primary" onClick={downloadAsPng}>
|
<IconButton color="primary" onClick={downloadAsPng}>
|
||||||
<DownloadIcon />
|
<DownloadIcon />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full h-500 overflow-auto p-2.5 box-border h-full">
|
<div className="w-full h-500 overflow-auto p-2.5 box-border h-full">
|
||||||
<div className='mermaid' ref={mermaidRef}></div>
|
<div className="mermaid" ref={mermaidRef}></div>
|
||||||
</div>
|
</div>
|
||||||
</> : <div className="flex justify-center items-center w-full h-500">
|
</>
|
||||||
|
) : (
|
||||||
|
<div className="flex justify-center items-center w-full h-500">
|
||||||
<NoDataOverlay label="No Activity yet" />
|
<NoDataOverlay label="No Activity yet" />
|
||||||
</div>
|
</div>
|
||||||
}
|
)}
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
export default SequenceDiagram;
|
export default SequenceDiagram;
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
.container {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: flex-end;
|
|
||||||
}
|
|
||||||
|
|
||||||
.buttons-container {
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-end;
|
|
||||||
gap: 10px;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.diagram-container {
|
|
||||||
width: 100%;
|
|
||||||
height: 500px;
|
|
||||||
overflow: auto;
|
|
||||||
border: 1px solid #ddd;
|
|
||||||
padding: 10px;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user