diff --git a/backend/go-app/main.go b/backend/go-app/main.go
index e775ebf5..f86a557c 100644
--- a/backend/go-app/main.go
+++ b/backend/go-app/main.go
@@ -6085,11 +6085,6 @@ func initHandlers() {
panic(fmt.Sprintf("DBclient error during init: %s", err))
}
- //dbclient, err := shuffle.GetDatastoreClient(ctx, gceProject)
- //if err != nil {
- // panic(fmt.Sprintf("Error setting datastore connector: %s", err))
- //}
-
_ = shuffle.RunInit(*dbclient, storage.Client{}, gceProject, "onprem", true)
log.Printf("Finished Shuffle database init")
diff --git a/frontend/src/components/ConfigureWorkflow.jsx b/frontend/src/components/ConfigureWorkflow.jsx
index b311dc95..95457675 100644
--- a/frontend/src/components/ConfigureWorkflow.jsx
+++ b/frontend/src/components/ConfigureWorkflow.jsx
@@ -95,7 +95,7 @@ const Workflow = (props) => {
}
if (action.errors !== undefined && action.errors !== null && action.errors.length > 0) {
- console.log("Node has errors!: ", action.errors)
+ //console.log("Node has errors!: ", action.errors)
}
if (newaction.must_authenticate) {
@@ -103,19 +103,23 @@ const Workflow = (props) => {
for (var key in appAuthentication) {
const auth = appAuthentication[key]
if (auth.app.name === app.name && auth.active) {
- console.log("Found auth: ", auth)
+ //console.log("Found auth: ", auth)
authenticationOptions.push(auth)
newaction.authenticationId = auth.id
break
}
}
- console.log("APPAUTH: ", app.authentication, action)
if (newaction.authenticationId === null || newaction.authenticationId === undefined || newaction.authenticationId.length === "") {
- console.log("FAILED to authentication node!")
- newactions.push(newaction)
+ //console.log("FAILED to authenticate node!")
+
+ if (newactions.find(tmpaction => tmpaction.app_id === newaction.app_id && tmpaction.app_name === newaction.app_name) !== undefined) {
+ console.log("Action already found.")
+ } else {
+ newactions.push(newaction)
+ }
} else {
- console.log("Skipping node as it's already authenticated.")
+ //console.log("Skipping node as it's already authenticated.")
newaction.authentication = authenticationOptions
workflow.actions[key] = newaction
}
@@ -157,16 +161,12 @@ const Workflow = (props) => {
setConfigureWorkflowModalOpen(false)
}
- console.log("VARIABLES: ", requiredVariables)
- console.log("ACTIONS: ", newactions)
setRequiredTriggers(requiredTriggers)
setRequiredVariables(requiredVariables)
setRequiredActions(newactions)
}
- console.log("AUTH: ", appAuthentication)
if (appAuthentication.length !== previousAuth.length) {
- console.log("APP AUTH CHANGED!")
var newactions = []
for (var actionkey in requiredActions) {
var newaction = requiredActions[actionkey]
@@ -175,7 +175,6 @@ const Workflow = (props) => {
for (var key in appAuthentication) {
const auth = appAuthentication[key]
if (auth.app.name === app.name && auth.active) {
- console.log("FOUND AUTH FOR: ", auth.app.name)
newaction.auth_done = true
break
}
@@ -193,10 +192,7 @@ const Workflow = (props) => {
const TriggerSection = (props) => {
const {trigger} = props
- console.log(trigger)
-
return (
-
@@ -275,7 +271,6 @@ const Workflow = (props) => {
/>
*/}
-
)
}
@@ -343,16 +338,13 @@ const Workflow = (props) => {
{action.must_authenticate ?
action.auth_done ?
-
-
-
+
:
selectedAction.app_name === action.app_name ?
@@ -377,8 +369,6 @@ const Workflow = (props) => {
)
}
- console.log(requiredActions)
-
return (
{workflow.name}
@@ -401,11 +391,13 @@ const Workflow = (props) => {
{requiredVariables.length > 0 ?
Variables
- {requiredVariables.map((data, index) => {
- return (
-
- )
- })}
+
+ {requiredVariables.map((data, index) => {
+ return (
+
+ )
+ })}
+
: null}
@@ -413,21 +405,25 @@ const Workflow = (props) => {
{requiredTriggers.length > 0 ?
Triggers
- {requiredTriggers.map((data, index) => {
- return (
-
- )
- })}
+
+ {requiredTriggers.map((data, index) => {
+ return (
+
+ )
+ })}
+
: null }
+ {/*
+ */}
+ }
+ parentMenuOpen={!!menuPosition}
+ style={{backgroundColor: theme.palette.inputColor, color: "white", minWidth: 250,}}
+ onClick={() => {
+ handleItemClick([innerdata])
+ }}
+ >
+ {parsedPaths.map((pathdata, index) => {
+ // FIXME: Should be recursive in here
+ const icon = pathdata.type === "value" ?
: pathdata.type === "list" ?
:
+ return (
+
+ )
+
+ })}
+
+ :
+
+
+ )
+ })}
+
+ )
+ }
+
+ var itemColor = "#f85a3e"
+ if (!data.required) {
+ itemColor = "#ffeb3b"
+ }
+
+ var tmpitem = data.name.valueOf()
+ if (data.name.startsWith("${") && data.name.endsWith("}")) {
+ tmpitem = tmpitem.slice(2, data.name.length-1)
+ }
+
+ tmpitem = tmpitem.charAt(0).toUpperCase()+tmpitem.substring(1)
+ tmpitem = tmpitem.replaceAll("_", " ")
+ const description = data.description === undefined ? "" : data.description
+
+ return (
+
+
+
+
+ {data.configuration === true ?
+
+ {
+ setAuthenticationModalOpen(true)
+ }}/>
+
+ :
+
+ }
+
+
+ {tmpitem}
+
+
+
+ {/*selectedActionParameters[count].options !== undefined && selectedActionParameters[count].options !== null && selectedActionParameters[count].options.length > 0 ? null :
+
+
+ {
+ e.preventDefault()
+ changeActionParameterVariant("STATIC_VALUE", count)
+ }}>
+
+
+
+ |
+
+ {
+ e.preventDefault()
+ changeActionParameterVariant("ACTION_RESULT", count)
+ }}>
+
+
+
+ |
+
+ {
+ e.preventDefault()
+ changeActionParameterVariant("WORKFLOW_VARIABLE", count)
+ }}>
+
+
+
+
+ */}
+ {selectedActionParameters[count].options !== undefined && selectedActionParameters[count].options !== null && selectedActionParameters[count].options.length > 0 && selectedActionParameters[count].required === true && selectedActionParameters[count].unique_toggled !== undefined ? null :
+
+
+ {}}>
+ {
+ //console.log("CHECKED!: ", selectedActionParameters[count])
+ selectedActionParameters[count].unique_toggled = !selectedActionParameters[count].unique_toggled
+ selectedAction.parameters[count].unique_toggled = selectedActionParameters[count].unique_toggled
+ setSelectedActionParameters(selectedActionParameters)
+ setSelectedAction(selectedAction)
+ setUpdate(Math.random())
+ }}
+ name="requires_unique"
+ />
+
+
+
+ }
+
+ {datafield}
+ {showDropdown && showDropdownNumber === count && data.variant === "STATIC_VALUE" && jsonList.length > 0 ?
+
+ Autocomplete
+
+
+ : null}
+ {showDropdown && showDropdownNumber === count && data.variant === "STATIC_VALUE" && jsonList.length === 0 ?
+
+ : null}
+
+
+
+ )})}
+
+ )
+ }
+ return null
+ }
+ return (
+
+
+
+
{selectedAction.app_name.replaceAll("_", " ")}
+
+
{
+ console.log("FIND EXAMPLE RESULTS FOR ", selectedAction)
+ if (workflowExecutions.length > 0) {
+ // Look for the ID
+ const found = false
+ for (var key in workflowExecutions) {
+ if (workflowExecutions[key].results === undefined || workflowExecutions[key].results === null) {
+ continue
+ }
+
+ var foundResult = workflowExecutions[key].results.find(result => result.action.id === selectedAction.id)
+ if (foundResult === undefined || foundResult === null) {
+ continue
+ }
+
+ setSelectedResult(foundResult)
+ setCodeModalOpen(true)
+ break
+ }
+ }
+ }}>
+
+
+
+
+
+ What are actions?
+ {selectedAction.errors !== null && selectedAction.errors.length > 0 ?
+
+ Errors: {selectedAction.errors.join("\n")}
+
+ : null
+ }
+
+
+
+
+ {selectedAction.id === workflow.start ? null :
+
+ {
+ defineStartnode(e)
+ }}>
+
+
+
+ }
+ {selectedApp.versions !== null && selectedApp.versions !== undefined && selectedApp.versions.length > 0 ?
+
+ : null }
+
+
+
+
+ Name
+
+
+ {selectedApp.name !== undefined && selectedAction.authentication !== undefined && selectedAction.authentication.length === 0 && requiresAuthentication ?
+
+
+
+ {
+ setAuthenticationModalOpen(true)
+ }}>
+ Authenticate {selectedApp.name}
+
+
+
+
+ : null}
+ {selectedAction.authentication !== undefined && selectedAction.authentication.length > 0 ?
+
+ Authentication
+
+
+
+ {/*
+
+
setAuthenticationModalOpen(true)}>
+ AUTHENTICATE
+
+ curaction.authentication = authenticationOptions
+ if (curaction.selectedAuthentication === null || curaction.selectedAuthentication === undefined || curaction.selectedAuthentication.length === "")
+ */}
+
+ {
+ setAuthenticationModalOpen(true)
+ }}>
+
+
+
+
+
+ : null}
+ {showEnvironment ?
+
+
+ Environment
+
+
+
+ : null}
+ {workflow.execution_variables !== undefined && workflow.execution_variables !== null && workflow.execution_variables.length > 0 ?
+
+ Set execution variable (optional)
+
+
+ : null}
+
+
+
+ Actions
+
+
+ {selectedAction.description !== undefined && selectedAction.description.length > 0 ?
+
+ {selectedAction.description}
+
: null}
+
+
+
+ )
+ }
+
+
+export default ParsedAction;
diff --git a/frontend/src/theme.js b/frontend/src/theme.js
new file mode 100644
index 00000000..13b47d64
--- /dev/null
+++ b/frontend/src/theme.js
@@ -0,0 +1,57 @@
+import React from 'react';
+import { createMuiTheme } from '@material-ui/core/styles';
+
+const theme = createMuiTheme({
+ palette: {
+ primary: {
+ main: "#f85a3e"
+ },
+ secondary: {
+ main: '#e8eaf6',
+ },
+ text: {
+ secondary: "rgba(255,255,255,0.7)",
+ },
+ surfaceColor: "#27292d",
+ inputColor: "#383B40",
+ borderRadius: 5,
+ textFieldStyle: {
+ backgroundColor: "#383B40",
+ borderRadius: 5,
+ },
+ innerTextfieldStyle: {
+ color: "white",
+ minHeight: 50,
+ marginLeft: "5px",
+ maxWidth: "95%",
+ fontSize: "1em",
+ borderRadius: 5,
+ }
+ },
+ typography: {
+ "fontFamily": `"Roboto", "Helvetica", "Arial", sans-serif`,
+ useNextVariants: true,
+ h1: {
+ fontSize: 40,
+ },
+ h4: {
+ fontSize: 30,
+ fontWeight: 500,
+ },
+ h6: {
+ fontSize: 22,
+ },
+ body1: {
+ fontSize: 18,
+ },
+ },
+ overrides: {
+ MuiMenu: {
+ list: {
+ backgroundColor: "#383B40",
+ },
+ },
+ },
+});
+
+export default theme;
diff --git a/frontend/src/views/AngularWorkflow.jsx b/frontend/src/views/AngularWorkflow.jsx
index b32fb4b2..ed8e2295 100644
--- a/frontend/src/views/AngularWorkflow.jsx
+++ b/frontend/src/views/AngularWorkflow.jsx
@@ -27,6 +27,7 @@ import { useAlert } from "react-alert";
import { validateJson } from "./Workflows.jsx";
import { GetParsedPaths } from "./Apps.jsx";
import ConfigureWorkflow from '../components/ConfigureWorkflow.jsx';
+import ParsedAction from '../components/ParsedAction.jsx';
const surfaceColor = "#27292D"
const inputColor = "#383B40"
@@ -87,7 +88,6 @@ const AngularWorkflow = (props) => {
const { globalUrl, isLoggedIn, isLoaded, userdata } = props;
const referenceUrl = globalUrl+"/api/v1/hooks/"
const alert = useAlert()
- const borderRadius = 5
const theme = useTheme();
const green = "#86c142"
const yellow = "#FECC00"
@@ -128,7 +128,7 @@ const AngularWorkflow = (props) => {
const [rightSideBarOpen, setRightSideBarOpen] = React.useState(false)
const [showSkippedActions, setShowSkippedActions] = React.useState(false)
const [lastExecution, setLastExecution] = React.useState("")
- const [configureWorkflowModalOpen, setConfigureWorkflowModalOpen] = React.useState(true)
+ const [configureWorkflowModalOpen, setConfigureWorkflowModalOpen] = React.useState(false)
const [curpath, setCurpath] = useState(typeof window === 'undefined' || window.location === undefined ? "" : window.location.pathname)
// 0 = normal, 1 = just done, 2 = normal
@@ -1151,8 +1151,11 @@ const AngularWorkflow = (props) => {
//console.log(responseJson)
// Add error checks
- if (!responseJson.public && (!responseJson.previously_saved || (!responseJson.is_valid || (responseJson.errors !== undefined || responseJson.errors !== null || responseJson.errors !== responseJson.errors.length > 0)))) {
- setConfigureWorkflowModalOpen(true)
+ console.log(responseJson)
+ if (!responseJson.public) {
+ if ((!responseJson.previously_saved || (!responseJson.is_valid || (responseJson.errors !== undefined || responseJson.errors !== null || responseJson.errors !== responseJson.errors.length > 0)))) {
+ setConfigureWorkflowModalOpen(true)
+ }
}
})
.catch(error => {
@@ -2127,7 +2130,7 @@ const AngularWorkflow = (props) => {
const paperAppStyle = {
- borderRadius: borderRadius,
+ borderRadius: theme.palette.borderRadius,
minHeight: 100,
maxHeight: 100,
minWidth: "100%",
@@ -2140,7 +2143,7 @@ const AngularWorkflow = (props) => {
}
const paperVariableStyle = {
- borderRadius: borderRadius,
+ borderRadius: theme.palette.borderRadius,
minHeight: 50,
maxHeight: 50,
minWidth: "100%",
@@ -2629,6 +2632,7 @@ const AngularWorkflow = (props) => {
const handleAppDrag = (e, app) => {
const cycontainer = cy.container()
+
// Chrome lol
//if (e.srcElement !== undefined && e.srcElement.localName === "canvas") {
if (e.pageX > cycontainer.offsetLeft && e.pageX < cycontainer.offsetLeft+cycontainer.offsetWidth && e.pageY > cycontainer.offsetTop && e.pageY < cycontainer.offsetTop+cycontainer.offsetHeight) {
@@ -2641,6 +2645,10 @@ const AngularWorkflow = (props) => {
currentnode[0].renderedPosition("x", e.pageX-cycontainer.offsetLeft)
currentnode[0].renderedPosition("y", e.pageY-cycontainer.offsetTop)
} else{
+ if (workflow.public) {
+ return
+ }
+
if (app.actions === undefined || app.actions === null || app.actions.length === 0) {
alert.error("App "+app.name+" currently has no actions to perform. Please go to https://shuffler.io/apps to edit it.")
return
@@ -2669,13 +2677,14 @@ const AngularWorkflow = (props) => {
setUpdate(Math.random())
*/
+ console.log("ENVS: ", environments)
const newAppData = {
app_name: app.name,
app_version: app.app_version,
app_id: app.id,
sharing: app.sharing,
private_id: app.private_id,
- environment: environments === null ? "cloud" : environments[defaultEnvironmentIndex].Name,
+ environment: environments === null || environments === [] ? "cloud" : environments[defaultEnvironmentIndex].Name,
errors: [],
id_: newNodeId,
_id_: newNodeId,
@@ -2865,7 +2874,7 @@ const AngularWorkflow = (props) => {
{setHover(true)}} onMouseOut={() => {setHover(false)}}>
-
+
@@ -2900,7 +2909,7 @@ const AngularWorkflow = (props) => {
{
// Dropdown -> static, action, local env, global env
// VALUE (JSON)
// {data.name}, {data.description}, {data.required}, {data.schema.type}
- const AppActionArguments = (props) => {
- const [selectedActionParameters, setSelectedActionParameters] = React.useState([])
- const [selectedVariableParameter, setSelectedVariableParameter] = React.useState("")
- const [actionlist, setActionlist] = React.useState([])
- const [jsonList, setJsonList] = React.useState([])
- const [showDropdown, setShowDropdown] = React.useState(false)
- const [showDropdownNumber, setShowDropdownNumber] = React.useState(0)
- const [showAutocomplete, setShowAutocomplete] = React.useState(false)
- const [menuPosition, setMenuPosition] = useState(null)
-
- useEffect(() => {
- if (selectedActionParameters !== null && selectedActionParameters.length === 0) {
- if (selectedAction.parameters !== null && selectedAction.parameters.length > 0) {
- setSelectedActionParameters(selectedAction.parameters)
- }
- }
-
- if ((selectedVariableParameter === null || selectedVariableParameter === undefined) && (workflow.workflow_variables !== null && workflow.workflow_variables.length > 0)) {
- // FIXME - this is the bad thing
- setSelectedVariableParameter(workflow.workflow_variables[0].name)
- }
-
- if (actionlist.length === 0) {
- // FIXME: Have previous execution values in here
- actionlist.push({"type": "Execution Argument", "name": "Execution Argument", "value": "$exec", "highlight": "exec", "autocomplete": "exec", "example": "hello"})
- if (workflow.workflow_variables !== null && workflow.workflow_variables !== undefined && workflow.workflow_variables.length > 0) {
- for (var key in workflow.workflow_variables) {
- const item = workflow.workflow_variables[key]
- actionlist.push({"type": "workflow_variable", "name": item.name, "value": item.value, "id": item.id, "autocomplete": `${item.name.split(" ").join("_")}`, "example": item.value})
- }
- }
-
- // FIXME: Add values from previous executions if they exist
- if (workflow.execution_variables !== null && workflow.execution_variables !== undefined && workflow.execution_variables.length > 0) {
- for (var key in workflow.execution_variables) {
- const item = workflow.execution_variables[key]
- actionlist.push({"type": "execution_variable", "name": item.name, "value": item.value, "id": item.id, "autocomplete": `${item.name.split(" ").join("_")}`, "example": ""})
- }
- }
-
- // Loops parent nodes' old results to fix autocomplete
- var parents = getParents(selectedAction)
- if (parents.length > 1) {
- for (var key in parents) {
- const item = parents[key]
- if (item.label === "Execution Argument") {
- continue
- }
-
- var exampledata = item.example === undefined ? "" : item.example
- // Find previous execution and their variables
- //exampledata === "" &&
- if (workflowExecutions.length > 0) {
- // Look for the ID
- const found = false
- for (var key in workflowExecutions) {
- if (workflowExecutions[key].results === undefined || workflowExecutions[key].results === null) {
- continue
- }
-
- var foundResult = workflowExecutions[key].results.find(result => result.action.id === item.id)
- if (foundResult === undefined) {
- continue
- }
-
- foundResult.result = foundResult.result.trim()
- foundResult.result = foundResult.result.split(" None").join(" \"None\"")
- foundResult.result = foundResult.result.split(" False").join(" false")
- foundResult.result = foundResult.result.split(" True").join(" true")
-
- var jsonvalid = true
- try {
- const tmp = String(JSON.parse(foundResult.result))
- if (!foundResult.result.includes("{") && !foundResult.result.includes("[")) {
- jsonvalid = false
- }
- } catch (e) {
- try {
- foundResult.result = foundResult.result.split("\'").join("\"")
- const tmp = String(JSON.parse(foundResult.result))
- if (!foundResult.result.includes("{") && !foundResult.result.includes("[")) {
- jsonvalid = false
- }
- } catch (e) {
- jsonvalid = false
- }
- }
-
- // Finds the FIRST json only
- if (jsonvalid) {
- exampledata = JSON.parse(foundResult.result)
- break
- }
- //else {
- // console.log("Invalid JSON: ", foundResult.result)
- //}
- }
- }
-
- // 1. Take
- const actionvalue = {"type": "action", "id": item.id, "name": item.label, "autocomplete": `${item.label.split(" ").join("_")}`, "example": exampledata}
- actionlist.push(actionvalue)
- }
- }
-
- setActionlist(actionlist)
- }
- })
-
- const changeActionParameter = (event, count, data) => {
- if (data.name.startsWith("${") && data.name.endsWith("}")) {
- // PARAM FIX - Gonna use the ID field, even though it's a hack
- const paramcheck = selectedAction.parameters.find(param => param.name === "body")
- if (paramcheck !== undefined) {
- if (paramcheck["value_replace"] === undefined || paramcheck["value_replace"] === null) {
- paramcheck["value_replace"] = [{
- "key": data.name,
- "value": event.target.value,
- }]
-
- } else {
- const subparamindex = paramcheck["value_replace"].findIndex(param => param.key === data.name)
- if (subparamindex === -1) {
- paramcheck["value_replace"].push({
- "key": data.name,
- "value": event.target.value,
- })
- } else {
- paramcheck["value_replace"][subparamindex]["value"] = event.target.value
- }
- }
- //console.log("PARAM: ", paramcheck)
-
- selectedActionParameters[count]["value_replace"] = paramcheck
- selectedAction.parameters[count]["value_replace"] = paramcheck
- setSelectedAction(selectedAction)
- //setUpdate(Math.random())
- return
- }
- }
-
- if (event.target.value[event.target.value.length-1] === "$") {
- if (!showDropdown) {
- setShowAutocomplete(false)
- setShowDropdown(true)
- setShowDropdownNumber(count)
- }
- } else {
- if (showDropdown) {
- setShowDropdown(false)
- }
- }
-
- // bad detection mechanism probably
- if (event.target.value[event.target.value.length-1] === "." && actionlist.length > 0) {
- console.log("GET THE LAST ARGUMENT FOR NODE!")
- // THIS IS AN EXAMPLE OF SHOWING IT
- /*
- const inputdata = {"data": "1.2.3.4", "dataType": "4.5.6.6"}
- setJsonList(GetParsedPaths(inputdata, ""))
- if (!showDropdown) {
- setShowAutocomplete(false)
- setShowDropdown(true)
- setShowDropdownNumber(count)
- }
- console.log(jsonList)
- */
-
- // Search for the item backwards
- // 1. Reverse search backwards from . -> $
- // 2. Search the actionlist for the item
- // 3. Find the data for the specific item
-
- var curstring = ""
- var record = false
- for (var key in selectedActionParameters[count].value) {
- const item = selectedActionParameters[count].value[key]
- if (record) {
- curstring += item
- }
-
- if (item === "$") {
- record = true
- curstring = ""
- }
- }
-
- //console.log("CURSTRING: ", curstring)
- if (curstring.length > 0 && actionlist !== null) {
- // Search back in the action list
- curstring = curstring.split(" ").join("_").toLowerCase()
- var actionItem = actionlist.find(data => data.autocomplete.split(" ").join("_").toLowerCase() === curstring)
- if (actionItem !== undefined) {
- console.log("Found item: ", actionItem)
-
- //actionItem.example = actionItem.example.trim()
- //actionItem.example = actionItem.example.split(" None").join(" \"None\"")
- //actionItem.example = actionItem.example.split("\'").join("\"")
-
- var jsonvalid = true
- try {
- const tmp = String(JSON.parse(actionItem.example))
- if (!actionItem.example.includes("{") && !actionItem.example.includes("[")) {
- jsonvalid = false
- }
- } catch (e) {
- jsonvalid = false
- }
-
- if (jsonvalid) {
- setJsonList(GetParsedPaths(JSON.parse(actionItem.example), ""))
-
- if (!showDropdown) {
- setShowAutocomplete(false)
- setShowDropdown(true)
- setShowDropdownNumber(count)
- }
- }
- }
- }
- } else {
- if (jsonList.length > 0) {
- setJsonList([])
- }
- }
-
- selectedActionParameters[count].value = event.target.value
- selectedAction.parameters[count].value = event.target.value
- setSelectedAction(selectedAction)
- //setUpdate(Math.random())
- //setUpdate(event.target.value)
- }
-
- const changeActionParameterVariable = (fieldvalue, count) => {
- //console.log("CALLED THIS ONE WITH VALUE!", fieldvalue)
- //if (selectedVariableParameter === fieldvalue) {
- // return
- //}
-
- setSelectedVariableParameter(fieldvalue)
-
- selectedActionParameters[count].action_field = fieldvalue
- selectedAction.parameters = selectedActionParameters
-
- setSelectedApp(selectedApp)
- setSelectedAction(selectedAction)
- setUpdate(fieldvalue)
- }
-
- // Sets ACTION_RESULT things
- const changeActionParameterActionResult = (fieldvalue, count) => {
- //cy.nodes().forEach(function( ele ) {
- // if (ele.data()["label"] === fieldvalue) {
- // selectedActionParameters[count].action_field = ele.id()
- // return
- // }
- //});
-
- selectedActionParameters[count].action_field = fieldvalue
- selectedAction.parameters = selectedActionParameters
-
- // FIXME - check if startnode
-
- // Set value
- setSelectedApp(selectedApp)
-
- setSelectedAction(selectedAction)
- setUpdate(Math.random())
- }
-
- const changeActionParameterVariant = (data, count) => {
- selectedActionParameters[count].variant = data
- selectedActionParameters[count].value = ""
-
- if (data === "ACTION_RESULT") {
- var parents = getParents(selectedAction)
- if (parents.length > 0) {
- selectedActionParameters[count].action_field = parents[0].label
- } else {
- selectedActionParameters[count].action_field = ""
- }
- } else if (data === "WORKFLOW_VARIABLE") {
- if (workflow.workflow_variables !== null && workflow.workflow_variables !== undefined && workflow.workflow_variables.length > 0) {
- selectedActionParameters[count].action_field = workflow.workflow_variables[0].name
- }
- }
-
- selectedAction.parameters = selectedActionParameters
-
- // This is a stupid workaround to make it refresh rofl
- setSelectedAction({})
- setSelectedTrigger({})
- setSelectedApp({})
- setSelectedEdge({})
- // FIXME - check if startnode
-
- // Set value
- setSelectedApp(selectedApp)
- setSelectedAction(selectedAction)
- setUpdate(Math.random())
- }
-
- // FIXME: Issue #40 - selectedActionParameters not reset
- if (Object.getOwnPropertyNames(selectedAction).length > 0 && selectedActionParameters.length > 0) {
- return (
-
-
Parameters
- {selectedActionParameters.map((data, count) => {
- if (data.variant === "") {
- data.variant = "STATIC_VALUE"
- }
-
-
- // selectedAction.selectedAuthentication = e.target.value
- // selectedAction.authentication_id = e.target.value.id
- if (!selectedAction.auth_not_required && selectedAction.selectedAuthentication !== undefined && selectedAction.selectedAuthentication.fields !== undefined && selectedAction.selectedAuthentication.fields[data.name] !== undefined) {
- // This sets the placeholder in the frontend. (Replaced in backend)
- selectedActionParameters[count].value = selectedAction.selectedAuthentication.fields[data.name]
- selectedAction.parameters[count].value = selectedAction.selectedAuthentication.fields[data.name]
- setSelectedAction(selectedAction)
- //setUpdate(Math.random())
-
- return null
- }
-
- var staticcolor = "inherit"
- var actioncolor = "inherit"
- var varcolor = "inherit"
- var multiline
- if (data.multiline !== undefined && data.multiline !== null && data.multiline === true) {
- multiline = true
- }
-
- if (data.value !== undefined && data.value !== null && data.value.startsWith("{") && data.value.endsWith("}")) {
- multiline = true
- }
-
- var placeholder = "Static value"
- if (data.example !== undefined && data.example !== null && data.example.length > 0) {
- placeholder = data.example
- }
-
- if (data.name.startsWith("${") && data.name.endsWith("}")) {
- const paramcheck = selectedAction.parameters.find(param => param.name === "body")
- if (paramcheck !== undefined && paramcheck !== null) {
- if (paramcheck["value_replace"] !== undefined && paramcheck["value_replace"] !== null) {
- //console.log("IN THE VALUE REPLACE: ", paramcheck["value_replace"])
- const subparamindex = paramcheck["value_replace"].findIndex(param => param.key === data.name)
- if (subparamindex !== -1) {
- data.value = paramcheck["value_replace"][subparamindex]["value"]
- }
- }
- }
- }
-
- var disabled = false
- var rows = "5"
- var openApiHelperText = "This is an OpenAPI specific field"
- if (selectedApp.generated && selectedApp.activated && data.name === "body") {
- const regex = /\${(\w+)}/g
- const found = placeholder.match(regex)
- if (found === null) {
- //setExtraBodyFields([])
- } else {
- rows = "1"
- disabled = true
- openApiHelperText = "OpenAPI spec: fill the following fields."
- //console.log("SHOULD ADD TO selectedActionParameters!: ", found, selectedActionParameters)
- var changed = false
- for (var specKey in found) {
- const tmpitem = found[specKey]
- var skip = false
- for (var innerkey in selectedActionParameters) {
- if (selectedActionParameters[innerkey].name === tmpitem) {
- skip = true
- break
- }
- }
-
- if (skip) {
- //console.log("SKIPPING ", tmpitem)
- continue
- }
-
- changed = true
- selectedActionParameters.push({
- action_field: "",
- configuration: false,
- description: "Generated by OpenAPI body example",
- example: "",
- id: "",
- multiline: false,
- name: tmpitem,
- options: null,
- required: false,
- schema: {type: "string"},
- skip_multicheck: false,
- tags: null,
- value: "",
- variant: "STATIC_VALUE",
- })
- }
-
- if (changed) {
- setSelectedActionParameters(selectedActionParameters)
- }
-
- return
- }
- }
-
- //console.log("Data: ", data)
- var datafield =
-
-
- {
- setMenuPosition({
- top: event.pageY+10,
- left: event.pageX+10,
- })
- setShowDropdownNumber(count)
- setShowDropdown(true)
- setShowAutocomplete(true)
- }}/>
-
-
- )
- }}
- fullWidth
- multiline={multiline}
- rows={rows}
- color="primary"
- defaultValue={data.value}
- type={placeholder.includes("***") ? "password" : "text"}
- placeholder={placeholder}
- onChange={(event) => {
- changeActionParameter(event, count, data)
- }}
- helperText={selectedApp.generated && selectedApp.activated && data.name === "body" ?
-
- {openApiHelperText}
-
- :
- data.name.startsWith("${") && data.name.endsWith("}") ?
-
- OpenAPI helperfield
-
- :
- null
- }
- onBlur={(event) => {
- // Super basic check
- //if (event.target.value.startsWith("{")) {
- // console.log("VALIDATING JSON")
- // try {
- // JSON.parse(event.target.value)
- // } catch (e) {
- // alert.error("Failed to parse json: ", e)
- // }
- //}
- }}
- />
-
- if (selectedActionParameters[count].schema !== undefined && selectedActionParameters[count].schema !== null && selectedActionParameters[count].schema.type === "file") {
- datafield =
-
-
- {
- setMenuPosition({
- top: event.pageY+10,
- left: event.pageX+10,
- })
- setShowDropdownNumber(count)
- setShowDropdown(true)
- setShowAutocomplete(true)
- }}/>
-
-
- )
- }}
- fullWidth
- multiline={multiline}
- rows="5"
- color="primary"
- defaultValue={data.value}
- type={"text"}
- placeholder={"The file ID to get"}
- onChange={(event) => {
- changeActionParameter(event, count, data)
- }}
- onBlur={(event) => {
- }}
- />
- //const fileId = "6daabec1-892b-469c-b603-c902e47223a9"
- //datafield = `SHOW FILES FROM OTHER NODES? Filename: ${selectedActionParameters[count].value}`
- /*
- if (selectedActionParameters[count].value != fileId) {
- changeActionParameter(fileId, count, data)
- setUpdate(Math.random())
-
- }
- */
- } else if (selectedActionParameters[count].options !== undefined && selectedActionParameters[count].options !== null && selectedActionParameters[count].options.length > 0) {
- if (selectedActionParameters[count].value === "" && selectedActionParameters[count].required) {
- // Rofl, dirty workaround :)
- const e = {
- target: {
- value: selectedActionParameters[count].options[0],
- }
- }
-
- changeActionParameter(e, count, data)
- }
-
- datafield =
-
-
- } else if (data.variant === "STATIC_VALUE") {
- staticcolor = "#f85a3e"
- } else if (data.variant === "ACTION_RESULT") {
- // Gets the parents of the current node
- var parents = getParents(selectedAction)
- actioncolor = "#f85a3e"
- // set the datafield
- //var datafieldvalue = "Error: No parents. Action not eligible"
- //if (parents.length > 0) {
- // datafieldvalue = parents[0].label
- //}
- const fixedActionText = selectedActionParameters[count].value
-
- datafield =
-
-
- Example: $.body will get "data" from {'{"body": "data"}'}
}
- placeholder="Action variable ($.)"
- onChange={(event) => {
- changeActionParameter(event, count, data)
- }}
- />
-
-
- } else if (data.variant === "WORKFLOW_VARIABLE") {
- varcolor = "#f85a3e"
- if ((workflow.workflow_variables === null || workflow.workflow_variables === undefined || workflow.workflow_variables.length === 0) && (workflow.execution_variables === null || workflow.execution_variables === undefined || workflow.execution_variables.length === 0)) {
- setCurrentView(2)
- datafield =
-
-
- Looks like you don't have any variables yet.
-
-
- {
- setVariablesModalOpen(true)
- setLastSaved(false)
- }}>New workflow variable
-
-
- } else {
- // FIXME - this is a shitty solution that needs re-renders all the time
- datafield =
-
- }
- }
-
- // Shows nested list of nodes > their JSON lists
- const ActionlistWrapper = (props) => {
-
- const handleMenuClose = () => {
- setShowAutocomplete(false)
-
- if (!selectedActionParameters[count].value[selectedActionParameters[count].value.length-1] === "$") {
- setShowDropdown(false)
- }
-
- setUpdate(Math.random())
- setMenuPosition(null)
- }
-
- const handleItemClick = (values) => {
- if (values === undefined || values === null || values.length === 0) {
- return
- }
-
- var toComplete = selectedActionParameters[count].value.trim().endsWith("$") ? values[0].autocomplete : "$"+values[0].autocomplete
- for (var key in values) {
- if (key == 0 || values[key].autocomplete.length === 0) {
- continue
- }
-
- toComplete += values[key].autocomplete
- }
-
- // Handles the fields under OpenAPI body to be parsed.
- if (data.name.startsWith("${") && data.name.endsWith("}")) {
- console.log("INSIDE VALUE REPLACE: ", data.name, toComplete)
- // PARAM FIX - Gonna use the ID field, even though it's a hack
- const paramcheck = selectedAction.parameters.find(param => param.name === "body")
- if (paramcheck !== undefined) {
- if (paramcheck["value_replace"] === undefined || paramcheck["value_replace"] === null) {
- paramcheck["value_replace"] = [{
- "key": data.name,
- "value": toComplete,
- }]
-
- } else {
- const subparamindex = paramcheck["value_replace"].findIndex(param => param.key === data.name)
- if (subparamindex === -1) {
- paramcheck["value_replace"].push({
- "key": data.name,
- "value": toComplete,
- })
- } else {
- paramcheck["value_replace"][subparamindex]["value"] += toComplete
- }
- }
-
- selectedActionParameters[count]["value_replace"] = paramcheck
- selectedAction.parameters[count]["value_replace"] = paramcheck
- setSelectedAction(selectedAction)
- setUpdate(Math.random())
-
- setShowDropdown(false)
- setMenuPosition(null)
- return
- }
- }
-
- selectedActionParameters[count].value += toComplete
- selectedAction.parameters[count].value = selectedActionParameters[count].value
- setSelectedAction(selectedAction)
- setUpdate(Math.random())
-
- setShowDropdown(false)
- setMenuPosition(null)
- }
-
- const iconStyle = {
- marginRight: 15,
- }
-
- return (
-
- }
- parentMenuOpen={!!menuPosition}
- style={{backgroundColor: inputColor, color: "white", minWidth: 250,}}
- onClick={() => {
- handleItemClick([innerdata])
- }}
- >
- {parsedPaths.map((pathdata, index) => {
- // FIXME: Should be recursive in here
- const icon = pathdata.type === "value" ?
: pathdata.type === "list" ?
:
- return (
-
- )
-
- })}
-
- :
-
-
- )
- })}
-
- )
- }
-
- var itemColor = "#f85a3e"
- if (!data.required) {
- itemColor = "#ffeb3b"
- }
-
- var tmpitem = data.name.valueOf()
- if (data.name.startsWith("${") && data.name.endsWith("}")) {
- tmpitem = tmpitem.slice(2, data.name.length-1)
- }
-
- tmpitem = tmpitem.charAt(0).toUpperCase()+tmpitem.substring(1)
- tmpitem = tmpitem.replaceAll("_", " ")
- const description = data.description === undefined ? "" : data.description
-
- return (
-
-
-
-
- {data.configuration === true ?
-
- {
- setAuthenticationModalOpen(true)
- }}/>
-
- :
-
- }
-
-
- {tmpitem}
-
-
-
- {/*selectedActionParameters[count].options !== undefined && selectedActionParameters[count].options !== null && selectedActionParameters[count].options.length > 0 ? null :
-
-
- {
- e.preventDefault()
- changeActionParameterVariant("STATIC_VALUE", count)
- }}>
-
-
-
- |
-
- {
- e.preventDefault()
- changeActionParameterVariant("ACTION_RESULT", count)
- }}>
-
-
-
- |
-
- {
- e.preventDefault()
- changeActionParameterVariant("WORKFLOW_VARIABLE", count)
- }}>
-
-
-
-
- */}
- {selectedActionParameters[count].options !== undefined && selectedActionParameters[count].options !== null && selectedActionParameters[count].options.length > 0 && selectedActionParameters[count].required === true && selectedActionParameters[count].unique_toggled !== undefined ? null :
-
-
- {}}>
- {
- //console.log("CHECKED!: ", selectedActionParameters[count])
- selectedActionParameters[count].unique_toggled = !selectedActionParameters[count].unique_toggled
- selectedAction.parameters[count].unique_toggled = selectedActionParameters[count].unique_toggled
- setSelectedActionParameters(selectedActionParameters)
- setSelectedAction(selectedAction)
- setUpdate(Math.random())
- }}
- name="requires_unique"
- />
-
-
-
- }
-
- {datafield}
- {showDropdown && showDropdownNumber === count && data.variant === "STATIC_VALUE" && jsonList.length > 0 ?
-
- Autocomplete
-
-
- : null}
- {showDropdown && showDropdownNumber === count && data.variant === "STATIC_VALUE" && jsonList.length === 0 ?
-
- : null}
-
-
-
- )})}
-
- )
- }
- return null
- }
+
//height: "100%",
const appApiViewStyle = {
@@ -4148,49 +3124,7 @@ const AngularWorkflow = (props) => {
overflow: "auto",
}
- const defineStartnode = () => {
- var oldstartnode = cy.getElementById(workflow.start)
- if (oldstartnode.length > 0) {
- oldstartnode[0].data("isStartNode", false)
- var oldnodecnt = workflow.actions.findIndex(a => a.id === workflow.start)
- if (workflow.actions[oldnodecnt] !== undefined) {
- workflow.actions[oldnodecnt].isStartNode = false
- }
- }
-
- var newstartnode = cy.getElementById(selectedAction.id)
- if (newstartnode.length > 0) {
- newstartnode[0].data("isStartNode", true)
- var newnodecnt = workflow.actions.findIndex(a => a.id === selectedAction.id)
- console.log("NEW NODE CNT: ", newnodecnt)
- if (workflow.actions[newnodecnt] !== undefined) {
- workflow.actions[newnodecnt].isStartNode = true
- console.log(workflow.actions[newnodecnt])
- }
- }
-
- // Find branches with triggers as source nodes
- // Move these targets to be the new node
- // Set arrows pointing to new startnode with errors
- //for (var key in workflow.branches) {
- // var item = workflow.branches[key]
- // if (item.destination_id === oldstartnode[0].data()["id"]) {
- // var curbranch = cy.getElementById(item.id)
- // if (curbranch.length > 0) {
- // //console.log(curbranch[0].data())
- // //curbranch[0].data("target", selectedAction.id)
- // //curbranch[0].data("hasErrors", true)
- // //workflow.branches[key].destination_id = selectedAction.id
- // //console.log(curbranch[0].data())
- // }
- // }
- //}
-
- setUpdate("start_node"+selectedAction.id)
- workflow.start = selectedAction.id
- setWorkflow(workflow)
- //setStartNode(selectedAction.id)
- }
+
function sortByKey(array, key) {
if (array === undefined) {
@@ -4226,353 +3160,43 @@ const AngularWorkflow = (props) => {
zIndex: 1000,
}
- const textFieldStyle = {
- backgroundColor: inputColor,
- borderRadius: borderRadius,
- }
-
- const getApp = (appId, setApp) => {
- fetch(globalUrl+"/api/v1/apps/"+appId+"/config?openapi=false", {
- headers: {
- 'Accept': 'application/json',
- },
- credentials: "include",
- })
- .then((response) => {
- if (response.status === 200) {
- //alert.success("Successfully GOT app "+appId)
- } else {
- alert.error("Failed getting app")
- }
-
- return response.json()
- })
- .then((responseJson) => {
- if (setApp && responseJson.actions !== undefined && responseJson.actions !== null) {
- if (selectedApp.versions !== undefined && selectedApp.versions !== null) {
- responseJson.versions = selectedApp.versions
- }
-
- if (selectedApp.loop_versions !== undefined && selectedApp.loop_versions !== null) {
- responseJson.loop_versions = selectedApp.loop_versions
- }
-
- var foundAction = responseJson.actions.find(action => action.name === selectedAction.name)
- if (foundAction !== null && foundAction !== undefined) {
- for (var paramkey in foundAction.parameters) {
- const param = foundAction.parameters[paramkey]
-
- const foundParam = selectedAction.parameters.find(item => item.name === param.name)
- if (foundParam === undefined) {
- //console.log("COULDNT find Param: ", param)
- } else {
- foundAction.parameters[paramkey] = foundParam
- }
- }
- } else {
- alert.error("Couldn't find action "+selectedAction.name)
- }
-
- // Updating params for the new action
- selectedAction.parameters = foundAction.parameters
- selectedAction.app_id = appId
- selectedAction.app_version = responseJson.app_version
-
- setSelectedAction(selectedAction)
- setSelectedApp(responseJson)
- }
- })
- .catch(error => {
- alert.error(error.toString())
- });
- }
-
- const innerTextfieldStyle = {
- color: "white",
- minHeight: 50,
- marginLeft: "5px",
- maxWidth: "95%",
- fontSize: "1em",
- borderRadius: borderRadius,
- }
-
const appApiView = Object.getOwnPropertyNames(selectedAction).length > 0 ?
-
-
-
-
{selectedAction.app_name.replaceAll("_", " ")}
-
-
{
- console.log("FIND EXAMPLE RESULTS FOR ", selectedAction)
- if (workflowExecutions.length > 0) {
- // Look for the ID
- const found = false
- for (var key in workflowExecutions) {
- if (workflowExecutions[key].results === undefined || workflowExecutions[key].results === null) {
- continue
- }
-
- var foundResult = workflowExecutions[key].results.find(result => result.action.id === selectedAction.id)
- if (foundResult === undefined || foundResult === null) {
- continue
- }
-
- setSelectedResult(foundResult)
- setCodeModalOpen(true)
- break
- }
- }
- }}>
-
-
-
-
-
- What are actions?
- {selectedAction.errors !== null && selectedAction.errors.length > 0 ?
-
- Errors: {selectedAction.errors.join("\n")}
-
- : null
- }
-
-
-
-
- {selectedAction.id === workflow.start ? null :
-
- {
- defineStartnode(e)
- }}>
-
-
-
- }
- {selectedApp.versions !== null && selectedApp.versions !== undefined && selectedApp.versions.length > 0 ?
-
- : null }
-
-
-
-
- Name
-
-
- {selectedApp.name !== undefined && selectedAction.authentication !== undefined && selectedAction.authentication.length === 0 && requiresAuthentication ?
-
-
-
- {
- setAuthenticationModalOpen(true)
- }}>
- Authenticate {selectedApp.name}
-
-
-
-
- : null}
- {selectedAction.authentication !== undefined && selectedAction.authentication.length > 0 ?
-
- Authentication
-
-
-
- {/*
-
-
setAuthenticationModalOpen(true)}>
- AUTHENTICATE
-
- curaction.authentication = authenticationOptions
- if (curaction.selectedAuthentication === null || curaction.selectedAuthentication === undefined || curaction.selectedAuthentication.length === "")
- */}
-
- {
- setAuthenticationModalOpen(true)
- }}>
-
-
-
-
-
- : null}
- {showEnvironment ?
-
-
- Environment
-
-
-
- : null}
- {workflow.execution_variables !== undefined && workflow.execution_variables !== null && workflow.execution_variables.length > 0 ?
-
- Set execution variable (optional)
-
-
- : null}
-
-
-
- Actions
-
-
- {selectedAction.description !== undefined && selectedAction.description.length > 0 ?
-
- {selectedAction.description}
-
: null}
-
-
-
-
-
-
- : null
+
+
+ :
+ null
const setTriggerFolderWrapperMulti = event => {
const { options } = event.target
@@ -4763,7 +3387,7 @@ const AngularWorkflow = (props) => {
var datafield =
{
Name
{
Environment:
{
Name
{
{
{
Name
{
{
var copyText = document.getElementById("webhook_uri_field");
@@ -6224,7 +4848,7 @@ const AngularWorkflow = (props) => {
Name
{
Environment:
{
{
{workflow.triggers[selectedTriggerIndex].parameters[2] !== undefined && workflow.triggers[selectedTriggerIndex].parameters[2].value.includes("email") ?
{
}
{workflow.triggers[selectedTriggerIndex].parameters[2] !== undefined && workflow.triggers[selectedTriggerIndex].parameters[2].value.includes("sms") ?
{
Name
{
{
{
{
-
-
- cy.fit(null, 50)}>
-
-
-
-
-
-
- {
- removeNode()
- }}>
-
-
-
-
-
-
- {
- setExecutionModalOpen(true)
- getWorkflowExecution(props.match.params.key, "")
- }}>
-
-
-
-
{workflow.public ?
@@ -6830,6 +5428,32 @@ const AngularWorkflow = (props) => {
: null}
+
+
+ cy.fit(null, 50)}>
+
+
+
+
+
+
+ {
+ removeNode()
+ }}>
+
+
+
+
+
+
+ {
+ setExecutionModalOpen(true)
+ getWorkflowExecution(props.match.params.key, "")
+ }}>
+
+
+
+
{/* */}
{workflow.configuration !== null && workflow.configuration !== undefined && workflow.configuration.exit_on_error !== undefined ? : null}
@@ -7942,7 +6566,7 @@ const AngularWorkflow = (props) => {
Name - what is this used for?
{
{data.name}
{
The API endpoint to use (URL) - predefined in the app