diff --git a/backend/go-app/go.mod b/backend/go-app/go.mod
index 94d499b4..ad9d40b5 100644
--- a/backend/go-app/go.mod
+++ b/backend/go-app/go.mod
@@ -10,7 +10,7 @@ go 1.15
require (
cloud.google.com/go/datastore v1.6.0
cloud.google.com/go/pubsub v1.17.0
- cloud.google.com/go/storage v1.18.1
+ cloud.google.com/go/storage v1.18.2
github.com/basgys/goxml2json v1.1.0
github.com/carlescere/scheduler v0.0.0-20170109141437-ee74d2f83d82
github.com/docker/docker v20.10.9+incompatible
@@ -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.70
+ github.com/shuffle/shuffle-shared v0.1.72
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 72caab2f..61de2288 100644
--- a/backend/go-app/main.go
+++ b/backend/go-app/main.go
@@ -3960,7 +3960,7 @@ func runInitEs(ctx context.Context) {
for _, org := range activeOrgs {
if !org.CloudSync {
- log.Printf("[WARNING] Skipping org syncCheck for %s because sync isn't set (1).", org.Id)
+ log.Printf("[INFO] Skipping org syncCheck for %s because sync isn't set (1).", org.Id)
continue
}
diff --git a/backend/go-app/walkoff.go b/backend/go-app/walkoff.go
index c7af3c50..390187e0 100644
--- a/backend/go-app/walkoff.go
+++ b/backend/go-app/walkoff.go
@@ -419,7 +419,7 @@ func handleWorkflowQueue(resp http.ResponseWriter, request *http.Request) {
resp.Write([]byte(fmt.Sprintf(`{"success": true, "reason": "success"}`)))
return
} else {
- log.Printf("[DEBUG] Handling other execution variant: %s", err)
+ log.Printf("[DEBUG] Handling other execution variant (subflow): %s", err)
}
var actionResult shuffle.ActionResult
@@ -1058,6 +1058,9 @@ func executeWorkflow(resp http.ResponseWriter, request *http.Request) {
}
fileId = location[4]
+ if strings.Contains(fileId, "?") {
+ fileId = strings.Split(fileId, "?")[0]
+ }
}
if len(fileId) != 36 {
@@ -1072,7 +1075,7 @@ func executeWorkflow(resp http.ResponseWriter, request *http.Request) {
if err != nil && workflow.ID == "" {
log.Printf("[WARNING] Failed getting the workflow locally (execute workflow): %s", err)
resp.WriteHeader(401)
- resp.Write([]byte(`{"success": false}`))
+ resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Workflow with ID %s doesn't exist."}`, fileId)))
return
}
diff --git a/docker-compose.yml b/docker-compose.yml
index d48c7797..f1c7ff7c 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/ParsedAction.jsx b/frontend/src/components/ParsedAction.jsx
index 6031622e..c66db8f2 100644
--- a/frontend/src/components/ParsedAction.jsx
+++ b/frontend/src/components/ParsedAction.jsx
@@ -161,6 +161,8 @@ const ParsedAction = (props) => {
authenticationType,
appAuthentication,
getAppAuthentication,
+ actionDelayChange,
+ isCloud,
} = props;
//const theme = useTheme();
@@ -1015,6 +1017,26 @@ const ParsedAction = (props) => {
Parameters
+ {selectedAction.description !== undefined && selectedAction.description !== null && selectedAction.description.length > 0 && hiddenDescription === false ? (
+
+
+ Description
+
+
+ {selectedAction.description}
+
+
+ ) : null}
{selectedActionParameters.map((data, count) => {
if (data.variant === "") {
data.variant = "STATIC_VALUE";
@@ -2282,6 +2304,7 @@ const ParsedAction = (props) => {
+
@@ -2351,39 +2374,76 @@ const ParsedAction = (props) => {
backgroundColor: "rgb(91, 96, 100)",
}}
/>
-
Name
-
{
- const name = e.target.value;
- console.log("CHANGED FROM2: ", baselabel);
- console.log("CHANGED TO: ", name);
- for (var key in workflow.actions) {
- for (var subkey in workflow.actions[key].parameters) {
- const param = workflow.actions[key].parameters[subkey];
- if (param.value.includes(baselabel)) {
- //if (param.value.toLowerCase().includes(baselabel)) {
- console.log("FOUND: ", param);
- workflow.actions[key].parameters[subkey].value.replaceAll(
- baselabel,
- e.target.value
- );
- }
- }
- }
+
+
+ Name
+ {
+ const name = e.target.value;
+ console.log("CHANGED FROM2: ", baselabel);
+ console.log("CHANGED TO: ", name);
+ for (var key in workflow.actions) {
+ for (var subkey in workflow.actions[key].parameters) {
+ const param = workflow.actions[key].parameters[subkey];
+ if (param.value.includes(baselabel)) {
+ //if (param.value.toLowerCase().includes(baselabel)) {
+ console.log("FOUND: ", param);
+ workflow.actions[key].parameters[subkey].value.replaceAll(
+ baselabel,
+ e.target.value
+ );
+ }
+ }
+ }
- console.log("DID REPLACE ACTUALLY WORK?? - Something is buggy.");
- setWorkflow(workflow);
- }}
- />
+ console.log("DID REPLACE ACTUALLY WORK?? - Something is buggy.");
+ setWorkflow(workflow);
+ }}
+ />
+
+ {!isCloud ? null :
+
+
+
+ Delay
+ {
+ if (actionDelayChange !== undefined) {
+ actionDelayChange(event)
+ }
+ }}
+ />
+
+
+
+ }
+
)}
{selectedApp.name !== undefined &&
@@ -2792,27 +2852,6 @@ const ParsedAction = (props) => {
: null*/}
- {selectedAction.description !== undefined && selectedAction.description !== null && selectedAction.description.length > 0 && hiddenDescription === false ? (
-
-
- Description
-
-
- {selectedAction.description}
-
-
- ) : null}
-
{
const [localcodedata, setlocalcodedata] = React.useState(codedata === undefined || codedata === null || codedata.length === 0 ? "" : codedata);
// const {codelang, setcodelang} = props
const theme = useTheme();
- const [validation, setvalidation] = React.useState(" ");
- const [expOutput, setexpOutput] = React.useState(" ");
+ const [validation, setValidation] = React.useState(false);
+ const [expOutput, setExpOutput] = React.useState(" ");
- function IsJsonString(str) {
- try {
- var o = JSON.parse(str);
- if (o && typeof o === "object") {
- setvalidation("Correct!")
- }
- } catch (e) {setvalidation("Incorrect!");}
- }
-
function expectedOutput(input) {
const found = input.match(/[$]{1}([a-zA-Z0-9_-]+\.?){1}([a-zA-Z0-9#_-]+\.?){0,}/g)
@@ -56,21 +49,15 @@ const CodeEditor = (props) => {
}
} catch (e) {}
- try {
- // var x = document.getElementById("expOutput");
- // x.innerHTML = JSON.stringify(JSON.parse(input), null, 4)
- setexpOutput(JSON.stringify(JSON.parse(input), null, 4))
- } catch (e) {
- setexpOutput(input)
+ const tmpValidation = validateJson(input.valueOf())
+ //setValidation(true)
+ if (tmpValidation.valid === true) {
+ setValidation(true)
+ setExpOutput(tmpValidation.result)
+ } else {
+ setExpOutput(input.valueOf())
+ setValidation(false)
}
-
- // const obj = JSON.parse(input);
- // setexpOutput(JSON.stringify(JSON.parse(input), null, 4))
- // x.innerHTML = "
" + JSON.stringify(input, null, 4) + ""
- // x.appendChild(document.createTextNode(JSON.stringify(JSON.parse(input), null, 4)));
- // setexpOutput(JSON.stringify(input, undefined, 4).replace('\ ', '\n'))
- // setexpOutput("Hi there \n Hey there")
- // Variables + Syntax highlighting + Validation
}
return (
@@ -108,14 +95,12 @@ const CodeEditor = (props) => {
}}>
{
setlocalcodedata(value.getValue())
expectedOutput(value.getValue())
- IsJsonString(value.getValue())
- // console.log(actionlist.slice(-1))
}}
options={{
theme: 'gruvbox-dark',
@@ -141,22 +126,47 @@ const CodeEditor = (props) => {
Output
-
- {expOutput}
-
+ {validation === true ?
+ {
+ //handleReactJsonClipboard(copy);
+ }}
+ displayDataTypes={false}
+ onSelect={(select) => {
+ //HandleJsonCopy(validate.result, select, "exec");
+ }}
+ name={"JSON autocompletion"}
+ />
+ :
+
+ {expOutput}
+
+ }
{
marginTop: -15,
}}
>
- JSON Validation: {validation}
+ JSON Validation: {validation ? "Correct" : "Incorrect"}
diff --git a/frontend/src/views/AngularWorkflow.jsx b/frontend/src/views/AngularWorkflow.jsx
index 12e7fa3f..3996d622 100644
--- a/frontend/src/views/AngularWorkflow.jsx
+++ b/frontend/src/views/AngularWorkflow.jsx
@@ -2173,11 +2173,9 @@ const AngularWorkflow = (defaultprops) => {
// FIXME: Trust it to just work?
//event.target.data()
var curaction = workflow.actions.find((a) => a.id === data.id);
- var newapps = JSON.parse(JSON.stringify(apps))
if (!curaction || curaction === undefined) {
console.log("NOT FOUND DATA: ", event.target.data())
if (data.id !== undefined && data.app_name !== undefined) {
- //newapps.push(data)
workflow.actions.push(data)
setWorkflow(workflow)
curaction = data
@@ -2188,6 +2186,7 @@ const AngularWorkflow = (defaultprops) => {
}
}
+ var newapps = JSON.parse(JSON.stringify(apps))
const curapp = newapps.find(
(a) =>
a.name === curaction.app_name &&
@@ -5310,13 +5309,10 @@ const AngularWorkflow = (defaultprops) => {
}
const newParamIndex = newSelectedAction.parameters.findIndex(paramdata => paramdata.name === param.name)
- console.log("INDEX: ", newParamIndex)
if (newParamIndex < 0) {
- console.log("NOT FOUND: ", param)
continue
}
- console.log("FOUND: ", param)
newSelectedAction.parameters[newParamIndex].value = param.value
}
}
@@ -5352,8 +5348,6 @@ const AngularWorkflow = (defaultprops) => {
// based on previous actions'
newSelectedAction = RunAutocompleter(newSelectedAction);
- console.log("ACTION: ", newSelectedAction);
-
if (
newaction.returns.example !== undefined &&
newaction.returns.example !== null &&
@@ -5377,7 +5371,17 @@ const AngularWorkflow = (defaultprops) => {
//}
//setSelectedActionEnvironment(env)
+
+ console.log("ACTION: ", newSelectedAction);
setSelectedAction(newSelectedAction);
+ if (workflow.actions !== undefined && workflow.actions !== null && workflow.actions.length > 0) {
+ const foundActionIndex = workflow.actions.findIndex(actiondata => actiondata.id === newSelectedAction.id)
+ console.log("Found action on index ", foundActionIndex)
+ if (foundActionIndex >= 0) {
+ workflow.actions[foundActionIndex] = newSelectedAction
+ setWorkflow(workflow)
+ }
+ }
setUpdate(Math.random());
// FIXME - should change icon-node (descriptor) as well
@@ -5406,7 +5410,6 @@ const AngularWorkflow = (defaultprops) => {
// appname & version
// description
// ACTION select
- //
const selectedNameChange = (event) => {
event.target.value = event.target.value.replaceAll("(", "");
event.target.value = event.target.value.replaceAll(")", "");
@@ -5429,6 +5432,22 @@ const AngularWorkflow = (defaultprops) => {
setSelectedAction(selectedAction);
};
+ const actionDelayChange = (event) => {
+ if (isNaN(event.target.value)) {
+ console.log("NAN: ", event.target.value)
+ return
+ }
+
+ const parsedNumber = parseInt(event.target.value)
+ if (parsedNumber > 86400) {
+ console.log("Max number is 1 day (86400)")
+ return
+ }
+
+ selectedAction.execution_delay = parsedNumber
+ setSelectedAction(selectedAction)
+ }
+
const selectedTriggerChange = (event) => {
selectedTrigger.label = event.target.value;
setSelectedTrigger(selectedTrigger);
@@ -7595,6 +7614,10 @@ const AngularWorkflow = (defaultprops) => {
const handleSubflowStartnodeSelection = (e) => {
setSubworkflowStartnode(e.target.value);
+ if (e.target.value === null || e.target.value === undefined) {
+ return
+ }
+
const branchId = uuidv4();
const newbranch = {
source_id: workflow.triggers[selectedTriggerIndex].id,
@@ -7736,26 +7759,75 @@ const AngularWorkflow = (defaultprops) => {
backgroundColor: "rgb(91, 96, 100)",
}}
/>
- Name
-
+
+
+ Name
+
+
+
+ {!isCloud ? null :
+
+
+
+ Delay
+ {
+ if (isNaN(event.target.value)) {
+ console.log("NAN: ", event.target.value)
+ return
+ }
+
+ const parsedNumber = parseInt(event.target.value)
+ if (parsedNumber > 86400) {
+ console.log("Max number is 1 day (86400)")
+ return
+ }
+
+ selectedTrigger.execution_delay = parseInt(event.target.value)
+ setSelectedTrigger(selectedTrigger)
+ }}
+ />
+
+
+
+ }
+
+
{
/>
-
Parameters
-
-
- Select a workflow to execute
-
-
+
+
+
+ Select a workflow to execute
+
+
+ {workflow.triggers[selectedTriggerIndex].parameters[0].value
+ .length === 0 ? null : workflow.triggers[selectedTriggerIndex]
+ .parameters[0].value === props.match.params.key ? null : (
+
+ )}
+
{workflows === undefined ||
workflows === null ||
workflows.length === 0 ? null : (
@@ -7832,7 +7925,7 @@ const AngularWorkflow = (defaultprops) => {
option.name === undefined ||
option.name === null
) {
- return "Loading";
+ return "No Workflow Selected";
}
const newname = (
@@ -7883,24 +7976,6 @@ const AngularWorkflow = (defaultprops) => {
}}
/>
)}
- {workflow.triggers[selectedTriggerIndex].parameters[0].value
- .length === 0 ? null : workflow.triggers[selectedTriggerIndex]
- .parameters[0].value === props.match.params.key ? null : (
-
-
- Explore selected workflow
-
-
- )}
{subworkflow === undefined ||
subworkflow === null ||
@@ -8131,7 +8206,7 @@ const AngularWorkflow = (defaultprops) => {
} else {
// Always update
const newUrl = referenceUrl+"webhook_"+selectedTrigger.id
- console.log("Validating webhook url: ", newUrl)
+ //console.log("Validating webhook url: ", newUrl)
if (newUrl !== workflow.triggers[selectedTriggerIndex].parameters[0].value) {
console.log("Url is wrong - updating")
workflow.triggers[selectedTriggerIndex].parameters[0].value = newUrl
@@ -8336,7 +8411,7 @@ const AngularWorkflow = (defaultprops) => {
} else {
// Always update
const newUrl = referenceUrl + "webhook_" + selectedTrigger.id;
- console.log("Validating webhook url: ", newUrl);
+ //console.log("Validating webhook url: ", newUrl);
if (
newUrl !== workflow.triggers[selectedTriggerIndex].parameters[0].value
) {
@@ -10079,6 +10154,8 @@ const AngularWorkflow = (defaultprops) => {
{
);
}}
>
- See sub-execution
+
) : (