Fixed bugs and visuals in angularworkflow

This commit is contained in:
frikky
2021-11-24 17:40:59 +01:00
parent 592932ed0d
commit 47b02dec89
8 changed files with 363 additions and 278 deletions
+9 -3
View File
@@ -587,10 +587,13 @@ class AppBase:
try: try:
e = sys.exc_info()[1] e = sys.exc_info()[1]
except: except:
self.logger.info("Exc check fail: %s" % e) self.logger.info("Exec check fail: %s" % e)
pass pass
tmp = "An error occured during execution: %s" % e tmp = json.dumps({
"success": False,
"reason": f"An error occured during execution: {e}",
})
# An attempt at decomposing coroutine results # An attempt at decomposing coroutine results
@@ -2156,7 +2159,10 @@ class AppBase:
if func == None: if func == None:
self.logger.debug(f"[DEBUG] Failed executing {actionname} because func is None (no function specified).") self.logger.debug(f"[DEBUG] Failed executing {actionname} because func is None (no function specified).")
self.action_result["status"] = "FAILURE" self.action_result["status"] = "FAILURE"
self.action_result["result"] = "Function %s doesn't exist." % actionname self.action_result["result"] = json.dumps({
"success": False,
"reason": f"Function {actionname} doesn't exist.",
})
elif callable(func): elif callable(func):
try: try:
if len(action["parameters"]) < 1: if len(action["parameters"]) < 1:
+1 -1
View File
@@ -22,7 +22,7 @@ require (
github.com/gorilla/mux v1.8.0 github.com/gorilla/mux v1.8.0
github.com/h2non/filetype v1.1.1 github.com/h2non/filetype v1.1.1
github.com/satori/go.uuid v1.2.0 github.com/satori/go.uuid v1.2.0
github.com/shuffle/shuffle-shared v0.1.43 github.com/shuffle/shuffle-shared v0.1.44
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e // indirect github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e // indirect
go4.org v0.0.0-20201209231011-d4a079459e60 // indirect go4.org v0.0.0-20201209231011-d4a079459e60 // indirect
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519
+1
View File
@@ -5811,6 +5811,7 @@ func initHandlers() {
// App specific // App specific
// From here down isnt checked for org specific // From here down isnt checked for org specific
r.HandleFunc("/api/v1/apps/{appId}/activate", shuffle.ActivateWorkflowApp).Methods("GET", "OPTIONS")
r.HandleFunc("/api/v1/apps/{appId}", shuffle.UpdateWorkflowAppConfig).Methods("PATCH", "OPTIONS") r.HandleFunc("/api/v1/apps/{appId}", shuffle.UpdateWorkflowAppConfig).Methods("PATCH", "OPTIONS")
r.HandleFunc("/api/v1/apps/{appId}", shuffle.DeleteWorkflowApp).Methods("DELETE", "OPTIONS") r.HandleFunc("/api/v1/apps/{appId}", shuffle.DeleteWorkflowApp).Methods("DELETE", "OPTIONS")
r.HandleFunc("/api/v1/apps/{appId}/config", shuffle.GetWorkflowAppConfig).Methods("GET", "OPTIONS") r.HandleFunc("/api/v1/apps/{appId}/config", shuffle.GetWorkflowAppConfig).Methods("GET", "OPTIONS")
+1 -1
View File
@@ -16,7 +16,7 @@ services:
depends_on: depends_on:
- backend - backend
backend: backend:
#build: ./backend build: ./backend
image: ghcr.io/frikky/shuffle-backend:nightly image: ghcr.io/frikky/shuffle-backend:nightly
container_name: shuffle-backend container_name: shuffle-backend
hostname: ${BACKEND_HOSTNAME} hostname: ${BACKEND_HOSTNAME}
+40 -33
View File
@@ -456,6 +456,44 @@ const ConfigureWorkflow = (props) => {
); );
}; };
const activateApp = (app_id, app_name, app_version) => {
fetch(
`${globalUrl}/api/v1/apps/${app_id}/activate?app_name=${app_name}&app_version=${app_version}`,
{
method: "GET",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
credentials: "include",
}
)
.then((response) => {
if (response.status !== 200) {
//window.location.pathname = "/search"
//alert.error("Failed to find this app. Is it public?")
}
return response.json();
})
.then((responseJson) => {
if (responseJson.success === false) {
if (responseJson.reason !== undefined) {
alert.error("Failed to activate the app: "+responseJson.reason);
} else {
alert.error("Failed to activate the app");
}
} else {
alert.success("App activated for your organization!");
}
})
.catch((error) => {
alert.error(error.toString());
});
};
const AppSection = (props) => { const AppSection = (props) => {
const { action } = props; const { action } = props;
@@ -517,7 +555,8 @@ const ConfigureWorkflow = (props) => {
color="primary" color="primary"
variant="outlined" variant="outlined"
onClick={() => { onClick={() => {
activateApp(action.app_id, action.app_name, action.app_version); console.log("ACTION: ", action)
activateApp(action.action.app_id, action.app_name, action.app_version);
setItemChanged(true); setItemChanged(true);
}} }}
> >
@@ -557,38 +596,6 @@ const ConfigureWorkflow = (props) => {
); );
}; };
const activateApp = (app_id, app_name, app_version) => {
fetch(
`${globalUrl}/api/v1/apps/app_id/activate?app_name=${app_name}&app_version=${app_version}`,
{
method: "GET",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
credentials: "include",
}
)
.then((response) => {
if (response.status !== 200) {
//window.location.pathname = "/search"
//alert.error("Failed to find this app. Is it public?")
}
return response.json();
})
.then((responseJson) => {
if (responseJson.success === false) {
alert.error("Failed to activate the app");
} else {
alert.success("App activated for your organization!");
}
})
.catch((error) => {
alert.error(error.toString());
});
};
return ( return (
<div> <div>
<Typography variant="h6">{workflow.name}</Typography> <Typography variant="h6">{workflow.name}</Typography>
+2 -3
View File
@@ -965,7 +965,7 @@ const ParsedAction = (props) => {
} }
var helperText = "" var helperText = ""
console.log("DATA: ", name, value) //console.log("DATA: ", name, value)
if (name.includes("url")) { if (name.includes("url")) {
if (value.includes("localhost") || value.includes("127.0.0.1")) { if (value.includes("localhost") || value.includes("127.0.0.1")) {
helperText = "Can't use localhost. Please change to an external IP or hostname." helperText = "Can't use localhost. Please change to an external IP or hostname."
@@ -1545,8 +1545,7 @@ const ParsedAction = (props) => {
console.log("AUTOCOMPLETE1: ", values); console.log("AUTOCOMPLETE1: ", values);
var toComplete = selectedActionParameters[count].value var toComplete = selectedActionParameters[count].value.trim()
.trim()
.endsWith("$") .endsWith("$")
? values[0].autocomplete ? values[0].autocomplete
: "$" + values[0].autocomplete; : "$" + values[0].autocomplete;
+267 -203
View File
@@ -12,6 +12,7 @@ import ReactMarkdown from "react-markdown";
import { useAlert } from "react-alert"; import { useAlert } from "react-alert";
import { import {
Zoom,
Popover, Popover,
TextField, TextField,
Drawer, Drawer,
@@ -1614,6 +1615,7 @@ const AngularWorkflow = (props) => {
setSelectedAction({}); setSelectedAction({});
setSelectedApp({}); setSelectedApp({});
setSelectedTrigger({}); setSelectedTrigger({});
setSelectedComment({})
//setSelectedEdge({}) //setSelectedEdge({})
// setSelectedTriggerIndex(-1) // setSelectedTriggerIndex(-1)
@@ -1967,6 +1969,8 @@ const AngularWorkflow = (props) => {
if (parentNode !== null && parentNode !== undefined) { if (parentNode !== null && parentNode !== undefined) {
parentNode.remove(); parentNode.remove();
} }
return
} else if ( } else if (
data.buttonType === "set_startnode" && data.buttonType === "set_startnode" &&
data.type !== "TRIGGER" data.type !== "TRIGGER"
@@ -1990,6 +1994,9 @@ const AngularWorkflow = (props) => {
setLastSaved(false); setLastSaved(false);
parentNode.data("isStartNode", true); parentNode.data("isStartNode", true);
} }
//event.target.unselect();
return
} else if (data.buttonType === "copy") { } else if (data.buttonType === "copy") {
console.log("COPY!"); console.log("COPY!");
// 1. Find parent // 1. Find parent
@@ -2088,10 +2095,12 @@ const AngularWorkflow = (props) => {
data: newbranch, data: newbranch,
}); });
} }
//event.target.unselect();
return
} }
} }
event.target.unselect();
return; return;
} else if (data.isDescriptor) { } else if (data.isDescriptor) {
console.log("Can't select descriptor"); console.log("Can't select descriptor");
@@ -2244,10 +2253,32 @@ const AngularWorkflow = (props) => {
setSelectedActionEnvironment(env); setSelectedActionEnvironment(env);
} }
} else if (data.type === "TRIGGER") { } else if (data.type === "TRIGGER") {
const trigger_index = workflow.triggers.findIndex( if (workflow.triggers === null) {
workflow.triggers = []
}
var trigger_index = workflow.triggers.findIndex(
(a) => a.id === data.id (a) => a.id === data.id
); );
console.log("Trigger: ", data, trigger_index)
if (trigger_index === -1) {
workflow.triggers.push(data)
trigger_index = workflow.triggers.length-1
setWorkflow(workflow)
}
console.log("Trigger2: ", data, trigger_index)
//if (data.id !== undefined && data.app_name !== undefined) {
// //newapps.push(data)
// workflow.actions.push(data)
// curaction = data
//} else {
// alert.error("Action not found. Please remake it.");
// event.target.remove();
// return;
//}
if (data.app_name === "Shuffle Workflow") { if (data.app_name === "Shuffle Workflow") {
getAvailableWorkflows(trigger_index); getAvailableWorkflows(trigger_index);
getSettings(); getSettings();
@@ -4782,6 +4813,9 @@ const AngularWorkflow = (props) => {
) )
); );
var delay = -75
var runDelay = false
const ParsedAppPaper = (props) => { const ParsedAppPaper = (props) => {
const app = props.app; const app = props.app;
const [hover, setHover] = React.useState(false); const [hover, setHover] = React.useState(false);
@@ -4977,7 +5011,25 @@ const AngularWorkflow = (props) => {
return null; return null;
} }
return <ParsedAppPaper key={index} app={app} />; var extraMessage = ""
if (index == 2) {
extraMessage = <div style={{marginTop: 5}} />
}
delay += 75
return (
runDelay ?
<Zoom key={index} in={true} style={{ transitionDelay: `${delay}ms` }}>
<div>
<ParsedAppPaper key={index} app={app} />
</div>
</Zoom>
:
<div>
{extraMessage}
<ParsedAppPaper key={index} app={app} />
</div>
)
})} })}
</div> </div>
) : apps.length > 0 ? ( ) : apps.length > 0 ? (
@@ -6420,11 +6472,15 @@ const AngularWorkflow = (props) => {
color="primary" color="primary"
onClick={() => { onClick={() => {
console.log("HOST: ", window.location.host); console.log("HOST: ", window.location.host);
console.log("HOST: ", window.location);
const redirectUri = isCloud const redirectUri = isCloud
? window.location.host === "localhost:3002" ? window.location.host === "localhost:3002"
? "http%3A%2F%2Flocalhost:5002%2Fapi%2Fv1%2Ftriggers%2Fgmail%2Fregister" ? "http%3A%2F%2Flocalhost:5002%2Fapi%2Fv1%2Ftriggers%2Fgmail%2Fregister"
: "https%3A%2F%2Fshuffler.io%2Fapi%2Fv1%2Ftriggers%2Fgmail%2Fregister" : "https%3A%2F%2Fshuffler.io%2Fapi%2Fv1%2Ftriggers%2Fgmail%2Fregister"
: "http%3A%2F%2Flocalhost:5001%2Fapi%2Fv1%2Ftriggers%2Fgmail%2Fregister"; : window.location.protocol === "http:" ?
`http%3A%2F%2F${window.location.host}%2Fapi%2Fv1%2Ftriggers%2Fgmail%2Fregister`
:
`https%3A%2F%2F${window.location.host}%2Fapi%2Fv1%2Ftriggers%2Fgmail%2Fregister`
const client_id = const client_id =
"253565968129-c0a35knic7q1pdk6i6qk9gdkvr07ci49.apps.googleusercontent.com"; "253565968129-c0a35knic7q1pdk6i6qk9gdkvr07ci49.apps.googleusercontent.com";
@@ -6510,13 +6566,15 @@ const AngularWorkflow = (props) => {
}} }}
color="primary" color="primary"
onClick={() => { onClick={() => {
//const redirectUri = isCloud ? "https%3A%2F%2Fshuffler.io%2Fapi%2Fv1%2Ftriggers%2Foutlook%2Fregister" : "http%3A%2F%2Flocalhost:5001%2Fapi%2Fv1%2Ftriggers%2Foutlook%2Fregister" console.log(window.location)
//const redirectUri = isCloud ? "http%3A%2F%2Flocalhost:5002%2Fapi%2Fv1%2Ftriggers%2Foutlook%2Fregister" : "http%3A%2F%2Flocalhost:5001%2Fapi%2Fv1%2Ftriggers%2Foutlook%2Fregister"
const redirectUri = isCloud const redirectUri = isCloud
? window.location.host === "localhost:3002" ? window.location.host === "localhost:3002"
? "http%3A%2F%2Flocalhost:5002%2Fapi%2Fv1%2Ftriggers%2Foutlook%2Fregister" ? "http%3A%2F%2Flocalhost:5002%2Fapi%2Fv1%2Ftriggers%2Foutlook%2Fregister"
: "https%3A%2F%2Fshuffler.io%2Fapi%2Fv1%2Ftriggers%2Foutlook%2Fregister" : "https%3A%2F%2Fshuffler.io%2Fapi%2Fv1%2Ftriggers%2Foutlook%2Fregister"
: "http%3A%2F%2Flocalhost:5001%2Fapi%2Fv1%2Ftriggers%2Foutlook%2Fregister"; : window.location.protocol === "http:" ?
`http%3A%2F%2F${window.location.host}%2Fapi%2Fv1%2Ftriggers%2Foutlook%2Fregister`
:
`https%3A%2F%2F${window.location.host}%2Fapi%2Fv1%2Ftriggers%2Foutlook%2Fregister`
//const client_id = "fd55c175-aa30-4fa6-b303-09a29fb3f750" //const client_id = "fd55c175-aa30-4fa6-b303-09a29fb3f750"
const client_id = "bb4bff85-0d0b-4f5d-8a69-3cee8029b11a"; const client_id = "bb4bff85-0d0b-4f5d-8a69-3cee8029b11a";
@@ -9806,7 +9864,8 @@ const AngularWorkflow = (props) => {
"action": { "action": {
"label": "Execution Argument", "label": "Execution Argument",
"name": "Execution Argument", "name": "Execution Argument",
"large_image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJYAAACOCAMAAADkWgEmAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAWlBMVEX4Wj69TDgmKCvkVTwlJyskJiokJikkJSkjJSn4Ykf+6+f5h3L////8xLr5alH/9fT7nYz4Wz/919H5cVn/+vr8qpv4XUL94d35e2X//v38t6v4YUbkVDy8SzcVIzHLAAAAAWJLR0QMgbNRYwAAAAlwSFlzAAARsAAAEbAByCf1VAAAAAd0SU1FB+QGGgsvBZ/GkmwAAAFKSURBVHja7dlrTgMxDEXhFgpTiukL2vLc/zbZQH5N7MmReu4KPmlGN4m9WgGzfhgtaOZxM1rQztNoQDvPowHtTKMB7WxHA2TJkiVLlixIZMmSRYgsWbIIkSVLFiGyZMkiRNZirBcma/eKZEW87ZGsOBxPRFbE+R3Jio/LlciKuH0iWfH1/UNkRSR3RRYruSvyWKldkcjK7IpUVl5X5LLSuiKbldQV6aycrihgZXRFCau/K2pY3V1RxersijJWX1cUsnq6opLV0RW1rNldUc2a2RXlrHldsQBrTlfcLwv5EZm/PLIgkHXKPHyQRzXzYoO8BjIvzcgnBvJBxny+Ih/7zNEIcpDEHLshh5TIkS5zAI5cFzCXK8hVFHNxh1xzQpfC0BV6XWTJkkWILFmyCJElSxYhsmTJIkSWLFmEyJIlixBZsmQB8stk/U3/Yb49pVcDMg4AAAAldEVYdGRhdGU6Y3JlYXRlADIwMjAtMDYtMjZUMTE6NDc6MDUrMDI6MDD8QCPmAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDIwLTA2LTI2VDExOjQ3OjA1KzAyOjAwjR2bWgAAAABJRU5ErkJggg==", "large_image": theme.palette.defaultImage,
"image": theme.palette.defaultImage,
}, },
"result": validate.valid ? JSON.stringify(validate.result) : validate.result, "result": validate.valid ? JSON.stringify(validate.result) : validate.result,
"status": "SUCCESS" "status": "SUCCESS"
@@ -9823,10 +9882,6 @@ const AngularWorkflow = (props) => {
<ArrowLeftIcon style={{ color: "white" }} /> <ArrowLeftIcon style={{ color: "white" }} />
</Tooltip> </Tooltip>
</IconButton> </IconButton>
{/*
<ShowReactJsonField jsonValue={showResult} validate={validate} collapsed={true} label={"Execution Argument"} autocomplete={"exec"} />
*/}
<ReactJson <ReactJson
src={validate.result} src={validate.result}
theme={theme.palette.jsonTheme} theme={theme.palette.jsonTheme}
@@ -9992,6 +10047,10 @@ const AngularWorkflow = (props) => {
base = JSON.stringify(base) base = JSON.stringify(base)
} }
if (base_node_name === "execution_argument") {
base_node_name = "exec"
}
console.log("COPY: ", copy); console.log("COPY: ", copy);
var newitem = JSON.parse(base); var newitem = JSON.parse(base);
to_be_copied = "$" + base_node_name.toLowerCase().replaceAll(" ", "_"); to_be_copied = "$" + base_node_name.toLowerCase().replaceAll(" ", "_");
@@ -10156,6 +10215,7 @@ const AngularWorkflow = (props) => {
) )
} }
var executionDelay = -75
const executionModal = ( const executionModal = (
<Drawer <Drawer
anchor={"right"} anchor={"right"}
@@ -10209,6 +10269,8 @@ const AngularWorkflow = (props) => {
{workflowExecutions.length > 0 ? ( {workflowExecutions.length > 0 ? (
<div> <div>
{workflowExecutions.map((data, index) => { {workflowExecutions.map((data, index) => {
executionDelay += 75
const statusColor = const statusColor =
data.status === "FINISHED" data.status === "FINISHED"
? green ? green
@@ -10244,106 +10306,110 @@ const AngularWorkflow = (props) => {
} }
return ( return (
<Tooltip <Zoom key={index} in={true} style={{ transitionDelay: `${executionDelay}ms` }}>
key={data.execution_id} <div>
title={data.result} <Tooltip
placement="left-start" key={data.execution_id}
style={{ zIndex: 10010 }} title={data.result}
> placement="left-start"
<Paper style={{ zIndex: 10010 }}
elevation={5} >
key={data.execution_id} <Paper
square elevation={5}
style={executionPaperStyle} key={data.execution_id}
onMouseOver={() => {}} square
onMouseOut={() => {}} style={executionPaperStyle}
onClick={() => { onMouseOver={() => {}}
if ( onMouseOut={() => {}}
(data.result === undefined || onClick={() => {
data.result === null || if (
data.result.length === 0) && (data.result === undefined ||
data.status !== "FINISHED" && data.result === null ||
data.status !== "ABORTED" data.result.length === 0) &&
) { data.status !== "FINISHED" &&
start(); data.status !== "ABORTED"
setExecutionRunning(true); ) {
setExecutionRequestStarted(false); start();
} setExecutionRunning(true);
setExecutionRequestStarted(false);
}
const cur_execution = { const cur_execution = {
execution_id: data.execution_id, execution_id: data.execution_id,
authorization: data.authorization, authorization: data.authorization,
}; };
setExecutionRequest(cur_execution); setExecutionRequest(cur_execution);
setExecutionModalView(1); setExecutionModalView(1);
setExecutionData(data); setExecutionData(data);
handleUpdateResults(data, cur_execution); handleUpdateResults(data, cur_execution);
}} }}
> >
<div style={{ display: "flex", flex: 1 }}> <div style={{ display: "flex", flex: 1 }}>
<div <div
style={{ style={{
marginLeft: 0, marginLeft: 0,
width: lastExecution === data.execution_id ? 4 : 2, width: lastExecution === data.execution_id ? 4 : 2,
backgroundColor: statusColor, backgroundColor: statusColor,
marginRight: 5, marginRight: 5,
}} }}
/> />
<div <div
style={{ style={{
height: "100%", height: "100%",
width: 40, width: 40,
borderColor: "white", borderColor: "white",
marginRight: 15, marginRight: 15,
}} }}
> >
{getExecutionSourceImage(data)} {getExecutionSourceImage(data)}
</div> </div>
<div <div
style={{ style={{
marginTop: "auto", marginTop: "auto",
marginBottom: "auto", marginBottom: "auto",
marginRight: 15, marginRight: 15,
fontSize: 13, fontSize: 13,
}} }}
> >
{timestamp} {timestamp}
</div> </div>
{data.workflow.actions !== null ? ( {data.workflow.actions !== null ? (
<Tooltip <Tooltip
color="primary" color="primary"
title={resultsLength + " actions ran"} title={resultsLength + " actions ran"}
placement="top" placement="top"
> >
<div <div
style={{ style={{
marginRight: 10, marginRight: 10,
marginTop: "auto", marginTop: "auto",
marginBottom: "auto", marginBottom: "auto",
}} }}
> >
{resultsLength}/{calculatedResult} {resultsLength}/{calculatedResult}
</div> </div>
</Tooltip> </Tooltip>
) : null} ) : null}
</div> </div>
<Tooltip title={"Inspect execution"} placement="top"> <Tooltip title={"Inspect execution"} placement="top">
{lastExecution === data.execution_id ? ( {lastExecution === data.execution_id ? (
<KeyboardArrowRightIcon <KeyboardArrowRightIcon
style={{ style={{
color: "#f85a3e", color: "#f85a3e",
marginTop: "auto", marginTop: "auto",
marginBottom: "auto", marginBottom: "auto",
}} }}
/> />
) : ( ) : (
<KeyboardArrowRightIcon <KeyboardArrowRightIcon
style={{ marginTop: "auto", marginBottom: "auto" }} style={{ marginTop: "auto", marginBottom: "auto" }}
/> />
)} )}
</Tooltip> </Tooltip>
</Paper> </Paper>
</Tooltip> </Tooltip>
</div>
</Zoom>
); );
})} })}
</div> </div>
@@ -10833,10 +10899,6 @@ const AngularWorkflow = (props) => {
</div> </div>
{validate.valid ? ( {validate.valid ? (
<span> <span>
{/*
<ShowReactJsonField jsonValue={showResult} validate={validate} collapsed={true} label={"Results for "+data.action.label} autocomplete={data.action.label} />
*/}
<ReactJson <ReactJson
src={validate.result} src={validate.result}
theme={theme.palette.jsonTheme} theme={theme.palette.jsonTheme}
@@ -11085,7 +11147,7 @@ const AngularWorkflow = (props) => {
{curapp === null ? null : ( {curapp === null ? null : (
<img <img
alt={selectedResult.app_name} alt={selectedResult.app_name}
src={curapp === undefined ? "" : curapp.large_image} src={curapp === undefined ? theme.palette.defaultImage : curapp.large_image}
style={{ style={{
marginRight: 20, marginRight: 20,
width: imgsize, width: imgsize,
@@ -11218,93 +11280,95 @@ const AngularWorkflow = (props) => {
const newView = ( const newView = (
<div style={{ color: "white" }}> <div style={{ color: "white" }}>
<div <div
style={{ display: "flex", borderTop: "1px solid rgba(91, 96, 100, 1)" }} style={{ display: "flex", borderTop: "1px solid rgba(91, 96, 100, 1)" }}
> >
{leftView} {leftView}
{workflow.id === undefined || {workflow.id === undefined ||
workflow.id === null || workflow.id === null ||
apps.length === 0 ? ( apps.length === 0 ? (
<div <div
style={{ style={{
width: bodyWidth - leftBarSize - 15, width: bodyWidth - leftBarSize - 15,
height: 150, height: 150,
textAlign: "center", textAlign: "center",
}} }}
> >
<CircularProgress <CircularProgress
style={{ style={{
marginTop: "30vh", marginTop: "30vh",
height: 35, height: 35,
width: 35, width: 35,
marginLeft: "auto", marginLeft: "auto",
marginRight: "auto", marginRight: "auto",
}} }}
/> />
<Typography variant="body1" color="textSecondary"> <Typography variant="body1" color="textSecondary">
Loading Workflow Loading Workflow
</Typography> </Typography>
</div> </div>
) : ( ) : (
<CytoscapeComponent <Zoom in={true} timeout={1000} style={{ transitionDelay: `${150}ms` }}>
elements={elements} <CytoscapeComponent
minZoom={0.35} elements={elements}
maxZoom={2.0} minZoom={0.35}
wheelSensitivity={0.25} maxZoom={2.0}
style={{ wheelSensitivity={0.25}
width: bodyWidth - leftBarSize - 15, style={{
height: bodyHeight - appBarSize - 5, width: bodyWidth - leftBarSize - 15,
backgroundColor: surfaceColor, height: bodyHeight - appBarSize - 5,
}} backgroundColor: surfaceColor,
stylesheet={cystyle} }}
boxSelectionEnabled={true} stylesheet={cystyle}
autounselectify={false} boxSelectionEnabled={true}
showGrid={true} autounselectify={false}
id="cytoscape_view" showGrid={true}
cy={(incy) => { id="cytoscape_view"
// FIXME: There's something specific loading when cy={(incy) => {
// you do the first hover of a node. Why is this different? // FIXME: There's something specific loading when
//console.log("CY: ", incy) // you do the first hover of a node. Why is this different?
setCy(incy); //console.log("CY: ", incy)
}} setCy(incy);
/> }}
)} />
</div> </Zoom>
{executionModal} )}
<RightSideBar </div>
scrollConfig={scrollConfig} {executionModal}
setScrollConfig={setScrollConfig} <RightSideBar
selectedAction={selectedAction} scrollConfig={scrollConfig}
workflow={workflow} setScrollConfig={setScrollConfig}
setWorkflow={setWorkflow} selectedAction={selectedAction}
setSelectedAction={setSelectedAction} workflow={workflow}
setUpdate={setUpdate} setWorkflow={setWorkflow}
selectedApp={selectedApp} setSelectedAction={setSelectedAction}
workflowExecutions={workflowExecutions} setUpdate={setUpdate}
setSelectedResult={setSelectedResult} selectedApp={selectedApp}
setSelectedApp={setSelectedApp} workflowExecutions={workflowExecutions}
setSelectedTrigger={setSelectedTrigger} setSelectedResult={setSelectedResult}
setSelectedEdge={setSelectedEdge} setSelectedApp={setSelectedApp}
setCurrentView={setCurrentView} setSelectedTrigger={setSelectedTrigger}
cy={cy} setSelectedEdge={setSelectedEdge}
setAuthenticationModalOpen={setAuthenticationModalOpen} setCurrentView={setCurrentView}
setVariablesModalOpen={setVariablesModalOpen} cy={cy}
setLastSaved={setLastSaved} setAuthenticationModalOpen={setAuthenticationModalOpen}
setCodeModalOpen={setCodeModalOpen} setVariablesModalOpen={setVariablesModalOpen}
selectedNameChange={selectedNameChange} setLastSaved={setLastSaved}
rightsidebarStyle={rightsidebarStyle} setCodeModalOpen={setCodeModalOpen}
showEnvironment={showEnvironment} selectedNameChange={selectedNameChange}
selectedActionEnvironment={selectedActionEnvironment} rightsidebarStyle={rightsidebarStyle}
environments={environments} showEnvironment={showEnvironment}
setNewSelectedAction={setNewSelectedAction} selectedActionEnvironment={selectedActionEnvironment}
sortByKey={sortByKey} environments={environments}
appApiViewStyle={appApiViewStyle} setNewSelectedAction={setNewSelectedAction}
globalUrl={globalUrl} sortByKey={sortByKey}
setSelectedActionEnvironment={setSelectedActionEnvironment} appApiViewStyle={appApiViewStyle}
requiresAuthentication={requiresAuthentication} globalUrl={globalUrl}
/> setSelectedActionEnvironment={setSelectedActionEnvironment}
<BottomCytoscapeBar /> requiresAuthentication={requiresAuthentication}
<TopCytoscapeBar /> />
<BottomCytoscapeBar />
<TopCytoscapeBar />
</div> </div>
); );
+42 -34
View File
@@ -26,6 +26,7 @@ import {
DialogActions, DialogActions,
DialogContent, DialogContent,
} from "@material-ui/core"; } from "@material-ui/core";
import { import {
GridOn as GridOnIcon, GridOn as GridOnIcon,
List as ListIcon, List as ListIcon,
@@ -425,7 +426,6 @@ const Workflows = (props) => {
const [workflows, setWorkflows] = React.useState([]); const [workflows, setWorkflows] = React.useState([]);
const [filteredWorkflows, setFilteredWorkflows] = React.useState([]); const [filteredWorkflows, setFilteredWorkflows] = React.useState([]);
const [selectedWorkflow, setSelectedWorkflow] = React.useState({}); const [selectedWorkflow, setSelectedWorkflow] = React.useState({});
const [firstrequest, setFirstrequest] = React.useState(true);
const [workflowDone, setWorkflowDone] = React.useState(false); const [workflowDone, setWorkflowDone] = React.useState(false);
const [selectedWorkflowId, setSelectedWorkflowId] = React.useState(""); const [selectedWorkflowId, setSelectedWorkflowId] = React.useState("");
@@ -854,16 +854,16 @@ const Workflows = (props) => {
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
useEffect(() => { useEffect(() => {
if (workflows.length <= 0 && firstrequest) { if (workflows.length <= 0) {
const tmpView = localStorage.getItem("view"); const tmpView = localStorage.getItem("view");
if (tmpView !== undefined && tmpView !== null) { if (tmpView !== undefined && tmpView !== null) {
setView(tmpView); setView(tmpView);
} }
setFirstrequest(false); //setFirstrequest(false);
getAvailableWorkflows(); getAvailableWorkflows();
} }
}); }, [])
const viewStyle = { const viewStyle = {
color: "#ffffff", color: "#ffffff",
@@ -1459,7 +1459,7 @@ const Workflows = (props) => {
} }
return ( return (
<Grid item xs={4} style={{ padding: "12px 10px 12px 10px" }}> <div style={{width: "100%", position: "relative",}}>
<Paper square style={paperAppStyle}> <Paper square style={paperAppStyle}>
<div <div
style={{ style={{
@@ -1646,34 +1646,25 @@ const Workflows = (props) => {
}) })
: null} : null}
</Grid> </Grid>
</Grid>
{data.actions !== undefined && data.actions !== null ? ( {data.actions !== undefined && data.actions !== null ? (
<Grid <div style={{position: "absolute", top: 10, right: 10, }}>
item <IconButton
style={{ aria-label="more"
display: "flex", aria-controls="long-menu"
flexDirection: "column", aria-haspopup="true"
justifyContent: "space-between", onClick={menuClick}
}} style={{ padding: "0px", color: "#979797" }}
> >
<Grid> <MoreVertIcon />
<IconButton </IconButton>
aria-label="more" {workflowMenuButtons}
aria-controls="long-menu" </div>
aria-haspopup="true"
onClick={menuClick}
style={{ padding: "0px", color: "#979797" }}
>
<MoreVertIcon />
</IconButton>
{workflowMenuButtons}
</Grid>
</Grid>
) : null} ) : null}
</Paper> </Grid>
</Grid> </Paper>
); </div>
}; )
}
// Can create and set workflows // Can create and set workflows
const setNewWorkflow = ( const setNewWorkflow = (
@@ -2140,7 +2131,8 @@ const Workflows = (props) => {
}; };
return obj; return obj;
}); })
workflowData = ( workflowData = (
<DataGrid <DataGrid
color="primary" color="primary"
@@ -2467,6 +2459,8 @@ const Workflows = (props) => {
); );
} }
var workflowDelay = -150
var appDelay = -75
return ( return (
<div style={viewStyle}> <div style={viewStyle}>
<div style={workflowViewStyle}> <div style={workflowViewStyle}>
@@ -2587,7 +2581,10 @@ const Workflows = (props) => {
data.large_image = theme.palette.defaultImage; data.large_image = theme.palette.defaultImage;
} }
appDelay += 75
return ( return (
<Zoom key={index} in={true} style={{ transitionDelay: `${appDelay}ms` }}>
<span key={index} style={{ zIndex: 10 }}> <span key={index} style={{ zIndex: 10 }}>
<IconButton <IconButton
style={{ style={{
@@ -2642,15 +2639,26 @@ const Workflows = (props) => {
</Tooltip> </Tooltip>
</IconButton> </IconButton>
</span> </span>
</Zoom>
); );
})} })}
</div> </div>
) : null} ) : null}
{view === "grid" ? ( {view === "grid" ? (
<Grid container spacing={4} style={paperAppContainer}> <Grid container spacing={4} style={paperAppContainer}>
<NewWorkflowPaper /> <Zoom in={true} style={{ transitionDelay: `${workflowDelay}ms` }}>
<NewWorkflowPaper />
</Zoom>
{filteredWorkflows.map((data, index) => { {filteredWorkflows.map((data, index) => {
return <WorkflowPaper key={index} data={data} />; workflowDelay += 75
return (
<Zoom key={index} in={true} style={{ transitionDelay: `${workflowDelay}ms` }}>
<Grid item xs={4} style={{ padding: "12px 10px 12px 10px" }}>
<WorkflowPaper key={index} data={data} />
</Grid>
</Zoom>
)
})} })}
</Grid> </Grid>
) : ( ) : (