#247: Fixed Worker return and app SDK bug

This commit is contained in:
frikky
2021-02-21 17:00:23 +01:00
parent f4e0446bc9
commit 04e8a22a71
6 changed files with 83 additions and 42 deletions
+8 -5
View File
@@ -541,8 +541,9 @@ class AppBase:
"status": "EXECUTING" "status": "EXECUTING"
} }
# Simple validation of parameters in general
try: try:
print(action["parameters"]) tmp_parameters = action["parameters"]
except KeyError: except KeyError:
action["parameters"] = [] action["parameters"] = []
except TypeError: except TypeError:
@@ -1515,10 +1516,12 @@ class AppBase:
if len(json_replacement) > minlength: if len(json_replacement) > minlength:
minlength = len(json_replacement) minlength = len(json_replacement)
print("PRE new_replacement")
# FIXME: Only do this IF they want to loop # FIXME: Only do this IF they want to loop
new_replacement = [] new_replacement = []
for i in range(len(json_replacement)): for i in range(len(json_replacement)):
if isinstance(json_replacement[i], dict) or isinstance(json_replacement[i], dict): if isinstance(json_replacement[i], dict) or isinstance(json_replacement[i], list):
tmp_replacer = json.dumps(json_replacement[i]) tmp_replacer = json.dumps(json_replacement[i])
newvalue = tmpitem.replace(actualitem[0][0], tmp_replacer, 1) newvalue = tmpitem.replace(actualitem[0][0], tmp_replacer, 1)
else: else:
@@ -1727,7 +1730,7 @@ class AppBase:
#print("[INFO] APP_SDK DONE: Starting NORMAL execution of function") #print("[INFO] APP_SDK DONE: Starting NORMAL execution of function")
print("[INFO] Running normal execution\n") print("[INFO] Running normal execution\n")
newres = await func(**params) newres = await func(**params)
print("\n[INFO] Returned from execution:", newres) print("\n[INFO] Returned from execution with datalength!")#, newres)
if isinstance(newres, tuple): if isinstance(newres, tuple):
print("[INFO] Handling return as tuple") print("[INFO] Handling return as tuple")
# Handles files. # Handles files.
@@ -1753,7 +1756,7 @@ class AppBase:
result = json.dumps(tmp_result) result = json.dumps(tmp_result)
elif isinstance(newres, str): elif isinstance(newres, str):
print("[INFO] Handling return as string") print("[INFO] Handling return as string of length %d" % len(newres))
result += newres result += newres
else: else:
try: try:
@@ -1762,7 +1765,7 @@ class AppBase:
result += "Failed autocasting. Can't handle %s type from function. Must be string" % type(newres) result += "Failed autocasting. Can't handle %s type from function. Must be string" % type(newres)
print("Can't handle type %s value from function" % (type(newres))) print("Can't handle type %s value from function" % (type(newres)))
print("[INFO] POST NEWRES RESULT: ", result) print("[INFO] POST NEWRES RESULT!")#, result)
else: else:
#print("[INFO] APP_SDK DONE: Starting MULTI execution (length: %d) with values %s" % (minlength, multi_parameters)) #print("[INFO] APP_SDK DONE: Starting MULTI execution (length: %d) with values %s" % (minlength, multi_parameters))
# 1. Use number of executions based on the arrays being similar # 1. Use number of executions based on the arrays being similar
+1 -1
View File
@@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
NAME=shuffle-app_sdk NAME=shuffle-app_sdk
VERSION=0.8.56 VERSION=0.8.57
docker rmi docker.pkg.github.com/frikky/shuffle/$NAME:$VERSION --force docker rmi docker.pkg.github.com/frikky/shuffle/$NAME:$VERSION --force
docker build . -t frikky/shuffle:app_sdk -t frikky/$NAME:$VERSION -t docker.pkg.github.com/frikky/shuffle/$NAME:$VERSION -t ghcr.io/frikky/$NAME:$VERSION docker build . -t frikky/shuffle:app_sdk -t frikky/$NAME:$VERSION -t docker.pkg.github.com/frikky/shuffle/$NAME:$VERSION -t ghcr.io/frikky/$NAME:$VERSION
+5
View File
@@ -6163,6 +6163,11 @@ func loadSpecificApps(resp http.ResponseWriter, request *http.Request) {
return return
} }
cacheKey := fmt.Sprintf("workflowapps-sorted-100")
requestCache.Delete(cacheKey)
cacheKey = fmt.Sprintf("workflowapps-sorted-500")
requestCache.Delete(cacheKey)
resp.WriteHeader(200) resp.WriteHeader(200)
resp.Write([]byte(fmt.Sprintf(`{"success": true}`))) resp.Write([]byte(fmt.Sprintf(`{"success": true}`)))
} }
+1
View File
@@ -1122,6 +1122,7 @@ const Admin = (props) => {
<DialogTitle><span style={{ color: "white" }}>Edit authentication for {selectedAuthentication.app.name} ({selectedAuthentication.label})</span></DialogTitle> <DialogTitle><span style={{ color: "white" }}>Edit authentication for {selectedAuthentication.app.name} ({selectedAuthentication.label})</span></DialogTitle>
<DialogContent> <DialogContent>
{selectedAuthentication.fields.map((data, index) => { {selectedAuthentication.fields.map((data, index) => {
console.log("DATA: ", data, selectedAuthentication)
return ( return (
<div key={index}> <div key={index}>
<Typography style={{marginBottom: 0, marginTop: 10}}>{data.key}</Typography> <Typography style={{marginBottom: 0, marginTop: 10}}>{data.key}</Typography>
+39 -17
View File
@@ -1966,7 +1966,7 @@ const AngularWorkflow = (props) => {
return ( return (
<div style={appViewStyle}> <div style={appViewStyle}>
<div style={variableScrollStyle}> <div style={variableScrollStyle}>
What are <a target="_blank" href="https://shuffler.io/docs/workflows#workflow_variables" target="_blank" style={{textDecoration: "none", color: "#f85a3e"}}>WORKFLOW variables?</a> What are <a rel="norefferer" target="_blank" href="https://shuffler.io/docs/workflows#workflow_variables" target="_blank" style={{textDecoration: "none", color: "#f85a3e"}}>WORKFLOW variables?</a>
{workflow.workflow_variables === null ? {workflow.workflow_variables === null ?
null : workflow.workflow_variables.map(variable=> { null : workflow.workflow_variables.map(variable=> {
return ( return (
@@ -2033,7 +2033,7 @@ const AngularWorkflow = (props) => {
}}>New workflow variable</Button> }}>New workflow variable</Button>
</div> </div>
<Divider style={{marginBottom: 20, marginTop: 20, height: 1, width: "100%", backgroundColor: "rgb(91, 96, 100)"}}/> <Divider style={{marginBottom: 20, marginTop: 20, height: 1, width: "100%", backgroundColor: "rgb(91, 96, 100)"}}/>
What are <a target="_blank" href="https://shuffler.io/docs/workflows#execution_variables" target="_blank" style={{textDecoration: "none", color: "#f85a3e"}}>EXECUTION variables?</a> What are <a rel="norefferer" target="_blank" href="https://shuffler.io/docs/workflows#execution_variables" target="_blank" style={{textDecoration: "none", color: "#f85a3e"}}>EXECUTION variables?</a>
{workflow.execution_variables === null || workflow.execution_variables === undefined ? {workflow.execution_variables === null || workflow.execution_variables === undefined ?
null : workflow.execution_variables.map(variable=> { null : workflow.execution_variables.map(variable=> {
return ( return (
@@ -2254,9 +2254,9 @@ const AngularWorkflow = (props) => {
<div style={appScrollStyle}> <div style={appScrollStyle}>
{triggers.map((trigger, index) => { {triggers.map((trigger, index) => {
var imageline = trigger.large_image.length === 0 ? var imageline = trigger.large_image.length === 0 ?
<img alt="" style={{width: "80px"}} /> <img alt="" style={{width: "80px", pointerEvents: "none", }} />
: :
<img alt="" src={trigger.large_image} style={{width: 80, height: 80}} /> <img alt="" src={trigger.large_image} style={{width: 80, height: 80, pointerEvents: "none", }} />
const color = trigger.is_valid ? "green" : "orange" const color = trigger.is_valid ? "green" : "orange"
return( return(
@@ -3935,7 +3935,7 @@ const AngularWorkflow = (props) => {
</Tooltip> </Tooltip>
</IconButton> </IconButton>
<span style={{}}> <span style={{}}>
<Typography style={{marginTop: 5, marginLeft: 10,}}><a href="https://shuffler.io/docs/workflows#nodes" target="_blank" style={{textDecoration: "none", color: "#f85a3e"}}>What are actions?</a></Typography> <Typography style={{marginTop: 5, marginLeft: 10,}}><a rel="norefferer" href="https://shuffler.io/docs/workflows#nodes" target="_blank" style={{textDecoration: "none", color: "#f85a3e"}}>What are actions?</a></Typography>
{selectedAction.errors !== null && selectedAction.errors.length > 0 ? {selectedAction.errors !== null && selectedAction.errors.length > 0 ?
<div> <div>
Errors: {selectedAction.errors.join("\n")} Errors: {selectedAction.errors.join("\n")}
@@ -3969,11 +3969,13 @@ const AngularWorkflow = (props) => {
<div style={{marginTop: 15}}> <div style={{marginTop: 15}}>
Authenticate {selectedApp.name}: Authenticate {selectedApp.name}:
<Tooltip color="primary" title={"Add authentication option"} placement="top"> <Tooltip color="primary" title={"Add authentication option"} placement="top">
<span>
<Button color="primary" style={{}} variant="text" onClick={() => { <Button color="primary" style={{}} variant="text" onClick={() => {
setAuthenticationModalOpen(true) setAuthenticationModalOpen(true)
}}> }}>
<AddIcon /> <AddIcon />
</Button> </Button>
</span>
</Tooltip> </Tooltip>
</div> </div>
: null} : null}
@@ -4559,7 +4561,7 @@ const AngularWorkflow = (props) => {
}} }}
> >
<span style={{position: "absolute", bottom: 10, left: 10, color: "rgba(255,255,255,0.6)",}}> <span style={{position: "absolute", bottom: 10, left: 10, color: "rgba(255,255,255,0.6)",}}>
Conditions can't be used for loops [ .# ] <a target="_blank" href="https://shuffler.io/docs/workflows#conditions" style={{textDecoration: "none", color: "#f85a3e"}}>Learn more</a> Conditions can't be used for loops [ .# ] <a rel="norefferer" target="_blank" href="https://shuffler.io/docs/workflows#conditions" style={{textDecoration: "none", color: "#f85a3e"}}>Learn more</a>
</span> </span>
<FormControl> <FormControl>
<DialogTitle><span style={{color:"white"}}>Condition</span> <DialogTitle><span style={{color:"white"}}>Condition</span>
@@ -4568,6 +4570,7 @@ const AngularWorkflow = (props) => {
<div style={{display: "flex"}}> <div style={{display: "flex"}}>
<Tooltip color="primary" title={conditionValue.configuration ? "Negated" : "Default"} placement="top"> <Tooltip color="primary" title={conditionValue.configuration ? "Negated" : "Default"} placement="top">
<span>
<Button color="primary" variant={conditionValue.configuration ? "contained" : "outlined"} style={{margin: "auto", height: 50, marginBottom: "auto", marginTop: "auto", marginRight: 5}} onClick={(e) => { <Button color="primary" variant={conditionValue.configuration ? "contained" : "outlined"} style={{margin: "auto", height: 50, marginBottom: "auto", marginTop: "auto", marginRight: 5}} onClick={(e) => {
conditionValue.configuration = !conditionValue.configuration conditionValue.configuration = !conditionValue.configuration
setConditionValue(conditionValue) setConditionValue(conditionValue)
@@ -4575,6 +4578,7 @@ const AngularWorkflow = (props) => {
}}> }}>
{conditionValue.configuration ? "!" : "="} {conditionValue.configuration ? "!" : "="}
</Button> </Button>
</span>
</Tooltip> </Tooltip>
<div style={{flex: "2"}}> <div style={{flex: "2"}}>
<AppConditionHandler tmpdata={sourceValue} setData={setSourceValue} type={"source"} /> <AppConditionHandler tmpdata={sourceValue} setData={setSourceValue} type={"source"} />
@@ -4811,7 +4815,7 @@ const AngularWorkflow = (props) => {
<div style={{display: "flex", height: "40px", marginBottom: "30px"}}> <div style={{display: "flex", height: "40px", marginBottom: "30px"}}>
<div style={{flex: "1"}}> <div style={{flex: "1"}}>
<h3 style={{marginBottom: "5px"}} >Branch: Conditions - {selectedEdgeIndex}</h3> <h3 style={{marginBottom: "5px"}} >Branch: Conditions - {selectedEdgeIndex}</h3>
<a target="_blank" href="https://shuffler.io/docs/workflows#conditions" style={{textDecoration: "none", color: "#f85a3e"}}>What are conditions?</a> <a rel="norefferer" target="_blank" href="https://shuffler.io/docs/workflows#conditions" style={{textDecoration: "none", color: "#f85a3e"}}>What are conditions?</a>
</div> </div>
</div> </div>
<Divider style={{marginBottom: "10px", marginTop: "10px", height: "1px", width: "100%", backgroundColor: "rgb(91, 96, 100)"}}/> <Divider style={{marginBottom: "10px", marginTop: "10px", height: "1px", width: "100%", backgroundColor: "rgb(91, 96, 100)"}}/>
@@ -5035,7 +5039,7 @@ const AngularWorkflow = (props) => {
<div style={{display: "flex", height: "40px", marginBottom: "30px"}}> <div style={{display: "flex", height: "40px", marginBottom: "30px"}}>
<div style={{flex: "1"}}> <div style={{flex: "1"}}>
<h3 style={{marginBottom: "5px"}}>{selectedTrigger.app_name}: {selectedTrigger.status}</h3> <h3 style={{marginBottom: "5px"}}>{selectedTrigger.app_name}: {selectedTrigger.status}</h3>
<a target="_blank" href="https://shuffler.io/docs/triggers#email" style={{textDecoration: "none", color: "#f85a3e"}}>What are email triggers?</a> <a rel="norefferer" target="_blank" href="https://shuffler.io/docs/triggers#email" style={{textDecoration: "none", color: "#f85a3e"}}>What are email triggers?</a>
</div> </div>
</div> </div>
<Divider style={{marginBottom: "10px", marginTop: "10px", height: "1px", width: "100%", backgroundColor: "rgb(91, 96, 100)"}}/> <Divider style={{marginBottom: "10px", marginTop: "10px", height: "1px", width: "100%", backgroundColor: "rgb(91, 96, 100)"}}/>
@@ -5126,7 +5130,7 @@ const AngularWorkflow = (props) => {
<div style={{display: "flex", height: "40px", marginBottom: "30px"}}> <div style={{display: "flex", height: "40px", marginBottom: "30px"}}>
<div style={{flex: "1"}}> <div style={{flex: "1"}}>
<h3 style={{marginBottom: "5px"}}>{selectedTrigger.app_name}</h3> <h3 style={{marginBottom: "5px"}}>{selectedTrigger.app_name}</h3>
<a target="_blank" href="https://shuffler.io/docs/triggers#subflow" style={{textDecoration: "none", color: "#f85a3e"}}>What are subflows?</a> <a rel="norefferer" target="_blank" href="https://shuffler.io/docs/triggers#subflow" style={{textDecoration: "none", color: "#f85a3e"}}>What are subflows?</a>
</div> </div>
</div> </div>
<Divider style={{marginBottom: "10px", marginTop: "10px", height: "1px", width: "100%", backgroundColor: "rgb(91, 96, 100)"}}/> <Divider style={{marginBottom: "10px", marginTop: "10px", height: "1px", width: "100%", backgroundColor: "rgb(91, 96, 100)"}}/>
@@ -5202,7 +5206,7 @@ const AngularWorkflow = (props) => {
})} })}
</Select> </Select>
} }
{workflow.triggers[selectedTriggerIndex].parameters[0].value.length === 0 ? null : <span style={{marginTop: 5}}><a href={`/workflows/${workflow.triggers[selectedTriggerIndex].parameters[0].value}`} target="_blank" style={{textDecoration: "none", color: "#f85a3e", marginLeft: 5,}}>Explore selected workflow</a></span>} {workflow.triggers[selectedTriggerIndex].parameters[0].value.length === 0 ? null : <span style={{marginTop: 5}}><a rel="norefferer" href={`/workflows/${workflow.triggers[selectedTriggerIndex].parameters[0].value}`} target="_blank" style={{textDecoration: "none", color: "#f85a3e", marginLeft: 5,}}>Explore selected workflow</a></span>}
<div style={{marginTop: "20px", marginBottom: "7px", display: "flex"}}> <div style={{marginTop: "20px", marginBottom: "7px", display: "flex"}}>
<div style={{width: "17px", height: "17px", borderRadius: 17 / 2, backgroundColor: "#f85a3e", marginRight: "10px"}}/> <div style={{width: "17px", height: "17px", borderRadius: 17 / 2, backgroundColor: "#f85a3e", marginRight: "10px"}}/>
@@ -5329,7 +5333,7 @@ const AngularWorkflow = (props) => {
<div style={{display: "flex", height: "40px", marginBottom: "30px"}}> <div style={{display: "flex", height: "40px", marginBottom: "30px"}}>
<div style={{flex: "1"}}> <div style={{flex: "1"}}>
<h3 style={{marginBottom: "5px"}}>{selectedTrigger.app_name}: {selectedTrigger.status}</h3> <h3 style={{marginBottom: "5px"}}>{selectedTrigger.app_name}: {selectedTrigger.status}</h3>
<a target="_blank" href="https://shuffler.io/docs/triggers#webhook" style={{textDecoration: "none", color: "#f85a3e"}}>What are webhooks?</a> <a rel="norefferer" target="_blank" href="https://shuffler.io/docs/triggers#webhook" style={{textDecoration: "none", color: "#f85a3e"}}>What are webhooks?</a>
</div> </div>
</div> </div>
<Divider style={{marginBottom: "10px", marginTop: "10px", height: "1px", width: "100%", backgroundColor: "rgb(91, 96, 100)"}}/> <Divider style={{marginBottom: "10px", marginTop: "10px", height: "1px", width: "100%", backgroundColor: "rgb(91, 96, 100)"}}/>
@@ -5704,7 +5708,7 @@ const AngularWorkflow = (props) => {
<div style={{display: "flex", height: "40px", marginBottom: "30px"}}> <div style={{display: "flex", height: "40px", marginBottom: "30px"}}>
<div style={{flex: "1"}}> <div style={{flex: "1"}}>
<h3 style={{marginBottom: "5px"}}>{selectedTrigger.app_name}: {selectedTrigger.status}</h3> <h3 style={{marginBottom: "5px"}}>{selectedTrigger.app_name}: {selectedTrigger.status}</h3>
<a target="_blank" href="https://shuffler.io/docs/triggers#user_input" style={{textDecoration: "none", color: "#f85a3e"}}>What is the user input trigger?</a> <a rel="norefferer" target="_blank" href="https://shuffler.io/docs/triggers#user_input" style={{textDecoration: "none", color: "#f85a3e"}}>What is the user input trigger?</a>
</div> </div>
</div> </div>
<Divider style={{marginBottom: "10px", marginTop: "10px", height: "1px", width: "100%", backgroundColor: "rgb(91, 96, 100)"}}/> <Divider style={{marginBottom: "10px", marginTop: "10px", height: "1px", width: "100%", backgroundColor: "rgb(91, 96, 100)"}}/>
@@ -5882,7 +5886,7 @@ const AngularWorkflow = (props) => {
<div style={{display: "flex", height: "40px", marginBottom: "30px"}}> <div style={{display: "flex", height: "40px", marginBottom: "30px"}}>
<div style={{flex: "1"}}> <div style={{flex: "1"}}>
<h3 style={{marginBottom: "5px"}}>{selectedTrigger.app_name}: {selectedTrigger.status}</h3> <h3 style={{marginBottom: "5px"}}>{selectedTrigger.app_name}: {selectedTrigger.status}</h3>
<a target="_blank" href="https://shuffler.io/docs/triggers#schedule" style={{textDecoration: "none", color: "#f85a3e"}}>What are schedules?</a> <a rel="norefferer" target="_blank" href="https://shuffler.io/docs/triggers#schedule" style={{textDecoration: "none", color: "#f85a3e"}}>What are schedules?</a>
</div> </div>
</div> </div>
<Divider style={{marginBottom: "10px", marginTop: "10px", height: "1px", width: "100%", backgroundColor: "rgb(91, 96, 100)"}}/> <Divider style={{marginBottom: "10px", marginTop: "10px", height: "1px", width: "100%", backgroundColor: "rgb(91, 96, 100)"}}/>
@@ -6139,12 +6143,14 @@ const AngularWorkflow = (props) => {
</div> </div>
</Menu> </Menu>
<Tooltip color="secondary" title="Workflow settings" placement="top-start"> <Tooltip color="secondary" title="Workflow settings" placement="top-start">
<span>
<Button color="primary" style={{height: 50, marginLeft: 10, }} variant="outlined" onClick={(event) => { <Button color="primary" style={{height: 50, marginLeft: 10, }} variant="outlined" onClick={(event) => {
setShowShuffleMenu(!showShuffleMenu) setShowShuffleMenu(!showShuffleMenu)
setNewAnchor(event.currentTarget) setNewAnchor(event.currentTarget)
}}> }}>
<SettingsIcon /> <SettingsIcon />
</Button> </Button>
</span>
</Tooltip> </Tooltip>
</div> </div>
) )
@@ -6195,12 +6201,14 @@ const AngularWorkflow = (props) => {
</div> </div>
</Menu> </Menu>
<Tooltip color="secondary" title="Workflow settings" placement="top-start"> <Tooltip color="secondary" title="Workflow settings" placement="top-start">
<span>
<Button color="primary" style={{height: 50, marginLeft: 10, }} variant="outlined" onClick={(event) => { <Button color="primary" style={{height: 50, marginLeft: 10, }} variant="outlined" onClick={(event) => {
setShowShuffleMenu(!showShuffleMenu) setShowShuffleMenu(!showShuffleMenu)
setNewAnchor(event.currentTarget) setNewAnchor(event.currentTarget)
}}> }}>
<SettingsIcon /> <SettingsIcon />
</Button> </Button>
</span>
</Tooltip> </Tooltip>
</div> </div>
) )
@@ -6212,19 +6220,23 @@ const AngularWorkflow = (props) => {
const boxSize = 100 const boxSize = 100
const executionButton = executionRunning ? const executionButton = executionRunning ?
<Tooltip color="primary" title="Stop execution" placement="top"> <Tooltip color="primary" title="Stop execution" placement="top">
<span>
<Button style={{height: boxSize, width: boxSize}} color="secondary" variant="contained" onClick={() => { <Button style={{height: boxSize, width: boxSize}} color="secondary" variant="contained" onClick={() => {
abortExecution() abortExecution()
}}> }}>
<PauseIcon style={{ fontSize: 60}} /> <PauseIcon style={{ fontSize: 60}} />
</Button> </Button>
</span>
</Tooltip> </Tooltip>
: :
<Tooltip color="primary" title="Test execution" placement="top"> <Tooltip color="primary" title="Test execution" placement="top">
<span>
<Button disabled={executionRequestStarted || !workflow.isValid} style={{height: boxSize, width: boxSize}} color="primary" variant="contained" onClick={() => { <Button disabled={executionRequestStarted || !workflow.isValid} style={{height: boxSize, width: boxSize}} color="primary" variant="contained" onClick={() => {
executeWorkflow(executionText, workflow.start) executeWorkflow(executionText, workflow.start)
}}> }}>
<PlayArrowIcon style={{ fontSize: 60}} /> <PlayArrowIcon style={{ fontSize: 60}} />
</Button> </Button>
</span>
</Tooltip> </Tooltip>
return( return(
@@ -6247,29 +6259,37 @@ const AngularWorkflow = (props) => {
/> />
</Tooltip> </Tooltip>
<Tooltip color="primary" title="Save (ctrl+s)" placement="top"> <Tooltip color="primary" title="Save (ctrl+s)" placement="top">
<span>
<Button disabled={savingState !== 0} color="primary" style={{height: 50, width: 64, marginLeft: 10, }} variant={lastSaved ? "outlined" : "contained"} onClick={() => saveWorkflow()}> <Button disabled={savingState !== 0} color="primary" style={{height: 50, width: 64, marginLeft: 10, }} variant={lastSaved ? "outlined" : "contained"} onClick={() => saveWorkflow()}>
{savingState === 2 ? <CircularProgress style={{height: 35, width: 35}} /> : savingState === 1 ? <DoneIcon style={{color: "green"}} /> : <SaveIcon /> } {savingState === 2 ? <CircularProgress style={{height: 35, width: 35}} /> : savingState === 1 ? <DoneIcon style={{color: "green"}} /> : <SaveIcon /> }
</Button> </Button>
</span>
</Tooltip> </Tooltip>
<Tooltip color="secondary" title="Fit to screen (ctrl+f)" placement="top"> <Tooltip color="secondary" title="Fit to screen (ctrl+f)" placement="top">
<span>
<Button color="primary" style={{height: 50, marginLeft: 10, }} variant="outlined" onClick={() => cy.fit(null, 50)}> <Button color="primary" style={{height: 50, marginLeft: 10, }} variant="outlined" onClick={() => cy.fit(null, 50)}>
<AspectRatioIcon /> <AspectRatioIcon />
</Button> </Button>
</span>
</Tooltip> </Tooltip>
<Tooltip color="secondary" title="Remove selected item (del)" placement="top-start"> <Tooltip color="secondary" title="Remove selected item (del)" placement="top-start">
<span>
<Button color="primary" style={{height: 50, marginLeft: 10, }} variant="outlined" onClick={() => { <Button color="primary" style={{height: 50, marginLeft: 10, }} variant="outlined" onClick={() => {
removeNode() removeNode()
}}> }}>
<DeleteIcon /> <DeleteIcon />
</Button> </Button>
</span>
</Tooltip> </Tooltip>
<Tooltip color="secondary" title="Show executions" placement="top-start"> <Tooltip color="secondary" title="Show executions" placement="top-start">
<span>
<Button color="primary" style={{height: 50, marginLeft: 10, }} variant="outlined" onClick={() => { <Button color="primary" style={{height: 50, marginLeft: 10, }} variant="outlined" onClick={() => {
setExecutionModalOpen(true) setExecutionModalOpen(true)
getWorkflowExecution(props.match.params.key) getWorkflowExecution(props.match.params.key)
}}> }}>
<DirectionsRunIcon /> <DirectionsRunIcon />
</Button> </Button>
</span>
</Tooltip> </Tooltip>
{/* <FileMenu /> */} {/* <FileMenu /> */}
<WorkflowMenu /> <WorkflowMenu />
@@ -6608,6 +6628,7 @@ const AngularWorkflow = (props) => {
<div style={{display: "flex"}}> <div style={{display: "flex"}}>
<h2>Executing Workflow</h2> <h2>Executing Workflow</h2>
<Tooltip color="primary" title="Rerun workflow" placement="top"> <Tooltip color="primary" title="Rerun workflow" placement="top">
<span>
<Button color="primary" style={{float: "right"}} onClick={() => { <Button color="primary" style={{float: "right"}} onClick={() => {
console.log("DATA: ", executionData) console.log("DATA: ", executionData)
executeWorkflow(executionData.execution_argument, executionData.start) executeWorkflow(executionData.execution_argument, executionData.start)
@@ -6616,6 +6637,7 @@ const AngularWorkflow = (props) => {
}}> }}>
<CachedIcon style={{}}/> <CachedIcon style={{}}/>
</Button> </Button>
</span>
</Tooltip> </Tooltip>
</div> </div>
{executionData.status !== undefined && executionData.status.length > 0 ? {executionData.status !== undefined && executionData.status.length > 0 ?
@@ -6627,7 +6649,7 @@ const AngularWorkflow = (props) => {
{executionData.execution_source !== undefined && executionData.execution_source !== null && executionData.execution_source.length > 0 && executionData.execution_source !== "default" ? {executionData.execution_source !== undefined && executionData.execution_source !== null && executionData.execution_source.length > 0 && executionData.execution_source !== "default" ?
<div> <div>
<b>Source: &nbsp;&nbsp;</b>{executionData.execution_parent !== null && executionData.execution_parent !== undefined && executionData.execution_parent.length > 0 ? <b>Source: &nbsp;&nbsp;</b>{executionData.execution_parent !== null && executionData.execution_parent !== undefined && executionData.execution_parent.length > 0 ?
<a href={`/workflows/${executionData.execution_source}?view=executions&execution_id=${executionData.execution_parent}`} target="_blank" style={{textDecoration: "none", color: "#f85a3e"}}>Parent Workflow</a> <a rel="norefferer" href={`/workflows/${executionData.execution_source}?view=executions&execution_id=${executionData.execution_parent}`} target="_blank" style={{textDecoration: "none", color: "#f85a3e"}}>Parent Workflow</a>
: :
executionData.execution_source executionData.execution_source
} }
@@ -6744,7 +6766,7 @@ const AngularWorkflow = (props) => {
{data.action.app_name === "shuffle-subflow" ? {data.action.app_name === "shuffle-subflow" ?
<span> <span>
{validate.valid && data.action.parameters !== undefined && data.action.parameters !== null ? {validate.valid && data.action.parameters !== undefined && data.action.parameters !== null ?
<a href={`/workflows/${data.action.parameters[0].value}?view=executions&execution_id=${validate.result.execution_id}`} target="_blank" style={{textDecoration: "none", color: "#f85a3e"}}>See subflow execution</a> <a rel="norefferer" href={`/workflows/${data.action.parameters[0].value}?view=executions&execution_id=${validate.result.execution_id}`} target="_blank" style={{textDecoration: "none", color: "#f85a3e"}}>See subflow execution</a>
: :
"TBD: Load subexecution result for" "TBD: Load subexecution result for"
} }
@@ -6989,7 +7011,7 @@ const AngularWorkflow = (props) => {
<FormControl> <FormControl>
<DialogTitle><span style={{color: "white"}}>Execution Variable</span></DialogTitle> <DialogTitle><span style={{color: "white"}}>Execution Variable</span></DialogTitle>
<DialogContent> <DialogContent>
Execution Variables are TEMPORARY variables that you can ony be set and used during execution. Learn more <a href="https://shuffler.io/docs/workflow#execution_variables" target="_blank" style={{textDecoration: "none", color: "#f85a3e"}}>here</a> Execution Variables are TEMPORARY variables that you can ony be set and used during execution. Learn more <a rel="norefferer" href="https://shuffler.io/docs/workflow#execution_variables" target="_blank" style={{textDecoration: "none", color: "#f85a3e"}}>here</a>
<TextField <TextField
onBlur={(event) => setNewVariableName(event.target.value)} onBlur={(event) => setNewVariableName(event.target.value)}
color="primary" color="primary"
@@ -7264,7 +7286,7 @@ const AngularWorkflow = (props) => {
return ( return (
<div> <div>
<DialogContent> <DialogContent>
<a target="_blank" href="https://shuffler.io/docs/apps#authentication" style={{textDecoration: "none", color: "#f85a3e"}}>What is this?</a><div/> <a target="_blank" rel="norefferer" href="https://shuffler.io/docs/apps#authentication" style={{textDecoration: "none", color: "#f85a3e"}}>What is this?</a><div/>
These are required fields for authenticating with {selectedApp.name} These are required fields for authenticating with {selectedApp.name}
<div style={{marginTop: 15}}/> <div style={{marginTop: 15}}/>
<b>Name - what is this used for?</b> <b>Name - what is this used for?</b>
+15 -5
View File
@@ -1235,7 +1235,7 @@ func handleExecutionResult(workflowExecution WorkflowExecution) {
// IF NOT VISITED && IN toExecuteOnPrem // IF NOT VISITED && IN toExecuteOnPrem
// SKIP if it's not onprem // SKIP if it's not onprem
toRemove := []int{} toRemove := []int{}
log.Printf("\n\nNEXTACTIONS: %#v\n\n", nextActions) //log.Printf("\n\nNEXTACTIONS: %#v\n\n", nextActions)
for index, nextAction := range nextActions { for index, nextAction := range nextActions {
action := getAction(workflowExecution, nextAction, environment) action := getAction(workflowExecution, nextAction, environment)
// check visited and onprem // check visited and onprem
@@ -1698,9 +1698,11 @@ func executionInit(workflowExecution WorkflowExecution) error {
} }
} }
/*
log.Printf("\n\n\n[INFO] CHILDREN FOUND: %#v", children) log.Printf("\n\n\n[INFO] CHILDREN FOUND: %#v", children)
log.Printf("[INFO] PARENTS FOUND: %#v", parents) log.Printf("[INFO] PARENTS FOUND: %#v", parents)
log.Printf("[INFO] NEXT ACTIONS: %#v\n\n", nextActions) log.Printf("[INFO] NEXT ACTIONS: %#v\n\n", nextActions)
*/
log.Printf("[INFO] Actions: %d + Special Triggers: %d", len(workflowExecution.Workflow.Actions), extra) log.Printf("[INFO] Actions: %d + Special Triggers: %d", len(workflowExecution.Workflow.Actions), extra)
onpremApps := []string{} onpremApps := []string{}
@@ -2064,7 +2066,10 @@ func handleWorkflowQueue(resp http.ResponseWriter, request *http.Request) {
// return // return
//} //}
resp.WriteHeader(200)
resp.Write([]byte(fmt.Sprintf(`{"success": true}`)))
runWorkflowExecutionTransaction(ctx, 0, workflowExecution.ExecutionId, actionResult, resp) runWorkflowExecutionTransaction(ctx, 0, workflowExecution.ExecutionId, actionResult, resp)
} }
func findChildNodes(workflowExecution WorkflowExecution, nodeId string) []string { func findChildNodes(workflowExecution WorkflowExecution, nodeId string) []string {
@@ -2473,15 +2478,20 @@ func runWorkflowExecutionTransaction(ctx context.Context, attempts int64, workfl
return return
} }
} else { } else {
log.Printf("Skipping setexec with status %s", workflowExecution.Status) log.Printf("[INFO] Skipping setexec with status %s", workflowExecution.Status)
// Just in case. Should MAYBE validate finishing another time as well.
// This fixes issues with e.g. Action -> Trigger -> Action.
handleExecutionResult(*workflowExecution)
//validateFinished(workflowExecution)
} }
//if newExecutions && len(nextActions) > 0 { //if newExecutions && len(nextActions) > 0 {
// handleExecutionResult(*workflowExecution) // handleExecutionResult(*workflowExecution)
//} //}
resp.WriteHeader(200) //resp.WriteHeader(200)
resp.Write([]byte(fmt.Sprintf(`{"success": true}`))) //resp.Write([]byte(fmt.Sprintf(`{"success": true}`)))
} }
func getWorkflowExecution(ctx context.Context, id string) (*WorkflowExecution, error) { func getWorkflowExecution(ctx context.Context, id string) (*WorkflowExecution, error) {
@@ -2532,7 +2542,7 @@ func validateFinished(workflowExecution WorkflowExecution) {
} }
body, err := ioutil.ReadAll(newresp.Body) body, err := ioutil.ReadAll(newresp.Body)
log.Printf("BACKEND STATUS: %d", newresp.StatusCode) log.Printf("[INFO] BACKEND STATUS: %d", newresp.StatusCode)
if err != nil { if err != nil {
log.Printf("[ERROR] Failed reading body: %s", err) log.Printf("[ERROR] Failed reading body: %s", err)
} else { } else {