diff --git a/backend/go-app/walkoff.go b/backend/go-app/walkoff.go
index 4e04cd71..4b100d48 100644
--- a/backend/go-app/walkoff.go
+++ b/backend/go-app/walkoff.go
@@ -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)
if trigger.ID == workflowExecution.Start {
if trigger.AppName == "User Input" {
@@ -1975,7 +1975,78 @@ func handleExecution(id string, workflow shuffle.Workflow, request *http.Request
Status: "SKIPPED",
})
} 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
//}
+ // 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.IsValid = true
workflowapp.Generated = false
diff --git a/frontend/src/views/AngularWorkflow.jsx b/frontend/src/views/AngularWorkflow.jsx
index ee44b45b..3b11d6dd 100644
--- a/frontend/src/views/AngularWorkflow.jsx
+++ b/frontend/src/views/AngularWorkflow.jsx
@@ -563,7 +563,7 @@ const AngularWorkflow = (props) => {
}
}
} else {
- console.log("JSON is same")
+ //console.log("JSON is same")
}
//console.log("PRE LOOPING RESULTS: !", responseJson.execution_id, executionRequest.execution_id)
@@ -732,7 +732,7 @@ const AngularWorkflow = (props) => {
getWorkflowExecution(props.match.params.key, "")
setUpdate(Math.random())
} else {
- console.log("Nothing to update")
+ //console.log("Nothing to update")
}
}
@@ -1596,10 +1596,13 @@ const AngularWorkflow = (props) => {
//parentNode.data()
var newNodeData = JSON.parse(JSON.stringify(parentNode.data()))
newNodeData.id = uuid.v4()
- newNodeData.position = {
- "x": newNodeData.position.x+100,
- "y": newNodeData.position.y+100,
+ if (newNodeData.position !== undefined) {
+ newNodeData.position = {
+ "x": newNodeData.position.x+100,
+ "y": newNodeData.position.y+100,
+ }
}
+
newNodeData.isStartNode = false
newNodeData.errors = []
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)))))
+ console.log("APP: ", curapp)
if (!curapp || curapp === undefined) {
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)
setRequiresAuthentication(curapp.authentication.required && curapp.authentication.parameters !== undefined && curapp.authentication.parameters !== null)
if (curapp.authentication.required) {
+ console.log("App requires auth.")
// Setup auth here :)
const authenticationOptions = []
var findAuthId = ""
@@ -2793,7 +2798,9 @@ const AngularWorkflow = (props) => {
.then((responseJson) => {
// No matter what, it's being stopped.
if (!responseJson.success) {
- alert.WARNING("Failed to stop schedule: " + responseJson.reason)
+ if (responseJson.reason !== undefined) {
+ alert.error("Failed to stop schedule: " + responseJson.reason)
+ }
} else {
alert.success("Successfully stopped schedule")
}
diff --git a/frontend/src/views/Apps.jsx b/frontend/src/views/Apps.jsx
index a2255cc6..8beddedb 100644
--- a/frontend/src/views/Apps.jsx
+++ b/frontend/src/views/Apps.jsx
@@ -3,7 +3,7 @@ import React, { useEffect } from 'react';
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 {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';
@@ -333,6 +333,10 @@ const Apps = (props) => {
// dropdown with copy etc I guess
const appPaper = (data) => {
+ if (data.name === "" && data.id === "") {
+ return null
+ }
+
var boxWidth = "2px"
if (selectedApp.id === data.id) {
boxWidth = "4px"
@@ -801,9 +805,14 @@ const Apps = (props) => {
const circleSize = 10
return (
)
})}
diff --git a/frontend/src/views/Workflows.jsx b/frontend/src/views/Workflows.jsx
index 5064691e..b009de75 100644
--- a/frontend/src/views/Workflows.jsx
+++ b/frontend/src/views/Workflows.jsx
@@ -311,8 +311,29 @@ const Workflows = (props) => {
if (curWorkflow.tags === undefined || curWorkflow.tags === null) {
found = filters.map(filter => curWorkflow.name.toLowerCase().includes(filter))
} 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)
//if (found) {
if (found.every(v => v === true)) {
@@ -604,6 +625,8 @@ const Workflows = (props) => {
const paperAppStyle = {
minHeight: 130,
+ maxHeight: 130,
+ overflow: "hidden",
width: "100%",
color: "white",
backgroundColor: surfaceColor,
@@ -1503,7 +1526,7 @@ const Workflows = (props) => {
const data = params.row.record;
let [triggers, schedules, webhooks, subflows] = getWorkflowMeta(data);
- return
+ return (
{
: null}
- }
+ )
+ }
},
{ field: 'tags', headerName: 'Tags', width: 390, sortable: false,
disableClickEventBubbling: true,
renderCell: (params) => {
const data = params.row.record;
- return
+ return (
{data.tags !== undefined ?
data.tags.map((tag, index) => {
@@ -1556,6 +1580,7 @@ const Workflows = (props) => {
})
: null}
+ )
}
},
];
@@ -1707,11 +1732,11 @@ const Workflows = (props) => {
const workflowButtons =
- {workflows.length > 0 ?
+ {/*workflows.length > 0 ?
- : null}
+ : null*/}
{importLoading ?