enabled user input subflows and fixed bugs
This commit is contained in:
@@ -910,7 +910,9 @@ const AppFramework = (props) => {
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
handleLoadNextSuggestion(frameworkData)
|
||||
if (!window.location.pathname.includes("usecases")) {
|
||||
handleLoadNextSuggestion(frameworkData)
|
||||
}
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
@@ -985,9 +987,8 @@ const AppFramework = (props) => {
|
||||
}, [newSelectedApp])
|
||||
|
||||
|
||||
const isCloud =
|
||||
window.location.host === "localhost:3002" ||
|
||||
window.location.host === "shuffler.io";
|
||||
const isCloud = window.location.host === "localhost:3002" || window.location.host === "shuffler.io";
|
||||
|
||||
|
||||
const imgSize = 50;
|
||||
var parsedFrameworkData = frameworkData === undefined ? {} : frameworkData
|
||||
@@ -1906,7 +1907,7 @@ const AppFramework = (props) => {
|
||||
/>
|
||||
</div>
|
||||
|
||||
{injectedApps.map((apps) => {
|
||||
{injectedApps.map((apps, appindex) => {
|
||||
var categoryTop = 100
|
||||
var categoryLeft = 100
|
||||
|
||||
@@ -1934,7 +1935,7 @@ const AppFramework = (props) => {
|
||||
}
|
||||
|
||||
return (
|
||||
<div style={{display: "flex", position: "absolute", top: categoryTop, left: categoryLeft, zIndex: 10010, }}>
|
||||
<div key={appindex} style={{display: "flex", position: "absolute", top: categoryTop, left: categoryLeft, zIndex: 10010, }}>
|
||||
{apps.map((app, appIndex) => {
|
||||
return (
|
||||
<Chip
|
||||
|
||||
@@ -170,10 +170,7 @@ const ConfigureWorkflow = (props) => {
|
||||
"required": true,
|
||||
})
|
||||
} else {
|
||||
if (
|
||||
action.authentication_id === "" &&
|
||||
app.authentication.required === true
|
||||
) {
|
||||
if (action.authentication_id === "" && app.authentication.required === true && action.parameters !== undefined && action.parameters !== null) {
|
||||
// Check if configuration is filled or not
|
||||
var filled = true;
|
||||
for (let [key,keyval] in Object.entries(action.parameters)) {
|
||||
|
||||
@@ -701,10 +701,7 @@ const ParsedAction = (props) => {
|
||||
}
|
||||
|
||||
// bad detection mechanism probably
|
||||
if (
|
||||
event.target.value[event.target.value.length - 1] === "." &&
|
||||
actionlist.length > 0
|
||||
) {
|
||||
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
|
||||
/*
|
||||
@@ -2098,6 +2095,8 @@ const ParsedAction = (props) => {
|
||||
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);
|
||||
@@ -2131,10 +2130,8 @@ const ParsedAction = (props) => {
|
||||
}
|
||||
}
|
||||
|
||||
selectedActionParameters[count]["value_replace"] =
|
||||
paramcheck;
|
||||
selectedAction.parameters[count]["value_replace"] =
|
||||
paramcheck;
|
||||
selectedActionParameters[count]["value_replace"] = paramcheck;
|
||||
selectedAction.parameters[count]["value_replace"] = paramcheck;
|
||||
setSelectedAction(selectedAction);
|
||||
setUpdate(Math.random());
|
||||
|
||||
@@ -2144,13 +2141,15 @@ const ParsedAction = (props) => {
|
||||
}
|
||||
}
|
||||
|
||||
selectedActionParameters[count].value += toComplete;
|
||||
selectedAction.parameters[count].value =
|
||||
selectedActionParameters[count].value;
|
||||
setSelectedAction(selectedAction);
|
||||
setUpdate(Math.random());
|
||||
|
||||
setShowDropdown(false);
|
||||
console.log("In nestedclick!!")
|
||||
var newValue = selectedActionParameters[count].value + toComplete
|
||||
changeActionParameter({target: {value: newValue}}, count, data)
|
||||
//selectedActionParameters[count].value += toComplete;
|
||||
//selectedAction.parameters[count].value = selectedActionParameters[count].value;
|
||||
//setSelectedAction(selectedAction);
|
||||
//setUpdate(Math.random());
|
||||
|
||||
setShowDropdown(false);
|
||||
setMenuPosition(null);
|
||||
};
|
||||
|
||||
@@ -2604,7 +2603,9 @@ const ParsedAction = (props) => {
|
||||
|
||||
setUpdate(Math.random());
|
||||
}}
|
||||
onClick={() => setShowAutocomplete(true)}
|
||||
onClick={() => {
|
||||
setShowAutocomplete(true)
|
||||
}}
|
||||
fullWidth
|
||||
open={showAutocomplete}
|
||||
style={{
|
||||
@@ -2614,22 +2615,12 @@ const ParsedAction = (props) => {
|
||||
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
|
||||
);
|
||||
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;
|
||||
selectedActionParameters[count].value += e.target.value.autocomplete;
|
||||
selectedAction.parameters[count].value = selectedActionParameters[count].value;
|
||||
setSelectedAction(selectedAction);
|
||||
setUpdate(Math.random());
|
||||
|
||||
@@ -2973,108 +2964,110 @@ const ParsedAction = (props) => {
|
||||
// Should make it a function lol
|
||||
if (workflow.branches !== undefined && workflow.branches !== null) {
|
||||
for (let [key,keyval] in Object.entries(workflow.branches)) {
|
||||
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
|
||||
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
|
||||
}
|
||||
}
|
||||
// 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
|
||||
|
||||
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)
|
||||
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
|
||||
}
|
||||
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
|
||||
}
|
||||
// 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)
|
||||
}
|
||||
} 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
|
||||
}
|
||||
}
|
||||
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
|
||||
|
||||
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)
|
||||
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
|
||||
}
|
||||
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
|
||||
}
|
||||
// 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)
|
||||
}
|
||||
} catch (e) {
|
||||
console.log("Failed value replacement based on index: ", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,8 +54,14 @@ import { useNavigate, Link, useParams } from "react-router-dom";
|
||||
const liquidFilters = [
|
||||
{"name": "Size", "value": "size", "example": ""},
|
||||
{"name": "Date", "value": `date: "%Y%m%d"`, "example": `{{ "now" | date: "%s" }}`},
|
||||
{"name": "Split", "value": `split: ","`, "example": `{{ "this,can,become,a,list" | split: "," }}`},
|
||||
{"name": "Join", "value": `join: ","`, "example": `{{ ["this","can","become","a","string"] | join: "," }}`},
|
||||
{"name": "Escape String", "value": `{{ \"\"\"'string with weird'" quotes\"\"\" | escape_string }}`, "example": ``},
|
||||
{"name": "Flatten", "value": `flatten`, "example": `{{ [1, [1, 2], [2, 3, 4]] | flatten }}`},
|
||||
{"name": "URL encode", "value": `url_encode`, "example": `{{ "https://www.google.com/search?q=hello world" | url_encode }}`},
|
||||
{"name": "URL decode ", "value": `url_decode`, "example": `{{ "https://www.google.com/search?q=hello%20world" | url_decode }}`},
|
||||
{"name": "base64_encode", "value": `base64_encode`, "example": `{{ "https://www.google.com/search?q=hello%20world" | base64_encode }}`},
|
||||
{"name": "base64_decode", "value": `base64_decode`, "example": `{{ "aGVsbG8K" | base64_encode }}`},
|
||||
]
|
||||
|
||||
const mathFilters = [
|
||||
@@ -426,10 +432,11 @@ const CodeEditor = (props) => {
|
||||
if(fixedVariable.slice(1,).toLowerCase() === actionlist[j].autocomplete.toLowerCase()){
|
||||
valuefound = true
|
||||
|
||||
console.log("Valuefound: ", fixedVariable, actionlist[j].example)
|
||||
|
||||
try {
|
||||
if (actionlist[j].example.trim().startsWith("{") || actionlist[j].example.trim().startsWith("[")) {
|
||||
if (typeof actionlist[j].example === "object") {
|
||||
input = input.replace(fixedVariable, JSON.stringify(actionlist[j].example));
|
||||
|
||||
} else if (actionlist[j].example.trim().startsWith("{") || actionlist[j].example.trim().startsWith("[")) {
|
||||
input = input.replace(fixedVariable, JSON.stringify(actionlist[j].example));
|
||||
} else {
|
||||
input = input.replace(fixedVariable, actionlist[j].example)
|
||||
@@ -438,6 +445,7 @@ const CodeEditor = (props) => {
|
||||
input = input.replace(fixedVariable, actionlist[j].example)
|
||||
}
|
||||
} else {
|
||||
// Couldn't find the correct example value
|
||||
}
|
||||
}
|
||||
|
||||
@@ -565,12 +573,14 @@ const CodeEditor = (props) => {
|
||||
inputdata = JSON.stringify(inputdata)
|
||||
}
|
||||
|
||||
// Shuffle Tools 1.2.0 (in most cases?)
|
||||
const appid = "3e2bdf9d5069fe3f4746c29d68785a6a"
|
||||
const actiondata = {"description":"Repeats the call parameter","id":"","name":"repeat_back_to_me","label":"","node_type":"","environment":"","sharing":false,"private_id":"","public_id":"","app_id":"3e2bdf9d5069fe3f4746c29d68785a6a","tags":null,"authentication":[],"tested":false,"parameters":[{"description":"The message to repeat","id":"","name":"call","example":"REPEATING: Hello world","value":inputdata,"multiline":true,"options":null,"action_field":"","variant":"STATIC_VALUE","required":true,"configuration":false,"tags":null,"schema":{"type":"string"},"skip_multicheck":false,"value_replace":null,"unique_toggled":false,"autocompleted":false}],"execution_variable":{"description":"","id":"","name":"","value":""},"returns":{"description":"","example":"","id":"","schema":{"type":"string"}},"authentication_id":"","example":"","auth_not_required":false,"source_workflow":"","run_magic_output":false,"run_magic_input":false,"execution_delay":0,"app_name":"Shuffle Tools","app_version":"1.2.0","selectedAuthentication":{}}
|
||||
|
||||
setExecutionResult({
|
||||
"valid": false,
|
||||
"result": baseResult,
|
||||
"errors": [],
|
||||
})
|
||||
|
||||
setExecuting(true)
|
||||
@@ -593,21 +603,27 @@ const CodeEditor = (props) => {
|
||||
})
|
||||
.then((responseJson) => {
|
||||
//console.log("RESPONSE: ", responseJson)
|
||||
var newResult = {}
|
||||
if (responseJson.success === true && responseJson.result !== null && responseJson.result !== undefined && responseJson.result.length > 0) {
|
||||
const result = responseJson.result.slice(0, 50)+"..."
|
||||
//alert.info("SUCCESS: "+result)
|
||||
|
||||
const validate = validateJson(responseJson.result)
|
||||
setExecutionResult(validate)
|
||||
newResult = validate
|
||||
} else if (responseJson.success === false && responseJson.reason !== undefined && responseJson.reason !== null) {
|
||||
alert.error(responseJson.reason)
|
||||
setExecutionResult({"valid": false, "result": responseJson.reason})
|
||||
newResult = {"valid": false, "result": responseJson.reason}
|
||||
} else if (responseJson.success === true) {
|
||||
setExecutionResult({"valid": false, "result": "Couldn't finish execution. Please fill all the required fields, and retry the execution."})
|
||||
newResult = {"valid": false, "result": "Couldn't finish execution. Please fill all the required fields, and retry the execution."}
|
||||
} else {
|
||||
setExecutionResult({"valid": false, "result": "Couldn't finish execution (2). Please fill all the required fields, and validate the execution."})
|
||||
newResult = {"valid": false, "result": "Couldn't finish execution (2). Please fill all the required fields, and validate the execution."}
|
||||
}
|
||||
|
||||
|
||||
if (responseJson.errors !== undefined && responseJson.errors !== null && responseJson.errors.length > 0) {
|
||||
newResult.errors = responseJson.errors
|
||||
}
|
||||
|
||||
setExecutionResult(newResult)
|
||||
setExecuting(false)
|
||||
})
|
||||
.catch(error => {
|
||||
@@ -1262,7 +1278,7 @@ const CodeEditor = (props) => {
|
||||
<IconButton disabled={executing} color="primary" style={{border: `1px solid ${theme.palette.primary.main}`, marginLeft: 300, padding: 8}} variant="contained" onClick={() => {
|
||||
executeSingleAction(expOutput)
|
||||
}}>
|
||||
<Tooltip title="Try it! This runs the Shuffle Tools 'repeat back to me' action with what you see in the expected output window." placement="top">
|
||||
<Tooltip title="Try it! This runs the Shuffle Tools 'repeat back to me' action with what you see in the expected output window. Commonly used to test your Python scripts or Liquid filters, not requiring the full workflow to run again." placement="top">
|
||||
{executing ? <CircularProgress style={{height: 18, width: 18, }} /> : <PlayArrowIcon style={{height: 18, width: 18, }} /> }
|
||||
|
||||
</Tooltip>
|
||||
@@ -1340,6 +1356,11 @@ const CodeEditor = (props) => {
|
||||
Test output: {executionResult.result}
|
||||
</Typography>
|
||||
: null}
|
||||
{executionResult.errors !== undefined && executionResult.errors !== null && executionResult.errors.length > 0 ?
|
||||
<Typography variant="body2" style={{maxHeight: 100, overflow: "auto", color: "#f85a3e",}}>
|
||||
Errors ({executionResult.errors.length}): {executionResult.errors.join("\n")}
|
||||
</Typography>
|
||||
: null}
|
||||
</span>
|
||||
}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user