From b430e6c900d29b0d22f703d5177c2f26eba0b7ee Mon Sep 17 00:00:00 2001 From: Frikky Date: Thu, 6 Feb 2025 02:07:58 +0100 Subject: [PATCH] Fixed a lot of the weird suborg distribution workflow issues --- backend/go-app/walkoff.go | 9 - frontend/src/components/EditWorkflow.jsx | 8 +- frontend/src/components/LeftSideBar.jsx | 8 +- frontend/src/components/ParsedAction.jsx | 91 +- frontend/src/components/RuntimeDebugger.jsx | 271 ++-- frontend/src/defaultCytoscapeStyle.jsx | 2 +- frontend/src/views/Admin2.jsx | 11 +- frontend/src/views/AngularWorkflow.jsx | 1316 ++++++++++++------- frontend/src/views/AppCreator.jsx | 79 +- frontend/src/views/Workflows.jsx | 4 +- 10 files changed, 1204 insertions(+), 595 deletions(-) diff --git a/backend/go-app/walkoff.go b/backend/go-app/walkoff.go index 3e924ca4..df7addb8 100755 --- a/backend/go-app/walkoff.go +++ b/backend/go-app/walkoff.go @@ -1743,15 +1743,6 @@ func handleExecution(id string, workflow shuffle.Workflow, request *http.Request Environments: execInfo.Environments, } - //executionRequestWrapper, err := getWorkflowQueue(ctx, environment) - //if err != nil { - // executionRequestWrapper = ExecutionRequestWrapper{ - // Data: []ExecutionRequest{executionRequest}, - // } - //} else { - // executionRequestWrapper.Data = append(executionRequestWrapper.Data, executionRequest) - //} - //log.Printf("Execution request: %#v", executionRequest) executionRequest.Priority = workflowExecution.Priority err = shuffle.SetWorkflowQueue(ctx, executionRequest, environment) diff --git a/frontend/src/components/EditWorkflow.jsx b/frontend/src/components/EditWorkflow.jsx index d40fcd5b..fd53f5eb 100644 --- a/frontend/src/components/EditWorkflow.jsx +++ b/frontend/src/components/EditWorkflow.jsx @@ -104,9 +104,10 @@ const EditWorkflow = (props) => { const foundScroll = document.getElementById(scrollTo) if (foundScroll !== null) { // Smooth scroll - foundScroll.scrollIntoView({ behavior: "smooth" }) + foundScroll.scrollIntoView({ + behavior: "smooth", + }) } - }, 200) setScrollDone(true) @@ -565,13 +566,12 @@ const EditWorkflow = (props) => { fullWidth /> - + MSSP controls - MSSP Suborg Distribution (beta - contact support@shuffler.io for more info) diff --git a/frontend/src/components/LeftSideBar.jsx b/frontend/src/components/LeftSideBar.jsx index dd7fac86..31e43c28 100644 --- a/frontend/src/components/LeftSideBar.jsx +++ b/frontend/src/components/LeftSideBar.jsx @@ -889,7 +889,7 @@ useEffect(() => { - {!leftSideBarOpenByClick && setExpandLeftNav(true)}} onMouseLeave={()=>{!leftSideBarOpenByClick && setExpandLeftNav(false);setOpenAutocomplete(false)}}> + {(!leftSideBarOpenByClick || window?.location?.pathname?.includes("/workflows/")) && setExpandLeftNav(true)}} onMouseLeave={()=>{(!leftSideBarOpenByClick || window?.location?.pathname?.includes("/workflows/")) && setExpandLeftNav(false);setOpenAutocomplete(false)}}> { sx={{ display: "flex", flexDirection: "row", - marginTop: 1 + marginTop: 0 }} > @@ -1229,7 +1229,7 @@ useEffect(() => { width: 18, height: 18, marginRight: expandLeftNav ? 10 : 0, - color: userdata?.support ? "inherit" : "#6F6F6F", + color: "inherit", }} /> { - + - - ), - - }} - onChange={(e)=>{handleQueryChange(e)}} - color="primary" - placeholder="Filter by Workflow Name, Status, Execution Argument, Results.." - id="shuffle_search_field" - /> - - - - {selectedWorkflowExecutions.length > 0 ? +
+

Workflow Run Debugger {totalCount !== 0 ? ` (~${totalCount})` : ""}

+ {selectedWorkflowExecutions.length > 0 ? : null} +
+
+
+ + + + ), + endAdornment: ( + + {searchQuery.length > 0 && ( + setSearchQuery('')} + /> + )} + + + ), + + }} + onChange={(e)=>{handleQueryChange(e)}} + color="primary" + placeholder="Filter by Workflow Name, Status, Execution Argument, Results.." + id="shuffle_search_field" + /> +
+ {userdata?.active_org?.creator_org?.length === 0 ? ( +
+ { + setSuborgWorkflowRuns(!suborgWorkflowRuns); + //set selected workflow to all workflows when switching between suborg and all workflows + setWorkflowId("") + setWorkflow({"id": "", "name": "All Workflows"}) + setStatus("") + setStartTime("") + setEndTime("") + setSearchQuery("") + submitSearch("", "", "", "", rowCursor, rowsPerPage, !suborgWorkflowRuns)} + } + color="secondary" + /> + Show workflow runs from suborgs +
+ ) : null} +
+
{ - submitSearch(workflowId, status, startTime, endTime, rowCursor, rowsPerPage) - }} style={{display: "flex", }}> + submitSearch(workflowId, status, startTime, endTime, rowCursor, rowsPerPage, suborgWorkflowRuns) + }} style={{display: "flex", justifyContent: "center", alignItems: "center", }}> Status { workflow.triggers[ selectedTriggerIndex ].parameters[0].value.includes("127.0.0.1")) ? ( + @@ -15044,7 +15313,6 @@ const AngularWorkflow = (defaultprops) => { onClick={() => { var copyText = document.getElementById("webhook_uri_field"); if (copyText !== undefined && copyText !== null) { - console.log("NAVIGATOR: ", navigator); const clipboard = navigator.clipboard; if (clipboard === undefined) { toast("Can only copy over HTTPS (port 3443)"); @@ -15370,13 +15638,20 @@ const AngularWorkflow = (defaultprops) => { custom_response: custom_response, version: version, version_timeout: 15, - }; + } - console.log("Trigger data: ", data) + var headers = { + "Content-Type": "application/json", + "Accept": "application/json", + } + + if (workflow.org_id !== undefined && workflow.org_id !== null && workflow.org_id.length > 0) { + headers["Org-Id"] = workflow.org_id + } fetch(globalUrl + "/api/v1/hooks/new", { method: "POST", - headers: { "content-type": "application/json" }, + headers: headers, body: JSON.stringify(data), credentials: "include", }) @@ -15390,6 +15665,8 @@ const AngularWorkflow = (defaultprops) => { workflow.triggers[selectedTriggerIndex].status = "running"; setWorkflow(workflow); saveWorkflow(workflow); + + loadTriggers(workflow.org_id) } else { toast("Failed starting webhook: " + responseJson.reason); } @@ -15405,12 +15682,25 @@ const AngularWorkflow = (defaultprops) => { return; } - fetch(globalUrl + "/api/v1/hooks/" + trigger.id + "/delete", { + // Unselect everything in cytoscape + if (cy !== undefined && cy !== null) { + cy.$(":selected").unselect() + } + + var headers = { + "Content-Type": "application/json", + "Accept": "application/json", + } + + console.log("ORGID: ", workflow.org_id) + if (workflow.org_id !== undefined && workflow.org_id !== null && workflow.org_id.length > 0) { + headers["Org-Id"] = workflow.org_id + } + + const url = `${globalUrl}/api/v1/hooks/${trigger.id}/delete` + fetch(url, { method: "DELETE", - headers: { - "Content-Type": "application/json", - Accept: "application/json", - }, + headers: headers, credentials: "include", }) .then((response) => { @@ -15423,18 +15713,23 @@ const AngularWorkflow = (defaultprops) => { .then((responseJson) => { if (!responseJson.success) { if (responseJson.reason !== undefined) { - toast("Failed to stop webhook: " + responseJson.reason); - } + toast.error("Failed to stop webhook: " + responseJson.reason); + } else { + //toast.error("Failed to stop webhook. Please try again, or contact support@shuffler.io to get it sorted."); + } } else { toast("Successfully stopped webhook"); + + loadTriggers(workflow.org_id) } if (workflow.triggers[triggerindex] !== undefined) { workflow.triggers[triggerindex].status = "stopped"; } - trigger.status = "stopped"; - setSelectedTrigger(trigger); - setWorkflow(workflow); - saveWorkflow(workflow); + + trigger.status = "stopped" + setSelectedTrigger(trigger) + setWorkflow(workflow) + saveWorkflow(workflow) setSelectedTrigger({}) }) @@ -15449,11 +15744,18 @@ const AngularWorkflow = (defaultprops) => { // POST to /api/v1/workflows const createWorkflow = (workflow, trigger_index) => { + var headers = { + "Content-Type": "application/json", + "Accept": "application/json", + } + + if (workflow.org_id !== undefined && workflow.org_id !== null && workflow.org_id.length > 0) { + headers["Org-Id"] = workflow.org_id + } + fetch(globalUrl + "/api/v1/workflows", { method: "POST", - headers: { - "Content-Type": "application/json", - }, + headers: headers, body: JSON.stringify(workflow), credentials: "include", }) @@ -16314,7 +16616,9 @@ const AngularWorkflow = (defaultprops) => { selectedTrigger.parameters === undefined ? isCloud || selectedTrigger?.environment === "cloud" ? "*/25 * * * *" : "60" : selectedTrigger.parameters[0]?.value } color="primary" - placeholder="" + placeholder={ + selectedTrigger.parameters === undefined ? isCloud || selectedTrigger?.environment === "cloud" ? "*/25 * * * *" : "60" : selectedTrigger.parameters[0]?.value + } onBlur={(e) => { setTriggerCronWrapper(e.target.value); }} @@ -16575,331 +16879,432 @@ const AngularWorkflow = (defaultprops) => { : - Warning: This workflow is controlled by your parent org and may not be editable. + Warning: This workflow is controlled by your parent org and may not be editable. } - {originalWorkflow.suborg_distribution === undefined || originalWorkflow.suborg_distribution === null || originalWorkflow.suborg_distribution.length === 0 || originalWorkflow.suborg_distribution.includes("none") ? null : - + {originalWorkflow.suborg_distribution === undefined || originalWorkflow.suborg_distribution === null || originalWorkflow.suborg_distribution.length === 0 || originalWorkflow.suborg_distribution.includes("none") ? + originalWorkflow?.parentorg_workflow !== undefined && originalWorkflow?.parentorg_workflow !== null && originalWorkflow?.parentorg_workflow.length > 0 ? + + : userdata !== undefined && userdata !== null && userdata.orgs !== undefined && userdata.orgs !== null && userdata.orgs.length > 0 ? + + : null - - Select an Org - - { + if (lastSaved === false && originalWorkflow.id === workflow.id) { + saveWorkflow(workflow, undefined, undefined, e.target.value) + toast.warn("Saving workflow first due to detected changes. Please try to change workflow again when it is finished.", { + autoClose: 2000, + }) + return + } - // FIXME: There is a timing problem here. - // For events to have the data they need, they - // need to be registered with setupGraph() - // AFTER all the APIs are done + if (workflow.org_id === e.target.value) { + console.log("Same org selected. No change.") + return + } else { + //if (savingState === 0) { + // saveWorkflow(workflow, undefined, undefined, undefined) + // return + //} + } - // Should look through childorg workflow - setTimeout(() => { - if (e.target.value === originalWorkflow.org_id) { - console.log("Original org selected. No change.") + navigate(`?org_id=${e.target.value}`) - updateCurrentWorkflow(originalWorkflow) - return - } else { - // Load environments, auth, auth groups - //toast("Loading correct info for suborg") - } + // Unselect in cy + if (cy !== undefined && cy !== null) { + cy.nodes().unselect() + cy.edges().unselect() + } - if (originalWorkflow.childorg_workflow_ids === undefined || originalWorkflow.childorg_workflow_ids === null || originalWorkflow.childorg_workflow_ids.length === 0) { - //console.log("Childorg doesn't exist (?). Suborgworkflows: ", suborgWorkflows) + ReactDOM.unstable_batchedUpdates(() => { + getEnvironments(e.target.value) + getAppAuthentication(undefined, undefined, undefined, e.target.value) + getFiles(e.target.value) + listOrgCache(e.target.value) - if (suborgWorkflows !== undefined && suborgWorkflows !== null && suborgWorkflows.length > 0) { - var found = false - for (var suborgkey in suborgWorkflows) { - const suborgWorkflow = suborgWorkflows[suborgkey] - if (suborgWorkflow.org_id === e.target.value) { - found = true - updateCurrentWorkflow(suborgWorkflow) - break - } - } + // Reset the save button to ensure random saves don't occur during move + setLastSaved(true) - if (!found) { - toast("(3) Creating new workflow for this org. Please wait a second while we duplicate.") - //console.log("No workflow found out of suborg workflows.") + // FIXME: There is a timing problem here. + // For events to have the data they need, they + // need to be registered with setupGraph() + // AFTER all the APIs are done - //saveWorkflow(originalWorkflow, undefined, undefined, e.target.value) - } - } else { - console.log("Suborgworkflows: ", suborgWorkflows) - toast("(1) Loading NEW workflow for this org (?). Please wait a second.") - saveWorkflow(originalWorkflow, undefined, undefined, e.target.value) - } - } else { - console.log("In childorg EXIST!") + // Should look through childorg workflow + setTimeout(() => { + if (e.target.value === originalWorkflow.org_id) { + updateCurrentWorkflow(originalWorkflow) + return + } else { + // Load environments, auth, auth groups + //toast("Loading correct info for suborg") + } - var workflowFound = false - for (var childorgidkey in originalWorkflow.childorg_workflow_ids) { - const childworkflowid = originalWorkflow.childorg_workflow_ids[childorgidkey] - for (var suborgWorkflowKey in suborgWorkflows) { - const suborgWorkflow = suborgWorkflows[suborgWorkflowKey] - if (suborgWorkflow.org_id === e.target.value) { - workflowFound = true + if (originalWorkflow.childorg_workflow_ids === undefined || originalWorkflow.childorg_workflow_ids === null || originalWorkflow.childorg_workflow_ids.length === 0) { + //console.log("Childorg doesn't exist (?). Suborgworkflows: ", suborgWorkflows) - updateCurrentWorkflow(suborgWorkflow) - break - } - } + if (suborgWorkflows !== undefined && suborgWorkflows !== null && suborgWorkflows.length > 0) { + var found = false + for (var suborgkey in suborgWorkflows) { + const suborgWorkflow = suborgWorkflows[suborgkey] + if (suborgWorkflow.org_id === e.target.value) { + found = true + updateCurrentWorkflow(suborgWorkflow) + break + } + } - if (workflowFound) { - break - } - } + if (!found) { + toast("(3) Creating new workflow for this org. Please wait a second while we duplicate.") + //console.log("No workflow found out of suborg workflows.") - if (!workflowFound) { - console.log("No workflow found.") - toast("(2) Creating new workflow for this org. Please wait a few seconds while we prepare it for you.") - //saveWorkflow(originalWorkflow, undefined, undefined, e.target.value) - } - } - }, 500) - }) - }} - label="Suborg Distribution" - fullWidth - > - - Parent: {userdata.active_org.large_image}{" "} - - {userdata.active_org.name} - - + //saveWorkflow(originalWorkflow, undefined, undefined, e.target.value) + } + } else { + console.log("Suborgworkflows: ", suborgWorkflows) + toast("(1) Loading NEW workflow for this org (?). Please wait a second.") + saveWorkflow(originalWorkflow, undefined, undefined, e.target.value) + } + } else { + console.log("In childorg EXIST!") - + var workflowFound = false + for (var childorgidkey in originalWorkflow.childorg_workflow_ids) { + const childworkflowid = originalWorkflow.childorg_workflow_ids[childorgidkey] + for (var suborgWorkflowKey in suborgWorkflows) { + const suborgWorkflow = suborgWorkflows[suborgWorkflowKey] + if (suborgWorkflow.org_id === e.target.value) { + workflowFound = true - {originalWorkflow.suborg_distribution.map((org_id, index) => { - var data = {} - for (var key in userdata.orgs) { - if (userdata.orgs[key].id === org_id) { - data = userdata.orgs[key] - break - } - } + updateCurrentWorkflow(suborgWorkflow) + break + } + } - if (data.id === undefined || data.id === null) { - //toast("No org found for id: " + org_id) - return null - } + if (workflowFound) { + break + } + } - var skipOrg = false; + if (!workflowFound) { + console.log("No workflow found.") + toast("(2) Creating new workflow for this org. Please wait a few seconds while we prepare it for you.") + //saveWorkflow(originalWorkflow, undefined, undefined, e.target.value) + } + } + }, 500) + }) + }} + label="Suborg Distribution" + fullWidth + > + + + { + e.preventDefault() + e.stopPropagation() + }} + /> {userdata.active_org.large_image}{" "} + + {userdata.active_org.name} + + - const imagesize = 22 - const imageStyle = { - width: imagesize, - height: imagesize, - pointerEvents: "none", - marginRight: 10, - marginLeft: - data.creator_org !== undefined && - data.creator_org !== null && - data.creator_org.length > 0 - ? data.id === userdata.active_org.id - ? 0 - : 0 - : 0, - } + - const image = - data.image === "" ? ( - {data.name} - ) : ( - {data.name} - ) + {originalWorkflow.suborg_distribution.map((org_id, index) => { + var data = {} + for (var key in userdata.orgs) { + if (userdata.orgs[key].id === org_id) { + data = userdata.orgs[key] + break + } + } + + if (data.id === undefined || data.id === null) { + //toast("No org found for id: " + org_id) + return null + } + + var skipOrg = false; + + const imagesize = 22 + const imageStyle = { + width: imagesize, + height: imagesize, + pointerEvents: "none", + marginRight: 10, + marginLeft: + data.creator_org !== undefined && + data.creator_org !== null && + data.creator_org.length > 0 + ? data.id === userdata.active_org.id + ? 0 + : 0 + : 0, + } + + const image = + data.image === "" ? ( + {data.name} + ) : ( + {data.name} + ) - return ( - - {image}{" "} - - {data.name} - - - ) - })} - - + return ( + + {image}{" "} + + {data.name} + + + ) + })} + + + } {showEnvironment === true && environments.length > 0 && selectedActionEnvironment !== undefined && selectedActionEnvironment !== null && selectedActionEnvironment.Name !== undefined && selectedActionEnvironment.Name !== null ? - + 0 && Object.getOwnPropertyNames(selectedActionEnvironment).length !== 0 && selectedActionEnvironment?.Name !== "Cloud" && savingState === 0 ? ( + +
+ 0} + onChange={(event) => { + toast("Opening in new tab. Refresh this page after adding it.") - - Runtime Location - - { + getEnvironments(workflow.org_id) + }} + onChange={(e) => { + setLastSaved(false) + const env = environments.find((a) => a.Name === e.target.value); + setSelectedActionEnvironment(env) + selectedAction.environment = env.Name + setSelectedAction(selectedAction) - backgroundColor: theme.palette.inputColor, - height: 40, - }} - > - {environments.map((data, index) => { - if (data.archived === true) { - return null - } + for (let actionkey in workflow.actions) { + workflow.actions[actionkey].environment = env.Name + } - const isRunning = data.running_ip !== "" + setWorkflow(workflow) + //toast.success("Set execution location for ALL actions to " + env.Name) + }} + style={{ + pointerEvents: "auto", + color: "white", + maxWidth: 250, + minWidth: 250, + borderRadius: theme.palette?.borderRadius, + marginLeft: 35, - return ( - + backgroundColor: theme.palette.inputColor, + height: 40, + }} + > + {environments.map((data, index) => { + if (data.archived === true) { + return null + } - {data.Name === "cloud" || data.Name === "Cloud" ? null : !isRunning ? + const isRunning = data.running_ip !== "" - - - { - e.preventDefault() - e.stopPropagation() + return ( + - window.open(`/admin?tab=locations&env=${data.Name}`, "_blank", "noopener,noreferrer") - }} + {data.Name === "cloud" || data.Name === "Cloud" ? null : !isRunning ? + + + + { + e.preventDefault() + e.stopPropagation() + + window.open(`/admin?tab=locations&env=${data.Name}`, "_blank", "noopener,noreferrer") + }} - /> - - - : - { - //handleChipClick - }} - variant="outlined" - color="primary" - /> - } + /> + + + : + { + //handleChipClick + }} + variant="outlined" + color="primary" + /> + } - {data.default === true ? - - : null} + {data.default === true ? + + : null} - {data.Name} - - ); - })} - - + {data.Name} + + ); + })} + + + : null} @@ -17250,7 +17655,7 @@ const AngularWorkflow = (defaultprops) => { variant="body2" color="textSecondary" > - {workflow.errors.slice(0, 3).map((error) => { + {workflow.errors.slice(0, 3).map((error, index) => { // Loop through each word, and if it matches "Action " then replace it with a link to the action var colornext = false const newerror = error === undefined || error == null ? "" : error.split(" ").map((word) => { @@ -17258,6 +17663,7 @@ const AngularWorkflow = (defaultprops) => { colornext = false return ( { // Find it in cytoscape @@ -17446,7 +17852,7 @@ const AngularWorkflow = (defaultprops) => { onMouseLeave={() => setHovered(false)} onClick={() => { setExecutionModalOpen(true); - getWorkflowExecution(props.match.params.key, ""); + getWorkflowExecution(workflow.id, "", executionFilter, workflow.org_id) }} > @@ -17475,9 +17881,39 @@ const AngularWorkflow = (defaultprops) => { setSelectedApp({}) setWorkflow(inputworkflow) + if (workflow.id === originalWorkflow.id) { + if (selectedActionEnvironment !== undefined && selectedActionEnvironment !== null && selectedActionEnvironment.Name !== undefined && selectedActionEnvironment.Name !== null) { + setOriginalSelectedEnvironment(selectedActionEnvironment) + } + } + + if (inputworkflow.id === originalWorkflow.id && originalSelectedEnvironment !== undefined && originalSelectedEnvironment !== null && originalSelectedEnvironment.Name !== undefined && originalSelectedEnvironment.Name !== null) { + setSelectedActionEnvironment(originalSelectedEnvironment) + } else { + if (inputworkflow.actions !== undefined && inputworkflow.actions !== null && inputworkflow.actions.length > 0) { + + for (var actionkey in inputworkflow.actions) { + const action = inputworkflow.actions[actionkey] + if (action.environment === undefined || action.environment === null || action.environment === "") { + continue + } + + //const env = environments.find((a) => a.Name === action.environment) + const newenv = { + Name: action.environment, + Type: action.environment === "cloud" ? "cloud" : "onprem", + } + + setSelectedActionEnvironment(newenv) + break + } + } + } + if (inputworkflow !== undefined && inputworkflow !== null && inputworkflow.id !== undefined && inputworkflow.id !== null) { getRevisionHistory(inputworkflow.id, 50, 0, inputworkflow.org_id) - getWorkflowExecution(inputworkflow.id, "", "") + getWorkflowExecution(inputworkflow.id, "", executionFilter, inputworkflow.org_id) + loadTriggers(inputworkflow.org_id) } // Update props match key @@ -17501,9 +17937,9 @@ const AngularWorkflow = (defaultprops) => { cy.removeListener("free"); cy.removeListener("cxttap"); - setElements([]) // Remove all edges + setElements([]) cy.edges().remove() cy.nodes().remove() } @@ -17618,7 +18054,7 @@ const AngularWorkflow = (defaultprops) => { style={{ width: 55, }} onClick={() => { setExecutionModalOpen(true); - getWorkflowExecution(props.match.params.key, ""); + getWorkflowExecution(workflow.id, "", executionFilter, workflow.org_id) }} > @@ -18273,10 +18709,11 @@ const AngularWorkflow = (defaultprops) => { getAppAuthentication() getEnvironments(workflow.org_id) - getWorkflowExecution(props.match.params.key, "") getAvailableWorkflows(-1) getFiles() + getWorkflowExecution(workflow.id, "", executionFilter, workflow.org_id) + // For loading datastore setUpdate(Math.random()); @@ -19032,8 +19469,7 @@ const AngularWorkflow = (defaultprops) => { variant="outlined" fullWidth onClick={() => { - - getWorkflowExecution(props.match.params.key, "", executionFilter); + getWorkflowExecution(workflow.id, "", executionFilter, workflow.org_id) }} color="secondary" > @@ -19050,7 +19486,7 @@ const AngularWorkflow = (defaultprops) => { variant={executionFilter === "ALL" ? "contained" : "outlined"} onClick={() => { setExecutionFilter("ALL") - getWorkflowExecution(props.match.params.key, "", "ALL") + getWorkflowExecution(workflow.id, "", "ALL", workflow.org_id) }} > All @@ -19060,7 +19496,7 @@ const AngularWorkflow = (defaultprops) => { variant={executionFilter === "FINISHED" ? "contained" : "outlined"} onClick={() => { setExecutionFilter("FINISHED") - getWorkflowExecution(props.match.params.key, "", "FINISHED") + getWorkflowExecution(workflow.id, "", "FINISHED", workflow.org_id) }} > Finished @@ -19070,7 +19506,7 @@ const AngularWorkflow = (defaultprops) => { variant={executionFilter === "EXECUTING" ? "contained" : "outlined"} onClick={() => { setExecutionFilter("EXECUTING") - getWorkflowExecution(props.match.params.key, "", "EXECUTING") + getWorkflowExecution(workflow.id, "", "EXECUTING", workflow.org_id) }} > Executing @@ -19080,7 +19516,7 @@ const AngularWorkflow = (defaultprops) => { variant={executionFilter === "ABORTED" ? "contained" : "outlined"} onClick={() => { setExecutionFilter("ABORTED") - getWorkflowExecution(props.match.params.key, "", "ABORTED") + getWorkflowExecution(workflow.id, "", "ABORTED", workflow.org_id) }} > Aborted @@ -19141,7 +19577,9 @@ const AngularWorkflow = (defaultprops) => { const foundnotifications = data.notifications_created === undefined || data.notifications_created === null ? 0 : data.notifications_created return ( - + {/**/}
{ {workflowRevisions} {authenticationModal} {tenzirConfigModal} - {/*editWorkflowModal*/} {authgroupModal} {executionArgumentModal} {configureWorkflowModal} - {/*usecaseSlidein*/} @@ -22958,6 +23394,8 @@ const AngularWorkflow = (defaultprops) => { isEditing={true} userdata={userdata} usecases={usecases} + + scrollTo={"mssp_control"} /> : null} diff --git a/frontend/src/views/AppCreator.jsx b/frontend/src/views/AppCreator.jsx index e6a9888e..6e6dda22 100755 --- a/frontend/src/views/AppCreator.jsx +++ b/frontend/src/views/AppCreator.jsx @@ -276,7 +276,14 @@ export const appCategories = [ "color": "#FFC107", "icon": "network", "action_labels": ["Get Rules", "Allow IP", "Block IP",], - }, { + }, + { + "name": "AI", + "color": "#FFC107", + "icon": "AI", + "action_labels": ["Answer Question", "Run Action"], + }, + { "name": "Other", "color": "#FFC107", "icon": "other", @@ -418,6 +425,7 @@ const AppCreator = (defaultprops) => { const [appBuilding, setAppBuilding] = useState(false); const [fileDownloadEnabled, setFileDownloadEnabled] = useState(false); const [actionAmount, setActionAmount] = useState(increaseAmount); + const [newAppGroup, setNewAppGroup] = useState("") const [oauth2Scopes, setOauth2Scopes] = useState([]); const [oauth2Type, setOauth2Type] = useState("delegated"); @@ -4622,23 +4630,25 @@ const AppCreator = (defaultprops) => { }} /> */} -

Choose a Category

- { + setNewWorkflowCategories([e.target.value]); + setUpdate("added " + e.target.value); + }} + value={newWorkflowCategories.length === 0 ? "Select a category" : newWorkflowCategories[0]} + + style={{ backgroundColor: inputColor, color: "white", height: "50px" }} + > + {categories.map((data, index) => { if (data === undefined || data === null || data === "" || data === undefined || data === null || data === "") { return null } @@ -4651,9 +4661,38 @@ const AppCreator = (defaultprops) => { > {data.name} - ) + ) })} - + +
+ {/* +
+ +

Group

+
+ { + setNewAppGroup(e.target.value) + setUpdate("group added "+e.target.value) + }} + InputProps={{ + style: { + color: "white", + }, + }} + /> +
+ */} +

Tags

{ { key: "cache_add", values: ["set_cache"] }, { key: "cache_get", values: ["get_cache"] }, { key: "filter", values: ["filter"] }, - { key: "merge", values: ["join", "merge", "route", "router"] }, + { key: "merge", values: ["join", "merge", "route", "router", "routing"] }, { key: "search", values: ["search", "find", "locate", "index", "analyze", "anal", "match", "check cache", "check", "verify", "validate"], @@ -200,7 +200,7 @@ export const GetIconInfo = (action) => { }, { key: "compare", - values: ["compare", "convert", "to", "filter", "translate", "parse"], + values: ["compare", "convert", "to", "filter", "translate", "parse", "generate", ], }, { key: "close", values: ["close", "stop", "cancel", "block"] }, { key: "communication", values: ["communication", "comms", "email", "mail",] },