import React, { useState, useEffect, useLayoutEffect } from "react";
import { makeStyles, createStyles } from "@material-ui/core/styles";
import { validateJson, GetIconInfo } from "../views/Workflows.jsx";
import { GetParsedPaths } from "../views/Apps.jsx";
import { sortByKey } from "../views/AngularWorkflow.jsx";
import { useTheme } from "@material-ui/core/styles";
import NestedMenuItem from "material-ui-nested-menu-item";
import { useAlert } from "react-alert";
import theme from '../theme.jsx';
import {
ButtonGroup,
Popper,
TextField,
TextareaAutosize,
Drawer,
Button,
Paper,
Tabs,
InputAdornment,
Tab,
ButtonBase,
Tooltip,
Select,
MenuItem,
Divider,
Dialog,
Modal,
DialogActions,
DialogTitle,
InputLabel,
DialogContent,
FormControl,
IconButton,
Menu,
Input,
FormGroup,
FormControlLabel,
Typography,
Checkbox,
Breadcrumbs,
CircularProgress,
Switch,
Fade,
} from "@material-ui/core";
import {
Autocomplete
} from "@material-ui/lab";
import {
HelpOutline as HelpOutlineIcon,
Description as DescriptionIcon,
GetApp as GetAppIcon,
Search as SearchIcon,
ArrowUpward as ArrowUpwardIcon,
Visibility as VisibilityIcon,
Done as DoneIcon,
Close as CloseIcon,
Error as ErrorIcon,
FindReplace as FindreplaceIcon,
ArrowLeft as ArrowLeftIcon,
Cached as CachedIcon,
DirectionsRun as DirectionsRunIcon,
Add as AddIcon,
Polymer as PolymerIcon,
FormatListNumbered as FormatListNumberedIcon,
Create as CreateIcon,
PlayArrow as PlayArrowIcon,
AspectRatio as AspectRatioIcon,
MoreVert as MoreVertIcon,
Apps as AppsIcon,
Schedule as ScheduleIcon,
FavoriteBorder as FavoriteBorderIcon,
Pause as PauseIcon,
Delete as DeleteIcon,
AddCircleOutline as AddCircleOutlineIcon,
Save as SaveIcon,
KeyboardArrowLeft as KeyboardArrowLeftIcon,
KeyboardArrowRight as KeyboardArrowRightIcon,
ArrowBack as ArrowBackIcon,
Settings as SettingsIcon,
LockOpen as LockOpenIcon,
ExpandMore as ExpandMoreIcon,
VpnKey as VpnKeyIcon,
AutoFixHigh as AutoFixHighIcon,
Circle as CircleIcon,
SquareFoot as SquareFootIcon,
} from '@mui/icons-material';
//} from "@material-ui/icons";
//import CodeMirror from "@uiw/react-codemirror";
//import "codemirror/keymap/sublime";
//import "codemirror/theme/gruvbox-dark.css";
import ShuffleCodeEditor from "../components/ShuffleCodeEditor.jsx";
const useStyles = makeStyles({
notchedOutline: {
borderColor: "#f85a3e !important",
},
root: {
"& .MuiAutocomplete-listbox": {
border: "2px solid grey",
color: "white",
fontSize: 18,
"& li:nth-child(even)": {
backgroundColor: "#CCC",
},
"& li:nth-child(odd)": {
backgroundColor: "#FFF",
},
},
},
inputRoot: {
color: "white",
// This matches the specificity of the default styles at https://github.com/mui-org/material-ui/blob/v4.11.3/packages/material-ui-lab/src/Autocomplete/Autocomplete.js#L90
"&:hover .MuiOutlinedInput-notchedOutline": {
borderColor: "#f86a3e",
},
},
});
const openApiFieldDesc = "Generated by OpenAPI body example";
const ParsedAction = (props) => {
const {
workflow,
files,
setWorkflow,
setAction,
setSelectedAction,
setUpdate,
appActionArguments,
selectedApp,
workflowExecutions,
setSelectedResult,
selectedAction,
setSelectedApp,
setSelectedTrigger,
setSelectedEdge,
setCurrentView,
cy,
setAuthenticationModalOpen,
setVariablesModalOpen,
setCodeModalOpen,
selectedNameChange,
rightsidebarStyle,
showEnvironment,
selectedActionEnvironment,
environments,
setNewSelectedAction,
appApiViewStyle,
globalUrl,
setSelectedActionEnvironment,
requiresAuthentication,
hideExtraTypes,
scrollConfig,
setScrollConfig,
authenticationType,
appAuthentication,
getAppAuthentication,
actionDelayChange,
getParents,
isCloud,
lastSaved,
setLastSaved,
setShowVideo,
toolsAppId,
aiSubmit,
//expansionModalOpen,
//setExpansionModalOpen,
} = props;
//const theme = useTheme();
const classes = useStyles();
const alert = useAlert()
const [expansionModalOpen, setExpansionModalOpen] = React.useState(false);
const [hideBody, setHideBody] = React.useState(true);
const [activateHidingBodyButton, setActivateHidingBodyButton] = React.useState(false);
const [codedata, setcodedata] = React.useState("");
const [fieldCount, setFieldCount] = React.useState(0);
const [hiddenDescription, setHiddenDescription] = React.useState(true);
useEffect(() => {
if (setLastSaved !== undefined) {
setLastSaved(false)
}
}, [expansionModalOpen])
useEffect(() => {
if (selectedAction.parameters !== null && selectedAction.parameters !== undefined) {
const paramcheck = selectedAction.parameters.find(param => param.name === "body")
//console.log("LOADED! Change hideBody based on input? Action: ", selectedAction, paramcheck)
if (paramcheck !== undefined && paramcheck !== null) {
if (paramcheck.id === "TOGGLED"){
setHideBody(false)
setActivateHidingBodyButton(false)
} else {
setHideBody(true)
if (paramcheck.id === "UNTOGGLED") {
setActivateHidingBodyButton(false)
}
}
}
}
}, [])
const keywords = [
"len(",
"lower(",
"upper(",
"trim(",
"split(",
"length(",
"number(",
"parse(",
"join(",
];
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) => {
console.log("RESPONSE: ", responseJson);
const parsedapp =
responseJson.app !== undefined && responseJson.app !== null
? JSON.parse(atob(responseJson.app))
: {};
console.log("PARSED: ", parsedapp);
//data = parsedapp.body === undefined ? parsedapp : parsedapp.body
if (
setApp &&
parsedapp.actions !== undefined &&
parsedapp.actions !== null
) {
console.log("Inside first if");
if (
selectedApp.versions !== undefined &&
selectedApp.versions !== null
) {
parsedapp.versions = selectedApp.versions;
}
if (
selectedApp.loop_versions !== undefined &&
selectedApp.loop_versions !== null
) {
parsedapp.loop_versions = selectedApp.loop_versions;
}
// Find authentication, and if it works?
// If authentication has less OR more fields, it has to change
//console.log(selected
console.log("Inside first if2");
var foundAction = parsedapp.actions.find(
(action) =>
action.name.toLowerCase() === selectedAction.name.toLowerCase()
);
console.log("FOUNDACTION: ", foundAction);
if (foundAction !== null && foundAction !== undefined) {
var foundparams = [];
for (let [paramkey,paramkeyval] in Object.entries(foundAction.parameters)) {
const param = foundAction.parameters[paramkey];
const foundParam = selectedAction.parameters.find(
(item) => item.name.toLowerCase() === param.name.toLowerCase()
);
if (foundParam === undefined) {
console.log("COULDNT find Param: ", param);
} else {
foundAction.parameters[paramkey] = foundParam;
}
//foundparams.push(param.name)
}
} else {
alert.error("Couldn't find action " + selectedAction.name);
}
selectedAction.errors = [];
selectedAction.is_valid = true;
// Updating params for the new action
selectedAction.parameters = foundAction.parameters;
selectedAction.app_id = appId;
selectedAction.app_version = parsedapp.app_version;
setSelectedAction(selectedAction);
setSelectedApp(parsedapp);
}
})
.catch((error) => {
alert.error(error.toString());
});
};
const defineStartnode = () => {
if (cy === undefined) {
return;
}
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)
};
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
if (workflowExecutions.length > 0) {
for (let [key,keyval] in Object.entries(workflowExecutions)) {
if (
workflowExecutions[key].execution_argument === undefined ||
workflowExecutions[key].execution_argument === null ||
workflowExecutions[key].execution_argument.length === 0
) {
continue;
}
const valid = validateJson(workflowExecutions[key].execution_argument)
if (valid.valid) {
actionlist.push({
type: "Execution Argument",
name: "Execution Argument",
value: "$exec",
highlight: "exec",
autocomplete: "exec",
example: valid.result,
})
break
}
}
}
if (actionlist.length === 0) {
actionlist.push({
type: "Execution Argument",
name: "Execution Argument",
value: "$exec",
highlight: "exec",
autocomplete: "exec",
example: "",
})
}
actionlist.push({
type: "Shuffle DB",
name: "Shuffle DB",
value: "$shuffle_cache",
highlight: "shuffle_cache",
autocomplete: "shuffle_cache",
example: "",
})
if (
workflow.workflow_variables !== null &&
workflow.workflow_variables !== undefined &&
workflow.workflow_variables.length > 0
) {
for (let [key,keyval] in Object.entries(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 (let [key,keyval] in Object.entries(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
if (getParents !== undefined) {
var parents = getParents(selectedAction);
if (parents.length > 1) {
for (let [key,keyval] in Object.entries(parents)) {
const item = parents[key];
if (item.label === "Execution Argument") {
continue;
}
var exampledata = item.example === undefined || item.example === null ? "" : item.example;
// Find previous execution and their variables
//exampledata === "" &&
if (workflowExecutions.length > 0) {
// Look for the ID
const found = false;
for (let [key,keyval] in Object.entries(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 || foundResult === null) {
continue;
}
if (foundResult.result !== undefined && foundResult.result !== null) {
foundResult = foundResult.result
}
const valid = validateJson(foundResult)
if (valid.valid) {
if (valid.result.success === false) {
//console.log("Skipping success false autocomplete")
} else {
exampledata = valid.result;
break;
}
} else {
exampledata = foundResult;
}
}
}
// 1. Take
const itemlabelComplete =
item.label === null || item.label === undefined
? ""
: item.label.split(" ").join("_");
const actionvalue = {
type: "action",
id: item.id,
name: item.label,
autocomplete: itemlabelComplete,
example: exampledata,
};
actionlist.push(actionvalue);
}
}
//console.log("ACTIONLIST: ", actionlist)
setActionlist(actionlist);
}
}
});
const calculateHelpertext = (input_data) => {
var helperText = ""
var looperText = ""
//const found = input_data.match(/[$]{1}([a-zA-Z0-9_-]+\.?){1}([a-zA-Z0-9#_-]+\.?){0,}/g)
var found = input_data.match(/[\\]{0,1}[$]{1}([a-zA-Z0-9_-]+\.?){1}([a-zA-Z0-9#_-]+\.?){0,}/g)
if (found !== null && found !== undefined) {
var new_occurences = []
for (let [key,keyval] in Object.entries(found)) {
if (found[key][0] !== "\\") {
new_occurences.push(found[key])
}
}
found = new_occurences.valueOf()
}
if (found !== null) {
try {
// When the found array is empty.
for (let i = 0; i < found.length; i++) {
const variableSplit = found[i].split(".#")
if ((variableSplit.length-1) > 1) {
//console.log("Larger than 1: ", variableSplit)
if (looperText.length === 0) {
looperText += "PS: Double looping (.#.#) may cause problems."
}
}
var foundSlice = false
for (let j = 0; j < actionlist.length; j++) {
//console.log("ACTION: ", found[i], actionlist[j])
//console.log("ACTION :", found[i].split(".")[0].slice(1,).toLowerCase(), actionlist[j].autocomplete.toLowerCase())
if(found[i].split(".")[0].slice(1,).toLowerCase() == actionlist[j].autocomplete.toLowerCase()){
//console.log("Found: ", found[i])
// Validate path?
foundSlice = true
}
}
if (!foundSlice) {
if (!helperText.includes("Invalid variables")) {
helperText+= "Invalid variables: "
}
helperText+= found[i] + ", "
}
}
} catch (e) {
console.log("Parsing error: ", e)
}
}
if (looperText.length > 0) {
if (helperText.length > 0) {
helperText += ". "
}
helperText += looperText
}
return helperText
}
const changeActionParameter = (event, count, data, viewForceUpdate) => {
//console.log("Action change: ", selectedAction, 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) {
// Escapes all double quotes
var toReplace = event.target.value.trim()
if (!toReplace.startsWith("{") && !toReplace.startsWith("[")) {
toReplace = toReplace.replaceAll('\\"', '"').replaceAll('"', '\\"')
}
console.log("REPLACE WITH: ", toReplace);
if (
paramcheck["value_replace"] === undefined ||
paramcheck["value_replace"] === null
) {
paramcheck["value_replace"] = [
{
key: data.name,
value: toReplace,
},
];
console.log("IN IF: ", paramcheck);
} else {
const subparamindex = paramcheck["value_replace"].findIndex(
(param) => param.key === data.name
);
if (subparamindex === -1) {
paramcheck["value_replace"].push({
key: data.name,
value: toReplace,
});
} else {
paramcheck["value_replace"][subparamindex]["value"] = toReplace;
}
console.log("IN ELSE: ", paramcheck);
}
//console.log("PARAM: ", paramcheck)
//if (paramcheck.id === undefined) {
// console.log("Normal paramcheck")
//} else {
// selectedActionParameters[count]["value_replace"] = paramcheck
// selectedAction.parameters[count]["value_replace"] = paramcheck
//}
if (paramcheck["value_replace"] === undefined) {
selectedActionParameters[count]["value_replace"] = paramcheck;
selectedAction.parameters[count]["value_replace"] = paramcheck;
} else {
selectedActionParameters[count]["value_replace"] =
paramcheck["value_replace"];
selectedAction.parameters[count]["value_replace"] =
paramcheck["value_replace"];
}
console.log("RESULT: ", selectedAction);
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 (let [key,keyval] in Object.entries(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([]);
}
}
//console.log("CHANGING ACTION COUNT !")
selectedActionParameters[count].autocompleted = false
selectedAction.parameters[count].autocompleted = false
selectedActionParameters[count].value = event.target.value;
selectedAction.parameters[count].value = event.target.value;
var forceUpdate = false
if (isCloud && (selectedAction.app_name === "Shuffle Tools" || selectedAction.app_name === "email") && (selectedAction.name === "send_email_shuffle" || selectedAction.name === "send_sms_shuffle") && data.name === "apikey") {
console.log("APIKEY - this shouldn't show up!")
}
if (selectedAction.app_name === "Shuffle Tools" && selectedAction.name === "filter_list" && data.name === "input_list") {
//console.log("FILTER LIST!: ", event, count, data)
const parsedvalue = event.target.value
if (parsedvalue.includes("#")) {
const splitparsed = parsedvalue.split(".#.")
//console.log("Cant contain #: ", splitparsed)
if (splitparsed.length > 1) {
data.value = splitparsed[0]
selectedActionParameters[count].value = splitparsed[0]
selectedAction.parameters[count].value = splitparsed[0]
//changeActionParameter({target: {value: splitparsed[1]}},
selectedActionParameters[1].value = splitparsed[1]
selectedAction.parameters[1].value = splitparsed[1]
forceUpdate = true
}
}
}
setSelectedAction(selectedAction);
if (forceUpdate || viewForceUpdate === true) {
setUpdate(Math.random())
}
//setUpdate(event.target.value)
};
const changeActionParameterCodeMirror = (event, count, data) => {
if (data.startsWith("${") && data.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) {
// Escapes all double quotes
const toReplace = event.target.value.trim().replaceAll("\\\"", "\"").replaceAll("\"", "\\\"");
console.log("REPLACE WITH: ", toReplace)
if (paramcheck["value_replace"] === undefined || paramcheck["value_replace"] === null) {
paramcheck["value_replace"] = [{
"key": data.name,
"value": toReplace,
}]
console.log("IN IF: ", paramcheck)
} else {
const subparamindex = paramcheck["value_replace"].findIndex(param => param.key === data.name)
if (subparamindex === -1) {
paramcheck["value_replace"].push({
"key": data.name,
"value": toReplace,
})
} else {
paramcheck["value_replace"][subparamindex]["value"] = toReplace
}
console.log("IN ELSE: ", paramcheck)
}
//console.log("PARAM: ", paramcheck)
//if (paramcheck.id === undefined) {
// console.log("Normal paramcheck")
//} else {
// selectedActionParameters[count]["value_replace"] = paramcheck
// selectedAction.parameters[count]["value_replace"] = paramcheck
//}
if (paramcheck["value_replace"] === undefined) {
selectedActionParameters[count]["value_replace"] = paramcheck
selectedAction.parameters[count]["value_replace"] = paramcheck
} else {
selectedActionParameters[count]["value_replace"] = paramcheck["value_replace"]
selectedAction.parameters[count]["value_replace"] = paramcheck["value_replace"]
}
console.log("RESULT: ", selectedAction)
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 (let [key,keyval] in Object.entries(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].autocompleted = false
selectedAction.parameters[count].autocompleted = false
selectedActionParameters[count].value = data
selectedAction.parameters[count].value = data
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" && getParents !== undefined) {
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({});
if (setSelectedTrigger !== undefined) {
setSelectedTrigger({});
setSelectedApp({});
setSelectedEdge({});
}
// FIXME - check if startnode
// Set value
setSelectedApp(selectedApp);
setSelectedAction(selectedAction);
setUpdate(Math.random());
};
const returnHelperText = (name, value) => {
if (name === undefined || value === undefined) {
return ""
}
var helperText = ""
//console.log("DATA: ", name, value)
if (name.includes("url")) {
if (value.includes("localhost") || value.includes("127.0.0.1")) {
helperText = "Can't use localhost. Please change to an external IP or hostname."
}
}
return helperText
}
//console.log("AUTH: ", authenticationType)
if (authenticationType !== undefined && authenticationType !== null && authenticationType.type === "oauth2") {
/*
return (
You must authenticate before using oauth2 apps.
)
*/
}
//console.log("APP: ", selectedApp)
// FIXME: Issue #40 - selectedActionParameters not reset
if (
Object.getOwnPropertyNames(selectedAction).length > 0 &&
selectedActionParameters.length > 0
) {
var authWritten = false;
return (
{
setHiddenDescription(!hiddenDescription)
}}
>
Parameters
{selectedAction.template === true && selectedAction.matching_actions !== undefined && selectedAction.matching_actions !== null && selectedAction.matching_actions.length > 0 ?
Select an app you want to use
{
console.log("LABEL: ", option)
if (
option === undefined ||
option === null ||
option.app_name === undefined ||
option.app_name === null
) {
return null;
}
const newname = (
option.app_name.charAt(0).toUpperCase() + option.app_name.substring(1)
).replaceAll("_", " ");
return newname;
}}
options={selectedAction.matching_actions}
fullWidth
style={{
backgroundColor: theme.palette.inputColor,
height: 50,
borderRadius: theme.palette.borderRadius,
}}
onChange={(event, newValue) => {
console.log("SELECT: ", event, newValue)
// Workaround with event lol
//if (newValue !== undefined && newValue !== null) {
// setNewSelectedAction({ target: { value: newValue.name } });
//}
}}
renderOption={(data) => {
var newActionname = data.app_name;
if (
data.label !== undefined &&
data.label !== null &&
data.label.length > 0
) {
newActionname = data.label;
}
const iconInfo = GetIconInfo({ name: data.app_name });
const useIcon = iconInfo.originalIcon;
newActionname = (
newActionname.charAt(0).toUpperCase() +
newActionname.substring(1)
).replaceAll("_", " ");
return (
{useIcon}
{newActionname}
);
}}
renderInput={(params) => {
if (params.inputProps !== undefined && params.inputProps !== null && params.inputProps.value !== undefined && params.inputProps.value !== null) {
const prefixes = ["Post", "Put", "Patch"]
for (let [key,keyval] in Object.entries(prefixes)) {
if (params.inputProps.value.startsWith(prefixes[key])) {
params.inputProps.value = params.inputProps.value.replace(prefixes[key]+" ", "", -1)
if (params.inputProps.value.length > 1) {
params.inputProps.value = params.inputProps.value.charAt(0).toUpperCase()+params.inputProps.value.substring(1)
}
break
}
}
}
return (
);
}}
/>
: null}
{selectedAction.description !== undefined && selectedAction.description !== null && selectedAction.description.length > 0 && hiddenDescription === false ? (
Description
{selectedAction.description}
) : null}
{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())
if (authWritten) {
return null;
}
authWritten = true;
return (
Authentication fields are hidden
);
}
// Added autofill to make this ALOT simpler
if (isCloud && (selectedAction.app_name === "Shuffle Tools" || selectedAction.app_name === "email") && (selectedAction.name === "send_email_shuffle" || selectedAction.name === "send_sms_shuffle") && data.name === "apikey") {
if (selectedActionParameters[count].length === 0) {
selectedAction.parameters[count].value = "TMP: Will be replaced during execution if cloud"
setSelectedAction(selectedAction)
}
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 = "Value";
if (
data.example !== undefined &&
data.example !== null &&
data.example.length > 0
) {
placeholder = data.example;
if (data.name === "url" && data.value !== undefined && data.value !== null && data.value.length === 0) {
data.value = data.example;
}
// In case of data.example
if (data.value === undefined || data.value === null) {
data.value = ""
}
if (data.value.length === 0) {
if (data.name.toLowerCase() === "headers") {
console.log("Should show headers field instead with + and -!")
// Check if file ID exists
//
const fileFound = selectedActionParameters.find(param => param.name === "file_id")
if (fileFound === undefined || fileFound === null) {
data.value = data.example
} else {
// Purposely unset it if set by default when using files
data.value = ""
}
}
}
/*
if (data.name !== "queries" && data.name !== "key" && data.name !== "value" ) {
data.value = 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 &&
data.name === "url" &&
data.required &&
data.configuration
) {
//&&
//hideExtraTypes
//console.log("GENERATED WITH DATA: ", data);
return null;
}
*/
if (selectedApp.generated && data.name === "headers") {
//console.log("HEADER: ", data)
//if (data.value.length === 0) {
//}
//setSelectedActionParameters(selectedActionParameters)
}
var hideBodyButton = "";
const hideBodyButtonValue = (
{
var tag = "TOGGLED"
if (hideBody) {
tag = "UNTOGGLED"
}
setHideBody(!hideBody);
for (let paramkey in Object.entries(selectedActionParameters)) {
var currentItem = selectedActionParameters[paramkey];
if (currentItem.name === "ssl_verify") {
}
if (currentItem.name === "body") {
// FIXME: Workaround for toggling, as actions don't have IDs.
// May screw up something in the future.
currentItem.id = tag
}
if (currentItem.description === openApiFieldDesc) {
currentItem.field_active = !hideBody;
//console.log("Changing", currentItem);
}
}
}}
name="requires_unique"
/>
}
label={"Automatically fix body"}
/>
)
if (selectedApp.generated && data.name === "body") {
const regex = /\${(\w+)}/g;
const found = placeholder.match(regex);
hideBodyButton = hideBodyButtonValue;
if (found === null || !hideBody) {
if (found === null) {
setActivateHidingBodyButton(true);
} else {
//console.log("In found: ", found, hideBody)
}
} else {
//console.log("SHOW BUTTON");
rows = "1";
disabled = true;
openApiHelperText = "OpenAPI spec: fill the following fields.";
//console.log("SHOULD ADD TO selectedActionParameters!: ", found, selectedActionParameters)
var changed = false;
for (let specKey in found) {
const tmpitem = found[specKey];
var skip = false;
for (let 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: openApiFieldDesc,
example: "",
id: "",
multiline: true,
name: tmpitem,
options: null,
required: false,
schema: { type: "string" },
skip_multicheck: false,
tags: null,
value: "",
variant: "STATIC_VALUE",
field_active: true,
});
}
if (changed) {
setSelectedActionParameters(selectedActionParameters);
}
return hideBodyButton;
}
}
if (activateHidingBodyButton === true) {
hideBodyButton = "";
}
const clickedFieldId = "rightside_field_" + count;
const shufflecode = fieldCount !== count ? null :
(
)
//
0) {
baseHelperText = calculateHelpertext(data.value)
}
var tmpitem = data.name.valueOf();
if (data.name.startsWith("${") && data.name.endsWith("}")) {
tmpitem = tmpitem.slice(2, data.name.length - 1);
}
if (tmpitem === "from_shuffle") {
tmpitem = "from"
}
tmpitem = (
tmpitem.charAt(0).toUpperCase() + tmpitem.substring(1)
).replaceAll("_", " ");
if (tmpitem === "Username basic") {
tmpitem = "Username"
} else if (tmpitem === "Password basic") {
tmpitem = "Password"
}
multiline = data.name.startsWith("${") && data.name.endsWith("}") ? true : multiline
var datafield = (
{
event.preventDefault()
setFieldCount(count)
setcodedata(data.value)
setExpansionModalOpen(true)
}}
/>
{
event.preventDefault()
// Get cursor position
// This makes it so we can put it in the right location?
setMenuPosition({
top: event.pageY + 10,
left: event.pageX + 10,
});
setShowDropdownNumber(count);
setShowDropdown(true);
setShowAutocomplete(true);
}}
/>
),
}}
multiline={data.name.startsWith("${") && data.name.endsWith("}") ? true : multiline}
helperText={returnHelperText(data.name, data.value)}
onClick={() => {
console.log("Clicked field: ", clickedFieldId, data.name)
//if (data.name === "file_id") {
// console.log("show file video?")
// if (setShowVideo !== undefined) {
// setShowVideo("https://www.youtube.com/embed/DPYowyTbsSk")
// }
//}
//(data.name.toLowerCase().includes("api") ||
/*
setExpansionModalOpen(false);
if (
setScrollConfig !== undefined &&
scrollConfig !== null &&
scrollConfig !== undefined &&
scrollConfig.selected !== clickedFieldId
) {
scrollConfig.selected = clickedFieldId;
setScrollConfig(scrollConfig);
//console.log("Change field id!")
}
*/
//console.log("Clicked field: ", clickedFieldId)
if (setScrollConfig !== undefined && scrollConfig !== null && scrollConfig !== undefined && scrollConfig.selected !== clickedFieldId) {
scrollConfig.selected = clickedFieldId
setScrollConfig(scrollConfig)
//console.log("Change field id!")
}
}}
id={clickedFieldId}
rows={data.name.startsWith("${") && data.name.endsWith("}") ? 2 : rows}
color="primary"
defaultValue={data.value}
//value={data.value}
//options={{
// theme: 'gruvbox-dark',
// keyMap: 'sublime',
// mode: 'python',
//}}
//height={multiline ? 50 : 150}
type={
placeholder.includes("***") ||
(data.configuration &&
(data.name.toLowerCase().includes("api") ||
data.name.toLowerCase().includes("key") ||
data.name.toLowerCase().includes("pass")))
? "password"
: "text"
}
placeholder={placeholder}
onChange={(event) => {
//changeActionParameterCodemirror(event, count, data)
changeActionParameter(event, count, data);
}}
helperText={baseHelperText.length > 0 ? baseHelperText :
selectedApp.generated &&
selectedApp.activated &&
data.name === "body" ? (
{openApiHelperText}
) : data.name.startsWith("${") && data.name.endsWith("}") ?
null : null
}
onBlur={(event) => {
baseHelperText = calculateHelpertext(event.target.value)
if (setLastSaved !== undefined) {
setLastSaved(false)
}
}}
/>
);
// Finds headers from a string to be used for autocompletion
const findHeaders = (inputdata) => {
var splitdata = inputdata.split("\n")
var foundnewline = false
var allValues = []
for (let [key,keyval] in Object.entries(splitdata)) {
const line = splitdata[key]
if (line === "") {
foundnewline = true
continue
}
var splitvalue = ""
if (line.includes(":")) {
splitvalue = ":"
}
if (line.includes("=")) {
splitvalue = "="
}
if (splitvalue.length === 0){
allValues.push({
key: line,
value: "",
})
continue
}
var splitKeys = line.split(splitvalue)
if (splitKeys.length > 1) {
allValues.push({
key: splitKeys[0].trim(),
value: splitKeys[1].trim(),
})
} else {
console.log("No keys for ", line)
}
}
// Just add one
if (foundnewline) {
allValues.push({
key: "",
value: "",
})
}
return allValues
}
if (data.name.toLowerCase() === "headers") {
//var tmpheaders = findHeaders(data.value)
var tmpheaders = findHeaders(selectedActionParameters[count].value)
const tmpdatafield =
{tmpheaders.map((inputdata, index) => {
const oldkey = inputdata.key
const oldval = inputdata.value
return (
{
console.log("Change from oldkey to new: ", oldkey, e.target.value)
// Find the right line to replace!
//const newval = selectedActionParameters[count].value.replace(oldval, e.target.value, 1)
const tmpsplit = selectedActionParameters[count].value.split("\n")
var valsplit = []
var add_empty = false
for (let [key,keyval] in Object.entries(tmpsplit)) {
if (tmpsplit[key] === "") {
add_empty = true
continue
}
valsplit.push(tmpsplit[key])
}
if (add_empty) {
valsplit.push("")
}
console.log("Split: ", valsplit)
var newarr = []
for (let [key,keyval] in Object.entries(valsplit)) {
var line = valsplit[key]
if (key == index) {
if (oldkey === "") {
if (line.includes("=") || line.includes(":")) {
newarr.push(e.target.value + line)
} else {
newarr.push(e.target.value + ": " + line)
}
} else {
newarr.push(line.replace(oldkey, e.target.value, 1))
}
} else {
newarr.push(line)
}
}
var newval = newarr.join("\n")
console.log("Fixed: ", newval)
selectedActionParameters[count].value = newval
selectedAction.parameters[count].value = newval
setSelectedAction(selectedAction)
setSelectedActionParameters(selectedActionParameters)
}}
/>
{
console.log("Change from oldval to new: ", oldval, e.target.value)
// Find the right line to replace!
//const newval = selectedActionParameters[count].value.replace(oldval, e.target.value, 1)
var tmpsplit = selectedActionParameters[count].value.split("\n")
var valsplit = []
var add_empty = false
for (let [key,keyval] in Object.entries(tmpsplit)) {
if (tmpsplit[key] === "") {
add_empty = true
continue
}
valsplit.push(tmpsplit[key])
}
if (add_empty) {
valsplit.push("")
}
console.log("Split: ", valsplit)
var newarr = []
for (let [key,keyval] in Object.entries(valsplit)) {
var line = valsplit[key]
if (key == index) {
if (oldval === "") {
if (line.includes("=") || line.includes(":")) {
newarr.push(line + e.target.value)
} else {
newarr.push(line + ": " + e.target.value)
}
} else {
newarr.push(line.replace(oldval, e.target.value, 1))
}
} else {
newarr.push(line)
}
}
var newval = newarr.join("\n")
console.log("Fixed: ", newval)
selectedActionParameters[count].value = newval
selectedAction.parameters[count].value = newval
setSelectedAction(selectedAction)
setSelectedActionParameters(selectedActionParameters)
}}
/>
)
})}
{
console.log("Add header")
selectedActionParameters[count].value += "\n"
selectedAction.parameters[count].value += "\n"
setSelectedActionParameters(selectedActionParameters)
setSelectedAction(selectedAction)
setUpdate(Math.random())
}}>
Add header
}
//console.log("FIELD VALUE: ", data.value)
//const regexp = new RegExp("\W+\.", "g")
//let match
//while ((match = regexp.exec(data.value)) !== null) {
// console.log(`Found ${match[0]} start=${match.index} end=${regexp.lastIndex}.`);
//}
//const str = = data.value.search(submatch)
//console.log("FOUND? ", n)
//for (var key in keywords) {
// const keyword = keywords[key]
// if (data.value.includes(keyword)) {
// console.log("INCLUDED: ", keyword)
// }
//}
// Basic helpertext
if (files !== undefined && files !== null && data.name.toLowerCase() === "file_category") {
//selectedActionParameters[count].options.length > 0
console.log("FileS: ", files)
if (files.namespaces !== undefined && files.namespaces !== null && files.namespaces.length > 0) {
data.options = files.namespaces
}
}
//const keywords = ["len", "lower", "upper", "trim", "split", "length", "number", "parse", "join"]
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);
}}
/>
),
}}
helperText={returnHelperText(data.name, data.value)}
fullWidth
multiline={multiline}
rows="5"
color="primary"
defaultValue={data.value}
type={"text"}
placeholder={"The file ID to get"}
id={"rightside_field_" + count}
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 (
(data.options !== undefined &&
data.options !== null &&
data.options.length > 0)
||
(selectedActionParameters[count].options !== undefined &&
selectedActionParameters[count].options !== null &&
selectedActionParameters[count].options.length > 0)
) {
const parsedoptions = data.options !== undefined && data.options !== null && data.options.length > 0 ? data.options : selectedActionParameters[count].options
if (selectedActionParameters[count].value === "") {
// && selectedActionParameters[count].required) {
// Rofl, dirty workaround :)
const e = {
target: {
value: parsedoptions[0],
},
};
changeActionParameter(e, count, data);
}
datafield = (
{
changeActionParameter(e, count, data);
setUpdate(Math.random());
}}
style={{
backgroundColor: theme.palette.surfaceColor,
color: "white",
height: "50px",
borderRadius: theme.palette.borderRadius,
}}
>
{parsedoptions.map(
(data, index) => {
const split_data = data.split("||");
var viewed_data = data;
if (split_data.length > 1) {
viewed_data = split_data[0];
}
return (
{viewed_data}
);
}
)}
);
} else if (data.variant === "STATIC_VALUE") {
staticcolor = "#f85a3e";
}
if (data.field_active === false) {
return null;
}
// 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) => {
console.log("In normal itemclick")
if (values === undefined ||values === null ||values.length === 0) {
return;
}
var toComplete = selectedActionParameters[count].value.trim()
.endsWith("$")
? values[0].autocomplete
: "$" + values[0].autocomplete;
toComplete = toComplete.toLowerCase().replaceAll(" ", "_");
for (let [key,keyval] in Object.entries(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;
}
}
console.log("In nestedclick!!")
var newValue = selectedActionParameters[count].value + toComplete
changeActionParameter({target: {value: newValue}}, count, data, true)
//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 (
{
handleMenuClose();
}}
open={!!menuPosition}
style={{
color: "white",
marginTop: 2,
maxHeight: 650,
}}
>
{actionlist.map((innerdata) => {
const icon =
innerdata.type === "action" ? (
) : innerdata.type === "workflow_variable" ||
innerdata.type === "execution_variable" ? (
) : (
);
const handleExecArgumentHover = (inside) => {
var exec_text_field = document.getElementById(
"execution_argument_input_field"
);
if (exec_text_field !== null) {
if (inside) {
exec_text_field.style.border = "2px solid #f85a3e";
} else {
exec_text_field.style.border = "";
}
}
// Also doing arguments
if (
workflow.triggers !== undefined &&
workflow.triggers !== null &&
workflow.triggers.length > 0
) {
for (let [key,keyval] in Object.entries(workflow.triggers)) {
const item = workflow.triggers[key];
if (cy !== undefined) {
var node = cy.getElementById(item.id);
if (node.length > 0) {
if (inside) {
node.addClass("shuffle-hover-highlight");
} else {
node.removeClass("shuffle-hover-highlight");
}
}
}
}
}
};
const handleActionHover = (inside, actionId) => {
if (cy !== undefined) {
var node = cy.getElementById(actionId);
if (node.length > 0) {
if (inside) {
node.addClass("shuffle-hover-highlight");
} else {
node.removeClass("shuffle-hover-highlight");
}
}
}
};
const handleMouseover = () => {
if (innerdata.type === "Execution Argument") {
handleExecArgumentHover(true);
} else if (innerdata.type === "action") {
handleActionHover(true, innerdata.id);
}
};
const handleMouseOut = () => {
if (innerdata.type === "Execution Argument") {
handleExecArgumentHover(false);
} else if (innerdata.type === "action") {
handleActionHover(false, innerdata.id);
}
};
var parsedPaths = [];
if (typeof innerdata.example === "object") {
parsedPaths = GetParsedPaths(innerdata.example, "");
}
const coverColor = "#82ccc3"
//menuPosition.left -= 50
//menuPosition.top -= 250
//console.log("POS: ", menuPosition1)
var menuPosition1 = menuPosition
if (menuPosition1 === null) {
menuPosition1 = {
"left": 0,
"top": 0,
}
} else if (menuPosition1.top === null || menuPosition1.top === undefined) {
menuPosition1.top = 0
} else if (menuPosition1.left === null || menuPosition1.left === undefined) {
menuPosition1.left = 0
}
//console.log("POS1: ", menuPosition1)
return parsedPaths.length > 0 ? (
{icon} {innerdata.name}
}
parentMenuOpen={!!menuPosition}
style={{
color: "white",
minWidth: 250,
maxWidth: 250,
maxHeight: 50,
overflow: "hidden",
}}
onClick={() => {
console.log("CLICKED: ", innerdata);
console.log(innerdata.example)
handleItemClick([innerdata]);
}}
>
{
//console.log("HOVER: ", pathdata);
}}
onClick={() => {
handleItemClick([innerdata]);
}}
>
{innerdata.name}
{parsedPaths.map((pathdata, index) => {
// FIXME: Should be recursive in here
//
const icon =
pathdata.type === "value" ? (
) : pathdata.type === "list" ? (
) : (
);
//
const indentation_count = (pathdata.name.match(/\./g) || []).length+1
const baseIndent =
//const boxPadding = pathdata.type === "object" ? "10px 0px 0px 0px" : 0
const boxPadding = 0
const namesplit = pathdata.name.split(".")
const newname = namesplit[namesplit.length-1]
return (
{
//console.log("HOVER: ", pathdata);
}}
onClick={() => {
handleItemClick([innerdata, pathdata]);
}}
>
{Array(indentation_count).fill().map((subdata, subindex) => {
return (
baseIndent
)
})}
{icon} {newname}
{pathdata.type === "list" ? {
e.preventDefault()
e.stopPropagation()
console.log("INNER: ", innerdata, pathdata)
// Removing .list from autocomplete
var newname = pathdata.name
if (newname.length > 5) {
newname = newname.slice(0, newname.length-5)
}
selectedActionParameters[count].value += `{{ $${innerdata.name}.${newname} | size }}`
selectedAction.parameters[count].value = selectedActionParameters[count].value;
setSelectedAction(selectedAction);
setUpdate(Math.random());
setShowDropdown(false);
setMenuPosition(null);
// innerdata.name
// pathdata.name
//handleItemClick([innerdata, newpathdata])
//console.log("CLICK LENGTH!")
}} /> : null}
);
})}
) : (
handleMouseover()}
onMouseOut={() => {
handleMouseOut();
}}
onClick={() => {
handleItemClick([innerdata]);
}}
>
{icon} {innerdata.name}
);
})}
);
};
const description =
data.description === undefined ? "" : data.description;
const tooltipDescription = (
- Required:{" "}
{data.required === true || data.configuration === true
? "True"
: "False"}
- Example: {data.example}
- Description: {description}
);
//var itemColor = "#f85a3e"
//if (!data.required) {
// itemColor = "#ffeb3b"
//}
{
/*
*/
}
//console.log(data.configuration)
const buttonTitle = `Authenticate ${selectedApp.name.replaceAll("_", " ")}`
const hasAutocomplete = data.autocompleted === true
return (
{hideBodyButton}
{data.configuration === true ? (
{
setAuthenticationModalOpen(true);
}}
/>
) : null}
{hasAutocomplete === true ?
:
null}
{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) || hideExtraTypes ? 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}
{shufflecode}
{showDropdown &&
showDropdownNumber === count &&
data.variant === "STATIC_VALUE" &&
jsonList.length > 0 ? (
Autocomplete
{
setShowAutocomplete(false);
if (
!selectedActionParameters[count].value[
selectedActionParameters[count].value.length - 1
] === "."
) {
setShowDropdown(false);
}
setUpdate(Math.random());
}}
onClick={() => {
setShowAutocomplete(true)
}}
fullWidth
open={showAutocomplete}
style={{
color: "white",
height: 50,
marginTop: 2,
borderRadius: theme.palette.borderRadius,
}}
onChange={(e) => {
if (selectedActionParameters[count].value[selectedActionParameters[count].value.length - 1] === ".") {
e.target.value.autocomplete = e.target.value.autocomplete.slice(1,e.target.value.autocomplete.length);
}
selectedActionParameters[count].value += e.target.value.autocomplete;
selectedAction.parameters[count].value = selectedActionParameters[count].value;
setSelectedAction(selectedAction);
setUpdate(Math.random());
setShowDropdown(false);
}}
>
{jsonList.map((data) => {
const iconStyle = {
marginRight: 15,
};
const icon =
data.type === "value" ? (
) : data.type === "list" ? (
) : (
);
return (
{}}
>
{icon} {data.name}
);
})}
) : null}
{showDropdown &&
showDropdownNumber === count &&
data.variant === "STATIC_VALUE" &&
jsonList.length === 0 ? (
) : null}
);
})}
);
}
return null;
};
//const CustomPopper = function (props) {
// const classes = useStyles()
// return
//}
//console.log("env: ", selectedActionEnvironment)
var baselabel = selectedAction.label;
return (
{hideExtraTypes === true ? null : (
{(
selectedAction.app_name.charAt(0).toUpperCase() +
selectedAction.app_name.substring(1)
).replaceAll("_", " ")}
{
console.log("FIND EXAMPLE RESULTS FOR ", selectedAction);
if (workflowExecutions.length > 0) {
// Look for the ID
const found = false;
for (let [key,keyval] in Object.entries(workflowExecutions)) {
if (workflowExecutions[key].results === undefined || workflowExecutions[key].results === null) {
continue;
}
// Enforces it to show at least one
//if (workflowExecutions[key].execution_argument.includes("too large") && key !== workflowExecutions.length - 1) {
// continue
//}
var foundResult = workflowExecutions[key].results.find(
(result) => result.action.id === selectedAction.id
)
if (foundResult === undefined || foundResult === null) {
continue;
}
const oldstartnode = cy.getElementById(selectedAction.id);
console.log("FOUND NODe: ", oldstartnode)
if (oldstartnode !== undefined && oldstartnode !== null) {
const foundname = oldstartnode.data("label")
if (foundname !== undefined && foundname !== null) {
foundResult.action.label = foundname
}
}
setSelectedResult(foundResult);
if (setCodeModalOpen !== undefined) {
setCodeModalOpen(true);
}
break;
}
}
}}
>
{
setAuthenticationModalOpen(true)
}}
>
{}}
>
{/*
{
//setAuthenticationModalOpen(true);
console.log("Should enable/disable magic!")
console.log("Action: ", selectedAction)
if (selectedAction.run_magic_output === undefined) {
selectedAction.run_magic_output = true
} else {
if (selectedAction.run_magic_output === true) {
selectedAction.run_magic_output = false
} else {
selectedAction.run_magic_output = true
}
}
setSelectedAction(selectedAction)
setUpdate(Math.random());
}}
>
*/}
{
}}
>
{/*selectedAction.id === workflow.start ? null :
{
defineStartnode(e)
}}>
*/}
{selectedApp.versions !== null &&
selectedApp.versions !== undefined &&
selectedApp.versions.length > 1 ? (
{
console.log("VAL: ", event.target.value)
console.log("App: ", selectedApp)
const newversion = selectedApp.versions.find(
(tmpApp) => tmpApp.version == event.target.value
);
console.log("NEWVERSION: ", newversion);
if (newversion !== undefined && newversion !== null) {
getApp(newversion.id, true);
}
}}
style={{
marginTop: 10,
backgroundColor: theme.palette.surfaceColor,
backgroundColor: theme.palette.inputColor,
color: "white",
height: 35,
marginleft: 10,
borderRadius: theme.palette.borderRadius,
}}
SelectDisplayProps={{
style: {
marginLeft: 10,
},
}}
>
{selectedApp.versions.map((data, index) => {
return (
{data.version}
);
})}
) : null}
Name
{
const name = e.target.value;
const parsedBaseLabel = "$"+baselabel.toLowerCase().replaceAll(" ", "_")
const newname = "$"+name.toLowerCase().replaceAll(" ", "_")
// Change in actions, triggers & conditions
// Highlight the changes somehow with a glow?
//
// Should make it a function lol
if (workflow.branches !== undefined && workflow.branches !== null) {
for (let [key,keyval] in Object.entries(workflow.branches)) {
if (workflow.branches[key].conditions !== undefined && workflow.branches[key].conditions !== null) {
for (let [subkey,subkeyval] in Object.entries(workflow.branches[key].conditions)) {
const condition = workflow.branches[key].conditions[subkey]
const sourceparam = condition.source
const destinationparam = condition.destination
// Should have a smarter way of discovering node names
// Finding index(es) and replacing at the location
if (sourceparam.value.includes("$")) {
try {
var cnt = -1
var previous = 0
while (true) {
cnt += 1
// Need to make sure e.g. changing the first here doesn't change the 2nd
// $change_me
// $change_me_2
const foundindex = sourceparam.value.toLowerCase().indexOf(parsedBaseLabel, previous)
if (foundindex === previous && foundindex !== 0) {
break
}
if (foundindex >= 0) {
previous = foundindex+newname.length
// Need to add diff of length to word
// Check location:
// If it's a-zA-Z_ then don't replace
if (sourceparam.value.length > foundindex+parsedBaseLabel.length) {
const regex = /[a-zA-Z0-9_]/g;
const match = sourceparam.value[foundindex+parsedBaseLabel.length].match(regex);
if (match !== null) {
continue
}
}
console.log("Old found: ", workflow.branches[key].conditions[subkey].source.value)
const extralength = newname.length-parsedBaseLabel.length
sourceparam.value = sourceparam.value.substring(0, foundindex) + newname + sourceparam.value.substring(foundindex-extralength+newname.length, sourceparam.value.length)
console.log("New: ", workflow.branches[key].conditions[subkey].source.value)
} else {
break
}
// Break no matter what after 5 replaces. May need to increase
if (cnt >= 5) {
break
}
}
} catch (e) {
console.log("Failed value replacement based on index: ", e)
}
}
if (destinationparam.value.includes("$")) {
try {
var cnt = -1
var previous = 0
while (true) {
cnt += 1
// Need to make sure e.g. changing the first here doesn't change the 2nd
// $change_me
// $change_me_2
const foundindex = destinationparam.value.toLowerCase().indexOf(parsedBaseLabel, previous)
if (foundindex === previous && foundindex !== 0) {
break
}
if (foundindex >= 0) {
previous = foundindex+newname.length
// Need to add diff of length to word
// Check location:
// If it's a-zA-Z_ then don't replace
if (destinationparam.value.length > foundindex+parsedBaseLabel.length) {
const regex = /[a-zA-Z0-9_]/g;
const match = destinationparam.value[foundindex+parsedBaseLabel.length].match(regex);
if (match !== null) {
continue
}
}
console.log("Old found: ", workflow.branches[key].conditions[subkey].destination.value)
const extralength = newname.length-parsedBaseLabel.length
destinationparam.value = destinationparam.value.substring(0, foundindex) + newname + destinationparam.value.substring(foundindex-extralength+newname.length, destinationparam.value.length)
console.log("New: ", workflow.branches[key].conditions[subkey].destination.value)
} else {
break
}
// Break no matter what after 5 replaces. May need to increase
if (cnt >= 5) {
break
}
}
} catch (e) {
console.log("Failed value replacement based on index: ", e)
}
}
}
}
}
}
for (let [key,keyval] in Object.entries(workflow.actions)) {
if (workflow.actions[key].id === selectedAction.id) {
continue
}
for (let [subkey, subkeyval] in Object.entries(workflow.actions[key].parameters)) {
const param = workflow.actions[key].parameters[subkey];
if (!param.value.includes("$")) {
continue
}
// Should have a smarter way of discovering node names
// Do regex?
// Finding index(es) and replacing at the location
//
try {
var cnt = -1
var previous = 0
while (true) {
cnt += 1
// Need to make sure e.g. changing the first here doesn't change the 2nd
// $change_me
// $change_me_2
const foundindex = param.value.toLowerCase().indexOf(parsedBaseLabel, previous)
if (foundindex === previous && foundindex !== 0) {
break
}
if (foundindex >= 0) {
previous = foundindex+newname.length
// Need to add diff of length to word
// Check location:
// If it's a-zA-Z_ then don't replace
if (param.value.length > foundindex+parsedBaseLabel.length) {
const regex = /[a-zA-Z0-9_]/g;
const match = param.value[foundindex+parsedBaseLabel.length].match(regex);
if (match !== null) {
continue
}
}
console.log("Old found: ", workflow.actions[key].parameters[subkey].value)
const extralength = newname.length-parsedBaseLabel.length
param.value = param.value.substring(0, foundindex) + newname + param.value.substring(foundindex-extralength+newname.length, param.value.length)
console.log("New: ", workflow.actions[key].parameters[subkey].value)
} else {
break
}
// Break no matter what after 5 replaces. May need to increase
if (cnt >= 5) {
break
}
}
} catch (e) {
console.log("Failed value replacement based on index: ", e)
}
}
}
console.log("DID NAME REPLACE ACTUALLY WORK? - may be missing it in certain triggers");
setWorkflow(workflow);
setUpdate(Math.random());
baselabel = name
}}
/>
{/*!isCloud ? null :*/}
Delay
{
if (actionDelayChange !== undefined) {
actionDelayChange(event)
}
}}
/>
{/**/}
)}
{selectedApp.name !== undefined &&
selectedAction.authentication !== null &&
selectedAction.authentication !== undefined &&
selectedAction.authentication.length === 0 &&
requiresAuthentication ? (
{
console.log(authenticationType);
//if (authenticationType.type === "oauth2" && authenticationType.redirect_uri !== undefined && authenticationType.redirect_uri !== null) {
// return null
//}
setAuthenticationModalOpen(true);
}}
>
Authenticate{" "}
{selectedApp.name}
) : null}
{selectedAction.authentication !== undefined &&
selectedAction.authentication !== null &&
selectedAction.authentication.length > 0 ? (
Authentication
{
if (e.target.value === "No selection") {
selectedAction.selectedAuthentication = {};
selectedAction.authentication_id = "";
for (let [key,keyval] in Object.entries(selectedAction.parameters)) {
//console.log(selectedAction.parameters[key])
if (selectedAction.parameters[key].configuration) {
selectedAction.parameters[key].value = "";
}
}
setSelectedAction(selectedAction);
setUpdate(Math.random());
} else {
selectedAction.selectedAuthentication = e.target.value;
selectedAction.authentication_id = e.target.value.id;
setSelectedAction(selectedAction);
setUpdate(Math.random());
}
}}
style={{
backgroundColor: theme.palette.inputColor,
color: "white",
height: 50,
maxWidth: rightsidebarStyle.maxWidth - 80,
borderRadius: theme.palette.borderRadius,
}}
>
No selection
{selectedAction.authentication.map((data) => {
//console.log("AUTH DATA: ", data)
return (
{data.label} - ({data.app.app_version})
);
})}
{/*
setAuthenticationModalOpen(true)}>
AUTHENTICATE
curaction.authentication = authenticationOptions
if (curaction.selectedAuthentication === null || curaction.selectedAuthentication === undefined || curaction.selectedAuthentication.length === "")
*/}
{
setAuthenticationModalOpen(true);
}}
>
) : null}
{showEnvironment !== undefined && showEnvironment && environments.length > 1 ? (
Environment
{
const env = environments.find((a) => a.Name === e.target.value);
setSelectedActionEnvironment(env);
selectedAction.environment = env.Name;
setSelectedAction(selectedAction);
}}
style={{
backgroundColor: theme.palette.inputColor,
color: "white",
height: "50px",
borderRadius: theme.palette.borderRadius,
}}
>
{environments.map((data, index) => {
if (data.archived === true) {
return null;
}
return (
{data.Name}
);
})}
) : null}
{workflow.execution_variables !== undefined &&
workflow.execution_variables !== null &&
workflow.execution_variables.length > 0 ? (
Execution variable (optional)
0
? selectedAction.execution_variable.name
: "No selection"
}
SelectDisplayProps={{
style: {
marginLeft: 10,
},
}}
fullWidth
onChange={(e) => {
if (e.target.value === "No selection") {
selectedAction.execution_variable = { name: "No selection" };
} else {
const value = workflow.execution_variables.find(
(a) => a.name === e.target.value
);
selectedAction.execution_variable = value;
}
setSelectedAction(selectedAction);
setUpdate(Math.random());
}}
style={{
backgroundColor: theme.palette.inputColor,
color: "white",
height: "50px",
borderRadius: theme.palette.borderRadius,
}}
>
No selection
{workflow.execution_variables.map((data) => (
{data.name}
))}
) : null}
{/*hideExtraTypes ? null :
Actions
*/}
{setNewSelectedAction !== undefined ? (
{
// Most popular
// Is categorized
// Uncategorized
return option.category_label !== undefined && option.category_label !== null && option.category_label.length > 0 ? "Most used" : "All Actions";
}}
renderGroup={(params) => {
return (
{params.group}
{params.children}
)
}}
options={selectedApp.actions === undefined || selectedApp.actions === null ? [] : selectedApp.actions.filter((a) => a.category_label !== undefined && a.category_label !== null && a.category_label.length > 0).concat(sortByKey(selectedApp.actions, "label"))}
ListboxProps={{
style: {
backgroundColor: theme.palette.inputColor,
color: "white",
},
}}
filterOptions={(options, { inputValue }) => {
//console.log("Option contains?: ", inputValue, options)
const lowercaseValue = inputValue.toLowerCase()
options = options.filter(x => x.name.replaceAll("_", " ").toLowerCase().includes(lowercaseValue) || x.description.toLowerCase().includes(lowercaseValue))
return options
}}
getOptionLabel={(option) => {
if (option === undefined || option === null || option.name === undefined || option.name === null ) {
return null;
}
const newname = (
option.name.charAt(0).toUpperCase() + option.name.substring(1)
).replaceAll("_", " ");
return newname;
}}
fullWidth
style={{
backgroundColor: theme.palette.inputColor,
height: 50,
borderRadius: theme.palette.borderRadius,
}}
onChange={(event, newValue) => {
// Workaround with event lol
if (newValue !== undefined && newValue !== null) {
setNewSelectedAction({
target: {
value: newValue.name
}
});
}
}}
renderOption={(data) => {
var newActionname = data.name;
if (data.label !== undefined && data.label !== null && data.label.length > 0) {
newActionname = data.label;
}
var newActiondescription = data.description;
//console.log("DESC: ", newActiondescription)
if (data.description === undefined || data.description === null) {
newActiondescription = "Description: No description defined for this action"
} else {
newActiondescription = "Description: "+newActiondescription
}
const iconInfo = GetIconInfo({ name: data.name });
const useIcon = iconInfo.originalIcon;
newActionname = (
newActionname.charAt(0).toUpperCase() +
newActionname.substring(1)
).replaceAll("_", " ");
var method = ""
var extraDescription = ""
if (data.name.includes("get_")) {
method = "GET"
} else if (data.name.includes("post_")) {
method = "POST"
} else if (data.name.includes("put_")) {
method = "PUT"
} else if (data.name.includes("patch_")) {
method = "PATCH"
} else if (data.name.includes("delete_")) {
method = "DELETE"
} else if (data.name.includes("options_")) {
method = "OPTIONS"
} else if (data.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")) {
var extraUrl = ""
const descSplit = data.description.split("\n")
// Last line of descSplit
if (descSplit.length > 0) {
extraUrl = descSplit[descSplit.length-1]
}
//for (let [line,lineval] in Object.entries(descSplit)) {
// if (descSplit[line].includes("http") && descSplit[line].includes("://")) {
// const urlsplit = descSplit[line].split("/")
// try {
// extraUrl = "/"+urlsplit.slice(3, urlsplit.length).join("/")
// } catch (e) {
// //console.log("Failed - running with -1")
// extraUrl = "/"+urlsplit.slice(3, urlsplit.length-1).join("/")
// }
// //console.log("NO BASEURL TOO!! Why missing last one in certain scenarios (sevco)?", extraUrl, urlsplit, descSplit[line])
// //break
// }
//}
if (extraUrl.length > 0) {
if (extraUrl.includes(" ")) {
extraUrl = extraUrl.split(" ")[0]
}
if (extraUrl.includes("#")) {
extraUrl = extraUrl.split("#")[0]
}
extraDescription = `${method} ${extraUrl}`
} else {
//console.log("No url found. Check again :)")
}
}
return (
{useIcon}
{newActionname}
{extraDescription.length > 0 ?
{extraDescription}
: null}
);
}}
renderInput={(params) => {
if (params.inputProps !== undefined && params.inputProps !== null && params.inputProps.value !== undefined && params.inputProps.value !== null) {
const prefixes = ["Post", "Put", "Patch"]
for (let [key,keyval] in Object.entries(prefixes)) {
if (params.inputProps.value.startsWith(prefixes[key])) {
params.inputProps.value = params.inputProps.value.replace(prefixes[key]+" ", "", -1)
if (params.inputProps.value.length > 1) {
params.inputProps.value = params.inputProps.value.charAt(0).toUpperCase()+params.inputProps.value.substring(1)
}
break
}
}
}
return (
);
}}
/>
) : null}
{/*setNewSelectedAction !== undefined ?
{sortByKey(selectedApp.actions, "label").map(data => {
var newActionname = data.name
if (data.label !== undefined && data.label !== null && data.label.length > 0) {
newActionname = data.label
}
const iconInfo = GetIconInfo({"name": data.name})
const useIcon = iconInfo.originalIcon
// ROFL FIXME - loop
newActionname = newActionname.replaceAll("_", " ")
newActionname = newActionname.charAt(0).toUpperCase()+newActionname.substring(1)
return (
{useIcon}
{newActionname}
)
})}
: null*/}
);
};
export default ParsedAction;