{visibleApps.map((app, index) => {
if (app.invalid) {
return null;
}
var extraMessage = ""
if (index == 2) {
extraMessage =
}
delay += 75
return (
runDelay ?
{/**/}
{/**/}
:
{extraMessage}
)
})}
{visibleApps.length <= 4 ? (
{
}}
>
Click one of the relevant public apps below to Activate it for your organization.
{
console.log("CLICKED")
}}>
) : null}
) : apps.length > 0 ? (
{
console.log("Should load in extra apps?")
}}
>
Couldn't find the apps you were looking for? Searching unactivated apps. Click one of the below apps to Activate it for your organization.
{
console.log("CLICKED")
}}>
) : (
Loading Apps
)}
);
};
const getNextActionName = (appName) => {
var highest = "";
const allitems = workflow.actions.concat(workflow.triggers);
if (allitems !== undefined && allitems !== null) {
for (let itemkey in allitems) {
const item = allitems[itemkey];
if (item.app_name === appName && item.label !== undefined && item.label !== null) {
var number = item.label.split("_");
if (isNaN(number[-1]) && parseInt(number[number.length - 1]) > highest) {
highest = number[number.length - 1];
}
}
}
}
appName = appName.replaceAll(" ", "_")
if (highest) {
return appName + "_" + (parseInt(highest) + 1);
} else {
return appName + "_" + 1;
}
};
const setNewSelectedAction = (e) => {
if (selectedApp.actions === undefined || selectedApp.actions === null) {
return
}
const newaction = selectedApp.actions.find(
(a) => a.name === e.target.value
);
if (newaction === undefined || newaction === null) {
toast("Failed to find the action you selected. Please try again or contact support@shuffler.io if it persists.");
return;
}
if (workflow.actions !== undefined && workflow.actions !== null) {
const foundInfo = workflow.actions.find(ac => ac.id === selectedAction.id)
}
// Setting an old reference just to use the same memory space elsewhere
// for selectedAction
const oldaction = JSON.parse(JSON.stringify(selectedAction))
// Does this one find the wrong one?
//var newSelectedAction = JSON.parse(JSON.stringify(selectedAction))
var newSelectedAction = selectedAction
newSelectedAction.name = newaction.name;
newSelectedAction.parameters = JSON.parse(JSON.stringify(newaction.parameters))
newSelectedAction.errors = [];
newSelectedAction.isValid = true;
newSelectedAction.is_valid = true;
newSelectedAction.required_body_fields = newaction.required_body_fields
console.log("New selected action: ", newSelectedAction)
// Simple action swap autocompleter
if (oldaction.parameters !== undefined && oldaction.parameters !== null && newSelectedAction.parameters !== undefined && oldaction.id === newSelectedAction.id) {
var fileid_found = false
for (let [paramkey,paramkeyval] in Object.entries(oldaction.parameters)) {
const param = oldaction.parameters[paramkey];
if (param.name === "file_id") {
fileid_found = true
}
if (param.value === null || param.value === undefined || param.value.length === 0) {
continue
}
if (param.name === "body") {
//console.log("Param: ", param)
continue
}
if (param.name === "headers") {
if (fileid_found) {
newSelectedAction.parameters[paramkey].value = ""
newSelectedAction.parameters[paramkey].autocompleted = true
continue
}
//newSelectedAction.parameters[newParamIndex].value = param.value
}
if (newSelectedAction.parameters === undefined || newSelectedAction.parameters === null) {
continue
}
// Not doing options fields
const newParamIndex = newSelectedAction.parameters.findIndex(paramdata => paramdata.name === param.name)
if (newParamIndex < 0) {
continue
}
if (newSelectedAction.parameters[newParamIndex].name === "headers") {
if (param.value !== undefined && param.value !== null && param.value.includes("=undefined")) {
if (newSelectedAction.parameters[newParamIndex].example !== undefined && newSelectedAction.parameters[newParamIndex].example !== null) {
newSelectedAction.parameters[newParamIndex].value = newSelectedAction.parameters[newParamIndex].example
} else {
newSelectedAction.parameters[newParamIndex].value = ""
}
continue
}
}
newSelectedAction.parameters[newParamIndex].value = param.value
newSelectedAction.parameters[newParamIndex].autocompleted = true
if (param.options !== undefined && param.options !== null && param.options.length > 0) {
newSelectedAction.parameters[newParamIndex].autocompleted = false
}
}
}
if (newSelectedAction.app_name === "Shuffle Tools") {
const iconInfo = GetIconInfo(newSelectedAction);
console.log("ICONINFO: ", iconInfo);
const svg_pin = ``;
const svgpin_Url = encodeURI("data:image/svg+xml;utf-8," + svg_pin);
newSelectedAction.large_image = svgpin_Url;
newSelectedAction.fillGradient = iconInfo.fillGradient;
newSelectedAction.fillstyle = "solid";
if (
newSelectedAction.fillGradient !== undefined &&
newSelectedAction.fillGradient !== null &&
newSelectedAction.fillGradient.length > 0
) {
newSelectedAction.fillstyle = "linear-gradient";
} else {
newSelectedAction.iconBackground = iconInfo.iconBackgroundColor;
}
const foundnode = cy.getElementById(newSelectedAction.id);
if (foundnode !== null && foundnode !== undefined) {
foundnode.data(newSelectedAction);
}
}
// Takes an action as input, then runs through and updates the relevant parameters based on previous actions' results (parent nodes)
// Further checks if those fields are already set in a previously used action
newSelectedAction = RunAutocompleter(newSelectedAction);
if (
newaction.returns.example !== undefined &&
newaction.returns.example !== null &&
newaction.returns.example.length > 0
) {
newSelectedAction.example = newaction.returns.example;
}
if (
newaction.description !== undefined &&
newaction.description !== null &&
newaction.description.length > 0
) {
newSelectedAction.description = newaction.description
}
// FIXME - this is broken sometimes lol
//var env = environments.find(a => a.Name === newaction.environment)
//if ((!env || env === undefined) && selectedAction.environment === undefined ) {
// env = environments[defaultEnvironmentIndex]
//}
//setSelectedActionEnvironment(env)
if (workflow.actions !== undefined && workflow.actions !== null && workflow.actions.length > 0) {
const foundActionIndex = workflow.actions.findIndex(actiondata => actiondata.id === newSelectedAction.id)
if (foundActionIndex >= 0) {
workflow.actions[foundActionIndex] = newSelectedAction
setWorkflow(workflow)
}
}
setSelectedAction(newSelectedAction);
setUpdate(Math.random());
const allNodes = cy.nodes().jsons();
if (allNodes !== undefined && allNodes !== null) {
for (let nodekey in allNodes) {
const currentNode = allNodes[nodekey];
if (
currentNode.data.attachedTo === oldaction.id &&
currentNode.data.isDescriptor
) {
const foundnode = cy.getElementById(currentNode.data.id);
if (foundnode !== null && foundnode !== undefined) {
const iconInfo = GetIconInfo(newaction);
const svg_pin = ``;
const svgpin_Url = encodeURI("data:image/svg+xml;utf-8," + svg_pin);
foundnode.data("image", svgpin_Url);
foundnode.data("imageColor", iconInfo.iconBackgroundColor);
}
break;
}
}
}
// Send it in here, after all fields are filled
// Disabled for now :(
// const aiMsg = "Fill based on previous values"
// aiSubmit(aiMsg, undefined, undefined, newSelectedAction)
};
// APPSELECT at top
// appname & version
// description
// ACTION select
const selectedNameChange = (event) => {
event.target.value = event.target.value.replaceAll("(", "");
event.target.value = event.target.value.replaceAll(")", "");
event.target.value = event.target.value.replaceAll("]", "");
event.target.value = event.target.value.replaceAll("[", "");
event.target.value = event.target.value.replaceAll("{", "");
event.target.value = event.target.value.replaceAll("}", "");
event.target.value = event.target.value.replaceAll("*", "");
event.target.value = event.target.value.replaceAll("!", "");
event.target.value = event.target.value.replaceAll("@", "");
event.target.value = event.target.value.replaceAll("#", "");
event.target.value = event.target.value.replaceAll("$", "");
event.target.value = event.target.value.replaceAll("%", "");
event.target.value = event.target.value.replaceAll("&", "");
event.target.value = event.target.value.replaceAll("#", "");
event.target.value = event.target.value.replaceAll(".", "");
event.target.value = event.target.value.replaceAll(",", "");
event.target.value = event.target.value.replaceAll(" ", "_");
event.target.value = event.target.value.replaceAll("^", "_");
event.target.value = event.target.value.replaceAll("'", "_");
event.target.value = event.target.value.replaceAll("\"", "_");
event.target.value = event.target.value.replaceAll("\\", "_");
event.target.value = event.target.value.replaceAll(":", "_");
event.target.value = event.target.value.replaceAll(";", "_");
event.target.value = event.target.value.replaceAll("=", "_");
event.target.value = event.target.value.replaceAll("+", "_");
selectedAction.label = event.target.value;
setSelectedAction(selectedAction);
};
const actionDelayChange = (event) => {
if (isNaN(event.target.value)) {
console.log("NAN: ", event.target.value)
return
}
const parsedNumber = parseInt(event.target.value)
if (parsedNumber > 86400) {
console.log("Max number is 1 day (86400)")
return
}
selectedAction.execution_delay = parsedNumber
setSelectedAction(selectedAction)
}
const selectedTriggerChange = (event) => {
selectedTrigger.label = event.target.value;
setSelectedTrigger(selectedTrigger);
};
// Starts on current node and climbs UP the tree to the root object.
// Sends back everything in it's path
const getParents = (action) => {
if (action === undefined || action === null) {
return []
}
var allkeys = [action.id];
var handled = [];
var results = [];
// maxiter = max amount of parent nodes to loop
// also handles breaks if there are issues
var iterations = 0;
var maxiter = 10;
while (true) {
for (let parentkey in allkeys) {
var currentnode = cy.getElementById(allkeys[parentkey]);
if (currentnode === undefined || currentnode === null) {
continue;
}
if (currentnode.data() === undefined) {
handled.push(allkeys[parentkey]);
results.push({ id: allkeys[parentkey], type: "TRIGGER" });
} else {
if (handled.includes(currentnode.data().id)) {
continue;
} else {
handled.push(currentnode.data().id);
results.push(currentnode.data());
}
}
// Get the name / label here too?
if (currentnode.length === 0) {
continue;
}
const incomingEdges = currentnode.incomers("edge");
if (incomingEdges.length === 0) {
continue;
}
for (let i = 0; i < incomingEdges.length; i++) {
var tmp = incomingEdges[i];
if (tmp.data("decorator")) {
continue
}
if (!allkeys.includes(tmp.data("source"))) {
allkeys.push(tmp.data("source"));
}
}
}
if (results.length === allkeys.length || iterations === maxiter) {
break;
}
iterations += 1;
}
// Remove on the end as we don't want to remove everything
results = results.filter((data) => data.id !== action.id);
results = results.filter((data) => data.type === "ACTION" || data.app_name === "Shuffle Workflow" || data.app_name === "User Input");
results.push({ label: "Execution Argument", type: "INTERNAL" });
return results;
};
// BOLD name: type: required?
// FORM
// Dropdown -> static, action, local env, global env
// VALUE (JSON)
// {data.name}, {data.description}, {data.required}, {data.schema.type}
//height: "100%",
const appApiViewStyle = {
display: "flex",
flexDirection: "column",
backgroundColor: "#1F2023",
color: "white",
paddingRight: 15,
paddingLeft: 15,
minHeight: "100%",
zIndex: 1000,
resize: "vertical",
overflow: "auto",
paddingBottom: 100,
overflowAnchor: "none",
};
const minSize = 370
var rightsidebarStyle = {
position: "fixed",
top: appBarSize + 25,
right: 25,
height: "80vh",
width: isMobile ? "100%" : minSize,
minWidth: minSize,
maxWidth: 600,
maxHeight: "100vh",
border: "1px solid rgb(91, 96, 100)",
zIndex: 1000,
borderRadius: theme.palette.borderRadius,
resize: "both",
overflow: "auto",
overflowAnchor: "none",
};
const setTriggerFolderWrapperMulti = (event) => {
const { options } = event.target;
var value = [];
for (let i = 0, l = options.length; i < l; i += 1) {
if (options[i].selected) {
value.push(options[i].value);
}
}
if (selectedTrigger.parameters === null) {
selectedTrigger.parameters = [[]];
workflow.triggers[selectedTriggerIndex].parameters = [[]];
}
// Max 1 folder for office for some reason. MailFolders('MAILBOX_ID') in resource
// Can't parse URL with multiple folders.
if (selectedTrigger.name === "Office365" & value !== undefined && value !== null && value.length > 1) {
toast("Max 1 folder at a time allowed for Office365")
console.log("VALUE: ", value)
value = [value[0]]
}
// This is a dirty workaround for the static values in the go backend and datastore db
const fixedValue = value.join(splitter);
selectedTrigger.parameters[0] = {
value: fixedValue,
name: "outlookfolder",
};
workflow.triggers[selectedTriggerIndex].parameters[0] = {
value: fixedValue,
name: "outlookfolder",
};
// This resets state for some reason (:
setSelectedAction({});
setSelectedTrigger({});
setSelectedApp({});
setSelectedEdge({});
// Set value
setSelectedTrigger(selectedTrigger);
setWorkflow(workflow);
};
const setTriggerCronWrapper = (value) => {
console.log("Cron Value: ", value)
if (selectedTrigger.parameters === null) {
selectedTrigger.parameters = [];
}
workflow.triggers[selectedTriggerIndex].parameters[0] = {
value: value,
name: "cron",
};
setWorkflow(workflow);
};
const setTriggerOptionsWrapper = (value) => {
if (selectedTrigger.parameters === null || selectedTrigger.parameters === undefined) {
selectedTrigger.parameters = [
{ name: "", value: "" },
{ name: "", value: "" },
{ name: "", value: "" },
]
}
if (selectedTrigger.parameters.length < 3 ) {
selectedTrigger.parameters.push({ name: "", value: "" })
}
const splitItems = workflow.triggers[selectedTriggerIndex].parameters[2].value.split(",");
console.log(splitItems);
if (splitItems.includes(value)) {
for (let i = 0; i < splitItems.length; i++) {
if (splitItems[i] === value) {
splitItems.splice(i, 1);
}
}
} else {
splitItems.push(value);
}
for (let i = 0; i < splitItems.length; i++) {
if (splitItems[i] === "") {
splitItems.splice(i, 1);
}
}
workflow.triggers[selectedTriggerIndex].parameters[2].value = splitItems.join(",");
setWorkflow(workflow);
setLocalFirstrequest(!localFirstrequest);
setUpdate(Math.random());
};
const setTriggerTextInformationWrapper = (value) => {
if (selectedTrigger.parameters === null) {
selectedTrigger.parameters = [];
}
workflow.triggers[selectedTriggerIndex].parameters[0] = {
value: value,
name: "alertinfo",
};
setWorkflow(workflow);
};
const setTriggerBodyWrapper = (value) => {
if (selectedTrigger.parameters === null) {
selectedTrigger.parameters = [];
workflow.triggers[selectedTriggerIndex].parameters[0] = {
value: value,
name: "cron",
};
}
workflow.triggers[selectedTriggerIndex].parameters[1] = {
value: value,
name: "execution_argument",
};
setWorkflow(workflow);
};
const AppConditionHandler = (props) => {
const { tmpdata, type } = props;
const [data] = useState(tmpdata);
const [multiline, setMultiline] = useState(false);
const [showAutocomplete, setShowAutocomplete] = React.useState(false);
const [actionlist, setActionlist] = React.useState([]);
if (tmpdata === undefined) {
return tmpdata;
}
if (data.variant === "") {
data.variant = "STATIC_VALUE";
}
// Set actions based on NEXT node, since it should be able to involve those two
if (actionlist.length === 0) {
// FIXME: Have previous execution values in here
actionlist.push({
type: "Execution Argument",
name: "Execution Argument",
value: "$exec",
highlight: "exec",
autocomplete: "exec",
example: "tmp",
})
actionlist.push({
type: "Shuffle DB",
name: "Shuffle DB",
value: "$shuffle_cache",
highlight: "shuffle_cache",
autocomplete: "shuffle_cache",
example: "tmp",
})
if (workflow.workflow_variables !== null && workflow.workflow_variables !== undefined && workflow.workflow_variables.length > 0) {
for (let varkey in workflow.workflow_variables) {
const item = workflow.workflow_variables[varkey];
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 varkey in workflow.execution_variables) {
const item = workflow.execution_variables[varkey];
actionlist.push({
type: "execution_variable",
name: item.name,
value: item.value,
id: item.id,
autocomplete: `${item.name.split(" ").join("_")}`,
example: "",
});
}
}
const destAction = cy.getElementById(selectedEdge.target);
var parents = getParents(destAction.data());
if (parents.length > 1) {
for (let parentkey in parents) {
const item = parents[parentkey];
if (item.label === "Execution Argument") {
continue;
}
// 1. Take
const actionvalue = {
type: "action",
id: item.id,
name: item.label,
autocomplete: `${item.label.split(" ").join("_")}`,
example: item.example === undefined ? "" : item.example,
};
actionlist.push(actionvalue);
}
}
setActionlist(actionlist);
}
if (
data.multiline !== undefined &&
data.multiline !== null &&
data.multiline === true
) {
setMultiline(true);
}
var placeholder = "Static value";
if (
data.example !== undefined &&
data.example !== null &&
data.example.length > 0
) {
placeholder = data.example;
}
var datafield = (
Use "Shuffle Tools" app with "Filter List" action to handle loops
) : null
}
onBlur={(e) => {
changeActionVariable(data.action_field, e.target.value);
setUpdate(Math.random());
}}
/>
);
const changeActionVariable = (variable, value) => {
// set the name
data.value = value;
data.action_field = variable;
if (type === "source") {
setSourceValue(data);
} else if (type === "destination") {
setDestinationValue(data);
}
};
return (
{injectedData}
{/* Check if dest is the same as start */}
{conditionsDisabled ?
Conditions are unavailable between triggers and the startnode.
: null}
);
};
// 1. GET the trigger authentication data
// 2. Parse the fields that are used (outlook & gmail)
// 3. Parse the folders that are selected
// 4. Start / stop
const EmailSidebar = () => {
if (Object.getOwnPropertyNames(selectedTrigger).length === 0) {
return null;
}
if (workflow.triggers[selectedTriggerIndex] === undefined) {
return null;
}
if (
workflow.triggers[selectedTriggerIndex].parameters === undefined ||
workflow.triggers[selectedTriggerIndex].parameters === null ||
workflow.triggers[selectedTriggerIndex].parameters.length === 0
) {
workflow.triggers[selectedTriggerIndex].parameters = [
{ value: "No folders selected yet", name: "outlookfolder" },
];
selectedTrigger.parameters = [
{ value: "No folders selected yet", name: "outlookfolder" },
];
setWorkflow(workflow);
setSelectedTrigger(selectedTrigger);
}
const setGmailFolders = () => {
console.log("In set gmail folders");
fetch(
globalUrl +
"/api/v1/triggers/gmail/getFolders?trigger_id=" +
selectedTrigger.id,
{
method: "GET",
headers: { "content-type": "application/json" },
credentials: "include",
}
)
.then((response) => {
if (response.status !== 200) {
throw new Error("No folders :o!");
}
return response.json();
})
.then((responseJson) => {
if (
responseJson !== undefined &&
responseJson !== null &&
responseJson.success !== false &&
responseJson.length > 0
) {
setTriggerFolders(responseJson);
}
if (
workflow.triggers[selectedTriggerIndex].parameters.length === 0 &&
responseJson.length > 0
) {
workflow.triggers[selectedTriggerIndex].parameters = [
{
value: responseJson[0].displayName,
name: "outlookfolder",
id: responseJson[0].id,
},
];
selectedTrigger.parameters = [
{
value: responseJson[0].displayName,
name: "outlookfolder",
id: responseJson[0].id,
},
];
setWorkflow(workflow);
setSelectedTrigger(selectedTrigger);
}
})
.catch((error) => {
console.log("Get gmail folder error: ", error.toString());
});
};
const setOutlookFolders = () => {
fetch(
globalUrl +
"/api/v1/triggers/outlook/getFolders?trigger_id=" +
selectedTrigger.id,
{
method: "GET",
headers: { "content-type": "application/json" },
credentials: "include",
}
)
.then((response) => {
if (response.status !== 200) {
throw new Error("No folders :o!");
}
return response.json();
})
.then((responseJson) => {
if (
responseJson !== null &&
responseJson.success !== false &&
responseJson.length > 0
) {
console.log("Got trigger folders: ", triggerFolders)
setTriggerFolders(responseJson);
}
if (
workflow.triggers[selectedTriggerIndex].parameters.length === 0 &&
responseJson.length > 0
) {
workflow.triggers[selectedTriggerIndex].parameters = [
{
value: responseJson[0].displayName,
name: "outlookfolder",
id: responseJson[0].id,
},
]
selectedTrigger.parameters = [
{
value: responseJson[0].displayName,
name: "outlookfolder",
id: responseJson[0].id,
},
];
setWorkflow(workflow);
setSelectedTrigger(selectedTrigger);
}
})
.catch((error) => {
console.log("Get outlook folders error: ", error.toString());
});
};
const getTriggerAuth = () => {
fetch(`${globalUrl}/api/v1/triggers/${selectedTrigger.id}`, {
method: "GET",
headers: { "content-type": "application/json" },
credentials: "include",
})
.then((response) => {
if (response.status !== 200) {
throw new Error("No trigger info :o!");
}
return response.json();
})
.then((responseJson) => {
setTriggerAuthentication(responseJson);
})
.catch((error) => {
//console.log(error.toString());
console.log("Set trigger auth error: ", error.toString());
});
};
// Getting the triggers and the folders if they exist
if (localFirstrequest) {
//console.log("Trigger: ", selectedTrigger)
//console.log("Triggername: ", selectedTrigger.name)
//if (selectedTrigger.name.toLowerCase() === "gmail") {
setGmailFolders();
setOutlookFolders();
getTriggerAuth();
setLocalFirstrequest(false);
}
const gmailButton =
selectedTrigger.name !== "Gmail" ? null : (
);
const outlookButton =
selectedTrigger.name !== "Office365" ? null : (
);
// FIXME - set everything in here to multifolder etc
var triggerInfo = "SET UP BUT NO TYPE :)";
if (Object.getOwnPropertyNames(triggerAuthentication).length > 0) {
// Should get the folders if they don't already exist
if (
triggerAuthentication.type === "outlook" ||
triggerAuthentication.type === "gmail"
) {
triggerInfo = (
{selectedTrigger.status === "running" ? null : (
Change auth
{outlookButton}
{gmailButton}
If you have trouble using this trigger, please contact us to get access
)}
{triggerFolders === undefined || triggerFolders === null ? null : (
Select {triggerAuthentication.type === "gmail" ? "labels" : "a folder"}
{triggerFolders.length === 0 ?
No folders found. Please authenticate first. If this persists, contact us.
:
}
)}
{outlookButton}
{gmailButton}
If you have trouble using this trigger, please {
if (window.drift !== undefined) {
window.drift.api.startInteraction({ interactionId: 340043 })
} else {
console.log("Couldn't find drift in window.drift and not .drift-open-chat with querySelector: ", window.drift)
}
}}>contact us to get access
{workflow.triggers[selectedTriggerIndex].parameters.length > 4 ?
{
if (selectedTrigger.parameters === null) {
selectedTrigger.parameters = [];
}
// Sets the webhook to run as version 2.. kinda
var value = "v2"
if (workflow.triggers[selectedTriggerIndex].parameters[4].value.includes("v2")) {
value = "v1"
}
workflow.triggers[selectedTriggerIndex].parameters[4] = {
name: "await_response",
value: value
}
setWorkflow(workflow)
setUpdate(Math.random())
}}
color="primary"
value="await_response"
/>
}
label={
);
//return null;
};
// This can execute a workflow with firestore. Used for test, as datastore is old and stuff
// Too much work to move everything over alone, so won't touch it for now
//
//
// A list used for FRONTEND handling of whether a public workflow
// should be change-able
const allowList = ["frikky", "m1nk-code", "DavidtheGoliath"]
// console.log(allowList, userdata.public_username)
const leftView = workflow.public === true ?
{workflow.name}
This workflow is public and {
saveWorkflow()
}}>must be saved or exported before use.
{Object.getOwnPropertyNames(creatorProfile).length !== 0 && creatorProfile.github_avatar !== undefined && creatorProfile.github_avatar !== null ?
{environments.length > 0 && defaultEnvironmentIndex < environments.length && nonskippedResults.length === 0 && environments[defaultEnvironmentIndex].Name !== "Cloud" ?
No results yet. Is Orborus running for the "{environments[defaultEnvironmentIndex].Name}" environment? Learn more. If the Workflow doesn't start within 30 seconds with Orborus running, contact support: support@shuffler.io
:
null}
) : (
{/**/}
{
// FIXME: There's something specific loading when
// you do the first hover of a node. Why is this different?
setCy(incy);
}}
/>
)}
{executionModal}
{/* Looks for triggers" */}
{/* Only fixed the ones that require scrolling on a small screen */}
{/* Most important: Actions. But these are a lot more complex */}
{rightSideBarOpen && (selectedTrigger.trigger_type === "SCHEDULE" || selectedTrigger.trigger_type === "WEBHOOK") ?
Authentication for {selectedApp.name.replaceAll("_", " ", -1)}
What is app authentication?
These are required fields for authenticating with {selectedApp.name}
Name - what is this used for? {
authenticationOption.label = event.target.value;
}}
/>
{selectedApp.authentication.parameters.map((data, index) => {
return (