Started work on Workflow visualization dashboard with radial charts
This commit is contained in:
+121
-173
@@ -2,32 +2,15 @@ import React, { useState } from "react";
|
||||
import { useInterval } from "react-powerhooks";
|
||||
// nodejs library that concatenates classes
|
||||
import classNames from "classnames";
|
||||
import theme from '../theme';
|
||||
|
||||
// react plugin used to create charts
|
||||
import { Line, Bar } from "react-chartjs-2";
|
||||
//import { Line, Bar } from "react-chartjs-2";
|
||||
import { useAlert } from "react-alert";
|
||||
|
||||
// https://demos.creative-tim.com/black-dashboard-react/?ref=appseed#/admin/dashboard
|
||||
|
||||
// reactstrap components
|
||||
import {
|
||||
Button,
|
||||
ButtonGroup,
|
||||
Card,
|
||||
CardHeader,
|
||||
CardBody,
|
||||
CardTitle,
|
||||
DropdownToggle,
|
||||
DropdownMenu,
|
||||
DropdownItem,
|
||||
UncontrolledDropdown,
|
||||
Label,
|
||||
FormGroup,
|
||||
Input,
|
||||
Table,
|
||||
Row,
|
||||
Col,
|
||||
UncontrolledTooltip,
|
||||
} from "reactstrap";
|
||||
Typography,
|
||||
} from "@material-ui/core";
|
||||
|
||||
// core components
|
||||
import {
|
||||
@@ -37,6 +20,112 @@ import {
|
||||
chartExample4,
|
||||
} from "../charts.js";
|
||||
|
||||
import {
|
||||
RadialBarChart,
|
||||
RadialAreaChart,
|
||||
RadialAxis,
|
||||
StackedBarSeries,
|
||||
TooltipArea,
|
||||
ChartTooltip,
|
||||
TooltipTemplate,
|
||||
RadialAreaSeries,
|
||||
RadialPointSeries,
|
||||
RadialArea,
|
||||
RadialLine,
|
||||
} from 'reaviz';
|
||||
|
||||
const keys = [
|
||||
{ key: '1. Collect & Distribute', data: 2 },
|
||||
{ key: '2. Enrich', data: 11 },
|
||||
{ key: '3. Detect', data: 3 },
|
||||
{ key: '4. Respond', data: 4 },
|
||||
{ key: '5. Report', data: 12 },
|
||||
{ key: '6. Validate', data: 7, color: "red",},
|
||||
]
|
||||
|
||||
const RadialChart = () => {
|
||||
const [hovered, setHovered] = useState("");
|
||||
|
||||
return (
|
||||
<div style={{cursor: "pointer",}} onClick={() => {
|
||||
console.log("Click: ", hovered)
|
||||
}}>
|
||||
<RadialAreaChart
|
||||
id="workflow_categories"
|
||||
height={500}
|
||||
width={500}
|
||||
data={keys}
|
||||
axis={<RadialAxis type="category" />}
|
||||
series={
|
||||
|
||||
<RadialAreaSeries
|
||||
interpolation="smooth"
|
||||
colorScheme={'#f86a3e'}
|
||||
animated={false}
|
||||
id="workflow_series_id"
|
||||
style={{cursor: "pointer",}}
|
||||
line={
|
||||
<RadialLine
|
||||
color={"#000000"}
|
||||
data={(data, color) => {
|
||||
console.log("INFO: ", data, color)
|
||||
return (
|
||||
null
|
||||
)
|
||||
}}
|
||||
/>
|
||||
}
|
||||
tooltip={
|
||||
<TooltipArea
|
||||
color={"#000000"}
|
||||
style={{
|
||||
backgroundColor: "red",
|
||||
}}
|
||||
isRadial={true}
|
||||
onValueEnter={(event) => {
|
||||
console.log("Entered: ", event.value.x)
|
||||
if (hovered !== event.value.x) {
|
||||
setHovered(event.value.x)
|
||||
}
|
||||
}}
|
||||
tooltip={
|
||||
<ChartTooltip
|
||||
followCursor={true}
|
||||
modifiers={{
|
||||
offset: '5px, 5px'
|
||||
}}
|
||||
content={(data, color) => {
|
||||
return (
|
||||
<div style={{backgroundColor: theme.palette.inputColor, border: "1px solid rgba(255,255,255,0.3)", color: "white", padding: 5, cursor: "pointer",}}>
|
||||
<Typography variant="body1">
|
||||
{data.x}
|
||||
</Typography>
|
||||
</div>
|
||||
)
|
||||
/*
|
||||
<TooltipTemplate
|
||||
color={"#ffffff"}
|
||||
value={{
|
||||
x: data.x,
|
||||
}}
|
||||
/>
|
||||
)
|
||||
*/
|
||||
}
|
||||
}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
|
||||
}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
//axis={<RadialAxis type="category" />}
|
||||
}
|
||||
|
||||
// This is the start of a dashboard that can be used.
|
||||
// What data do we fill in here? Idk
|
||||
const Dashboard = (props) => {
|
||||
@@ -76,7 +165,8 @@ const Dashboard = (props) => {
|
||||
setChangeme(stats_id);
|
||||
})
|
||||
.catch((error) => {
|
||||
alert.error("ERROR: " + error.toString());
|
||||
//alert.error("ERROR: " + error.toString());
|
||||
console.log("ERROR: " + error.toString());
|
||||
});
|
||||
};
|
||||
|
||||
@@ -302,157 +392,15 @@ const Dashboard = (props) => {
|
||||
|
||||
const data = (
|
||||
<div className="content">
|
||||
<RadialChart />
|
||||
{/*
|
||||
<StackedBarSeries
|
||||
type="stackedDiverging"
|
||||
data={keys}
|
||||
/>
|
||||
*/}
|
||||
|
||||
{newdata}
|
||||
<Row>
|
||||
<Col xs="12">
|
||||
<div className="chart-area">
|
||||
<Line data={dayGraph.data} options={dayGraph.options} />
|
||||
</div>
|
||||
</Col>
|
||||
<Col xs="12">
|
||||
<Card className="card-chart">
|
||||
<CardHeader>
|
||||
<Row>
|
||||
<Col className="text-left" sm="6">
|
||||
<h5 className="card-category">Total Shipments</h5>
|
||||
<CardTitle tag="h2">Workflows</CardTitle>
|
||||
</Col>
|
||||
<Col sm="6">
|
||||
<ButtonGroup
|
||||
className="btn-group-toggle float-right"
|
||||
data-toggle="buttons"
|
||||
>
|
||||
<Button
|
||||
tag="label"
|
||||
className={classNames("btn-simple", {
|
||||
active: bigChartData === "data1",
|
||||
})}
|
||||
color="info"
|
||||
id="0"
|
||||
size="sm"
|
||||
onClick={() => setBgChartData("data1")}
|
||||
>
|
||||
<input
|
||||
defaultChecked
|
||||
className="d-none"
|
||||
name="options"
|
||||
type="radio"
|
||||
/>
|
||||
<span className="d-none d-sm-block d-md-block d-lg-block d-xl-block">
|
||||
Accounts
|
||||
</span>
|
||||
<span className="d-block d-sm-none">
|
||||
<i className="tim-icons icon-single-02" />
|
||||
</span>
|
||||
</Button>
|
||||
<Button
|
||||
color="info"
|
||||
id="1"
|
||||
size="sm"
|
||||
tag="label"
|
||||
className={classNames("btn-simple", {
|
||||
active: bigChartData === "data2",
|
||||
})}
|
||||
onClick={() => setBgChartData("data2")}
|
||||
>
|
||||
<input className="d-none" name="options" type="radio" />
|
||||
<span className="d-none d-sm-block d-md-block d-lg-block d-xl-block">
|
||||
Purchases
|
||||
</span>
|
||||
<span className="d-block d-sm-none">
|
||||
<i className="tim-icons icon-gift-2" />
|
||||
</span>
|
||||
</Button>
|
||||
<Button
|
||||
color="info"
|
||||
id="2"
|
||||
size="sm"
|
||||
tag="label"
|
||||
className={classNames("btn-simple", {
|
||||
active: bigChartData === "data3",
|
||||
})}
|
||||
onClick={() => setBgChartData("data3")}
|
||||
>
|
||||
<input className="d-none" name="options" type="radio" />
|
||||
<span className="d-none d-sm-block d-md-block d-lg-block d-xl-block">
|
||||
Sessions
|
||||
</span>
|
||||
<span className="d-block d-sm-none">
|
||||
<i className="tim-icons icon-tap-02" />
|
||||
</span>
|
||||
</Button>
|
||||
</ButtonGroup>
|
||||
</Col>
|
||||
</Row>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<div className="chart-area">
|
||||
<Line
|
||||
data={chartExample1[bigChartData]}
|
||||
options={chartExample1.options}
|
||||
/>
|
||||
</div>
|
||||
</CardBody>
|
||||
</Card>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row>
|
||||
<Col lg="4">
|
||||
<Card className="card-chart">
|
||||
<CardHeader>
|
||||
<h5 className="card-category">Total Shipments</h5>
|
||||
<CardTitle tag="h3">
|
||||
<i className="tim-icons icon-bell-55 text-info" /> 763,215
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<div className="chart-area">
|
||||
<Line
|
||||
data={chartExample2.data}
|
||||
options={chartExample2.options}
|
||||
/>
|
||||
</div>
|
||||
</CardBody>
|
||||
</Card>
|
||||
</Col>
|
||||
<Col lg="4">
|
||||
<Card className="card-chart">
|
||||
<CardHeader>
|
||||
<h5 className="card-category">Daily Sales</h5>
|
||||
<CardTitle tag="h3">
|
||||
<i className="tim-icons icon-delivery-fast text-primary" />{" "}
|
||||
3,500€
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<div className="chart-area">
|
||||
<Bar
|
||||
data={chartExample3.data}
|
||||
options={chartExample3.options}
|
||||
/>
|
||||
</div>
|
||||
</CardBody>
|
||||
</Card>
|
||||
</Col>
|
||||
<Col lg="4">
|
||||
<Card className="card-chart">
|
||||
<CardHeader>
|
||||
<h5 className="card-category">Completed Tasks</h5>
|
||||
<CardTitle tag="h3">
|
||||
<i className="tim-icons icon-send text-success" /> 12,100K
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<div className="chart-area">
|
||||
<Line
|
||||
data={chartExample4.data}
|
||||
options={chartExample4.options}
|
||||
/>
|
||||
</div>
|
||||
</CardBody>
|
||||
</Card>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
);
|
||||
|
||||
|
||||
@@ -110,263 +110,7 @@ const useStyles = makeStyles((theme) => ({
|
||||
},
|
||||
}));
|
||||
|
||||
// Takes an action in Shuffle and
|
||||
// Returns information about the icon, the color etc to be used
|
||||
// This can be used for actions of all types
|
||||
export const GetIconInfo = (action) => {
|
||||
// Finds the icon based on the action. Should be verbs.
|
||||
const iconList = [
|
||||
{ key: "cache_add", values: ["set_cache"] },
|
||||
{ key: "cache_get", values: ["get_cache"] },
|
||||
{ key: "filter", values: ["filter", "route", "router"] },
|
||||
{ key: "merge", values: ["join", "merge"] },
|
||||
{
|
||||
key: "search",
|
||||
values: ["search", "find", "locate", "index", "analyze", "anal", "match", "check cache", "check", "verify", "validate"],
|
||||
},
|
||||
{ key: "list", values: ["list", "head", "options"] },
|
||||
{
|
||||
key: "download",
|
||||
values: [
|
||||
"capture",
|
||||
"get",
|
||||
"download",
|
||||
"return",
|
||||
"hello_world",
|
||||
"curl",
|
||||
"request",
|
||||
"export",
|
||||
"preview",
|
||||
],
|
||||
},
|
||||
{ key: "add", values: ["add", "accept", ] },
|
||||
{ key: "delete", values: ["delete", "remove", "clear", "clean", "dismiss",] },
|
||||
{
|
||||
key: "send",
|
||||
values: [
|
||||
"send",
|
||||
"dispatch",
|
||||
"mail",
|
||||
"forward",
|
||||
"post",
|
||||
"submit",
|
||||
"mark",
|
||||
"set",
|
||||
"release",
|
||||
],
|
||||
},
|
||||
{
|
||||
key: "repeat",
|
||||
values: ["repeat", "retry", "pause", "skip", "copy", "replicat", "demo", ],
|
||||
},
|
||||
{ key: "execute", values: ["execute", "run", "play", "raise"] },
|
||||
{ key: "extract", values: ["extract", "unpack", "decompress", "open"] },
|
||||
{ key: "inflate", values: ["inflate", "pack", "compress"] },
|
||||
{
|
||||
key: "edit",
|
||||
values: [
|
||||
"modify",
|
||||
"update",
|
||||
"create",
|
||||
"edit",
|
||||
"put",
|
||||
"patch",
|
||||
"change",
|
||||
"replace",
|
||||
"conver",
|
||||
"map",
|
||||
"format",
|
||||
"escape",
|
||||
"describe",
|
||||
],
|
||||
},
|
||||
{
|
||||
key: "compare",
|
||||
values: ["compare", "convert", "to", "filter", "translate", "parse"],
|
||||
},
|
||||
{ key: "close", values: ["close", "stop", "cancel", "block"] },
|
||||
];
|
||||
|
||||
var selectedKey = "";
|
||||
if (action.name === undefined || action.name === null) {
|
||||
} else {
|
||||
const actionname = action.name.toLowerCase();
|
||||
for (var key in iconList) {
|
||||
//console.log(iconList[key], actionname)
|
||||
const found = iconList[key].values.find((value) =>
|
||||
actionname.includes(value)
|
||||
);
|
||||
if (found !== null && found !== undefined) {
|
||||
selectedKey = iconList[key].key;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Some of these are manually parsed or created instead of material ui
|
||||
//M8 0C3.58 0 0 1.79 0 4C0 6.21 3.58 8 8 8C12.42 8 16 6.21 16 4C16 1.79 12.42 0 8 0ZM0 6V9C0 11.21 3.58 13 8 13C12.42 13 16 11.21 16 9V6C16 8.21 12.42 10 8 10C3.58 10 0 8.21 0 6ZM0 11V14C0 16.21 3.58 18 8 18C9.41 18 10.79 17.81 12 17.46V14.46C10.79 14.81 9.41 15 8 15C3.58 15 0 13.21 0 11ZM17 11V14H14V16H17V19H19V16H22V14H19V11
|
||||
//https://www.figma.com/file/uCfnMs5w6wnLx6ehPHEV74/Figma-Material-Design-System-v3_0?node-id=834%3A21
|
||||
//COLORS: https://www.pinterest.co.uk/pin/326299935499972946/
|
||||
const defaultColor = "#f76b1c";
|
||||
const defaultGradient = ["#fad961", "#f76b1c"];
|
||||
const parsedIcons = {
|
||||
cache_add: {
|
||||
icon: "M11 3C6.58 3 3 4.79 3 7C3 9.21 6.58 11 11 11C15.42 11 19 9.21 19 7C19 4.79 15.42 3 11 3ZM3 9V12C3 14.21 6.58 16 11 16C15.42 16 19 14.21 19 12V9C19 11.21 15.42 13 11 13C6.58 13 3 11.21 3 9ZM3 14V17C3 19.21 6.58 21 11 21C12.41 21 13.79 20.81 15 20.46V17.46C13.79 17.81 12.41 18 11 18C6.58 18 3 16.21 3 14ZM20 14V17H17V19H20V22H22V19H25V17H22V14",
|
||||
iconColor: "white",
|
||||
iconBackgroundColor: "#8acc3f",
|
||||
originalIcon: "",
|
||||
fillGradient: ["#8acc3f", "#459622"],
|
||||
},
|
||||
cache_get: {
|
||||
icon: "M12 2C7.58 2 4 3.79 4 6C4 8.06 7.13 9.74 11.15 9.96C12.45 8.7 14.19 8 16 8C16.8 8 17.59 8.14 18.34 8.41C19.37 7.74 20 6.91 20 6C20 3.79 16.42 2 12 2ZM4 8V11C4 12.68 6.08 14.11 9 14.71C9.06 13.7 9.32 12.72 9.77 11.82C6.44 11.34 4 9.82 4 8ZM15.93 9.94C14.75 9.95 13.53 10.4 12.46 11.46C8.21 15.71 13.71 22.5 18.75 19.17L23.29 23.71L24.71 22.29L20.17 17.75C22.66 13.97 19.47 9.93 15.93 9.94ZM15.9 12C17.47 11.95 19 13.16 19 15C19 15.7956 18.6839 16.5587 18.1213 17.1213C17.5587 17.6839 16.7956 18 16 18C13.33 18 12 14.77 13.88 12.88C14.47 12.29 15.19 12 15.9 12ZM4 13V16C4 18.05 7.09 19.72 11.06 19.95C10.17 19.07 9.54 17.95 9.22 16.74C6.18 16.17 4 14.72 4 13Z",
|
||||
iconColor: "white",
|
||||
iconBackgroundColor: "#8acc3f",
|
||||
originalIcon: "",
|
||||
fillGradient: ["#8acc3f", "#459622"],
|
||||
},
|
||||
repeat: {
|
||||
icon: "M19 8l-4 4h3c0 3.31-2.69 6-6 6-1.01 0-1.97-.25-2.8-.7l-1.46 1.46C8.97 19.54 10.43 20 12 20c4.42 0 8-3.58 8-8h3l-4-4zM6 12c0-3.31 2.69-6 6-6 1.01 0 1.97.25 2.8.7l1.46-1.46C15.03 4.46 13.57 4 12 4c-4.42 0-8 3.58-8 8H1l4 4 4-4H6z",
|
||||
iconColor: "white",
|
||||
iconBackgroundColor: defaultColor,
|
||||
originalIcon: <CachedIcon />,
|
||||
},
|
||||
add: {
|
||||
icon: "M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z",
|
||||
iconColor: "white",
|
||||
iconBackgroundColor: defaultColor,
|
||||
originalIcon: <AddIcon />,
|
||||
},
|
||||
edit: {
|
||||
icon: "M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34a.9959.9959 0 00-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z",
|
||||
iconColor: "white",
|
||||
iconBackgroundColor: defaultColor,
|
||||
originalIcon: <EditIcon />,
|
||||
},
|
||||
filter: {
|
||||
icon: "M4.25 5.61C6.27 8.2 10 13 10 13v6c0 .55.45 1 1 1h2c.55 0 1-.45 1-1v-6s3.72-4.8 5.74-7.39c.51-.66.04-1.61-.79-1.61H5.04c-.83 0-1.3.95-.79 1.61z",
|
||||
iconColor: "white",
|
||||
iconBackgroundColor: "#f5515f",
|
||||
originalIcon: "",
|
||||
fillGradient: ["#f5515f", "#a1051d"],
|
||||
},
|
||||
merge: {
|
||||
icon: "M17 20.41 18.41 19 15 15.59 13.59 17 17 20.41zM7.5 8H11v5.59L5.59 19 7 20.41l6-6V8h3.5L12 3.5 7.5 8z",
|
||||
iconColor: "white",
|
||||
iconBackgroundColor: "#f5515f",
|
||||
originalIcon: "",
|
||||
fillGradient: ["#f5515f", "#a1051d"],
|
||||
},
|
||||
compare: {
|
||||
icon: "M10 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h5v2h2V1h-2v2zm0 15H5l5-6v6zm9-15h-5v2h5v13l-5-6v9h5c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z",
|
||||
iconColor: "white",
|
||||
iconBackgroundColor: defaultColor,
|
||||
originalIcon: <CompareIcon />,
|
||||
},
|
||||
extract: {
|
||||
icon: "M3 3h18v2H3z",
|
||||
iconColor: "white",
|
||||
iconBackgroundColor: defaultColor,
|
||||
originalIcon: <MaximizeIcon />,
|
||||
},
|
||||
inflate: {
|
||||
icon: "M6 19h12v2H6z",
|
||||
iconColor: "white",
|
||||
iconBackgroundColor: defaultColor,
|
||||
originalIcon: <MinimizeIcon />,
|
||||
},
|
||||
list: {
|
||||
icon: "M3 9h14V7H3v2zm0 4h14v-2H3v2zm0 4h14v-2H3v2zm16 0h2v-2h-2v2zm0-10v2h2V7h-2zm0 6h2v-2h-2v2z",
|
||||
iconColor: "white",
|
||||
iconBackgroundColor: defaultColor,
|
||||
originalIcon: <TocIcon />,
|
||||
},
|
||||
execute: {
|
||||
icon: "M8 5v14l11-7z",
|
||||
iconColor: "white",
|
||||
iconBackgroundColor: defaultColor,
|
||||
originalIcon: <PlayArrowIcon />,
|
||||
},
|
||||
delete: {
|
||||
icon: "M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z",
|
||||
iconColor: "white",
|
||||
iconBackgroundColor: "#03030e",
|
||||
originalIcon: <DeleteIcon />,
|
||||
fillGradient: ["#03030e", "#205d66"],
|
||||
},
|
||||
close: {
|
||||
icon: "M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z",
|
||||
iconColor: "white",
|
||||
iconBackgroundColor: "#03030e",
|
||||
originalIcon: <CloseIcon />,
|
||||
fillGradient: ["#03030e", "#205d66"],
|
||||
},
|
||||
send: {
|
||||
icon: "M2.01 21L23 12 2.01 3 2 10l15 2-15 2z",
|
||||
iconColor: "white",
|
||||
iconBackgroundColor: "#0373da",
|
||||
originalIcon: <SendIcon />,
|
||||
fillGradient: ["#0bc8bf", "#0373da"],
|
||||
},
|
||||
download: {
|
||||
icon: "M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z",
|
||||
iconColor: "white",
|
||||
iconBackgroundColor: "#0373da",
|
||||
originalIcon: <GetAppIcon />,
|
||||
fillGradient: ["#0bc8bf", "#0373da"],
|
||||
},
|
||||
search: {
|
||||
icon: "M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z",
|
||||
iconColor: "white",
|
||||
iconBackgroundColor: "green",
|
||||
originalIcon: <SearchIcon />,
|
||||
},
|
||||
};
|
||||
|
||||
var selectedItem = parsedIcons[selectedKey];
|
||||
if (selectedItem === undefined || selectedItem === null) {
|
||||
return {
|
||||
icon: "",
|
||||
iconColor: "",
|
||||
iconBackground: "black",
|
||||
originalIcon: "",
|
||||
};
|
||||
}
|
||||
|
||||
if (selectedItem.fillGradient === undefined) {
|
||||
selectedItem.fillGradient = defaultGradient;
|
||||
selectedItem.iconBackgroundColor = defaultColor;
|
||||
}
|
||||
|
||||
if (selectedItem.icon === "" || selectedItem.icon === undefined) {
|
||||
console.log(
|
||||
`MISSING PATH FOR ${selectedKey} (find in scope): `,
|
||||
selectedItem.originalIcon.type.type
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
(selectedItem.originalIcon === undefined ||
|
||||
selectedItem.originalIcon === "") &&
|
||||
selectedItem.icon !== "" &&
|
||||
selectedItem.icon !== undefined
|
||||
) {
|
||||
const svg_pin = (
|
||||
<svg
|
||||
width={svgSize}
|
||||
height={svgSize}
|
||||
viewBox={`0 0 ${svgSize} ${svgSize}`}
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path d={selectedItem.icon} fill={selectedItem.iconColor}></path>
|
||||
</svg>
|
||||
);
|
||||
selectedItem.originalIcon = svg_pin;
|
||||
}
|
||||
|
||||
return selectedItem;
|
||||
};
|
||||
|
||||
|
||||
const chipStyle = {
|
||||
backgroundColor: "#3d3f43",
|
||||
marginRight: 5,
|
||||
@@ -378,62 +122,6 @@ const chipStyle = {
|
||||
color: "white",
|
||||
};
|
||||
|
||||
export const validateJson = (showResult) => {
|
||||
//showResult = showResult.split(" None").join(" \"None\"")
|
||||
showResult = showResult.split(" False").join(" false");
|
||||
showResult = showResult.split(" True").join(" true");
|
||||
|
||||
var jsonvalid = true;
|
||||
try {
|
||||
if (!showResult.includes("{") && !showResult.includes("[")) {
|
||||
jsonvalid = false;
|
||||
}
|
||||
} catch (e) {
|
||||
showResult = showResult.split("'").join('"');
|
||||
|
||||
try {
|
||||
if (!showResult.includes("{") && !showResult.includes("[")) {
|
||||
jsonvalid = false;
|
||||
}
|
||||
} catch (e) {
|
||||
jsonvalid = false;
|
||||
}
|
||||
}
|
||||
|
||||
var result = showResult;
|
||||
try {
|
||||
result = jsonvalid ? JSON.parse(showResult) : showResult;
|
||||
} catch (e) {
|
||||
////console.log("Failed parsing JSON even though its valid: ", e)
|
||||
jsonvalid = false;
|
||||
}
|
||||
|
||||
if (jsonvalid === false) {
|
||||
|
||||
if (typeof showResult === 'string') {
|
||||
showResult = showResult.trim()
|
||||
}
|
||||
|
||||
try {
|
||||
var newstr = showResult.replaceAll("'", '"')
|
||||
|
||||
//console.log("Try replacements and trimming with new value: ", newstr)
|
||||
result = JSON.parse(newstr)
|
||||
jsonvalid = true
|
||||
} catch (e) {
|
||||
|
||||
//console.log("Failed parsing JSON even though its valid (2): ", e)
|
||||
jsonvalid = false
|
||||
}
|
||||
}
|
||||
|
||||
//console.log("VALID: ", jsonvalid, result)
|
||||
return {
|
||||
valid: jsonvalid,
|
||||
result: result,
|
||||
};
|
||||
};
|
||||
|
||||
const GettingStarted = (props) => {
|
||||
const { globalUrl, isLoggedIn, isLoaded, userdata } = props;
|
||||
|
||||
@@ -461,8 +149,8 @@ const GettingStarted = (props) => {
|
||||
"https://github.com/frikky/shuffle-workflows"
|
||||
);
|
||||
const [downloadBranch, setDownloadBranch] = React.useState("master");
|
||||
const [loadWorkflowsModalOpen, setLoadWorkflowsModalOpen] =
|
||||
React.useState(false);
|
||||
const [loadWorkflowsModalOpen, setLoadWorkflowsModalOpen] = React.useState(false);
|
||||
const [videoViewOpen, setVideoViewOpen] = React.useState(false);
|
||||
const [exportModalOpen, setExportModalOpen] = React.useState(false);
|
||||
const [exportData, setExportData] = React.useState("");
|
||||
|
||||
@@ -827,6 +515,8 @@ const GettingStarted = (props) => {
|
||||
credentials: "include",
|
||||
})
|
||||
.then((response) => {
|
||||
setVideoViewOpen(true)
|
||||
|
||||
if (response.status !== 200) {
|
||||
console.log("Status not 200 for workflows :O!: ", response.status);
|
||||
|
||||
@@ -881,6 +571,8 @@ const GettingStarted = (props) => {
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
setVideoViewOpen(true)
|
||||
|
||||
alert.error(error.toString());
|
||||
});
|
||||
};
|
||||
@@ -2448,58 +2140,8 @@ const GettingStarted = (props) => {
|
||||
maxWidth: 600,
|
||||
};
|
||||
|
||||
const WorkflowView = () => {
|
||||
/*
|
||||
if (workflows.length === 0) {
|
||||
return (
|
||||
<div style={emptyWorkflowStyle}>
|
||||
<Paper style={boxStyle}>
|
||||
<div>
|
||||
<h2>Welcome to Shuffle</h2>
|
||||
</div>
|
||||
<div>
|
||||
<p>
|
||||
<b>Shuffle</b> is a flexible, easy to use, automation platform
|
||||
allowing users to integrate their services and devices freely.
|
||||
It's made to significantly reduce the amount of manual labor,
|
||||
and is focused on security applications.{" "}
|
||||
<a
|
||||
href="/docs/about"
|
||||
style={{ textDecoration: "none", color: "#f85a3e" }}
|
||||
>
|
||||
Click here to learn more.
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
If you want to jump straight into it, click here to create your
|
||||
first workflow:
|
||||
</div>
|
||||
<div style={{ display: "flex" }}>
|
||||
<Button
|
||||
id="second-step"
|
||||
color="primary"
|
||||
style={{ marginTop: "20px" }}
|
||||
variant="outlined"
|
||||
onClick={() => setModalOpen(true)}
|
||||
>
|
||||
New workflow
|
||||
</Button>
|
||||
<span style={{ paddingTop: 20, display: "flex" }}>
|
||||
<Typography
|
||||
style={{ marginTop: 5, marginLeft: 30, marginRight: 15 }}
|
||||
>
|
||||
..OR
|
||||
</Typography>
|
||||
{workflowButtons}
|
||||
</span>
|
||||
</div>
|
||||
</Paper>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
*/
|
||||
|
||||
const WorkflowView = () => {
|
||||
var workflowDelay = -150
|
||||
var appDelay = -75
|
||||
|
||||
@@ -2584,6 +2226,53 @@ const GettingStarted = (props) => {
|
||||
|
||||
return (
|
||||
<div style={viewStyle}>
|
||||
<Dialog
|
||||
open={videoViewOpen}
|
||||
onClose={() => {
|
||||
setVideoViewOpen(false)
|
||||
}}
|
||||
PaperProps={{
|
||||
style: {
|
||||
backgroundColor: surfaceColor,
|
||||
color: "white",
|
||||
minWidth: 560,
|
||||
minHeight: 415,
|
||||
textAlign: "center",
|
||||
},
|
||||
}}
|
||||
>
|
||||
<DialogTitle>
|
||||
Welcome to Shuffle!
|
||||
</DialogTitle>
|
||||
|
||||
<Tooltip
|
||||
title="Close window"
|
||||
placement="top"
|
||||
style={{ zIndex: 10011 }}
|
||||
>
|
||||
<IconButton
|
||||
style={{ zIndex: 5000, position: "absolute", top: 10, right: 34 }}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
setVideoViewOpen(false)
|
||||
}}
|
||||
>
|
||||
<CloseIcon style={{ color: "white" }} />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
|
||||
<iframe
|
||||
width="560"
|
||||
height="315"
|
||||
style={{margin: "0px auto 0px auto", width: 560, height: 315,}}
|
||||
src="https://www.youtube-nocookie.com/embed/rO7k9q3OgC0"
|
||||
title="Introduction video"
|
||||
frameborder="0"
|
||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
||||
allowfullscreen
|
||||
>
|
||||
</iframe>
|
||||
</Dialog>
|
||||
<div style={workflowViewStyle}>
|
||||
<Typography variant="h1" style={{fontSize: 30, marginTop: 25, }}>
|
||||
Getting Started with Shuffle
|
||||
|
||||
Reference in New Issue
Block a user