diff --git a/backend/app_sdk/app_base.py b/backend/app_sdk/app_base.py
index 3ded5fba..a29853d8 100755
--- a/backend/app_sdk/app_base.py
+++ b/backend/app_sdk/app_base.py
@@ -1178,7 +1178,7 @@ class AppBase:
#ret = ret[0]
self.logger.info("[DEBUG] DONT make list of 1 into 0!!")
- self.logger.info("Return from execution: %s" % ret)
+ #self.logger.info("Return from execution: %s" % ret)
if ret == None:
results.append("")
json_object = False
@@ -1202,11 +1202,12 @@ class AppBase:
except:
results.append(ret)
- if len(results) == 1:
- #results = results[0]
- self.logger.info("DONT MAKE LIST FROM 1 TO 0!!")
+ #if len(results) == 1:
+ # #results = results[0]
+ # #self.logger.info("DONT MAKE LIST FROM 1 TO 0!!")
+ # pass
- self.logger.info("\nLOOP: %s\nRESULTS: %s" % (loop_wrapper, results))
+ #self.logger.info("\nLOOP: %s\nRESULTS: %s" % (loop_wrapper, results))
return results
# Downloads all files from a namespace
@@ -3305,7 +3306,7 @@ class AppBase:
pass
- self.logger.info(f"""HANDLING BODY: {action["parameters"][counter]["value"]}""")
+ #self.logger.info(f"""HANDLING BODY: {action["parameters"][counter]["value"]}""")
action["parameters"][counter]["value"] = recurse_cleanup_script(action["parameters"][counter]["value"])
#self.logger.info(action["parameters"])
@@ -3345,9 +3346,8 @@ class AppBase:
"exception": f"Value Error: {check}",
}))
- if parameter["name"] == "body":
- #self.logger.info(f"[INFO] Should debug field with liquid and other checks as it's BODY: {value}")
- pass
+ #if parameter["name"] == "body":
+ # #self.logger.info(f"[INFO] Should debug field with liquid and other checks as it's BODY: {value}")
# Custom format for ${name[0,1,2,...]}$
#submatch = "([${]{2}([0-9a-zA-Z_-]+)(\[.*\])[}$]{2})"
diff --git a/frontend/src/components/ParsedAction.jsx b/frontend/src/components/ParsedAction.jsx
index aef01467..68366fe4 100755
--- a/frontend/src/components/ParsedAction.jsx
+++ b/frontend/src/components/ParsedAction.jsx
@@ -175,8 +175,6 @@ const ParsedAction = (props) => {
} = props;
const classes = useStyles();
- //const alert = useAlert()
-
const [hideBody, setHideBody] = React.useState(true);
const [activateHidingBodyButton, setActivateHidingBodyButton] = React.useState(false);
@@ -185,31 +183,34 @@ const ParsedAction = (props) => {
const [autoCompleting, setAutocompleting] = React.useState(false);
+ useEffect(() => {
+ if (setLastSaved !== undefined) {
+ setLastSaved(false)
+ }
+ }, [expansionModalOpen])
useEffect(() => {
- if (setLastSaved !== undefined) {
- setLastSaved(false)
- }
- }, [expansionModalOpen])
+ if (selectedAction.parameters === null || selectedAction.parameters === undefined) {
+ return
+ }
- 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)
+ const paramcheck = selectedAction.parameters.find(param => param.name === "body")
+ if (paramcheck === undefined || paramcheck === null) {
+ return
+ }
- if (paramcheck.id === "UNTOGGLED") {
- setActivateHidingBodyButton(false)
- }
- }
- }
+ // This was just opposite..
+ if (paramcheck.id === "TOGGLED"){
+ setHideBody(true)
+ } else {
+ setHideBody(false)
+
+ if (paramcheck.id === "UNTOGGLED") {
+ setActivateHidingBodyButton(false)
}
- }, [])
+ }
+
+ }, [])
const keywords = [
"len(",
@@ -1190,14 +1191,14 @@ const ParsedAction = (props) => {
}
return (
-
);
}}
@@ -1360,20 +1361,6 @@ const ParsedAction = (props) => {
var disabled = false;
var rows = "3";
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)
@@ -1386,8 +1373,9 @@ const ParsedAction = (props) => {
const hideBodyButtonValue = (
{
>
{
color: theme.palette.primary.secondary,
}}
onChange={(event) => {
- var tag = "TOGGLED"
- if (hideBody) {
- tag = "UNTOGGLED"
- }
+ var tag = "TOGGLED"
+ if (hideBody) {
+ tag = "UNTOGGLED"
+ }
- setHideBody(!hideBody);
-
+ setHideBody(!hideBody)
for (let paramkey in Object.entries(selectedActionParameters)) {
var currentItem = selectedActionParameters[paramkey];
if (currentItem.name === "ssl_verify") {
@@ -1423,21 +1410,33 @@ const ParsedAction = (props) => {
}
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);
+ currentItem.field_active = !hideBody
}
}
+
+
+ // Scroll to hide_body_button
+ setTimeout(() => {
+ var element = document.getElementById("hide_body_button")
+ if (element !== undefined && element !== null) {
+ // Keep the button a little below the top
+ element.scrollIntoView({
+ behavior: "smooth",
+ block: "center",
+ })
+ }
+ }, 100)
+
+
}}
name="requires_unique"
/>
}
- label={"Automatically fix body"}
+ label={hideBody ? "Show Body" : "Hide Body"}
/>
@@ -1447,6 +1446,8 @@ const ParsedAction = (props) => {
const regex = /\${(\w+)}/g;
const found = placeholder.match(regex);
+ // setActivateHidingBodyButton(false)
+ //
hideBodyButton = hideBodyButtonValue;
if (found === null || !hideBody) {
if (found === null) {
@@ -1455,13 +1456,13 @@ const ParsedAction = (props) => {
//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;
+ var tempArray = []
for (let specKey in found) {
const tmpitem = found[specKey];
var skip = false;
@@ -1490,7 +1491,7 @@ const ParsedAction = (props) => {
}
}
- selectedActionParameters.push({
+ tempArray.push({
action_field: "",
configuration: false,
description: openApiFieldDesc,
@@ -1506,11 +1507,39 @@ const ParsedAction = (props) => {
value: "",
variant: "STATIC_VALUE",
field_active: true,
+
+ autocompleted: true,
});
}
+
+ console.log("TEMP ARRAY: ", tempArray)
+ var required = selectedActionParameters.filter(item => item.required === true)
+ var notRequired = selectedActionParameters.filter(item => item.required === false)
+
+ if (tempArray.length > 0) {
+ // Sort tempArray based on tempArray.required
+ tempArray.sort((a, b) => (a.required < b.required) ? 1 : -1)
+ // Add all items to the selectedActionParameters array
+ for (let innerkey in tempArray) {
+ tempArray[innerkey].id = "ADDED"
+
+ if (tempArray[innerkey].required === true) {
+ required.push(tempArray[innerkey])
+ } else {
+ notRequired.push(tempArray[innerkey])
+ }
+ }
+ }
+ //selectedActionParameters
if (changed) {
- setSelectedActionParameters(selectedActionParameters);
+ // Sort selectedActionParameters based on selectedActionParameters.required
+ //selectedActionParameters.sort((a, b) => (a.required < b.required) ? 1 : -1)
+ // Find the "headers" and "queries" field names and put them on the first indexes anyway
+ var newArray = required.concat(notRequired)
+
+
+ setSelectedActionParameters(newArray)
}
return hideBodyButton;
@@ -1523,9 +1552,6 @@ const ParsedAction = (props) => {
const clickedFieldId = "rightside_field_" + count;
- // 0) {
baseHelperText = calculateHelpertext(data.value)
@@ -1619,33 +1645,15 @@ const ParsedAction = (props) => {
helperText={returnHelperText(data.name, data.value)}
onClick={() => {
console.log("Clicked field: ", clickedFieldId, data.name)
+ /*
+ setExpansionModalOpen(false);
+ */
- //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) {
+ console.log("IN SCROLL CONFIG!")
+
scrollConfig.selected = clickedFieldId
setScrollConfig(scrollConfig)
- //console.log("Change field id!")
}
}}
id={clickedFieldId}
@@ -2476,19 +2484,19 @@ const ParsedAction = (props) => {
) : null}
- {hasAutocomplete === true ?
-
-
-
- :
- null}
+ {hasAutocomplete === true ?
+
+
+
+ :
+ null}
{
const parsedBaseLabel = "$"+baselabel.toLowerCase().replaceAll(" ", "_")
const newname = "$"+name.toLowerCase().replaceAll(" ", "_")
- console.log("NAME: ", name)
-
// Check if it's the same as the current name in use
//if (name === selectedAction.label) {
// console.log("Returning from name thing")
@@ -3352,9 +3358,8 @@ const ParsedAction = (props) => {
No selection
{selectedAction.authentication.map((data) => {
- console.log("AUTH DATA: ", data)
if (data.last_modified === true) {
- console.log("LAST MODIFIED: ", data.label)
+ //console.log("LAST MODIFIED: ", data.label)
}
return (
@@ -3736,9 +3741,12 @@ const ParsedAction = (props) => {
return (
{
backgroundColor: theme.palette.inputColor,
borderRadius: theme.palette.borderRadius,
}}
- {...params}
label="Find Actions"
variant="outlined"
+ name={`disable_autocomplete_${Math.random()}`}
+
/>
);
}}
diff --git a/frontend/src/components/RuntimeDebugger.jsx b/frontend/src/components/RuntimeDebugger.jsx
index 570778df..01bb345c 100644
--- a/frontend/src/components/RuntimeDebugger.jsx
+++ b/frontend/src/components/RuntimeDebugger.jsx
@@ -54,6 +54,7 @@ const RuntimeDebugger = (props) => {
const [status, setStatus] = useState("")
const [endTime, setEndTime] = useState("")
const [startTime, setStartTime] = useState("")
+ const [totalCount, setTotalCount] = useState(0)
const [workflow, setWorkflow] = useState({})
const [ignoreOrg, setIgnoreOrg] = useState(false)
@@ -65,16 +66,80 @@ const RuntimeDebugger = (props) => {
const [workflows, setWorkflows] = useState([
{"id": "", "name": "All Workflows",}
])
- /*
- [
- {id: "1", execution_id: "1", status: "FINISHED", startTimestamp: "2021-10-01 12:00:00", endTimestamp: "2021-10-01 12:00:00", workflow: {"id": "1234", "name": "what",}},
- {id: "2", execution_id: "2", status: "WAITING", startTimestamp: "2021-10-01 12:00:00", endTimestamp: "2021-10-01 12:00:00", workflow: {"id": "1234", "name": "what",}},
- {id: "3", execution_id: "3", status: "EXECUTING",startTimestamp: "2021-10-01 12:00:00", endTimestamp: "2021-10-01 12:00:00", workflow: {"id": "1234", "name": "what",}},
- {id: "4", execution_id: "4", status: "ABORTED", startTimestamp: "2021-10-01 12:00:00", endTimestamp: "2021-10-01 12:00:00", workflow: {"id": "1234", "name": "what",}},
- ]);
- */
+
+ // Shitty workflow search on purpose :)
+ const handleWorkflowUsageCount = (workflows) => {
+ if (workflows === undefined || workflows === null || workflows.length === 0) {
+ return
+ }
+
+ setTotalCount(0)
+
+ var count = 0
+ var starttime = startTime === undefined || startTime === null || startTime === "" ? "" : new Date(startTime).toISOString()
+ var endtime = endTime === undefined || endTime === null || endTime == "" ? "" : new Date(endTime).toISOString()
+
+ var maxworkflows = 5
+
+ console.log("Looking for MAX this amount of workflows: ", maxworkflows)
+ for (let key in workflows) {
+ if (key > maxworkflows) {
+ break
+ }
+
+ const workflowId = workflows[key].id
+ // Fetch the data for the workflow
+ var url = `${globalUrl}/api/v1/workflows/${workflowId}/executions/count`
+ if (starttime !== "") {
+ url += `?start_time=${starttime}`
+ }
+
+ if (endtime !== "") {
+ if (starttime !== "") {
+ url += `&end_time=${endtime}`
+ } else {
+ url += `?end_time=${endtime}`
+ }
+ }
+
+ fetch(url, {
+ method: "GET",
+ headers: {
+ "Content-Type": "application/json",
+ Accept: "application/json",
+ },
+ credentials: "include",
+ })
+ .then((response) => {
+ if (response.status !== 200) {
+ console.log("Status not 200 for workflows :O!");
+ return;
+ }
+
+ return response.json()
+ })
+ .then((data) => {
+ if (data.success) {
+ if (data.count !== undefined && data.count !== null) {
+ count += data.count
+ }
+ } else {
+ console.log("Failed to get workflow usage count: ", data)
+ }
+ })
+ .catch((error) => {
+ console.error("Error:", error);
+ })
+ }
+
+ setTimeout(() => {
+ console.log("Setting total count: ", count)
+ setTotalCount(count)
+ }, maxworkflows*300)
+ }
const submitSearch = (workflowId, status, startTime, endTime, cursor, limit) => {
+ handleWorkflowUsageCount(workflows)
//setResultRows([])
setSearchLoading(true)
@@ -135,6 +200,7 @@ const RuntimeDebugger = (props) => {
})
}
+
const getAvailableWorkflows = () => {
fetch(globalUrl + "/api/v1/workflows", {
method: "GET",
@@ -624,7 +690,7 @@ const RuntimeDebugger = (props) => {
-
Workflow Run Debugger
+
Workflow Run Debugger {totalCount !== 0 ? ` (~${totalCount})` : ""}
{selectedWorkflowExecutions.length > 0 ?
diff --git a/frontend/src/views/AngularWorkflow.jsx b/frontend/src/views/AngularWorkflow.jsx
index ed968653..92a57baa 100755
--- a/frontend/src/views/AngularWorkflow.jsx
+++ b/frontend/src/views/AngularWorkflow.jsx
@@ -1393,7 +1393,7 @@ const AngularWorkflow = (defaultprops) => {
}
if (streamDisabled) {
- console.log("Stream disabled")
+ console.log("Stream disabled - send")
return
}
@@ -2739,7 +2739,7 @@ const AngularWorkflow = (defaultprops) => {
}
if (streamDisabled) {
- console.log("Stream disabled")
+ console.log("Stream listener disabled")
return
}
@@ -2751,6 +2751,7 @@ const AngularWorkflow = (defaultprops) => {
const url = `${streamUrl}/api/v1/workflows/${workflowId}/stream`
while (true) {
if (streamDisabled === true || streamDisabled2 === true) {
+ console.log("Stream disabled, breaking")
break
}
@@ -3731,6 +3732,10 @@ const AngularWorkflow = (defaultprops) => {
return
} else if (data.buttonType === "set_startnode" && data.type !== "TRIGGER") {
+ //console.log("STARTNODE")
+ //event.preventDefault()
+ //event.stopPropagation()
+
const parentNode = cy.getElementById(data.attachedTo);
if (parentNode !== null && parentNode !== undefined) {
var oldstartnode = cy.getElementById(workflow.start);
@@ -3967,8 +3972,6 @@ const AngularWorkflow = (defaultprops) => {
//}
curaction.app_id = curapp.id
- console.log("CURAPP: ", curapp.authentication)
-
setAuthenticationType(
curapp.authentication.type === "oauth2" && curapp.authentication.redirect_uri !== undefined && curapp.authentication.redirect_uri !== null ? {
type: "oauth2",
@@ -4000,7 +4003,6 @@ const AngularWorkflow = (defaultprops) => {
}
const tmpAuth = JSON.parse(JSON.stringify(newAppAuth));
- //console.log("FOUND AUTH OPTIONS: ", tmpAuth)
const curappName = curapp.name.toLowerCase()
for (let tmpAuthKey in tmpAuth) {
@@ -4036,7 +4038,6 @@ const AngularWorkflow = (defaultprops) => {
}
}
- console.log("OPTIONS: ", authenticationOptions)
// Find with authenticationOption (authenticationOptions) has the highest .edited time. In this index, set the "last_modified" to true
var latesttime = 0
@@ -4044,7 +4045,6 @@ const AngularWorkflow = (defaultprops) => {
for (var i = 0; i < authenticationOptions.length; i++) {
const authopt = authenticationOptions[i]
- console.log("AUTHOPT: ", authopt)
if (authopt.edited > latesttime) {
latesttime = authopt.edited
@@ -4052,7 +4052,6 @@ const AngularWorkflow = (defaultprops) => {
}
}
- console.log("LATEST INDEX: ", latestindex)
if (latestindex !== -1) {
authenticationOptions[latestindex].last_modified = true
}
@@ -5933,7 +5932,7 @@ const AngularWorkflow = (defaultprops) => {
if (workflow.actions.length < 4) {
addSuggestionButtons(nodedata, event);
} else {
- console.log("Too many actions to suggest (for now)")
+ //console.log("Too many actions to suggest (for now)")
}
}
}
@@ -14666,6 +14665,7 @@ const AngularWorkflow = (defaultprops) => {
}
}
+
return (
{
}
}
+ const cursearch = typeof window === "undefined" || window.location === undefined ? "" : window.location.search;
+ const chosenNodeId = new URLSearchParams(cursearch).get("node");
+ const highlightNode = chosenNodeId !== null && chosenNodeId !== undefined && chosenNodeId !== "" && chosenNodeId === data.action.id
return (
{
);
// Awful way of handling scroll
- if (
- scrollConfig !== undefined &&
- setScrollConfig !== undefined &&
- Object.getOwnPropertyNames(selectedAction).length !== 0
- ) {
+ if (scrollConfig !== undefined && setScrollConfig !== undefined && Object.getOwnPropertyNames(selectedAction).length !== 0) {
const rightSideActionView = document.getElementById("rightside_actions");
if (rightSideActionView !== undefined && rightSideActionView !== null) {
- if (
- scrollConfig.top !== 0 &&
- scrollConfig.top !== undefined &&
- scrollConfig.top !== 0
- ) {
+ if (scrollConfig.top !== null && scrollConfig.top !== undefined && scrollConfig.top !== 0) {
setTimeout(() => {
- if (
- scrollConfig.selected !== undefined &&
- scrollConfig.selected !== null
- ) {
- const selectedField = document.getElementById(
- scrollConfig.selected
- );
+ if (scrollConfig.selected !== undefined && scrollConfig.selected !== null) {
+ const selectedField = document.getElementById(scrollConfig.selected)
if (selectedField !== undefined && selectedField !== null) {
- selectedField.focus();
+ selectedField.focus()
}
}
}, 5);