Added basic mobile view for workflows

This commit is contained in:
frikky
2022-03-02 20:45:58 +01:00
parent 790bb8607d
commit 80a6893b16
3 changed files with 548 additions and 377 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
{ {
"name": "shuffler", "name": "shuffler",
"homepage": "https://shuffler.io", "homepage": "https://shuffler.io",
"version": "0.9.50", "version": "0.9.61",
"private": true, "private": true,
"dependencies": { "dependencies": {
"@babel/core": "^7.15.8", "@babel/core": "^7.15.8",
+403 -237
View File
@@ -12,6 +12,7 @@ import NestedMenuItem from "material-ui-nested-menu-item";
import ReactMarkdown from "react-markdown"; import ReactMarkdown from "react-markdown";
import { useAlert } from "react-alert"; import { useAlert } from "react-alert";
import theme from '../theme'; import theme from '../theme';
import { isMobile } from "react-device-detect"
import { import {
Zoom, Zoom,
@@ -46,6 +47,7 @@ import {
Checkbox, Checkbox,
Breadcrumbs, Breadcrumbs,
CircularProgress, CircularProgress,
SwipeableDrawer,
Switch, Switch,
Chip, Chip,
} from "@material-ui/core"; } from "@material-ui/core";
@@ -254,8 +256,8 @@ const AngularWorkflow = (defaultprops) => {
const [userSettings, setUserSettings] = React.useState({}); const [userSettings, setUserSettings] = React.useState({});
const [subworkflow, setSubworkflow] = React.useState({}); const [subworkflow, setSubworkflow] = React.useState({});
const [subworkflowStartnode, setSubworkflowStartnode] = React.useState(""); const [subworkflowStartnode, setSubworkflowStartnode] = React.useState("");
const [leftViewOpen, setLeftViewOpen] = React.useState(true); const [leftViewOpen, setLeftViewOpen] = React.useState(isMobile ? false : true);
const [leftBarSize, setLeftBarSize] = React.useState(350); const [leftBarSize, setLeftBarSize] = React.useState(isMobile ? 0 : 350);
const [creatorProfile, setCreatorProfile] = React.useState({}); const [creatorProfile, setCreatorProfile] = React.useState({});
const [appGroup, setAppGroup] = React.useState([]); const [appGroup, setAppGroup] = React.useState([]);
const [triggerGroup, setTriggerGroup] = React.useState([]); const [triggerGroup, setTriggerGroup] = React.useState([]);
@@ -369,6 +371,7 @@ const AngularWorkflow = (defaultprops) => {
const triggerEnvironments = isCloud ? ["cloud"] : ["onprem", "cloud"]; const triggerEnvironments = isCloud ? ["cloud"] : ["onprem", "cloud"];
const unloadText = "Are you sure you want to leave without saving (CTRL+S)?"; const unloadText = "Are you sure you want to leave without saving (CTRL+S)?";
const classes = useStyles(); const classes = useStyles();
const cytoscapeWidth = isMobile ? bodyWidth - leftBarSize : bodyWidth - leftBarSize - 25
const [elements, setElements] = useState([]); const [elements, setElements] = useState([]);
@@ -3551,152 +3554,6 @@ const AngularWorkflow = (defaultprops) => {
window.location.pathname = "/workflows/" + props.match.params.key; window.location.pathname = "/workflows/" + props.match.params.key;
} }
// eslint-disable-next-line react-hooks/exhaustive-deps
useEffect(() => {
if (firstrequest) {
setFirstrequest(false);
getWorkflow(props.match.params.key, {});
getApps();
getAppAuthentication();
getEnvironments();
getWorkflowExecution(props.match.params.key, "");
getAvailableWorkflows(-1);
getSettings();
const cursearch =
typeof window === "undefined" || window.location === undefined
? ""
: window.location.search;
// FIXME: Don't check specific one here
const tmpExec = new URLSearchParams(cursearch).get("execution_highlight");
if (
tmpExec !== undefined &&
tmpExec !== null &&
tmpExec === "executions"
) {
setExecutionModalOpen(true)
const newitem = removeParam("execution_highlight", cursearch);
navigate(curpath + newitem)
//props.history.push(curpath + newitem);
}
const tmpView = new URLSearchParams(cursearch).get("view");
if (
tmpView !== undefined &&
tmpView !== null &&
tmpView === "executions"
) {
setExecutionModalOpen(true);
const newitem = removeParam("view", cursearch);
navigate(curpath + newitem)
//navigate(`?execution_highlight=${parsed_url}`)
//props.history.push(curpath + newitem);
}
return;
}
// App length necessary cus of cy initialization
if (
// First load - gets the workflow
elements.length === 0 &&
workflow.actions !== undefined &&
!graphSetup &&
Object.getOwnPropertyNames(workflow).length > 0
) {
setGraphSetup(true);
setupGraph();
console.log("In graph setup")
} else if (
// 2nd load - configures cytoscape
//
!established &&
cy !== undefined &&
((apps !== null &&
apps !== undefined &&
apps.length > 0) || workflow.public === true) &&
Object.getOwnPropertyNames(workflow).length > 0 &&
authLoaded
) {
console.log("In POST graph setup!")
//This part has to load LAST, as it's kind of not async.
//This means we need everything else to happen first.
setEstablished(true);
// Validate if the node is just a node lol
cy.edgehandles({
handleNodes: (el) => {
if (el.isNode() &&
!el.data("isButton") &&
!el.data("isDescriptor") &&
!el.data("isSuggestion") &&
el.data("type") !== "COMMENT") {
return true
}
return false
},
preview: true,
toggleOffOnLeave: true,
loopAllowed: function (node) {
return false;
},
});
cy.fit(null, 200);
cy.on("boxselect", "node", (e) => {
if (e.target.data("isButton") || e.target.data("isDescriptor") || e.target.data("isSuggestion")) {
e.target.unselect();
}
e.target.addClass("selected");
});
cy.on("boxstart", (e) => {
console.log("START");
cy.removeListener("select");
});
cy.on("boxend", (e) => {
console.log("END: ", cy)
var cydata = cy.$(":selected").jsons();
if (cydata !== undefined && cydata !== null && cydata.length > 0) {
alert.success(`Selected ${cydata.length} element(s). CTRL+C to copy them.`);
}
});
cy.on("select", "node", (e) => {
onNodeSelect(e, appAuthentication);
});
cy.on("select", "edge", (e) => onEdgeSelect(e));
cy.on("unselect", (e) => onUnselect(e));
cy.on("add", "node", (e) => onNodeAdded(e));
cy.on("add", "edge", (e) => onEdgeAdded(e));
cy.on("remove", "node", (e) => onNodeRemoved(e));
cy.on("remove", "edge", (e) => onEdgeRemoved(e));
cy.on("mouseover", "edge", (e) => onEdgeHover(e));
cy.on("mouseout", "edge", (e) => onEdgeHoverOut(e));
cy.on("mouseover", "node", (e) => onNodeHover(e));
cy.on("mouseout", "node", (e) => onNodeHoverOut(e));
// Handles dragging
cy.on("drag", "node", (e) => onNodeDrag(e, selectedAction));
cy.on("free", "node", (e) => onNodeDragStop(e, selectedAction));
cy.on("cxttap", "node", (e) => onCtxTap(e));
document.title = "Workflow - " + workflow.name;
registerKeys();
}
})
const animationDuration = 150; const animationDuration = 150;
const onNodeHoverOut = (event) => { const onNodeHoverOut = (event) => {
const nodedata = event.target.data(); const nodedata = event.target.data();
@@ -4377,6 +4234,152 @@ const AngularWorkflow = (defaultprops) => {
*/ */
}; };
// eslint-disable-next-line react-hooks/exhaustive-deps
//useEffect(() => {
if (firstrequest) {
setFirstrequest(false);
getWorkflow(props.match.params.key, {});
getApps();
getAppAuthentication();
getEnvironments();
getWorkflowExecution(props.match.params.key, "");
getAvailableWorkflows(-1);
getSettings();
const cursearch =
typeof window === "undefined" || window.location === undefined
? ""
: window.location.search;
// FIXME: Don't check specific one here
const tmpExec = new URLSearchParams(cursearch).get("execution_highlight");
if (
tmpExec !== undefined &&
tmpExec !== null &&
tmpExec === "executions"
) {
setExecutionModalOpen(true)
const newitem = removeParam("execution_highlight", cursearch);
navigate(curpath + newitem)
//props.history.push(curpath + newitem);
}
const tmpView = new URLSearchParams(cursearch).get("view");
if (
tmpView !== undefined &&
tmpView !== null &&
tmpView === "executions"
) {
setExecutionModalOpen(true);
const newitem = removeParam("view", cursearch);
navigate(curpath + newitem)
//navigate(`?execution_highlight=${parsed_url}`)
//props.history.push(curpath + newitem);
}
return;
}
// App length necessary cus of cy initialization
if (
// First load - gets the workflow
elements.length === 0 &&
workflow.actions !== undefined &&
!graphSetup &&
Object.getOwnPropertyNames(workflow).length > 0
) {
setGraphSetup(true);
setupGraph();
console.log("In graph setup")
} else if (
// 2nd load - configures cytoscape
//
!established &&
cy !== undefined &&
((apps !== null &&
apps !== undefined &&
apps.length > 0) || workflow.public === true) &&
Object.getOwnPropertyNames(workflow).length > 0 &&
authLoaded
) {
console.log("In POST graph setup!")
//This part has to load LAST, as it's kind of not async.
//This means we need everything else to happen first.
setEstablished(true);
// Validate if the node is just a node lol
cy.edgehandles({
handleNodes: (el) => {
if (el.isNode() &&
!el.data("isButton") &&
!el.data("isDescriptor") &&
!el.data("isSuggestion") &&
el.data("type") !== "COMMENT") {
return true
}
return false
},
preview: true,
toggleOffOnLeave: true,
loopAllowed: function (node) {
return false;
},
});
cy.fit(null, 200);
cy.on("boxselect", "node", (e) => {
if (e.target.data("isButton") || e.target.data("isDescriptor") || e.target.data("isSuggestion")) {
e.target.unselect();
}
e.target.addClass("selected");
});
cy.on("boxstart", (e) => {
console.log("START");
cy.removeListener("select");
});
cy.on("boxend", (e) => {
console.log("END: ", cy)
var cydata = cy.$(":selected").jsons();
if (cydata !== undefined && cydata !== null && cydata.length > 0) {
alert.success(`Selected ${cydata.length} element(s). CTRL+C to copy them.`);
}
});
cy.on("select", "node", (e) => {
onNodeSelect(e, appAuthentication);
});
cy.on("select", "edge", (e) => onEdgeSelect(e));
cy.on("unselect", (e) => onUnselect(e));
cy.on("add", "node", (e) => onNodeAdded(e));
cy.on("add", "edge", (e) => onEdgeAdded(e));
cy.on("remove", "node", (e) => onNodeRemoved(e));
cy.on("remove", "edge", (e) => onEdgeRemoved(e));
cy.on("mouseover", "edge", (e) => onEdgeHover(e));
cy.on("mouseout", "edge", (e) => onEdgeHoverOut(e));
cy.on("mouseover", "node", (e) => onNodeHover(e));
cy.on("mouseout", "node", (e) => onNodeHoverOut(e));
// Handles dragging
cy.on("drag", "node", (e) => onNodeDrag(e, selectedAction));
cy.on("free", "node", (e) => onNodeDragStop(e, selectedAction));
cy.on("cxttap", "node", (e) => onCtxTap(e));
document.title = "Workflow - " + workflow.name;
registerKeys();
}
//})
const stopSchedule = (trigger, triggerindex) => { const stopSchedule = (trigger, triggerindex) => {
fetch( fetch(
globalUrl + globalUrl +
@@ -4478,15 +4481,16 @@ const AngularWorkflow = (defaultprops) => {
marginRight: 5, marginRight: 5,
display: "flex", display: "flex",
flexDirection: "column", flexDirection: "column",
height: "100%", minHeight: isMobile ? bodyHeight-appBarSize*4 : "100%",
maxHeight: isMobile ? bodyHeight-appBarSize*4 : "100%",
}; };
const paperAppStyle = { const paperAppStyle = {
borderRadius: theme.palette.borderRadius, borderRadius: theme.palette.borderRadius,
minHeight: 100, minHeight: isMobile ? 50 : 100,
maxHeight: 100, maxHeight: isMobile ? 50 : 100,
minWidth: "100%", minWidth: isMobile ? 50 : "100%",
maxWidth: "100%", maxWidth: isMobile ? 50 : "100%",
marginTop: "5px", marginTop: "5px",
color: "white", color: "white",
backgroundColor: surfaceColor, backgroundColor: surfaceColor,
@@ -4542,7 +4546,7 @@ const AngularWorkflow = (defaultprops) => {
const variableScrollStyle = { const variableScrollStyle = {
margin: 15, margin: 15,
overflow: "scroll", overflow: "scroll",
height: "66vh", height: isMobile ? "100%" : "66vh",
overflowX: "auto", overflowX: "auto",
overflowY: "auto", overflowY: "auto",
flex: "10", flex: "10",
@@ -4834,8 +4838,8 @@ const AngularWorkflow = (defaultprops) => {
} }
const tabStyle = { const tabStyle = {
maxWidth: leftBarSize / 3, maxWidth: isMobile ? leftBarSize : leftBarSize / 3,
minWidth: leftBarSize / 3, minWidth: isMobile ? leftBarSize : leftBarSize / 3,
flex: 1, flex: 1,
textTransform: "none", textTransform: "none",
}; };
@@ -4845,12 +4849,14 @@ const AngularWorkflow = (defaultprops) => {
marginRight: 5, marginRight: 5,
}; };
const parsedHeight = isMobile ? bodyHeight - appBarSize*4 : bodyHeight - appBarSize - 50
return ( return (
<div> <div>
<div <div
style={{ style={{
minHeight: bodyHeight - appBarSize - 50, minHeight: parsedHeight,
maxHeight: bodyHeight - appBarSize - 50, maxHeight: parsedHeight,
overflow: "hidden",
}} }}
> >
{thisview} {thisview}
@@ -4861,6 +4867,8 @@ const AngularWorkflow = (defaultprops) => {
indicatorColor="primary" indicatorColor="primary"
onChange={handleSetTab} onChange={handleSetTab}
aria-label="Left sidebar tab" aria-label="Left sidebar tab"
orientation={isMobile ? "vertical" : "horizontal"}
style={{}}
> >
<Tab <Tab
label={ label={
@@ -4868,7 +4876,7 @@ const AngularWorkflow = (defaultprops) => {
<Grid item> <Grid item>
<AppsIcon style={iconStyle} /> <AppsIcon style={iconStyle} />
</Grid> </Grid>
<Grid item>Apps</Grid> {isMobile ? null : <Grid item>Apps</Grid>}
</Grid> </Grid>
} }
style={tabStyle} style={tabStyle}
@@ -4879,7 +4887,7 @@ const AngularWorkflow = (defaultprops) => {
<Grid item> <Grid item>
<ScheduleIcon style={iconStyle} /> <ScheduleIcon style={iconStyle} />
</Grid> </Grid>
<Grid item>Triggers</Grid> {isMobile ? null : <Grid item>Triggers</Grid>}
</Grid> </Grid>
} }
style={tabStyle} style={tabStyle}
@@ -4890,7 +4898,7 @@ const AngularWorkflow = (defaultprops) => {
<Grid item> <Grid item>
<FavoriteBorderIcon style={iconStyle} /> <FavoriteBorderIcon style={iconStyle} />
</Grid> </Grid>
<Grid item>Variables</Grid> {isMobile ? null : <Grid item>Variables</Grid>}
</Grid> </Grid>
} }
style={tabStyle} style={tabStyle}
@@ -5003,12 +5011,12 @@ const AngularWorkflow = (defaultprops) => {
{triggers.map((trigger, index) => { {triggers.map((trigger, index) => {
var imageline = var imageline =
trigger.large_image.length === 0 ? ( trigger.large_image.length === 0 ? (
<img alt="" style={{ width: "80px", pointerEvents: "none" }} /> <img alt="" style={{ width: isMobile ? 40 : 80, pointerEvents: "none" }} />
) : ( ) : (
<img <img
alt="" alt=""
src={trigger.large_image} src={trigger.large_image}
style={{ width: 80, height: 80, pointerEvents: "none" }} style={{ width: isMobile ? 40 : 80, height: isMobile ? 40 : 80, pointerEvents: "none" }}
/> />
); );
@@ -5031,8 +5039,8 @@ const AngularWorkflow = (defaultprops) => {
<Paper square style={paperAppStyle} onClick={() => {}}> <Paper square style={paperAppStyle} onClick={() => {}}>
<div <div
style={{ style={{
marginLeft: "10px", marginLeft: isMobile ? 0 : "10px",
marginTop: "5px", marginTop: isMobile ? 10 : "5px",
marginBottom: "5px", marginBottom: "5px",
width: "2px", width: "2px",
backgroundColor: color, backgroundColor: color,
@@ -5041,11 +5049,12 @@ const AngularWorkflow = (defaultprops) => {
></div> ></div>
<Grid <Grid
container container
style={{ margin: "10px 10px 10px 10px", flex: "10" }} style={{ margin: isMobile ? "10px 0px 0px 0px" : "10px 10px 10px 10px", flex: "10" }}
> >
<Grid item> <Grid item>
<ButtonBase>{imageline}</ButtonBase> <ButtonBase>{imageline}</ButtonBase>
</Grid> </Grid>
{isMobile ? null :
<Grid <Grid
style={{ style={{
display: "flex", display: "flex",
@@ -5062,6 +5071,7 @@ const AngularWorkflow = (defaultprops) => {
{trigger.description} {trigger.description}
</Grid> </Grid>
</Grid> </Grid>
}
</Grid> </Grid>
</Paper> </Paper>
</Draggable> </Draggable>
@@ -5236,8 +5246,8 @@ const AngularWorkflow = (defaultprops) => {
const appScrollStyle = { const appScrollStyle = {
overflow: "scroll", overflow: "scroll",
maxHeight: bodyHeight - appBarSize - 55 - 50, maxHeight: isMobile ? bodyHeight-appBarSize*4 : bodyHeight - appBarSize - 55 - 50,
minHeight: bodyHeight - appBarSize - 55 - 50, minHeight: isMobile ? bodyHeight-appBarSize*4 : bodyHeight - appBarSize - 55 - 50,
marginTop: 1, marginTop: 1,
overflowY: "auto", overflowY: "auto",
overflowX: "hidden", overflowX: "hidden",
@@ -5246,6 +5256,9 @@ const AngularWorkflow = (defaultprops) => {
const handleAppDrag = (e, app) => { const handleAppDrag = (e, app) => {
const cycontainer = cy.container(); const cycontainer = cy.container();
//console.log("e: ", e)
//console.log("Offset: ", cycontainer)
// Chrome lol // Chrome lol
if ( if (
e.pageX > cycontainer.offsetLeft && e.pageX > cycontainer.offsetLeft &&
@@ -5437,6 +5450,94 @@ const AngularWorkflow = (defaultprops) => {
onMouseOut={() => { onMouseOut={() => {
setHover(false); setHover(false);
}} }}
onClick={() => {
if (isMobile) {
newNodeId = uuidv4();
const actionType = "ACTION";
const actionLabel = getNextActionName(app.name);
var parameters = null;
var example = "";
var description = ""
if (
app.actions[0].parameters !== null &&
app.actions[0].parameters.length > 0
) {
parameters = app.actions[0].parameters;
}
if (
app.actions[0].returns.example !== undefined &&
app.actions[0].returns.example !== null &&
app.actions[0].returns.example.length > 0
) {
example = app.actions[0].returns.example;
}
if (
app.actions[0].description !== undefined &&
app.actions[0].description !== null &&
app.actions[0].description.length > 0
) {
description = app.actions[0].description
}
const parsedEnvironments =
environments === null || environments === []
? "cloud"
: environments[defaultEnvironmentIndex] === undefined
? "cloud"
: environments[defaultEnvironmentIndex].Name;
// activated: app.generated === true ? app.activated === false ? false : true : true,
const newAppData = {
app_name: app.name,
app_version: app.app_version,
app_id: app.id,
sharing: app.sharing,
private_id: app.private_id,
description: description,
environment: parsedEnvironments,
errors: [],
finished: false,
id_: newNodeId,
_id_: newNodeId,
id: newNodeId,
is_valid: true,
label: actionLabel,
type: actionType,
name: app.actions[0].name,
parameters: parameters,
isStartNode: false,
large_image: app.large_image,
run_magic_output: false,
authentication: [],
execution_variable: undefined,
example: example,
category:
app.categories !== null &&
app.categories !== undefined &&
app.categories.length > 0
? app.categories[0]
: "",
authentication_id: "",
finished: false,
};
const nodeToBeAdded = {
group: "nodes",
data: newAppData,
renderedPosition: {
x: 100,
y: 100,
},
};
parsedApp = nodeToBeAdded;
cy.add(nodeToBeAdded);
}
}}
> >
<Grid <Grid
container container
@@ -5451,11 +5552,12 @@ const AngularWorkflow = (defaultprops) => {
userDrag: "none", userDrag: "none",
userSelect: "none", userSelect: "none",
borderRadius: theme.palette.borderRadius, borderRadius: theme.palette.borderRadius,
height: 80, height: isMobile ? 40 : 80,
width: 80, width: isMobile ? 40 : 80,
}} }}
/> />
</Grid> </Grid>
{isMobile ? null :
<Grid <Grid
style={{ style={{
display: "flex", display: "flex",
@@ -5494,6 +5596,7 @@ const AngularWorkflow = (defaultprops) => {
</Typography> </Typography>
</Grid> </Grid>
</Grid> </Grid>
}
</Grid> </Grid>
</Paper> </Paper>
</Draggable> </Draggable>
@@ -5949,7 +6052,7 @@ const AngularWorkflow = (defaultprops) => {
top: appBarSize + 25, top: appBarSize + 25,
right: 25, right: 25,
height: "80vh", height: "80vh",
width: 365, width: isMobile ? "100%" : 365,
minWidth: 200, minWidth: 200,
maxWidth: 600, maxWidth: 600,
maxHeight: "100vh", maxHeight: "100vh",
@@ -6412,7 +6515,7 @@ const AngularWorkflow = (defaultprops) => {
pointerEvents: "auto", pointerEvents: "auto",
backgroundColor: surfaceColor, backgroundColor: surfaceColor,
color: "white", color: "white",
minWidth: 800, minWidth: isMobile ? "90%" : 800,
border: theme.palette.defaultBorder, border: theme.palette.defaultBorder,
}, },
}} }}
@@ -10066,12 +10169,13 @@ const AngularWorkflow = (defaultprops) => {
return null; return null;
}; };
const cytoscapeViewWidths = 850; const cytoscapeViewWidths = isMobile ? 50 : 850;
const bottomBarStyle = { const bottomBarStyle = {
position: "fixed", position: "fixed",
right: 20, right: isMobile ? 20 : 20,
left: leftBarSize, bottom: isMobile ? undefined : 0,
bottom: 0, top: isMobile ? appBarSize + 55 : undefined,
left: isMobile ? undefined : leftBarSize,
minWidth: cytoscapeViewWidths, minWidth: cytoscapeViewWidths,
maxWidth: cytoscapeViewWidths, maxWidth: cytoscapeViewWidths,
marginLeft: 20, marginLeft: 20,
@@ -10082,8 +10186,8 @@ const AngularWorkflow = (defaultprops) => {
const topBarStyle = { const topBarStyle = {
position: "fixed", position: "fixed",
right: 0, right: 0,
left: leftBarSize + 20, left: isMobile ? 20 : leftBarSize + 20,
top: appBarSize + 20, top: isMobile ? 30 : appBarSize + 20,
}; };
const TopCytoscapeBar = (props) => { const TopCytoscapeBar = (props) => {
@@ -10226,6 +10330,29 @@ const AngularWorkflow = (defaultprops) => {
</Button> </Button>
</span> </span>
</Tooltip> </Tooltip>
{isMobile ?
<Tooltip
color="secondary"
title="Show apps"
placement="top-start"
>
<span>
<Button
disabled={workflow.public}
color="primary"
style={{ height: 50, marginLeft: 10 }}
variant="outlined"
onClick={(event) => {
console.log("Show apps!")
setLeftBarSize(leftViewOpen ? 0 : 60)
setLeftViewOpen(!leftViewOpen)
}}
>
<AppsIcon />
</Button>
</span>
</Tooltip>
: null}
</div> </div>
); );
}; };
@@ -10315,7 +10442,7 @@ const AngularWorkflow = (defaultprops) => {
return null; return null;
} }
const boxSize = 100; const boxSize = isMobile ? 50 : 100;
const executionButton = executionRunning ? ( const executionButton = executionRunning ? (
<Tooltip color="primary" title="Stop execution" placement="top"> <Tooltip color="primary" title="Stop execution" placement="top">
<span> <span>
@@ -10327,7 +10454,7 @@ const AngularWorkflow = (defaultprops) => {
abortExecution(); abortExecution();
}} }}
> >
<PauseIcon style={{ fontSize: 60 }} /> <PauseIcon style={{ fontSize: isMobile ? 30 : 60 }} />
</Button> </Button>
</span> </span>
</Tooltip> </Tooltip>
@@ -10345,7 +10472,7 @@ const AngularWorkflow = (defaultprops) => {
executeWorkflow(executionText, workflow.start, lastSaved); executeWorkflow(executionText, workflow.start, lastSaved);
}} }}
> >
<PlayArrowIcon style={{ fontSize: 60 }} /> <PlayArrowIcon style={{ fontSize: isMobile ? 30 : 60 }} />
</Button> </Button>
</span> </span>
</Tooltip> </Tooltip>
@@ -10356,13 +10483,17 @@ const AngularWorkflow = (defaultprops) => {
{executionButton} {executionButton}
<div <div
style={{ style={{
marginLeft: "10px", marginLeft: isMobile ? 0 : 10,
left: boxSize, marginTop: isMobile ? 5 : 0,
left: isMobile ? -10 : boxSize,
top: isMobile ? boxSize : undefined,
bottom: 0, bottom: 0,
position: "absolute", position: "absolute",
display: "flex",
flexDirection: isMobile ? "column" : "row",
}} }}
> >
{workflow.public ? null : ( {isMobile || workflow.public ? null : (
<Tooltip <Tooltip
color="primary" color="primary"
title="An argument to be used for execution. This is a variable available to every node in your workflow." title="An argument to be used for execution. This is a variable available to every node in your workflow."
@@ -10599,15 +10730,13 @@ const AngularWorkflow = (defaultprops) => {
return null; return null;
} }
var defaultReturn = null
if (Object.getOwnPropertyNames(selectedAction).length > 0) { if (Object.getOwnPropertyNames(selectedAction).length > 0) {
if (Object.getOwnPropertyNames(selectedAction).length === 0) { if (Object.getOwnPropertyNames(selectedAction).length === 0) {
return null; return null;
} }
return ( defaultReturn = <ParsedAction
<Fade in={true} style={{ transitionDelay: `$0ms` }}>
<div id="rightside_actions" style={rightsidebarStyle}>
<ParsedAction
id="rightside_subactions" id="rightside_subactions"
isCloud={isCloud} isCloud={isCloud}
getParents={getParents} getParents={getParents}
@@ -10646,47 +10775,22 @@ const AngularWorkflow = (defaultprops) => {
setSelectedActionEnvironment={setSelectedActionEnvironment} setSelectedActionEnvironment={setSelectedActionEnvironment}
requiresAuthentication={requiresAuthentication} requiresAuthentication={requiresAuthentication}
/> />
</div>
</Fade>
);
} else if (Object.getOwnPropertyNames(selectedComment).length > 0) { } else if (Object.getOwnPropertyNames(selectedComment).length > 0) {
return ( defaultReturn = <CommentSidebar />
<div style={rightsidebarStyle}>
<CommentSidebar />
</div>
);
} else if (Object.getOwnPropertyNames(selectedTrigger).length > 0) { } else if (Object.getOwnPropertyNames(selectedTrigger).length > 0) {
if (selectedTrigger.trigger_type === "SCHEDULE") { if (selectedTrigger.trigger_type === "SCHEDULE") {
return ( defaultReturn = <ScheduleSidebar />
<div style={rightsidebarStyle}>
<ScheduleSidebar />
</div>
);
} else if (selectedTrigger.trigger_type === "WEBHOOK") { } else if (selectedTrigger.trigger_type === "WEBHOOK") {
return ( defaultReturn = <WebhookSidebar />
<div style={rightsidebarStyle}>
<WebhookSidebar />
</div>
);
} else if (selectedTrigger.trigger_type === "SUBFLOW") { } else if (selectedTrigger.trigger_type === "SUBFLOW") {
return ( defaultReturn = <SubflowSidebar />
<div style={rightsidebarStyle}>
<SubflowSidebar />
</div>
);
} else if (selectedTrigger.trigger_type === "EMAIL") { } else if (selectedTrigger.trigger_type === "EMAIL") {
return ( defaultReturn = <EmailSidebar />
<div style={rightsidebarStyle}>
<EmailSidebar />
</div>
);
} else if (selectedTrigger.trigger_type === "USERINPUT") { } else if (selectedTrigger.trigger_type === "USERINPUT") {
return ( defaultReturn = <UserinputSidebar />
<div style={rightsidebarStyle}>
<UserinputSidebar />
</div>
);
} else if (selectedTrigger.trigger_type === undefined) { } else if (selectedTrigger.trigger_type === undefined) {
//defaultReturn = <UserinputSidebar />
return null; return null;
} else { } else {
console.log( console.log(
@@ -10696,14 +10800,46 @@ const AngularWorkflow = (defaultprops) => {
return null; return null;
} }
} else if (Object.getOwnPropertyNames(selectedEdge).length > 0) { } else if (Object.getOwnPropertyNames(selectedEdge).length > 0) {
return ( defaultReturn = <EdgeSidebar />
<div style={rightsidebarStyle}>
<EdgeSidebar />
</div>
);
} }
return null; const iOS = typeof navigator !== 'undefined' && /iPad|iPhone|iPod/.test(navigator.userAgent);
const drawerBleeding = 56;
return (
isMobile ?
<SwipeableDrawer
anchor={"bottom"}
disableBackdropTransition={!iOS}
disableDiscovery={iOS}
open={true}
onClose={() => {
console.log("Close!")
//setRightSideBarOpen(false)
cy.elements().unselect()
}}
disableSwipeToOpen={false}
ModalProps={{
keepMounted: true,
}}
PaperProps={{
style: {
maxHeight: "70%",
overflow: "auto",
}
}}
>
{defaultReturn}
</SwipeableDrawer>
:
<Fade in={true} style={{ transitionDelay: `$0ms` }}>
<div id="rightside_actions" style={rightsidebarStyle}>
{defaultReturn}
</div>
</Fade>
);
//return null;
}; };
// This can execute a workflow with firestore. Used for test, as datastore is old and stuff // This can execute a workflow with firestore. Used for test, as datastore is old and stuff
@@ -10850,6 +10986,14 @@ const AngularWorkflow = (defaultprops) => {
</div> </div>
: null} : null}
</div> </div>
: isMobile && leftViewOpen ?
<div
style={{
borderRight: "1px solid rgb(91, 96, 100)",
}}
>
<HandleLeftView />
</div>
: leftViewOpen ? ( : leftViewOpen ? (
<div <div
style={{ style={{
@@ -11287,7 +11431,9 @@ const parsedExecutionArgument = () => {
<Drawer <Drawer
anchor={"right"} anchor={"right"}
open={executionModalOpen} open={executionModalOpen}
onClose={() => setExecutionModalOpen(false)} onClose={() => {
setExecutionModalOpen(false)
}}
style={{ resize: "both", overflow: "auto", zIndex: 10005 }} style={{ resize: "both", overflow: "auto", zIndex: 10005 }}
hideBackdrop={false} hideBackdrop={false}
variant="temporary" variant="temporary"
@@ -11300,8 +11446,8 @@ const parsedExecutionArgument = () => {
style: { style: {
resize: "both", resize: "both",
overflow: "auto", overflow: "auto",
minWidth: 420, minWidth: isMobile ? "100%" : 420,
maxWidth: 420, maxWidth: isMobile ? "100%" : 420,
backgroundColor: "#1F2023", backgroundColor: "#1F2023",
color: "white", color: "white",
fontSize: 18, fontSize: 18,
@@ -11310,8 +11456,25 @@ const parsedExecutionArgument = () => {
}, },
}} }}
> >
{isMobile ?
<Tooltip
title="Close window"
placement="top"
style={{ zIndex: 10011 }}
>
<IconButton
style={{ zIndex: 5000, position: "absolute", top: 10 , right: 10 }}
onClick={(e) => {
e.preventDefault();
setExecutionModalOpen(false)
}}
>
<CloseIcon style={{ color: "white" }} />
</IconButton>
</Tooltip>
: null}
{executionModalView === 0 ? ( {executionModalView === 0 ? (
<div style={{ padding: 25 }}> <div style={{ padding: isMobile ? "0px 0px 0px 10px" : 25 }}>
<Breadcrumbs <Breadcrumbs
aria-label="breadcrumb" aria-label="breadcrumb"
separator="›" separator="›"
@@ -11525,7 +11688,7 @@ const parsedExecutionArgument = () => {
)} )}
</div> </div>
) : ( ) : (
<div style={{ padding: "25px 15px 25px 15px", maxWidth: 365, overflowX: "hidden" }}> <div style={{ padding: isMobile ? "0px 10px 25px 10px" : "25px 15px 25px 15px", maxWidth: isMobile ? "100%" : 365, overflowX: "hidden" }}>
<Breadcrumbs <Breadcrumbs
aria-label="breadcrumb" aria-label="breadcrumb"
separator="›" separator="›"
@@ -12194,7 +12357,7 @@ const parsedExecutionArgument = () => {
pointerEvents: "auto", pointerEvents: "auto",
backgroundColor: inputColor, backgroundColor: inputColor,
color: "white", color: "white",
minWidth: 650, minWidth: isMobile ? "90%" : 650,
padding: 30, padding: 30,
maxHeight: 550, maxHeight: 550,
overflowY: "auto", overflowY: "auto",
@@ -12444,6 +12607,7 @@ const parsedExecutionArgument = () => {
<div <div
style={{ display: "flex", borderTop: "1px solid rgba(91, 96, 100, 1)" }} style={{ display: "flex", borderTop: "1px solid rgba(91, 96, 100, 1)" }}
> >
{/*isMobile ? null : leftView*/}
{leftView} {leftView}
{workflow.id === undefined || {workflow.id === undefined ||
workflow.id === null || workflow.id === null ||
@@ -12476,7 +12640,7 @@ const parsedExecutionArgument = () => {
maxZoom={2.0} maxZoom={2.0}
wheelSensitivity={0.25} wheelSensitivity={0.25}
style={{ style={{
width: bodyWidth - leftBarSize - 25, width: cytoscapeWidth,
height: bodyHeight - appBarSize - 5, height: bodyHeight - appBarSize - 5,
backgroundColor: surfaceColor, backgroundColor: surfaceColor,
}} }}
@@ -12563,6 +12727,7 @@ const parsedExecutionArgument = () => {
backgroundColor: surfaceColor, backgroundColor: surfaceColor,
color: "white", color: "white",
border: theme.palette.defaultBorder, border: theme.palette.defaultBorder,
maxWidth: "100%",
}, },
}} }}
> >
@@ -12718,6 +12883,7 @@ const parsedExecutionArgument = () => {
backgroundColor: surfaceColor, backgroundColor: surfaceColor,
color: "white", color: "white",
border: theme.palette.defaultBorder, border: theme.palette.defaultBorder,
maxWidth: isMobile ? bodyWidth-100 : "100%",
}, },
}} }}
> >
@@ -13308,10 +13474,10 @@ const parsedExecutionArgument = () => {
style={{ style={{
flex: 2, flex: 2,
padding: 0, padding: 0,
minHeight: 650, minHeight: isMobile ? "90%" : 650,
maxHeight: 650, maxHeight: isMobile ? "90%" : 650,
overflowY: "auto", overflowY: "auto",
overflowX: "hidden", overflowX: isMobile ? "auto" : "hidden",
}} }}
> >
{authenticationType.type === "oauth2" ? ( {authenticationType.type === "oauth2" ? (
+13 -8
View File
@@ -6,6 +6,7 @@ import { Navigate } from "react-router-dom";
import SecurityFramework from '../components/SecurityFramework.jsx'; import SecurityFramework from '../components/SecurityFramework.jsx';
import { ShepherdTour, ShepherdTourContext } from 'react-shepherd' import { ShepherdTour, ShepherdTourContext } from 'react-shepherd'
import { isMobile } from "react-device-detect"
import { import {
@@ -1017,8 +1018,8 @@ const Workflows = (props) => {
color: "#ffffff", color: "#ffffff",
width: "100%", width: "100%",
display: "flex", display: "flex",
minWidth: 1024, minWidth: isMobile ? "100%" : 1024,
maxWidth: 1024, maxWidth: isMobile ? "100%" : 1024,
margin: "auto", margin: "auto",
}; };
@@ -1038,6 +1039,7 @@ const Workflows = (props) => {
flexDirection: "column", flexDirection: "column",
}; };
//flexDirection: !isMobile ? "column" : "row",
const paperAppContainer = { const paperAppContainer = {
display: "flex", display: "flex",
flexWrap: "wrap", flexWrap: "wrap",
@@ -1382,7 +1384,7 @@ const Workflows = (props) => {
}; };
return ( return (
<Grid item xs={4} style={{ padding: "12px 10px 12px 10px" }}> <Grid item xs={isMobile ? 12 : 4} style={{ padding: "12px 10px 12px 10px" }}>
<Paper <Paper
square square
style={setupPaperStyle} style={setupPaperStyle}
@@ -2402,7 +2404,8 @@ const Workflows = (props) => {
style: { style: {
backgroundColor: surfaceColor, backgroundColor: surfaceColor,
color: "white", color: "white",
minWidth: "800px", minWidth: isMobile ? "90%" : "800px",
maxWidth: isMobile ? "90%" : "800px",
}, },
}} }}
> >
@@ -2905,6 +2908,7 @@ const Workflows = (props) => {
</Typography> </Typography>
</div> </div>
*/} */}
{isMobile ? null :
<div style={{ display: "flex", margin: "0px 0px 20px 0px" }}> <div style={{ display: "flex", margin: "0px 0px 20px 0px" }}>
<div style={{ flex: 1, float: "right" }}> <div style={{ flex: 1, float: "right" }}>
<ChipInput <ChipInput
@@ -2929,6 +2933,7 @@ const Workflows = (props) => {
/> />
</div> </div>
</div> </div>
}
<div style={{ flex: 1, textAlign: "right" }}> <div style={{ flex: 1, textAlign: "right" }}>
{workflowButtons} {workflowButtons}
</div> </div>
@@ -2982,7 +2987,7 @@ const Workflows = (props) => {
*/} */}
<div style={{width: "100%",}}> <div style={{width: "100%",}}>
{usecases !== null && usecases !== undefined && usecases.length > 0 ? {!isMobile && usecases !== null && usecases !== undefined && usecases.length > 0 ?
<div style={{ display: "flex", }}> <div style={{ display: "flex", }}>
{usecases.map((usecase, index) => { {usecases.map((usecase, index) => {
//console.log(usecase) //console.log(usecase)
@@ -3136,7 +3141,7 @@ const Workflows = (props) => {
workflowDelay += 75 workflowDelay += 75
} else { } else {
return ( return (
<Grid key={index} item xs={4} style={{ padding: "12px 10px 12px 10px" }}> <Grid key={index} item xs={isMobile ? 12 : 4} style={{ padding: "12px 10px 12px 10px" }}>
<WorkflowPaper key={index} data={data} /> <WorkflowPaper key={index} data={data} />
</Grid> </Grid>
) )
@@ -3144,7 +3149,7 @@ const Workflows = (props) => {
return ( return (
<Zoom key={index} in={true} style={{ transitionDelay: `${workflowDelay}ms` }}> <Zoom key={index} in={true} style={{ transitionDelay: `${workflowDelay}ms` }}>
<Grid item xs={4} style={{ padding: "12px 10px 12px 10px" }}> <Grid item xs={isMobile ? 12 : 4} style={{ padding: "12px 10px 12px 10px" }}>
<WorkflowPaper key={index} data={data} /> <WorkflowPaper key={index} data={data} />
</Grid> </Grid>
</Zoom> </Zoom>
@@ -3355,7 +3360,7 @@ const Workflows = (props) => {
*/} */}
<Dropzone <Dropzone
style={{ style={{
maxWidth: window.innerWidth > 1366 ? 1366 : 1200, maxWidth: window.innerWidth > 1366 ? 1366 : isMobile ? "100%" : 1200,
margin: "auto", margin: "auto",
padding: 20, padding: 20,
}} }}