"use client";
import { useRef, useEffect, useState } from "react";
import mermaid from "mermaid";
import {
Button,
Card,
Chip,
Dialog,
DialogActions,
Tooltip,
DialogContent,
DialogContentText,
DialogTitle,
IconButton,
List,
TextField,
} from "@mui/material";
//Icons
import RefreshIcon from "@mui/icons-material/Refresh";
import ZoomInIcon from "@mui/icons-material/ZoomIn";
import ZoomOutIcon from "@mui/icons-material/ZoomOut";
import FullscreenIcon from "@mui/icons-material/Fullscreen";
import DownloadIcon from "@mui/icons-material/Download";
import ResetIcon from "@mui/icons-material/Autorenew";
import FilterAltIcon from "@mui/icons-material/FilterAlt";
// Custom Components
import { NoDataOverlay } from "../noDataOverlay";
import { LoadingOverlay } from "../join/loadingOverlay";
import { useGetAllEventmessages } from "@/api/eventmessages/eventmessages";
import { mutate } from "swr";
import { extractAllEventMessages, generateMermaidString } from "./helpers";
import CopyToClipboard from "../copy_to_clipboard";
import { formatDateTime, getGroupById } from "@/utils/helpers";
const SequenceDiagram = () => {
const {
data: eventMessagesData,
isLoading: loadingEventMessages,
swrKey: eventMessagesKeyFunc,
} = useGetAllEventmessages();
const mermaidRef: any = useRef(null);
const [scale, setScale] = useState(1);
const [openFilters, setOpenFilters] = useState(false);
const [sequenceNr, setSequenceNr] = useState("");
const hasData = eventMessagesData?.data;
const mermaidString = generateMermaidString(eventMessagesData?.data);
const allEventMessages = extractAllEventMessages(eventMessagesData?.data);
useEffect(() => {
if (!loadingEventMessages && hasData)
mermaid.initialize({
startOnLoad: false,
securityLevel: "loose",
sequence: {
mirrorActors: true,
showSequenceNumbers: true,
},
});
if (mermaidRef.current) {
mermaidRef.current.innerHTML = mermaidString;
mermaid.init(undefined, mermaidRef.current);
}
}, [loadingEventMessages, hasData, mermaidString]);
useEffect(() => {
if (mermaidRef.current) {
const svg = mermaidRef.current.querySelector("svg");
if (svg) {
svg.style.transform = `scale(${scale})`;
svg.style.transformOrigin = "top left";
mermaidRef.current.style.width = `${
svg.getBoundingClientRect().width * scale
}px`;
mermaidRef.current.style.height = `${
svg.getBoundingClientRect().height * scale
}px`;
}
}
}, [scale]);
const onRefresh = () => {
const eventMessagesKey =
typeof eventMessagesKeyFunc === "function"
? eventMessagesKeyFunc()
: eventMessagesKeyFunc;
if (eventMessagesKey) {
mutate(eventMessagesKey);
}
};
const zoomIn = () => {
setScale((scale) => scale * 1.1);
};
const zoomOut = () => {
setScale((scale) => scale / 1.1);
};
const resetZoom = () => {
setScale(1);
};
const viewInFullScreen = () => {
if (mermaidRef.current) {
const svg = mermaidRef.current.querySelector("svg");
const serializer = new XMLSerializer();
const svgBlob = new Blob([serializer.serializeToString(svg)], {
type: "image/svg+xml",
});
const url = URL.createObjectURL(svgBlob);
window.open(url, "_blank");
}
};
const downloadAsPng = () => {
if (mermaidRef.current) {
const svg = mermaidRef.current.querySelector("svg");
const svgData = new XMLSerializer().serializeToString(svg);
// Create a canvas element to convert SVG to PNG
const canvas = document.createElement("canvas");
const svgSize = svg.getBoundingClientRect();
canvas.width = svgSize.width;
canvas.height = svgSize.height;
const ctx = canvas.getContext("2d");
const img = document.createElement("img");
img.onload = () => {
ctx?.drawImage(img, 0, 0);
const pngData = canvas.toDataURL("image/png");
// Trigger download
const link = document.createElement("a");
link.download = "sequence-diagram.png";
link.href = pngData;
link.click();
};
img.src =
"data:image/svg+xml;base64," +
btoa(unescape(encodeURIComponent(svgData)));
}
};
const toggleFilters = () => {
setOpenFilters((prevState) => !prevState);
};
const onSearchBySeqNumber = (e: any) => {
setSequenceNr(e.target.value);
};
const isFilterMatch = (index: number) => {
if (!sequenceNr) return true;
const filterSeqNrInt = parseInt(sequenceNr, 10);
return index + 1 === filterSeqNrInt;
};
if (loadingEventMessages)
return