generated from Luis/nextjs-python-web-template
current progress with diagram and project fixes
This commit is contained in:
committed by
Sara Pervana
parent
60205b3c22
commit
c03da10e98
@@ -1,136 +1,276 @@
|
||||
import { Eventmessage } from "@/api/model";
|
||||
|
||||
export const generateMermaidString = (data: Eventmessage[] | undefined) => {
|
||||
if (!data || data.length === 0) return "";
|
||||
if (!data) return "";
|
||||
|
||||
const participants = Array.from(
|
||||
new Set(data.flatMap((item) => [item.src_did, item.des_did])),
|
||||
);
|
||||
let mermaidString = "";
|
||||
|
||||
let mermaidString = "sequenceDiagram\n";
|
||||
// We'll use a Set to ensure participant uniqueness
|
||||
const participants: Set<string> = new Set();
|
||||
|
||||
participants.forEach((participant, index) => {
|
||||
mermaidString += ` participant ${String.fromCharCode(
|
||||
65 + index,
|
||||
)} as ${participant}\n`;
|
||||
});
|
||||
// Define colors for groups (if you have more groups, add more colors)
|
||||
const groupColors: Record<number, string> = {
|
||||
0: "rgb(191, 223, 255)",
|
||||
1: "rgb(200, 150, 255)",
|
||||
// Add more group colors if needed
|
||||
};
|
||||
|
||||
let currentGroupId: number | null = null;
|
||||
// Loop through the groups and group_ids to build the string
|
||||
Object.entries(data).forEach(([group, groupData]) => {
|
||||
// Add a rectangle for each group with a note
|
||||
mermaidString += ` rect ${
|
||||
groupColors[parseInt(group)] || "rgb(128, 128, 128)"
|
||||
}\n`; // Fallback color if not defined
|
||||
mermaidString += ` Note over ${Object.values(groupData)
|
||||
.flatMap((gd) => gd.map((msg: any) => msg.src_name))
|
||||
.join(",")}: Group ${group}\n`;
|
||||
|
||||
data.forEach((item, index) => {
|
||||
const srcParticipant = String.fromCharCode(
|
||||
65 + participants.indexOf(item.src_did),
|
||||
);
|
||||
const desParticipant = String.fromCharCode(
|
||||
65 + participants.indexOf(item.des_did),
|
||||
);
|
||||
const timestamp = new Date(item.timestamp * 1000).toLocaleString();
|
||||
const message = item.msg.text || `Event message ${index + 1}`;
|
||||
Object.entries(groupData).forEach(([groupId, messages]) => {
|
||||
// Add a rectangle for each group_id with a note
|
||||
mermaidString += ` alt Group ID ${groupId}\n`;
|
||||
|
||||
if (item.group_id !== currentGroupId) {
|
||||
if (currentGroupId !== null) {
|
||||
mermaidString += ` end\n`;
|
||||
}
|
||||
mermaidString += ` alt Group ${item.group_id}\n`;
|
||||
currentGroupId = item.group_id;
|
||||
}
|
||||
messages.forEach((msg: any) => {
|
||||
// Ensure we include each participant
|
||||
participants.add(msg.src_name);
|
||||
participants.add(msg.des_name);
|
||||
|
||||
mermaidString += ` ${srcParticipant}->>${desParticipant}: [${timestamp}] ${message}\n`;
|
||||
});
|
||||
// Add each message
|
||||
mermaidString += ` ${msg.src_name}->>${msg.des_name}: [${msg.msg_type_name}]: Event Message ${msg.id}\n`;
|
||||
});
|
||||
|
||||
mermaidString += ` end\n`;
|
||||
});
|
||||
|
||||
if (currentGroupId !== null) {
|
||||
mermaidString += ` end\n`;
|
||||
}
|
||||
});
|
||||
|
||||
// Add participants at the start of the string
|
||||
const participantString = Array.from(participants)
|
||||
.map((participant) => {
|
||||
return ` participant ${participant}\n`;
|
||||
})
|
||||
.join("");
|
||||
|
||||
// Prepend participants to the mermaidString
|
||||
mermaidString = `sequenceDiagram\n${participantString}` + mermaidString;
|
||||
|
||||
return mermaidString;
|
||||
};
|
||||
|
||||
// Dummy Data
|
||||
export const mermaidSample = `
|
||||
sequenceDiagram
|
||||
participant C0 as C0 <br/>did:sov:test:120
|
||||
participant C1 as C1 <br/>did:sov:test:121
|
||||
participant C2 as C2 <br/>did:sov:test:122
|
||||
|
||||
export const dataFromBE = [
|
||||
rect rgb(255, 154, 162)
|
||||
Note over C0,C1 : Group 0
|
||||
alt Group Id 16
|
||||
C1->>C0: [Presentation]: Event Message 1
|
||||
C1->>C0: [DID Resolution]: Event Message 2
|
||||
end
|
||||
|
||||
alt Group Id 51
|
||||
C0->>C1: [Attachement]: Event Message 3
|
||||
C0->>C1: [Connection Setup]: Event Message 4
|
||||
end
|
||||
end
|
||||
|
||||
rect rgb(254, 183, 177)
|
||||
Note over C1,C2 : Group 1
|
||||
alt Group Id 13
|
||||
C2->>C1: [Presentation]: Event Message 5
|
||||
C2->>C1: [DID Resolution]: Event Message 6
|
||||
end
|
||||
|
||||
alt Group Id 21
|
||||
C1->>C2: [Attachement]: Event Message 7
|
||||
C1->>C2: [Connection Setup]: Event Message 8
|
||||
end
|
||||
end
|
||||
|
||||
rect rgb(255, 218, 192)
|
||||
Note over C0,C1 : Group 0
|
||||
alt Group Id 16
|
||||
C1->>C0: [Presentation]: Event Message 1
|
||||
C1->>C0: [DID Resolution]: Event Message 2
|
||||
end
|
||||
|
||||
alt Group Id 51
|
||||
C0->>C1: [Attachement]: Event Message 3
|
||||
C0->>C1: [Connection Setup]: Event Message 4
|
||||
end
|
||||
end
|
||||
|
||||
rect rgb(255, 236, 196)
|
||||
Note over C1,C2 : Group 1
|
||||
alt Group Id 13
|
||||
C2->>C1: [Presentation]: Event Message 5
|
||||
C2->>C1: [DID Resolution]: Event Message 6
|
||||
end
|
||||
|
||||
alt Group Id 21
|
||||
C1->>C2: [Attachement]: Event Message 7
|
||||
C1->>C2: [Connection Setup]: Event Message 8
|
||||
end
|
||||
end
|
||||
|
||||
rect rgb(226, 240, 204)
|
||||
Note over C0,C1 : Group 0
|
||||
alt Group Id 16
|
||||
C1->>C0: [Presentation]: Event Message 1
|
||||
C1->>C0: [DID Resolution]: Event Message 2
|
||||
end
|
||||
|
||||
alt Group Id 51
|
||||
C0->>C1: [Attachement]: Event Message 3
|
||||
C0->>C1: [Connection Setup]: Event Message 4
|
||||
end
|
||||
end
|
||||
|
||||
rect rgb(181, 234, 214)
|
||||
Note over C1,C2 : Group 1
|
||||
alt Group Id 13
|
||||
C2->>C1: [Presentation]: Event Message 5
|
||||
C2->>C1: [DID Resolution]: Event Message 6
|
||||
end
|
||||
|
||||
alt Group Id 21
|
||||
C1->>C2: [Attachement]: Event Message 7
|
||||
C1->>C2: [Connection Setup]: Event Message 8
|
||||
end
|
||||
end
|
||||
|
||||
rect rgb(183, 219, 235)
|
||||
Note over C0,C1 : Group 0
|
||||
alt Group Id 16
|
||||
C1->>C0: [Presentation]: Event Message 1
|
||||
C1->>C0: [DID Resolution]: Event Message 2
|
||||
end
|
||||
|
||||
alt Group Id 51
|
||||
C0->>C1: [Attachement]: Event Message 3
|
||||
C0->>C1: [Connection Setup]: Event Message 4
|
||||
end
|
||||
end
|
||||
|
||||
rect rgb(199, 206, 234)
|
||||
Note over C1,C2 : Group 1
|
||||
alt Group Id 13
|
||||
C2->>C1: [Presentation]: Event Message 5
|
||||
C2->>C1: [DID Resolution]: Event Message 6
|
||||
end
|
||||
|
||||
alt Group Id 21
|
||||
C1->>C2: [Attachement]: Event Message 7
|
||||
C1->>C2: [Connection Setup]: Event Message 8
|
||||
end
|
||||
end
|
||||
`;
|
||||
|
||||
export const eventMessages = [
|
||||
{
|
||||
id: 12,
|
||||
timestamp: 1704892813,
|
||||
timestamp: 1706034368,
|
||||
group: 0,
|
||||
group_id: 12,
|
||||
// "group_name": "Data",
|
||||
msg_type: 4,
|
||||
src_did: "did:sov:test:121",
|
||||
// "src_name": "Entity A",
|
||||
des_did: "did:sov:test:120",
|
||||
// "des_name": "Entity B",
|
||||
msg: {
|
||||
text: "Hello World",
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 60,
|
||||
timestamp: 1704892823,
|
||||
group: 1,
|
||||
group_id: 19,
|
||||
msg_type: 4,
|
||||
src_did: "did:sov:test:122",
|
||||
des_did: "did:sov:test:121",
|
||||
msg: {},
|
||||
},
|
||||
{
|
||||
id: 30162,
|
||||
timestamp: 1704892817,
|
||||
group: 1,
|
||||
group_id: 53,
|
||||
msg_type: 2,
|
||||
src_did: "did:sov:test:121",
|
||||
des_did: "did:sov:test:122",
|
||||
msg: {},
|
||||
},
|
||||
{
|
||||
id: 63043,
|
||||
timestamp: 1704892809,
|
||||
group: 0,
|
||||
group_id: 12,
|
||||
group_id: 16,
|
||||
msg_type: 3,
|
||||
src_did: "did:sov:test:121",
|
||||
des_did: "did:sov:test:120",
|
||||
msg: {},
|
||||
id: 3,
|
||||
des_name: "C0",
|
||||
src_name: "C1",
|
||||
msg_type_name: "Presentation",
|
||||
},
|
||||
{
|
||||
id: 66251,
|
||||
timestamp: 1704892805,
|
||||
timestamp: 1706034372,
|
||||
group: 0,
|
||||
group_id: 16,
|
||||
msg_type: 4,
|
||||
src_did: "did:sov:test:121",
|
||||
des_did: "did:sov:test:120",
|
||||
msg: {},
|
||||
id: 4,
|
||||
des_name: "C0",
|
||||
src_name: "C1",
|
||||
msg_type_name: "DID Resolution",
|
||||
},
|
||||
{
|
||||
timestamp: 1706034364,
|
||||
group: 0,
|
||||
group_id: 51,
|
||||
msg_type: 1,
|
||||
src_did: "did:sov:test:120",
|
||||
des_did: "did:sov:test:121",
|
||||
msg: {},
|
||||
id: 1,
|
||||
des_name: "C1",
|
||||
src_name: "C0",
|
||||
msg_type_name: "Attachement",
|
||||
},
|
||||
{
|
||||
id: 85434,
|
||||
timestamp: 1704892807,
|
||||
timestamp: 1706034366,
|
||||
group: 0,
|
||||
group_id: 51,
|
||||
msg_type: 2,
|
||||
src_did: "did:sov:test:120",
|
||||
des_did: "did:sov:test:121",
|
||||
msg: {},
|
||||
id: 2,
|
||||
des_name: "C1",
|
||||
src_name: "C0",
|
||||
msg_type_name: "Connection Setup",
|
||||
},
|
||||
{
|
||||
id: 124842,
|
||||
timestamp: 1704892819,
|
||||
timestamp: 1706034378,
|
||||
group: 1,
|
||||
group_id: 19,
|
||||
group_id: 13,
|
||||
msg_type: 3,
|
||||
src_did: "did:sov:test:122",
|
||||
des_did: "did:sov:test:121",
|
||||
msg: {},
|
||||
id: 7,
|
||||
des_name: "C1",
|
||||
src_name: "C2",
|
||||
msg_type_name: "Presentation",
|
||||
},
|
||||
{
|
||||
id: 246326,
|
||||
timestamp: 1704892815,
|
||||
timestamp: 1706034382,
|
||||
group: 1,
|
||||
group_id: 53,
|
||||
group_id: 13,
|
||||
msg_type: 4,
|
||||
src_did: "did:sov:test:122",
|
||||
des_did: "did:sov:test:121",
|
||||
msg: {},
|
||||
id: 8,
|
||||
des_name: "C1",
|
||||
src_name: "C2",
|
||||
msg_type_name: "DID Resolution",
|
||||
},
|
||||
{
|
||||
timestamp: 1706034374,
|
||||
group: 1,
|
||||
group_id: 21,
|
||||
msg_type: 1,
|
||||
src_did: "did:sov:test:121",
|
||||
des_did: "did:sov:test:122",
|
||||
msg: {},
|
||||
id: 5,
|
||||
des_name: "C2",
|
||||
src_name: "C1",
|
||||
msg_type_name: "Attachement",
|
||||
},
|
||||
{
|
||||
timestamp: 1706034376,
|
||||
group: 1,
|
||||
group_id: 21,
|
||||
msg_type: 2,
|
||||
src_did: "did:sov:test:121",
|
||||
des_did: "did:sov:test:122",
|
||||
msg: {},
|
||||
id: 6,
|
||||
des_name: "C2",
|
||||
src_name: "C1",
|
||||
msg_type_name: "Connection Setup",
|
||||
},
|
||||
];
|
||||
|
||||
@@ -2,32 +2,59 @@
|
||||
|
||||
import { useRef, useEffect, useState } from "react";
|
||||
import mermaid from "mermaid";
|
||||
import { IconButton } from "@mui/material";
|
||||
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 Tooltip from "@mui/material/Tooltip";
|
||||
import FilterAltIcon from "@mui/icons-material/FilterAlt";
|
||||
import ContentCopyIcon from "@mui/icons-material/ContentCopy";
|
||||
|
||||
// Custom Components
|
||||
import { NoDataOverlay } from "../noDataOverlay";
|
||||
import { LoadingOverlay } from "../join/loadingOverlay";
|
||||
|
||||
import { useGetAllEventmessages } from "@/api/eventmessages/eventmessages";
|
||||
import { mutate } from "swr";
|
||||
import { LoadingOverlay } from "../join/loadingOverlay";
|
||||
//import { generateMermaidString } from "./helpers";
|
||||
|
||||
import { eventMessages, generateMermaidString, mermaidSample } from "./helpers";
|
||||
import { iconMatch } from "@/config/config";
|
||||
import CopyToClipboard from "../copy_to_clipboard";
|
||||
import { formatDateTime } from "@/utils/helpers";
|
||||
|
||||
const SequenceDiagram = () => {
|
||||
const {
|
||||
// data: eventMessagesData,
|
||||
data: eventMessagesData,
|
||||
isLoading: loadingEventMessages,
|
||||
swrKey: eventMessagesKeyFunc,
|
||||
} = useGetAllEventmessages();
|
||||
|
||||
const mermaidRef: any = useRef(null);
|
||||
const [scale, setScale] = useState(1);
|
||||
const hasData = false; // TODO: Readd this, right now it's always false
|
||||
const [openFilters, setOpenFilters] = useState(false);
|
||||
|
||||
const mermaidString = ""; //generateMermaidString(eventMessagesData?.data);
|
||||
const [sequenceNr, setSequenceNr] = useState("");
|
||||
const hasData = eventMessagesData?.data;
|
||||
|
||||
// const mermaidString = generateMermaidString(eventMessagesData?.data);
|
||||
|
||||
const mermaidString = mermaidSample;
|
||||
|
||||
useEffect(() => {
|
||||
if (!loadingEventMessages && hasData)
|
||||
@@ -35,7 +62,8 @@ const SequenceDiagram = () => {
|
||||
startOnLoad: false,
|
||||
securityLevel: "loose",
|
||||
sequence: {
|
||||
mirrorActors: false,
|
||||
mirrorActors: true,
|
||||
showSequenceNumbers: true,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -126,55 +154,177 @@ const SequenceDiagram = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const toggleFilters = () => {
|
||||
setOpenFilters((prevState) => !prevState);
|
||||
};
|
||||
|
||||
const onSearchBySeqNumber = (e: any) => {
|
||||
setSequenceNr(e.target.value);
|
||||
};
|
||||
|
||||
const copyToClipboard = (data: any) => {
|
||||
navigator.clipboard.writeText(JSON.stringify(data, null, 2)).then(() => {
|
||||
alert("JSON copied to clipboard!");
|
||||
});
|
||||
};
|
||||
|
||||
const isFilterMatch = (index: number) => {
|
||||
if (!sequenceNr) return true;
|
||||
|
||||
const filterSeqNrInt = parseInt(sequenceNr, 10);
|
||||
return index + 1 === filterSeqNrInt;
|
||||
};
|
||||
|
||||
if (loadingEventMessages)
|
||||
return <LoadingOverlay title="Loading Diagram" subtitle="Please wait..." />;
|
||||
|
||||
return (
|
||||
<div className="flex flex-col items-end">
|
||||
{hasData ? (
|
||||
<>
|
||||
<div className="flex flex-col items-end">
|
||||
{hasData ? (
|
||||
<>
|
||||
<div className="flex justify-end">
|
||||
<Tooltip placement="top" title="Filter Messages">
|
||||
<IconButton color="primary" onClick={toggleFilters}>
|
||||
<FilterAltIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<Tooltip placement="top" title="Refresh Diagram">
|
||||
<IconButton color="primary" onClick={onRefresh}>
|
||||
<RefreshIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<Tooltip title="Zoom In" placement="top">
|
||||
<IconButton color="primary" onClick={zoomIn}>
|
||||
<ZoomInIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<Tooltip title="Zoom Out" placement="top">
|
||||
<IconButton color="primary" onClick={zoomOut}>
|
||||
<ZoomOutIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<Tooltip title="Reset" placement="top">
|
||||
<IconButton color="primary" onClick={resetZoom}>
|
||||
<ResetIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<Tooltip title="View in Fullscreen" placement="top">
|
||||
<IconButton color="primary" onClick={viewInFullScreen}>
|
||||
<FullscreenIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<Tooltip title="Download as PNG" placement="top">
|
||||
<IconButton color="primary" onClick={downloadAsPng}>
|
||||
<DownloadIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div className="w-full p-2.5">
|
||||
<div className="mermaid" ref={mermaidRef}></div>
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<div className="flex w-full justify-center">
|
||||
<NoDataOverlay label="No Activity yet" />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{openFilters && (
|
||||
<>
|
||||
<div className="flex justify-end">
|
||||
<Tooltip placement="top" title="Refresh Diagram">
|
||||
<IconButton color="default" onClick={onRefresh}>
|
||||
<RefreshIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<Tooltip title="Zoom In" placement="top">
|
||||
<IconButton color="primary" onClick={zoomIn}>
|
||||
<ZoomInIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<Tooltip title="Zoom Out" placement="top">
|
||||
<IconButton color="primary" onClick={zoomOut}>
|
||||
<ZoomOutIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<Tooltip title="Reset" placement="top">
|
||||
<IconButton color="primary" onClick={resetZoom}>
|
||||
<ResetIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<Tooltip title="View in Fullscreen" placement="top">
|
||||
<IconButton color="primary" onClick={viewInFullScreen}>
|
||||
<FullscreenIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<Tooltip title="Download as PNG" placement="top">
|
||||
<IconButton color="primary" onClick={downloadAsPng}>
|
||||
<DownloadIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div className="w-full p-2.5">
|
||||
<div className="mermaid" ref={mermaidRef}></div>
|
||||
</div>
|
||||
<Dialog
|
||||
open={openFilters}
|
||||
keepMounted
|
||||
fullWidth
|
||||
maxWidth="lg"
|
||||
onClose={toggleFilters}
|
||||
>
|
||||
<DialogTitle>All Event Messages</DialogTitle>
|
||||
<DialogContent>
|
||||
<DialogContentText>
|
||||
<div className="flex items-center gap-2.5">
|
||||
<label>Search by Sequence # </label>
|
||||
<TextField
|
||||
onChange={onSearchBySeqNumber}
|
||||
size="small"
|
||||
variant="outlined"
|
||||
/>
|
||||
</div>
|
||||
<List className="w-full" component="nav">
|
||||
{eventMessages
|
||||
.filter((_: any, index: number) => {
|
||||
return isFilterMatch(index);
|
||||
})
|
||||
.map((message: any, index: number) => {
|
||||
const {
|
||||
msg_type_name: msgType,
|
||||
des_name,
|
||||
src_name,
|
||||
group,
|
||||
group_id,
|
||||
timestamp,
|
||||
src_did,
|
||||
des_did,
|
||||
msg,
|
||||
} = message;
|
||||
|
||||
const formattedTimeStamp = formatDateTime(timestamp);
|
||||
const IconComponent = iconMatch[msgType];
|
||||
return (
|
||||
<div className="flex items-center gap-5 mb-7">
|
||||
<Chip label={sequenceNr ? sequenceNr : ++index} />
|
||||
<Card className="w-full p-2">
|
||||
<div className="flex justify-between">
|
||||
<div>
|
||||
<span className="font-bold flex gap-2">
|
||||
{IconComponent} {message.msg_type_name}
|
||||
</span>
|
||||
<span>
|
||||
Sender: {src_name} <Chip label={src_did} /> |{" "}
|
||||
</span>
|
||||
<span>
|
||||
Receiver: {des_name} <Chip label={des_did} />{" "}
|
||||
|{" "}
|
||||
</span>
|
||||
<span>Group: {group} | </span>
|
||||
<span>Group ID: {group_id}</span>
|
||||
</div>
|
||||
<span>{formattedTimeStamp}</span>
|
||||
</div>
|
||||
<span className="font-bold">
|
||||
Event Message {sequenceNr ? sequenceNr : index++}
|
||||
</span>
|
||||
<div
|
||||
className="flex"
|
||||
style={{
|
||||
border: "1px solid #f1f1f1",
|
||||
borderRadius: 5,
|
||||
}}
|
||||
>
|
||||
<pre className="flex-1 p-2">
|
||||
{JSON.stringify(message, null, 2)}
|
||||
</pre>
|
||||
<div className="flex-shrink-0 p-2">
|
||||
<CopyToClipboard textToCopy={message} />
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</List>
|
||||
</DialogContentText>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button variant="contained" onClick={toggleFilters}>
|
||||
Close
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
</>
|
||||
) : (
|
||||
<div className="flex w-full justify-center">
|
||||
<NoDataOverlay label="No Activity yet" />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user