From 0a46ef8546438983d814e981570c37ab8764af82 Mon Sep 17 00:00:00 2001 From: Cheithanya Date: Fri, 3 Nov 2023 14:22:44 +0530 Subject: [PATCH 01/19] nov 3 2023 --- backend/deployments/workflow1/deployment.js | 1 + backend/middelware.js | 737 +++++++++++++++++- backend/server.js | 5 +- frontend/src/InvocationsPage.js | 8 +- frontend/src/index.js | 2 + frontend/src/scenes/bar/Bar.jsx | 106 +++ frontend/src/scenes/bar/index.jsx | 15 - .../src/scenes/invocations/Invocation.jsx | 215 ++--- .../scenes/invocations/InvocationDetails.jsx | 258 ++++++ frontend/src/scenes/line/Line.jsx | 112 +++ frontend/src/scenes/line/index.jsx | 17 - 11 files changed, 1338 insertions(+), 138 deletions(-) create mode 100644 frontend/src/scenes/bar/Bar.jsx delete mode 100644 frontend/src/scenes/bar/index.jsx create mode 100644 frontend/src/scenes/invocations/InvocationDetails.jsx create mode 100644 frontend/src/scenes/line/Line.jsx delete mode 100644 frontend/src/scenes/line/index.jsx diff --git a/backend/deployments/workflow1/deployment.js b/backend/deployments/workflow1/deployment.js index 28f097d..cbfc988 100644 --- a/backend/deployments/workflow1/deployment.js +++ b/backend/deployments/workflow1/deployment.js @@ -403,6 +403,7 @@ const refractored=[{ "original_func_ids": ["zxd0", "rysh", "37u3"] } ], + "wf_partitions": [ { "partition_label": "label for datacentre", diff --git a/backend/middelware.js b/backend/middelware.js index 4c9e3b9..7e3799f 100644 --- a/backend/middelware.js +++ b/backend/middelware.js @@ -476,4 +476,739 @@ var output2 = input.map(obj => { }); console.log(JSON.stringify(output2, null, 2)); - \ No newline at end of file + + +// +var inp={ + "WorkflowOwner": "String", + "Workflow Id": "uuid", + "Refactored Workflow Id": "82097845-56fb-48ec-8bcd-3f1ab70c46c1", + "WorkflowName": "ImgProcessingFanoutMulticloudAWSToAzure", + "WorkflowDescription": "String", + "WorkflowVersion": "String", + "refactoring_strategy": "", + "PackageUrl": "String", + "wf_fusion_config": [ + { + "fused_func_id": "3ycp", + "original_func_ids": ["zxd0", "rysh", "37u3"] + } + ], + "wf_partitions": [ + { + "partition_label": "label for datacentre", + "func_ids": ["zxd0", "rysh", "37u3"] + } + ], + "Nodes": [ + { + "NodeId": "fm9m", + "ModuleName": "String", + "NodeName": "Resize", + "Path": "examples/image-processing-diamond-multicloud-aws-to-az/src/Resize", + "EntryPoint": "func.py", + "MemoryInMB": 512, + "IsFused": "boolean" , + "IsAutoGenerated": "boolean" + }, + { + "NodeId": "b74b", + "NodeName": "Mobilenet", + "Path": "examples/image-processing-diamond-multicloud-aws-to-az/src/Mobilenet", + "EntryPoint": "func.py", + "MemoryInMB": 512 + }, + { + "NodeId": "3ycp", + "NodeName": "Resnet", + "Path": "examples/image-processing-diamond-multicloud-aws-to-az/src/Resnet", + "EntryPoint": "func.py", + "MemoryInMB": 512 + }, + { + "NodeId": "bq21", + "NodeName": "Squeezenet", + "Path": "examples/image-processing-diamond-multicloud-aws-to-az/src/Squeezenet", + "EntryPoint": "func.py", + "MemoryInMB": 512 + }, + { + "NodeId": "tyvq", + "NodeName": "Union", + "Path": "examples/image-processing-diamond-multicloud-aws-to-az/src/Union", + "EntryPoint": "func.py", + "MemoryInMB": 512 + }, + { + "NodeId": "256", + "NodeName": "CollectLogs", + "Path": "examples/image-processing-diamond-multicloud-aws-to-az/src/CollectLogs", + "EntryPoint": "func.py", + "MemoryInMB": 512 + } + ], + "graphs": { + "nodes": [ + { "id": 9, "label": "Mobilenet","color":"#0080FF" }, + { "id": 7, "label": "Resnet","color":"#FF9900" }, + { "id": 3, "label": "Squeezenet","color":"#0080FF" }, + { "id": 2, "label": "Union" ,"color":"#FF9900"}, + { "id": 4, "label": "CollectLogs","color":"#FF9900" } + ], + "edges": [ + { "from": 9, "to": 7 }, + { "from": 9, "to": 3 }, + { "from": 7, "to": 2 }, + { "from": 7, "to": 4 } + ] + }, + + "Edges": [ + { + "src_node_id": "fm9m", + "sink_node_id": "b74b", + "is_auto_generated": "boolean" + }, + { + "b74b": ["3ycp"] + }, + { + "3ycp": ["bq21"] + }, + { + "bq21": ["tyvq"] + } + ] +} +var inp1={ + "Nodes": { + "L": [ + { + "M": { + "NodeId": { + "S": "1" + }, + "NodeName": { + "S": "TaskA" + }, + "Path": { + "S": "examples/smart-grid-fusion-aws/src/xmlparse_23KB_25KB" + }, + "EntryPoint": { + "S": "func.py" + }, + "CSP": { + "S": "Azure" + }, + "MemoryInMB": { + "N": "128" + } + } + }, + { + "M": { + "NodeId": { + "S": "2" + }, + "NodeName": { + "S": "TaskB" + }, + "Path": { + "S": "examples/smart-grid-fusion-aws/src/memstress_128MB_25KB" + }, + "EntryPoint": { + "S": "func.py" + }, + "CSP": { + "S": "Azure" + }, + "MemoryInMB": { + "N": "256" + } + } + }, + { + "M": { + "NodeId": { + "S": "3" + }, + "NodeName": { + "S": "TaskC" + }, + "Path": { + "S": "examples/smart-grid-fusion-aws/src/resnet_25KB" + }, + "EntryPoint": { + "S": "func.py" + }, + "CSP": { + "S": "Azure" + }, + "MemoryInMB": { + "N": "512" + } + } + }, + { + "M": { + "NodeId": { + "S": "4" + }, + "NodeName": { + "S": "TaskD" + }, + "Path": { + "S": "examples/smart-grid-fusion-aws/src/iostress_512wr_25KB" + }, + "EntryPoint": { + "S": "func.py" + }, + "CSP": { + "S": "Azure" + }, + "MemoryInMB": { + "N": "128" + } + } + }, + { + "M": { + "NodeId": { + "S": "5" + }, + "NodeName": { + "S": "TaskE" + }, + "Path": { + "S": "examples/smart-grid-fusion-aws/src/memstress_128MB_25KB" + }, + "EntryPoint": { + "S": "func.py" + }, + "CSP": { + "S": "Azure" + }, + "MemoryInMB": { + "N": "256" + } + } + }, + { + "M": { + "NodeId": { + "S": "6" + }, + "NodeName": { + "S": "TaskF" + }, + "Path": { + "S": "examples/smart-grid-fusion-aws/src/xmlparse_23KB_25KB" + }, + "EntryPoint": { + "S": "func.py" + }, + "CSP": { + "S": "Azure" + }, + "MemoryInMB": { + "N": "128" + } + } + }, + { + "M": { + "NodeId": { + "S": "7" + }, + "NodeName": { + "S": "TaskG" + }, + "Path": { + "S": "examples/smart-grid-fusion-aws/src/iostress_512wr_25KB" + }, + "EntryPoint": { + "S": "func.py" + }, + "CSP": { + "S": "Azure" + }, + "MemoryInMB": { + "N": "128" + } + } + }, + { + "M": { + "NodeId": { + "S": "8" + }, + "NodeName": { + "S": "TaskH" + }, + "Path": { + "S": "examples/smart-grid-fusion-aws/src/resnet_25KB" + }, + "EntryPoint": { + "S": "func.py" + }, + "CSP": { + "S": "Azure" + }, + "MemoryInMB": { + "N": "512" + } + } + }, + { + "M": { + "NodeId": { + "S": "9" + }, + "NodeName": { + "S": "TaskI" + }, + "Path": { + "S": "examples/smart-grid-fusion-aws/src/memstress_128MB_25KB" + }, + "EntryPoint": { + "S": "func.py" + }, + "CSP": { + "S": "Azure" + }, + "MemoryInMB": { + "N": "256" + } + } + }, + { + "M": { + "NodeId": { + "S": "10" + }, + "NodeName": { + "S": "TaskJ" + }, + "Path": { + "S": "examples/smart-grid-fusion-aws/src/iostress_512wr_25KB" + }, + "EntryPoint": { + "S": "func.py" + }, + "CSP": { + "S": "Azure" + }, + "MemoryInMB": { + "N": "128" + } + } + }, + { + "M": { + "NodeId": { + "S": "11" + }, + "NodeName": { + "S": "TaskK" + }, + "Path": { + "S": "examples/smart-grid-fusion-aws/src/memstress_128MB_25KB" + }, + "EntryPoint": { + "S": "func.py" + }, + "CSP": { + "S": "Azure" + }, + "MemoryInMB": { + "N": "256" + } + } + }, + { + "M": { + "NodeId": { + "S": "12" + }, + "NodeName": { + "S": "TaskL" + }, + "Path": { + "S": "examples/smart-grid-fusion-aws/src/resnet_25KB" + }, + "EntryPoint": { + "S": "func.py" + }, + "CSP": { + "S": "Azure" + }, + "MemoryInMB": { + "N": "512" + } + } + }, + { + "M": { + "NodeId": { + "S": "13" + }, + "NodeName": { + "S": "TaskM" + }, + "Path": { + "S": "examples/smart-grid-fusion-aws/src/xmlparse_23KB_25KB" + }, + "EntryPoint": { + "S": "func.py" + }, + "CSP": { + "S": "Azure" + }, + "MemoryInMB": { + "N": "128" + } + } + }, + { + "M": { + "NodeId": { + "S": "14" + }, + "NodeName": { + "S": "TaskN" + }, + "Path": { + "S": "examples/smart-grid-fusion-aws/src/iostress_512wr_25KB" + }, + "EntryPoint": { + "S": "func.py" + }, + "CSP": { + "S": "Azure" + }, + "MemoryInMB": { + "N": "128" + } + } + }, + { + "M": { + "NodeId": { + "S": "15" + }, + "NodeName": { + "S": "TaskO" + }, + "Path": { + "S": "examples/smart-grid-fusion-aws/src/memstress_128MB_25KB" + }, + "EntryPoint": { + "S": "func.py" + }, + "CSP": { + "S": "Azure" + }, + "MemoryInMB": { + "N": "256" + } + } + }, + { + "M": { + "NodeId": { + "S": "16" + }, + "NodeName": { + "S": "TaskP" + }, + "Path": { + "S": "examples/smart-grid-fusion-aws/src/resnet_25KB" + }, + "EntryPoint": { + "S": "func.py" + }, + "CSP": { + "S": "Azure" + }, + "MemoryInMB": { + "N": "512" + } + } + }, + { + "M": { + "NodeId": { + "S": "17" + }, + "NodeName": { + "S": "TaskQ" + }, + "Path": { + "S": "examples/smart-grid-fusion-aws/src/xmlparse_23KB_25KB" + }, + "EntryPoint": { + "S": "func.py" + }, + "CSP": { + "S": "Azure" + }, + "MemoryInMB": { + "N": "128" + } + } + } + ] + }, + "WorkflowName": { + "S": "SmartGridFusionAWS" + }, + "Edges": { + "L": [ + { + "M": { + "TaskA": { + "L": [ + { + "S": "TaskB" + } + ] + } + } + }, + { + "M": { + "TaskB": { + "L": [ + { + "S": "TaskC" + } + ] + } + } + }, + { + "M": { + "TaskC": { + "L": [ + { + "S": "TaskD" + }, + { + "S": "TaskE" + } + ] + } + } + }, + { + "M": { + "TaskD": { + "L": [ + { + "S": "TaskM" + } + ] + } + } + }, + { + "M": { + "TaskE": { + "L": [ + { + "S": "TaskF" + } + ] + } + } + }, + { + "M": { + "TaskF": { + "L": [ + { + "S": "TaskG" + }, + { + "S": "TaskH" + }, + { + "S": "TaskI" + } + ] + } + } + }, + { + "M": { + "TaskG": { + "L": [ + { + "S": "TaskK" + } + ] + } + } + }, + { + "M": { + "TaskH": { + "L": [ + { + "S": "TaskK" + } + ] + } + } + }, + { + "M": { + "TaskI": { + "L": [ + { + "S": "TaskJ" + } + ] + } + } + }, + { + "M": { + "TaskJ": { + "L": [ + { + "S": "TaskK" + } + ] + } + } + }, + { + "M": { + "TaskK": { + "L": [ + { + "S": "TaskL" + } + ] + } + } + }, + { + "M": { + "TaskL": { + "L": [ + { + "S": "TaskP" + } + ] + } + } + }, + { + "M": { + "TaskM": { + "L": [ + { + "S": "TaskN" + } + ] + } + } + }, + { + "M": { + "TaskN": { + "L": [ + { + "S": "TaskO" + } + ] + } + } + }, + { + "M": { + "TaskO": { + "L": [ + { + "S": "TaskL" + } + ] + } + } + }, + { + "M": { + "TaskP": { + "L": [ + { + "S": "TaskQ" + } + ] + } + } + } + ] + }, + "wf_refactored_id": { + "S": "6e975fc5-b2cb-4759-a5a0-ee49851d33ef" + }, + "refactoring_strategy": { + "S": "Function fusion" + }, + "wf_partitions": { + "L": [ + { + "M": { + "partition_label": { + "S": "AWS" + }, + "function_ids": { + "L": [ + { + "S": "4" + }, + { + "S": "7" + }, + { + "S": "8" + }, + { + "S": "9" + }, + { + "S": "10" + }, + { + "S": "11" + }, + { + "S": "13" + }, + { + "S": "14" + }, + { + "S": "15" + }, + { + "S": "5" + }, + { + "S": "12" + }, + { + "S": "1" + }, + { + "S": "256" + } + ] + } + } + } + ] + } +} \ No newline at end of file diff --git a/backend/server.js b/backend/server.js index d6baf3d..fe77df6 100644 --- a/backend/server.js +++ b/backend/server.js @@ -58,6 +58,7 @@ dynamodb.listTables({}, (err, data) => { } if(tableName=="workflow_invocation_table"){ INVOCATION_VARIABLE=scanData.Items + } @@ -303,7 +304,7 @@ app.post("/api/workflowId/refactoredID/",(req,res)=>{ }) app.post("/api/deploymentId/invocations",(req,res)=>{ - const clickedId =req.body.wf_deployment_id;//"5fa74fb4-bb52-4ce7-932a-d0d30936b3d3" + const clickedId ="76154d98-a0d7-4fc7-8c3e-99c74d91e2ed"//req.body.wf_deployment_id; var input=INVOCATION_VARIABLE.filter((item)=>item.workflow_deployment_id.S==clickedId); return res.json({"workflow_deployment_id":clickedId,"no_of_invocations":input.length}); @@ -312,7 +313,7 @@ app.post("/api/deploymentId/invocations",(req,res)=>{ app.post("/api/deploymentId/listAllInvocations/",async(req,res)=>{ - const clickedId =req.body.wf_deployment_id; + const clickedId ="76154d98-a0d7-4fc7-8c3e-99c74d91e2ed";//req.body.wf_deployment_id;//"76154d98-a0d7-4fc7-8c3e-99c74d91e2ed" var inputArray=INVOCATION_VARIABLE.filter((item)=>item.workflow_deployment_id.S==clickedId); const output = await inputArray.map((input) => { const functionKeys = Object.keys(input.functions.M); diff --git a/frontend/src/InvocationsPage.js b/frontend/src/InvocationsPage.js index 6c2f5a9..8b0be5c 100644 --- a/frontend/src/InvocationsPage.js +++ b/frontend/src/InvocationsPage.js @@ -13,6 +13,7 @@ import { useLocation } from "react-router-dom"; + const GraphWrapper = ({depdetails}) => { const depploymentdetails=depdetails; console.log(depploymentdetails); @@ -114,10 +115,11 @@ console.log(graph); function InvocationsPage() { const location=useLocation(); const [depdetails,setDepdetails]=useState({}) - +const [deploymentId,setDeploymentId]=useState(""); useEffect(()=>{ const params=new URLSearchParams(location.search); const depid=params.get("wf_deployment_id"); + setDeploymentId(depid) axios.post("/api/workflowId/deployments/deploymentId/",{"wf_deployment_id":depid}).then(res=>{ const depObj=res.data console.log("res"); @@ -140,7 +142,7 @@ function InvocationsPage() { setActiveComponent('GraphTable'); }; const handleInvoClick=()=>{ - navigate("/wf/deployment/invocations"); + navigate(`/wf/deployment/invocations/?wfid=${deploymentId}`); } const [theme]=useMode(); @@ -172,7 +174,7 @@ const [theme]=useMode(); {activeComponent === 'GraphWrapper' ? : } - + diff --git a/frontend/src/index.js b/frontend/src/index.js index c43e5a9..4c7db37 100644 --- a/frontend/src/index.js +++ b/frontend/src/index.js @@ -9,6 +9,7 @@ import CodeViewer from './components/CodeViewer'; import InvocationsPage from './InvocationsPage'; import Invocation from './scenes/invocations/Invocation'; import Login from './scenes/login/Login'; +import InvocationDetails from './scenes/invocations/InvocationDetails'; const root = ReactDOM.createRoot(document.getElementById('root')); @@ -22,6 +23,7 @@ root.render( } /> } /> } /> + } /> diff --git a/frontend/src/scenes/bar/Bar.jsx b/frontend/src/scenes/bar/Bar.jsx new file mode 100644 index 0000000..e9a15b8 --- /dev/null +++ b/frontend/src/scenes/bar/Bar.jsx @@ -0,0 +1,106 @@ +// import { Box } from "@mui/material"; + +// import BarChart from "../../components/BarChart"; + +// const Bar = () => { +// return ( +// +// +// +// +// +// ); +// }; + +// export default Bar; +import React, { useState } from "react"; +import { Box, Button, styled } from "@mui/material"; +import { ResponsiveBar } from "@nivo/bar"; +import axios from "axios"; + +const BarChart = ({ chartData }) => { + const [totalInvocations, setTotalInvocations] = useState(0); + + return ( + { + setTotalInvocations(0); + }} + /> + ); +}; + +const CustomButton = styled(Button)({ + background: "white", + color: "blue", + "&:hover": { + background: "white", + }, +}); + +const Bar = () => { + const [chartData, setChartData] = useState([]); + + const fetchData = async () => { + try { + const response = await axios.post("/api/deploymentId/invocations",{"wf_deployment_id":"5fa74fb4-bb52-4ce7-9324-d0d30936b3d3"}); + const { workflow_deployment_id, no_of_invocations } = response.data; + const currentTime = new Date().toLocaleTimeString(); + + setChartData((prevData) => [ + ...prevData, + { + x: currentTime, + y: no_of_invocations, + }, + ]); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + return ( + + + Invocations + + + + + + ); +}; + +export default Bar; diff --git a/frontend/src/scenes/bar/index.jsx b/frontend/src/scenes/bar/index.jsx deleted file mode 100644 index 4ee9c04..0000000 --- a/frontend/src/scenes/bar/index.jsx +++ /dev/null @@ -1,15 +0,0 @@ -import { Box } from "@mui/material"; - -import BarChart from "../../components/BarChart"; - -const Bar = () => { - return ( - - - - - - ); -}; - -export default Bar; \ No newline at end of file diff --git a/frontend/src/scenes/invocations/Invocation.jsx b/frontend/src/scenes/invocations/Invocation.jsx index 21ffd70..7afa1d4 100644 --- a/frontend/src/scenes/invocations/Invocation.jsx +++ b/frontend/src/scenes/invocations/Invocation.jsx @@ -1,114 +1,129 @@ import React, { useState, useEffect } from 'react'; -import List from '@mui/material/List'; -import ListItem from '@mui/material/ListItem'; -import ListItemText from '@mui/material/ListItemText'; -import { Box, IconButton } from '@mui/material'; -import MoreHorizIcon from '@mui/icons-material/MoreHoriz'; -import Line from '../line'; -import Bar from '../bar'; -import { useMode } from '../../theme'; -import { ThemeProvider } from '@emotion/react'; -import ResponsiveAppBar from "../../components/App-bar"; +import { Box, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, TextField, MenuItem, Select } from '@mui/material'; +import { useLocation } from "react-router-dom"; +import { Link } from 'react-router-dom'; +import axios from "axios"; +import Line from '../line/Line'; - -const Invocation = (InvId) => { - const id= InvId; +const Invocation = () => { const [invocationList, setInvocationList] = useState([]); - const [selectedInvocation, setSelectedInvocation] = useState(null); + const [filterValue, setFilterValue] = useState(''); + const [filterTime, setFilterTime] = useState('all'); + const [deploymentId,setDeploymentId]=useState(""); + const location=useLocation(); + useEffect(() => { - // Simulating fetching data from an API - const fetchData = () => { - try { - // Replace this with your actual API call - // const response = await fetch('url'); - // const json = await response.json(); - var json={ "workflow_deployment_id": "uuid", - "workflow_invocation_id": "uuid", - "client_request_time_ms": 1669527328928, - "invocation_start_time_ms": 1669527329557, - "functions": { - "10": { - "start_delta_ms": 0, - "end_delta_ms": 100 - }, - "20": { - "start_delta": 462, - "end_delta": 562, - }, - "30": { - "end_delta": 1423, - "start_delta": 1323 - }, - "40": { - "end_delta": 1907, - "start_delta": 1807 - }, - "50": { - "end_delta": 2360, - "start_delta": 2260 - }, - "60": { - "end_delta": 2753, - "start_delta": 2653 - }, - "70": { - "end_delta": 3199, - "start_delta": 3099 - } - } - } - setInvocationList(json.functions); - } catch (err) { - console.log(err); - } - }; + const params=new URLSearchParams(location.search); +const depid=params.get("wf_deployment_id"); +setDeploymentId(depid) +axios.post("/api/deploymentId/listAllInvocations/",{"wf_deployment_id":depid}).then(res=>{ + const invo=res.data + + setInvocationList(invo); + +}).catch(err=> + console.error(err)) +},[location]) - fetchData(); - }, []); - const handleInvocation = (id) => { - if (id !== selectedInvocation) { - setSelectedInvocation(id); + const getLastFunctionEndTime = (functions, invocationStartTime) => { + const functionEntries = Object.entries(functions); + if (functionEntries.length === 0) { + return null; } - - } - - const [theme]=useMode(); - return ( - <> - - - - -

Deployment Invocations

- {Object.keys(invocationList).map((key) => ( - handleInvocation(key)}> - - - } - > - - - ))} + const maxEndTime = Math.max(...functionEntries.map(([_, func]) => func.end_delta_ms)); + const lastFunctionEndTime = new Date(invocationStartTime + maxEndTime).toLocaleString(); + return lastFunctionEndTime; + }; -
- { selectedInvocation && } - - -
-
- + const handleFilterChange = (event) => { + setFilterValue(event.target.value); + }; - - - + const handleFilterByTime = (timeValue) => { + setFilterTime(timeValue); + }; + + const applyTimeFilter = (filteredData) => { + if (filterTime === 'all') { + return filteredData; + } else { + const now = Date.now(); + const filterTimes = { + last1Hour: now - 3600000, + lastDay: now - 86400000, + lastMonth: now - 2629746000, + last6Months: now - 15778476000, + last12Months: now - 31556952000, + }; + return filteredData.filter(item => { + const startTime = new Date(item.invocation_start_time_ms).getTime(); + return startTime > filterTimes[filterTime]; + }); + } + }; + + const filteredInvocationListByID = invocationList.filter(item => item.workflow_invocation_id.startsWith(filterValue)); + + const filteredByTime = applyTimeFilter(filteredInvocationListByID); + + return ( +
+ + + + + + + + + + + + Invocation ID + Start Time + End Time + + + + {filteredByTime.map(item => ( + + + {item.workflow_invocation_id} + + {new Date(item.invocation_start_time_ms).toLocaleString()} + + {getLastFunctionEndTime(item.functions, item.invocation_start_time_ms)} + + + ))} + +
+
+
+
+
); }; -export default Invocation; +export default Invocation \ No newline at end of file diff --git a/frontend/src/scenes/invocations/InvocationDetails.jsx b/frontend/src/scenes/invocations/InvocationDetails.jsx new file mode 100644 index 0000000..db7b68f --- /dev/null +++ b/frontend/src/scenes/invocations/InvocationDetails.jsx @@ -0,0 +1,258 @@ +import React, { useState, useEffect } from 'react'; +import { Box, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, TextField } from '@mui/material'; +import { useParams } from 'react-router-dom'; +import { useLocation } from "react-router-dom"; +import axios from "axios"; + + +const InvocationDetails = () => { + const [filterValue, setFilterValue] = useState(''); + const [invocationList, setInvocationList] = useState([]); + const [InvocationData,setInvocationData]=useState([]); + const { id } = useParams(); + const location=useLocation(); + + useEffect(() => { + const params=new URLSearchParams(location.search); + const depid=params.get("wf_deployment_id"); + axios.post("/api/deploymentId/listAllInvocations/",{"wf_deployment_id":depid}).then(res=>{ + const invo=res.data + + setInvocationData(invo); + + }).catch(err=> + console.error(err)) + },[location]) + + const convertInvocationList = () => { + const instance = InvocationData.find(data => data.workflow_invocation_id === id); + const invocationStartTime = instance ? instance.invocation_start_time_ms : 0; // Fetch the invocation start time + const functions = instance ? instance.functions : {}; + + const convertMsToDateTime = (ms) => { + const date = new Date(invocationStartTime + ms); // Calculate date based on the invocation start time + return date.toLocaleString(); + }; + + for (const key in functions) { + if (functions.hasOwnProperty(key)) { + const func = functions[key]; + func.start_time_formatted = convertMsToDateTime(func.start_delta_ms); + func.end_time_formatted = convertMsToDateTime(func.end_delta_ms); + } + } + return functions; + }; + +useEffect(() => { + + const formattedInvocationList = convertInvocationList(); + setInvocationList(formattedInvocationList); + + },) + + + const handleFilterChange = (event) => { + setFilterValue(event.target.value); + }; + + // Filter and sort functions based on start time in ascending order + const filteredInvocationList = Object.entries(invocationList) + .filter(([key]) => key.startsWith(filterValue)) + .sort(([, a], [, b]) => b.end_delta_ms - a.end_delta_ms); + + return ( +
+ + + + + + + + + + + Function ID + Start Time (UTC+5:30) + End Time (UTC+5:30) + Execution Time (ms) + + + + {filteredInvocationList.map(([key, value]) => { + const executionTime = value.end_delta_ms - value.start_delta_ms; + return ( + + {key} + {value.start_time_formatted} + {value.end_time_formatted} + {executionTime} + + ); + })} + +
+
+
+
+
+ ); +}; + + export default InvocationDetails; + +// import React, { useState, useEffect } from 'react'; +// import { Box, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, TextField, Button, MenuItem, Select } from '@mui/material'; +// import { useParams } from 'react-router-dom'; +// import { useLocation } from "react-router-dom"; +// import axios from "axios"; + +// const InvocationDetails = () => { +// const [filterValue, setFilterValue] = useState(''); +// const [filterTime, setFilterTime] = useState('all'); +// const [invocationList, setInvocationList] = useState([]); +// const [InvocationData,setInvocationData]=useState([]); +// const { id } = useParams(); + +// const location=useLocation(); + +// useEffect(() => { +// const params=new URLSearchParams(location.search); +// const depid=params.get("wf_deployment_id"); +// axios.post("/api/deploymentId/listAllInvocations/",{"wf_deployment_id":depid}).then(res=>{ +// const invo=res.data + +// setInvocationData(invo); + +// }).catch(err=> +// console.error(err)) +// },[location]) +// const convertInvocationList = () => { +// const instance = InvocationData.find(data => data.workflow_invocation_id === id); +// const invocationStartTime = instance ? instance.invocation_start_time_ms : 0; +// const functions = instance ? instance.functions : {}; + +// const convertMsToDateTime = (ms) => { +// const date = new Date(invocationStartTime + ms); +// return date.toLocaleString(); +// }; + +// for (const key in functions) { +// if (functions.hasOwnProperty(key)) { +// const func = functions[key]; +// func.start_time_formatted = convertMsToDateTime(func.start_delta_ms); +// func.end_time_formatted = convertMsToDateTime(func.end_delta_ms); +// } +// } +// return functions; +// }; + +// useEffect(() => { +// const formattedInvocationList = convertInvocationList(); +// setInvocationList(formattedInvocationList); +// }, ); + +// const handleFilterChange = (event) => { +// setFilterValue(event.target.value); +// }; + +// const handleFilterByTime = (timeValue) => { +// setFilterTime(timeValue); +// }; + +// const applyTimeFilter = (filteredData) => { +// if (filterTime === 'all') { +// return filteredData; +// } else { +// const now = Date.now(); +// const filterTimes = { +// last1Hour: now - 3600000, +// lastDay: now - 86400000, +// lastMonth: now - 2629746000, +// last6Months: now - 15778476000, +// last12Months: now - 31556952000, +// }; + +// return filteredData.filter(([_key, value]) => { +// const startTime = new Date(value.start_time_formatted).getTime(); +// return startTime > filterTimes[filterTime]; +// }); +// } +// }; + +// const filteredInvocationList = Object.entries(invocationList) +// .filter(([key]) => key.startsWith(filterValue)) +// .sort(([, a], [, b]) => b.end_delta_ms - a.end_delta_ms); + +// const filteredByTime = applyTimeFilter(filteredInvocationList); + +// return ( +//
+// +// +// +// +// +// +// +// + +// +// +// +// +// +// Function ID +// Start Time (UTC+5:30) +// End Time (UTC+5:30) +// Execution Time (ms) +// +// +// +// {filteredByTime.map(([key, value]) => { +// const executionTime = value.end_delta_ms - value.start_delta_ms; +// return ( +// +// {key} +// {value.start_time_formatted} +// {value.end_time_formatted} +// {executionTime} +// +// ); +// })} +// +//
+//
+ +//
+//
+// ); +// }; + +// export default InvocationDetails; \ No newline at end of file diff --git a/frontend/src/scenes/line/Line.jsx b/frontend/src/scenes/line/Line.jsx new file mode 100644 index 0000000..6cf10f0 --- /dev/null +++ b/frontend/src/scenes/line/Line.jsx @@ -0,0 +1,112 @@ +// import { Box } from "@mui/material"; + + +// import LineChart from "../../components/LineChart"; + +// const Line = ({invocationId}) => { + +// return ( +// +// +// +// +// +// ); +// }; + +// export default Line; +import React, { useState } from "react"; +import { Box, Button, styled } from "@mui/material"; +import { ResponsiveLine } from "@nivo/line"; +import axios from "axios"; +import { useTheme } from "@emotion/react"; +import { tokens } from "../../theme"; + +const LineChart = ({ chartData }) => { + + return ( + + ); +}; + +const CustomButton = styled(Button)({ + background: "white", + color: "blue", + "&:hover": { + background: "white", + }, +}); + +const Line = () => { + const [chartData, setChartData] = useState([]); + + const fetchData = async () => { + try { + const response = await axios.post("/api/deploymentId/invocations",{"wf_deployment_id":"5fa74fb4-bb52-4ce7-932a-d0d30936b3d3"}); + const { workflow_deployment_id, no_of_invocations } = response.data; + const currentTime = new Date().toLocaleTimeString(); + + setChartData((prevData) => [ + ...prevData, + { + x: currentTime, + y: no_of_invocations, + }, + ]); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + return ( + + + Invocations + + + + + + ); +}; + +export default Line; \ No newline at end of file diff --git a/frontend/src/scenes/line/index.jsx b/frontend/src/scenes/line/index.jsx deleted file mode 100644 index 8fd8157..0000000 --- a/frontend/src/scenes/line/index.jsx +++ /dev/null @@ -1,17 +0,0 @@ -import { Box } from "@mui/material"; - - -import LineChart from "../../components/LineChart"; - -const Line = ({invocationId}) => { - - return ( - - - - - - ); -}; - -export default Line; \ No newline at end of file From f88e64d12c92935ec6dd1dc7db24ca4e915a4fc8 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 5 Nov 2023 21:58:04 +0530 Subject: [PATCH 02/19] merged mermaid with invocations --- backend/server.js | 74 ++- frontend/src/InvocationsPage.js | 84 +++- frontend/src/components/MermaidDiagram.css | 19 + frontend/src/components/Wf.jsx | 552 +++++++++++++++++---- 4 files changed, 591 insertions(+), 138 deletions(-) create mode 100644 frontend/src/components/MermaidDiagram.css diff --git a/backend/server.js b/backend/server.js index fe77df6..d65a279 100644 --- a/backend/server.js +++ b/backend/server.js @@ -102,6 +102,17 @@ app.post("/api/workflowId",(req,res)=>{ const input = SHARED_VARIABLE.find( (item) => item.wf_id.S == wfIdToFetch ); + //console.log(input); + + // fs.writeFile("eg.txt", JSON.stringify(input), { flag: 'a' }, (err) => { + // if (err) { + // console.error('Error writing to the file:', err); + // } else { + // console.log('Data has been written to the file.'); + // } + // }); + + var output = { "wfid": input.wf_id.S, "wfname": input.WorkflowName.S, @@ -115,8 +126,37 @@ app.post("/api/workflowId",(req,res)=>{ "to": parseInt(input.Nodes.L.find(node => node.M.NodeName.S === toNode).M.NodeId.S) })); }).flat() - } + }, + "mermaidGraphDefinition":"" }; + //console.log(output); + // fs.writeFile("op.txt", JSON.stringify(output), { flag: 'a' }, (err) => { + // if (err) { + // console.error('Error writing to the file:', err); + // } else { + // console.log('Data has been written to the file.'); + // } + // }); + + const graphData = output + const { nodes, edges } = graphData.graphs; + + // Start with the graph definition + let mermaidString = 'graph LR;\n'; + + // Convert nodes to Mermaid nodes + for (const node of nodes) { + mermaidString += ` ${node.id}["${node.label}"];\n`; + } + + // Convert edges to Mermaid edges + for (const edge of edges) { + mermaidString += ` ${edge.from} --> ${edge.to};\n`; + } + + console.log(mermaidString); + output.mermaidGraphDefinition=mermaidString + res.json(JSON.stringify(output)) }) @@ -240,6 +280,8 @@ app.post("/api/workflowId/deployments/deploymentId/", (req, res) => { //console.log(input) return res.json(output); }); + + //to get refractored wf details from depid/refid app.post("/api/workflowId/refactoredID/",(req,res)=>{ var clickedId = req.body.wf_deployment_id; @@ -273,13 +315,13 @@ app.post("/api/workflowId/refactoredID/",(req,res)=>{ let color = ""; if (csp === "Azure") { - color = "#0080FF"; + color = "dodgerblue"; //#0080FF } else if (csp === "AWS") { - color = "#FF9900"; + color = "orange"; //#FF9900 } else if (csp === "GCP") { - color = "#00CC00"; + color = "springgreen"; //#00CC00 } else { - color = "#FF9900"; // Default color if CSP is not defined + color = "orange"; // #FF9900 Default color if CSP is not defined } return { @@ -295,14 +337,34 @@ app.post("/api/workflowId/refactoredID/",(req,res)=>{ "from": parseInt(input.Nodes.L.find(node => node.M.NodeName.S === fromNode).M.NodeId.S), "to": parseInt(input.Nodes.L.find(node => node.M.NodeName.S === toNode).M.NodeId.S) })); - }).flat() + }).flat(), + "mermaidGraphDefinition": "" }, }; + const graphData = output + const { nodes, edges } = graphData.graphs; + + // Start with the graph definition + let mermaidString = 'graph LR;\n'; + + //Convert nodes to Mermaid nodes + for (const node of nodes) { + mermaidString += ` ${node.id}["${node.label}"];\n`; + } + + // Convert edges to Mermaid edges + for (const edge of edges) { + mermaidString += ` ${edge.from} --> ${edge.to};\n`; + } + + console.log(mermaidString); + output.graphs.mermaidGraphDefinition=mermaidString return res.json(output); }) + app.post("/api/deploymentId/invocations",(req,res)=>{ const clickedId ="76154d98-a0d7-4fc7-8c3e-99c74d91e2ed"//req.body.wf_deployment_id; diff --git a/frontend/src/InvocationsPage.js b/frontend/src/InvocationsPage.js index 8b0be5c..b2b904f 100644 --- a/frontend/src/InvocationsPage.js +++ b/frontend/src/InvocationsPage.js @@ -9,41 +9,84 @@ import Button from '@mui/material/Button'; import GraphTable from './components/GraphTable'; import axios from "axios"; import { useLocation } from "react-router-dom"; +import mermaid from "mermaid"; +const MermaidDiagram = ({ definition }) => { + const [mermaidInitialized, setMermaidInitialized] = useState(false); + useEffect(() => { + // Initialize Mermaid when the component mounts + mermaid.initialize({ startOnLoad: true }); + setMermaidInitialized(true); + }, []); + + useEffect(() => { + const reloadCount = sessionStorage.getItem('reloadCount'); + + if (mermaidInitialized && (!reloadCount || parseInt(reloadCount) === 0)) { + const timeout = setTimeout(() => { + sessionStorage.setItem('reloadCount', '1'); // Set the flag to prevent further reloads + window.location.reload(); + }, 100); + + return () => { + clearTimeout(timeout); + }; + } + }, [mermaidInitialized]); + + return ( +
+ {mermaidInitialized ? ( +
+ {definition} +
+ ) : ( +

Loading Mermaid diagram...

+ )} +
+ ); +}; const GraphWrapper = ({depdetails}) => { const depploymentdetails=depdetails; - console.log(depploymentdetails); + //console.log(depploymentdetails); const navigate = useNavigate(); const location=useLocation(); const [graphdet,setGraphdet]=useState({}); const [graph,setGraph]=useState({ nodes:[], - edges:[] + edges:[], + mermaidGraphDefinition: "" }); + useEffect(() => { const params = new URLSearchParams(location.search); const wf_deployment_id= params.get("wf_deployment_id"); - axios.post("/api/workflowId/refactoredID", { "wf_deployment_id": wf_deployment_id }) - .then(response => { + axios.post("/api/workflowId/refactoredID", { "wf_deployment_id": wf_deployment_id }) + .then(response => { const ref = response.data; - //console.log(ref); + //console.log("logging ref"); + //console.log(ref); + sessionStorage.removeItem('reloadCount'); setGraphdet(ref); + setGraph(ref.graphs) + console.log("all logging"); + console.log(ref); }) .catch(error => { console.error(error); }); }, [location]); -console.log(graph); + console.log(graph); + - const HandleNodeClick = (event) => { const nodeId = event.nodes[0]; @@ -85,25 +128,22 @@ console.log(graph); "size": 18, "face": "ariel", - }, - - - }, - - - + }, + }, }; - - - - return ( -
-
- + //
+ //
+ // + //
+ //
+ +
+

+
-
+ ); }; diff --git a/frontend/src/components/MermaidDiagram.css b/frontend/src/components/MermaidDiagram.css new file mode 100644 index 0000000..40e18ca --- /dev/null +++ b/frontend/src/components/MermaidDiagram.css @@ -0,0 +1,19 @@ +/* Style the container for the Mermaid diagram */ +.mermaid-container { + width: 100%; /* Set the width as desired */ + height: 100%; /* Set the height as desired */ + margin: 0 auto; /* Center the diagram horizontally */ +} + +/* Add additional styles for your diagram as needed */ +.mermaid-container .node rect { + fill: #009688; /* Example: Change the node rectangle fill color */ +} + +.mermaid-container .node text { + font-size: 14px; /* Example: Adjust the font size for node text */ +} + +.mermaid-container .edgePath path { + stroke: #333; /* Example: Change the edge path stroke color */ +} diff --git a/frontend/src/components/Wf.jsx b/frontend/src/components/Wf.jsx index f995d42..1aeeb0c 100644 --- a/frontend/src/components/Wf.jsx +++ b/frontend/src/components/Wf.jsx @@ -1,87 +1,429 @@ -import './Wf.css'; -import Graph from 'react-graph-vis'; -import DeploymentTable from './DeployTable'; -import ResponsiveAppBar from './App-bar'; -import { useNavigate } from 'react-router-dom'; -import { useMode } from '../theme'; -import {ThemeProvider} from "@mui/material" -import { useLocation } from 'react-router-dom'; -import { useEffect, useState } from 'react'; -import axios, { all } from 'axios'; +// import './Wf.css'; +// import Graph from 'react-graph-vis'; +// import DeploymentTable from './DeployTable'; +// import ResponsiveAppBar from './App-bar'; +// import { useNavigate } from 'react-router-dom'; +// import { useMode } from '../theme'; +// import {ThemeProvider} from "@mui/material" +// import { useLocation } from 'react-router-dom'; +// import { useEffect, useState } from 'react'; +// import axios, { all } from 'axios'; -const GraphWrapper = ({wfdetails}) => { - //const {wfdetails} =wfdetails - const graph={ - nodes:wfdetails.graphs["nodes"], - edges:wfdetails.graphs["edges"] - } - const navigate = useNavigate(); +// const GraphWrapper = ({wfdetails}) => { +// //const {wfdetails} =wfdetails +// const graph={ +// nodes:wfdetails.graphs["nodes"], +// edges:wfdetails.graphs["edges"] +// } +// const navigate = useNavigate(); - const HandleNodeClick = (event) => { - const nodeId = event.nodes[0]; - if (nodeId) { - navigate('/wf/CodeViewer'); - } - }; - - const options = { - layout: { - hierarchical: { - enabled:true, - direction:'LR', - }, +// const HandleNodeClick = (event) => { +// const nodeId = event.nodes[0]; +// if (nodeId) { +// navigate('/wf/CodeViewer'); +// } +// }; + +// const options = { +// layout: { +// hierarchical: { +// enabled:true, +// direction:'LR', +// }, - }, - edges: { - arrows: 'to', - }, - height: '400px', - interaction: { - zoomView: false, - hover: true, - hoverConnectedEdges: false, - selectConnectedEdges: true, +// }, +// edges: { +// arrows: 'to', +// }, +// height: '400px', +// interaction: { +// zoomView: false, +// hover: true, +// hoverConnectedEdges: false, +// selectConnectedEdges: true, - }, - nodes: { +// }, +// nodes: { - fixed:{ - x:true, - y:true - }, - opacity: 1, +// fixed:{ +// x:true, +// y:true +// }, +// opacity: 1, - shape:"square", +// shape:"square", - font: { - "size": 18, - "face": "ariel", +// font: { +// "size": 18, +// "face": "ariel", - }, +// }, - }, +// }, - }; +// }; - return ( -
-
- -
-
- ); -}; +// return ( +//
+//
+// +//
+//
+// ); +// }; + +// function createData(wf_deployment_id, wf_deployment_time, wf_deployment_name) { +// return { wf_deployment_id, wf_deployment_time, wf_deployment_name }; +// } + +// const Wf = () => { +// const [wfdetails,setWfdetails]=useState({ +// "wfid": "", +// "wfname": "", +// "executedTime": "", +// "graphs":{ +// "nodes": [], +// "edges": [] +// } +// }); +// const [alldep,setAlldep]=useState([]) +// const location=useLocation(); +// //console.log(location) +// useEffect(()=>{ +// const params=new URLSearchParams(location.search); +// const wfid=params.get("wfid"); +// axios.post("/api/workflowId",{"wfid":wfid}).then(response=>{ +// const resObj = JSON.parse(response.data); + +// setWfdetails(resObj); + +// }).catch(error => { +// console.error(error); +// }); + +// },[location]); + + +// var deployments=[] + +// useEffect(() => { +// const params = new URLSearchParams(location.search); +// const wfid = params.get("wfid"); +// axios.post("/api/workflowId/deployments", { "wfid": wfid }) +// .then(response => { +// console.log(response.data); +// response.data.forEach((dep)=>{ +// deployments.push(createData(dep.wf_deployment_id, dep.wf_deployment_time, dep.wf_deployment_name)); +// }) +// const depArr = response.data; + +// // console.log(depArr); + + +// setAlldep(depArr); + +// }) +// .catch(error => { +// console.error(error); +// }); +// }, [location]); +// console.log(alldep); +// console.log(deployments); + + +// const [theme]=useMode(); + +// return( + +// + +//
+ +// + + +// +//
+//

Workflow ID:

+ +//
{wfdetails.wfid}
+//
+ +//
+//

Workflow Name:

+ +//
{wfdetails.wfname}
+//
+ +//
+//

Workflow Description:

+//
{wfdetails.WorkflowDescription}
+//
+// +// + +// + +//
+//
+// ); +// }; + +// export default Wf; + +// import './Wf.css'; +// import Graph from 'react-graph-vis'; +// import DeploymentTable from './DeployTable'; +// import ResponsiveAppBar from './App-bar'; +// import { useNavigate } from 'react-router-dom'; +// import { useMode } from '../theme'; +// import {ThemeProvider} from "@mui/material" +// import { useLocation } from 'react-router-dom'; +// import { useEffect, useState } from 'react'; +// import axios, { all } from 'axios'; + + +// const GraphWrapper = ({wfdetails}) => { +// //const {wfdetails} =wfdetails +// const graph={ +// nodes:wfdetails.graphs["nodes"], +// edges:wfdetails.graphs["edges"] +// } +// const navigate = useNavigate(); + +// const HandleNodeClick = (event) => { +// const nodeId = event.nodes[0]; +// if (nodeId) { +// navigate('/wf/CodeViewer'); +// } +// }; + +// const options = { +// layout: { +// hierarchical: { +// enabled:true, +// direction:'LR', +// }, + +// }, +// edges: { +// arrows: 'to', +// }, +// height: '400px', +// interaction: { +// zoomView: false, +// hover: true, +// hoverConnectedEdges: false, +// selectConnectedEdges: true, + +// }, +// nodes: { + +// fixed:{ +// x:true, +// y:true +// }, +// opacity: 1, + +// shape:"square", + +// font: { +// "size": 18, +// "face": "ariel", + +// }, + + +// }, + + + +// }; + + +// return ( +//
+//
+// +//
+//
+// ); +// }; + +// function createData(wf_deployment_id, wf_deployment_time, wf_deployment_name) { +// return { wf_deployment_id, wf_deployment_time, wf_deployment_name }; +// } + +// const Wf = () => { +// const [wfdetails,setWfdetails]=useState({ +// "wfid": "", +// "wfname": "", +// "executedTime": "", +// "graphs":{ +// "nodes": [], +// "edges": [] +// } +// }); +// const [alldep,setAlldep]=useState([]) +// const location=useLocation(); +// //console.log(location) +// useEffect(()=>{ +// const params=new URLSearchParams(location.search); +// const wfid=params.get("wfid"); +// axios.post("/api/workflowId",{"wfid":wfid}).then(response=>{ +// const resObj = JSON.parse(response.data); + +// setWfdetails(resObj); + +// }).catch(error => { +// console.error(error); +// }); + +// },[location]); + + +// var deployments=[] + +// useEffect(() => { +// const params = new URLSearchParams(location.search); +// const wfid = params.get("wfid"); +// axios.post("/api/workflowId/deployments", { "wfid": wfid }) +// .then(response => { +// console.log(response.data); +// response.data.forEach((dep)=>{ +// deployments.push(createData(dep.wf_deployment_id, dep.wf_deployment_time, dep.wf_deployment_name)); +// }) +// const depArr = response.data; + +// // console.log(depArr); + + +// setAlldep(depArr); + +// }) +// .catch(error => { +// console.error(error); +// }); +// }, [location]); +// console.log(alldep); +// console.log(deployments); + + +// const [theme]=useMode(); + +// return( + +// + +//
+ +// + + +// +//
+//

Workflow ID:

+ +//
{wfdetails.wfid}
+//
+ +//
+//

Workflow Name:

+ +//
{wfdetails.wfname}
+//
+ +//
+//

Workflow Description:

+//
{wfdetails.WorkflowDescription}
+//
+// +// + +// + +//
+//
+// ); +// }; + +// export default Wf; + +import './Wf.css'; +import Graph from 'react-graph-vis'; +import DeploymentTable from './DeployTable'; +import ResponsiveAppBar from './App-bar'; +import { useNavigate } from 'react-router-dom'; +import { useMode } from '../theme'; +import {ThemeProvider} from "@mui/material" +import { useLocation } from 'react-router-dom'; +import { useEffect, useState } from 'react'; +import axios, { all } from 'axios'; +//import MermaidDiagram from './MermaidDiagram.jsx'; +import mermaid from 'mermaid'; function createData(wf_deployment_id, wf_deployment_time, wf_deployment_name) { return { wf_deployment_id, wf_deployment_time, wf_deployment_name }; } -const Wf = () => { +// const MermaidDiagram = ({ definition }) => { +// useEffect(() => { +// // Initialize Mermaid when the component mounts +// mermaid.initialize({ startOnLoad: true }); + +// }, [definition]); + +// return ( +//
+// {definition} +//
+// ); +// }; + + +const MermaidDiagram = ({ definition }) => { + const [mermaidInitialized, setMermaidInitialized] = useState(false); + + useEffect(() => { + // Initialize Mermaid when the component mounts + mermaid.initialize({ startOnLoad: true }); + setMermaidInitialized(true); + }, []); + + useEffect(() => { + const reloadCount = sessionStorage.getItem('reloadCount'); + + if (mermaidInitialized && (!reloadCount || parseInt(reloadCount) === 0)) { + const timeout = setTimeout(() => { + sessionStorage.setItem('reloadCount', '1'); // Set the flag to prevent further reloads + window.location.reload(); + }, 100); + + return () => { + clearTimeout(timeout); + }; + } + }, [mermaidInitialized]); + + return ( +
+ {mermaidInitialized ? ( +
+ {definition} +
+ ) : ( +

Loading Mermaid diagram...

+ )} +
+ ); +}; + +const Wf = () => { const [wfdetails,setWfdetails]=useState({ "wfid": "", "wfname": "", @@ -89,89 +431,79 @@ const Wf = () => { "graphs":{ "nodes": [], "edges": [] - } + }, + "mermaidGraphDefinition": "" }); + + const [alldep,setAlldep]=useState([]) + + const location=useLocation(); - //console.log(location) useEffect(()=>{ const params=new URLSearchParams(location.search); const wfid=params.get("wfid"); - axios.post("/api/workflowId",{"wfid":wfid}).then(response=>{ - const resObj = JSON.parse(response.data); - - setWfdetails(resObj); - - }).catch(error => { - console.error(error); - }); - + {axios.post("/api/workflowId",{"wfid":wfid}).then(response=>{ + const resObj = JSON.parse(response.data); + sessionStorage.removeItem('reloadCount'); + setWfdetails(resObj); + }).catch(error => { + console.error(error); + }); } },[location]); -var deployments=[] - + var deployments=[] useEffect(() => { const params = new URLSearchParams(location.search); const wfid = params.get("wfid"); - axios.post("/api/workflowId/deployments", { "wfid": wfid }) - .then(response => { - console.log(response.data); + axios.post("/api/workflowId/deployments", { "wfid": wfid }) + .then(response => { response.data.forEach((dep)=>{ deployments.push(createData(dep.wf_deployment_id, dep.wf_deployment_time, dep.wf_deployment_name)); }) const depArr = response.data; - - // console.log(depArr); - - - setAlldep(depArr); - + setAlldep(depArr); }) .catch(error => { console.error(error); }); }, [location]); - console.log(alldep); - console.log(deployments); - - const [theme]=useMode(); - return( - - - -
- - - - -
-

Workflow ID:

- + const [theme]=useMode(); + + return( + +
+ + +
+

Workflow ID:

{wfdetails.wfid}
-
-

Workflow Name:

- +

Workflow Name:

{wfdetails.wfname}
-

Workflow Description:

{wfdetails.WorkflowDescription}
- - + - - + +
+

+ +
+ + +
); }; -export default Wf; +export default Wf; \ No newline at end of file From d94b0eb7713621223623efc2f45b22c3fc51229c Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 6 Nov 2023 19:45:10 +0530 Subject: [PATCH 03/19] added css to mainpage --- frontend/README.md | 4 - frontend/package-lock.json | 1449 ++++++++++++++++++++++++--- frontend/package.json | 5 +- frontend/public/favicon.ico | Bin 3870 -> 0 bytes frontend/public/index.html | 12 +- frontend/public/manifest.json | 2 +- frontend/src/App.css | 30 +- frontend/src/App.js | 47 +- frontend/src/TypeWriterEffect.css | 21 + frontend/src/TypeWriterEffect.jsx | 26 + frontend/src/components/Allwf.jsx | 289 ++++-- frontend/src/components/App-bar.jsx | 15 +- frontend/src/components/Welcome.jsx | 52 - frontend/src/index.js | 14 +- frontend/src/setupTests.js | 2 +- 15 files changed, 1626 insertions(+), 342 deletions(-) delete mode 100644 frontend/public/favicon.ico create mode 100644 frontend/src/TypeWriterEffect.css create mode 100644 frontend/src/TypeWriterEffect.jsx delete mode 100644 frontend/src/components/Welcome.jsx diff --git a/frontend/README.md b/frontend/README.md index 2f151bd..17eea5b 100644 --- a/frontend/README.md +++ b/frontend/README.md @@ -1,5 +1,4 @@ ### 'Create-react-app' - The app was built using create-react-app command, this is necessary to install all the node modules which is otherwise not present in this repository due to size constraints ### 'Visualizing the connected graph' @@ -10,13 +9,10 @@ In order to incorporate interactive features please the material UI libraries npm install @mui/material @emotion/react @emotion/styled npm install @mui/icons-material @mui/material @emotion/styled @emotion/react - ### 'npm start' - Runs the app in the development mode.\ Open [http://localhost:3000](http://localhost:3000) to view it in your browser. ### `npm test` - Launches the test runner in the interactive watch mode.\ See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. diff --git a/frontend/package-lock.json b/frontend/package-lock.json index b90cc60..0286fe7 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -10,17 +10,20 @@ "dependencies": { "@emotion/react": "^11.11.0", "@emotion/styled": "^11.11.0", - "@mui/icons-material": "^5.11.16", + "@material/icon-button": "^14.0.0", + "@mui/icons-material": "^5.14.16", "@mui/material": "^5.13.4", "@nivo/bar": "^0.83.0", "@nivo/core": "^0.83.0", "@nivo/line": "^0.83.0", + "@passageidentity/passage-auth": "^0.1.0-beta.28", "@passageidentity/passage-elements": "^1.9.2", "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", "axios": "^1.4.0", "dotenv": "^16.3.1", + "mermaid": "^10.6.0", "react": "^18.2.0", "react-dom": "^18.2.0", "react-graph-vis": "^1.0.7", @@ -2039,16 +2042,21 @@ "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==" }, "node_modules/@babel/runtime": { - "version": "7.22.3", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.3.tgz", - "integrity": "sha512-XsDuspWKLUsxwCp6r7EhsExHtYfbe5oAGQ19kqngTdCPUoPQzOPdUbD/pB9PJiwb2ptYKQDjSJT3R6dC+EPqfQ==", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.2.tgz", + "integrity": "sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==", "dependencies": { - "regenerator-runtime": "^0.13.11" + "regenerator-runtime": "^0.14.0" }, "engines": { "node": ">=6.9.0" } }, + "node_modules/@babel/runtime/node_modules/regenerator-runtime": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", + "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==" + }, "node_modules/@babel/template": { "version": "7.21.9", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.21.9.tgz", @@ -2100,6 +2108,11 @@ "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==" }, + "node_modules/@braintree/sanitize-url": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-6.0.4.tgz", + "integrity": "sha512-s3jaWicZd0pkP0jf5ysyHUI/RE7MHos6qlToFcGWXVp+ykHOy77OUMrfbgJ9it2C5bow7OIQwYYaHjk9XlBQ2A==" + }, "node_modules/@csstools/normalize.css": { "version": "12.0.0", "resolved": "https://registry.npmjs.org/@csstools/normalize.css/-/normalize.css-12.0.0.tgz", @@ -2370,18 +2383,6 @@ "postcss-selector-parser": "^6.0.10" } }, - "node_modules/@egjs/hammerjs": { - "version": "2.0.17", - "resolved": "https://registry.npmjs.org/@egjs/hammerjs/-/hammerjs-2.0.17.tgz", - "integrity": "sha512-XQsZgjm2EcVUiZQf11UBJQfmZeEmOW8DpI1gsFeln6w0ae0ii4dMQEQ0kjl6DspdWX1aGY1/loyXnP0JS06e/A==", - "peer": true, - "dependencies": { - "@types/hammerjs": "^2.0.36" - }, - "engines": { - "node": ">=0.8.0" - } - }, "node_modules/@emotion/babel-plugin": { "version": "11.11.0", "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz", @@ -3526,6 +3527,131 @@ "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==" }, + "node_modules/@material/animation": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@material/animation/-/animation-14.0.0.tgz", + "integrity": "sha512-VlYSfUaIj/BBVtRZI8Gv0VvzikFf+XgK0Zdgsok5c1v5DDnNz5tpB8mnGrveWz0rHbp1X4+CWLKrTwNmjrw3Xw==", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@material/base": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@material/base/-/base-14.0.0.tgz", + "integrity": "sha512-Ou7vS7n1H4Y10MUZyYAbt6H0t67c6urxoCgeVT7M38aQlaNUwFMODp7KT/myjYz2YULfhu3PtfSV3Sltgac9mA==", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@material/density": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@material/density/-/density-14.0.0.tgz", + "integrity": "sha512-NlxXBV5XjNsKd8UXF4K/+fOXLxoFNecKbsaQO6O2u+iG8QBfFreKRmkhEBb2hPPwC3w8nrODwXX0lHV+toICQw==", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@material/dom": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@material/dom/-/dom-14.0.0.tgz", + "integrity": "sha512-8t88XyacclTj8qsIw9q0vEj4PI2KVncLoIsIMzwuMx49P2FZg6TsLjor262MI3Qs00UWAifuLMrhnOnfyrbe7Q==", + "dependencies": { + "@material/feature-targeting": "^14.0.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/elevation": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@material/elevation/-/elevation-14.0.0.tgz", + "integrity": "sha512-Di3tkxTpXwvf1GJUmaC8rd+zVh5dB2SWMBGagL4+kT8UmjSISif/OPRGuGnXs3QhF6nmEjkdC0ijdZLcYQkepw==", + "dependencies": { + "@material/animation": "^14.0.0", + "@material/base": "^14.0.0", + "@material/feature-targeting": "^14.0.0", + "@material/rtl": "^14.0.0", + "@material/theme": "^14.0.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/feature-targeting": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@material/feature-targeting/-/feature-targeting-14.0.0.tgz", + "integrity": "sha512-a5WGgHEq5lJeeNL5yevtgoZjBjXWy6+klfVWQEh8oyix/rMJygGgO7gEc52uv8fB8uAIoYEB3iBMOv8jRq8FeA==", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@material/focus-ring": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@material/focus-ring/-/focus-ring-14.0.0.tgz", + "integrity": "sha512-fqqka6iSfQGJG3Le48RxPCtnOiaLGPDPikhktGbxlyW9srBVMgeCiONfHM7IT/1eu80O0Y67Lh/4ohu5+C+VAQ==", + "dependencies": { + "@material/dom": "^14.0.0", + "@material/feature-targeting": "^14.0.0", + "@material/rtl": "^14.0.0" + } + }, + "node_modules/@material/icon-button": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@material/icon-button/-/icon-button-14.0.0.tgz", + "integrity": "sha512-wHMqzm7Q/UwbWLoWv32Li1r2iVYxadIrwTNxT0+p+7NdfI3lEwMN3NoB0CvoJnHTljjXDzce0KJ3nZloa0P0gA==", + "dependencies": { + "@material/base": "^14.0.0", + "@material/density": "^14.0.0", + "@material/dom": "^14.0.0", + "@material/elevation": "^14.0.0", + "@material/feature-targeting": "^14.0.0", + "@material/focus-ring": "^14.0.0", + "@material/ripple": "^14.0.0", + "@material/rtl": "^14.0.0", + "@material/theme": "^14.0.0", + "@material/touch-target": "^14.0.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/ripple": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@material/ripple/-/ripple-14.0.0.tgz", + "integrity": "sha512-9XoGBFd5JhFgELgW7pqtiLy+CnCIcV2s9cQ2BWbOQeA8faX9UZIDUx/g76nHLZ7UzKFtsULJxZTwORmsEt2zvw==", + "dependencies": { + "@material/animation": "^14.0.0", + "@material/base": "^14.0.0", + "@material/dom": "^14.0.0", + "@material/feature-targeting": "^14.0.0", + "@material/rtl": "^14.0.0", + "@material/theme": "^14.0.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/rtl": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@material/rtl/-/rtl-14.0.0.tgz", + "integrity": "sha512-xl6OZYyRjuiW2hmbjV2omMV8sQtfmKAjeWnD1RMiAPLCTyOW9Lh/PYYnXjxUrNa0cRwIIbOn5J7OYXokja8puA==", + "dependencies": { + "@material/theme": "^14.0.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/theme": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@material/theme/-/theme-14.0.0.tgz", + "integrity": "sha512-6/SENWNIFuXzeHMPHrYwbsXKgkvCtWuzzQ3cUu4UEt3KcQ5YpViazIM6h8ByYKZP8A9d8QpkJ0WGX5btGDcVoA==", + "dependencies": { + "@material/feature-targeting": "^14.0.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/touch-target": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@material/touch-target/-/touch-target-14.0.0.tgz", + "integrity": "sha512-o3kvxmS4HkmZoQTvtzLJrqSG+ezYXkyINm3Uiwio1PTg67pDgK5FRwInkz0VNaWPcw9+5jqjUQGjuZMtjQMq8w==", + "dependencies": { + "@material/base": "^14.0.0", + "@material/feature-targeting": "^14.0.0", + "@material/rtl": "^14.0.0", + "tslib": "^2.1.0" + } + }, "node_modules/@mui/base": { "version": "5.0.0-beta.4", "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.4.tgz", @@ -3568,11 +3694,11 @@ } }, "node_modules/@mui/icons-material": { - "version": "5.11.16", - "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.11.16.tgz", - "integrity": "sha512-oKkx9z9Kwg40NtcIajF9uOXhxiyTZrrm9nmIJ4UjkU2IdHpd4QVLbCc/5hZN/y0C6qzi2Zlxyr9TGddQx2vx2A==", + "version": "5.14.16", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.14.16.tgz", + "integrity": "sha512-wmOgslMEGvbHZjFLru8uH5E+pif/ciXAvKNw16q6joK6EWVWU5rDYWFknDaZhCvz8ZE/K8ZnJQ+lMG6GgHzXbg==", "dependencies": { - "@babel/runtime": "^7.21.0" + "@babel/runtime": "^7.23.2" }, "engines": { "node": ">=12.0.0" @@ -4031,6 +4157,34 @@ "node": ">= 8" } }, + "node_modules/@passageidentity/passage-auth": { + "version": "0.1.0-beta.28", + "resolved": "https://registry.npmjs.org/@passageidentity/passage-auth/-/passage-auth-0.1.0-beta.28.tgz", + "integrity": "sha512-+5YK66FuEt6n6zQLoA7SxOlKM/wARXVBdBsxDY0tb+jwATJT2GRysTQhCFb7km/eWFrcpIcpWg0jvr4sbBmsbA==", + "deprecated": "Package no longer supported. Upgrade to @passageidentity/passage-elements", + "dependencies": { + "@passageidentity/passage-js": "^2.0.2", + "bulma": "^0.9.3", + "intl-tel-input": "^17.0.13", + "vue": "^3.2.22" + } + }, + "node_modules/@passageidentity/passage-auth/node_modules/@passageidentity/passage-js": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/@passageidentity/passage-js/-/passage-js-2.6.3.tgz", + "integrity": "sha512-DV/duYjcp7ZvJz8IOD+KKmGC8ktKq60zvb7cP1I1oqrQYnTj/cTMNr/CG6Q9Z1Y45a17WNqXi7VnooFXBNSUBw==", + "deprecated": "passage-js v2.x and earlier is no longer supported. Update to @passageidentity/passage-js@latest", + "dependencies": { + "@types/node": "^17.0.27", + "jwt-decode": "^3.1.2", + "ua-parser-js": "^1.0.2" + } + }, + "node_modules/@passageidentity/passage-auth/node_modules/@types/node": { + "version": "17.0.45", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", + "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==" + }, "node_modules/@passageidentity/passage-elements": { "version": "1.9.2", "resolved": "https://registry.npmjs.org/@passageidentity/passage-elements/-/passage-elements-1.9.2.tgz", @@ -4541,25 +4695,6 @@ "url": "https://github.com/sponsors/gregberge" } }, - "node_modules/@testing-library/dom": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-9.3.1.tgz", - "integrity": "sha512-0DGPd9AR3+iDTjGoMpxIkAsUihHZ3Ai6CneU6bRRrffXMgzCdlNk43jTrD2/5LT6CBb3MWTP8v510JzYtahD2w==", - "peer": true, - "dependencies": { - "@babel/code-frame": "^7.10.4", - "@babel/runtime": "^7.12.5", - "@types/aria-query": "^5.0.1", - "aria-query": "5.1.3", - "chalk": "^4.1.0", - "dom-accessibility-api": "^0.5.9", - "lz-string": "^1.5.0", - "pretty-format": "^27.0.2" - }, - "engines": { - "node": ">=14" - } - }, "node_modules/@testing-library/jest-dom": { "version": "5.16.5", "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.16.5.tgz", @@ -4791,6 +4926,14 @@ "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-2.3.1.tgz", "integrity": "sha512-fck0Z9RGfIQn3GJIEKVrp15h9m6Vlg0d5XXeiE/6+CQiBmMDZxfR21XtjEPuDeg7gC3bBM0SdieA5XF3GW1wKA==" }, + "node_modules/@types/debug": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.10.tgz", + "integrity": "sha512-tOSCru6s732pofZ+sMv9o4o3Zc+Sa8l3bxd/tweTQudFn06vAzb13ZX46Zi6m6EJ+RUbRTHvgQJ1gBtSgkaUYA==", + "dependencies": { + "@types/ms": "*" + } + }, "node_modules/@types/eslint": { "version": "8.40.0", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.40.0.tgz", @@ -4844,12 +4987,6 @@ "@types/node": "*" } }, - "node_modules/@types/hammerjs": { - "version": "2.0.41", - "resolved": "https://registry.npmjs.org/@types/hammerjs/-/hammerjs-2.0.41.tgz", - "integrity": "sha512-ewXv/ceBaJprikMcxCmWU1FKyMAQ2X7a9Gtmzw8fcg2kIePI1crERDM818W+XYrxqdBBOdlf2rm137bU+BltCA==", - "peer": true - }, "node_modules/@types/hast": { "version": "2.3.4", "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.4.tgz", @@ -4935,11 +5072,24 @@ "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==" }, + "node_modules/@types/mdast": { + "version": "3.0.14", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.14.tgz", + "integrity": "sha512-gVZ04PGgw1qLZKsnWnyFv4ORnaJ+DXLdHTVSFbU8yX6xZ34Bjg4Q32yPkmveUP1yItXReKfB0Aknlh/3zxTKAw==", + "dependencies": { + "@types/unist": "^2" + } + }, "node_modules/@types/mime": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==" }, + "node_modules/@types/ms": { + "version": "0.7.33", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.33.tgz", + "integrity": "sha512-AuHIyzR5Hea7ij0P9q7vx7xu4z0C28ucwjAZC0ja7JhINyCnOw8/DnvAPQQ9TfOlCtZAmCERKQX9+o1mgQhuOQ==" + }, "node_modules/@types/node": { "version": "20.2.5", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.2.5.tgz", @@ -6520,6 +6670,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/bulma": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/bulma/-/bulma-0.9.4.tgz", + "integrity": "sha512-86FlT5+1GrsgKbPLRRY7cGDg8fsJiP/jzTqXXVqiUZZ2aZT8uemEOHlU1CDU+TxklPEZ11HZNNWclRBBecP4CQ==" + }, "node_modules/bytes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", @@ -6933,12 +7088,6 @@ "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==" }, - "node_modules/component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "peer": true - }, "node_modules/compressible": { "version": "2.0.18", "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", @@ -7077,6 +7226,14 @@ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" }, + "node_modules/cose-base": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/cose-base/-/cose-base-1.0.3.tgz", + "integrity": "sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg==", + "dependencies": { + "layout-base": "^1.0.0" + } + }, "node_modules/cosmiconfig": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", @@ -7508,6 +7665,93 @@ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" }, + "node_modules/cytoscape": { + "version": "3.27.0", + "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.27.0.tgz", + "integrity": "sha512-pPZJilfX9BxESwujODz5pydeGi+FBrXq1rcaB1mfhFXXFJ9GjE6CNndAk+8jPzoXGD+16LtSS4xlYEIUiW4Abg==", + "dependencies": { + "heap": "^0.2.6", + "lodash": "^4.17.21" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/cytoscape-cose-bilkent": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cytoscape-cose-bilkent/-/cytoscape-cose-bilkent-4.1.0.tgz", + "integrity": "sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ==", + "dependencies": { + "cose-base": "^1.0.0" + }, + "peerDependencies": { + "cytoscape": "^3.2.0" + } + }, + "node_modules/cytoscape-fcose": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cytoscape-fcose/-/cytoscape-fcose-2.2.0.tgz", + "integrity": "sha512-ki1/VuRIHFCzxWNrsshHYPs6L7TvLu3DL+TyIGEsRcvVERmxokbf5Gdk7mFxZnTdiGtnA4cfSmjZJMviqSuZrQ==", + "dependencies": { + "cose-base": "^2.2.0" + }, + "peerDependencies": { + "cytoscape": "^3.2.0" + } + }, + "node_modules/cytoscape-fcose/node_modules/cose-base": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cose-base/-/cose-base-2.2.0.tgz", + "integrity": "sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g==", + "dependencies": { + "layout-base": "^2.0.0" + } + }, + "node_modules/cytoscape-fcose/node_modules/layout-base": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/layout-base/-/layout-base-2.0.1.tgz", + "integrity": "sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg==" + }, + "node_modules/d3": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/d3/-/d3-7.8.5.tgz", + "integrity": "sha512-JgoahDG51ncUfJu6wX/1vWQEqOflgXyl4MaHqlcSruTez7yhaRKR9i8VjjcQGeS2en/jnFivXuaIMnseMMt0XA==", + "dependencies": { + "d3-array": "3", + "d3-axis": "3", + "d3-brush": "3", + "d3-chord": "3", + "d3-color": "3", + "d3-contour": "4", + "d3-delaunay": "6", + "d3-dispatch": "3", + "d3-drag": "3", + "d3-dsv": "3", + "d3-ease": "3", + "d3-fetch": "3", + "d3-force": "3", + "d3-format": "3", + "d3-geo": "3", + "d3-hierarchy": "3", + "d3-interpolate": "3", + "d3-path": "3", + "d3-polygon": "3", + "d3-quadtree": "3", + "d3-random": "3", + "d3-scale": "4", + "d3-scale-chromatic": "3", + "d3-selection": "3", + "d3-shape": "3", + "d3-time": "3", + "d3-time-format": "4", + "d3-timer": "3", + "d3-transition": "3", + "d3-zoom": "3" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/d3-array": { "version": "2.12.1", "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz", @@ -7516,6 +7760,40 @@ "internmap": "^1.0.0" } }, + "node_modules/d3-axis": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz", + "integrity": "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-brush": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz", + "integrity": "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "3", + "d3-transition": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-chord": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-3.0.1.tgz", + "integrity": "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==", + "dependencies": { + "d3-path": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/d3-color": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", @@ -7524,6 +7802,28 @@ "node": ">=12" } }, + "node_modules/d3-contour": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.2.tgz", + "integrity": "sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==", + "dependencies": { + "d3-array": "^3.2.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-contour/node_modules/d3-array": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "dependencies": { + "internmap": "1 - 2" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/d3-delaunay": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-5.3.0.tgz", @@ -7532,11 +7832,114 @@ "delaunator": "4" } }, + "node_modules/d3-dispatch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", + "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-drag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz", + "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-selection": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dsv": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz", + "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==", + "dependencies": { + "commander": "7", + "iconv-lite": "0.6", + "rw": "1" + }, + "bin": { + "csv2json": "bin/dsv2json.js", + "csv2tsv": "bin/dsv2dsv.js", + "dsv2dsv": "bin/dsv2dsv.js", + "dsv2json": "bin/dsv2json.js", + "json2csv": "bin/json2dsv.js", + "json2dsv": "bin/json2dsv.js", + "json2tsv": "bin/json2dsv.js", + "tsv2csv": "bin/dsv2dsv.js", + "tsv2json": "bin/dsv2json.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dsv/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-fetch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz", + "integrity": "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==", + "dependencies": { + "d3-dsv": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-force": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz", + "integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-quadtree": "1 - 3", + "d3-timer": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/d3-format": { "version": "1.4.5", "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-1.4.5.tgz", "integrity": "sha512-J0piedu6Z8iB6TbIGfZgDzfXxUFN3qQRMofy2oPdXzQibYGqPB/9iMcxr/TGalU+2RsyDO+U4f33id8tbnSRMQ==" }, + "node_modules/d3-geo": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.0.tgz", + "integrity": "sha512-JEo5HxXDdDYXCaWdwLRt79y7giK8SbhZJbFWXqbRTolCHFI5jRqteLzCsq51NKbUoX0PjBVSohxrx+NoOUujYA==", + "dependencies": { + "d3-array": "2.5.0 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-hierarchy": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz", + "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==", + "engines": { + "node": ">=12" + } + }, "node_modules/d3-interpolate": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-2.0.1.tgz", @@ -7555,6 +7958,39 @@ "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz", "integrity": "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==" }, + "node_modules/d3-polygon": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz", + "integrity": "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-quadtree": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz", + "integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-random": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz", + "integrity": "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-sankey": { + "version": "0.12.3", + "resolved": "https://registry.npmjs.org/d3-sankey/-/d3-sankey-0.12.3.tgz", + "integrity": "sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==", + "dependencies": { + "d3-array": "1 - 2", + "d3-shape": "^1.2.0" + } + }, "node_modules/d3-scale": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-3.3.0.tgz", @@ -7581,6 +8017,14 @@ "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-2.0.0.tgz", "integrity": "sha512-SPXi0TSKPD4g9tw0NMZFnR95XVgUZiBH+uUTqQuDu1OsE2zomHU7ho0FISciaPvosimixwHFl3WHLGabv6dDgQ==" }, + "node_modules/d3-selection": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", + "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", + "engines": { + "node": ">=12" + } + }, "node_modules/d3-shape": { "version": "1.3.7", "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz", @@ -7605,30 +8049,197 @@ "d3-time": "1 - 2" } }, - "node_modules/damerau-levenshtein": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", - "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==" + "node_modules/d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "engines": { + "node": ">=12" + } }, - "node_modules/data-urls": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", - "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", + "node_modules/d3-transition": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz", + "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==", "dependencies": { - "abab": "^2.0.3", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.0.0" + "d3-color": "1 - 3", + "d3-dispatch": "1 - 3", + "d3-ease": "1 - 3", + "d3-interpolate": "1 - 3", + "d3-timer": "1 - 3" }, "engines": { - "node": ">=10" + "node": ">=12" + }, + "peerDependencies": { + "d3-selection": "2 - 3" } }, - "node_modules/dayjs": { - "version": "1.11.8", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.8.tgz", - "integrity": "sha512-LcgxzFoWMEPO7ggRv1Y2N31hUf2R0Vj7fuy/m+Bg1K8rr+KAs1AEy4y9jd5DXe8pbHgX+srkHNS7TH6Q6ZhYeQ==" - }, - "node_modules/debug": { + "node_modules/d3-zoom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz", + "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "2 - 3", + "d3-transition": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3/node_modules/d3-array": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "dependencies": { + "internmap": "1 - 2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3/node_modules/d3-delaunay": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz", + "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==", + "dependencies": { + "delaunator": "5" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3/node_modules/d3-format": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", + "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3/node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3/node_modules/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3/node_modules/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "dependencies": { + "d3-array": "2.10.0 - 3", + "d3-format": "1 - 3", + "d3-interpolate": "1.2.0 - 3", + "d3-time": "2.1.1 - 3", + "d3-time-format": "2 - 4" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3/node_modules/d3-scale-chromatic": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.0.0.tgz", + "integrity": "sha512-Lx9thtxAKrO2Pq6OO2Ua474opeziKr279P/TKZsMAhYyNDD3EnCffdbgeSYN5O7m2ByQsxtuP2CSDczNUIZ22g==", + "dependencies": { + "d3-color": "1 - 3", + "d3-interpolate": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3/node_modules/d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "dependencies": { + "d3-path": "^3.1.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3/node_modules/d3-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "dependencies": { + "d3-array": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3/node_modules/d3-time-format": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "dependencies": { + "d3-time": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3/node_modules/delaunator": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.0.tgz", + "integrity": "sha512-AyLvtyJdbv/U1GkiS6gUUzclRoAY4Gs75qkMygJJhU75LW4DNuSF2RMzpxs9jw9Oz1BobHjTdkG3zdP55VxAqw==", + "dependencies": { + "robust-predicates": "^3.0.0" + } + }, + "node_modules/dagre-d3-es": { + "version": "7.0.10", + "resolved": "https://registry.npmjs.org/dagre-d3-es/-/dagre-d3-es-7.0.10.tgz", + "integrity": "sha512-qTCQmEhcynucuaZgY5/+ti3X/rnszKZhEQH/ZdWdtP1tA/y3VoHJzcVrO9pjjJCNpigfscAtoUB5ONcd2wNn0A==", + "dependencies": { + "d3": "^7.8.2", + "lodash-es": "^4.17.21" + } + }, + "node_modules/damerau-levenshtein": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", + "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==" + }, + "node_modules/data-urls": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", + "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", + "dependencies": { + "abab": "^2.0.3", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/dayjs": { + "version": "1.11.8", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.8.tgz", + "integrity": "sha512-LcgxzFoWMEPO7ggRv1Y2N31hUf2R0Vj7fuy/m+Bg1K8rr+KAs1AEy4y9jd5DXe8pbHgX+srkHNS7TH6Q6ZhYeQ==" + }, + "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", @@ -7649,6 +8260,27 @@ "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==" }, + "node_modules/decode-named-character-reference": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz", + "integrity": "sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==", + "dependencies": { + "character-entities": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/decode-named-character-reference/node_modules/character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/dedent": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", @@ -7750,6 +8382,14 @@ "node": ">= 0.8" } }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "engines": { + "node": ">=6" + } + }, "node_modules/destroy": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", @@ -7806,6 +8446,14 @@ "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==" }, + "node_modules/diff": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz", + "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==", + "engines": { + "node": ">=0.3.1" + } + }, "node_modules/diff-sequences": { "version": "29.4.3", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", @@ -7936,6 +8584,11 @@ "url": "https://github.com/fb55/domhandler?sponsor=1" } }, + "node_modules/dompurify": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.0.6.tgz", + "integrity": "sha512-ilkD8YEnnGh1zJ240uJsW7AzE+2qpbOUYjacomn3AvJ6J4JhKGSZ2nh4wUIXPZrEPppaCLx5jFe8T89Rk8tQ7w==" + }, "node_modules/domutils": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", @@ -8003,6 +8656,11 @@ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.421.tgz", "integrity": "sha512-wZOyn3s/aQOtLGAwXMZfteQPN68kgls2wDAnYOA8kCjBvKVrW5RwmWVspxJYTqrcN7Y263XJVsC66VCIGzDO3g==" }, + "node_modules/elkjs": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/elkjs/-/elkjs-0.8.2.tgz", + "integrity": "sha512-L6uRgvZTH+4OF5NE/MBbzQx/WYpru1xCBE9respNj6qznEewGUIfhzmm7horWWxbNO2M0WckQypGctR8lH79xQ==" + }, "node_modules/emittery": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", @@ -9817,6 +10475,11 @@ "he": "bin/he" } }, + "node_modules/heap": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/heap/-/heap-0.2.7.tgz", + "integrity": "sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==" + }, "node_modules/highlight.js": { "version": "10.7.3", "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", @@ -12725,11 +13388,10 @@ "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-3.1.2.tgz", "integrity": "sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A==" }, - "node_modules/keycharm": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/keycharm/-/keycharm-0.4.0.tgz", - "integrity": "sha512-TyQTtsabOVv3MeOpR92sIKk/br9wxS+zGj4BG7CR8YbK4jM3tyIBaF0zhzeBUMx36/Q/iQLOKKOT+3jOQtemRQ==", - "peer": true + "node_modules/khroma": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/khroma/-/khroma-2.1.0.tgz", + "integrity": "sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==" }, "node_modules/kind-of": { "version": "6.0.3", @@ -12777,6 +13439,11 @@ "shell-quote": "^1.7.3" } }, + "node_modules/layout-base": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/layout-base/-/layout-base-1.0.2.tgz", + "integrity": "sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==" + }, "node_modules/leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -12850,6 +13517,11 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" + }, "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", @@ -12961,6 +13633,41 @@ "tmpl": "1.0.5" } }, + "node_modules/mdast-util-from-markdown": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.1.tgz", + "integrity": "sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==", + "dependencies": { + "@types/mdast": "^3.0.0", + "@types/unist": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "mdast-util-to-string": "^3.1.0", + "micromark": "^3.0.0", + "micromark-util-decode-numeric-character-reference": "^1.0.0", + "micromark-util-decode-string": "^1.0.0", + "micromark-util-normalize-identifier": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "unist-util-stringify-position": "^3.0.0", + "uvu": "^0.5.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz", + "integrity": "sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==", + "dependencies": { + "@types/mdast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/mdn-data": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", @@ -13003,6 +13710,46 @@ "node": ">= 8" } }, + "node_modules/mermaid": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-10.6.0.tgz", + "integrity": "sha512-Hcti+Q2NiWnb2ZCijSX89Bn2i7TCUwosBdIn/d+u63Sz7y40XU6EKMctT4UX4qZuZGfKGZpfOeim2/KTrdR7aQ==", + "dependencies": { + "@braintree/sanitize-url": "^6.0.1", + "@types/d3-scale": "^4.0.3", + "@types/d3-scale-chromatic": "^3.0.0", + "cytoscape": "^3.23.0", + "cytoscape-cose-bilkent": "^4.1.0", + "cytoscape-fcose": "^2.1.0", + "d3": "^7.4.0", + "d3-sankey": "^0.12.3", + "dagre-d3-es": "7.0.10", + "dayjs": "^1.11.7", + "dompurify": "^3.0.5", + "elkjs": "^0.8.2", + "khroma": "^2.0.0", + "lodash-es": "^4.17.21", + "mdast-util-from-markdown": "^1.3.0", + "non-layered-tidy-tree-layout": "^2.0.2", + "stylis": "^4.1.3", + "ts-dedent": "^2.2.0", + "uuid": "^9.0.0", + "web-worker": "^1.2.0" + } + }, + "node_modules/mermaid/node_modules/@types/d3-scale": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.6.tgz", + "integrity": "sha512-lo3oMLSiqsQUovv8j15X4BNEDOsnHuGjeVg7GRbAuB2PUa1prK5BNSOu6xixgNf3nqxPl4I1BqJWrPvFGlQoGQ==", + "dependencies": { + "@types/d3-time": "*" + } + }, + "node_modules/mermaid/node_modules/@types/d3-scale-chromatic": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.0.1.tgz", + "integrity": "sha512-Ob7OrwiTeQXY/WBBbRHGZBOn6rH1h7y3jjpTSKYqDEeqFjktql6k2XSgNwLrLDmAsXhEn8P9NHDY4VTuo0ZY1w==" + }, "node_modules/methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", @@ -13011,6 +13758,427 @@ "node": ">= 0.6" } }, + "node_modules/micromark": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-3.2.0.tgz", + "integrity": "sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "micromark-core-commonmark": "^1.0.1", + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-chunked": "^1.0.0", + "micromark-util-combine-extensions": "^1.0.0", + "micromark-util-decode-numeric-character-reference": "^1.0.0", + "micromark-util-encode": "^1.0.0", + "micromark-util-normalize-identifier": "^1.0.0", + "micromark-util-resolve-all": "^1.0.0", + "micromark-util-sanitize-uri": "^1.0.0", + "micromark-util-subtokenize": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.1", + "uvu": "^0.5.0" + } + }, + "node_modules/micromark-core-commonmark": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-1.1.0.tgz", + "integrity": "sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-factory-destination": "^1.0.0", + "micromark-factory-label": "^1.0.0", + "micromark-factory-space": "^1.0.0", + "micromark-factory-title": "^1.0.0", + "micromark-factory-whitespace": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-chunked": "^1.0.0", + "micromark-util-classify-character": "^1.0.0", + "micromark-util-html-tag-name": "^1.0.0", + "micromark-util-normalize-identifier": "^1.0.0", + "micromark-util-resolve-all": "^1.0.0", + "micromark-util-subtokenize": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.1", + "uvu": "^0.5.0" + } + }, + "node_modules/micromark-factory-destination": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-1.1.0.tgz", + "integrity": "sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-factory-label": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-1.1.0.tgz", + "integrity": "sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "uvu": "^0.5.0" + } + }, + "node_modules/micromark-factory-space": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz", + "integrity": "sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-factory-title": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-1.1.0.tgz", + "integrity": "sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-factory-whitespace": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-1.1.0.tgz", + "integrity": "sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-util-character": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz", + "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-util-chunked": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-1.1.0.tgz", + "integrity": "sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^1.0.0" + } + }, + "node_modules/micromark-util-classify-character": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-1.1.0.tgz", + "integrity": "sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-util-combine-extensions": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.1.0.tgz", + "integrity": "sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-chunked": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.1.0.tgz", + "integrity": "sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^1.0.0" + } + }, + "node_modules/micromark-util-decode-string": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-1.1.0.tgz", + "integrity": "sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-decode-numeric-character-reference": "^1.0.0", + "micromark-util-symbol": "^1.0.0" + } + }, + "node_modules/micromark-util-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-1.1.0.tgz", + "integrity": "sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-html-tag-name": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.2.0.tgz", + "integrity": "sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-normalize-identifier": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.1.0.tgz", + "integrity": "sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^1.0.0" + } + }, + "node_modules/micromark-util-resolve-all": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-1.1.0.tgz", + "integrity": "sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.2.0.tgz", + "integrity": "sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-encode": "^1.0.0", + "micromark-util-symbol": "^1.0.0" + } + }, + "node_modules/micromark-util-subtokenize": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-1.1.0.tgz", + "integrity": "sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-chunked": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "uvu": "^0.5.0" + } + }, + "node_modules/micromark-util-symbol": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", + "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", + "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, "node_modules/micromatch": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", @@ -13171,6 +14339,14 @@ "mkdirp": "bin/cmd.js" } }, + "node_modules/mri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", + "engines": { + "node": ">=4" + } + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -13265,6 +14441,11 @@ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.12.tgz", "integrity": "sha512-QzsYKWhXTWx8h1kIvqfnC++o0pEmpRQA/aenALsL2F4pqNVr7YzcdMlDij5WBnwftRbJCNJL/O7zdKaxKPHqgQ==" }, + "node_modules/non-layered-tidy-tree-layout": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/non-layered-tidy-tree-layout/-/non-layered-tidy-tree-layout-2.0.2.tgz", + "integrity": "sha512-gkXMxRzUH+PB0ax9dUN0yYF0S25BqeAYqhgMaLUFmpXLEk7Fcu8f4emJuOAY0V8kjDICxROIKsTAKsV/v355xw==" + }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -15917,6 +17098,11 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/robust-predicates": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz", + "integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==" + }, "node_modules/rollup": { "version": "2.79.1", "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", @@ -15989,6 +17175,22 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/rw": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", + "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==" + }, + "node_modules/sade": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", + "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", + "dependencies": { + "mri": "^1.1.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/safe-array-concat": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.0.tgz", @@ -17208,12 +18410,6 @@ "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==" }, - "node_modules/timsort": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", - "integrity": "sha512-qsdtZH+vMoCARQtyod4imc2nIJwg9Cc7lPRrw9CzF8ZKR0khdr8+2nX80PBhET3tcyTtJDxAffGh2rXH4tyU8A==", - "peer": true - }, "node_modules/tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", @@ -17284,6 +18480,14 @@ "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz", "integrity": "sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==" }, + "node_modules/ts-dedent": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz", + "integrity": "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==", + "engines": { + "node": ">=6.10" + } + }, "node_modules/ts-interface-checker": { "version": "0.1.13", "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", @@ -17406,19 +18610,6 @@ "is-typedarray": "^1.0.0" } }, - "node_modules/typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", - "peer": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, "node_modules/ua-parser-js": { "version": "1.0.35", "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.35.tgz", @@ -17498,6 +18689,18 @@ "node": ">=8" } }, + "node_modules/unist-util-stringify-position": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz", + "integrity": "sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/universalify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", @@ -17607,14 +18810,42 @@ } }, "node_modules/uuid": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", - "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", - "peer": true, + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], "bin": { "uuid": "dist/bin/uuid" } }, + "node_modules/uvu": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/uvu/-/uvu-0.5.6.tgz", + "integrity": "sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==", + "dependencies": { + "dequal": "^2.0.0", + "diff": "^5.0.0", + "kleur": "^4.0.3", + "sade": "^1.7.3" + }, + "bin": { + "uvu": "bin.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/uvu/node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "engines": { + "node": ">=6" + } + }, "node_modules/v8-to-istanbul": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", @@ -17677,23 +18908,6 @@ "vis-util": "^5.0.1" } }, - "node_modules/vis-util": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/vis-util/-/vis-util-5.0.3.tgz", - "integrity": "sha512-Wf9STUcFrDzK4/Zr7B6epW2Kvm3ORNWF+WiwEz2dpf5RdWkLUXFSbLcuB88n1W6tCdFwVN+v3V4/Xmn9PeL39g==", - "peer": true, - "engines": { - "node": ">=8" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/visjs" - }, - "peerDependencies": { - "@egjs/hammerjs": "^2.0.0", - "component-emitter": "^1.3.0" - } - }, "node_modules/vue": { "version": "3.3.4", "resolved": "https://registry.npmjs.org/vue/-/vue-3.3.4.tgz", @@ -17784,6 +18998,11 @@ "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-2.1.4.tgz", "integrity": "sha512-sVWcwhU5mX6crfI5Vd2dC4qchyTqxV8URinzt25XqVh+bHEPGH4C3NPrNionCP7Obx59wrYEbNlw4Z8sjALzZg==" }, + "node_modules/web-worker": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.2.0.tgz", + "integrity": "sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA==" + }, "node_modules/webidl-conversions": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", diff --git a/frontend/package.json b/frontend/package.json index e78ef6d..2cfd7aa 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -6,17 +6,20 @@ "dependencies": { "@emotion/react": "^11.11.0", "@emotion/styled": "^11.11.0", - "@mui/icons-material": "^5.11.16", + "@material/icon-button": "^14.0.0", + "@mui/icons-material": "^5.14.16", "@mui/material": "^5.13.4", "@nivo/bar": "^0.83.0", "@nivo/core": "^0.83.0", "@nivo/line": "^0.83.0", + "@passageidentity/passage-auth": "^0.1.0-beta.28", "@passageidentity/passage-elements": "^1.9.2", "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", "axios": "^1.4.0", "dotenv": "^16.3.1", + "mermaid": "^10.6.0", "react": "^18.2.0", "react-dom": "^18.2.0", "react-graph-vis": "^1.0.7", diff --git a/frontend/public/favicon.ico b/frontend/public/favicon.ico deleted file mode 100644 index a11777cc471a4344702741ab1c8a588998b1311a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3870 zcma);c{J4h9>;%nil|2-o+rCuEF-(I%-F}ijC~o(k~HKAkr0)!FCj~d>`RtpD?8b; zXOC1OD!V*IsqUwzbMF1)-gEDD=A573Z-&G7^LoAC9|WO7Xc0Cx1g^Zu0u_SjAPB3vGa^W|sj)80f#V0@M_CAZTIO(t--xg= z!sii`1giyH7EKL_+Wi0ab<)&E_0KD!3Rp2^HNB*K2@PHCs4PWSA32*-^7d{9nH2_E zmC{C*N*)(vEF1_aMamw2A{ZH5aIDqiabnFdJ|y0%aS|64E$`s2ccV~3lR!u<){eS` z#^Mx6o(iP1Ix%4dv`t@!&Za-K@mTm#vadc{0aWDV*_%EiGK7qMC_(`exc>-$Gb9~W!w_^{*pYRm~G zBN{nA;cm^w$VWg1O^^<6vY`1XCD|s_zv*g*5&V#wv&s#h$xlUilPe4U@I&UXZbL z0)%9Uj&@yd03n;!7do+bfixH^FeZ-Ema}s;DQX2gY+7g0s(9;`8GyvPY1*vxiF&|w z>!vA~GA<~JUqH}d;DfBSi^IT*#lrzXl$fNpq0_T1tA+`A$1?(gLb?e#0>UELvljtQ zK+*74m0jn&)5yk8mLBv;=@}c{t0ztT<v;Avck$S6D`Z)^c0(jiwKhQsn|LDRY&w(Fmi91I7H6S;b0XM{e zXp0~(T@k_r-!jkLwd1_Vre^v$G4|kh4}=Gi?$AaJ)3I+^m|Zyj#*?Kp@w(lQdJZf4 z#|IJW5z+S^e9@(6hW6N~{pj8|NO*>1)E=%?nNUAkmv~OY&ZV;m-%?pQ_11)hAr0oAwILrlsGawpxx4D43J&K=n+p3WLnlDsQ$b(9+4 z?mO^hmV^F8MV{4Lx>(Q=aHhQ1){0d*(e&s%G=i5rq3;t{JC zmgbn5Nkl)t@fPH$v;af26lyhH!k+#}_&aBK4baYPbZy$5aFx4}ka&qxl z$=Rh$W;U)>-=S-0=?7FH9dUAd2(q#4TCAHky!$^~;Dz^j|8_wuKc*YzfdAht@Q&ror?91Dm!N03=4=O!a)I*0q~p0g$Fm$pmr$ zb;wD;STDIi$@M%y1>p&_>%?UP($15gou_ue1u0!4(%81;qcIW8NyxFEvXpiJ|H4wz z*mFT(qVx1FKufG11hByuX%lPk4t#WZ{>8ka2efjY`~;AL6vWyQKpJun2nRiZYDij$ zP>4jQXPaP$UC$yIVgGa)jDV;F0l^n(V=HMRB5)20V7&r$jmk{UUIe zVjKroK}JAbD>B`2cwNQ&GDLx8{pg`7hbA~grk|W6LgiZ`8y`{Iq0i>t!3p2}MS6S+ zO_ruKyAElt)rdS>CtF7j{&6rP-#c=7evGMt7B6`7HG|-(WL`bDUAjyn+k$mx$CH;q2Dz4x;cPP$hW=`pFfLO)!jaCL@V2+F)So3}vg|%O*^T1j>C2lx zsURO-zIJC$^$g2byVbRIo^w>UxK}74^TqUiRR#7s_X$e)$6iYG1(PcW7un-va-S&u zHk9-6Zn&>T==A)lM^D~bk{&rFzCi35>UR!ZjQkdSiNX*-;l4z9j*7|q`TBl~Au`5& z+c)*8?#-tgUR$Zd%Q3bs96w6k7q@#tUn`5rj+r@_sAVVLqco|6O{ILX&U-&-cbVa3 zY?ngHR@%l{;`ri%H*0EhBWrGjv!LE4db?HEWb5mu*t@{kv|XwK8?npOshmzf=vZA@ zVSN9sL~!sn?r(AK)Q7Jk2(|M67Uy3I{eRy z_l&Y@A>;vjkWN5I2xvFFTLX0i+`{qz7C_@bo`ZUzDugfq4+>a3?1v%)O+YTd6@Ul7 zAfLfm=nhZ`)P~&v90$&UcF+yXm9sq!qCx3^9gzIcO|Y(js^Fj)Rvq>nQAHI92ap=P z10A4@prk+AGWCb`2)dQYFuR$|H6iDE8p}9a?#nV2}LBCoCf(Xi2@szia7#gY>b|l!-U`c}@ zLdhvQjc!BdLJvYvzzzngnw51yRYCqh4}$oRCy-z|v3Hc*d|?^Wj=l~18*E~*cR_kU z{XsxM1i{V*4GujHQ3DBpl2w4FgFR48Nma@HPgnyKoIEY-MqmMeY=I<%oG~l!f<+FN z1ZY^;10j4M4#HYXP zw5eJpA_y(>uLQ~OucgxDLuf}fVs272FaMxhn4xnDGIyLXnw>Xsd^J8XhcWIwIoQ9} z%FoSJTAGW(SRGwJwb=@pY7r$uQRK3Zd~XbxU)ts!4XsJrCycrWSI?e!IqwqIR8+Jh zlRjZ`UO1I!BtJR_2~7AbkbSm%XQqxEPkz6BTGWx8e}nQ=w7bZ|eVP4?*Tb!$(R)iC z9)&%bS*u(lXqzitAN)Oo=&Ytn>%Hzjc<5liuPi>zC_nw;Z0AE3Y$Jao_Q90R-gl~5 z_xAb2J%eArrC1CN4G$}-zVvCqF1;H;abAu6G*+PDHSYFx@Tdbfox*uEd3}BUyYY-l zTfEsOqsi#f9^FoLO;ChK<554qkri&Av~SIM*{fEYRE?vH7pTAOmu2pz3X?Wn*!ROX ztd54huAk&mFBemMooL33RV-*1f0Q3_(7hl$<#*|WF9P!;r;4_+X~k~uKEqdzZ$5Al zV63XN@)j$FN#cCD;ek1R#l zv%pGrhB~KWgoCj%GT?%{@@o(AJGt*PG#l3i>lhmb_twKH^EYvacVY-6bsCl5*^~L0 zonm@lk2UvvTKr2RS%}T>^~EYqdL1q4nD%0n&Xqr^cK^`J5W;lRRB^R-O8b&HENO||mo0xaD+S=I8RTlIfVgqN@SXDr2&-)we--K7w= zJVU8?Z+7k9dy;s;^gDkQa`0nz6N{T?(A&Iz)2!DEecLyRa&FI!id#5Z7B*O2=PsR0 zEvc|8{NS^)!d)MDX(97Xw}m&kEO@5jqRaDZ!+%`wYOI<23q|&js`&o4xvjP7D_xv@ z5hEwpsp{HezI9!~6O{~)lLR@oF7?J7i>1|5a~UuoN=q&6N}EJPV_GD`&M*v8Y`^2j zKII*d_@Fi$+i*YEW+Hbzn{iQk~yP z>7N{S4)r*!NwQ`(qcN#8SRQsNK6>{)X12nbF`*7#ecO7I)Q$uZsV+xS4E7aUn+U(K baj7?x%VD!5Cxk2YbYLNVeiXvvpMCWYo=by@ diff --git a/frontend/public/index.html b/frontend/public/index.html index aa069f2..af0101c 100644 --- a/frontend/public/index.html +++ b/frontend/public/index.html @@ -24,20 +24,10 @@ work correctly both with client-side routing and a non-root public URL. Learn how to configure a non-root public URL by running `npm run build`. --> - React App + XFaaS
- diff --git a/frontend/public/manifest.json b/frontend/public/manifest.json index 080d6c7..fc7ce89 100644 --- a/frontend/public/manifest.json +++ b/frontend/public/manifest.json @@ -22,4 +22,4 @@ "display": "standalone", "theme_color": "#000000", "background_color": "#ffffff" -} +} \ No newline at end of file diff --git a/frontend/src/App.css b/frontend/src/App.css index 179572f..fd2a964 100644 --- a/frontend/src/App.css +++ b/frontend/src/App.css @@ -1,7 +1,11 @@ +* { + margin: 0px; + box-sizing: border-box; + scroll-behavior: smooth; +} -.App-header { - - height: 20vh; +.App-header { + height: 40vh; display: flex; flex-direction: column; align-items: center; @@ -9,11 +13,9 @@ color: white; } -/* -.App-link { - color: #61dafb; -} */ - +.App{ + margin: auto; +} .button-container { display: flex; @@ -22,15 +24,3 @@ margin-top: 5%; margin-bottom: 2% } - - -.FooterBox { - font-size: medium; - display: flex; - width: 100%; - height: 100px; - padding: 20px; - margin-top: 20px; - color:black; - -} diff --git a/frontend/src/App.js b/frontend/src/App.js index 316c38d..b7bac8c 100644 --- a/frontend/src/App.js +++ b/frontend/src/App.js @@ -1,55 +1,22 @@ import AllwfTable from './components/Allwf'; import ResponsiveAppBar from './components/App-bar'; import "./App.css"; -import Welcome from './components/Welcome'; import { useMode } from './theme'; import {Box, ThemeProvider} from "@mui/material" -import { useAuthStatus } from './hooks/useAuthStatus'; -import { useEffect,useState } from 'react'; - +import TypewriterEffect from './TypeWriterEffect'; function App() { const [theme]=useMode(); - const [result,setResult]=useAuthStatus(); - const {isLoading,isAuthorized,username}=result; - const [showApp, setShowApp] = useState(false); - console.log(isAuthorized); - - useEffect(() => { - const timer = setTimeout(() => { - setShowApp(true); - }, 2000); - - return () => clearTimeout(timer); - }, []); return ( - - - -
- -
-
- -
- {/* {isAuthorized? -
- -
+ + +
+ +
- -
- : showApp?( <> - -

...404...

-
...NOT AUTHORISED USER...
-
-):(<>) -} */} - - + ); } diff --git a/frontend/src/TypeWriterEffect.css b/frontend/src/TypeWriterEffect.css new file mode 100644 index 0000000..bc1cfd3 --- /dev/null +++ b/frontend/src/TypeWriterEffect.css @@ -0,0 +1,21 @@ +.typewriter-container { + text-align: center; + padding: 20px; + } + + .typewriter-text { + font-size: 24px; + font-weight: bold; + white-space: nowrap; + border-right: 3px solid transparent; /* Set the border to transparent */ + } + + @keyframes typing { + from { + width: 0; + } + to { + width: 100%; + } + } + \ No newline at end of file diff --git a/frontend/src/TypeWriterEffect.jsx b/frontend/src/TypeWriterEffect.jsx new file mode 100644 index 0000000..0805117 --- /dev/null +++ b/frontend/src/TypeWriterEffect.jsx @@ -0,0 +1,26 @@ +import React, { useState, useEffect } from 'react'; +import './TypeWriterEffect.css'; // Import the CSS file for styling + +const TypewriterEffect = ({ text }) => { + const [displayedText, setDisplayedText] = useState(''); + const [currentIndex, setCurrentIndex] = useState(0); + + useEffect(() => { + const typingInterval = 100; // Adjust typing speed (milliseconds) + + if (currentIndex < text.length) { + setTimeout(() => { + setDisplayedText(text.slice(0, currentIndex + 1)); + setCurrentIndex(currentIndex + 1); + }, typingInterval); + } + }, [currentIndex, text]); + + return ( +
+

{displayedText}

+
+ ); +}; + +export default TypewriterEffect; diff --git a/frontend/src/components/Allwf.jsx b/frontend/src/components/Allwf.jsx index b9a92a4..58a061a 100644 --- a/frontend/src/components/Allwf.jsx +++ b/frontend/src/components/Allwf.jsx @@ -1,4 +1,110 @@ -import React, { useEffect } from 'react'; +// import React, { useEffect } from 'react'; +// import Paper from '@mui/material/Paper'; +// import Table from '@mui/material/Table'; +// import TableBody from '@mui/material/TableBody'; +// import TableCell from '@mui/material/TableCell'; +// import TableContainer from '@mui/material/TableContainer'; +// import TableHead from '@mui/material/TableHead'; +// import TablePagination from '@mui/material/TablePagination'; +// import TableRow from '@mui/material/TableRow'; +// import { Link} from 'react-router-dom'; +// import axios from 'axios' + +// const columns = [ +// { id: 'workflowID', label: 'Workflow ID', align: 'center', minWidth: 80 }, +// { id: 'workflow', label: 'Workflow Name', align: 'center', minWidth: 80 }, +// ]; + +// function createData(workflowID,workflow) { +// return {workflowID,workflow}; +// } + + + +// export default function AllwfTable() { +// const [page, setPage] = React.useState(0); +// const [rowsPerPage, setRowsPerPage] = React.useState(5); +// const [rows,setRows]=React.useState([]); + +// const handleChangePage = (event, newPage) => { +// setPage(newPage); +// }; + +// const handleChangeRowsPerPage = (event) => { +// setRowsPerPage(+event.target.value); +// setPage(0); +// }; +// React.useEffect(()=>{ +// axios.get('/api/allWorkflows').then(response=>{ +// var rows=[] +// response.data.forEach(ele=>{ +// rows.push(createData(ele["wfId"],ele["workflowName"])) +// }); +// setRows(rows); +// }).catch(err=>{ +// console.error(err) +// }) +// },[]) + + +// return ( +// +// +// +// +// +// {columns.map((column) => ( +// +// {column.label} +// +// ))} +// +// +// +// {rows +// .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) +// .map((row) => { +// return ( +// + +// +// +// {row[columns[0].id]} +// {/* {row[columns[0].id]} */} +// + +// +// +// {row[columns[1].id]} +// {/* {row[columns[1].id]} */} +// + +// +// ); +// })} +// +//
+//
+// +//
+// ); +// } + +import React, { useEffect, useState } from 'react'; import Paper from '@mui/material/Paper'; import Table from '@mui/material/Table'; import TableBody from '@mui/material/TableBody'; @@ -7,25 +113,23 @@ import TableContainer from '@mui/material/TableContainer'; import TableHead from '@mui/material/TableHead'; import TablePagination from '@mui/material/TablePagination'; import TableRow from '@mui/material/TableRow'; -import { Link } from 'react-router-dom'; -import axios from 'axios' +import { Link } from 'react-router-dom'; +import axios from 'axios'; const columns = [ - { id: 'workflowID', label: 'Workflows ID', align: 'center', minWidth: 80 }, - { id: 'workflow', label: 'All workflows', align: 'center', minWidth: 80 }, - { id: 'time', label: 'Executed at', align: 'center', minWidth:80}, + { id: 'workflowID', label: 'Workflow ID', align: 'center', minWidth: 80 }, + { id: 'workflow', label: 'Workflow Name', align: 'center', minWidth: 80 }, ]; -function createData(workflowID,workflow, time) { - return {workflowID,workflow,time}; +function createData(workflowID, workflow) { + return { workflowID, workflow }; } - - export default function AllwfTable() { - const [page, setPage] = React.useState(0); - const [rowsPerPage, setRowsPerPage] = React.useState(5); - const [rows,setRows]=React.useState([]); + const [page, setPage] = useState(0); + const [rowsPerPage, setRowsPerPage] = useState(5); + const [rows, setRows] = useState([]); + const [searchQuery, setSearchQuery] = useState(''); const handleChangePage = (event, newPage) => { setPage(newPage); @@ -35,75 +139,108 @@ export default function AllwfTable() { setRowsPerPage(+event.target.value); setPage(0); }; - React.useEffect(()=>{ - axios.get('/api/allWorkflows').then(response=>{ - console.log(response) - var rows=[] - response.data.forEach(ele=>{ - rows.push(createData(ele["wfId"],ele["workflowName"],0)) - }); - setRows(rows); - }).catch(err=>{ - console.error(err) - }) - - },[]) - + useEffect(() => { + axios.get('/api/allWorkflows') + .then(response => { + const newRows = response.data.map(ele => createData(ele['wfId'], ele['workflowName'])); + setRows(newRows); + }) + .catch(err => { + console.error(err); + }); + }, []); - + // Create a function that filters rows based on the search query + const filteredRows = rows.filter((row) => { + const lowerCaseSearchQuery = searchQuery.toLowerCase(); + return ( + row.workflowID.toString().toLowerCase().includes(lowerCaseSearchQuery) || + row.workflow.toLowerCase().includes(lowerCaseSearchQuery) + ); + }); return ( - - - - - - {columns.map((column) => ( + +
+ setSearchQuery(e.target.value)} + style={{ + fontSize: '1rem', + padding: '8px', + width: '300px', // Adjust width as needed + height: '40px', // Adjust height as needed + background: 'black', + color: 'white', + border: 'none', + boxShadow: 'inset 0 0 5px rgba(0, 0, 0, 0.5), 0 0 5px rgba(255, 255, 255, 0.5)', + borderRadius: '10px' + }} + /> +
+ +
+ + + {columns.map((column) => ( + + {column.label} + + ))} + + + + {filteredRows + .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) + .map((row) => { + return ( + - {column.label} + + {row.workflowID} + - - ))} - - - - {rows - .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) - .map((row) => { - return ( - - - {row[columns[0].id]} - - - - {row[columns[1].id]} - - - {row[columns[2].id]} - - - ); - })} - -
-
- - -
- + + + {row.workflow} + + + + ); + })} + + + + + ); } diff --git a/frontend/src/components/App-bar.jsx b/frontend/src/components/App-bar.jsx index 70d08c7..f27bfae 100644 --- a/frontend/src/components/App-bar.jsx +++ b/frontend/src/components/App-bar.jsx @@ -17,12 +17,11 @@ import { useAuthStatus } from '../hooks/useAuthStatus'; -const pages = ['Main', 'About Us', 'Contact']; +const pages = ['Home', 'About Us', 'Contact']; const settings = ['Profile', 'Logout']; function ResponsiveAppBar() { const navigate = useNavigate(); - // const dispatch=useDispatch(); const [anchorElNav, setAnchorElNav] = React.useState(null); const [anchorElUser, setAnchorElUser] = React.useState(null); const [result,setResult]=useAuthStatus(); @@ -44,7 +43,6 @@ function ResponsiveAppBar() { isAuthorized: false, username: "", }); - // dispatch(setLogout()) navigate("/"); }; @@ -53,12 +51,11 @@ function ResponsiveAppBar() { - - XFAAS - + >XFaaS - + ({ - width: '70%', - padding: theme.spacing(2), - backgroundColor: theme.palette.background.default, - opacity: 0, - transition: 'opacity 1s ease', -})); - -const Welcome = () => { - const [showText, setShowText] = useState(false); - - useEffect(() => { - // Delay the appearance of the text - const timer = setTimeout(() => { - setShowText(true); - }, 1000); - - return () => clearTimeout(timer); - }, []); - - return ( - -
-
- - {showText && ( -

Manage your workflows

with XFaaS

- - )} - -
-
-
-
- ); - }; - - -export default Welcome; diff --git a/frontend/src/index.js b/frontend/src/index.js index 4c7db37..d6f92c5 100644 --- a/frontend/src/index.js +++ b/frontend/src/index.js @@ -8,28 +8,20 @@ import { BrowserRouter as Router, Route, Routes } from 'react-router-dom'; import CodeViewer from './components/CodeViewer'; import InvocationsPage from './InvocationsPage'; import Invocation from './scenes/invocations/Invocation'; -import Login from './scenes/login/Login'; import InvocationDetails from './scenes/invocations/InvocationDetails'; - const root = ReactDOM.createRoot(document.getElementById('root')); -root.render( - +root.render( - {/* } /> */} - } /> + } /> }/> } /> } /> } /> - } /> - - + } /> - - ); reportWebVitals(); diff --git a/frontend/src/setupTests.js b/frontend/src/setupTests.js index 8f2609b..b28b910 100644 --- a/frontend/src/setupTests.js +++ b/frontend/src/setupTests.js @@ -2,4 +2,4 @@ // allows you to do things like: // expect(element).toHaveTextContent(/react/i) // learn more: https://github.com/testing-library/jest-dom -import '@testing-library/jest-dom'; +import '@testing-library/jest-dom'; \ No newline at end of file From 10ceed24b7118f0655b6252cf2b4d7137f2e06c9 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 7 Nov 2023 21:43:41 +0530 Subject: [PATCH 04/19] added css to wf page --- frontend/src/App.js | 2 +- frontend/src/InvocationsPage.js | 4 +- frontend/src/components/DeployTable.jsx | 192 ++++++++++-------- frontend/src/components/MermaidDiagram.css | 7 +- .../src/{ => components}/TypeWriterEffect.css | 0 .../src/{ => components}/TypeWriterEffect.jsx | 0 frontend/src/components/Wf.css | 123 ++++------- frontend/src/components/Wf.jsx | 60 +++--- 8 files changed, 194 insertions(+), 194 deletions(-) rename frontend/src/{ => components}/TypeWriterEffect.css (100%) rename frontend/src/{ => components}/TypeWriterEffect.jsx (100%) diff --git a/frontend/src/App.js b/frontend/src/App.js index b7bac8c..a8d8310 100644 --- a/frontend/src/App.js +++ b/frontend/src/App.js @@ -3,7 +3,7 @@ import ResponsiveAppBar from './components/App-bar'; import "./App.css"; import { useMode } from './theme'; import {Box, ThemeProvider} from "@mui/material" -import TypewriterEffect from './TypeWriterEffect'; +import TypewriterEffect from './components/TypeWriterEffect'; function App() { const [theme]=useMode(); diff --git a/frontend/src/InvocationsPage.js b/frontend/src/InvocationsPage.js index b2b904f..e2cb1b0 100644 --- a/frontend/src/InvocationsPage.js +++ b/frontend/src/InvocationsPage.js @@ -76,8 +76,8 @@ const GraphWrapper = ({depdetails}) => { setGraphdet(ref); setGraph(ref.graphs) - console.log("all logging"); - console.log(ref); + // console.log("all logging"); + // console.log(ref); }) .catch(error => { diff --git a/frontend/src/components/DeployTable.jsx b/frontend/src/components/DeployTable.jsx index 773acfb..edd1c90 100644 --- a/frontend/src/components/DeployTable.jsx +++ b/frontend/src/components/DeployTable.jsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useState, useEffect } from 'react'; import Paper from '@mui/material/Paper'; import Table from '@mui/material/Table'; import TableBody from '@mui/material/TableBody'; @@ -7,43 +7,32 @@ import TableContainer from '@mui/material/TableContainer'; import TableHead from '@mui/material/TableHead'; import TablePagination from '@mui/material/TablePagination'; import TableRow from '@mui/material/TableRow'; -import { Link, Navigate, useLocation, useNavigate } from 'react-router-dom'; -import Invocation from '../scenes/invocations/Invocation' -import { ListItem } from '@mui/material'; -import { useState } from 'react'; -import { useEffect } from 'react'; - +import { Link } from 'react-router-dom'; const columns = [ { id: 'wf_deployment_id', label: 'Deployment ID', align: 'center', minWidth: 170 }, { id: 'wf_deployment_time', label: 'Deployment Date/Time', align: 'center', minWidth: 100 }, - { id: 'wf_deployment_name', label: 'Deployment name', align: 'center', minWidth: 100 }, + { id: 'wf_deployment_name', label: 'Deployment Name', align: 'center', minWidth: 100 }, ]; function createData(wf_deployment_id, wf_deployment_time, wf_deployment_name) { - return {wf_deployment_id, wf_deployment_time, wf_deployment_name }; + return { wf_deployment_id, wf_deployment_time, wf_deployment_name }; } +export default function DeployTable({ alldep }) { + const [searchQuery, setSearchQuery] = useState(''); + const [rows, setRows] = useState([]); + const [page, setPage] = useState(0); + const [rowsPerPage, setRowsPerPage] = useState(10); -export default function DeployTable({alldep}) { - const location=useLocation(); - const [rows,setRows]=useState([]) - const [page, setPage] = React.useState(0); - const [rowsPerPage, setRowsPerPage] = React.useState(10); - - -// console.log(deparray) -const temprows=[] -useEffect(() => { + const temprows = []; - alldep.forEach((dep)=>{ - temprows.push(createData(dep.wf_deployment_id, dep.wf_deployment_time, dep.wf_deployment_name)); - }) - - setRows(temprows); -},[alldep]); - -console.log(rows); + useEffect(() => { + alldep.forEach((dep) => { + temprows.push(createData(dep.wf_deployment_id, dep.wf_deployment_time, dep.wf_deployment_name)); + }); + setRows(temprows); + }, [alldep]); const handleChangePage = (event, newPage) => { setPage(newPage); @@ -53,61 +42,104 @@ console.log(rows); setRowsPerPage(+event.target.value); setPage(0); }; - + + // Create a function that filters rows based on the search query + const filteredRows = rows.filter((row) => { + const lowerCaseSearchQuery = searchQuery.toLowerCase(); + return ( + row.wf_deployment_id.toString().toLowerCase().includes(lowerCaseSearchQuery) || + row.wf_deployment_name.toLowerCase().includes(lowerCaseSearchQuery) + ); + }); return ( - - - - - - {columns.map((column) => ( - +
+ setSearchQuery(e.target.value)} + style={{ + fontSize: '1rem', + padding: '8px', + width: '300px', + height: '40px', + background: 'black', + color: 'white', + border: 'none', + boxShadow: 'inset 0 0 5px rgba(0, 0, 0, 0.5), 0 0 5px rgba(255, 255, 255, 0.5)', + borderRadius: '10px', + }} + /> +
+ +
+ + + {columns.map((column) => ( + + {column.label} + + ))} + + + + {filteredRows + .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) + .map((row) => { + return ( + + + + {row.wf_deployment_id} + + + + {row.wf_deployment_time} + + + - {column.label} - - ))} + {row.wf_deployment_name} + + - - - {rows - .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) - .map((row) => { - return ( - - - - {row[columns[0].id]} - - - - {row[columns[1].id]} - - - {row[columns[2].id]} - - - ); - })} - -
-
- - -
- + ); + })} + + + + + ); -} - - +} \ No newline at end of file diff --git a/frontend/src/components/MermaidDiagram.css b/frontend/src/components/MermaidDiagram.css index 40e18ca..14d953e 100644 --- a/frontend/src/components/MermaidDiagram.css +++ b/frontend/src/components/MermaidDiagram.css @@ -1,7 +1,7 @@ /* Style the container for the Mermaid diagram */ .mermaid-container { width: 100%; /* Set the width as desired */ - height: 100%; /* Set the height as desired */ + height: 5rem; /* Set the height as desired */ margin: 0 auto; /* Center the diagram horizontally */ } @@ -17,3 +17,8 @@ .mermaid-container .edgePath path { stroke: #333; /* Example: Change the edge path stroke color */ } + +#mermaid-diagram{ + width: 100%; /* Set the width as desired */ + height: 20%; /* Set the height as desired */ +} \ No newline at end of file diff --git a/frontend/src/TypeWriterEffect.css b/frontend/src/components/TypeWriterEffect.css similarity index 100% rename from frontend/src/TypeWriterEffect.css rename to frontend/src/components/TypeWriterEffect.css diff --git a/frontend/src/TypeWriterEffect.jsx b/frontend/src/components/TypeWriterEffect.jsx similarity index 100% rename from frontend/src/TypeWriterEffect.jsx rename to frontend/src/components/TypeWriterEffect.jsx diff --git a/frontend/src/components/Wf.css b/frontend/src/components/Wf.css index 77d78d4..52b09ad 100644 --- a/frontend/src/components/Wf.css +++ b/frontend/src/components/Wf.css @@ -1,80 +1,45 @@ +* { + margin: 0px; + box-sizing: border-box; + scroll-behavior: smooth; +} -.wf-header { - - height: 20vh; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - color: white; - } - - - /* .App-link { - color: #61dafb; - } - */ - - .box-container { - display: flex; - flex-direction: column; - - position: absolute; - } - - .box { - display: flex; - width: 93%; - height: 43px; - border: 2px solid #000000; - border-radius: 20px; - padding: 20px; - margin: 20px; - background-color: #ffffff; - color: #000000; - - } - - .box1 { - display: flex; - width: 100%; - height: 40px; - border: 0px solid #e7d9d9; - padding: 20px; - margin: 20px; - background-color: #ffffff; - color: #000000; - margin-bottom: 5% - } - - .graphcontainer { - display: flex; - justify-content: center; - align-items: center; - height: 100vh; - } - - .graphbox{ - display: flex; - width: 60%; - height: 400px; - border: 2px solid rgb(0, 0, 0); - border-radius: 20px; - padding: 20px; - margin: 20px; - background-color: #ffffff; - margin: '0 auto'; - justify-content: center; - - } - - .FooterBox { - display: flex; - width: 100%; - height: 100px; - padding: 20px; - margin-top: 20px; - - color: #ffffff; - - } +.wf{ + margin: 2rem; +} + +.mermaidGraphh{ + margin: 2rem 0; + box-shadow: rgba(50, 50, 93, 0.25) 0px 6px 12px -2px, rgba(0, 0, 0, 0.3) 0px 3px 7px -3px; + border-radius: 10px; + overflow: hidden; + height: 95vh; +} + +.mermaidGraphhHeading{ + background-color: black; + color: white; + padding: 1rem; + font-size: 1.5rem; +} + +.graphcontainer { + display: flex; + justify-content: center; + align-items: center; + height: 100vh; +} + +.graphbox{ + display: flex; + width: 60%; + height: 400px; + border: 2px solid rgb(0, 0, 0); + border-radius: 20px; + padding: 20px; + margin: 20px; + background-color: #ffffff; + margin: '0 auto'; + justify-content: center; + +} \ No newline at end of file diff --git a/frontend/src/components/Wf.jsx b/frontend/src/components/Wf.jsx index 1aeeb0c..4dda349 100644 --- a/frontend/src/components/Wf.jsx +++ b/frontend/src/components/Wf.jsx @@ -355,10 +355,8 @@ // export default Wf; import './Wf.css'; -import Graph from 'react-graph-vis'; import DeploymentTable from './DeployTable'; import ResponsiveAppBar from './App-bar'; -import { useNavigate } from 'react-router-dom'; import { useMode } from '../theme'; import {ThemeProvider} from "@mui/material" import { useLocation } from 'react-router-dom'; @@ -366,6 +364,7 @@ import { useEffect, useState } from 'react'; import axios, { all } from 'axios'; //import MermaidDiagram from './MermaidDiagram.jsx'; import mermaid from 'mermaid'; +import './MermaidDiagram.css' function createData(wf_deployment_id, wf_deployment_time, wf_deployment_name) { return { wf_deployment_id, wf_deployment_time, wf_deployment_name }; @@ -411,7 +410,7 @@ const MermaidDiagram = ({ definition }) => { }, [mermaidInitialized]); return ( -
+
{mermaidInitialized ? (
{definition} @@ -474,35 +473,34 @@ const Wf = () => { const [theme]=useMode(); - return( - -
- - -
-

Workflow ID:

-
{wfdetails.wfid}
-
-
-

Workflow Name:

-
{wfdetails.wfname}
-
-
-

Workflow Description:

-
{wfdetails.WorkflowDescription}
-
- - + return( + + +
-
-

- -
- - - -
-
+ +
+
+

Workflow ID: {wfdetails.wfid}

+
+
+

Workflow Name: {wfdetails.wfname}

+
+
+

Workflow Description: {wfdetails.WorkflowDescription}

+
+
+ +
+
User Submitted Workflow
+

+ +
+ + + +
+
); }; From c2744db00f5b59e1c70d9008697de0b4f67f5d32 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 29 Dec 2023 18:51:50 +0530 Subject: [PATCH 05/19] styling 1.0 --- frontend/src/InvocationsPage.css | 66 +++++++++++--------------- frontend/src/InvocationsPage.js | 37 +++++++-------- frontend/src/components/GraphTable.css | 0 frontend/src/components/GraphTable.jsx | 59 +++++++++++++++++------ frontend/src/components/Wf.css | 2 +- 5 files changed, 91 insertions(+), 73 deletions(-) create mode 100644 frontend/src/components/GraphTable.css diff --git a/frontend/src/InvocationsPage.css b/frontend/src/InvocationsPage.css index 629e6d2..16849f9 100644 --- a/frontend/src/InvocationsPage.css +++ b/frontend/src/InvocationsPage.css @@ -1,41 +1,29 @@ -.header { - - height: 20vh; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - color: white; - } +.mermaidGraphh{ + margin: 2rem; + box-shadow: rgba(50, 50, 93, 0.25) 0px 6px 12px -2px, rgba(0, 0, 0, 0.3) 0px 3px 7px -3px; + border-radius: 10px; + overflow: hidden; + height: 95vh; +} - - .graphcontainer { - display: flex; - justify-content: center; - align-items: center; - height: 100vh; - } - - .graphbox{ - display: flex; - width: 80%; - height: 400px; - border: 1px solid gray; - border-radius: 30px; - padding: 20px; - margin: 20px; - background-color: #ced9ee; - margin: '0 auto'; - justify-content: center; - - } +.mermaidGraphhHeading{ + background-color: black; + color: white; + padding: 1rem; + font-size: 1.5rem; +} -.FooterBox { - display: flex; - width: 100%; - height: 100px; - padding: 20px; - margin-top: 20px; - color: #ffffff; - - } +/* For WebKit-based browsers (Chrome, Safari) */ +::-webkit-scrollbar { + width: 12px; /* Width of the scrollbar */ +} + +::-webkit-scrollbar-thumb { + background: rgba(0, 0, 0, 0.785); /* Color of the scrollbar thumb */ +} + +/* For Firefox */ +* { + scrollbar-width: thin; /* Show the scrollbar in Firefox */ + scrollbar-color: rgba(0, 0, 0, 0.785); /* Color of the thumb and the track */ +} \ No newline at end of file diff --git a/frontend/src/InvocationsPage.js b/frontend/src/InvocationsPage.js index e2cb1b0..33a0f55 100644 --- a/frontend/src/InvocationsPage.js +++ b/frontend/src/InvocationsPage.js @@ -133,17 +133,15 @@ const GraphWrapper = ({depdetails}) => { }; return ( - //
- //
- // - //
- //
- -
-

- -
- + //
+ //

+ // + //
+
+
User Submitted Workflow
+

+ +
); }; @@ -155,7 +153,7 @@ const GraphWrapper = ({depdetails}) => { function InvocationsPage() { const location=useLocation(); const [depdetails,setDepdetails]=useState({}) -const [deploymentId,setDeploymentId]=useState(""); + const [deploymentId,setDeploymentId]=useState(""); useEffect(()=>{ const params=new URLSearchParams(location.search); const depid=params.get("wf_deployment_id"); @@ -198,25 +196,26 @@ const [theme]=useMode(); color="primary" size="large" variant="outlined" - onClick={handlegraphClick}>Graph View + onClick={handlegraphClick} + style={{backgroundColor:'black', color: 'white'}}>Graph View
- {activeComponent === 'GraphWrapper' ? : } - -
- + {activeComponent === 'GraphWrapper' ? : } +
diff --git a/frontend/src/components/GraphTable.css b/frontend/src/components/GraphTable.css new file mode 100644 index 0000000..e69de29 diff --git a/frontend/src/components/GraphTable.jsx b/frontend/src/components/GraphTable.jsx index 58d8a44..6bd38f9 100644 --- a/frontend/src/components/GraphTable.jsx +++ b/frontend/src/components/GraphTable.jsx @@ -13,7 +13,7 @@ import { useLocation } from "react-router-dom"; const columns = [ { id: 'Label', label: 'Label', align: 'center', minWidth: 100 }, - { id: 'ID', label: 'Func ID', align: 'center', minWidth: 170 }, + { id: 'ID', label: 'Function ID', align: 'center', minWidth: 170 }, { id: 'CSP', label: 'CSP', align: 'center', minWidth: 100 }, ]; @@ -25,11 +25,12 @@ export default function GraphTable() { const [rows, setRows] = useState([]); const [page, setPage] = useState(0); const [rowsPerPage, setRowsPerPage] = useState(10); - const location=useLocation(); + const [searchQuery, setSearchQuery] = useState(''); // Add searchQuery state + const location = useLocation(); useEffect(() => { const params = new URLSearchParams(location.search); - const wf_deployment_id= params.get("wf_deployment_id"); + const wf_deployment_id = params.get("wf_deployment_id"); axios.post("/api/workflowId/refactoredID", { "wf_deployment_id": wf_deployment_id }) .then(response => { const nodes = response.data.graphs.nodes; @@ -52,8 +53,37 @@ export default function GraphTable() { setPage(0); }; + // Create a function that filters rows based on the search query + const filteredRows = rows.filter((row) => { + const lowerCaseSearchQuery = searchQuery.toLowerCase(); + return ( + row.Label.toString().toLowerCase().includes(lowerCaseSearchQuery) || + row.ID.toString().toLowerCase().includes(lowerCaseSearchQuery) || + row.CSP.toLowerCase().includes(lowerCaseSearchQuery) + ); + }); + return ( - + +
+ setSearchQuery(e.target.value)} + style={{ + fontSize: '1rem', + padding: '8px', + width: '300px', + height: '40px', + background: 'black', + color: 'white', + border: 'none', + boxShadow: 'inset 0 0 5px rgba(0, 0, 0, 0.5), 0 0 5px rgba(255, 255, 255, 0.5)', + borderRadius: '10px' + }} + /> +
@@ -62,7 +92,7 @@ export default function GraphTable() { {column.label} @@ -70,19 +100,22 @@ export default function GraphTable() { - {rows + {filteredRows .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) .map((row) => { return ( - - {row[columns[0].id]} + + {row[columns[0].id]} - + {row[columns[1].id]} - - {row[columns[2].id]} + +
+ {row[columns[2].id]} +
+
); @@ -93,7 +126,7 @@ export default function GraphTable() { ); } - - diff --git a/frontend/src/components/Wf.css b/frontend/src/components/Wf.css index 52b09ad..9fcd7b8 100644 --- a/frontend/src/components/Wf.css +++ b/frontend/src/components/Wf.css @@ -9,7 +9,7 @@ } .mermaidGraphh{ - margin: 2rem 0; + box-shadow: rgba(50, 50, 93, 0.25) 0px 6px 12px -2px, rgba(0, 0, 0, 0.3) 0px 3px 7px -3px; border-radius: 10px; overflow: hidden; From f38ca4be775b3c44669e6e07d844fc02292337e5 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 29 Dec 2023 20:23:50 +0530 Subject: [PATCH 06/19] commit before adding styles to main Invocation.jsx --- backend/server.js | 56 +++++- .../src/scenes/invocations/Invocation.jsx | 161 +++++++++++++++++- frontend/src/scenes/line/Line2.jsx | 159 +++++++++++++++++ 3 files changed, 368 insertions(+), 8 deletions(-) create mode 100644 frontend/src/scenes/line/Line2.jsx diff --git a/backend/server.js b/backend/server.js index d65a279..78f9252 100644 --- a/backend/server.js +++ b/backend/server.js @@ -373,6 +373,57 @@ app.post("/api/deploymentId/invocations",(req,res)=>{ }) +app.post("/api/deploymentId/invocations/workflowEndTime/",async(req,res)=>{ + const clickedId ="76154d98-a0d7-4fc7-8c3e-99c74d91e2ed"//req.body.wf_deployment_id; + var inputArray=INVOCATION_VARIABLE.filter((item)=>item.workflow_deployment_id.S==clickedId); + const temp = await inputArray.map((input) => { + const functionKeys = Object.keys(input.functions.M); + const functions = {}; + + for (const key of functionKeys) { + const func = input.functions.M[key].M; + functions[key] = { + start_delta_ms: parseInt(func.start_delta.N), + end_delta_ms: parseInt(func.end_delta.N), + }; + } + + return { + workflow_deployment_id: input.workflow_deployment_id.S, + workflow_invocation_id: input.workflow_invocation_id.S, + client_request_time_ms: parseInt(input.client_request_time_ms.S), + invocation_start_time_ms: parseInt(input.invocation_start_time_ms.S), + functions, + }; + }); + +var output=[] + for (let i = temp.length - 1; i >= 0; i--) { + const obj = temp[i]; + const functions = obj.functions; + // Check if the function ID exists in the functions object. + if (!functions["254"]) { + return null; + } + //console.log(functions) + // Get the previous function ID. +const previousFunctionId = Object.keys(functions)[Object.keys(functions).indexOf("254") - 1]; + + // Get the previous function end time. + +const invocation_start_time_ms=obj["invocation_start_time_ms"]; +const workflowEndTime = functions[previousFunctionId].end_delta_ms+invocation_start_time_ms; + + output.push({ + workflowEndTime, + invocation_start_time_ms, + }); + } + + return res.json(output); + +}) + app.post("/api/deploymentId/listAllInvocations/",async(req,res)=>{ const clickedId ="76154d98-a0d7-4fc7-8c3e-99c74d91e2ed";//req.body.wf_deployment_id;//"76154d98-a0d7-4fc7-8c3e-99c74d91e2ed" @@ -401,7 +452,4 @@ app.post("/api/deploymentId/listAllInvocations/",async(req,res)=>{ }) app.listen(port, () => { console.log(`Server is running on http://localhost:${port}`); -}); - - - +}); \ No newline at end of file diff --git a/frontend/src/scenes/invocations/Invocation.jsx b/frontend/src/scenes/invocations/Invocation.jsx index 7afa1d4..9cb6cc7 100644 --- a/frontend/src/scenes/invocations/Invocation.jsx +++ b/frontend/src/scenes/invocations/Invocation.jsx @@ -1,9 +1,143 @@ +// import React, { useState, useEffect } from 'react'; +// import { Box, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, TextField, MenuItem, Select } from '@mui/material'; +// import { useLocation } from "react-router-dom"; +// import { Link } from 'react-router-dom'; +// import axios from "axios"; +// import Line from '../line/Line'; + +// const Invocation = () => { +// const [invocationList, setInvocationList] = useState([]); +// const [filterValue, setFilterValue] = useState(''); +// const [filterTime, setFilterTime] = useState('all'); +// const [deploymentId,setDeploymentId]=useState(""); + +// const location=useLocation(); + +// useEffect(() => { +// const params=new URLSearchParams(location.search); +// const depid=params.get("wf_deployment_id"); +// setDeploymentId(depid) +// axios.post("/api/deploymentId/listAllInvocations/",{"wf_deployment_id":depid}).then(res=>{ +// const invo=res.data + +// setInvocationList(invo); + +// }).catch(err=> +// console.error(err)) +// },[location]) + + +// const getLastFunctionEndTime = (functions, invocationStartTime) => { +// const functionEntries = Object.entries(functions); +// if (functionEntries.length === 0) { +// return null; +// } + +// const maxEndTime = Math.max(...functionEntries.map(([_, func]) => func.end_delta_ms)); +// const lastFunctionEndTime = new Date(invocationStartTime + maxEndTime).toLocaleString(); +// return lastFunctionEndTime; +// }; + +// const handleFilterChange = (event) => { +// setFilterValue(event.target.value); +// }; + +// const handleFilterByTime = (timeValue) => { +// setFilterTime(timeValue); +// }; + +// const applyTimeFilter = (filteredData) => { +// if (filterTime === 'all') { +// return filteredData; +// } else { +// const now = Date.now(); +// const filterTimes = { +// last1Hour: now - 3600000, +// lastDay: now - 86400000, +// lastMonth: now - 2629746000, +// last6Months: now - 15778476000, +// last12Months: now - 31556952000, +// }; +// return filteredData.filter(item => { +// const startTime = new Date(item.invocation_start_time_ms).getTime(); +// return startTime > filterTimes[filterTime]; +// }); +// } +// }; + +// const filteredInvocationListByID = invocationList.filter(item => item.workflow_invocation_id.startsWith(filterValue)); + +// const filteredByTime = applyTimeFilter(filteredInvocationListByID); + +// return ( +//
+// +// +// +// +// +// +// +// +//
+// +// +// Invocation ID +// Start Time +// End Time +// +// +// +// {filteredByTime.map(item => ( +// +// +// {item.workflow_invocation_id} +// +// {new Date(item.invocation_start_time_ms).toLocaleString()} +// +// {getLastFunctionEndTime(item.functions, item.invocation_start_time_ms)} +// +// +// ))} +// +//
+//
+// +// +//
+// ); +// }; + +// export default Invocation + import React, { useState, useEffect } from 'react'; import { Box, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, TextField, MenuItem, Select } from '@mui/material'; import { useLocation } from "react-router-dom"; import { Link } from 'react-router-dom'; import axios from "axios"; import Line from '../line/Line'; +import StartvsEndScatterPlot from '../line/Line2'; +import ResponsiveAppBar from '../../components/App-bar'; +import {useMode} from '../../theme' +import {ThemeProvider} from "@mui/material" const Invocation = () => { const [invocationList, setInvocationList] = useState([]); @@ -27,6 +161,7 @@ axios.post("/api/deploymentId/listAllInvocations/",{"wf_deployment_id":depid}).t },[location]) + const getLastFunctionEndTime = (functions, invocationStartTime) => { const functionEntries = Object.entries(functions); if (functionEntries.length === 0) { @@ -69,10 +204,24 @@ axios.post("/api/deploymentId/listAllInvocations/",{"wf_deployment_id":depid}).t const filteredByTime = applyTimeFilter(filteredInvocationListByID); + const [theme]=useMode(); + return ( +<> + +
+
+ - + + + + + + + + Last 12 months + - - + +
- Invocation ID + Invocation ID Start Time End Time @@ -123,6 +273,9 @@ axios.post("/api/deploymentId/listAllInvocations/",{"wf_deployment_id":depid}).t + + + ); }; diff --git a/frontend/src/scenes/line/Line2.jsx b/frontend/src/scenes/line/Line2.jsx new file mode 100644 index 0000000..9dba282 --- /dev/null +++ b/frontend/src/scenes/line/Line2.jsx @@ -0,0 +1,159 @@ +import React, { useState, useEffect } from 'react'; +import { ResponsiveScatterPlot } from '@nivo/scatterplot' +import { FormControl, InputLabel, Select, MenuItem } from '@mui/material'; +import axios from "axios"; +import { useLocation } from "react-router-dom"; + +const StartvsEndScatterPlot = (props) => { + const [selectedFilter, setSelectedFilter] = useState('all'); + const [filteredData, setFilteredData] = useState([]); + const [execTime,setExecTimeList]=useState([]); + const location=useLocation(); + + + useEffect(() => { + const params=new URLSearchParams(location.search); + const depid=params.get("wf_deployment_id"); + axios.post("/api/deploymentId/invocations/workflowEndTime/",{"wf_deployment_id":depid}).then(res=>{ + const list=res.data + + setExecTimeList(list); + + }).catch(err=> + console.error(err)) + },[selectedFilter]) + + + useEffect(() => { + const filterData = () => { + const currentDate = new Date(); + switch (selectedFilter) { + case 'lastDay': + setFilteredData( + execTime.filter(item => { + const startTime = new Date(item.invocation_start_time_ms); + return currentDate - startTime <= 24 * 60 * 60 * 1000; // 24 hours + }) + ); + break; + case 'lastMonth': + setFilteredData( + execTime.filter(item => { + const startTime = new Date(item.invocation_start_time_ms); + return currentDate - startTime <= 30 * 24 * 60 * 60 * 1000; // 30 days + }) + ); + break; + case 'last6Months': + setFilteredData( + execTime.filter(item => { + const startTime = new Date(item.invocation_start_time_ms); + return currentDate - startTime <= 6 * 30 * 24 * 60 * 60 * 1000; // 6 months + }) + ); + break; + case 'last12Months': + setFilteredData( + execTime.filter(item => { + const startTime = new Date(item.invocation_start_time_ms); + return currentDate - startTime <= 12 * 30 * 24 * 60 * 60 * 1000; // 12 months + }) + ); + break; + case 'all': + default: + setFilteredData(execTime); + break; + } + }; + + filterData(); + }, [selectedFilter]); + + const XsortedData = filteredData + .map(item => ({ + x: new Date(item.invocation_start_time_ms).toLocaleString(), + y: new Date(item.workflowEndTime).toLocaleString(), + })) + .sort((a, b) => new Date(a.x) - new Date(b.x)); + + const YsortedData = [...XsortedData].sort((a, b) => new Date(a.y) - new Date(b.y)); + + const formattedData = [{ id: 'invocations', data: XsortedData }]; + + const startX = XsortedData[0]?.x || ''; + const endX = XsortedData[XsortedData.length - 1]?.x || ''; + const startY = YsortedData[0]?.y || ''; + const endY = YsortedData[YsortedData.length - 1]?.y || ''; + + return ( + <> + + Filter +
+ +
+ + ( +
+ Start Time: {node.data.x} +
+ End Time: {node.data.y} +
+ )} + /> + + ); +}; + +export default StartvsEndScatterPlot; \ No newline at end of file From f6aba0e038b0f74e5561da732a412436061c75d9 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 29 Dec 2023 21:40:22 +0530 Subject: [PATCH 07/19] Complete 1.0 --- frontend/package-lock.json | 404 ++++++++++++++---- frontend/package.json | 3 +- .../src/scenes/invocations/Invocation.jsx | 115 +++-- .../scenes/invocations/InvocationDetails.jsx | 54 ++- frontend/src/scenes/line/Line.jsx | 4 +- readme.txt | 0 6 files changed, 450 insertions(+), 130 deletions(-) create mode 100644 readme.txt diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 0286fe7..190fcfa 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -12,10 +12,11 @@ "@emotion/styled": "^11.11.0", "@material/icon-button": "^14.0.0", "@mui/icons-material": "^5.14.16", - "@mui/material": "^5.13.4", + "@mui/material": "^5.15.2", "@nivo/bar": "^0.83.0", "@nivo/core": "^0.83.0", "@nivo/line": "^0.83.0", + "@nivo/scatterplot": "^0.84.0", "@passageidentity/passage-auth": "^0.1.0-beta.28", "@passageidentity/passage-elements": "^1.9.2", "@testing-library/jest-dom": "^5.16.5", @@ -2042,9 +2043,9 @@ "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==" }, "node_modules/@babel/runtime": { - "version": "7.23.2", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.2.tgz", - "integrity": "sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.6.tgz", + "integrity": "sha512-zHd0eUrf5GZoOWVCXp6koAKQTfZV07eit6bGPmJgnZdnSAvvZee6zniW2XMF7Cmc4ISOOnPy3QaSiIJGJkVEDQ==", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -2609,6 +2610,40 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@floating-ui/core": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.5.2.tgz", + "integrity": "sha512-Ii3MrfY/GAIN3OhXNzpCKaLxHQfJF9qvwq/kEJYdqDxeIHa01K8sldugal6TmeeXl+WMvhv9cnVzUTaFFJF09A==", + "dependencies": { + "@floating-ui/utils": "^0.1.3" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.5.3.tgz", + "integrity": "sha512-ClAbQnEqJAKCJOEbbLo5IUlZHkNszqhuxS4fHAVxRPXPya6Ysf2G8KypnYcOTpx6I8xcgF9bbHb6g/2KpbV8qA==", + "dependencies": { + "@floating-ui/core": "^1.4.2", + "@floating-ui/utils": "^0.1.3" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.4.tgz", + "integrity": "sha512-CF8k2rgKeh/49UrnIBs4BdxPUV6vize/Db1d/YbCLyp9GiVZ0BEwf5AiDSxJRCr6yOkGqTFHtmrULxkEfYZ7dQ==", + "dependencies": { + "@floating-ui/dom": "^1.5.1" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.1.6.tgz", + "integrity": "sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A==" + }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", @@ -3653,25 +3688,24 @@ } }, "node_modules/@mui/base": { - "version": "5.0.0-beta.4", - "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.4.tgz", - "integrity": "sha512-ejhtqYJpjDgHGEljjMBQWZ22yEK0OzIXNa7toJmmXsP4TT3W7xVy8bTJ0TniPDf+JNjrsgfgiFTDGdlEhV1E+g==", - "dependencies": { - "@babel/runtime": "^7.21.0", - "@emotion/is-prop-valid": "^1.2.1", - "@mui/types": "^7.2.4", - "@mui/utils": "^5.13.1", + "version": "5.0.0-beta.29", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.29.tgz", + "integrity": "sha512-OXfUssYrB6ch/xpBVHMKAjThPlI9VyGGKdvQLMXef2j39wXfcxPlUVQlwia/lmE3rxWIGvbwkZsDtNYzLMsDUg==", + "dependencies": { + "@babel/runtime": "^7.23.6", + "@floating-ui/react-dom": "^2.0.4", + "@mui/types": "^7.2.11", + "@mui/utils": "^5.15.2", "@popperjs/core": "^2.11.8", - "clsx": "^1.2.1", - "prop-types": "^15.8.1", - "react-is": "^18.2.0" + "clsx": "^2.0.0", + "prop-types": "^15.8.1" }, "engines": { "node": ">=12.0.0" }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/mui" + "url": "https://opencollective.com/mui-org" }, "peerDependencies": { "@types/react": "^17.0.0 || ^18.0.0", @@ -3685,12 +3719,12 @@ } }, "node_modules/@mui/core-downloads-tracker": { - "version": "5.13.4", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.13.4.tgz", - "integrity": "sha512-yFrMWcrlI0TqRN5jpb6Ma9iI7sGTHpytdzzL33oskFHNQ8UgrtPas33Y1K7sWAMwCrr1qbWDrOHLAQG4tAzuSw==", + "version": "5.15.2", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.15.2.tgz", + "integrity": "sha512-0vk4ckS2w1F5PmkSXSd7F/QuRlNcPqWTJ8CPl+HQRLTIhJVS/VKEI+3dQufOdKfn2wS+ecnvlvXerbugs+xZ8Q==", "funding": { "type": "opencollective", - "url": "https://opencollective.com/mui" + "url": "https://opencollective.com/mui-org" } }, "node_modules/@mui/icons-material": { @@ -3719,18 +3753,18 @@ } }, "node_modules/@mui/material": { - "version": "5.13.4", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.13.4.tgz", - "integrity": "sha512-Yq+4f1KLPa/Szd3xqra2hbOAf2Usl8GbubncArM6LIp40mBLtXIdPE29MNtHsbtuzz4g+eidrETgoi3wdbEYfQ==", - "dependencies": { - "@babel/runtime": "^7.21.0", - "@mui/base": "5.0.0-beta.4", - "@mui/core-downloads-tracker": "^5.13.4", - "@mui/system": "^5.13.2", - "@mui/types": "^7.2.4", - "@mui/utils": "^5.13.1", - "@types/react-transition-group": "^4.4.6", - "clsx": "^1.2.1", + "version": "5.15.2", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.15.2.tgz", + "integrity": "sha512-JnoIrpNmEHG5uC1IyEdgsnDiaiuCZnUIh7f9oeAr87AvBmNiEJPbo7XrD7kBTFWwp+b97rQ12QdSs9CLhT2n/A==", + "dependencies": { + "@babel/runtime": "^7.23.6", + "@mui/base": "5.0.0-beta.29", + "@mui/core-downloads-tracker": "^5.15.2", + "@mui/system": "^5.15.2", + "@mui/types": "^7.2.11", + "@mui/utils": "^5.15.2", + "@types/react-transition-group": "^4.4.10", + "clsx": "^2.0.0", "csstype": "^3.1.2", "prop-types": "^15.8.1", "react-is": "^18.2.0", @@ -3741,7 +3775,7 @@ }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/mui" + "url": "https://opencollective.com/mui-org" }, "peerDependencies": { "@emotion/react": "^11.5.0", @@ -3763,12 +3797,12 @@ } }, "node_modules/@mui/private-theming": { - "version": "5.13.1", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.13.1.tgz", - "integrity": "sha512-HW4npLUD9BAkVppOUZHeO1FOKUJWAwbpy0VQoGe3McUYTlck1HezGHQCfBQ5S/Nszi7EViqiimECVl9xi+/WjQ==", + "version": "5.15.2", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.15.2.tgz", + "integrity": "sha512-KlXx5TH1Mw9omSY+Q6rz5TA/P71meSYaAOeopiW8s6o433+fnOxS17rZbmd1RnDZGCo+j24TfCavQuCMBAZnQA==", "dependencies": { - "@babel/runtime": "^7.21.0", - "@mui/utils": "^5.13.1", + "@babel/runtime": "^7.23.6", + "@mui/utils": "^5.15.2", "prop-types": "^15.8.1" }, "engines": { @@ -3776,7 +3810,7 @@ }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/mui" + "url": "https://opencollective.com/mui-org" }, "peerDependencies": { "@types/react": "^17.0.0 || ^18.0.0", @@ -3789,11 +3823,11 @@ } }, "node_modules/@mui/styled-engine": { - "version": "5.13.2", - "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.13.2.tgz", - "integrity": "sha512-VCYCU6xVtXOrIN8lcbuPmoG+u7FYuOERG++fpY74hPpEWkyFQG97F+/XfTQVYzlR2m7nPjnwVUgATcTCMEaMvw==", + "version": "5.15.2", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.15.2.tgz", + "integrity": "sha512-fYEN3IZzbebeHwAmQHhxwruiOIi8W74709qXg/7tgtHV4byQSmPgnnKsZkg0hFlzjEbcJIRZyZI0qEecgpR2cg==", "dependencies": { - "@babel/runtime": "^7.21.0", + "@babel/runtime": "^7.23.6", "@emotion/cache": "^11.11.0", "csstype": "^3.1.2", "prop-types": "^15.8.1" @@ -3803,7 +3837,7 @@ }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/mui" + "url": "https://opencollective.com/mui-org" }, "peerDependencies": { "@emotion/react": "^11.4.1", @@ -3820,16 +3854,16 @@ } }, "node_modules/@mui/system": { - "version": "5.13.2", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.13.2.tgz", - "integrity": "sha512-TPyWmRJPt0JPVxacZISI4o070xEJ7ftxpVtu6LWuYVOUOINlhoGOclam4iV8PDT3EMQEHuUrwU49po34UdWLlw==", - "dependencies": { - "@babel/runtime": "^7.21.0", - "@mui/private-theming": "^5.13.1", - "@mui/styled-engine": "^5.13.2", - "@mui/types": "^7.2.4", - "@mui/utils": "^5.13.1", - "clsx": "^1.2.1", + "version": "5.15.2", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.15.2.tgz", + "integrity": "sha512-I7CzLiHDtU/BTobJgSk+wPGGWG95K8lYfdFEnq//wOgSrLDAdOVvl2gleDxJWO+yAbGz4RKEOnR9KuD+xQZH4A==", + "dependencies": { + "@babel/runtime": "^7.23.6", + "@mui/private-theming": "^5.15.2", + "@mui/styled-engine": "^5.15.2", + "@mui/types": "^7.2.11", + "@mui/utils": "^5.15.2", + "clsx": "^2.0.0", "csstype": "^3.1.2", "prop-types": "^15.8.1" }, @@ -3838,7 +3872,7 @@ }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/mui" + "url": "https://opencollective.com/mui-org" }, "peerDependencies": { "@emotion/react": "^11.5.0", @@ -3859,11 +3893,11 @@ } }, "node_modules/@mui/types": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.4.tgz", - "integrity": "sha512-LBcwa8rN84bKF+f5sDyku42w1NTxaPgPyYKODsh01U1fVstTClbUoSA96oyRBnSNyEiAVjKm6Gwx9vjR+xyqHA==", + "version": "7.2.11", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.11.tgz", + "integrity": "sha512-KWe/QTEsFFlFSH+qRYf3zoFEj3z67s+qAuSnMMg+gFwbxG7P96Hm6g300inQL1Wy///gSRb8juX7Wafvp93m3w==", "peerDependencies": { - "@types/react": "*" + "@types/react": "^17.0.0 || ^18.0.0" }, "peerDependenciesMeta": { "@types/react": { @@ -3872,13 +3906,12 @@ } }, "node_modules/@mui/utils": { - "version": "5.13.1", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.13.1.tgz", - "integrity": "sha512-6lXdWwmlUbEU2jUI8blw38Kt+3ly7xkmV9ljzY4Q20WhsJMWiNry9CX8M+TaP/HbtuyR8XKsdMgQW7h7MM3n3A==", + "version": "5.15.2", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.15.2.tgz", + "integrity": "sha512-6dGM9/guFKBlFRHA7/mbM+E7wE7CYDy9Ny4JLtD3J+NTyhi8nd8YxlzgAgTaTVqY0BpdQ2zdfB/q6+p2EdGM0w==", "dependencies": { - "@babel/runtime": "^7.21.0", - "@types/prop-types": "^15.7.5", - "@types/react-is": "^18.2.0", + "@babel/runtime": "^7.23.6", + "@types/prop-types": "^15.7.11", "prop-types": "^15.8.1", "react-is": "^18.2.0" }, @@ -3887,10 +3920,16 @@ }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/mui" + "url": "https://opencollective.com/mui-org" }, "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, "node_modules/@nicolo-ribaudo/eslint-scope-5-internals": { @@ -4101,6 +4140,213 @@ "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-1.1.0.tgz", "integrity": "sha512-Xh0isrZ5rPYYdqhAVk8VLnMEidhz5aP7htAADH6MfzgmmicPkTo8LhkLxci61/lCB7n7UmE3bN0leRt+qvkLxA==" }, + "node_modules/@nivo/scatterplot": { + "version": "0.84.0", + "resolved": "https://registry.npmjs.org/@nivo/scatterplot/-/scatterplot-0.84.0.tgz", + "integrity": "sha512-E4AE0vspLo/7CwTNbL/lAO1K//51CpJhtWTbZwWcmjdo/SKv559CA4PPqXBgS6QgdzzE6Kn3hgp2io76UqIZvQ==", + "dependencies": { + "@nivo/annotations": "0.84.0", + "@nivo/axes": "0.84.0", + "@nivo/colors": "0.84.0", + "@nivo/core": "0.84.0", + "@nivo/legends": "0.84.0", + "@nivo/scales": "0.84.0", + "@nivo/tooltip": "0.84.0", + "@nivo/voronoi": "0.84.0", + "@react-spring/web": "9.4.5 || ^9.7.2", + "@types/d3-scale": "^3.2.3", + "@types/d3-shape": "^2.0.0", + "d3-scale": "^3.2.3", + "d3-shape": "^1.3.5", + "lodash": "^4.17.21" + }, + "peerDependencies": { + "react": ">= 16.14.0 < 19.0.0" + } + }, + "node_modules/@nivo/scatterplot/node_modules/@nivo/annotations": { + "version": "0.84.0", + "resolved": "https://registry.npmjs.org/@nivo/annotations/-/annotations-0.84.0.tgz", + "integrity": "sha512-g3n+WaZgRza7fZVQZrrxq1cLS+6vmjhWGmQqEynFmKM2f11F7gdkHLhGMYosayjZ0Sb/bMUXvBSkUbyKli7NVw==", + "dependencies": { + "@nivo/colors": "0.84.0", + "@nivo/core": "0.84.0", + "@react-spring/web": "9.4.5 || ^9.7.2", + "@types/prop-types": "^15.7.2", + "lodash": "^4.17.21", + "prop-types": "^15.7.2" + }, + "peerDependencies": { + "react": ">= 16.14.0 < 19.0.0" + } + }, + "node_modules/@nivo/scatterplot/node_modules/@nivo/axes": { + "version": "0.84.0", + "resolved": "https://registry.npmjs.org/@nivo/axes/-/axes-0.84.0.tgz", + "integrity": "sha512-bC9Rx5ixGJiupTRXSnATIVRLPcx0HR8yXGBuO8GTy6K1DDnhaNWfhErnBLYbB9Sq13WQGrS2he6uvLVLd23CtA==", + "dependencies": { + "@nivo/core": "0.84.0", + "@nivo/scales": "0.84.0", + "@react-spring/web": "9.4.5 || ^9.7.2", + "@types/d3-format": "^1.4.1", + "@types/d3-time-format": "^2.3.1", + "@types/prop-types": "^15.7.2", + "d3-format": "^1.4.4", + "d3-time-format": "^3.0.0", + "prop-types": "^15.7.2" + }, + "peerDependencies": { + "react": ">= 16.14.0 < 19.0.0" + } + }, + "node_modules/@nivo/scatterplot/node_modules/@nivo/colors": { + "version": "0.84.0", + "resolved": "https://registry.npmjs.org/@nivo/colors/-/colors-0.84.0.tgz", + "integrity": "sha512-wNG1uYyDP5Owc1Pdkz0zesdZCrPAywmSssNzQ2Aju7nVs7Ru7iHNBIvOAGgyXTe2gcrIO9VSasXWR+jEYyxN2Q==", + "dependencies": { + "@nivo/core": "0.84.0", + "@types/d3-color": "^2.0.0", + "@types/d3-scale": "^3.2.3", + "@types/d3-scale-chromatic": "^2.0.0", + "@types/prop-types": "^15.7.2", + "d3-color": "^3.1.0", + "d3-scale": "^3.2.3", + "d3-scale-chromatic": "^2.0.0", + "lodash": "^4.17.21", + "prop-types": "^15.7.2" + }, + "peerDependencies": { + "react": ">= 16.14.0 < 19.0.0" + } + }, + "node_modules/@nivo/scatterplot/node_modules/@nivo/core": { + "version": "0.84.0", + "resolved": "https://registry.npmjs.org/@nivo/core/-/core-0.84.0.tgz", + "integrity": "sha512-HyQM4x4B7d4X9+xLPKkPxqIxhSDzbJUywGTDWHWx1daeX9VP8O+MqkTBsNsoB+tjxrbKrRJ0+ceS2w89JB+qrA==", + "dependencies": { + "@nivo/recompose": "0.84.0", + "@nivo/tooltip": "0.84.0", + "@react-spring/web": "9.4.5 || ^9.7.2", + "@types/d3-shape": "^2.0.0", + "d3-color": "^3.1.0", + "d3-format": "^1.4.4", + "d3-interpolate": "^3.0.1", + "d3-scale": "^3.2.3", + "d3-scale-chromatic": "^3.0.0", + "d3-shape": "^1.3.5", + "d3-time-format": "^3.0.0", + "lodash": "^4.17.21" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nivo/donate" + }, + "peerDependencies": { + "prop-types": ">= 15.5.10 < 16.0.0", + "react": ">= 16.14.0 < 19.0.0" + } + }, + "node_modules/@nivo/scatterplot/node_modules/@nivo/core/node_modules/d3-scale-chromatic": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.0.0.tgz", + "integrity": "sha512-Lx9thtxAKrO2Pq6OO2Ua474opeziKr279P/TKZsMAhYyNDD3EnCffdbgeSYN5O7m2ByQsxtuP2CSDczNUIZ22g==", + "dependencies": { + "d3-color": "1 - 3", + "d3-interpolate": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@nivo/scatterplot/node_modules/@nivo/legends": { + "version": "0.84.0", + "resolved": "https://registry.npmjs.org/@nivo/legends/-/legends-0.84.0.tgz", + "integrity": "sha512-o0s1cXoIH6Km9A2zoKB8Ey99Oc1w5nymz0j8s7hR2B0EHo5HgVbYjSs2sZD7NSwLt3QM57Nzxw9VzJ+sqfV30Q==", + "dependencies": { + "@nivo/colors": "0.84.0", + "@nivo/core": "0.84.0", + "@types/d3-scale": "^3.2.3", + "@types/prop-types": "^15.7.2", + "d3-scale": "^3.2.3", + "prop-types": "^15.7.2" + }, + "peerDependencies": { + "react": ">= 16.14.0 < 19.0.0" + } + }, + "node_modules/@nivo/scatterplot/node_modules/@nivo/recompose": { + "version": "0.84.0", + "resolved": "https://registry.npmjs.org/@nivo/recompose/-/recompose-0.84.0.tgz", + "integrity": "sha512-Odb+r0pEmGt4RV020jwvngF7PxBgxS1e1sy8bWlZKc5qkm6k3eVlZNuYU+zGbDxHMigImvrx5KfUv5iUqtQBZA==", + "dependencies": { + "@types/prop-types": "^15.7.2", + "@types/react-lifecycles-compat": "^3.0.1", + "prop-types": "^15.7.2", + "react-lifecycles-compat": "^3.0.4" + }, + "peerDependencies": { + "react": ">= 16.14.0 < 19.0.0" + } + }, + "node_modules/@nivo/scatterplot/node_modules/@nivo/scales": { + "version": "0.84.0", + "resolved": "https://registry.npmjs.org/@nivo/scales/-/scales-0.84.0.tgz", + "integrity": "sha512-Cayo9jFMpoF7Ha7eqOAucHLUG6zZLGpxiAtyZ/vTUCkRZPHmd/YMvrm8E6OyQCTBVf+aRtOKk9tQnMv8E9fWiw==", + "dependencies": { + "@types/d3-scale": "^3.2.3", + "@types/d3-time": "^1.1.1", + "@types/d3-time-format": "^3.0.0", + "d3-scale": "^3.2.3", + "d3-time": "^1.0.11", + "d3-time-format": "^3.0.0", + "lodash": "^4.17.21" + } + }, + "node_modules/@nivo/scatterplot/node_modules/@nivo/scales/node_modules/@types/d3-time-format": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-3.0.4.tgz", + "integrity": "sha512-or9DiDnYI1h38J9hxKEsw513+KVuFbEVhl7qdxcaudoiqWWepapUen+2vAriFGexr6W5+P4l9+HJrB39GG+oRg==" + }, + "node_modules/@nivo/scatterplot/node_modules/@nivo/tooltip": { + "version": "0.84.0", + "resolved": "https://registry.npmjs.org/@nivo/tooltip/-/tooltip-0.84.0.tgz", + "integrity": "sha512-x/6Vk4RXKHkG9q5dk4uFYwEfbMoIvJd5ahhVQ6bskuLks5FZoS6bkKoNggjxwmHbIWOVITGUXuykOfC54EWSpw==", + "dependencies": { + "@nivo/core": "0.84.0", + "@react-spring/web": "9.4.5 || ^9.7.2" + } + }, + "node_modules/@nivo/scatterplot/node_modules/@nivo/voronoi": { + "version": "0.84.0", + "resolved": "https://registry.npmjs.org/@nivo/voronoi/-/voronoi-0.84.0.tgz", + "integrity": "sha512-CJTb0sQWYNbfjjrCEK3W0jt1v+hqAd4fDUNJxB3SNRHEEQtF+MCr2EG3p/CWyxIb3avjF4N53/03tQpnuDwBvQ==", + "dependencies": { + "@nivo/core": "0.84.0", + "@types/d3-delaunay": "^5.3.0", + "@types/d3-scale": "^3.2.3", + "d3-delaunay": "^5.3.0", + "d3-scale": "^3.2.3" + }, + "peerDependencies": { + "react": ">= 16.14.0 < 19.0.0" + } + }, + "node_modules/@nivo/scatterplot/node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@nivo/scatterplot/node_modules/d3-time": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-1.1.0.tgz", + "integrity": "sha512-Xh0isrZ5rPYYdqhAVk8VLnMEidhz5aP7htAADH6MfzgmmicPkTo8LhkLxci61/lCB7n7UmE3bN0leRt+qvkLxA==" + }, "node_modules/@nivo/tooltip": { "version": "0.83.0", "resolved": "https://registry.npmjs.org/@nivo/tooltip/-/tooltip-0.83.0.tgz", @@ -5106,9 +5352,9 @@ "integrity": "sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==" }, "node_modules/@types/prop-types": { - "version": "15.7.5", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", - "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==" + "version": "15.7.11", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz", + "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==" }, "node_modules/@types/q": { "version": "1.5.5", @@ -5143,14 +5389,6 @@ "@types/react": "*" } }, - "node_modules/@types/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/@types/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-1vz2yObaQkLL7YFe/pme2cpvDsCwI1WXIfL+5eLz0MI9gFG24Re16RzUsI8t9XZn9ZWvgLNDrJBmrqXJO7GNQQ==", - "dependencies": { - "@types/react": "*" - } - }, "node_modules/@types/react-lifecycles-compat": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@types/react-lifecycles-compat/-/react-lifecycles-compat-3.0.1.tgz", @@ -5160,9 +5398,9 @@ } }, "node_modules/@types/react-transition-group": { - "version": "4.4.6", - "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.6.tgz", - "integrity": "sha512-VnCdSxfcm08KjsJVQcfBmhEQAPnLB8G08hAxn39azX1qYBQ/5RVQuoHuKIcfKOdncuaUvEpFKFzEvbtIMsfVew==", + "version": "4.4.10", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.10.tgz", + "integrity": "sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q==", "dependencies": { "@types/react": "*" } @@ -6918,9 +7156,9 @@ } }, "node_modules/clsx": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", - "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz", + "integrity": "sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==", "engines": { "node": ">=6" } diff --git a/frontend/package.json b/frontend/package.json index 2cfd7aa..69864c5 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -8,10 +8,11 @@ "@emotion/styled": "^11.11.0", "@material/icon-button": "^14.0.0", "@mui/icons-material": "^5.14.16", - "@mui/material": "^5.13.4", + "@mui/material": "^5.15.2", "@nivo/bar": "^0.83.0", "@nivo/core": "^0.83.0", "@nivo/line": "^0.83.0", + "@nivo/scatterplot": "^0.84.0", "@passageidentity/passage-auth": "^0.1.0-beta.28", "@passageidentity/passage-elements": "^1.9.2", "@testing-library/jest-dom": "^5.16.5", diff --git a/frontend/src/scenes/invocations/Invocation.jsx b/frontend/src/scenes/invocations/Invocation.jsx index 9cb6cc7..f6108d5 100644 --- a/frontend/src/scenes/invocations/Invocation.jsx +++ b/frontend/src/scenes/invocations/Invocation.jsx @@ -138,6 +138,7 @@ import StartvsEndScatterPlot from '../line/Line2'; import ResponsiveAppBar from '../../components/App-bar'; import {useMode} from '../../theme' import {ThemeProvider} from "@mui/material" +import Paper from '@mui/material/Paper'; const Invocation = () => { const [invocationList, setInvocationList] = useState([]); @@ -214,55 +215,105 @@ axios.post("/api/deploymentId/listAllInvocations/",{"wf_deployment_id":depid}).t
+ + {/* + + */} - + - + + + + {/* + + */} + + - - - - + + + + - + + +
+ +
- Invocation ID - Start Time - End Time + Invocation ID + Start Time + End Time {filteredByTime.map(item => ( - - {item.workflow_invocation_id} + + {item.workflow_invocation_id} - {new Date(item.invocation_start_time_ms).toLocaleString()} - + {new Date(item.invocation_start_time_ms).toLocaleString()} + {getLastFunctionEndTime(item.functions, item.invocation_start_time_ms)} @@ -270,7 +321,7 @@ axios.post("/api/deploymentId/listAllInvocations/",{"wf_deployment_id":depid}).t
-
+
diff --git a/frontend/src/scenes/invocations/InvocationDetails.jsx b/frontend/src/scenes/invocations/InvocationDetails.jsx index db7b68f..c8e63d3 100644 --- a/frontend/src/scenes/invocations/InvocationDetails.jsx +++ b/frontend/src/scenes/invocations/InvocationDetails.jsx @@ -3,6 +3,10 @@ import { Box, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, import { useParams } from 'react-router-dom'; import { useLocation } from "react-router-dom"; import axios from "axios"; +import Paper from '@mui/material/Paper'; +import {useMode} from '../../theme' +import {ThemeProvider} from "@mui/material" +import ResponsiveAppBar from '../../components/App-bar'; const InvocationDetails = () => { @@ -56,16 +60,32 @@ useEffect(() => { setFilterValue(event.target.value); }; + const [theme]=useMode(); + // Filter and sort functions based on start time in ascending order const filteredInvocationList = Object.entries(invocationList) .filter(([key]) => key.startsWith(filterValue)) .sort(([, a], [, b]) => b.end_delta_ms - a.end_delta_ms); + + return ( + <> + +
+
- - + + + { variant="outlined" /> - + + + +
+ +
+ - Function ID - Start Time (UTC+5:30) - End Time (UTC+5:30) - Execution Time (ms) + Function ID + Start Time (UTC+5:30) + End Time (UTC+5:30) + Execution Time (ms) @@ -89,19 +115,23 @@ useEffect(() => { const executionTime = value.end_delta_ms - value.start_delta_ms; return ( - {key} - {value.start_time_formatted} - {value.end_time_formatted} - {executionTime} + {key} + {value.start_time_formatted} + {value.end_time_formatted} + {executionTime} ); })}
-
+
+
+
+
+ ); }; diff --git a/frontend/src/scenes/line/Line.jsx b/frontend/src/scenes/line/Line.jsx index 6cf10f0..ec592a7 100644 --- a/frontend/src/scenes/line/Line.jsx +++ b/frontend/src/scenes/line/Line.jsx @@ -70,7 +70,7 @@ const LineChart = ({ chartData }) => { const CustomButton = styled(Button)({ background: "white", - color: "blue", + color: "black", "&:hover": { background: "white", }, @@ -100,7 +100,7 @@ const Line = () => { return ( - Invocations + Add Invocation diff --git a/readme.txt b/readme.txt new file mode 100644 index 0000000..e69de29 From 31a3b2b3cf9fa03a8152c42701cdb4b81df978e8 Mon Sep 17 00:00:00 2001 From: Cheithanya Date: Fri, 2 Feb 2024 16:49:30 +0530 Subject: [PATCH 08/19] Feb 2 2024 --- frontend/src/InvocationsPage.js | 26 ++-- frontend/src/components/Wf.jsx | 31 ++-- .../src/scenes/invocations/Invocation.jsx | 5 +- frontend/src/scenes/line/Line.jsx | 20 ++- .../src/scenes/line/StartvsEndHistogram.jsx | 132 ++++++++++++++++++ .../{Line2.jsx => StartvsEndScatterPlot.jsx} | 16 ++- 6 files changed, 192 insertions(+), 38 deletions(-) create mode 100644 frontend/src/scenes/line/StartvsEndHistogram.jsx rename frontend/src/scenes/line/{Line2.jsx => StartvsEndScatterPlot.jsx} (90%) diff --git a/frontend/src/InvocationsPage.js b/frontend/src/InvocationsPage.js index 33a0f55..291b19d 100644 --- a/frontend/src/InvocationsPage.js +++ b/frontend/src/InvocationsPage.js @@ -21,20 +21,20 @@ const MermaidDiagram = ({ definition }) => { setMermaidInitialized(true); }, []); - useEffect(() => { - const reloadCount = sessionStorage.getItem('reloadCount'); + // useEffect(() => { + // const reloadCount = sessionStorage.getItem('reloadCount'); - if (mermaidInitialized && (!reloadCount || parseInt(reloadCount) === 0)) { - const timeout = setTimeout(() => { - sessionStorage.setItem('reloadCount', '1'); // Set the flag to prevent further reloads - window.location.reload(); - }, 100); - - return () => { - clearTimeout(timeout); - }; - } - }, [mermaidInitialized]); + // if (mermaidInitialized && (!reloadCount || parseInt(reloadCount) === 0)) { + // const timeout = setTimeout(() => { + // sessionStorage.setItem('reloadCount', '1'); // Set the flag to prevent further reloads + // window.location.reload(); + // }, 100); + + // return () => { + // clearTimeout(timeout); + // }; + // } + // }, [mermaidInitialized]); return (
diff --git a/frontend/src/components/Wf.jsx b/frontend/src/components/Wf.jsx index 4dda349..4d877b1 100644 --- a/frontend/src/components/Wf.jsx +++ b/frontend/src/components/Wf.jsx @@ -382,32 +382,31 @@ function createData(wf_deployment_id, wf_deployment_time, wf_deployment_name) { // {definition} //
// ); -// }; +// };m const MermaidDiagram = ({ definition }) => { const [mermaidInitialized, setMermaidInitialized] = useState(false); useEffect(() => { - // Initialize Mermaid when the component mounts + // Initialize Mermaid when the component mounts mermaid.initialize({ startOnLoad: true }); setMermaidInitialized(true); - }, []); + }, [definition]); - useEffect(() => { - const reloadCount = sessionStorage.getItem('reloadCount'); + // useEffect(() => { + // const reloadCount = sessionStorage.getItem('reloadCount'); - if (mermaidInitialized && (!reloadCount || parseInt(reloadCount) === 0)) { - const timeout = setTimeout(() => { - sessionStorage.setItem('reloadCount', '1'); // Set the flag to prevent further reloads - window.location.reload(); - }, 100); - - return () => { - clearTimeout(timeout); - }; - } - }, [mermaidInitialized]); + // if (mermaidInitialized && (!reloadCount || parseInt(reloadCount) === 0)) { + // const timeout = setTimeout(() => { + // sessionStorage.setItem('reloadCount', '1'); // Set the flag to prevent further reloads + // window.location.reload(); + // }, 100); + // return () => { + // clearTimeout(timeout); + // }; + // } + // }, [mermaidInitialized]); return (
diff --git a/frontend/src/scenes/invocations/Invocation.jsx b/frontend/src/scenes/invocations/Invocation.jsx index f6108d5..a5c836a 100644 --- a/frontend/src/scenes/invocations/Invocation.jsx +++ b/frontend/src/scenes/invocations/Invocation.jsx @@ -134,11 +134,12 @@ import { useLocation } from "react-router-dom"; import { Link } from 'react-router-dom'; import axios from "axios"; import Line from '../line/Line'; -import StartvsEndScatterPlot from '../line/Line2'; +import StartvsEndScatterPlot from '../line/StartvsEndScatterPlot'; import ResponsiveAppBar from '../../components/App-bar'; import {useMode} from '../../theme' import {ThemeProvider} from "@mui/material" import Paper from '@mui/material/Paper'; +import StartvsEndHistogram from '../line/StartvsEndHistogram'; const Invocation = () => { const [invocationList, setInvocationList] = useState([]); @@ -252,7 +253,7 @@ axios.post("/api/deploymentId/listAllInvocations/",{"wf_deployment_id":depid}).t height:"50rem", paddingBottom: '8rem' }}> - + diff --git a/frontend/src/scenes/line/Line.jsx b/frontend/src/scenes/line/Line.jsx index ec592a7..9310dc0 100644 --- a/frontend/src/scenes/line/Line.jsx +++ b/frontend/src/scenes/line/Line.jsx @@ -15,7 +15,7 @@ // }; // export default Line; -import React, { useState } from "react"; +import React, { useState,useEffect } from "react"; import { Box, Button, styled } from "@mui/material"; import { ResponsiveLine } from "@nivo/line"; import axios from "axios"; @@ -78,6 +78,24 @@ const CustomButton = styled(Button)({ const Line = () => { const [chartData, setChartData] = useState([]); +useEffect(() => { + axios.post("/api/deploymentId/invocations",{"wf_deployment_id":"5fa74fb4-bb52-4ce7-932a-d0d30936b3d3"}) + .then(response => { + const { workflow_deployment_id, no_of_invocations } = response.data; + const currentTime = new Date().toLocaleTimeString(); + // Update chartData with array of objects + setChartData(prevData => [ + ...prevData, + { + x: currentTime, + y: no_of_invocations, + } + ]); + }) + .catch(error => { + console.error("Error fetching data:", error); + }); +}, []); const fetchData = async () => { try { diff --git a/frontend/src/scenes/line/StartvsEndHistogram.jsx b/frontend/src/scenes/line/StartvsEndHistogram.jsx new file mode 100644 index 0000000..c5ffd96 --- /dev/null +++ b/frontend/src/scenes/line/StartvsEndHistogram.jsx @@ -0,0 +1,132 @@ +import React, { useState, useEffect } from 'react'; +import { ResponsiveBar } from '@nivo/bar'; +import { FormControl, InputLabel, Select, MenuItem } from '@mui/material'; +import axios from "axios"; +import { useLocation } from "react-router-dom"; + +const StartvsEndHistogram = (props) => { + const [selectedFilter, setSelectedFilter] = useState('all'); + const [execTime, setExecTimeList] = useState([]); + const location = useLocation(); + + const calculateExecutionTime = (startTime, endTime) => { + const start = new Date(startTime).getTime(); + const end = new Date(endTime).getTime(); + return (end - start) / 1000; // Returns execution time in seconds + }; + + useEffect(() => { + const params = new URLSearchParams(location.search); + const depid = params.get("wf_deployment_id"); + axios.post("/api/deploymentId/invocations/workflowEndTime/", { "wf_deployment_id": depid }) + .then(res => { + const list = res.data; + setExecTimeList(list); + }) + .catch(err => console.error(err)); + }, [selectedFilter]); + + useEffect(() => { + const filterData = () => { + const currentDate = new Date(); + switch (selectedFilter) { + case 'lastDay': + setExecTimeList( + execTime.filter(item => { + const startTime = new Date(item.invocation_start_time_ms); + return currentDate - startTime <= 24 * 60 * 60 * 1000; // 24 hours + }) + ); + break; + case 'lastMonth': + setExecTimeList( + execTime.filter(item => { + const startTime = new Date(item.invocation_start_time_ms); + return currentDate - startTime <= 30 * 24 * 60 * 60 * 1000; // 30 days + }) + ); + break; + case 'last6Months': + setExecTimeList( + execTime.filter(item => { + const startTime = new Date(item.invocation_start_time_ms); + return currentDate - startTime <= 6 * 30 * 24 * 60 * 60 * 1000; // 6 months + }) + ); + break; + case 'last12Months': + setExecTimeList( + execTime.filter(item => { + const startTime = new Date(item.invocation_start_time_ms); + return currentDate - startTime <= 12 * 30 * 24 * 60 * 60 * 1000; // 12 months + }) + ); + break; + case 'all': + default: + setExecTimeList(execTime); + break; + } + }; + + filterData(); + }, [selectedFilter]); + const startTimeHistogramData = execTime.map(item => ({ + startTime: new Date(item.invocation_start_time_ms).toLocaleString(), + executionTime: calculateExecutionTime(item.invocation_start_time_ms, item.workflowEndTime), + })); + + return ( + <> + + Filter +
+ +
+ + + + ); +}; + +export default StartvsEndHistogram; diff --git a/frontend/src/scenes/line/Line2.jsx b/frontend/src/scenes/line/StartvsEndScatterPlot.jsx similarity index 90% rename from frontend/src/scenes/line/Line2.jsx rename to frontend/src/scenes/line/StartvsEndScatterPlot.jsx index 9dba282..bab4666 100644 --- a/frontend/src/scenes/line/Line2.jsx +++ b/frontend/src/scenes/line/StartvsEndScatterPlot.jsx @@ -10,7 +10,11 @@ const StartvsEndScatterPlot = (props) => { const [execTime,setExecTimeList]=useState([]); const location=useLocation(); - + const calculateExecutionTime = (startTime, endTime) => { + const start = new Date(startTime).getTime(); + const end = new Date(endTime).getTime(); + return end - start; // Returns execution time in milliseconds + }; useEffect(() => { const params=new URLSearchParams(location.search); const depid=params.get("wf_deployment_id"); @@ -73,7 +77,7 @@ const StartvsEndScatterPlot = (props) => { const XsortedData = filteredData .map(item => ({ x: new Date(item.invocation_start_time_ms).toLocaleString(), - y: new Date(item.workflowEndTime).toLocaleString(), + y: calculateExecutionTime(item.invocation_start_time_ms,item.workflowEndTime)/1000, })) .sort((a, b) => new Date(a.x) - new Date(b.x)); @@ -113,7 +117,7 @@ const StartvsEndScatterPlot = (props) => { min: startX, max: endX, }} - yScale={{ type: 'point', min: startY, max: endY }} + yScale={{ type: 'point', min: 0, max: 500 }} colors="lightblue" blendMode="normal" enableGridX={true} @@ -131,10 +135,10 @@ const StartvsEndScatterPlot = (props) => { axisLeft={{ tickSize: 0, tickPadding: 5, - legend: 'End Time', + legend: 'Execution Time', legendPosition: 'middle', legendOffset: -40, - tickValues: [startY, endY], + tickValues: [0, 500], }} nodeSize={8} tooltip={({ node }) => ( @@ -148,7 +152,7 @@ const StartvsEndScatterPlot = (props) => { > Start Time: {node.data.x}
- End Time: {node.data.y} + Execution Time: {node.data.y} seconds
)} /> From 5cb3e98e599e22e5d49722ee53205d93b698c6cf Mon Sep 17 00:00:00 2001 From: Bhuvan Suresh <84003148+BhuvanSuresh@users.noreply.github.com> Date: Sat, 3 Feb 2024 21:03:46 +0530 Subject: [PATCH 09/19] Update readme.txt --- readme.txt | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/readme.txt b/readme.txt index e69de29..9dca9fa 100644 --- a/readme.txt +++ b/readme.txt @@ -0,0 +1,44 @@ +Prerequisites for Running XFaaS Dashboard +Before you proceed with setting up the XFaaS dashboard, ensure the following prerequisites are met: +1. Git Installation: +• Confirm that Git is installed on your system. If not, download and install Git for your respective operating system from here. +2. Node.js Installation: +• Install the latest version of Node.js. Visit Node.js's official website for detailed instructions on installation. +3. AWS CLI and SDK Setup: +• Set up the AWS Command Line Interface (CLI) and AWS Software Development Kits (SDKs) to enable interactions with AWS services. +• Refer to the following link for comprehensive setup instructions: Setting up AWS CLI and SDKs. + +Cloning and Running XFaaS + +Before you proceed with cloning and running XFaaS, ensure you have Google Chrome installed as it is mandatory for viewing the XFaaS dashboard. + +Clone the Repository: + +Clone the GitHub repository XFaaS using the following command: +bash +Copy code +git clone https://github.com/itsCheithanya/XFaaS/tree/styling_branch +Alternatively, you can download the zip file of the repository and unzip it. +Frontend Setup: + +Open your terminal and navigate to the /XFaaS/frontend directory using the following command: +bash +Copy code +cd XFaaS/frontend +Install all the npm packages by executing the command: +Copy code +npm install +Start the frontend server by executing the command: +sql +Copy code +npm start +Backend Setup: + +Navigate to the /XFaaS/backend directory. +Install all the backend packages by executing the command: +Copy code +npm install +Start the backend server by executing the command: +arduino +Copy code +npm run dev From bcd803df07426c767a1f7e75a85991e0e98513a3 Mon Sep 17 00:00:00 2001 From: Bhuvan Suresh <84003148+BhuvanSuresh@users.noreply.github.com> Date: Sat, 3 Feb 2024 21:10:00 +0530 Subject: [PATCH 10/19] Update readme.txt --- readme.txt | 92 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 48 insertions(+), 44 deletions(-) diff --git a/readme.txt b/readme.txt index 9dca9fa..302f7ca 100644 --- a/readme.txt +++ b/readme.txt @@ -1,44 +1,48 @@ -Prerequisites for Running XFaaS Dashboard -Before you proceed with setting up the XFaaS dashboard, ensure the following prerequisites are met: -1. Git Installation: -• Confirm that Git is installed on your system. If not, download and install Git for your respective operating system from here. -2. Node.js Installation: -• Install the latest version of Node.js. Visit Node.js's official website for detailed instructions on installation. -3. AWS CLI and SDK Setup: -• Set up the AWS Command Line Interface (CLI) and AWS Software Development Kits (SDKs) to enable interactions with AWS services. -• Refer to the following link for comprehensive setup instructions: Setting up AWS CLI and SDKs. - -Cloning and Running XFaaS - -Before you proceed with cloning and running XFaaS, ensure you have Google Chrome installed as it is mandatory for viewing the XFaaS dashboard. - -Clone the Repository: - -Clone the GitHub repository XFaaS using the following command: -bash -Copy code -git clone https://github.com/itsCheithanya/XFaaS/tree/styling_branch -Alternatively, you can download the zip file of the repository and unzip it. -Frontend Setup: - -Open your terminal and navigate to the /XFaaS/frontend directory using the following command: -bash -Copy code -cd XFaaS/frontend -Install all the npm packages by executing the command: -Copy code -npm install -Start the frontend server by executing the command: -sql -Copy code -npm start -Backend Setup: - -Navigate to the /XFaaS/backend directory. -Install all the backend packages by executing the command: -Copy code -npm install -Start the backend server by executing the command: -arduino -Copy code -npm run dev +# XFaaS Dashboard Setup Guide + +## Prerequisites + +Before setting up the XFaaS dashboard, ensure you have the following prerequisites: + +- **Google Chrome**: Using Chrome as a default browser is mandatory for viewing XFaaS dashboard. + +## Cloning and Running XFaaS + +Follow these steps to clone and run the XFaaS dashboard: + +1. **Clone the Repository**: + - Clone the GitHub repository [XFaaS](https://github.com/itsCheithanya/XFaaS/tree/styling_branch) using the following command: + ```bash + git clone https://github.com/itsCheithanya/XFaaS/tree/styling_branch + ``` + - Alternatively, you can download the zip file of the repository and unzip it. + +2. **Frontend Setup**: + - Open your terminal and navigate to the `/XFaaS/frontend` directory using the following command: + ```bash + cd XFaaS/frontend + ``` + - Install all the npm packages by executing the command: + ```bash + npm install + ``` + - Start the frontend server by executing the command: + ```bash + npm start + ``` + +3. **Backend Setup**: + - Navigate to the `/XFaaS/backend` directory. + - Install all the backend packages by executing the command: + ```bash + npm install + ``` + - Start the backend server by executing the command: + ```bash + npm run dev + ``` + +## Feedback and Contributions + +Feel free to open an issue or pull request for any feedback or contributions. + From 1b12373d1eb6f49bd13e80143006803cff4aafa8 Mon Sep 17 00:00:00 2001 From: Bhuvan Suresh <84003148+BhuvanSuresh@users.noreply.github.com> Date: Sat, 3 Feb 2024 21:10:30 +0530 Subject: [PATCH 11/19] Update and rename readme.txt to readme.md --- readme.txt => readme.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename readme.txt => readme.md (100%) diff --git a/readme.txt b/readme.md similarity index 100% rename from readme.txt rename to readme.md From 267d4a71697684137ae1f7c688fc66ea2e337b44 Mon Sep 17 00:00:00 2001 From: Bhuvan Suresh <84003148+BhuvanSuresh@users.noreply.github.com> Date: Sat, 3 Feb 2024 21:12:06 +0530 Subject: [PATCH 12/19] Update readme.md --- readme.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/readme.md b/readme.md index 302f7ca..4ad9936 100644 --- a/readme.md +++ b/readme.md @@ -41,8 +41,3 @@ Follow these steps to clone and run the XFaaS dashboard: ```bash npm run dev ``` - -## Feedback and Contributions - -Feel free to open an issue or pull request for any feedback or contributions. - From 82687b8df9922dfe7bd84bfe1443241ff6d50831 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 3 Feb 2024 22:00:40 +0530 Subject: [PATCH 13/19] changed header for final submission --- frontend/src/App.js | 2 ++ frontend/src/components/App-bar.jsx | 21 +++++++++++++-------- frontend/src/components/Footer.css | 5 +++++ frontend/src/components/Footer.jsx | 9 +++++++++ 4 files changed, 29 insertions(+), 8 deletions(-) create mode 100644 frontend/src/components/Footer.css create mode 100644 frontend/src/components/Footer.jsx diff --git a/frontend/src/App.js b/frontend/src/App.js index a8d8310..0314a4f 100644 --- a/frontend/src/App.js +++ b/frontend/src/App.js @@ -4,6 +4,7 @@ import "./App.css"; import { useMode } from './theme'; import {Box, ThemeProvider} from "@mui/material" import TypewriterEffect from './components/TypeWriterEffect'; +import Footer from './components/Footer'; function App() { const [theme]=useMode(); @@ -16,6 +17,7 @@ function App() {
+
); } diff --git a/frontend/src/components/App-bar.jsx b/frontend/src/components/App-bar.jsx index f27bfae..be89a8c 100644 --- a/frontend/src/components/App-bar.jsx +++ b/frontend/src/components/App-bar.jsx @@ -18,7 +18,7 @@ import { useAuthStatus } from '../hooks/useAuthStatus'; const pages = ['Home', 'About Us', 'Contact']; -const settings = ['Profile', 'Logout']; +//const settings = ['Profile', 'Logout']; function ResponsiveAppBar() { const navigate = useNavigate(); @@ -64,10 +64,12 @@ function ResponsiveAppBar() { letterSpacing: '.3rem', color: 'inherit', textDecoration: 'none', + marginLeft: 'auto', + marginRight: 'auto' }} >XFaaS - + {/* ))} - + */} - + + + {/* @@ -148,12 +152,12 @@ function ResponsiveAppBar() { anchorEl={anchorElUser} anchorOrigin={{ vertical: 'top', - horizontal: 'right', + horizontal: 'rightright', }} keepMounted transformOrigin={{ vertical: 'top', - horizontal: 'right', + horizontal: 'left', }} open={Boolean(anchorElUser)} onClose={handleCloseUserMenu} @@ -165,7 +169,8 @@ function ResponsiveAppBar() { ))} - + */} + diff --git a/frontend/src/components/Footer.css b/frontend/src/components/Footer.css new file mode 100644 index 0000000..db2b764 --- /dev/null +++ b/frontend/src/components/Footer.css @@ -0,0 +1,5 @@ +.footer{ + background-color: black; + height: 100px; + width: 100%; +} \ No newline at end of file diff --git a/frontend/src/components/Footer.jsx b/frontend/src/components/Footer.jsx new file mode 100644 index 0000000..2ce0893 --- /dev/null +++ b/frontend/src/components/Footer.jsx @@ -0,0 +1,9 @@ +import "./Footer.css"; +function Footer() { + + return ( +
+ ); +} + +export default Footer; From cebc5f90bda88c221dd2a5f820bef9fe1f03596b Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 9 Feb 2024 19:30:54 +0530 Subject: [PATCH 14/19] handled exceptions conditions related to mermaid graph --- frontend/src/InvocationsPage.js | 16 +++++++++++++--- frontend/src/components/App-bar.jsx | 6 +++--- frontend/src/components/Wf.css | 29 +++++++++++++++++++++++++++-- frontend/src/components/Wf.jsx | 12 +++++++++--- 4 files changed, 52 insertions(+), 11 deletions(-) diff --git a/frontend/src/InvocationsPage.js b/frontend/src/InvocationsPage.js index 291b19d..ffb35c6 100644 --- a/frontend/src/InvocationsPage.js +++ b/frontend/src/InvocationsPage.js @@ -137,11 +137,21 @@ const GraphWrapper = ({depdetails}) => { //

// //
+ //
+ //
Refactored Workflow! If graph is not visible, please reload the page
+ //

+ // + //
+
-
User Submitted Workflow
-

- +
Refactored Workflow! If graph is not visible, please reload the page
+ {graph.mermaidGraphDefinition !== '' ? ( + + ) : ( +

No refactored workflow found

+ )}
+ ); }; diff --git a/frontend/src/components/App-bar.jsx b/frontend/src/components/App-bar.jsx index be89a8c..984474e 100644 --- a/frontend/src/components/App-bar.jsx +++ b/frontend/src/components/App-bar.jsx @@ -18,7 +18,7 @@ import { useAuthStatus } from '../hooks/useAuthStatus'; const pages = ['Home', 'About Us', 'Contact']; -//const settings = ['Profile', 'Logout']; +const settings = ['Profile', 'Logout']; function ResponsiveAppBar() { const navigate = useNavigate(); @@ -138,7 +138,7 @@ function ResponsiveAppBar() { - {/* + @@ -169,7 +169,7 @@ function ResponsiveAppBar() { ))} - */} + diff --git a/frontend/src/components/Wf.css b/frontend/src/components/Wf.css index 9fcd7b8..96cec44 100644 --- a/frontend/src/components/Wf.css +++ b/frontend/src/components/Wf.css @@ -8,14 +8,17 @@ margin: 2rem; } -.mermaidGraphh{ - +.mermaidGraphh{ box-shadow: rgba(50, 50, 93, 0.25) 0px 6px 12px -2px, rgba(0, 0, 0, 0.3) 0px 3px 7px -3px; border-radius: 10px; overflow: hidden; height: 95vh; } +.mermaidGraphhHeader{ + width: 100%; +} + .mermaidGraphhHeading{ background-color: black; color: white; @@ -23,6 +26,28 @@ font-size: 1.5rem; } +.caution{ + color: yellow; + font-size: 1rem; + padding-left: 2rem; +} + +.cautionMark{ + border-width: 1px; + border-color: yellow; + border-style: solid; + border-radius: 2px; + padding: 2px; +} + +.mermaidGraphhHeadingCaution{ + background-color: black; + color: yellow; + padding-top: 1rem; + font-size: 1rem; + flex: 1.2; +} + .graphcontainer { display: flex; justify-content: center; diff --git a/frontend/src/components/Wf.jsx b/frontend/src/components/Wf.jsx index 4d877b1..e0c299e 100644 --- a/frontend/src/components/Wf.jsx +++ b/frontend/src/components/Wf.jsx @@ -470,7 +470,7 @@ const Wf = () => { - const [theme]=useMode(); + const [theme] = useMode(); return( @@ -491,9 +491,15 @@ const Wf = () => {
-
User Submitted Workflow
+
User Submitted Workflow! If graph is not visible, please reload the page
+ +

- + {wfdetails.mermaidGraphDefinition !== '' ? ( + + ) : ( +

No user submitted workflow found

+ )}
From 0bae30487500b6affefaeb0695ce6b4ca0adfae9 Mon Sep 17 00:00:00 2001 From: Bhuvan Suresh <84003148+BhuvanSuresh@users.noreply.github.com> Date: Fri, 9 Feb 2024 20:55:24 +0530 Subject: [PATCH 15/19] Update readme.md --- readme.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index 4ad9936..ef846cd 100644 --- a/readme.md +++ b/readme.md @@ -1,8 +1,18 @@ # XFaaS Dashboard Setup Guide -## Prerequisites +## Prerequisites for Running XFaaS Dashboard -Before setting up the XFaaS dashboard, ensure you have the following prerequisites: +Before you proceed with setting up the XFaaS dashboard, ensure the following prerequisites are met: + +1. **Git Installation**: + - Confirm that Git is installed on your system. If not, download and install Git for your respective operating system from [here](https://git-scm.com/). + +2. **Node.js Installation**: + - Install the latest version of Node.js. Visit Node.js's official website for detailed instructions on installation. + +3. **AWS CLI and SDK Setup**: + - Set up the AWS Command Line Interface (CLI) and AWS Software Development Kits (SDKs) to enable interactions with AWS services. + - Refer to the following link for comprehensive setup instructions: [Setting up AWS CLI and SDKs](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html). - **Google Chrome**: Using Chrome as a default browser is mandatory for viewing XFaaS dashboard. From d926234a9fdb724319dd35c98f38cf2fdea4b1d1 Mon Sep 17 00:00:00 2001 From: itsCheithanya <85927700+itsCheithanya@users.noreply.github.com> Date: Sat, 10 Feb 2024 00:05:51 +0530 Subject: [PATCH 16/19] Update readme.md --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index ef846cd..1b87874 100644 --- a/readme.md +++ b/readme.md @@ -21,7 +21,7 @@ Before you proceed with setting up the XFaaS dashboard, ensure the following pre Follow these steps to clone and run the XFaaS dashboard: 1. **Clone the Repository**: - - Clone the GitHub repository [XFaaS](https://github.com/itsCheithanya/XFaaS/tree/styling_branch) using the following command: + - Clone the GitHub repository [XFaaS](https://github.com/itsCheithanya/XFaaS.git) using the following command: ```bash git clone https://github.com/itsCheithanya/XFaaS/tree/styling_branch ``` From 7d408212c0e2f71dd2feb00567698a738e5d1f8b Mon Sep 17 00:00:00 2001 From: itsCheithanya <85927700+itsCheithanya@users.noreply.github.com> Date: Sat, 10 Feb 2024 00:06:42 +0530 Subject: [PATCH 17/19] Update readme.md --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 1b87874..2ed9784 100644 --- a/readme.md +++ b/readme.md @@ -23,7 +23,7 @@ Follow these steps to clone and run the XFaaS dashboard: 1. **Clone the Repository**: - Clone the GitHub repository [XFaaS](https://github.com/itsCheithanya/XFaaS.git) using the following command: ```bash - git clone https://github.com/itsCheithanya/XFaaS/tree/styling_branch + git clone https://github.com/itsCheithanya/XFaaS.git ``` - Alternatively, you can download the zip file of the repository and unzip it. From 9caa14452183203e607708c83e6d6f2b8a8003ab Mon Sep 17 00:00:00 2001 From: itsCheithanya <85927700+itsCheithanya@users.noreply.github.com> Date: Sat, 10 Feb 2024 00:20:40 +0530 Subject: [PATCH 18/19] Update readme.md --- readme.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/readme.md b/readme.md index 2ed9784..19bf5bf 100644 --- a/readme.md +++ b/readme.md @@ -13,6 +13,18 @@ Before you proceed with setting up the XFaaS dashboard, ensure the following pre 3. **AWS CLI and SDK Setup**: - Set up the AWS Command Line Interface (CLI) and AWS Software Development Kits (SDKs) to enable interactions with AWS services. - Refer to the following link for comprehensive setup instructions: [Setting up AWS CLI and SDKs](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html). + - Run this command to quickly set and view your credentials, Region, and output format. The following example shows sample values. + + ``` +$ aws configure +AWS Access Key ID [None]: AKIAIOSFODNN7EXAMPLE +AWS Secret Access Key [None]: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY +Default region name [None]: us-west-2 +Default output format [None]: json + +``` + + - **Google Chrome**: Using Chrome as a default browser is mandatory for viewing XFaaS dashboard. From 3260947b9eb5b7e19d836d5c36361b93290fed62 Mon Sep 17 00:00:00 2001 From: itsCheithanya <85927700+itsCheithanya@users.noreply.github.com> Date: Sat, 10 Feb 2024 00:21:29 +0530 Subject: [PATCH 19/19] Update readme.md --- readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index 19bf5bf..6192697 100644 --- a/readme.md +++ b/readme.md @@ -17,8 +17,8 @@ Before you proceed with setting up the XFaaS dashboard, ensure the following pre ``` $ aws configure -AWS Access Key ID [None]: AKIAIOSFODNN7EXAMPLE -AWS Secret Access Key [None]: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY +AWS Access Key ID [None]: *************** +AWS Secret Access Key [None]: ************ Default region name [None]: us-west-2 Default output format [None]: json