import React, { useState, useEffect } from "react";
import { useInterval } from "react-powerhooks";
import AppFramework from "../components/AppFramework.jsx";
import { makeStyles, useTheme } from "@material-ui/core/styles";
// nodejs library that concatenates classes
import classNames from "classnames";
import theme from '../theme';
import { useNavigate, Link, useParams } from "react-router-dom";
// react plugin used to create charts
//import { Line, Bar } from "react-chartjs-2";
import { useAlert } from "react-alert";
import Autocomplete from "@material-ui/lab/Autocomplete";
import {
Tooltip,
TextField,
IconButton,
Button,
Typography,
Grid,
Paper,
Chip,
Checkbox,
} from "@material-ui/core";
import {
Close as CloseIcon,
DoneAll as DoneAllIcon,
Description as DescriptionIcon,
PlayArrow as PlayArrowIcon,
Edit as EditIcon,
CheckBox as CheckBoxIcon,
CheckBoxOutlineBlank as CheckBoxOutlineBlankIcon,
OpenInNew as OpenInNewIcon,
} from "@material-ui/icons";
import WorkflowPaper from "../components/WorkflowPaper.jsx"
import { removeParam } from "../views/AngularWorkflow.jsx"
// core components
//import {
// chartExample1,
// chartExample2,
// chartExample3,
// chartExample4,
//} from "../charts.js";
import {
RadialBarChart,
RadialAreaChart,
RadialAxis,
StackedBarSeries,
TooltipArea,
ChartTooltip,
TooltipTemplate,
RadialAreaSeries,
RadialPointSeries,
RadialArea,
RadialLine,
TreeMap,
TreeMapSeries,
TreeMapLabel,
TreeMapRect,
} from 'reaviz';
const useStyles = makeStyles({
notchedOutline: {
borderColor: "#f85a3e !important",
},
root: {
"& .MuiAutocomplete-listbox": {
border: "2px solid #f85a3e",
color: "white",
fontSize: 18,
"& li:nth-child(even)": {
backgroundColor: "#CCC",
},
"& li:nth-child(odd)": {
backgroundColor: "#FFF",
},
},
},
inputRoot: {
color: "white",
// This matches the specificity of the default styles at https://github.com/mui-org/material-ui/blob/v4.11.3/packages/material-ui-lab/src/Autocomplete/Autocomplete.js#L90
"&:hover .MuiOutlinedInput-notchedOutline": {
borderColor: "#f86a3e",
},
},
});
const UsecaseListComponent = ({keys, isCloud, globalUrl, frameworkData, isLoggedIn, workflows, setWorkflows}) => {
const [expandedIndex, setExpandedIndex] = useState(-1);
const [expandedItem, setExpandedItem] = useState(-1);
const [inputUsecase, setInputUsecase] = useState({});
const [editing, setEditing] = useState(false);
const [description, setDescription] = useState("");
const [video, setVideo] = useState("");
const [blogpost, setBlogpost] = useState("");
const [workflowOutline, setWorkflowOutline] = useState("");
const [selectedWorkflows, setSelectedWorkflows] = useState([])
const [firstLoad, setFirstLoad] = useState(true)
const classes = useStyles();
let navigate = useNavigate();
const [mitreTags, setMitreTags] = useState([]);
if (keys === undefined || keys === null || keys.length === 0) {
return null
}
const getUsecase = (name, index, subindex) => {
fetch(`${globalUrl}/api/v1/workflows/usecases/${escape(name.replaceAll(" ", "_"))}`, {
method: "GET",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
credentials: "include",
})
.then((response) => {
if (response.status !== 200) {
console.log("Status not 200 for framework!");
}
return response.json();
})
.then((responseJson) => {
if (responseJson.success === false) {
setInputUsecase({
"name": name,
})
} else {
setInputUsecase(responseJson)
}
setExpandedIndex(index)
setExpandedItem(subindex)
setTimeout(() => {
//console.log("Scroll!")
const found = document.getElementById("selected_box");
if (found !== undefined && found !== null) {
//console.log("FOUND!!")
found.scrollTo({
top: 100,
behavior: "smooth",
})
}
setFirstLoad(true)
setSelectedWorkflows([])
}, 100);
})
.catch((error) => {
//alert.error(error.toString());
setInputUsecase({})
setExpandedIndex(index)
setExpandedItem(subindex)
setFirstLoad(true)
setSelectedWorkflows([])
})
}
const setUsecaseItem = (inputUsecase) => {
var parsedUsecase = inputUsecase
if (blogpost !== inputUsecase.blogpost) {
inputUsecase.blogpost = blogpost
parsedUsecase.blogpost = blogpost
}
if (video !== inputUsecase.video) {
inputUsecase.video = video
parsedUsecase.video = video
}
if (description !== inputUsecase.description) {
inputUsecase.description = description
parsedUsecase.description = description
}
if (mitreTags !== inputUsecase.mitre) {
inputUsecase.mitre = mitreTags
parsedUsecase.mitre = mitreTags
}
if (workflowOutline !== inputUsecase.workflow_outline) {
inputUsecase.workflow_outline = workflowOutline
parsedUsecase.workflow_outline = workflowOutline
}
fetch(globalUrl + "/api/v1/workflows/usecases", {
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
body: JSON.stringify(parsedUsecase),
credentials: "include",
})
.then((response) => {
if (response.status !== 200) {
console.log("Status not 200 for framework!");
}
return response.json();
})
.then((responseJson) => {
if (responseJson.success === false) {
if (responseJson.reason !== undefined) {
//alert.error("Failed updating: " + responseJson.reason)
} else {
//alert.error("Failed to update framework for your org.")
}
} else {
//alert.info("Updated usecase.")
}
})
.catch((error) => {
//alert.error(error.toString());
//setFrameworkLoaded(true)
})
}
const setWorkflow = (workflowdata) => {
const new_url = `${globalUrl}/api/v1/workflows/${workflowdata.id}`
fetch(new_url, {
method: "PUT",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
body: JSON.stringify(workflowdata),
credentials: "include",
})
.then((response) => {
if (response.status !== 200) {
console.log("Status not 200 for workflows :O!");
return;
}
return response.json();
})
.then((responseJson) => {
if (responseJson.success === false) {
if (responseJson.reason !== undefined) {
alert.error("Error updating workflow: ", responseJson.reason)
} else {
alert.error("Error updating workflow.")
}
return
}
return responseJson;
})
.catch((error) => {
alert.error("Problem setting workflow: ", error.toString());
});
};
return (
Shuffle usecases
Usecases in Shuffle are divided into {keys.length} type{keys.length === 1 ? "" : "s"}.
{keys.map((usecase, index) => {
return (
{usecase.name}
{usecase.list.map((subcase, subindex) => {
const selectedItem = subindex === expandedItem && index === expandedIndex
if (subcase.matches === undefined || subcase.matches === null) {
subcase.matches = []
} else {
if (selectedItem && subcase.matches.length > 0 && selectedWorkflows.length === 0 && firstLoad === true) {
setFirstLoad(false)
setSelectedWorkflows(subcase.matches)
}
}
if (selectedItem && subcase.name !== undefined && inputUsecase.name !== undefined) {
if (subcase.name.toLowerCase().replaceAll(" ", "_") === inputUsecase.name.toLowerCase().replaceAll(" ", "_")) {
if (inputUsecase.description !== undefined && inputUsecase.description !== null) {
subcase.description = inputUsecase.description
}
if (inputUsecase.blogpost !== undefined && inputUsecase.blogpost !== null) {
subcase.blogpost = inputUsecase.blogpost
}
if (inputUsecase.video !== undefined && inputUsecase.video !== null) {
subcase.video = inputUsecase.video
}
if (inputUsecase.extra_buttons !== undefined && inputUsecase.extra_buttons !== null) {
subcase.extra_buttons = inputUsecase.extra_buttons
}
if (inputUsecase.workflow_outline !== undefined && inputUsecase.workflow_outline !== null) {
subcase.workflow_outline = inputUsecase.workflow_outline
}
}
}
//const backgroundColor = selectedItem ? "inherit" : finished ? "inherit" : usecase.color
const finished = subcase.matches.length > 0
const backgroundColor = theme.palette.surfaceColor
//"inherit"
const itemBorder = `${selectedItem ? "3px" : expandedItem >= 0 ? "0px" : "1px"} solid ${usecase.color}`
const fixedName = subcase.name.toLowerCase().replace("_", " ")
return (
{
//setSelectedWorkflows([])
if (selectedItem) {
} else {
getUsecase(subcase.name, index, subindex)
navigate(`/usecases?selected_object=${fixedName}`)
//const newitem = removeParam("selected_object", cursearch);
//navigate(curpath + newitem)
}
}}>
{
}}>
{!selectedItem ?
{subcase.name}
{finished ?
{
}}
>
: null}
{subcase.blogpost !== null && subcase.blogpost !== undefined && subcase.blogpost.length > 0 ?
{
}}
>
: null}
{subcase.video !== null && subcase.video !== undefined && subcase.video.length > 0 ?
{
}}
>
: null}
:
{subcase.name}
{isLoggedIn === true ?
{
setEditing(true)
if (subcase.description !== undefined && subcase.description !== null) {
setDescription(subcase.description)
}
if (subcase.blogpost !== undefined && subcase.blogpost !== null) {
setBlogpost(subcase.blogpost)
}
if (subcase.video !== undefined && subcase.video !== null) {
setVideo(subcase.video)
}
if (subcase.mitre !== undefined && subcase.mitre !== null) {
setMitreTags(subcase.mitre)
}
if (subcase.workflow_outline !== undefined && subcase.workflow_outline !== null) {
setWorkflowOutline(subcase.workflow_outline)
} else {
setWorkflowOutline("")
}
}}
>
: null}
{subcase.blogpost !== null && subcase.blogpost !== undefined && subcase.blogpost.length > 0 ?
{
}}
>
: null}
{subcase.video !== null && subcase.video !== undefined && subcase.video.length > 0 ?
{
}}
>
: null}
{
setExpandedItem(-1)
setExpandedIndex(-1)
setEditing(false)
setInputUsecase({})
}}
>
{editing ?
{
setDescription(event.target.value)
}}
id="descriptionEditng"
/>
{
setBlogpost(event.target.value)
}}
id="blogpostEditing"
/>
{
setVideo(event.target.value)
}}
id="videoEditing"
/>
{
setWorkflowOutline(event.target.value)
}}
id="workflowOutline"
tabIndex="-1"
/>
:
{subcase.description}
{workflows !== undefined && workflows !== null && workflows.length > 0 ?
Select relevant workflows
: null}
{workflows !== undefined && workflows !== null && workflows.length > 0 ?
option.id === value.id}
getOptionLabel={(option) => {
if (
option === undefined ||
option === null ||
option.name === undefined ||
option.name === null
) {
return "No Workflow Selected";
}
const newname = (option.name.charAt(0).toUpperCase() + option.name.substring(1)).replaceAll("_", " ");
return newname;
}}
fullWidth
style={{
backgroundColor: theme.palette.inputColor,
height: 50,
borderRadius: theme.palette.borderRadius,
}}
onChange={(event, newValue) => {
console.log("CLICK: ", newValue)
//handleWorkflowSelectionUpdate({ target: { value: newValue} })
//setSelectedWorkflows=
//var newvalue = []
//for (var key in newValue) {
// if (newValue[key].id !== undefined) {
// newvalue.push(newValue[key].id)
// }
//}
// Doing this way as you may want to remove some too
for (var key in workflows) {
if (!newValue.find(data => data.id === workflows[key].id)) {
// Check if it has the one in it
if (workflows[key]["usecase_ids"] !== undefined && workflows[key]["usecase_ids"] !== null && workflows[key]["usecase_ids"].includes(subcase.name)) {
const filtered = workflows[key]["usecase_ids"].filter(data => data !== subcase.name)
if (filtered !== undefined && filtered !== null) {
//console.log("Removing: ", workflows[key].name, workflows[key])
workflows[key]["usecase_ids"] = filtered
setWorkflow(workflows[key])
}
}
continue
}
if (workflows[key]["usecase_ids"] === undefined || workflows[key]["usecase_ids"] === null) {
workflows[key]["usecase_ids"] = [subcase.name]
console.log("Setting: ", workflows[key].name)
setWorkflow(workflows[key])
} else if (!workflows[key]["usecase_ids"].includes(subcase.name)) {
workflows[key]["usecase_ids"].push(subcase.name)
console.log("Adding: ", workflows[key].name)
setWorkflow(workflows[key])
}
}
setWorkflows(workflows)
console.log("New: ", newValue)
setSelectedWorkflows(newValue)
//setUpdate(Math.random())
}}
renderOption={(props, option) => {
//console.log("In options?: ", props, option)
var newname = props.name
if (newname === undefined || newname === null) {
newname = "placeholder"
}
if (newname.length > 2) {
newname = newname.charAt(0).toUpperCase() + newname.substring(1)
}
return (
{props.image !== undefined && props.image !== null && props.image.length > 0 ?
: null}
Choose {newname}
} placement="bottom">
}
checkedIcon={}
style={{ marginRight: 8 }}
checked={option.selected}
/>
{newname}
)
}}
renderInput={(params) => {
return (
);
}}
/>
: null}
{/*subcase.matches.length > 0 ?
{subcase.matches.map((workflow, workflowindex) => {
return (
)
})}
:
No workflow selected yet.
*/}
{subcase.extra_buttons !== undefined && subcase.extra_buttons !== null && subcase.extra_buttons.length > 0 ?
{}}>
Examples
{subcase.extra_buttons.map((subdata, index) => {
var highlight = false
var baseTypeInfo = subcase.type !== undefined ? subcase.type : "communication"
if (frameworkData !== undefined && frameworkData !== null) {
if (frameworkData[baseTypeInfo] !== undefined && frameworkData[baseTypeInfo] !== null && subdata.app !== undefined && subdata.app !== null) {
if (frameworkData[baseTypeInfo].name !== undefined && frameworkData[baseTypeInfo].name.toLowerCase().replaceAll("_", " ") === subdata.app.toLowerCase().replaceAll("_", " ")) {
highlight = true
}
}
}
var marginTop = 6
if (subdata.name.includes(" ") && subdata.name.length > 10) {
marginTop = 0
}
return (
{subdata.name}
)
})}
: null}
}
}
)
})}
)
})}
)
}
const TreeChart = ({keys}) => {
const [hovered, setHovered] = useState("");
return (
{
console.log("Click: ", hovered)
}}>
{
return info.color
}}
label={
}
rect={
{
console.log("Click: ", event)
}}
/>
}
/>
}
/>
)
//axis={}
}
const RadialChart = ({keys, setSelectedCategory}) => {
const [hovered, setHovered] = useState("");
return (
{
console.log("Click: ", hovered)
if (setSelectedCategory !== undefined) {
setSelectedCategory(hovered)
}
}}>
}
series={
{
return '#f86a3e'
}}
animated={false}
id="workflow_series_id"
style={{cursor: "pointer",}}
line={
{
console.log("INFO: ", data, color)
return (
null
)
}}
/>
}
tooltip={
{
if (hovered !== event.value.x) {
setHovered(event.value.x)
}
}}
tooltip={
{
return (
{data.x}
)
/*
)
*/
}
}
/>
}
/>
}
/>
}
/>
)
//axis={}
}
// This is the start of a dashboard that can be used.
// What data do we fill in here? Idk
const Dashboard = (props) => {
const { globalUrl, isLoggedIn } = props;
const alert = useAlert();
const [bigChartData, setBgChartData] = useState("data1");
const [dayAmount, setDayAmount] = useState(7);
const [firstRequest, setFirstRequest] = useState(true);
const [stats, setStats] = useState({});
const [changeme, setChangeme] = useState("");
const [statsRan, setStatsRan] = useState(false);
const [keys, setKeys] = useState([])
const [treeKeys, setTreeKeys] = useState([])
const [selectedUsecaseCategory, setSelectedUsecaseCategory] = useState("");
const [selectedUsecases, setSelectedUsecases] = useState([]);
const [usecases, setUsecases] = useState([]);
const [workflows, setWorkflows] = useState([]);
const [frameworkData, setFrameworkData] = useState(undefined);
let navigate = useNavigate();
const isCloud =
window.location.host === "localhost:3002" ||
window.location.host === "shuffler.io";
useEffect(() => {
if (selectedUsecaseCategory.length === 0) {
setSelectedUsecases(usecases)
} else {
const foundUsecase = usecases.find(data => data.name === selectedUsecaseCategory)
if (foundUsecase !== undefined && foundUsecase !== null) {
setSelectedUsecases([foundUsecase])
}
}
}, [selectedUsecaseCategory])
const checkSelectedParams = () => {
const urlSearchParams = new URLSearchParams(window.location.search)
const params = Object.fromEntries(urlSearchParams.entries())
const curpath = typeof window === "undefined" || window.location === undefined ? "" : window.location.pathname;
const cursearch = typeof window === "undefined" || window.location === undefined ? "" : window.location.search;
const foundQuery = params["selected"]
if (foundQuery !== null && foundQuery !== undefined) {
setSelectedUsecaseCategory(foundQuery)
const newitem = removeParam("selected", cursearch);
navigate(curpath + newitem)
}
const foundQuery2 = params["selected_object"]
if (foundQuery2 !== null && foundQuery2 !== undefined) {
console.log("Got selected_object: ", foundQuery2)
const queryName = foundQuery2.toLowerCase().replaceAll("_", " ")
// Waiting a bit for it to render
setTimeout(() => {
const foundItem = document.getElementById(queryName)
if (foundItem !== undefined && foundItem !== null) {
foundItem.click()
} else {
//console.log("Couldn't find item with name ", queryName)
}
}, 100);
}
}
useEffect(() => {
if (usecases.length > 0) {
console.log(usecases)
checkSelectedParams()
}
}, [usecases])
const getFramework = () => {
fetch(globalUrl + "/api/v1/apps/frameworkConfiguration", {
method: "GET",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
credentials: "include",
})
.then((response) => {
if (response.status !== 200) {
console.log("Status not 200 for framework!");
}
return response.json();
})
.then((responseJson) => {
if (responseJson.success === false) {
if (responseJson.reason !== undefined) {
//alert.error("Failed loading: " + responseJson.reason)
} else {
//alert.error("Failed to load framework for your org.")
}
} else {
setFrameworkData(responseJson)
}
})
.catch((error) => {
alert.error(error.toString());
})
}
const getAvailableWorkflows = () => {
fetch(globalUrl + "/api/v1/workflows", {
method: "GET",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
credentials: "include",
})
.then((response) => {
if (response.status !== 200) {
fetchUsecases()
console.log("Status not 200 for workflows :O!: ", response.status);
return;
}
return response.json();
})
.then((responseJson) => {
fetchUsecases(responseJson)
if (responseJson !== undefined) {
setWorkflows(responseJson);
}
})
.catch((error) => {
fetchUsecases()
//alert.error(error.toString());
});
}
document.title = "Shuffle - usecases";
var dayGraphLabels = [60, 80, 65, 130, 80, 105, 90, 130, 70, 115, 60, 130];
var dayGraphData = [60, 80, 65, 130, 80, 105, 90, 130, 70, 115, 60, 130];
const handleKeysetting = (categorydata) => {
var allCategories = []
var treeCategories = []
for (key in categorydata) {
const category = categorydata[key]
allCategories.push({"key": category.name, "data": category.list.length, "color": category.color})
treeCategories.push({"key": category.name, "data": 100, "color": category.color,})
for (var subkey in category.list) {
treeCategories.push({"key": category.list[subkey].name, "data": 20, "color": category.color})
}
}
setKeys(allCategories)
setTreeKeys(treeCategories)
}
const fetchUsecases = (workflows) => {
fetch(globalUrl + "/api/v1/workflows/usecases", {
method: "GET",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
credentials: "include",
})
.then((response) => {
if (response.status !== 200) {
console.log("Status not 200 for usecases");
}
return response.json();
})
.then((responseJson) => {
// Matching workflows with usecases
if (responseJson.success !== false) {
if (workflows !== undefined && workflows !== null && workflows.length > 0) {
var categorydata = responseJson
var newcategories = []
for (var key in categorydata) {
var category = categorydata[key]
category.matches = []
for (var subcategorykey in category.list) {
var subcategory = category.list[subcategorykey]
subcategory.matches = []
for (var workflowkey in workflows) {
const workflow = workflows[workflowkey]
if (workflow.usecase_ids !== undefined && workflow.usecase_ids !== null) {
for (var usecasekey in workflow.usecase_ids) {
if (workflow.usecase_ids[usecasekey].toLowerCase() === subcategory.name.toLowerCase()) {
category.matches.push({
"workflow": workflow.id,
"category": subcategory.name,
})
subcategory.matches.push(workflow)
break
}
}
}
if (subcategory.matches.length > 0) {
break
}
}
}
newcategories.push(category)
}
if (newcategories !== undefined && newcategories !== null && newcategories.length > 0) {
handleKeysetting(newcategories)
setUsecases(newcategories)
setSelectedUsecases(newcategories)
} else {
handleKeysetting(responseJson)
setUsecases(responseJson)
setSelectedUsecases(responseJson)
}
} else {
handleKeysetting(responseJson)
setUsecases(responseJson)
setSelectedUsecases(responseJson)
}
}
})
.catch((error) => {
//alert.error("ERROR: " + error.toString());
console.log("ERROR: " + error.toString());
});
};
useEffect(() => {
getAvailableWorkflows()
getFramework()
//fetchUsecases()
}, []);
const fetchdata = (stats_id) => {
fetch(globalUrl + "/api/v1/stats/" + stats_id, {
method: "GET",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
credentials: "include",
})
.then((response) => {
if (response.status !== 200) {
console.log("Status not 200 for " + stats_id);
}
return response.json();
})
.then((responseJson) => {
stats[stats_id] = responseJson;
setStats(stats);
// Used to force updates
setChangeme(stats_id);
})
.catch((error) => {
//alert.error("ERROR: " + error.toString());
console.log("ERROR: " + error.toString());
});
};
let chart1_2_options = {
maintainAspectRatio: false,
legend: {
display: false,
},
tooltips: {
backgroundColor: "#f5f5f5",
titleFontColor: "#333",
bodyFontColor: "#666",
bodySpacing: 4,
xPadding: 12,
mode: "nearest",
intersect: 0,
position: "nearest",
},
responsive: true,
scales: {
yAxes: [
{
barPercentage: 1.6,
gridLines: {
drawBorder: false,
color: "rgba(29,140,248,0.0)",
zeroLineColor: "transparent",
},
ticks: {
suggestedMin: 60,
suggestedMax: 125,
padding: 20,
fontColor: "#9a9a9a",
},
},
],
xAxes: [
{
barPercentage: 1.6,
gridLines: {
drawBorder: false,
color: "rgba(29,140,248,0.1)",
zeroLineColor: "transparent",
},
ticks: {
padding: 20,
fontColor: "#9a9a9a",
},
},
],
},
};
const dayGraph = {
data: (canvas) => {
let ctx = canvas.getContext("2d");
let gradientStroke = ctx.createLinearGradient(0, 230, 0, 50);
gradientStroke.addColorStop(1, "rgba(29,140,248,0.2)");
gradientStroke.addColorStop(0.4, "rgba(29,140,248,0.0)");
gradientStroke.addColorStop(0, "rgba(29,140,248,0)"); //blue colors
return {
labels: dayGraphLabels,
datasets: [
{
label: "My First dataset",
fill: true,
backgroundColor: gradientStroke,
borderColor: "#1f8ef1",
borderWidth: 2,
borderDash: [],
borderDashOffset: 0.0,
pointBackgroundColor: "#1f8ef1",
pointBorderColor: "rgba(255,255,255,0)",
pointHoverBackgroundColor: "#1f8ef1",
pointBorderWidth: 20,
pointHoverRadius: 4,
pointHoverBorderWidth: 15,
pointRadius: 4,
data: dayGraphData,
},
],
};
},
options: chart1_2_options,
};
// All these are currently tracked.
const variables = [
"backend_executions",
"workflow_executions",
"workflow_executions_aborted",
"workflow_executions_success",
"total_apps_created",
"total_apps_loaded",
"openapi_apps_created",
"total_apps_deleted",
"total_webhooks_ran",
"total_workflows",
"total_workflow_actions",
"total_workflow_triggers",
];
const runUpdate = () => {
for (var key in variables) {
fetchdata(variables[key]);
}
};
// Refresh every 60 seconds
const autoUpdate = 60000;
const { start, stop } = useInterval({
duration: autoUpdate,
startImmediate: false,
callback: () => {
runUpdate();
},
});
if (firstRequest) {
setFirstRequest(false);
//start();
//runUpdate();
} else if (!statsRan) {
// FIXME: Run this under runUpdate schedule?
// 1. Fix labels in dayGraphy.data
// 2. Add data to the daygraph
// Every time there's an update :)
// This should probably be done in the backend.. bleh
if (
stats["workflow_executions"] !== undefined &&
stats["workflow_executions"] !== null &&
stats["workflow_executions"].data !== undefined
) {
setStatsRan(true);
//console.log("NEW DATA?: ", stats)
console.log("SET WORKFLOW: ", stats["workflow_executions"]);
//var curday = startDate.getDate()
// Index = what day are we on
// 0 = today
var newDayGraphLabels = [];
var newDayGraphData = [];
for (var i = dayAmount; i > 0; i--) {
var enddate = new Date();
enddate.setDate(-i);
enddate.setHours(23, 59, 59, 999);
var startdate = new Date();
startdate.setDate(-i);
startdate.setHours(0, 0, 0, 0);
var endtime = enddate.getTime() / 1000;
var starttime = startdate.getTime() / 1000;
console.log(
"START: ",
starttime,
"END: ",
endtime,
"Data: ",
stats["workflow_executions"]
);
for (var key in stats["workflow_executions"].data) {
const item = stats["workflow_executions"]["data"][key];
console.log("ITEM: ", item.timestamp, endtime);
console.log(endtime - starttime);
if (
endtime - starttime > endtime - item.timestamp &&
endtime.timestamp >= 0
) {
console.log("HIT? ");
}
console.log(item.timestamp - endtime);
//console.log(item.timestamp-endtime)
break;
if (item.timestamp > endtime && item.timestamp < starttime) {
if (newDayGraphData[i - 1] === undefined) {
newDayGraphData[i - 1] = 1;
} else {
newDayGraphData[i - 1] += 1;
}
//break
}
}
newDayGraphLabels.push(i);
}
console.log(newDayGraphLabels);
console.log(newDayGraphData);
}
}
const newdata =
Object.getOwnPropertyNames(stats).length > 0 ? (
Autoupdate every {autoUpdate / 1000} seconds
{variables.map((data) => {
if (stats[data] === undefined || stats[data] === null) {
return null;
}
if (stats[data].total === undefined) {
return null;
}
return (
{data}: {stats[data].total}
);
})}
) : null;
const data = (
{keys.length > 0 ?
: null}
{usecases !== null && usecases !== undefined && usecases.length > 0 ?
{usecases.map((usecase, index) => {
return (
{
console.log("Clicked: ", usecase.name)
if (selectedUsecaseCategory === usecase.name) {
setSelectedUsecaseCategory("")
} else {
setSelectedUsecaseCategory(usecase.name)
}
//addFilter(usecase.name.slice(3,usecase.name.length))
}}
variant="outlined"
color="primary"
/>
)
})}
: null}
{treeKeys.length > 0 ?
: null}
{newdata}
);
const dataWrapper = (
{data}
);
return dataWrapper;
};
export default Dashboard;