Moved over relevant files

This commit is contained in:
Frikky
2024-11-27 10:46:59 +01:00
parent 11e313c885
commit cf7d744273
7 changed files with 459 additions and 369 deletions
+4 -5
View File
@@ -153,10 +153,9 @@ const AuthenticationOauth2 = (props) => {
}
}, [])
if (selectedApp.authentication === undefined) {
return null;
}
if (selectedApp.authentication === undefined) {
return null;
}
const startOauth2Request = (admin_consent) => {
// Admin consent also means to add refresh tokens
@@ -758,7 +757,7 @@ const AuthenticationOauth2 = (props) => {
<div />
</span>
{isCloud && registeredApps.includes(selectedApp.name.toLowerCase()) ?
{isCloud && registeredApps?.includes(selectedApp?.name?.replaceAll(" ", "_").toLowerCase()) ?
<span>
<span style={{display: "flex"}}>
{autoAuthButton}
+239 -203
View File
@@ -180,7 +180,7 @@ const ParsedAction = (props) => {
let navigate = useNavigate();
const classes = useStyles();
const [hideBody, setHideBody] = React.useState(true)
const [hideBody, setHideBody] = React.useState(false)
const [activateHidingBodyButton, setActivateHidingBodyButton] = React.useState(false)
const [appActionName, setAppActionName] = React.useState(selectedAction?.label);
const [delay, setDelay] = React.useState(selectedAction?.execution_delay || 0);
@@ -207,15 +207,16 @@ const ParsedAction = (props) => {
}
}, [expansionModalOpen])
useEffect(() => {
// Changes the order of params to show in order:
// auth, required, optional
/*
var changed = false
if (selectedActionParameters === undefined || selectedActionParameters === null || selectedActionParameters.length === 0) {
return
}
// Check if missing parameters?
var auth = []
var required = []
var optional = []
@@ -234,6 +235,10 @@ const ParsedAction = (props) => {
param.value = ""
}
if (selectedApp?.generated === true && param?.name === "body") {
param.required = true
}
if (param.required) {
required.push(param)
continue
@@ -255,12 +260,17 @@ const ParsedAction = (props) => {
selectedAction.parameters = newparams
setSelectedAction(selectedAction)
}
*/
}, [selectedActionParameters])
useEffect(() => {
const shouldHide = localStorage.getItem("hideBody")
if (shouldHide !== null) {
const ishiding = shouldHide !== "true"
if (ishiding !== hideBody) {
setHideBody(ishiding)
}
}
if (selectedActionEnvironment === undefined || selectedActionEnvironment === null || Object.keys(selectedActionEnvironment).length === 0) {
if (environments !== undefined && environments !== null && environments.length > 0) {
@@ -276,28 +286,6 @@ const ParsedAction = (props) => {
}
}, [])
useEffect(() => {
if (selectedAction.parameters === null || selectedAction.parameters === undefined) {
return
}
const paramcheck = selectedAction.parameters.find(param => param.name === "body")
if (paramcheck === undefined || paramcheck === null) {
return
}
// This was just opposite..
if (paramcheck.id === "TOGGLED"){
setHideBody(true)
} else {
setHideBody(false)
if (paramcheck.id === "UNTOGGLED") {
setActivateHidingBodyButton(false)
}
}
}, [])
const keywords = [
"len(",
"lower(",
@@ -456,38 +444,41 @@ const ParsedAction = (props) => {
};
useEffect(
() => {
// Only set app action name if it has changed
if (selectedAction.label !== appActionName) {
setAppActionName(selectedAction.label);
}
useEffect(() => {
// Only set app action name if it has changed
if (selectedAction.label !== appActionName) {
setAppActionName(selectedAction.label);
if(selectedAction.label !== prevActionName){
setPrevActionName(selectedAction.label)
const shouldHide = localStorage.getItem("hideBody")
if (shouldHide !== null) {
const ishiding = shouldHide !== "true"
if (ishiding !== hideBody) {
setHideBody(ishiding)
}
}
// Only set delay if it has changed
const newDelay = selectedAction?.execution_delay || 0;
if (newDelay !== delay) {
setDelay(newDelay);
}
// Only set selected action parameters if they have changed
if (selectedAction?.parameters && selectedAction?.parameters.length > 0) {
setSelectedActionParameters(selectedAction?.parameters);
}
// Only set selected variable parameter if it is null or undefined
if (!selectedVariableParameter && workflow.workflow_variables?.length > 0) {
setSelectedVariableParameter(workflow.workflow_variables[0].name);
}
},
[selectedAction,selectedApp,setNewSelectedAction,workflow, workflowExecutions, getParents]
);
}
if(selectedAction.label !== prevActionName){
setPrevActionName(selectedAction.label)
}
// Only set delay if it has changed
const newDelay = selectedAction?.execution_delay || 0;
if (newDelay !== delay) {
setDelay(newDelay);
}
// Only set selected action parameters if they have changed
if (selectedAction?.parameters?.length > 0 && selectedAction.label !== appActionName) {
//console.log("PARAMS CHANGED DURING APPCHANGE: ", selectedAction.parameters)
setSelectedActionParameters(selectedAction.parameters);
}
// Only set selected variable parameter if it is null or undefined
if (!selectedVariableParameter && workflow.workflow_variables?.length > 0) {
setSelectedVariableParameter(workflow.workflow_variables[0].name);
}
},[selectedAction,selectedApp,setNewSelectedAction,workflow, workflowExecutions, getParents])
useEffect(() => {
const newActionList = [];
@@ -507,8 +498,9 @@ const ParsedAction = (props) => {
highlight: "exec",
autocomplete: "exec",
example: valid.result,
});
break;
})
break
}
}
}
@@ -523,32 +515,35 @@ const ParsedAction = (props) => {
highlight: "exec",
autocomplete: "exec",
example: "",
});
})
}
let cacheKey = {
type: "Shuffle DB",
name: "Shuffle DB",
value: "$shuffle_cache",
highlight: "shuffle_cache",
autocomplete: "shuffle_cache",
example: "",
};
// Look for cachekey
if (newActionList.find((item) => item.type === "Shuffle DB") === undefined) {
let cacheKey = {
type: "Shuffle DB",
name: "Shuffle DB",
value: "$shuffle_cache",
highlight: "shuffle_cache",
autocomplete: "shuffle_cache",
example: "",
};
if (listCache?.keys?.length > 0) {
cacheKey.example = {};
for (let item of listCache.keys) {
if (item.key) {
let itemValue = item.value ?? "";
if (itemValue.length > 10000) {
itemValue = "";
}
cacheKey.example[item.key.split(" ").join("_")] = { value: itemValue };
}
}
}
if (listCache?.keys?.length > 0) {
cacheKey.example = {};
for (let item of listCache.keys) {
if (item.key) {
let itemValue = item.value ?? "";
if (itemValue.length > 10000) {
itemValue = "";
}
cacheKey.example[item.key.split(" ").join("_")] = { value: itemValue };
}
}
}
newActionList.push(cacheKey);
}
newActionList.push(cacheKey);
}
// Process workflow variables
if (workflow.workflow_variables?.length > 0) {
@@ -680,7 +675,7 @@ const ParsedAction = (props) => {
});
setSelectedActionParameters(newParameters);
setActionlist(newActionList);
}, [workflow.execution_variables,paramUpdate, workflow.workflow_variables, workflowExecutions, workflow, selectedAction, listCache, getParents,setNewSelectedAction]);
}, [workflow.execution_variables, paramUpdate, workflow.workflow_variables, workflowExecutions, workflow, selectedAction, listCache, getParents,setNewSelectedAction]);
useEffect(() => {
selectedNameChange(appActionName)
@@ -767,7 +762,7 @@ const ParsedAction = (props) => {
}
const changeActionParameter = (event, count, data, viewForceUpdate) => {
//console.log("Action change: ", selectedAction, data)
//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");
@@ -777,9 +772,9 @@ const ParsedAction = (props) => {
var toReplace = event.target.value.trim()
if (!toReplace.startsWith("{") && !toReplace.startsWith("[")) {
toReplace = toReplace.replaceAll('\\"', '"').replaceAll('"', '\\"')
}
if (!toReplace.startsWith("{") && !toReplace.startsWith("[")) {
toReplace = toReplace.replaceAll('\\"', '"').replaceAll('"', '\\"')
}
console.log("REPLACE WITH: ", toReplace);
if (
@@ -793,7 +788,6 @@ const ParsedAction = (props) => {
},
];
console.log("IN IF: ", paramcheck);
} else {
const subparamindex = paramcheck["value_replace"].findIndex(
(param) => param.key === data.name
@@ -806,24 +800,27 @@ const ParsedAction = (props) => {
} else {
paramcheck["value_replace"][subparamindex]["value"] = toReplace;
}
console.log("IN ELSE: ", paramcheck);
}
if (selectedActionParameters[count].value_replace === undefined) {
selectedActionParameters[count].value_replace = paramcheck
}
if (selectedAction.parameters[count].value_replace === undefined) {
if (selectedAction?.parameters[count] !== undefined && selectedAction?.parameters[count].value_replace === undefined) {
selectedAction.parameters[count].value_replace = paramcheck
}
if (paramcheck["value_replace"] === undefined) {
selectedActionParameters[count]["value_replace"] = paramcheck
selectedAction.parameters[count]["value_replace"] = paramcheck
if (selectedAction?.parameters[count] !== undefined) {
selectedAction.parameters[count]["value_replace"] = paramcheck
}
} else {
selectedActionParameters[count]["value_replace"] = paramcheck["value_replace"];
selectedAction.parameters[count]["value_replace"] = paramcheck["value_replace"];
if (selectedAction?.parameters[count] !== undefined) {
selectedAction.parameters[count]["value_replace"] = paramcheck["value_replace"];
}
}
setSelectedAction(selectedAction);
//setUpdate(Math.random())
@@ -924,57 +921,58 @@ const ParsedAction = (props) => {
}
}
//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;
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!")
}
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]
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]
selectedActionParameters[count].value = splitparsed[0]
selectedAction.parameters[count].value = splitparsed[0]
selectedActionParameters[1].value = splitparsed[1]
selectedAction.parameters[1].value = splitparsed[1]
} else {
// Remove .# and after
const splitparsed = parsedvalue.split(".#")
data.value = splitparsed[0]
selectedActionParameters[0].value = splitparsed[0]
selectedAction.parameters[0].value = splitparsed[0]
selectedActionParameters[1].value = splitparsed[1]
selectedAction.parameters[1].value = splitparsed[1]
} else {
// Remove .# and after
const splitparsed = parsedvalue.split(".#")
data.value = splitparsed[0]
selectedActionParameters[0].value = splitparsed[0]
selectedAction.parameters[0].value = splitparsed[0]
selectedActionParameters[1].value = ""
selectedAction.parameters[1].value = ""
selectedActionParameters[1].value = ""
selectedAction.parameters[1].value = ""
toast.warn("No value found in the list. Please select an item in the list to filter based on.")
}
forceUpdate = true
selectedActionParameters[0].autocompleted = true
selectedAction.parameters[0].autocompleted = true
selectedActionParameters[1].autocompleted = true
selectedAction.parameters[1].autocompleted = true
toast.warn("No value found in the list. Please select an item in the list to filter based on.")
}
}
setSelectedAction(selectedAction);
if (forceUpdate || viewForceUpdate === true) {
setUpdate(Math.random())
forceUpdate = true
selectedActionParameters[0].autocompleted = true
selectedAction.parameters[0].autocompleted = true
selectedActionParameters[1].autocompleted = true
selectedAction.parameters[1].autocompleted = true
}
//setUpdate(event.target.value)
}
setSelectedAction(selectedAction)
if (forceUpdate || viewForceUpdate === true) {
setUpdate(Math.random())
}
//console.log("END OF THIS THING")
//setUpdate(event.target.value)
};
@@ -3004,86 +3002,120 @@ const ParsedAction = (props) => {
//setSelectedActionParameters(selectedActionParameters)
}
const hideBodyButtonValue = (
var hideBodyButtonValue = (
<div
key={data.name}
id="hide_body_button"
style={{
marginTop: 50,
border: "1px solid rgba(255,255,255,0.7)",
borderTop: "1px solid rgba(255,255,255,0.7)",
marginTop: 30,
borderRadius: theme.palette?.borderRadius,
alignItems: "center",
textAlign: "center",
}}
>
<Tooltip
color="secondary"
title={
hideBody
? "Hide all body fields and only show the body itself"
: "Show all body fields instead of the body itself"
}
placement="top"
>
<ButtonGroup fullWidth>
<Button variant={hideBody === true ? "outlined" : "contained"} color="primary" onClick={() => {
setHideBody(false)
const updatedParameters = selectedActionParameters.map((param) => {
if (param.name === "body") {
return {
...param,
id: "UNTOGGLED",
<Tooltip
color="secondary"
title={
"Show all body fields instead of the body itself"
}
placement="top"
>
<Button
variant={hideBody === true ? "outlined" : "contained"}
color="primary"
style={{textTransform: "none",}}
onClick={() => {
// Set localstorage
localStorage.setItem("hideBody", "true")
setHideBody(false)
const updatedParameters = selectedActionParameters.map((param) => {
if (param.name === "body") {
return {
...param,
id: "UNTOGGLED",
}
}
}
if (param.description === openApiFieldDesc) {
return { ...param, field_active: true }
}
if (param.description === openApiFieldDesc) {
// Check required fields here
if (selectedAction.required_body_fields !== undefined && selectedAction.required_body_fields !== null && selectedAction.required_body_fields.length > 0) {
// Look for the field name in the required_body_fields
if (selectedAction.required_body_fields.includes(param.name)) {
param.required = true
} else {
param.required = false
}
}
return param
})
setSelectedActionParameters(updatedParameters)
}}>
Simple
</Button>
<Button variant={hideBody === true ? "contained" : "outlined" } color="primary" onClick={() => {
setHideBody(true)
// Make sure the body field is shown
const updatedParameters = selectedActionParameters.map((param) => {
if (param.name === "body") {
return {
...param,
id: "TOGGLED",
return { ...param, field_active: true }
}
}
if (param.description === openApiFieldDesc) {
return { ...param, field_active: false }
}
return param
})
setSelectedActionParameters(updatedParameters)
}}>
Simplified
</Button>
</Tooltip>
<Tooltip
color="secondary"
title={
"Show the body as it is"
}
placement="top"
>
<Button
variant={hideBody === true ? "contained" : "outlined" }
color="primary"
style={{textTransform: "none",}}
onClick={() => {
localStorage.setItem("hideBody", "false")
setHideBody(true)
// Make sure the body field is shown
const updatedParameters = selectedActionParameters.map((param) => {
if (param.name === "body") {
return {
...param,
id: "TOGGLED",
}
}
return param
})
setSelectedActionParameters(updatedParameters)
}}>
Advanced
</Button>
if (param.description === openApiFieldDesc) {
return { ...param, field_active: false }
}
return param
})
setSelectedActionParameters(updatedParameters)
}}>
Advanced
</Button>
</Tooltip>
</ButtonGroup>
</Tooltip>
</div>
);
var showButtonField = false
if (selectedApp.generated && data.name === "body") {
if (selectedApp.generated === true && data.name === "body") {
const regex = /\${(\w+)}/g;
const found = placeholder.match(regex);
showButtonField = true
if (hideBody === true) {
var newhidebody = hideBody
showButtonField = true
if (found === undefined || found === null || found.length === 0) {
newhidebody = false
hideBodyButtonValue = null
if (hideBody === false) {
setHideBody(true)
}
}
if (newhidebody === true) {
//toast("BODYBUTTON TRUE")
} else {
@@ -3170,8 +3202,6 @@ const ParsedAction = (props) => {
}
}
//return hideBodyButtonValue
}
const clickedFieldId = "rightside_field_" + count;
@@ -3198,9 +3228,20 @@ const ParsedAction = (props) => {
tmpitem = "Username"
} else if (tmpitem === "Password basic") {
tmpitem = "Password"
}
}
multiline = data.name.startsWith("${") && data.name.endsWith("}") ? true : multiline
multiline = data.name.startsWith("${") && data.name.endsWith("}") ? true : multiline
if (data.name === "body") {
//console.log("BODY: ", data)
if (hideBody === false) {
return hideBodyButtonValue
}
rows = "4"
multiline = true
disabled = false
}
const description = data.description === undefined ? "" : data?.description;
@@ -3379,7 +3420,6 @@ const ParsedAction = (props) => {
// mode: 'python',
//}}
//height={multiline ? 50 : 150}
type={
placeholder.includes("***") ||
(data.configuration &&
@@ -3670,7 +3710,7 @@ const ParsedAction = (props) => {
</InputAdornment>
),
}}
helperText={returnHelperText(data.name, data.value)}
helperText={returnHelperText(data.name, data.value)}
fullWidth
multiline={multiline}
rows={"3"}
@@ -3766,10 +3806,10 @@ const ParsedAction = (props) => {
}
if (data.field_active === false) {
return null;
console.log("Field not active: ", data?.name)
return null
}
// Shows nested list of nodes > their JSON lists
const ActionlistWrapper = (props) => {
const handleMenuClose = () => {
@@ -4140,10 +4180,6 @@ const ParsedAction = (props) => {
data.variant = "STATIC_VALUE"
}
if (data.name === "body" && hideBody === false) {
return hideBodyButtonValue
}
return (
<div key={data.name}>
{showButtonField === true ? hideBodyButtonValue : null}
+11 -6
View File
@@ -895,8 +895,8 @@ const CodeEditor = (props) => {
// Shuffle Tools 1.2.0 (in most cases?)
const appid = toolsAppId !== undefined && toolsAppId !== null && toolsAppId.length > 0 ? toolsAppId : "3e2bdf9d5069fe3f4746c29d68785a6a"
const actionname = selectedAction.name === "execute_python" && !inputdata.replaceAll(" ", "").includes("{%python%}") ? "execute_python" : "repeat_back_to_me"
const params = actionname === "execute_python" ? [{"name": "code", "value":inputdata}] : [{"name":"call", "value": inputdata}]
const actionname = selectedAction.name === "execute_python" && !inputdata.replaceAll(" ", "").includes("{%python%}") ? "execute_python" : selectedAction.name === "execute_bash" ? "execute_bash" : "repeat_back_to_me"
const params = actionname === "execute_python" ? [{"name": "code", "value":inputdata}] : actionname === "execute_bash" ? [{"name": "code", "value":inputdata}, {"name": "shuffle_input", "value": "", }] : [{"name":"call", "value": inputdata}]
const actiondata = {"description":"Repeats the call parameter","id":"","name":actionname,"label":"","node_type":"","environment":"","sharing":false,"private_id":"","public_id":"","app_id": appid,"tags":null,"authentication":[],"tested":false,"parameters": params, "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":{}}
@@ -1134,6 +1134,11 @@ const CodeEditor = (props) => {
<Typography variant="body1" style={{marginTop: 5, }}>
Run Python Code
</Typography>
:
selectedAction.name === "execute_bash" ?
<Typography variant="body1" style={{marginTop: 5, }}>
Run Bash Code
</Typography>
:
<div style={{display: "flex", }}>
<Button
@@ -1545,7 +1550,7 @@ const CodeEditor = (props) => {
width: 50,
marginLeft: 0,
}}
disabled={isAiLoading || editorData.name !== "body"}
disabled={isAiLoading}
onClick={() => {
if (setAiQueryModalOpen !== undefined) {
setAiQueryModalOpen(true)
@@ -1582,7 +1587,7 @@ const CodeEditor = (props) => {
id="shuffle-codeeditor"
name="shuffle-codeeditor"
value={localcodedata}
mode={selectedAction === undefined ? "json" : selectedAction.name === "execute_python" ? "python" : "json"}
mode={selectedAction === undefined ? "json" : selectedAction.name === "execute_python" ? "python" : selectedAction.name === "execute_bash" ? "bash" : "json"}
theme="gruvbox"
height={isFileEditor ? 450 : 550}
width={isFileEditor ? 650 : "100%"}
@@ -1658,7 +1663,7 @@ const CodeEditor = (props) => {
<div>
<span style={{color: "white"}}>
{selectedAction === undefined ? "" : selectedAction.name === "execute_python" ? "Code to run" : "Expected Output"}
{selectedAction === undefined ? "" : selectedAction.name === "execute_python" || selectedAction.name === "execute_bash" ? "Code to run" : `Expected Output for '${selectedAction.name}'`}
</span>
</div>
@@ -1686,7 +1691,7 @@ const CodeEditor = (props) => {
{executing ?
<CircularProgress style={{height: 18, width: 18, }} />
:
<span>{selectedAction === undefined ? "" : selectedAction.name === "execute_python" ? "Run Python Code" : "Try it"}<PlayArrowIcon style={{height: 18, width: 18, marginBottom: -4, marginLeft: 5, }} /> </span>
<span>{selectedAction === undefined ? "" : selectedAction.name === "execute_python" ? "Run Python Code" : selectedAction.name === "execute_bash" ? "Run Bash" : "Try it"}<PlayArrowIcon style={{height: 18, width: 18, marginBottom: -4, marginLeft: 5, }} /> </span>
}
</Button>
</Tooltip>
+3 -3
View File
@@ -142,10 +142,10 @@ const data = [
},
},
{
selector: `node[app_name="Shuffle Tools"]`,
selector: `node[app_name="Shuffle Tools"], node[app_name="email"], node[app_name="http"]`,
css: {
width: "30px",
height: "30px",
width: "35px",
height: "35px",
"z-index": 5000,
"font-size": "0px",
"background-width": "75%",
+96 -53
View File
@@ -3793,6 +3793,20 @@ const releaseToConnectLabel = "Release to Connect"
}
}
// Ensuring overwriting
if (nodedata?.type === "ACTION") {
if (nodedata?.parameters !== undefined && nodedata.parameters !== null && nodedata.parameters.length > 0 && workflow?.actions !== undefined && workflow?.actions !== null && workflow?.actions.length > 0) {
for (var actionkey in workflow.actions) {
const action = workflow.actions[actionkey]
if (action.id === nodedata.id) {
workflow.actions[actionkey].parameters = nodedata.parameters
break
}
}
}
}
// Unselecting all
//cy.elements().unselect()
@@ -4164,6 +4178,7 @@ const releaseToConnectLabel = "Release to Connect"
const onNodeDrag = (event, selectedAction) => {
const nodedata = event.target.data();
if (nodedata.finished === false) {
console.log("NOT FINISHED - ADD EXAMPLE BRANCHES TO CLOSEST!!")
return
@@ -4450,11 +4465,15 @@ const releaseToConnectLabel = "Release to Connect"
var AppContext = []
var originalParams = []
var originalField = ""
if (inputAction !== undefined && inputAction !== null) {
// Reload the data without copying
inputAction = JSON.parse(JSON.stringify(inputAction))
originalParams = JSON.parse(JSON.stringify(inputAction.parameters))
if (originalParams.length > 0) {
originalField = originalParams[0].name
}
const parents = getParents(inputAction)
var actionlist = []
@@ -4590,7 +4609,6 @@ const releaseToConnectLabel = "Release to Connect"
credentials: "include",
})
.then((response) => {
setAiQueryModalOpen(false)
setAutocompleting(false)
if (setSuggestionLoading !== undefined) {
setSuggestionLoading(false)
@@ -4599,7 +4617,7 @@ const releaseToConnectLabel = "Release to Connect"
if (response.status !== 200) {
console.log("Status not 200 for stream results :O!");
} else {
toast("Completion finished. Please verify your action!")
toast("Completion finished. Please verify the output and run the workflow again!")
}
return response.json();
@@ -4611,47 +4629,49 @@ const releaseToConnectLabel = "Release to Connect"
if (setResponseMsg !== undefined) {
setResponseMsg(responseJson.reason)
}
toast.error(responseJson.reason)
}
return
} else {
setAiQueryModalOpen(false)
}
if (inputAction !== undefined) {
console.log("In input action! Should check params if they match, and add suggestions")
console.log("ORIGINAL PARAMS: ", originalParams)
console.log("RESPONSE PARAMS: ", responseJson.parameters)
if (responseJson.parameters === undefined || responseJson.parameters.length === 0) {
return
}
var changed = false
var codeeditorfound = false
for (let respParamKey in responseJson.parameters) {
var respParam = responseJson.parameters[respParamKey]
if (respParam.value === undefined || respParam.value === null || respParam.value === "" ) {
continue
}
for (let paramkey in originalParams) {
const actionParam = originalParams[paramkey]
/*
if (actionParam.value !== "" && actionParam.value !== actionParam.example) {
console.log("Skipping: ", actionParam)
continue
}
*/
if (respParam.name !== actionParam.name) {
for (var paramkey in selectedAction?.parameters) {
const actionParam = selectedAction.parameters[paramkey]
if (actionParam.name !== respParam.name) {
continue
}
const codeeditor = document.getElementById("shuffle-codeeditor")
if (codeeditor !== undefined && codeeditor !== null) {
if (codeeditor !== undefined && codeeditor !== null && actionParam.name === originalField) {
const editorInstance = window?.ace?.edit("shuffle-codeeditor")
if (editorInstance === undefined || editorInstance === null) {
toast.error("Failed to find code editor instance")
return
} else {
codeeditorfound = true
editorInstance.setValue(respParam.value)
originalParams[paramkey].autocompleted = true
//selectedAction.parameters[paramkey].value = respParam.value
changed = true
}
}
@@ -4659,26 +4679,25 @@ const releaseToConnectLabel = "Release to Connect"
if (!changed) {
console.log("Found match for param: ", respParam)
changed = true
originalParams[paramkey].autocompleted = true
originalParams[paramkey].value = respParam.value
selectedAction.parameters[paramkey].autocompleted = true
selectedAction.parameters[paramkey].value = respParam.value
}
break
}
}
if (changed === true) {
inputAction.parameters = originalParams
if (changed === true && codeeditorfound === false) {
//inputAction.parameters = JSON.parse(JSON.stringify(selectedAction.parameters))
selectedAction.parameters = JSON.parse(JSON.stringify(selectedAction.parameters))
console.log("Setting action! Force update pls :)")
setUpdate(Math.random())
setSelectedAction(inputAction)
setSelectedAction(selectedAction)
// Find it in cytoscape and update the action
if (cy !== undefined && cy !== null) {
const cyAction = cy.getElementById(inputAction.id)
if (cyAction !== undefined && cyAction !== null) {
cyAction.data("parameters", inputAction.parameters)
cyAction.data("parameters", selectedAction.parameters)
}
}
@@ -8871,8 +8890,8 @@ const releaseToConnectLabel = "Release to Connect"
const paperVariableStyle = {
borderRadius: theme.palette?.borderRadius,
minHeight: 50,
maxHeight: 50,
minHeight: 70,
maxHeight: 150,
minWidth: "100%",
maxWidth: "100%",
marginTop: "5px",
@@ -8960,7 +8979,7 @@ const releaseToConnectLabel = "Release to Connect"
}
}}
>
Name: {variable.name}
{variable.name}
</div>
<div style={{ flex: "1", marginLeft: "0px" }}>
<IconButton
@@ -9448,10 +9467,7 @@ const releaseToConnectLabel = "Release to Connect"
const handleDragStop = (e, app) => {
var currentnode = cy.getElementById(newNodeId);
if (
currentnode === undefined ||
currentnode === null ||
currentnode.length === 0
if (currentnode === undefined || currentnode === null || currentnode.length === 0
) {
return;
}
@@ -9464,16 +9480,37 @@ const releaseToConnectLabel = "Release to Connect"
// Using remove & replace, as this triggers the function
// onNodeAdded() with this node after it's added
console.log("Nodedata: ", parsedApp.data)
currentnode.remove()
currentnode.remove();
parsedApp.data.finished = true;
parsedApp.data.position = currentnode.renderedPosition();
parsedApp.position = currentnode.renderedPosition();
parsedApp.renderedPosition = currentnode.renderedPosition();
parsedApp.data.finished = true
parsedApp.data.position = currentnode.renderedPosition()
parsedApp.position = currentnode.renderedPosition()
parsedApp.renderedPosition = currentnode.renderedPosition()
var newAppData = parsedApp.data;
var newAppData = JSON.parse(JSON.stringify(parsedApp.data))
if (newAppData.type === "ACTION") {
if (newAppData.app_name === "Shuffle Tools") {
const iconInfo = GetIconInfo(newAppData)
const svg_pin = `<svg width="${svgSize}" height="${svgSize}" viewBox="0 0 ${svgSize} ${svgSize}" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="${iconInfo.icon}" fill="${iconInfo.iconColor}"></path></svg>`;
const svgpin_Url = encodeURI("data:image/svg+xml;utf-8," + svg_pin)
newAppData.large_image = svgpin_Url
newAppData.fillGradient = iconInfo.fillGradient
newAppData.fillstyle = "solid"
if (
newAppData.fillGradient !== undefined &&
newAppData.fillGradient !== null &&
newAppData.fillGradient.length > 0
) {
newAppData.fillstyle = "linear-gradient"
} else {
newAppData.iconBackground = iconInfo.iconBackgroundColor
}
}
//const activateApp = (appid) => {
if (newAppData.activated === false) {
activateApp(newAppData.app_id, false)
@@ -9556,13 +9593,13 @@ const releaseToConnectLabel = "Release to Connect"
}
parsedApp.data = newAppData;
cy.add(parsedApp);
cy.add(parsedApp)
} else if (newAppData.type === "TRIGGER") {
cy.add(parsedApp);
cy.add(parsedApp)
}
newNodeId = "";
parsedApp = {};
newNodeId = ""
parsedApp = {}
};
const barHeight = bodyHeight - appBarSize - 50;
@@ -9576,7 +9613,7 @@ const releaseToConnectLabel = "Release to Connect"
}
const handleAppDrag = (e, app) => {
const cycontainer = cy.container();
const cycontainer = cy.container()
// Handling drag of public apps
if (app.objectID !== undefined && app.objectID !== null && app.objectID.length > 0) {
@@ -9612,7 +9649,7 @@ const releaseToConnectLabel = "Release to Connect"
currentnode === null ||
currentnode.length === 0
) {
return;
return
}
currentnode[0].renderedPosition("x", e.pageX - cycontainer.offsetLeft)
@@ -9737,7 +9774,6 @@ const releaseToConnectLabel = "Release to Connect"
description: description,
environment: parsedEnvironments,
errors: [],
finished: false,
id_: newNodeId,
_id_: newNodeId,
id: newNodeId,
@@ -9758,8 +9794,10 @@ const releaseToConnectLabel = "Release to Connect"
? app.categories[0]
: "",
authentication_id: authId,
finished: false,
template: app.template === true ? true : false,
//finished: false,
finished: false,
}
// FIXME: Something is going wrong with params
@@ -11041,6 +11079,7 @@ const releaseToConnectLabel = "Release to Connect"
autocomplete: "exec",
example: "tmp",
})
actionlist.push({
type: "Shuffle DB",
name: "Shuffle DB",
@@ -13823,6 +13862,7 @@ const releaseToConnectLabel = "Release to Connect"
</div>
</div>
{/*
<div>
<div>
<div className="app">
@@ -13840,6 +13880,7 @@ const releaseToConnectLabel = "Release to Connect"
</div>
</div>
</div>
*/}
</div>
);
}
@@ -16152,7 +16193,7 @@ const releaseToConnectLabel = "Release to Connect"
</div>
{showEnvironment === true && environments.length > 1 && selectedActionEnvironment !== undefined && selectedActionEnvironment !== null && selectedActionEnvironment.Name !== undefined && selectedActionEnvironment.Name !== null ?
<FormControl fullWidth style={{marginTop: 15, marginleft: 10, pointerEvents: "auto", }}>
<FormControl fullWidth style={{marginTop: 15, marginleft: 10, pointerEvents: "auto", maxWidth: 250, }}>
<InputLabel
id="execution_location"
@@ -21758,11 +21799,11 @@ const releaseToConnectLabel = "Release to Connect"
}
const drawerData = originalWorkflow !== undefined && originalWorkflow !== null ?
<div style={{ height: "100%"}}>
<Typography variant="h4" style={{ paddingLeft: 25, paddingTop:25, backgroundColor: theme.palette.surfaceColor, }}>
<div style={{ height: "100%", backgroundColor: theme.palette.backgroundColor, }}>
<Typography variant="h4" style={{ paddingLeft: 25, paddingTop:25, backgroundColor: theme.palette.backgroundColor, }}>
Version History
</Typography>
<Typography variant="body2" color="textSecondary" style={{ paddingLeft: 25, paddingTop: 5, paddingBottom: 5, backgroundColor: theme.palette.surfaceColor, }}>
<Typography variant="body2" color="textSecondary" style={{ paddingLeft: 25, paddingTop: 5, paddingBottom: 5, }}>
Versions are stored for every change made, up to once per minute. When restoring a version, the changes will not take effect until you save the workflow.
</Typography>
<Divider style={{marginTop: 25, }}/>
@@ -21871,21 +21912,23 @@ const releaseToConnectLabel = "Release to Connect"
</Button>
: null*/}
</div>
<div style={{textAlign: "center", color: "white", flex: 1, paddingTop: 20, }}>
<div style={{textAlign: "center", color: "white", flex: 2, paddingTop: 20, }}>
<Typography variant="h6">
{selectedVersion?.name}
</Typography>
</div>
{/* Cross icon to close it */}
<div style={{flex: 1, itemAlign: "right", textAlign: "right", paddingRight: 25, paddingTop: 10, }}>
<IconButton
<Button
onClick={() => {
setShowWorkflowRevisions(false)
}}
style={{color: "white", height: 50, width: 50, }}
color="secondary"
variant="outlined"
style={{marginTop: 10, }}
>
<CloseIcon />
</IconButton>
Use Version
<CloseIcon style={{marginLeft: 10, }}/>
</Button>
</div>
</div>
</div>
+105 -98
View File
@@ -37,14 +37,15 @@ import {
AttachFile as AttachFileIcon,
Apps as AppsIcon,
ErrorOutline as ErrorOutlineIcon,
AddAPhoto as AddAPhotoIcon,
AddAPhotoOutlined as AddAPhotoOutlinedIcon,
ZoomInOutlined as ZoomInOutlinedIcon,
ZoomOutOutlined as ZoomOutOutlinedIcon,
Loop as LoopIcon,
AddPhotoAlternate as AddPhotoAlternateIcon,
CallMerge as CallMergeIcon,
AddAPhoto as AddAPhotoIcon,
AddAPhotoOutlined as AddAPhotoOutlinedIcon,
ZoomInOutlined as ZoomInOutlinedIcon,
ZoomOutOutlined as ZoomOutOutlinedIcon,
Loop as LoopIcon,
AddPhotoAlternate as AddPhotoAlternateIcon,
CallMerge as CallMergeIcon,
CloudDownload as CloudDownloadIcon,
OpenInNew as OpenInNewIcon,
} from "@mui/icons-material";
import { v4 as uuidv4 } from "uuid";
@@ -3172,7 +3173,7 @@ const AppCreator = (defaultprops) => {
<div style={{ color: "white", marginTop: 20 }}>
<Typography variant="body1">API key authentication</Typography>
<Typography variant="body2" color="textSecondary">
Add the name of the field used for authentication, e.g. "X-APIKEY". Should NOT be your actual API-key.
<b>Do NOT put your actual API-key.</b> Add the name of the field used for authentication, e.g. "X-APIKEY".
</Typography>
<div style={{display: "flex", marginTop: 10, }}>
<div style={{flex: 4,}}>
@@ -3848,7 +3849,7 @@ const AppCreator = (defaultprops) => {
required
style={{
flex: "1",
marginTop: "5px",
marginTop: 5,
marginRight: "15px",
backgroundColor: inputColor,
}}
@@ -4341,7 +4342,8 @@ const AppCreator = (defaultprops) => {
>
<ErrorOutlineIcon />
</Tooltip>
) : (
) : null
{/*
<Tooltip
color="secondary"
title={data.errors.join("\n")}
@@ -4349,7 +4351,7 @@ const AppCreator = (defaultprops) => {
>
<CheckCircleIcon style={{ marginTop: 6 }} />
</Tooltip>
);
*/}
var bgColor = "#61afee";
if (data.method === "POST") {
@@ -5800,19 +5802,35 @@ const AppCreator = (defaultprops) => {
General information
</h2>
</div>
<div style={{flex: 1, itemAlign: "right", textAlign: "right",}}>
<Tooltip title="Merge with another API (coming soon)" placement="bottom">
<IconButton
disabled
<div style={{flex: 1, itemAlign: "right", textAlign: "right", marginRight: 10, }}>
<Tooltip title="Try the API" placement="bottom">
<Button
variant="outlined"
color="secondary"
onClick={() => {
setOpenApiModal(true)
var urlParams = new URLSearchParams(window.location.search);
if (!urlParams.has("id")) {
window.open(`/apis/${app.id}`, "_blank")
} else {
toast.error("Build the app first.")
}
}}
>
<OpenInNewIcon style={{marginRight: 5, }}/>
Try the API
</Button>
</Tooltip>
<Tooltip title="Manage forks and Merge with another API (coming soon)" placement="bottom">
<IconButton
onClick={() => {
//setOpenApiModal(true)
toast.info("Action merging & fork management coming soon")
}}
style={{marginLeft: 10, }}
>
<CallMergeIcon
style={{}}
onClick={() => {
setOpenApiModal(true)
}}
/>
</IconButton>
</Tooltip>
@@ -5839,18 +5857,13 @@ const AppCreator = (defaultprops) => {
flex: "1",
margin: 10,
border: "1px solid #f85a3e",
borderRadius: theme.palette?.borderRadius,
cursor: "pointer",
backgroundColor: inputColor,
maxWidth: 174,
maxHeight: 174,
}}
onClick={() => {
/*
if (fileBase64.length === 0) {
upload.click()
}
*/
setOpenImageModal(true);
}}
>
@@ -5863,7 +5876,7 @@ const AppCreator = (defaultprops) => {
/>
</div>
</Tooltip>
<div style={{ flex: "3", color: "white" }}>
<div style={{ flex: "3", color: "white", marginLeft: 20, }}>
<div style={{ marginTop: "10px" }} />
Name
<TextField
@@ -5917,35 +5930,28 @@ const AppCreator = (defaultprops) => {
},
}}
/>
<div style={{ marginTop: "10px" }} />
<div style={{ marginTop: 10, }} />
Description
<TextField
required
style={{
flex: "1",
marginTop: "5px",
marginRight: "15px",
paddingTop: 5,
marginTop: 5,
marginRight: 15,
backgroundColor: inputColor,
maxHeight: 250,
overflow: "auto",
maxHeight: 250,
overflowY: "auto"
}}
fullWidth={true}
type="name"
id="outlined-with-placeholder"
margin="normal"
multiline
multiline
variant="outlined"
placeholder="A description for the service"
value={description}
onChange={(e) => setDescription(e.target.value)}
InputProps={{
classes: {
notchedOutline: classes.notchedOutline,
},
style: {
color: "white",
},
}}
defaultValue={description}
//onChange={(e) => setDescription(e.target.value)}
onBlur={(e) => setDescription(e.target.value)}
/>
</div>
</div>
@@ -6185,62 +6191,63 @@ const AppCreator = (defaultprops) => {
{testView}
*/}
<div style={{display: "flex", marginTop: 35, }}>
{appDownloadData.length > 0 ?
<Tooltip title="Download the OpenAPI specification for the App" placement="bottom">
<IconButton
style={{marginRight: 25, }}
onClick={() => {
toast(`Downloading OpenAPI JSON data for for ${name}`)
// Download as file
var blob = new Blob([appDownloadData], {
type: "application/octet-stream",
});
<div style={{height: 50, padding: 25, display: "flex", marginTop: 35, position: "fixed", bottom: 0, left: 0, width: "100%", backgroundColor: theme.palette?.backgroundColor, borderTop: "1px solid rgba(255,255,255,0.3)",}}>
<div style={{width: 450, margin: "auto", display: "flex", textAlign: "center", }}>
{appDownloadData.length > 0 ?
<Tooltip title="Download the OpenAPI specification for the App" placement="bottom">
<IconButton
style={{marginRight: 25, }}
onClick={() => {
toast(`Downloading OpenAPI JSON data for for ${name}`)
// Download as file
var blob = new Blob([appDownloadData], {
type: "application/octet-stream",
});
var url = URL.createObjectURL(blob);
var link = document.createElement("a");
link.setAttribute("href", url);
link.setAttribute("download", `${name}.json`);
var event = document.createEvent("MouseEvents");
event.initMouseEvent(
"click",
true,
true,
window,
1,
0,
0,
0,
0,
false,
false,
false,
false,
0,
null
);
link.dispatchEvent(event);
}}
>
<CloudDownloadIcon />
</IconButton>
</Tooltip>
: null}
<Button
disabled={appBuilding}
color="primary"
variant="contained"
fullWidth
style={{ height: "50px", flex: 1, }}
onClick={() => {
submitApp();
}}
>
{appBuilding ? <CircularProgress /> : "Save"}
</Button>
{appDownloadData.length > 0 ?
<div style={{width: 50, }}/>
: null}
var url = URL.createObjectURL(blob);
var link = document.createElement("a");
link.setAttribute("href", url);
link.setAttribute("download", `${name}.json`);
var event = document.createEvent("MouseEvents");
event.initMouseEvent(
"click",
true,
true,
window,
1,
0,
0,
0,
0,
false,
false,
false,
false,
0,
null
);
link.dispatchEvent(event);
}}
>
<CloudDownloadIcon />
</IconButton>
</Tooltip>
: null}
<Button
disabled={appBuilding}
color="primary"
variant="contained"
style={{ height: 50, flex: 1, minWidth: 400, maxWidth: 400, }}
onClick={() => {
submitApp();
}}
>
{appBuilding ? <CircularProgress /> : "Save API"}
</Button>
{appDownloadData.length > 0 ?
<div style={{width: 50, }}/>
: null}
</div>
</div>
<Typography style={{ marginTop: 25, textAlign: "center", }}>
+1 -1
View File
@@ -3513,7 +3513,7 @@ func getRunningWorkers(ctx context.Context, workerTimeout int) int {
// Automatically updates the version
if err != nil {
log.Printf("[ERROR] Error getting containers: %s", err)
log.Printf("[ERROR] Error getting containers from Docker: %s", err)
newVersionSplit := strings.Split(fmt.Sprintf("%s", err), "version is")
if len(newVersionSplit) > 1 {