diff --git a/backend/app_sdk/app_base.py b/backend/app_sdk/app_base.py
index 132b3fe9..190d983a 100644
--- a/backend/app_sdk/app_base.py
+++ b/backend/app_sdk/app_base.py
@@ -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:
diff --git a/backend/go-app/go.mod b/backend/go-app/go.mod
index 627332b2..c08245ed 100644
--- a/backend/go-app/go.mod
+++ b/backend/go-app/go.mod
@@ -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
diff --git a/backend/go-app/main.go b/backend/go-app/main.go
index 88cfe1a4..444f3ba3 100644
--- a/backend/go-app/main.go
+++ b/backend/go-app/main.go
@@ -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")
diff --git a/docker-compose.yml b/docker-compose.yml
index 8a8ba025..b03ecd3f 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -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}
diff --git a/frontend/src/components/ConfigureWorkflow.jsx b/frontend/src/components/ConfigureWorkflow.jsx
index 460ca8cf..b66ed310 100644
--- a/frontend/src/components/ConfigureWorkflow.jsx
+++ b/frontend/src/components/ConfigureWorkflow.jsx
@@ -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 (
{workflow.name}
diff --git a/frontend/src/components/ParsedAction.jsx b/frontend/src/components/ParsedAction.jsx
index 0ff8120d..b0cc7e74 100644
--- a/frontend/src/components/ParsedAction.jsx
+++ b/frontend/src/components/ParsedAction.jsx
@@ -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;
diff --git a/frontend/src/views/AngularWorkflow.jsx b/frontend/src/views/AngularWorkflow.jsx
index de3c5617..2643c0ec 100644
--- a/frontend/src/views/AngularWorkflow.jsx
+++ b/frontend/src/views/AngularWorkflow.jsx
@@ -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
;
+ var extraMessage = ""
+ if (index == 2) {
+ extraMessage =
+ }
+
+ delay += 75
+ return (
+ runDelay ?
+
+
+
+ :
+
+ )
})}
) : 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) => {
- {/*
-
- */}
-
{
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 = (
{
{workflowExecutions.length > 0 ? (
{workflowExecutions.map((data, index) => {
+ executionDelay += 75
+
const statusColor =
data.status === "FINISHED"
? green
@@ -10244,106 +10306,110 @@ const AngularWorkflow = (props) => {
}
return (
-
- {}}
- onMouseOut={() => {}}
- onClick={() => {
- if (
- (data.result === undefined ||
- data.result === null ||
- data.result.length === 0) &&
- data.status !== "FINISHED" &&
- data.status !== "ABORTED"
- ) {
- start();
- setExecutionRunning(true);
- setExecutionRequestStarted(false);
- }
+
+
+
+ {}}
+ onMouseOut={() => {}}
+ onClick={() => {
+ if (
+ (data.result === undefined ||
+ data.result === null ||
+ data.result.length === 0) &&
+ data.status !== "FINISHED" &&
+ data.status !== "ABORTED"
+ ) {
+ start();
+ setExecutionRunning(true);
+ setExecutionRequestStarted(false);
+ }
- const cur_execution = {
- execution_id: data.execution_id,
- authorization: data.authorization,
- };
- setExecutionRequest(cur_execution);
- setExecutionModalView(1);
- setExecutionData(data);
- handleUpdateResults(data, cur_execution);
- }}
- >
-
-
-
- {getExecutionSourceImage(data)}
-
-
- {timestamp}
-
- {data.workflow.actions !== null ? (
-
-
- {resultsLength}/{calculatedResult}
-
-
- ) : null}
-
-
- {lastExecution === data.execution_id ? (
-
- ) : (
-
- )}
-
-
-
+ const cur_execution = {
+ execution_id: data.execution_id,
+ authorization: data.authorization,
+ };
+ setExecutionRequest(cur_execution);
+ setExecutionModalView(1);
+ setExecutionData(data);
+ handleUpdateResults(data, cur_execution);
+ }}
+ >
+
+
+
+ {getExecutionSourceImage(data)}
+
+
+ {timestamp}
+
+ {data.workflow.actions !== null ? (
+
+
+ {resultsLength}/{calculatedResult}
+
+
+ ) : null}
+
+
+ {lastExecution === data.execution_id ? (
+
+ ) : (
+
+ )}
+
+
+
+
+
);
})}
@@ -10833,10 +10899,6 @@ const AngularWorkflow = (props) => {
{validate.valid ? (
- {/*
-
- */}
-
{
{curapp === null ? null : (
{
const newView = (
-
- {leftView}
- {workflow.id === undefined ||
- workflow.id === null ||
- apps.length === 0 ? (
-
-
-
- Loading Workflow
-
-
- ) : (
-
{
- // FIXME: There's something specific loading when
- // you do the first hover of a node. Why is this different?
- //console.log("CY: ", incy)
- setCy(incy);
- }}
- />
- )}
-
- {executionModal}
-
-
-
+
+ {leftView}
+ {workflow.id === undefined ||
+ workflow.id === null ||
+ apps.length === 0 ? (
+
+
+
+ Loading Workflow
+
+
+ ) : (
+
+ {
+ // FIXME: There's something specific loading when
+ // you do the first hover of a node. Why is this different?
+ //console.log("CY: ", incy)
+ setCy(incy);
+ }}
+ />
+
+ )}
+
+ {executionModal}
+
+
+
);
diff --git a/frontend/src/views/Workflows.jsx b/frontend/src/views/Workflows.jsx
index de86d8c9..1bd9abf1 100644
--- a/frontend/src/views/Workflows.jsx
+++ b/frontend/src/views/Workflows.jsx
@@ -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 (
-
+
{
})
: null}
-
{data.actions !== undefined && data.actions !== null ? (
-
-
-
-
-
- {workflowMenuButtons}
-
-
+
+
+
+
+ {workflowMenuButtons}
+
) : null}
-
-
- );
- };
+
+
+
+ )
+ }
// Can create and set workflows
const setNewWorkflow = (
@@ -2140,7 +2131,8 @@ const Workflows = (props) => {
};
return obj;
- });
+ })
+
workflowData = (
{
);
}
+ var workflowDelay = -150
+ var appDelay = -75
return (
@@ -2587,7 +2581,10 @@ const Workflows = (props) => {
data.large_image = theme.palette.defaultImage;
}
+ appDelay += 75
+
return (
+
{
+
);
})}
) : null}
{view === "grid" ? (
-
+
+
+
{filteredWorkflows.map((data, index) => {
- return ;
+ workflowDelay += 75
+
+ return (
+
+
+
+
+
+ )
})}
) : (