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:
e = sys.exc_info()[1]
except:
self.logger.info("Exc check fail: %s" % e)
self.logger.info("Exec check fail: %s" % e)
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
@@ -2156,7 +2159,10 @@ class AppBase:
if func == None:
self.logger.debug(f"[DEBUG] Failed executing {actionname} because func is None (no function specified).")
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):
try:
if len(action["parameters"]) < 1:
+1 -1
View File
@@ -22,7 +22,7 @@ require (
github.com/gorilla/mux v1.8.0
github.com/h2non/filetype v1.1.1
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
go4.org v0.0.0-20201209231011-d4a079459e60 // indirect
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519
+1
View File
@@ -5811,6 +5811,7 @@ func initHandlers() {
// App 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.DeleteWorkflowApp).Methods("DELETE", "OPTIONS")
r.HandleFunc("/api/v1/apps/{appId}/config", shuffle.GetWorkflowAppConfig).Methods("GET", "OPTIONS")
+1 -1
View File
@@ -16,7 +16,7 @@ services:
depends_on:
- backend
backend:
#build: ./backend
build: ./backend
image: ghcr.io/frikky/shuffle-backend:nightly
container_name: shuffle-backend
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 { action } = props;
@@ -517,7 +555,8 @@ const ConfigureWorkflow = (props) => {
color="primary"
variant="outlined"
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);
}}
>
@@ -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 (
<div>
<Typography variant="h6">{workflow.name}</Typography>
+2 -3
View File
@@ -965,7 +965,7 @@ const ParsedAction = (props) => {
}
var helperText = ""
console.log("DATA: ", name, value)
//console.log("DATA: ", name, value)
if (name.includes("url")) {
if (value.includes("localhost") || value.includes("127.0.0.1")) {
helperText = "Can't use localhost. Please change to an external IP or hostname."
@@ -1545,8 +1545,7 @@ const ParsedAction = (props) => {
console.log("AUTOCOMPLETE1: ", values);
var toComplete = selectedActionParameters[count].value
.trim()
var toComplete = selectedActionParameters[count].value.trim()
.endsWith("$")
? values[0].autocomplete
: "$" + values[0].autocomplete;
+81 -17
View File
@@ -12,6 +12,7 @@ import ReactMarkdown from "react-markdown";
import { useAlert } from "react-alert";
import {
Zoom,
Popover,
TextField,
Drawer,
@@ -1614,6 +1615,7 @@ const AngularWorkflow = (props) => {
setSelectedAction({});
setSelectedApp({});
setSelectedTrigger({});
setSelectedComment({})
//setSelectedEdge({})
// setSelectedTriggerIndex(-1)
@@ -1967,6 +1969,8 @@ const AngularWorkflow = (props) => {
if (parentNode !== null && parentNode !== undefined) {
parentNode.remove();
}
return
} else if (
data.buttonType === "set_startnode" &&
data.type !== "TRIGGER"
@@ -1990,6 +1994,9 @@ const AngularWorkflow = (props) => {
setLastSaved(false);
parentNode.data("isStartNode", true);
}
//event.target.unselect();
return
} else if (data.buttonType === "copy") {
console.log("COPY!");
// 1. Find parent
@@ -2088,10 +2095,12 @@ const AngularWorkflow = (props) => {
data: newbranch,
});
}
//event.target.unselect();
return
}
}
event.target.unselect();
return;
} else if (data.isDescriptor) {
console.log("Can't select descriptor");
@@ -2244,10 +2253,32 @@ const AngularWorkflow = (props) => {
setSelectedActionEnvironment(env);
}
} 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
);
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") {
getAvailableWorkflows(trigger_index);
getSettings();
@@ -4782,6 +4813,9 @@ const AngularWorkflow = (props) => {
)
);
var delay = -75
var runDelay = false
const ParsedAppPaper = (props) => {
const app = props.app;
const [hover, setHover] = React.useState(false);
@@ -4977,7 +5011,25 @@ const AngularWorkflow = (props) => {
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>
) : apps.length > 0 ? (
@@ -6420,11 +6472,15 @@ const AngularWorkflow = (props) => {
color="primary"
onClick={() => {
console.log("HOST: ", window.location.host);
console.log("HOST: ", window.location);
const redirectUri = isCloud
? window.location.host === "localhost:3002"
? "http%3A%2F%2Flocalhost:5002%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 =
"253565968129-c0a35knic7q1pdk6i6qk9gdkvr07ci49.apps.googleusercontent.com";
@@ -6510,13 +6566,15 @@ const AngularWorkflow = (props) => {
}}
color="primary"
onClick={() => {
//const redirectUri = isCloud ? "https%3A%2F%2Fshuffler.io%2Fapi%2Fv1%2Ftriggers%2Foutlook%2Fregister" : "http%3A%2F%2Flocalhost:5001%2Fapi%2Fv1%2Ftriggers%2Foutlook%2Fregister"
//const redirectUri = isCloud ? "http%3A%2F%2Flocalhost:5002%2Fapi%2Fv1%2Ftriggers%2Foutlook%2Fregister" : "http%3A%2F%2Flocalhost:5001%2Fapi%2Fv1%2Ftriggers%2Foutlook%2Fregister"
console.log(window.location)
const redirectUri = isCloud
? window.location.host === "localhost:3002"
? "http%3A%2F%2Flocalhost:5002%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 = "bb4bff85-0d0b-4f5d-8a69-3cee8029b11a";
@@ -9806,7 +9864,8 @@ const AngularWorkflow = (props) => {
"action": {
"label": "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,
"status": "SUCCESS"
@@ -9823,10 +9882,6 @@ const AngularWorkflow = (props) => {
<ArrowLeftIcon style={{ color: "white" }} />
</Tooltip>
</IconButton>
{/*
<ShowReactJsonField jsonValue={showResult} validate={validate} collapsed={true} label={"Execution Argument"} autocomplete={"exec"} />
*/}
<ReactJson
src={validate.result}
theme={theme.palette.jsonTheme}
@@ -9992,6 +10047,10 @@ const AngularWorkflow = (props) => {
base = JSON.stringify(base)
}
if (base_node_name === "execution_argument") {
base_node_name = "exec"
}
console.log("COPY: ", copy);
var newitem = JSON.parse(base);
to_be_copied = "$" + base_node_name.toLowerCase().replaceAll(" ", "_");
@@ -10156,6 +10215,7 @@ const AngularWorkflow = (props) => {
)
}
var executionDelay = -75
const executionModal = (
<Drawer
anchor={"right"}
@@ -10209,6 +10269,8 @@ const AngularWorkflow = (props) => {
{workflowExecutions.length > 0 ? (
<div>
{workflowExecutions.map((data, index) => {
executionDelay += 75
const statusColor =
data.status === "FINISHED"
? green
@@ -10244,6 +10306,8 @@ const AngularWorkflow = (props) => {
}
return (
<Zoom key={index} in={true} style={{ transitionDelay: `${executionDelay}ms` }}>
<div>
<Tooltip
key={data.execution_id}
title={data.result}
@@ -10344,6 +10408,8 @@ const AngularWorkflow = (props) => {
</Tooltip>
</Paper>
</Tooltip>
</div>
</Zoom>
);
})}
</div>
@@ -10833,10 +10899,6 @@ const AngularWorkflow = (props) => {
</div>
{validate.valid ? (
<span>
{/*
<ShowReactJsonField jsonValue={showResult} validate={validate} collapsed={true} label={"Results for "+data.action.label} autocomplete={data.action.label} />
*/}
<ReactJson
src={validate.result}
theme={theme.palette.jsonTheme}
@@ -11085,7 +11147,7 @@ const AngularWorkflow = (props) => {
{curapp === null ? null : (
<img
alt={selectedResult.app_name}
src={curapp === undefined ? "" : curapp.large_image}
src={curapp === undefined ? theme.palette.defaultImage : curapp.large_image}
style={{
marginRight: 20,
width: imgsize,
@@ -11246,6 +11308,7 @@ const AngularWorkflow = (props) => {
</Typography>
</div>
) : (
<Zoom in={true} timeout={1000} style={{ transitionDelay: `${150}ms` }}>
<CytoscapeComponent
elements={elements}
minZoom={0.35}
@@ -11268,6 +11331,7 @@ const AngularWorkflow = (props) => {
setCy(incy);
}}
/>
</Zoom>
)}
</div>
{executionModal}
+30 -22
View File
@@ -26,6 +26,7 @@ import {
DialogActions,
DialogContent,
} from "@material-ui/core";
import {
GridOn as GridOnIcon,
List as ListIcon,
@@ -425,7 +426,6 @@ const Workflows = (props) => {
const [workflows, setWorkflows] = React.useState([]);
const [filteredWorkflows, setFilteredWorkflows] = React.useState([]);
const [selectedWorkflow, setSelectedWorkflow] = React.useState({});
const [firstrequest, setFirstrequest] = React.useState(true);
const [workflowDone, setWorkflowDone] = React.useState(false);
const [selectedWorkflowId, setSelectedWorkflowId] = React.useState("");
@@ -854,16 +854,16 @@ const Workflows = (props) => {
// eslint-disable-next-line react-hooks/exhaustive-deps
useEffect(() => {
if (workflows.length <= 0 && firstrequest) {
if (workflows.length <= 0) {
const tmpView = localStorage.getItem("view");
if (tmpView !== undefined && tmpView !== null) {
setView(tmpView);
}
setFirstrequest(false);
//setFirstrequest(false);
getAvailableWorkflows();
}
});
}, [])
const viewStyle = {
color: "#ffffff",
@@ -1459,7 +1459,7 @@ const Workflows = (props) => {
}
return (
<Grid item xs={4} style={{ padding: "12px 10px 12px 10px" }}>
<div style={{width: "100%", position: "relative",}}>
<Paper square style={paperAppStyle}>
<div
style={{
@@ -1646,17 +1646,8 @@ const Workflows = (props) => {
})
: null}
</Grid>
</Grid>
{data.actions !== undefined && data.actions !== null ? (
<Grid
item
style={{
display: "flex",
flexDirection: "column",
justifyContent: "space-between",
}}
>
<Grid>
<div style={{position: "absolute", top: 10, right: 10, }}>
<IconButton
aria-label="more"
aria-controls="long-menu"
@@ -1667,13 +1658,13 @@ const Workflows = (props) => {
<MoreVertIcon />
</IconButton>
{workflowMenuButtons}
</Grid>
</Grid>
</div>
) : null}
</Paper>
</Grid>
);
};
</Paper>
</div>
)
}
// Can create and set workflows
const setNewWorkflow = (
@@ -2140,7 +2131,8 @@ const Workflows = (props) => {
};
return obj;
});
})
workflowData = (
<DataGrid
color="primary"
@@ -2467,6 +2459,8 @@ const Workflows = (props) => {
);
}
var workflowDelay = -150
var appDelay = -75
return (
<div style={viewStyle}>
<div style={workflowViewStyle}>
@@ -2587,7 +2581,10 @@ const Workflows = (props) => {
data.large_image = theme.palette.defaultImage;
}
appDelay += 75
return (
<Zoom key={index} in={true} style={{ transitionDelay: `${appDelay}ms` }}>
<span key={index} style={{ zIndex: 10 }}>
<IconButton
style={{
@@ -2642,15 +2639,26 @@ const Workflows = (props) => {
</Tooltip>
</IconButton>
</span>
</Zoom>
);
})}
</div>
) : null}
{view === "grid" ? (
<Grid container spacing={4} style={paperAppContainer}>
<Zoom in={true} style={{ transitionDelay: `${workflowDelay}ms` }}>
<NewWorkflowPaper />
</Zoom>
{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>
) : (