diff --git a/frontend/src/components/ParsedAction.jsx b/frontend/src/components/ParsedAction.jsx
index 1db53973..95a9ad4e 100755
--- a/frontend/src/components/ParsedAction.jsx
+++ b/frontend/src/components/ParsedAction.jsx
@@ -180,9 +180,8 @@ const ParsedAction = (props) => {
const [fieldCount, setFieldCount] = React.useState(0);
const [hiddenDescription, setHiddenDescription] = React.useState(true);
-
const [autoCompleting, setAutocompleting] = React.useState(false);
- const [selectedActionParameters, setSelectedActionParameters] = React.useState([]);
+ const [selectedActionParameters, setSelectedActionParameters] = React.useState(selectedAction.parameters);
const [selectedVariableParameter, setSelectedVariableParameter] = React.useState("");
const [actionlist, setActionlist] = React.useState([]);
const [jsonList, setJsonList] = React.useState([]);
@@ -382,9 +381,12 @@ const ParsedAction = (props) => {
useEffect(
() => {
+ console.log("UseEffect Rendered!")
+ console.log("Workflow", workflow)
// if (selectedActionParameters !== undefined && selectedActionParameters !== null
// ) {
if (selectedAction.parameters !== undefined && selectedAction.parameters !== null && selectedAction.parameters.length > 0) {
+ console.log("Setting action parameters!!")
setSelectedActionParameters(selectedAction.parameters);
// }
}
@@ -614,9 +616,13 @@ const ParsedAction = (props) => {
}
}
},
- [selectedAction, selectedVariableParameter, workflowExecutions, listCache]);
-
-
+ [selectedAction,selectedApp,setNewSelectedAction]
+ );
+ console.log("selectedActionParameters: ", selectedActionParameters)
+ console.log("selectedApp:", selectedApp)
+ console.log("selectedAction: ", selectedAction)
+ console.log("ACTIONLIST: ", actionlist)
+ console.log("selectedVariableParameter", selectedVariableParameter)
const calculateHelpertext = (input_data) => {
var helperText = ""
var looperText = ""
@@ -1184,7 +1190,7 @@ const ParsedAction = (props) => {
}
// FIXME: Issue #40 - selectedActionParameters not reset
-
+ if (Object.getOwnPropertyNames(selectedAction).length > 0 && selectedActionParameters.length > 0) {
var wrapperapp = {
"id": "",
"name": "noapp",
@@ -1210,15 +1216,16 @@ const ParsedAction = (props) => {
var authWritten = false;
var noAppSelected = false
- const paramIndex = selectedAction.parameters.findIndex((param) => param.name === "app_name")
+ var paramIndex = selectedAction.parameters.findIndex((param) => param.name === "app_name")
if (paramIndex === -1 || selectedAction.parameters[paramIndex].value === "" || selectedAction.parameters[paramIndex].value === "noapp") {
// Check the actual value and if it's the same
noAppSelected = true
}
+ }
const ActionSelectOption = (actionprops) => {
- const { data, newActionname, newActiondescription, useIcon, extraDescription, } = actionprops;
+ const { option, newActionname, newActiondescription, useIcon, extraDescription, } = actionprops;
const [hover, setHover] = React.useState(false);
return (
@@ -1234,18 +1241,20 @@ const ParsedAction = (props) => {
paddingBottom: 4,
backgroundColor: hover ? theme.palette.surfaceColor : theme.palette.inputColor,
}} onMouseEnter={() => setHover(true)} onMouseLeave={() => setHover(false)}
- onClick={() => {
+ onClick={(event) => {
+ // event.preventDefault()
//setSelectedAction(actionprops)
//setShowActionList(false)
//setUpdate(Math.random())
//
- if (data !== undefined && data !== null) {
+ if (option !== undefined && option !== null) {
setNewSelectedAction({
target: {
- value: data.name
+ value: option.name
}
});
}
+ document.activeElement.blur();
}}
>
@@ -1308,7 +1317,7 @@ const ParsedAction = (props) => {
const selectedAppIcon = selectedAction.large_image
- console.log("Selected action: ", selectedAction)
+// console.log("Selected action: ", selectedAction)
console.log("Selected action paramaters: ", selectedAction.parameters)
var baselabel = selectedAction.label
return (
@@ -2220,54 +2229,55 @@ const ParsedAction = (props) => {
}
});
}
- }}
- renderOption={(props, data, state) => {
- var newActionname = data.name;
- if (data.label !== undefined && data.label !== null && data.label.length > 0) {
- newActionname = data.label;
+ event.target.blur();
+ }}
+ renderOption={(props, option, state) => {
+ var newActionname = option.name;
+ if (option.label !== undefined && option.label !== null && option.label.length > 0) {
+ newActionname = option.label;
}
- var newActiondescription = data.description;
+ var newActiondescription = option.description;
//console.log("DESC: ", newActiondescription)
- if (data.description === undefined || data.description === null) {
+ if (option.description === undefined || option.description === null) {
newActiondescription = "Description: No description defined for this action"
} else {
newActiondescription = "Description: "+newActiondescription
}
- const iconInfo = GetIconInfo({ name: data.name });
+ const iconInfo = GetIconInfo({ name: option.name });
const useIcon = iconInfo.originalIcon;
if (newActionname === undefined || newActionname === null) {
newActionname = "No name"
- data.name = "No name"
- data.label = "No name"
+ option.name = "No name"
+ option.label = "No name"
}
newActionname = (newActionname.charAt(0).toUpperCase() + newActionname.substring(1)).replaceAll("_", " ");
var method = ""
var extraDescription = ""
- if (data.name.includes("get_")) {
+ if (option.name.includes("get_")) {
method = "GET"
- } else if (data.name.includes("post_")) {
+ } else if (option.name.includes("post_")) {
method = "POST"
- } else if (data.name.includes("put_")) {
+ } else if (option.name.includes("put_")) {
method = "PUT"
- } else if (data.name.includes("patch_")) {
+ } else if (option.name.includes("patch_")) {
method = "PATCH"
- } else if (data.name.includes("delete_")) {
+ } else if (option.name.includes("delete_")) {
method = "DELETE"
- } else if (data.name.includes("options_")) {
+ } else if (option.name.includes("options_")) {
method = "OPTIONS"
- } else if (data.name.includes("connect_")) {
+ } else if (option.name.includes("connect_")) {
method = "CONNECT"
}
// FIXME: Should it require a base URL?
- if (method.length > 0 && data.description !== undefined && data.description !== null && data.description.includes("http")) {
+ if (method.length > 0 && option.description !== undefined && option.description !== null && option.description.includes("http")) {
var extraUrl = ""
- const descSplit = data.description.split("\n")
+ const descSplit = option.description.split("\n")
// Last line of descSplit
if (descSplit.length > 0) {
extraUrl = descSplit[descSplit.length-1]
@@ -2306,7 +2316,8 @@ const ParsedAction = (props) => {
return (
{
//const data = JSON.parse(JSON.stringify(event.target.data()))
const data = event.target.data()
-
+ console.log("===============================Node selected=============================")
console.log("NODE SELECT: ", data)
if (data.app_name === "Shuffle Workflow") {
@@ -8567,11 +8567,15 @@ const AngularWorkflow = (defaultprops) => {
);
};
- const handleSetTab = (event, newValue) => {
- setCurrentView(newValue);
- };
+
const HandleLeftView = () => {
+ // console.log("HandleLeftView Rendered!")
+
+ const handleSetTab = (event, newValue) => {
+ setCurrentView(newValue);
+ };
+
// Defaults to apps.
var thisview = (
{
)
}
-
-
- const TriggersView = () => {
- const triggersViewStyle = {
- marginLeft: 10,
- marginRight: 10,
- display: "flex",
- flexDirection: "column",
- }
-
- // Predefined hurr
- return (
-
-
- {triggers.map((trigger, index) => {
-
- /*
- if (trigger.trigger_type === "PIPELINE") {
- if (userdata.support !== true) {
- return null
- }
- }
- */
-
- // Hiding since March 2024
- if (trigger.trigger_type === "EMAIL") {
- return null
- }
-
- const imagesize = isMobile ? 40 : trigger.large_image.includes("svg") ? 50 : 50
- var imageline = trigger.large_image.length === 0 ?
![]()
- :
-

-
- const title = trigger.trigger_type === "WEBHOOK" ? "Workflow starters" : trigger.trigger_type === "SUBFLOW" ? "Mid-Workflow" : ""
-
- const color = trigger.is_valid ? green : yellow;
- return (
-
- {title.length > 0 ?
-
- {title}
-
- : null}
-
- {
- handleTriggerDrag(e, trigger);
- }}
- onStop={(e) => {
- handleDragStop(e);
- }}
- dragging={false}
- position={{
- x: 0,
- y: 0,
- }}
- >
- { }}>
-
-
-
- {imageline}
-
- {isMobile ? null :
-
-
-
- {trigger.name}
-
-
-
-
- {trigger.description}
-
-
-
- }
-
-
-
-
- );
- })}
-
-
- );
- };
-
- var newNodeId = "";
- var parsedApp = {};
- const handleTriggerDrag = (e, data) => {
- const cycontainer = cy.container();
- // Chrome lol
- if (
- e.pageX > cycontainer.offsetLeft &&
- e.pageX < cycontainer.offsetLeft + cycontainer.offsetWidth &&
- e.pageY > cycontainer.offsetTop &&
- e.pageY < cycontainer.offsetTop + cycontainer.offsetHeight
- ) {
- if (newNodeId.length > 0) {
- var currentnode = cy.getElementById(newNodeId);
- if (currentnode.length === 0) {
- return;
- }
-
- currentnode[0].renderedPosition("x", e.pageX - cycontainer.offsetLeft);
- currentnode[0].renderedPosition("y", e.pageY - cycontainer.offsetTop);
- } else {
- if (workflow.start === "" || workflow.start === undefined) {
- toast("Define a starting action first.");
- return;
- }
-
- const triggerLabel = getNextActionName(data.name);
-
- newNodeId = uuidv4();
- const newposition = {
- x: e.pageX - cycontainer.offsetLeft,
- y: e.pageY - cycontainer.offsetTop,
- };
-
- const newAppData = {
- app_name: data.name,
- app_version: "1.0.0",
- environment: isCloud ? "cloud" : data.environment,
- description: data.description,
- long_description: data.long_description,
- errors: [],
- id_: newNodeId,
- _id_: newNodeId,
- id: newNodeId,
- finished: false,
- label: triggerLabel,
- type: data.type,
- is_valid: true,
- trigger_type: data.trigger_type,
- large_image: data.large_image,
- status: "uninitialized",
- name: data.name,
- isStartNode: false,
- position: newposition,
- };
-
- // Can all the data be in here? hmm
- const nodeToBeAdded = {
- group: "nodes",
- data: newAppData,
- renderedPosition: newposition,
- };
-
- cy.add(nodeToBeAdded);
- parsedApp = nodeToBeAdded;
- return;
- }
- }
- };
-
- const handleDragStop = (e, app) => {
- var currentnode = cy.getElementById(newNodeId);
- if (
- currentnode === undefined ||
- currentnode === null ||
- currentnode.length === 0
- ) {
- return;
- }
-
- // Using remove & replace, as this triggers the function
- // onNodeAdded() with this node after it's added
-
- currentnode.remove();
- parsedApp.data.finished = true;
- parsedApp.data.position = currentnode.renderedPosition();
- parsedApp.position = currentnode.renderedPosition();
- parsedApp.renderedPosition = currentnode.renderedPosition();
-
- var newAppData = parsedApp.data;
- if (newAppData.type === "ACTION") {
-
- //const activateApp = (appid) => {
- if (newAppData.activated === false) {
- activateApp(newAppData.app_id, false)
- }
-
- // AUTHENTICATION
- if (app.authentication !== undefined && app.authentication !== null && app.authentication.required === true) {
-
- // Setup auth here :)
- const authenticationOptions = [];
- var findAuthId = "";
- if (
- newAppData.authentication_id !== null &&
- newAppData.authentication_id !== undefined &&
- newAppData.authentication_id.length > 0
- ) {
- findAuthId = newAppData.authentication_id;
- }
-
- const tmpAuth = JSON.parse(JSON.stringify(appAuthentication));
- for (let authkey in tmpAuth) {
- if (authkey === undefined) {
- continue
- }
-
- var item = tmpAuth[authkey];
- const newfields = {};
- for (let fieldkey in item.fields) {
- if (item.fields[fieldkey] === undefined) {
- console.log("Problem with filterkey in Node select", fieldkey)
- continue
- }
-
- const filterkey = item.fields[fieldkey]["key"]
- if (filterkey === null || filterkey === undefined) {
- console.log("Problem with filterkey 2. Null or undefined 3")
- continue
- }
-
- newfields[filterkey] = item.fields[fieldkey]["value"];
- }
-
- item.fields = newfields;
- if (item.app.id === app.id || item.app.name === app.name) {
- authenticationOptions.push(item);
-
- if (item.id === findAuthId) {
- newAppData.selectedAuthentication = item
- newAppData.authentication_id = item.id
-
- } else if (findAuthId === "") {
- // Will always be set to the last one if one isn't found.
- // Last = timestamp too
- newAppData.selectedAuthentication = item
- newAppData.authentication_id = item.id
- }
- }
- }
-
- if (
- authenticationOptions !== undefined &&
- authenticationOptions !== null &&
- authenticationOptions.length > 0
- ) {
- for (let authkey in authenticationOptions) {
- const option = authenticationOptions[authkey];
-
- if (option.active && newAppData.authentication_id === "") {
- newAppData.selectedAuthentication = option;
- newAppData.authentication_id = option.id;
- break;
- }
- }
- }
- } else {
- newAppData.authentication = [];
- newAppData.authentication_id = "";
- newAppData.selectedAuthentication = {};
- }
-
- parsedApp.data = newAppData;
- cy.add(parsedApp);
- } else if (newAppData.type === "TRIGGER") {
- cy.add(parsedApp);
- }
-
- newNodeId = "";
- parsedApp = {};
- };
-
- const barHeight = bodyHeight - appBarSize - 50;
- const appScrollStyle = {
- overflow: "scroll",
- maxHeight: isMobile ? bodyHeight - appBarSize * 4 : barHeight,
- minHeight: isMobile ? bodyHeight - appBarSize * 4 : barHeight,
- marginTop: 1,
- overflowY: "auto",
- overflowX: "hidden",
- }
-
- const handleAppDrag = (e, app) => {
- const cycontainer = cy.container();
-
-
- if (app.type === "TRIGGER") {
- handleTriggerDrag(e, app)
- return
- }
-
- //console.log("e: ", e)
- //console.log("Offset: ", cycontainer)
-
- // Chrome lol
- if (
- e.pageX > cycontainer.offsetLeft &&
- e.pageX < cycontainer.offsetLeft + cycontainer.offsetWidth &&
- e.pageY > cycontainer.offsetTop &&
- e.pageY < cycontainer.offsetTop + cycontainer.offsetHeight
- ) {
- if (newNodeId.length > 0) {
- var currentnode = cy.getElementById(newNodeId);
- if (
- currentnode === undefined ||
- currentnode === null ||
- currentnode.length === 0
- ) {
- return;
- }
-
- currentnode[0].renderedPosition("x", e.pageX - cycontainer.offsetLeft)
- currentnode[0].renderedPosition("y", e.pageY - cycontainer.offsetTop)
- } else {
- if (workflow.public) {
- console.log("workflow is public - not adding")
- return;
- }
-
- if (app.actions === undefined || app.actions === null) {
- app.actions = []
- }
-
- /*
- if (app.actions === undefined || app.actions === null || app.actions.length === 0) {
- toast("App " + app.name + " currently has no actions to perform. Please go to https://shuffler.io/apps to edit it.")
-
- return
- }
- */
-
- newNodeId = uuidv4();
- const actionType = "ACTION";
- const actionLabel = getNextActionName(app.name);
- //console.log("Next action name: ", actionLabel)
- var parameters = null;
- var example = "";
- var description = ""
-
- const startIndex = app.actions.findIndex((action) => action.category_label !== undefined && action.category_label !== null && action.category_label.length > 0)
- const actionIndex = startIndex < 0 ? 0 : startIndex
-
- // Make the first action the most relevant one for them based on previous use
- if (
- app.actions[actionIndex].parameters !== undefined &&
- app.actions[actionIndex].parameters !== null &&
- app.actions[actionIndex].parameters.length > 0
- ) {
- parameters = app.actions[actionIndex].parameters;
- for (let paramkey in parameters) {
- // Check if parameter.name == "headers" and if it includes "=undefined". If it does, set the value to example if it exists, otherwise empty
- if (parameters[paramkey].name === "headers" && parameters[paramkey].value.includes("=undefined")) {
- if (parameters[paramkey].example !== undefined && parameters[paramkey].example !== null && parameters[paramkey].example.length > 0) {
- parameters[paramkey].value = parameters[paramkey].example
- } else {
- parameters[paramkey].value = ""
- }
- }
- }
-
- //parameters = app.actions[0].parameters;
- }
-
- if (
- app.actions[actionIndex].returns !== undefined &&
- app.actions[actionIndex].returns !== null &&
- app.actions[actionIndex].returns.example !== undefined &&
- app.actions[actionIndex].returns.example !== null &&
- app.actions[actionIndex].returns.example.length > 0
- ) {
- example = app.actions[actionIndex].returns.example;
- }
-
- if (
- app.actions[actionIndex].description !== undefined &&
- app.actions[actionIndex].description !== null &&
- app.actions[actionIndex].description.length > 0
- ) {
- description = app.actions[actionIndex].description
- }
-
- var parsedEnvironments =
- environments === null || environments === []
- ? "cloud"
- : environments[defaultEnvironmentIndex] === undefined
- ? "cloud"
- : environments[defaultEnvironmentIndex].Name
-
- // Basic automatic auth mapping
- var authId = ""
- if (appAuthentication !== undefined && appAuthentication !== null && appAuthentication.length > 0) {
- const appname = app.name.toLowerCase().replace(" ", "_")
- for (var key in appAuthentication) {
- const authKey = appAuthentication[key]
- if (authKey.app.id === app.id) {
- authId = authKey.id
- break
- }
-
- const appauthname = authKey.app.name.toLowerCase().replace(" ", "_")
- if (appauthname === appname) {
- authId = authKey.id
- }
- }
- }
-
- // List other nodes in the workflow and see if they have an environment set. If they do, use that as the default
- if (cy !== undefined && cy !== null) {
- const foundnodes = cy.nodes().jsons()
- if (foundnodes !== undefined && foundnodes !== null && foundnodes.length > 0) {
- // As they should all be the same, this is just an override
- for (let nodekey in foundnodes) {
- const curnode = foundnodes[nodekey]
- if (curnode.data.environment !== undefined && curnode.data.environment !== null && curnode.data.environment.length > 0) {
- parsedEnvironments = curnode.data.environment
- break
- }
- }
- }
- }
-
- const newAppData = {
- name: app.actions[actionIndex].name,
- label: actionLabel,
- app_name: app.name,
- app_version: app.app_version,
- app_id: app.id,
- sharing: app.sharing,
- private_id: app.private_id,
- description: description,
- environment: parsedEnvironments,
- errors: [],
- finished: false,
- id_: newNodeId,
- _id_: newNodeId,
- id: newNodeId,
- is_valid: true,
- type: actionType,
- parameters: parameters,
- isStartNode: false,
- large_image: app.large_image,
- run_magic_output: false,
- authentication: [],
- execution_variable: undefined,
- example: example,
- required_body_fields: app.actions[actionIndex].required_body_fields,
- category:
- app.categories !== null &&
- app.categories !== undefined &&
- app.categories.length > 0
- ? app.categories[0]
- : "",
- authentication_id: authId,
- finished: false,
- template: app.template === true ? true : false,
- };
-
- // FIXME: overwrite category if the ACTION chosen has a different category
- //
-
- if (!isCloud && (!app.is_valid || (!app.activated && app.generated))) {
- console.log("NOT VALID: Activate!")
-
- activateApp(app.id, false)
- }
-
- // const image = "url("+app.large_image+")"
- // FIXME - find the cytoscape offset position
- // Can this be done with zoom calculations?
- const nodeToBeAdded = {
- group: "nodes",
- data: newAppData,
- renderedPosition: {
- x: e.pageX - cycontainer.offsetLeft,
- y: e.pageY - cycontainer.offsetTop,
- },
- };
-
- parsedApp = nodeToBeAdded;
- cy.add(nodeToBeAdded);
- return;
- }
- }
- };
-
const AppView = (props) => {
const { allApps, prioritizedApps, filteredApps, extraApps } = props;
-
+ // console.log("AppView Rendered!")
//extraApps,
const [visibleApps, setVisibleApps] = React.useState(
Array.prototype.concat.apply(
@@ -9833,8 +9323,505 @@ const AngularWorkflow = (defaultprops) => {
);
+}
+
+ const TriggersView = () => {
+ console.log("TriggerView Rendered!")
+ const triggersViewStyle = {
+ marginLeft: 10,
+ marginRight: 10,
+ display: "flex",
+ flexDirection: "column",
+ }
+
+ // Predefined hurr
+ return (
+
+
+ {triggers.map((trigger, index) => {
+
+ /*
+ if (trigger.trigger_type === "PIPELINE") {
+ if (userdata.support !== true) {
+ return null
+ }
+ }
+ */
+
+ // Hiding since March 2024
+ if (trigger.trigger_type === "EMAIL") {
+ return null
+ }
+
+ const imagesize = isMobile ? 40 : trigger.large_image.includes("svg") ? 50 : 50
+ var imageline = trigger.large_image.length === 0 ?
![]()
+ :
+

+
+ const title = trigger.trigger_type === "WEBHOOK" ? "Workflow starters" : trigger.trigger_type === "SUBFLOW" ? "Mid-Workflow" : ""
+
+ const color = trigger.is_valid ? green : yellow;
+ return (
+
+ {title.length > 0 ?
+
+ {title}
+
+ : null}
+
+ {
+ handleTriggerDrag(e, trigger);
+ }}
+ onStop={(e) => {
+ handleDragStop(e);
+ }}
+ dragging={false}
+ position={{
+ x: 0,
+ y: 0,
+ }}
+ >
+ { }}>
+
+
+
+ {imageline}
+
+ {isMobile ? null :
+
+
+
+ {trigger.name}
+
+
+
+
+ {trigger.description}
+
+
+
+ }
+
+
+
+
+ );
+ })}
+
+
+ );
+ }
+
+ var newNodeId = "";
+ var parsedApp = {};
+ const handleTriggerDrag = (e, data) => {
+ const cycontainer = cy.container();
+ // Chrome lol
+ if (
+ e.pageX > cycontainer.offsetLeft &&
+ e.pageX < cycontainer.offsetLeft + cycontainer.offsetWidth &&
+ e.pageY > cycontainer.offsetTop &&
+ e.pageY < cycontainer.offsetTop + cycontainer.offsetHeight
+ ) {
+ if (newNodeId.length > 0) {
+ var currentnode = cy.getElementById(newNodeId);
+ if (currentnode.length === 0) {
+ return;
+ }
+
+ currentnode[0].renderedPosition("x", e.pageX - cycontainer.offsetLeft);
+ currentnode[0].renderedPosition("y", e.pageY - cycontainer.offsetTop);
+ } else {
+ if (workflow.start === "" || workflow.start === undefined) {
+ toast("Define a starting action first.");
+ return;
+ }
+
+ const triggerLabel = getNextActionName(data.name);
+
+ newNodeId = uuidv4();
+ const newposition = {
+ x: e.pageX - cycontainer.offsetLeft,
+ y: e.pageY - cycontainer.offsetTop,
+ };
+
+ const newAppData = {
+ app_name: data.name,
+ app_version: "1.0.0",
+ environment: isCloud ? "cloud" : data.environment,
+ description: data.description,
+ long_description: data.long_description,
+ errors: [],
+ id_: newNodeId,
+ _id_: newNodeId,
+ id: newNodeId,
+ finished: false,
+ label: triggerLabel,
+ type: data.type,
+ is_valid: true,
+ trigger_type: data.trigger_type,
+ large_image: data.large_image,
+ status: "uninitialized",
+ name: data.name,
+ isStartNode: false,
+ position: newposition,
+ };
+
+ // Can all the data be in here? hmm
+ const nodeToBeAdded = {
+ group: "nodes",
+ data: newAppData,
+ renderedPosition: newposition,
+ };
+
+ cy.add(nodeToBeAdded);
+ parsedApp = nodeToBeAdded;
+ return;
+ }
+ }
};
+ const handleDragStop = (e, app) => {
+ var currentnode = cy.getElementById(newNodeId);
+ if (
+ currentnode === undefined ||
+ currentnode === null ||
+ currentnode.length === 0
+ ) {
+ return;
+ }
+
+ // Using remove & replace, as this triggers the function
+ // onNodeAdded() with this node after it's added
+
+ currentnode.remove();
+ parsedApp.data.finished = true;
+ parsedApp.data.position = currentnode.renderedPosition();
+ parsedApp.position = currentnode.renderedPosition();
+ parsedApp.renderedPosition = currentnode.renderedPosition();
+
+ var newAppData = parsedApp.data;
+ if (newAppData.type === "ACTION") {
+
+ //const activateApp = (appid) => {
+ if (newAppData.activated === false) {
+ activateApp(newAppData.app_id, false)
+ }
+
+ // AUTHENTICATION
+ if (app.authentication !== undefined && app.authentication !== null && app.authentication.required === true) {
+
+ // Setup auth here :)
+ const authenticationOptions = [];
+ var findAuthId = "";
+ if (
+ newAppData.authentication_id !== null &&
+ newAppData.authentication_id !== undefined &&
+ newAppData.authentication_id.length > 0
+ ) {
+ findAuthId = newAppData.authentication_id;
+ }
+
+ const tmpAuth = JSON.parse(JSON.stringify(appAuthentication));
+ for (let authkey in tmpAuth) {
+ if (authkey === undefined) {
+ continue
+ }
+
+ var item = tmpAuth[authkey];
+ const newfields = {};
+ for (let fieldkey in item.fields) {
+ if (item.fields[fieldkey] === undefined) {
+ console.log("Problem with filterkey in Node select", fieldkey)
+ continue
+ }
+
+ const filterkey = item.fields[fieldkey]["key"]
+ if (filterkey === null || filterkey === undefined) {
+ console.log("Problem with filterkey 2. Null or undefined 3")
+ continue
+ }
+
+ newfields[filterkey] = item.fields[fieldkey]["value"];
+ }
+
+ item.fields = newfields;
+ if (item.app.id === app.id || item.app.name === app.name) {
+ authenticationOptions.push(item);
+
+ if (item.id === findAuthId) {
+ newAppData.selectedAuthentication = item
+ newAppData.authentication_id = item.id
+
+ } else if (findAuthId === "") {
+ // Will always be set to the last one if one isn't found.
+ // Last = timestamp too
+ newAppData.selectedAuthentication = item
+ newAppData.authentication_id = item.id
+ }
+ }
+ }
+
+ if (
+ authenticationOptions !== undefined &&
+ authenticationOptions !== null &&
+ authenticationOptions.length > 0
+ ) {
+ for (let authkey in authenticationOptions) {
+ const option = authenticationOptions[authkey];
+
+ if (option.active && newAppData.authentication_id === "") {
+ newAppData.selectedAuthentication = option;
+ newAppData.authentication_id = option.id;
+ break;
+ }
+ }
+ }
+ } else {
+ newAppData.authentication = [];
+ newAppData.authentication_id = "";
+ newAppData.selectedAuthentication = {};
+ }
+
+ parsedApp.data = newAppData;
+ cy.add(parsedApp);
+ } else if (newAppData.type === "TRIGGER") {
+ cy.add(parsedApp);
+ }
+
+ newNodeId = "";
+ parsedApp = {};
+ };
+
+ const barHeight = bodyHeight - appBarSize - 50;
+ const appScrollStyle = {
+ overflow: "scroll",
+ maxHeight: isMobile ? bodyHeight - appBarSize * 4 : barHeight,
+ minHeight: isMobile ? bodyHeight - appBarSize * 4 : barHeight,
+ marginTop: 1,
+ overflowY: "auto",
+ overflowX: "hidden",
+ }
+
+ const handleAppDrag = (e, app) => {
+ const cycontainer = cy.container();
+
+
+ if (app.type === "TRIGGER") {
+ handleTriggerDrag(e, app)
+ return
+ }
+
+ //console.log("e: ", e)
+ //console.log("Offset: ", cycontainer)
+
+ // Chrome lol
+ if (
+ e.pageX > cycontainer.offsetLeft &&
+ e.pageX < cycontainer.offsetLeft + cycontainer.offsetWidth &&
+ e.pageY > cycontainer.offsetTop &&
+ e.pageY < cycontainer.offsetTop + cycontainer.offsetHeight
+ ) {
+ if (newNodeId.length > 0) {
+ var currentnode = cy.getElementById(newNodeId);
+ if (
+ currentnode === undefined ||
+ currentnode === null ||
+ currentnode.length === 0
+ ) {
+ return;
+ }
+
+ currentnode[0].renderedPosition("x", e.pageX - cycontainer.offsetLeft)
+ currentnode[0].renderedPosition("y", e.pageY - cycontainer.offsetTop)
+ } else {
+ if (workflow.public) {
+ console.log("workflow is public - not adding")
+ return;
+ }
+
+ if (app.actions === undefined || app.actions === null) {
+ app.actions = []
+ }
+
+ /*
+ if (app.actions === undefined || app.actions === null || app.actions.length === 0) {
+ toast("App " + app.name + " currently has no actions to perform. Please go to https://shuffler.io/apps to edit it.")
+
+ return
+ }
+ */
+
+ newNodeId = uuidv4();
+ const actionType = "ACTION";
+ const actionLabel = getNextActionName(app.name);
+ //console.log("Next action name: ", actionLabel)
+ var parameters = null;
+ var example = "";
+ var description = ""
+
+ const startIndex = app.actions.findIndex((action) => action.category_label !== undefined && action.category_label !== null && action.category_label.length > 0)
+ const actionIndex = startIndex < 0 ? 0 : startIndex
+
+ // Make the first action the most relevant one for them based on previous use
+ if (
+ app.actions[actionIndex].parameters !== undefined &&
+ app.actions[actionIndex].parameters !== null &&
+ app.actions[actionIndex].parameters.length > 0
+ ) {
+ parameters = app.actions[actionIndex].parameters;
+ for (let paramkey in parameters) {
+ // Check if parameter.name == "headers" and if it includes "=undefined". If it does, set the value to example if it exists, otherwise empty
+ if (parameters[paramkey].name === "headers" && parameters[paramkey].value.includes("=undefined")) {
+ if (parameters[paramkey].example !== undefined && parameters[paramkey].example !== null && parameters[paramkey].example.length > 0) {
+ parameters[paramkey].value = parameters[paramkey].example
+ } else {
+ parameters[paramkey].value = ""
+ }
+ }
+ }
+
+ //parameters = app.actions[0].parameters;
+ }
+
+ if (
+ app.actions[actionIndex].returns !== undefined &&
+ app.actions[actionIndex].returns !== null &&
+ app.actions[actionIndex].returns.example !== undefined &&
+ app.actions[actionIndex].returns.example !== null &&
+ app.actions[actionIndex].returns.example.length > 0
+ ) {
+ example = app.actions[actionIndex].returns.example;
+ }
+
+ if (
+ app.actions[actionIndex].description !== undefined &&
+ app.actions[actionIndex].description !== null &&
+ app.actions[actionIndex].description.length > 0
+ ) {
+ description = app.actions[actionIndex].description
+ }
+
+ var parsedEnvironments =
+ environments === null || environments === []
+ ? "cloud"
+ : environments[defaultEnvironmentIndex] === undefined
+ ? "cloud"
+ : environments[defaultEnvironmentIndex].Name;
+
+ // List other nodes in the workflow and see if they have an environment set. If they do, use that as the default
+ if (cy !== undefined && cy !== null) {
+ const foundnodes = cy.nodes().jsons()
+ if (foundnodes !== undefined && foundnodes !== null && foundnodes.length > 0) {
+ // As they should all be the same, this is just an override
+ for (let nodekey in foundnodes) {
+ const curnode = foundnodes[nodekey]
+ if (curnode.data.environment !== undefined && curnode.data.environment !== null && curnode.data.environment.length > 0) {
+ parsedEnvironments = curnode.data.environment
+ break
+ }
+ }
+ }
+ }
+
+ const newAppData = {
+ name: app.actions[actionIndex].name,
+ label: actionLabel,
+ app_name: app.name,
+ app_version: app.app_version,
+ app_id: app.id,
+ sharing: app.sharing,
+ private_id: app.private_id,
+ description: description,
+ environment: parsedEnvironments,
+ errors: [],
+ finished: false,
+ id_: newNodeId,
+ _id_: newNodeId,
+ id: newNodeId,
+ is_valid: true,
+ type: actionType,
+ parameters: parameters,
+ isStartNode: false,
+ large_image: app.large_image,
+ run_magic_output: false,
+ authentication: [],
+ execution_variable: undefined,
+ example: example,
+ required_body_fields: app.actions[actionIndex].required_body_fields,
+ category:
+ app.categories !== null &&
+ app.categories !== undefined &&
+ app.categories.length > 0
+ ? app.categories[0]
+ : "",
+ authentication_id: "",
+ finished: false,
+ template: app.template === true ? true : false,
+ };
+
+ // FIXME: overwrite category if the ACTION chosen has a different category
+ //
+
+ if (!isCloud && (!app.is_valid || (!app.activated && app.generated))) {
+ console.log("NOT VALID: Activate!")
+
+ activateApp(app.id, false)
+ }
+
+ // const image = "url("+app.large_image+")"
+ // FIXME - find the cytoscape offset position
+ // Can this be done with zoom calculations?
+ const nodeToBeAdded = {
+ group: "nodes",
+ data: newAppData,
+ renderedPosition: {
+ x: e.pageX - cycontainer.offsetLeft,
+ y: e.pageY - cycontainer.offsetTop,
+ },
+ };
+
+ parsedApp = nodeToBeAdded;
+ cy.add(nodeToBeAdded);
+ return;
+ }
+ }
+ };
+
+
const getNextActionName = (appName) => {
var highest = "";