#223: Added basic resultgrabbing from subworkflow if NOT loop
This commit is contained in:
+121
-2
@@ -1936,7 +1936,7 @@ func handleExecution(id string, workflow shuffle.Workflow, request *http.Request
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, trigger := range workflowExecution.Workflow.Triggers {
|
for triggerIndex, trigger := range workflowExecution.Workflow.Triggers {
|
||||||
//log.Printf("[INFO] ID: %s vs %s", trigger.ID, workflowExecution.Start)
|
//log.Printf("[INFO] ID: %s vs %s", trigger.ID, workflowExecution.Start)
|
||||||
if trigger.ID == workflowExecution.Start {
|
if trigger.ID == workflowExecution.Start {
|
||||||
if trigger.AppName == "User Input" {
|
if trigger.AppName == "User Input" {
|
||||||
@@ -1975,7 +1975,78 @@ func handleExecution(id string, workflow shuffle.Workflow, request *http.Request
|
|||||||
Status: "SKIPPED",
|
Status: "SKIPPED",
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
//log.Printf("SHOULD KEEP TRIGGER %s", trigger.ID)
|
// Replaces trigger with the subflow
|
||||||
|
if trigger.AppName == "Shuffle Workflow" {
|
||||||
|
replaceActions := false
|
||||||
|
workflowAction := ""
|
||||||
|
for _, param := range trigger.Parameters {
|
||||||
|
if param.Name == "argument" && !strings.Contains(param.Value, ".#") {
|
||||||
|
replaceActions = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if param.Name == "startnode" {
|
||||||
|
workflowAction = param.Value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if replaceActions {
|
||||||
|
replacementNodes, newBranches, lastnode := shuffle.GetReplacementNodes(ctx, workflowExecution, trigger)
|
||||||
|
log.Printf("REPLACEMENTS: %d, %d", len(replacementNodes), len(newBranches))
|
||||||
|
if len(replacementNodes) > 0 {
|
||||||
|
//workflowExecution.Workflow.Actions = append(workflowExecution.Workflow.Actions, action)
|
||||||
|
|
||||||
|
//lastnode = replacementNodes[0]
|
||||||
|
// Have to validate in case it's the same workflow and such
|
||||||
|
for _, action := range replacementNodes {
|
||||||
|
found := false
|
||||||
|
for subActionIndex, subaction := range newActions {
|
||||||
|
if subaction.ID == action.ID {
|
||||||
|
found = true
|
||||||
|
//newActions[subActionIndex].Name = action.Name
|
||||||
|
newActions[subActionIndex].Label = action.Label
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !found {
|
||||||
|
newActions = append(newActions, action)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if it's already set to have a value
|
||||||
|
for resultIndex, result := range defaultResults {
|
||||||
|
if result.Action.ID == action.ID {
|
||||||
|
defaultResults = append(defaultResults[:resultIndex], defaultResults[resultIndex+1:]...)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, branch := range newBranches {
|
||||||
|
workflowExecution.Workflow.Branches = append(workflowExecution.Workflow.Branches, branch)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append branches:
|
||||||
|
// parent -> new inner node (FIRST one)
|
||||||
|
for branchIndex, branch := range workflowExecution.Workflow.Branches {
|
||||||
|
if branch.DestinationID == trigger.ID {
|
||||||
|
log.Printf("REPLACE DESTINATION WITH %s!!", workflowAction)
|
||||||
|
workflowExecution.Workflow.Branches[branchIndex].DestinationID = workflowAction
|
||||||
|
}
|
||||||
|
|
||||||
|
if branch.SourceID == trigger.ID {
|
||||||
|
log.Printf("REPLACE SOURCE WITH LASTNODE %s!!", lastnode)
|
||||||
|
workflowExecution.Workflow.Branches[branchIndex].SourceID = lastnode
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove the trigger
|
||||||
|
workflowExecution.Workflow.Triggers = append(workflowExecution.Workflow.Triggers[:triggerIndex], workflowExecution.Workflow.Triggers[triggerIndex+1:]...)
|
||||||
|
workflow.Triggers = append(workflow.Triggers[:triggerIndex], workflow.Triggers[triggerIndex+1:]...)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("NEW ACTION LENGTH %d, RESULT: %d, Triggers: %d", len(newActions), len(defaultResults), len(workflowExecution.Workflow.Triggers))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4334,6 +4405,54 @@ func setNewWorkflowApp(resp http.ResponseWriter, request *http.Request) {
|
|||||||
// workflowapp.Environment = baseEnvironment
|
// workflowapp.Environment = baseEnvironment
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
// Fixes (appends) authentication parameters if they're required
|
||||||
|
if workflowapp.Authentication.Required {
|
||||||
|
log.Printf("[INFO] Checking authentication fields and appending for %s!", workflowapp.Name)
|
||||||
|
// FIXME:
|
||||||
|
// Might require reflection into the python code to append the fields as well
|
||||||
|
for index, action := range workflowapp.Actions {
|
||||||
|
if action.AuthNotRequired {
|
||||||
|
log.Printf("Skipping auth setup: %s", action.Name)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1. Check if authentication params exists at all
|
||||||
|
// 2. Check if they're present in the action
|
||||||
|
// 3. Add them IF they DONT exist
|
||||||
|
// 4. Fix python code with reflection (FIXME)
|
||||||
|
appendParams := []shuffle.WorkflowAppActionParameter{}
|
||||||
|
for _, fieldname := range workflowapp.Authentication.Parameters {
|
||||||
|
found := false
|
||||||
|
for index, param := range action.Parameters {
|
||||||
|
if param.Name == fieldname.Name {
|
||||||
|
found = true
|
||||||
|
|
||||||
|
action.Parameters[index].Configuration = true
|
||||||
|
//log.Printf("Set config to true for field %s!", param.Name)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !found {
|
||||||
|
appendParams = append(appendParams, shuffle.WorkflowAppActionParameter{
|
||||||
|
Name: fieldname.Name,
|
||||||
|
Description: fieldname.Description,
|
||||||
|
Example: fieldname.Example,
|
||||||
|
Required: fieldname.Required,
|
||||||
|
Configuration: true,
|
||||||
|
Schema: fieldname.Schema,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(appendParams) > 0 {
|
||||||
|
log.Printf("[AUTH] Appending %d params to the START of %s", len(appendParams), action.Name)
|
||||||
|
workflowapp.Actions[index].Parameters = append(appendParams, workflowapp.Actions[index].Parameters...)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
workflowapp.ID = uuid.NewV4().String()
|
workflowapp.ID = uuid.NewV4().String()
|
||||||
workflowapp.IsValid = true
|
workflowapp.IsValid = true
|
||||||
workflowapp.Generated = false
|
workflowapp.Generated = false
|
||||||
|
|||||||
@@ -563,7 +563,7 @@ const AngularWorkflow = (props) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.log("JSON is same")
|
//console.log("JSON is same")
|
||||||
}
|
}
|
||||||
|
|
||||||
//console.log("PRE LOOPING RESULTS: !", responseJson.execution_id, executionRequest.execution_id)
|
//console.log("PRE LOOPING RESULTS: !", responseJson.execution_id, executionRequest.execution_id)
|
||||||
@@ -732,7 +732,7 @@ const AngularWorkflow = (props) => {
|
|||||||
getWorkflowExecution(props.match.params.key, "")
|
getWorkflowExecution(props.match.params.key, "")
|
||||||
setUpdate(Math.random())
|
setUpdate(Math.random())
|
||||||
} else {
|
} else {
|
||||||
console.log("Nothing to update")
|
//console.log("Nothing to update")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1596,10 +1596,13 @@ const AngularWorkflow = (props) => {
|
|||||||
//parentNode.data()
|
//parentNode.data()
|
||||||
var newNodeData = JSON.parse(JSON.stringify(parentNode.data()))
|
var newNodeData = JSON.parse(JSON.stringify(parentNode.data()))
|
||||||
newNodeData.id = uuid.v4()
|
newNodeData.id = uuid.v4()
|
||||||
newNodeData.position = {
|
if (newNodeData.position !== undefined) {
|
||||||
"x": newNodeData.position.x+100,
|
newNodeData.position = {
|
||||||
"y": newNodeData.position.y+100,
|
"x": newNodeData.position.x+100,
|
||||||
|
"y": newNodeData.position.y+100,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
newNodeData.isStartNode = false
|
newNodeData.isStartNode = false
|
||||||
newNodeData.errors = []
|
newNodeData.errors = []
|
||||||
newNodeData.is_valid = true
|
newNodeData.is_valid = true
|
||||||
@@ -1713,6 +1716,7 @@ const AngularWorkflow = (props) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const curapp = apps.find(a => a.name === curaction.app_name && ((a.app_version === curaction.app_version || (a.loop_versions !== null && a.loop_versions.includes(curaction.app_version)))))
|
const curapp = apps.find(a => a.name === curaction.app_name && ((a.app_version === curaction.app_version || (a.loop_versions !== null && a.loop_versions.includes(curaction.app_version)))))
|
||||||
|
console.log("APP: ", curapp)
|
||||||
if (!curapp || curapp === undefined) {
|
if (!curapp || curapp === undefined) {
|
||||||
alert.error(`App ${curaction.app_name}:${curaction.app_version} not found. Is it activated?`)
|
alert.error(`App ${curaction.app_name}:${curaction.app_version} not found. Is it activated?`)
|
||||||
|
|
||||||
@@ -1734,6 +1738,7 @@ const AngularWorkflow = (props) => {
|
|||||||
//console.log("AUTHENTICATION: ", curapp.authentication)
|
//console.log("AUTHENTICATION: ", curapp.authentication)
|
||||||
setRequiresAuthentication(curapp.authentication.required && curapp.authentication.parameters !== undefined && curapp.authentication.parameters !== null)
|
setRequiresAuthentication(curapp.authentication.required && curapp.authentication.parameters !== undefined && curapp.authentication.parameters !== null)
|
||||||
if (curapp.authentication.required) {
|
if (curapp.authentication.required) {
|
||||||
|
console.log("App requires auth.")
|
||||||
// Setup auth here :)
|
// Setup auth here :)
|
||||||
const authenticationOptions = []
|
const authenticationOptions = []
|
||||||
var findAuthId = ""
|
var findAuthId = ""
|
||||||
@@ -2793,7 +2798,9 @@ const AngularWorkflow = (props) => {
|
|||||||
.then((responseJson) => {
|
.then((responseJson) => {
|
||||||
// No matter what, it's being stopped.
|
// No matter what, it's being stopped.
|
||||||
if (!responseJson.success) {
|
if (!responseJson.success) {
|
||||||
alert.WARNING("Failed to stop schedule: " + responseJson.reason)
|
if (responseJson.reason !== undefined) {
|
||||||
|
alert.error("Failed to stop schedule: " + responseJson.reason)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
alert.success("Successfully stopped schedule")
|
alert.success("Successfully stopped schedule")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import React, { useEffect } from 'react';
|
|||||||
import { useInterval } from 'react-powerhooks';
|
import { useInterval } from 'react-powerhooks';
|
||||||
|
|
||||||
import {IconButton, Typography, Grid, Select, Paper, Divider, ButtonBase, Button, TextField, FormControl, MenuItem, Tooltip, FormControlLabel, Switch, Input, Breadcrumbs, Chip, Dialog, DialogTitle, DialogActions, DialogContent, CircularProgress} from '@material-ui/core';
|
import {IconButton, Typography, Grid, Select, Paper, Divider, ButtonBase, Button, TextField, FormControl, MenuItem, Tooltip, FormControlLabel, Switch, Input, Breadcrumbs, Chip, Dialog, DialogTitle, DialogActions, DialogContent, CircularProgress} from '@material-ui/core';
|
||||||
import {OpenInNew as OpenInNewIcon,Apps as AppsIcon, Cached as CachedIcon, Publish as PublishIcon, CloudDownload as CloudDownloadIcon, Edit as EditIcon, Delete as DeleteIcon} from '@material-ui/icons';
|
import {LockOpen as LockOpenIcon, OpenInNew as OpenInNewIcon,Apps as AppsIcon, Cached as CachedIcon, Publish as PublishIcon, CloudDownload as CloudDownloadIcon, Edit as EditIcon, Delete as DeleteIcon} from '@material-ui/icons';
|
||||||
|
|
||||||
import { useTheme } from '@material-ui/core/styles';
|
import { useTheme } from '@material-ui/core/styles';
|
||||||
|
|
||||||
@@ -333,6 +333,10 @@ const Apps = (props) => {
|
|||||||
|
|
||||||
// dropdown with copy etc I guess
|
// dropdown with copy etc I guess
|
||||||
const appPaper = (data) => {
|
const appPaper = (data) => {
|
||||||
|
if (data.name === "" && data.id === "") {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
var boxWidth = "2px"
|
var boxWidth = "2px"
|
||||||
if (selectedApp.id === data.id) {
|
if (selectedApp.id === data.id) {
|
||||||
boxWidth = "4px"
|
boxWidth = "4px"
|
||||||
@@ -801,9 +805,14 @@ const Apps = (props) => {
|
|||||||
const circleSize = 10
|
const circleSize = 10
|
||||||
return (
|
return (
|
||||||
<MenuItem key={data.name} style={{backgroundColor: inputColor, color: "white"}} value={data}>
|
<MenuItem key={data.name} style={{backgroundColor: inputColor, color: "white"}} value={data}>
|
||||||
<div style={{width: circleSize, height: circleSize, borderRadius: circleSize / 2, backgroundColor: itemColor, marginRight: "10px"}}/>
|
{data.configuration === true ?
|
||||||
|
<Tooltip color="primary" title={`Authenticate ${selectedApp.name}`} placement="top">
|
||||||
|
<LockOpenIcon style={{cursor: "pointer", width: 24, height: 24, marginRight: 10, }} />
|
||||||
|
</Tooltip>
|
||||||
|
:
|
||||||
|
<div style={{width: 17, height: 17, borderRadius: 17 / 2, backgroundColor: itemColor, marginRight: 10, marginTop: 2, marginTop: "auto", marginBottom: "auto",}}/>
|
||||||
|
}
|
||||||
{data.name}
|
{data.name}
|
||||||
|
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
|
|||||||
@@ -311,8 +311,29 @@ const Workflows = (props) => {
|
|||||||
if (curWorkflow.tags === undefined || curWorkflow.tags === null) {
|
if (curWorkflow.tags === undefined || curWorkflow.tags === null) {
|
||||||
found = filters.map(filter => curWorkflow.name.toLowerCase().includes(filter))
|
found = filters.map(filter => curWorkflow.name.toLowerCase().includes(filter))
|
||||||
} else {
|
} else {
|
||||||
found = filters.map(filter => curWorkflow.name.toLowerCase().includes(filter.toLowerCase()) || curWorkflow.tags.includes(filter))
|
found = filters.map(filter => {
|
||||||
|
if (filter === undefined) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (curWorkflow.name.toLowerCase().includes(filter.toLowerCase())) {
|
||||||
|
return true
|
||||||
|
} else if (curWorkflow.tags.includes(filter)) {
|
||||||
|
return true
|
||||||
|
} else if (curWorkflow.actions !== null && curWorkflow.actions !== undefined) {
|
||||||
|
const newfilter = filter.toLowerCase()
|
||||||
|
for (var key in curWorkflow.actions) {
|
||||||
|
const action = curWorkflow.actions[key]
|
||||||
|
if (action.app_name.toLowerCase().includes(newfilter)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
//console.log("FOUND: ", found)
|
//console.log("FOUND: ", found)
|
||||||
//if (found) {
|
//if (found) {
|
||||||
if (found.every(v => v === true)) {
|
if (found.every(v => v === true)) {
|
||||||
@@ -604,6 +625,8 @@ const Workflows = (props) => {
|
|||||||
|
|
||||||
const paperAppStyle = {
|
const paperAppStyle = {
|
||||||
minHeight: 130,
|
minHeight: 130,
|
||||||
|
maxHeight: 130,
|
||||||
|
overflow: "hidden",
|
||||||
width: "100%",
|
width: "100%",
|
||||||
color: "white",
|
color: "white",
|
||||||
backgroundColor: surfaceColor,
|
backgroundColor: surfaceColor,
|
||||||
@@ -1503,7 +1526,7 @@ const Workflows = (props) => {
|
|||||||
const data = params.row.record;
|
const data = params.row.record;
|
||||||
let [triggers, schedules, webhooks, subflows] = getWorkflowMeta(data);
|
let [triggers, schedules, webhooks, subflows] = getWorkflowMeta(data);
|
||||||
|
|
||||||
return
|
return (
|
||||||
<Grid item>
|
<Grid item>
|
||||||
<Link to={"/workflows/"+data.id}>
|
<Link to={"/workflows/"+data.id}>
|
||||||
<EditIcon style={{background: "#F85A3E",
|
<EditIcon style={{background: "#F85A3E",
|
||||||
@@ -1530,13 +1553,14 @@ const Workflows = (props) => {
|
|||||||
</Tooltip>
|
</Tooltip>
|
||||||
: null}
|
: null}
|
||||||
</Grid>
|
</Grid>
|
||||||
}
|
)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{ field: 'tags', headerName: 'Tags', width: 390, sortable: false,
|
{ field: 'tags', headerName: 'Tags', width: 390, sortable: false,
|
||||||
disableClickEventBubbling: true,
|
disableClickEventBubbling: true,
|
||||||
renderCell: (params) => {
|
renderCell: (params) => {
|
||||||
const data = params.row.record;
|
const data = params.row.record;
|
||||||
return
|
return (
|
||||||
<Grid item>
|
<Grid item>
|
||||||
{data.tags !== undefined ?
|
{data.tags !== undefined ?
|
||||||
data.tags.map((tag, index) => {
|
data.tags.map((tag, index) => {
|
||||||
@@ -1556,6 +1580,7 @@ const Workflows = (props) => {
|
|||||||
})
|
})
|
||||||
: null}
|
: null}
|
||||||
</Grid>
|
</Grid>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
@@ -1707,11 +1732,11 @@ const Workflows = (props) => {
|
|||||||
|
|
||||||
const workflowButtons =
|
const workflowButtons =
|
||||||
<span>
|
<span>
|
||||||
{workflows.length > 0 ?
|
{/*workflows.length > 0 ?
|
||||||
<Tooltip color="primary" title={"Create new workflow"} placement="top">
|
<Tooltip color="primary" title={"Create new workflow"} placement="top">
|
||||||
<Button color="primary" style={{}} variant="text" onClick={() => setModalOpen(true)}><AddIcon /></Button>
|
<Button color="primary" style={{}} variant="text" onClick={() => setModalOpen(true)}><AddIcon /></Button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
: null}
|
: null*/}
|
||||||
<Tooltip color="primary" title={"Import workflows"} placement="top">
|
<Tooltip color="primary" title={"Import workflows"} placement="top">
|
||||||
{importLoading ?
|
{importLoading ?
|
||||||
<Button color="primary" style={{}} variant="text" onClick={() => {}}>
|
<Button color="primary" style={{}} variant="text" onClick={() => {}}>
|
||||||
|
|||||||
@@ -1023,10 +1023,6 @@ func handleExecutionResult(workflowExecution shuffle.WorkflowExecution) {
|
|||||||
// Trying to replace with lowercase to deploy again. This seems to work with Dockerhub well.
|
// Trying to replace with lowercase to deploy again. This seems to work with Dockerhub well.
|
||||||
// FIXME: Should try to remotely download directly if this persists.
|
// FIXME: Should try to remotely download directly if this persists.
|
||||||
image = images[1]
|
image = images[1]
|
||||||
if strings.Contains(image, " ") {
|
|
||||||
image = strings.ReplaceAll(image, " ", "-")
|
|
||||||
}
|
|
||||||
|
|
||||||
err = deployApp(dockercli, image, identifier, env, workflowExecution)
|
err = deployApp(dockercli, image, identifier, env, workflowExecution)
|
||||||
if err != nil && !strings.Contains(err.Error(), "Conflict. The container name") {
|
if err != nil && !strings.Contains(err.Error(), "Conflict. The container name") {
|
||||||
if strings.Contains(err.Error(), "exited prematurely") {
|
if strings.Contains(err.Error(), "exited prematurely") {
|
||||||
@@ -1034,10 +1030,6 @@ func handleExecutionResult(workflowExecution shuffle.WorkflowExecution) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
image = images[2]
|
image = images[2]
|
||||||
if strings.Contains(image, " ") {
|
|
||||||
image = strings.ReplaceAll(image, " ", "-")
|
|
||||||
}
|
|
||||||
|
|
||||||
err = deployApp(dockercli, image, identifier, env, workflowExecution)
|
err = deployApp(dockercli, image, identifier, env, workflowExecution)
|
||||||
if err != nil && !strings.Contains(err.Error(), "Conflict. The container name") {
|
if err != nil && !strings.Contains(err.Error(), "Conflict. The container name") {
|
||||||
if strings.Contains(err.Error(), "exited prematurely") {
|
if strings.Contains(err.Error(), "exited prematurely") {
|
||||||
|
|||||||
Reference in New Issue
Block a user