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 ? {newname} : 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;