diff --git a/frontend/package.json b/frontend/package.json index 6e606427..bd605329 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -74,10 +74,16 @@ "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject", - "lint": "eslint 'src/**/*.{tsx,ts,js,jsx}'" + "lint": "eslint 'src/**/*.{tsx,ts,js,jsx}'", + "lint_file": "eslint 'src/views/AngularWorkflow.jsx'" }, "eslintConfig": { - "extends": "react-app" + "extends": "react-app", + "rules":{ + "jsx-a11y/img-redundant-alt" : "off", + "no-redeclare" : "off", + "no-loop-func": "off" + } }, "browserslist": [ ">0.2%", diff --git a/frontend/src/views/AngularWorkflow.jsx b/frontend/src/views/AngularWorkflow.jsx index 45226356..1c13d698 100644 --- a/frontend/src/views/AngularWorkflow.jsx +++ b/frontend/src/views/AngularWorkflow.jsx @@ -1,4 +1,4 @@ -import React, {useRef, useState, useEffect, useLayoutEffect} from 'react'; +import React, { useState, useEffect, useLayoutEffect} from 'react'; import { useInterval } from 'react-powerhooks'; import { useTheme } from '@material-ui/core/styles'; @@ -11,8 +11,64 @@ import NestedMenuItem from "material-ui-nested-menu-item"; import ReactMarkdown from 'react-markdown'; -import {Slide, TextField, Drawer, Button, Paper, Grid, Tabs, InputAdornment, Tab, ButtonBase, Tooltip, Select, MenuItem, Divider, Dialog, Modal, DialogActions, DialogTitle, InputLabel, DialogContent, FormControl, IconButton, Menu, Input, FormGroup, FormControlLabel, Typography, Checkbox, Breadcrumbs, CircularProgress, Switch, Fade} from '@material-ui/core'; -import {OpenInNew as OpenInNewIcon,Undo as UndoIcon, FileCopy as FileCopyIcon, GetApp as GetAppIcon, Search as SearchIcon, ArrowUpward as ArrowUpwardIcon, Visibility as VisibilityIcon, Done as DoneIcon, Close as CloseIcon, Error as ErrorIcon, FindReplace as FindreplaceIcon, ArrowLeft as ArrowLeftIcon, Cached as CachedIcon, DirectionsRun as DirectionsRunIcon, Add as AddIcon, Polymer as PolymerIcon, FormatListNumbered as FormatListNumberedIcon, Create as CreateIcon, PlayArrow as PlayArrowIcon, AspectRatio as AspectRatioIcon, MoreVert as MoreVertIcon, Apps as AppsIcon, Schedule as ScheduleIcon, FavoriteBorder as FavoriteBorderIcon, Pause as PauseIcon, Delete as DeleteIcon, AddCircleOutline as AddCircleOutlineIcon, Save as SaveIcon, KeyboardArrowLeft as KeyboardArrowLeftIcon, KeyboardArrowRight as KeyboardArrowRightIcon, ArrowBack as ArrowBackIcon, Settings as SettingsIcon, LockOpen as LockOpenIcon, ExpandMore as ExpandMoreIcon, VpnKey as VpnKeyIcon} from '@material-ui/icons'; +import {TextField, + Drawer, + Button, + Paper, + Grid, + Tabs, + InputAdornment, + Tab, + ButtonBase, + Tooltip, + Select, + MenuItem, + Divider, + Dialog, + DialogActions, + DialogTitle, + InputLabel, + DialogContent, + FormControl, + IconButton, + Menu, + Input, + FormGroup, + FormControlLabel, + Typography, + Checkbox, + Breadcrumbs, + CircularProgress, + Switch} from '@material-ui/core'; +import {OpenInNew as OpenInNewIcon, + Undo as UndoIcon, + GetApp as GetAppIcon, + Search as SearchIcon, + Visibility as VisibilityIcon, + Done as DoneIcon, + Close as CloseIcon, + Error as ErrorIcon, + ArrowLeft as ArrowLeftIcon, + Cached as CachedIcon, + DirectionsRun as DirectionsRunIcon, + Polymer as PolymerIcon, + FormatListNumbered as FormatListNumberedIcon, + PlayArrow as PlayArrowIcon, + AspectRatio as AspectRatioIcon, + MoreVert as MoreVertIcon, + Apps as AppsIcon, + Schedule as ScheduleIcon, + FavoriteBorder as FavoriteBorderIcon, + Pause as PauseIcon, + Delete as DeleteIcon, + AddCircleOutline as AddCircleOutlineIcon, + Save as SaveIcon, + KeyboardArrowRight as KeyboardArrowRightIcon, + ArrowBack as ArrowBackIcon, + Settings as SettingsIcon, + LockOpen as LockOpenIcon, + ExpandMore as ExpandMoreIcon, + VpnKey as VpnKeyIcon} from '@material-ui/icons'; import * as cytoscape from 'cytoscape'; import * as edgehandles from 'cytoscape-edgehandles'; @@ -24,19 +80,15 @@ import Draggable from 'react-draggable'; import cytoscapestyle from '../defaultCytoscapeStyle'; import cxtmenu from 'cytoscape-cxtmenu'; -import { w3cwebsocket as W3CWebSocket } from "websocket"; import { useAlert } from "react-alert"; import { validateJson, GetIconInfo } from "./Workflows.jsx"; import { GetParsedPaths } from "./Apps.jsx"; import ConfigureWorkflow from '../components/ConfigureWorkflow.jsx'; import AuthenticationOauth2 from "../components/Oauth2Auth.jsx"; import ParsedAction from '../components/ParsedAction.jsx'; -//import Scroll from 'react-scroll' -//import { Element as ScrollElement, animateScroll as scroll, scrollSpy, scroller } from 'react-scroll' const surfaceColor = "#27292D" const inputColor = "#383B40" -const appSorter = "favorite_apps" // http://apps.cytoscape.org/apps/yfileslayoutalgorithms cytoscape.use(edgehandles); @@ -119,22 +171,6 @@ const svgSize = 24 //const referenceUrl = "https://shuffler.io/functions/webhooks/" //const referenceUrl = window.location.origin+"/api/v1/hooks/" -function useTraceUpdate(props) { - const prev = useRef(props) - useEffect(() => { - const changedProps = Object.entries(props).reduce((ps, [k, v]) => { - if (prev.current[k] !== v) { - ps[k] = [prev.current[k], v]; - } - return ps; - }, {}); - if (Object.keys(changedProps).length > 0) { - console.log('Changed props:', changedProps); - } - prev.current = props; - }); -} - const AngularWorkflow = (props) => { const { globalUrl, isLoggedIn, isLoaded, userdata } = props; const referenceUrl = globalUrl+"/api/v1/hooks/" @@ -189,7 +225,8 @@ const AngularWorkflow = (props) => { const [showSkippedActions, setShowSkippedActions] = React.useState(false) const [lastExecution, setLastExecution] = React.useState("") const [configureWorkflowModalOpen, setConfigureWorkflowModalOpen] = React.useState(false) - const [curpath, setCurpath] = useState(typeof window === 'undefined' || window.location === undefined ? "" : window.location.pathname) + + const curpath = typeof window === 'undefined' || window.location === undefined ? "" : window.location.pathname // 0 = normal, 1 = just done, 2 = normal const [savingState, setSavingState] = React.useState(0) @@ -216,14 +253,11 @@ const AngularWorkflow = (props) => { const [visited, setVisited] = React.useState([]); - //const [workflow, setWorkflow] = React.useState(workflowdata); const [apps, setApps] = React.useState([]); const [filteredApps, setFilteredApps] = React.useState([]); const [prioritizedApps, setPrioritizedApps] = React.useState([]); const [firstrequest, setFirstrequest] = React.useState(true) - //const [apps, setApps] = React.useState(appdata); - //const [filteredApps, setFilteredApps] = React.useState(); const [environments, setEnvironments] = React.useState([]); const [established, setEstablished] = React.useState(false); @@ -236,7 +270,6 @@ const AngularWorkflow = (props) => { const [executionRequest, setExecutionRequest] = React.useState({}) - const [, setExecutingNodes] = React.useState([]) const [executionRunning, setExecutionRunning] = React.useState(false) const [executionModalOpen, setExecutionModalOpen] = React.useState(false) const [executionModalView, setExecutionModalView] = React.useState(0) @@ -244,15 +277,15 @@ const AngularWorkflow = (props) => { const [lastSaved, setLastSaved] = React.useState(true) - const [appAdded, setAppAdded] = useState(false) - const [update, setUpdate] = useState(""); + // eslint-disable-next-line no-unused-vars + const [_, setUpdate] = useState(""); // Used for rendring, don't remove + const [workflowExecutions, setWorkflowExecutions] = React.useState([]); const [defaultEnvironmentIndex, setDefaultEnvironmentIndex] = React.useState(0) // This should all be set once, not on every iteration // Use states and don't update lol const cloudSyncEnabled = props.userdata !== undefined && props.userdata.active_org !== null && props.userdata.active_org !== undefined ? props.userdata.active_org.cloud_sync === true : false - //const triggerEnvironments = cloudSyncEnabled ? ["cloud", "onprem"] : environments const isCloud = window.location.host === "localhost:3002" || window.location.host === "shuffler.io" const appBarSize = isCloud ? 75 : 60 const triggerEnvironments = isCloud ? ["cloud"] : ["onprem", "cloud"] @@ -297,7 +330,6 @@ const AngularWorkflow = (props) => { // Sets up subflow trigger with the right info if (trigger_index > -1) { - var outersub = {} const trigger = workflow.triggers[trigger_index] if (trigger.parameters.length >= 3) { for (var key in trigger.parameters) { @@ -305,31 +337,17 @@ const AngularWorkflow = (props) => { if (param.name === "workflow") { if (param.value === workflow.id) { setSubworkflow(workflow) - outersub = workflow } else { const sub = responseJson.find(data => data.id === param.value) if (sub !== undefined && subworkflow.id !== sub.id) { setSubworkflow(sub) - outersub = sub } } } console.log("PARAM: ", param) - //console.log("PARAMVAL: ", param.value) if (param.name === "startnode" && param.value !== undefined && param.value !== null) { - //console.log("SHOULD SET STARTNODE IN SUBFLOW SELECTION: ", outersub) - //const innernode = outersub.actions.find(action => action.id === param.value) - //console.log("FOUND NODE: ", innernode) - //if (innernode !== undefined && subworkflowStartnode.id !== innernode.id) { - //setSubworkflowStartnode(JSON.parse(JSON.stringify(param.value))) setSubworkflowStartnode(param.value) - //} - /* - const sub = responseJson.find(data => data.id === param.value) - setSubworkflow(sub) - } - */ } } } @@ -481,8 +499,6 @@ const AngularWorkflow = (props) => { // - means it's opposite const newkeys = sortByKey(responseJson, "-started_at") setWorkflowExecutions(newkeys) - //console.log("NEWKEYS: ", newkeys) - //setWorkflowExecutions(responseJson) const cursearch = typeof window === 'undefined' || window.location === undefined ? "" : window.location.search var tmpView = new URLSearchParams(cursearch).get("execution_id") @@ -508,32 +524,12 @@ const AngularWorkflow = (props) => { } } - //alert.info("Loaded executions") - //setWorkflowExecutions(responseJson) }) .catch(error => { alert.error(error.toString()) }); } - const debugView = workflowExecutions.length > 0 ? - -
- {workflowExecutions.slice(0,15).map((data, index) => { - return ( -
- {new Date(data.started_at*1000).toISOString()} - , {data.status} - {data.result.length > 0 ? ", "+data.result : ", "} - {data.execution_argument.length > 0 ? ", "+data.execution_argument : ", "} - -
- ) - return - })} -
-
- : null const fetchUpdates = () => { fetch(globalUrl+"/api/v1/streams/results", { @@ -558,7 +554,6 @@ const AngularWorkflow = (props) => { }) .catch(error => { console.log("Error: ", error) - //alert.error(error.toString()) stop() }) } @@ -566,7 +561,6 @@ const AngularWorkflow = (props) => { const abortExecution = () => { setExecutionRunning(false) - //alert.info("Aborting execution") fetch(globalUrl+"/api/v1/workflows/"+props.match.params.key+"/executions/"+executionRequest.execution_id+"/abort", { method: 'GET', headers: { @@ -578,8 +572,6 @@ const AngularWorkflow = (props) => { .then((response) => { if (response.status !== 200) { console.log("Status not 200 for ABORT EXECUTION :O!") - } else { - //alert.success("Execution aborted") } return response.json() @@ -602,26 +594,18 @@ const AngularWorkflow = (props) => { if (executionData.execution_id === undefined || (responseJson.execution_id === executionData.execution_id && responseJson.results !== undefined && responseJson.results !== null)) { if (executionData.status !== responseJson.status || executionData.result !== responseJson.result || executionData.results.length !== responseJson.results.length) { - //console.log("Updated state with this data:") - //console.log(responseJson) - //console.log(executionData) setExecutionData(responseJson) } else { console.log("NOT updating state.") } } - } else { - //console.log("JSON is same") } - //console.log("PRE LOOPING RESULTS: !", responseJson.execution_id, executionRequest.execution_id) - if (responseJson.execution_id !== executionRequest.execution_id) { cy.elements().removeClass('success-highlight failure-highlight executing-highlight') return } - //console.log("LOOPING RESULTS!") if (responseJson.results !== null && responseJson.results.length > 0) { for (var key in responseJson.results) { @@ -635,7 +619,6 @@ const AngularWorkflow = (props) => { const outgoingEdges = currentnode.outgoers('edge') const incomingEdges = currentnode.incomers('edge') - //currentnode.removeClass('success-highlight failure-highlight executing-highlight') switch (item.status) { case "EXECUTING": currentnode.removeClass('not-executing-highlight') @@ -665,7 +648,6 @@ const AngularWorkflow = (props) => { if (!visited.includes(item.action.label)) { if (executionRunning) { - //alert.show("WAITING FOR "+item.action.label+" with result "+item.result) visited.push(item.action.label) setVisited(visited) } @@ -689,8 +671,6 @@ const AngularWorkflow = (props) => { if (visited !== undefined && visited !== null && !visited.includes(item.action.label)) { if (executionRunning) { - //alert.show("Success in node "+item.action.label) - //+" with result "+item.result) visited.push(item.action.label) setVisited(visited) } @@ -711,8 +691,6 @@ const AngularWorkflow = (props) => { targetnode.addClass('executing-highlight') } } - - // const outgoingEdges = currentnode.outgoers('edge') } break case "FAILURE": @@ -751,7 +729,7 @@ const AngularWorkflow = (props) => { } } - if (responseJson.status === "ABORTED" || responseJson.status === "STOPPED" || responseJson.status === "FAILURE" || responseJson.status == "WAITING") { + if (responseJson.status === "ABORTED" || responseJson.status === "STOPPED" || responseJson.status === "FAILURE" || responseJson.status === "WAITING") { stop() if (executionRunning) { @@ -763,24 +741,15 @@ const AngularWorkflow = (props) => { if (curelements[i].classes().includes("executing-highlight")) { curelements[i].removeClass("executing-highlight") curelements[i].addClass("failure-highlight") - } else { - //curelements[i].removeClass('not-executing-highlight') - //curelements[i].removeClass('executing-highlight') - //curelements[i].removeClass('success-highlight') - //curelements[i].removeClass('awaiting-data-highlight') - //curelements[i].removeClass('failure-highlight') } } getWorkflowExecution(props.match.params.key, "") } else if (responseJson.status === "FINISHED") { - //console.log("STOPPING BECAUSE ITS OVAH!") setExecutionRunning(false) stop() getWorkflowExecution(props.match.params.key, "") setUpdate(Math.random()) - } else { - //console.log("Nothing to update") } } @@ -802,8 +771,6 @@ const AngularWorkflow = (props) => { var useworkflow = workflow if (curworkflow !== undefined) { useworkflow = curworkflow - } else { - //alert.info("Saving workflow") } var cyelements = cy.elements() @@ -877,14 +844,12 @@ const AngularWorkflow = (props) => { curworkflowAction.parameters = newparams newActions.push(curworkflowAction) } else if (type === "TRIGGER") { - //console.log("TRIGGER") var curworkflowTrigger = useworkflow.triggers.find(a => a.id === cyelements[key].data()["id"]) if (curworkflowTrigger === undefined) { curworkflowTrigger = cyelements[key].data() } curworkflowTrigger.position = cyelements[key].position() - //console.log(curworkflowTrigger) newTriggers.push(curworkflowTrigger) } else { @@ -937,14 +902,11 @@ const AngularWorkflow = (props) => { success = true if (responseJson.errors !== undefined) { - //console.log(responseJson) workflow.errors = responseJson.errors if (responseJson.errors.length === 0) { workflow.isValid = true workflow.is_valid = true - //console.log("ELEMENTS: ", cy.elements()) - //const setupGraph = () => { const cyelements = cy.elements() for (var i = 0; i < cyelements.length; i++) { cyelements[i].removeStyle() @@ -959,14 +921,12 @@ const AngularWorkflow = (props) => { } for (var key in workflow.errors) { - //console.log("Error: ", workflow.errors[key]) alert.info(workflow.errors[key]) } setWorkflow(workflow) } - //alert.success("Successfully saved workflow") setSavingState(1) setTimeout(() => { setSavingState(0) @@ -1008,9 +968,6 @@ const AngularWorkflow = (props) => { const executeWorkflow = (executionArgument, startNode, hasSaved) => { if (hasSaved === false) { - //alert.error("You might have forgotten to save before executing.") - //const saveWorkflow = (curworkflow) => { - //setExecutionRunning(true) setExecutionRequestStarted(true) saveWorkflow(workflow, executionArgument, startNode) console.log("FIXME: Might have forgotten to save before executing.") @@ -1036,11 +993,6 @@ const AngularWorkflow = (props) => { curelements[i].addClass("not-executing-highlight") } - if (executionArgument !== undefined && executionArgument !== null && executionArgument.length > 0) { - //alert.success("Starting execution WITH an execution argument") - } else { - //alert.success("Starting execution") - } const data = {"execution_argument": executionArgument, "start": startNode} fetch(globalUrl+"/api/v1/workflows/"+props.match.params.key+"/execute", { @@ -1092,7 +1044,6 @@ const AngularWorkflow = (props) => { "execution_id": responseJson.execution_id, "authorization": responseJson.authorization, }) - setExecutingNodes([workflow.start]) setExecutionData({}) setExecutionModalOpen(true) setExecutionModalView(1) @@ -1103,77 +1054,6 @@ const AngularWorkflow = (props) => { }); } - //const handleAppVersioning = (apps) => { - // var newapps = [] - // for (var key in apps) { - // var item = apps[key] - // const previtem = newapps.findIndex(data => data.name === item.name) - // if (previtem === -1) { - // item["versions"] = [item.app_version] - // newapps.push(item) - // continue - // } - - // // THere might be duplicates for some reason.. - // if (!newapps[previtem]["versions"].includes(item.app_version)) { - // newapps[previtem]["versions"].push(item.app_version) - // } - // } - // - // // FIXME - handle this, as we can't have more than one of each :) - // //setVersionedApps(newapps) - //} - - // Builtin actions that should ran in Worker and not apps - const getExtraApps = () => { - const data = [{ - name: "Filter", - is_valid: true, - id: "0ca8887e-b4af-4e3e-887c-87e9d3bc3d3e", - link: "https://shuffler.io", - app_version: "1.0.0", - generated: true, - downloaded: false, - sharing: false, - verified: false, - tested: false, - owner: "", - private_id: "", - description: "Filter", - environment: "Shuffle", - small_image: "", - large_image: "", - contact_info: {name: "", url: ""}, - authentication: {required: false, parameters: [],}, - actions: [{ - description: "Filter cases", - id: "", - name: "filter_cases", - node_type: "action", - environment: "Shuffle", - sharing: false, - private_id: "", - app_id: "", - authentication: null, - tested: true, - parameters: [{ - description: "", - id: "", - name: "Field to look for", - example: "$testing_1.#.id", - value: "", - multiline: true, - action_field: "", - variant: "", - required: true, - schema: {type: "string"}, - }] - }], - }] - - return data - } - // This can be used to only show prioritzed ones later // Right now, it can prioritize authenticated ones //"Testing", @@ -1209,7 +1089,6 @@ const AngularWorkflow = (props) => { newauth.push(responseJson.data[key]) } - //{selectedAction.authentication.map(data => { if (cy !== undefined) { console.log("NEW AUTH = reset cy's onnodeselect") @@ -1224,23 +1103,13 @@ const AngularWorkflow = (props) => { setAuthLoaded(true) if (updateAction === true) { - //console.log("Should update authentication for selectedAction!!") - //console.log(responseJson) if (selectedApp.authentication.required) { - //console.log("App requires auth!!") // Setup auth here :) var appUpdates = false const authenticationOptions = [] - var findAuthId = "" - if (selectedAction.authentication_id !== null && selectedAction.authentication_id !== undefined && selectedAction.authentication_id.length > 0) { - findAuthId = selectedAction.authentication_id - } var tmpAuth = JSON.parse(JSON.stringify(responseJson.data)) - //console.log("FOUND AUTH: ", tmpAuth) - - //console.log("Checking authentication: ", tmpAuth) var latest = 0 for (var key in tmpAuth) { var item = tmpAuth[key] @@ -1260,29 +1129,18 @@ const AngularWorkflow = (props) => { selectedAction.selectedAuthentication = item for (var key in workflow.actions) { - //console.log(workflow.actions[key].app_name) - if (workflow.actions[key].app_name == selectedApp.name) { - //console.log("Setting auth at: ", workflow.actions[key], item.id) + if (workflow.actions[key].app_name === selectedApp.name) { workflow.actions[key].selectedAuthentication = item workflow.actions[key].authentication_id = item.id appUpdates = true - //if (workflow.actions[key].selectedAuthentication === undefined || workflow.actions[key].selectedAuthentication === null || workflow.actions[key].selectedAuthentication.length === 0) { - // console.log("Setting inner auth: ", workflow.actions[key]) - //} } } } } } - //if (item.id === findAuthId) { - // selectedAction.selectedAuthentication = item - //} - //console.log("ACTION: ", selectedAction) - //console.log("OPTIONS: ", authenticationOptions) selectedAction.authentication = authenticationOptions - //console.log("Authentication: ", authenticationOptions) if (selectedAction.selectedAuthentication === null || selectedAction.selectedAuthentication === undefined || selectedAction.selectedAuthentication.length === "") { selectedAction.selectedAuthentication = {} } @@ -1303,7 +1161,6 @@ const AngularWorkflow = (props) => { } } else { setAuthLoaded(true) - //alert.error("Failed getting authentications") } }) .catch(error => { @@ -1382,7 +1239,6 @@ const AngularWorkflow = (props) => { if (responseJson.public) { alert.info("This workflow is public. You will have to save it to make it your own!") - //setLastSaved(false) } // Appends SUBFLOWS. Does NOT run during normal grabbing of workflows. @@ -1462,9 +1318,6 @@ const AngularWorkflow = (props) => { return edge; }) - - //console.log("Adding node: ", node) - //cy.on('add', 'node', (e) => onNodeAdded(e)) edges = edges.filter(edge => edge !== null) cy.removeListener('add') cy.add(actions) @@ -1487,20 +1340,22 @@ const AngularWorkflow = (props) => { } cy.fit(null, 100) - //cy.zoom(2.0) cy.on('add', 'node', (e) => onNodeAdded(e)) cy.on('add', 'edge', (e) => onEdgeAdded(e)) - //for (var key in } else { setWorkflow(responseJson) setWorkflowDone(true) - //console.log(responseJson) // Add error checks console.log("Workflow: ", responseJson) if (!responseJson.public) { - if ((!responseJson.previously_saved || (!responseJson.is_valid || (responseJson.errors !== undefined || responseJson.errors !== null || responseJson.errors !== responseJson.errors.length > 0)))) { + if ((!responseJson.previously_saved || + (!responseJson.is_valid || + (responseJson.errors !== undefined || + responseJson.errors !== null || + responseJson.errors !== // what + (responseJson.errors.length > 0))))) { setConfigureWorkflowModalOpen(true) } } @@ -1591,7 +1446,6 @@ const AngularWorkflow = (props) => { const triggercheck = workflow.triggers.find(trigger => trigger.id === event.target.data()["source"]) if (triggercheck === undefined) { */ - //console.log(event.target.data()) if (event.target.data().decorator) { alert.info("This edge can't be edited.") } else { @@ -1601,7 +1455,7 @@ const AngularWorkflow = (props) => { const curaction = workflow.actions.find(a => a.id === destinationId) //console.log("ACTION: ", curaction) if (curaction !== undefined && curaction !== null) { - if (curaction.app_name == "Shuffle Tools" && curaction.name === "router") { + if (curaction.app_name === "Shuffle Tools" && curaction.name === "router") { alert.info("Router action can't have incoming conditions") event.target.unselect() return @@ -1612,12 +1466,6 @@ const AngularWorkflow = (props) => { setSelectedEdge(event.target.data()) } - /* - } else { - //alert.info("Can't edit branches from triggers") - console.log("IN HERE: !", triggercheck) - } - */ setSelectedAction({}) setSelectedTrigger({}) @@ -1655,36 +1503,15 @@ const AngularWorkflow = (props) => { .promise() .then( () => { console.log("DONE: ", workflow_id) - //cy.elements().remove() getWorkflow(workflow_id.value, nodedata) cy.fit(null, 50) - //props.match.params.key - //cy.animation({ - // zoom: 500, - // center: { - // eles: cy.nodes(), - // }, - //}) - //.play() - //.promise() }) - //const animationDuration = 150 - //style: { - //maxZoom={2.00} - //cy.animate({ - // fit: 100, - //}, { - // duration: 500, - //}) } } - //cy.on('cxttap', "node", (e) => onCtxTap(e)) - var hiddenNodes = [] const onNodeDragStop = (event, selectedAction) => { const nodedata = event.target.data() - //console.log("IN NODE DRAG STOP: ", nodedata) if (nodedata.id === selectedAction.id) { return } @@ -1693,19 +1520,11 @@ const AngularWorkflow = (props) => { return } - //console.log("Drag: ", nodedata) - //return - - //console.log("DRAGGED NODE: ", nodedata) - //console.log("TARGET NODE: ", selectedAction) if (styledElements.length === 1) { console.log("Should reset location and autofill: ", styledElements, selectedAction) - //event.target.position = originalLocation - //curworkflowTrigger.position = cyelements[key].position() if (originalLocation.x !== 0 || originalLocation.y !== 0) { const currentnode = cy.getElementById(nodedata.id) if (currentnode !== null && currentnode !== undefined) { - //currentnode.position = originalLocation currentnode.position("x", originalLocation.x) currentnode.position("y", originalLocation.y) } @@ -1715,7 +1534,6 @@ const AngularWorkflow = (props) => { const curElement = document.getElementById(styledElements[0]) if (curElement !== null && curElement !== undefined) { - //console.log("ELE: ", curElement) curElement.style.border = curElement.style.original_border var newValue = "$"+nodedata.label.toLowerCase().replaceAll(" ", "_") var paramname = "" @@ -1751,7 +1569,6 @@ const AngularWorkflow = (props) => { } } - const skipnames = [] if (nodedata.app_name !== undefined && (( nodedata.app_name !== "Shuffle Tools" && nodedata.app_name !== "Testing" && @@ -1774,13 +1591,11 @@ const AngularWorkflow = (props) => { // Readding the icon after moving the node if (!found) { - //console.log("Node wasn't found") const iconInfo = GetIconInfo(nodedata) const svg_pin = `` const svgpin_Url = encodeURI("data:image/svg+xml;utf-8," + svg_pin) const offset = nodedata.isStartNode ? 36 : 44 - //console.log(event.target.position()) const decoratorNode = { position: { x: event.target.position().x+offset, @@ -1802,10 +1617,7 @@ const AngularWorkflow = (props) => { } else { console.log("Node already exists - don't add descriptor node") } - } else { - //console.log("Shouldnt re-add info? ") } - originalLocation = { x: 0, y: 0, @@ -1813,28 +1625,12 @@ const AngularWorkflow = (props) => { } const onNodeDrag = (event, selectedAction) => { - //if (Object.getOwnPropertyNames(selectedAction).length === 0) { - // return - //} const nodedata = event.target.data() - //console.log("Dragging: ", nodedata) if (nodedata.finished === false) { return } - //console.log("Dragging node!!") - if (nodedata.app_name == "Shuffle Tools" || nodedata.app_name == "Testing") { - //console.log("NODE: ", - //selector: `node[app_name="Shuffle Tools"]`, - //console.log(event.target) - - // 1. Find location of node - // 2. Check if it's within view of another node (inside) - // 3. If it is, then hide text - } - if (nodedata.app_name !== undefined) { - //console.log("Trying to remove friendly nodes") const allNodes = cy.nodes().jsons() for (var key in allNodes) { const currentNode = allNodes[key] @@ -1851,7 +1647,6 @@ const AngularWorkflow = (props) => { } if (originalLocation.x === 0 && originalLocation.y === 0 && nodedata.position !== undefined) { - //console.log("Updating location!: ", nodedata) originalLocation.x = nodedata.position.x originalLocation.y = nodedata.position.y } @@ -1866,8 +1661,7 @@ const AngularWorkflow = (props) => { if (elementMouseIsOver !== undefined && elementMouseIsOver !== null) { // Color for #f85a3e translated to rgb const newBorder = "3px solid rgb(248, 90, 62)" - if (elementMouseIsOver.style.border != newBorder && elementMouseIsOver.id.includes("rightside")) { - //console.log(elementMouseIsOver.style.border) + if (elementMouseIsOver.style.border !== newBorder && elementMouseIsOver.id.includes("rightside")) { if (elementMouseIsOver.style.border !== undefined) { elementMouseIsOver.style.original_border = elementMouseIsOver.style.border } else { @@ -1903,46 +1697,19 @@ const AngularWorkflow = (props) => { document.addEventListener('mousemove', onMouseUpdate, false); - /* - event.target.animate({ - style: { - "border-width": "12px", - "border-opacity": ".7", - } - }, { - duration: animationDuration, - }) - event.target.animate({ - style: { - "border-width": "12px", - "border-opacity": ".7", - } - }, { - duration: animationDuration, - }) - */ } // Nodeselectbatching: // https://stackoverflow.com/questions/16677856/cy-onselect-callback-only-once const onNodeSelect = (event, newAppAuth) => { const data = event.target.data() - //console.log("NEW NODE ID: ", data.id) if (data.isButton) { - //console.log("BUTTON CLICKED: ", data) if (data.buttonType === "delete") { - //console.log("DELETE!") const parentNode = cy.getElementById(data.attachedTo) if (parentNode !== null && parentNode !== undefined) { parentNode.remove() } - //for (var key in allNodes) { - // const currentNode = allNodes[key] - // if (currentNode.data.attachedTo === data.attachedTo) { - // cy.getElementById(currentNode.data.id).remove() - // } - //} } else if (data.buttonType === "set_startnode" && data.type !== "TRIGGER") { const parentNode = cy.getElementById(data.attachedTo) if (parentNode !== null && parentNode !== undefined) { @@ -1967,7 +1734,6 @@ const AngularWorkflow = (props) => { // 3. Make a new node that's moved a little bit const parentNode = cy.getElementById(data.attachedTo) if (parentNode !== null && parentNode !== undefined) { - //parentNode.data() var newNodeData = JSON.parse(JSON.stringify(parentNode.data())) newNodeData.id = uuidv4.v4() if (newNodeData.position !== undefined) { @@ -1990,7 +1756,6 @@ const AngularWorkflow = (props) => { }) // Readding the icon after moving the node - //console.log("Node wasn't found") if (newNodeData.app_name !== "Testing" || newNodeData.app_name !== "Shuffle Workflow") { } else { const iconInfo = GetIconInfo(newNodeData) @@ -1998,7 +1763,6 @@ const AngularWorkflow = (props) => { const svgpin_Url = encodeURI("data:image/svg+xml;utf-8," + svg_pin) const offset = newNodeData.isStartNode ? 36 : 44 - //console.log(event.target.position()) const decoratorNode = { position: { x: newNodeData.position.x+offset, @@ -2024,15 +1788,6 @@ const AngularWorkflow = (props) => { const sourcebranches = workflow.branches.filter(foundbranch => foundbranch.source_id === parentNode.data("id")) const destinationbranches = workflow.branches.filter(foundbranch => foundbranch.destination_id === parentNode.data("id")) - //for (var key in sourcebranches) { - // var newbranch = JSON.parse(JSON.stringify(sourcebranches[key])) - // newbranch.id = uuidv4() - // newbranch.source_id = newNodeData.id - // cy.add({ - // group: "edges", - // data: newbranch, - // }) - //} for (var key in sourcebranches) { var newbranch = JSON.parse(JSON.stringify(sourcebranches[key])) @@ -2072,31 +1827,16 @@ const AngularWorkflow = (props) => { return } - //const node = cy.getElementById(data.id) - //if (node.length > 0) { - // node.addClass('shuffle-hover-highlight') - //} - - //const branch = workflow.branches.filter(branch => branch.source_id === data.id || branch.destination_id === data.id) - //console.log("APPAUTH: ", newAppAuth) - //console.log("BRANCHES: ", branch) - //console.log("CLICK: ", data) if (data.type === "ACTION") { - //setSelectedApp({}) - //setSelectedAction({}) var curaction = workflow.actions.find(a => a.id === data.id) - //console.log("PARAMS: ", curaction.parameters[0]) - //console.log("INSIDE CURACTION: ", curaction) if (!curaction || curaction === undefined) { - //event.target.unselect() alert.error("Action not found. Please remake it.") return } const curapp = apps.find(a => a.name === curaction.app_name && ((a.app_version === curaction.app_version || (a.loop_versions !== null && a.loop_versions.includes(curaction.app_version))))) - //console.log("APP: ", curapp) if (!curapp || curapp === undefined) { alert.error(`App ${curaction.app_name}:${curaction.app_version} not found. Is it activated?`) @@ -2108,15 +1848,9 @@ const AngularWorkflow = (props) => { actions: [curaction], } - //console.log(tmpapp) - //console.log(curaction) setSelectedApp(tmpapp) - //setSelectedAction(JSON.parse(JSON.stringify(curaction))) setSelectedAction(curaction) - //return } else { - //console.log("AUTHENTICATION: ", curapp.authentication) - //console.log(curapp.authentication) setAuthenticationType(curapp.authentication.type === "oauth2" && curapp.authentication.redirect_uri !== undefined && curapp.authentication.redirect_uri !== null ? { "type": "oauth2", @@ -2132,7 +1866,6 @@ const AngularWorkflow = (props) => { ) const requiresAuth = curapp.authentication.required //&& ((curapp.authentication.parameters !== undefined && curapp.authentication.parameters !== null) || (curapp.authentication.type === "oauth2" && curapp.authentication.redirect_uri !== undefined && curapp.authentication.redirect_uri !== null)) - //console.log("AUTHCHECK: ", requiresAuth) setRequiresAuthentication(requiresAuth) if (curapp.authentication.required) { //console.log("App requires auth.") @@ -2144,9 +1877,7 @@ const AngularWorkflow = (props) => { } var tmpAuth = JSON.parse(JSON.stringify(newAppAuth)) - //console.log("FOUND AUTH: ", tmpAuth) - //console.log("Checking authentication: ", tmpAuth) for (var key in tmpAuth) { var item = tmpAuth[key] @@ -2164,9 +1895,7 @@ const AngularWorkflow = (props) => { } } - //console.log("OPTIONS: ", authenticationOptions) curaction.authentication = authenticationOptions - //console.log("Authentication: ", authenticationOptions) if (curaction.selectedAuthentication === null || curaction.selectedAuthentication === undefined || curaction.selectedAuthentication.length === "") { curaction.selectedAuthentication = {} } @@ -2176,13 +1905,12 @@ const AngularWorkflow = (props) => { curaction.selectedAuthentication = {} } - //setSelectedAction(JSON.parse(JSON.stringify(curaction))) - //console.log("CURAPP: ", curapp, selectedApp) - //console.log("ACTION: ", curaction) if (curaction.parameters !== undefined && curaction.parameters !== null && curaction.parameters.length > 0) { - //console.log("params: ", curaction.parameters) for (var key in curaction.parameters) { - if (curaction.parameters[key].options !== undefined && curaction.parameters[key].options !== null && curaction.parameters[key].options.length > 0 && curaction.parameters[key].value == "") { + if (curaction.parameters[key].options !== undefined && + curaction.parameters[key].options !== null && + curaction.parameters[key].options.length > 0 && + curaction.parameters[key].value === "") { curaction.parameters[key].value = curaction.parameters[key].options[0] } } @@ -2207,8 +1935,6 @@ const AngularWorkflow = (props) => { } } else if (data.type === "TRIGGER") { - //console.log("Should handle trigger "+data.triggertype) - //console.log(data) const trigger_index = workflow.triggers.findIndex(a => a.id === data.id) if (data.app_name === "Shuffle Workflow") { @@ -2227,14 +1953,9 @@ const AngularWorkflow = (props) => { alert.error("Can't handle "+data.type) } - //console.log("BAR: ", rightSideBarOpen, "SAVE: ", lastSaved) setRightSideBarOpen(true) setLastSaved(false) - // Refresh listeners - //cy.removeListener('select') - //cy.on('select', 'node', (e) => onNodeSelect(e, newAppAuth, curapp, rightSideBarOpen, lastSaved)) - //cy.on('select', 'edge', (e) => onEdgeSelect(e)) setScrollConfig({ top: 0, @@ -2247,7 +1968,6 @@ const AngularWorkflow = (props) => { var exampledata = item.example === undefined ? "" : item.example if (workflowExecutions.length > 0) { // Look for the ID - const found = false for (var key in workflowExecutions) { if (workflowExecutions[key].results === undefined || workflowExecutions[key].results === null) { continue @@ -2255,7 +1975,6 @@ const AngularWorkflow = (props) => { var foundResult = {"result": ""} if (item.id === "exec") { - //console.log("EXEC: ", workflowExecutions[key].execution_argument) if (workflowExecutions[key].execution_argument !== undefined && workflowExecutions[key].execution_argument !== null && workflowExecutions[key].execution_argument.length > 0) { foundResult.result = workflowExecutions[key].execution_argument } else { @@ -2275,14 +1994,12 @@ const AngularWorkflow = (props) => { var jsonvalid = true try { - const tmp = String(JSON.parse(foundResult.result)) if (!foundResult.result.includes("{") && !foundResult.result.includes("[")) { jsonvalid = false } } catch (e) { try { - foundResult.result = foundResult.result.split("\'").join("\"") - const tmp = String(JSON.parse(foundResult.result)) + foundResult.result = foundResult.result.split("'").join("\"") if (!foundResult.result.includes("{") && !foundResult.result.includes("[")) { jsonvalid = false } @@ -2293,23 +2010,16 @@ const AngularWorkflow = (props) => { // Finds the FIRST json only if (jsonvalid) { - //console.log("VALID!") exampledata = JSON.parse(foundResult.result) break - } else { - //console.log("INVALID: ", foundResult.result) } } } - //console.log("EXAMPLE: ", exampledata) return exampledata } const GetParamMatch = (paramname, exampledata, basekey) => { - const splitkey = "." - //console.log(typeof(exampledata)) - //console.log("MATCHING WITH: ", exampledata) if (typeof(exampledata) !== "object") { return "" } @@ -2340,36 +2050,14 @@ const AngularWorkflow = (props) => { break } } - //console.log("SELECTED: ", selectedsynonyms) - //console.log("SYNONYMS FOR ", paramname, selectedsynonyms) var toreturn = "" for (const [key, value] of Object.entries(exampledata)) { // Check if loop or JSON - const extra = basekey.length > 0 ? splitkey : "" - const basekeyname = `${basekey.slice(1, basekey.length).split(".").join(splitkey)}${extra}${key}` - // Handle direct loop! - //if (!isNaN(key) && basekey === "") { - // //console.log("Handling direct loop: ", key, value) - // //parsedValues.push({"type": "object", "name": "Node", "autocomplete": `${basekey}`}) - // //parsedValues.push({"type": "list", "name": `${splitkey}list`, "autocomplete": `${basekey}.#`}) - // //for (var subkey in returnValues) { - // // parsedValues.push(returnValues[subkey]) - // //} - - // toreturn = GetParsedPaths(paramname, value, `${basekey}.#`) - // console.log("LIST, TORETURN: ", value, toreturn) - // if (toreturn.length > 0) { - // break - // } - //} - - //console.log("KEY: ", key, "VALUE: ", value, "BASEKEY: ", basekeyname) if (typeof(value) === 'object') { if (Array.isArray(value)) { - //console.log("LIST!!: ", value, key) var selectedkey = "" if (isNaN(key)) { selectedkey = `.${key}` @@ -2392,19 +2080,13 @@ const AngularWorkflow = (props) => { } toreturn = GetParamMatch(paramname, value, `${basekey}${selectedkey}`) - //console.log("OBJECT: ", value, toreturn, key) if (toreturn.length > 0) { break } } - //console.log("VALUE IS OBJECT: ", key, value) } else { - //console.log("SINGLE ITEM: ", key) if (selectedsynonyms.includes(key.toLowerCase())) { - //parsedValues.push({"type": "value", "name": basekeyname, "autocomplete": `${basekey}.${key}`, "value": value,}) - //console.log("STRING: ", key, value) toreturn = `${basekey}.${key}` - //toreturn = basekeyname break } } @@ -2420,7 +2102,6 @@ const AngularWorkflow = (props) => { // 1. Check execution argument // 2. Check parents in order var exampledata = GetExampleResult({"id": "exec", "name": "exec",}) - //console.log("EXAMPLE RETURN: ", exampledata) var parentlabel = "exec" for (var paramkey in dstdata.parameters) { const param = dstdata.parameters[paramkey] @@ -2430,23 +2111,17 @@ const AngularWorkflow = (props) => { } const paramname = param.name.toLowerCase().trim().replaceAll("_", " ") - //console.log("PARAM: ", param) - //console.log("PARAMNAME: ", paramname) const foundresult = GetParamMatch(paramname, exampledata, "") if (foundresult.length > 0) { - //console.log("FOUND: ", paramname, foundresult) if (dstdata.parameters[paramkey].value.length === 0) { dstdata.parameters[paramkey].value = `$${parentlabel}${foundresult}` - } else { - //console.log("Skipping ", dstdata.parameters[paramkey], " because it already has a value") - } + } } } var parents = getParents(dstdata) - //console.log("PARENTS: ", parents) if (parents.length > 1) { for (var key in parents) { const item = parents[key] @@ -2464,18 +2139,14 @@ const AngularWorkflow = (props) => { } const paramname = param.name.toLowerCase().trim().replaceAll("_", " ") - //console.log("PARAM: ", param) - //console.log("PARAMNAME: ", paramname) const foundresult = GetParamMatch(paramname, exampledata, "") if (foundresult.length > 0) { - //console.log("FOUND: ", paramname, foundresult) if (dstdata.parameters[paramkey].value.length === 0) { dstdata.parameters[paramkey].value = `$${parentlabel}${foundresult}` } else { dstdata.parameters[paramkey].value = `$${parentlabel}${foundresult}` - //console.log("Skipping ", dstdata.parameters[paramkey], " because it already has a value") } } } @@ -2486,14 +2157,12 @@ const AngularWorkflow = (props) => { return dstdata } - //const FixNameUpdater = (sourcenode) => { - //} + // Checks for errors in edges when they're added const onEdgeAdded = (event) => { const edge = event.target.data() - //console.log("EDGE ADDED: ", edge) - //setLastSaved(false) + var targetnode = workflow.triggers.findIndex(data => data.id === edge.target) if (targetnode !== -1) { console.log("TARGETNODE: ", targetnode) @@ -2504,50 +2173,14 @@ const AngularWorkflow = (props) => { } } - //console.log("TARGET: ", event.target.target().data()) if (event.target.target().data("isButton") === true || event.target.target().data("isDescriptor") === true) { event.target.remove() return } targetnode = -1 - var sourcenode = workflow.triggers.findIndex(data => data.id === edge.source) - //console.log("SOURCENODE: ", sourcenode) - if (sourcenode !== -1) { - if (workflow.triggers[sourcenode].app_name === "User Input" || workflow.triggers[sourcenode].app_name === "Shuffle Workflow") { - //console.log("NORMAL TRIGGER") - } else { - //var currentnode = cy.getElementById(workflow.triggers[sourcenode].id) - //console.log("NODE: ", currentnode) - //if (currentnode !== null && currentnode !== undefined) { - // console.log("SHOULD CHECK IF TRIGGER HAS MULTIPLE EDGES: ", currentnode) - //if (workflow.branches !== undefined && workflow.branches !== null) { - // const found_branches = workflow.branches.filter(branch => branch.source == workflow.triggers[sourcenode].id) - // console.log("FOUND BRANCHES: ", found_branches) - // if (found_branches.length > 0) { - // alert.error("Can't have multiple branches from this trigger") - // event.target.remove() - // } - //} - - //if (cy.edges().size() === 1) { - // https://js.cytoscape.org/#edges.connectedNodes - //console.log("CURRENTNODE: ", currentnode) - //console.log("EDGES: ", currentnode.connectedEdges(`node[id=${workflow.triggers[sourcenode].id}]`)) - //console.log("EDGES2: ", currentnode.connectedEdges()) - //currentnode.connectedEdges().animate({style: {lineColor: "red"}}) - //console.log("OUTGOERS: ", currentnode.outgoers()) - - //console.log("LEN2: ", currentnode.edges().length) - //if (currentnode.connectedNodes().length > 0) { - // alert.error("Can't have multiple branches from this trigger") - // event.target.remove() - //} - } - } - //console.log(workflow.branches) // Check if: // dest == source && source == dest @@ -2617,8 +2250,6 @@ const AngularWorkflow = (props) => { const newsource = cy.getElementById(edge.source) const newdst = cy.getElementById(edge.target) if (newsource !== undefined && newsource !== null && newdst !== undefined && newdst !== null) { - //const srcdata = newsource.data() - //console.log("EDGE: ", edge) const dstdata = RunAutocompleter(newdst.data()) console.log("DST: ", dstdata) } @@ -2652,13 +2283,11 @@ const AngularWorkflow = (props) => { const node = event.target const nodedata = event.target.data() if (nodedata.finished === false || (nodedata.id !== undefined && nodedata.is_valid === undefined)) { - //console.log("RETURNING (NOT ADDING) NODE ADD FOR: ", nodedata) return } //console.log("IS IT ADDED TO THE WORKFLOW?: ", nodedata) if (node.isNode() && cy.nodes().size() === 1) { - //setStartNode(node.data('id')) workflow.start = node.data('id') nodedata.isStartNode = true } else { @@ -2667,7 +2296,6 @@ const AngularWorkflow = (props) => { } // Remove bad startnode - const startnode_exists = false for (var key in workflow.actions) { const action = workflow.actions[key] if (action.isStartNode && workflow.start !== action.id) { @@ -2677,29 +2305,7 @@ const AngularWorkflow = (props) => { } if (nodedata.type === "ACTION") { - /* - const tmpView = localStorage.getItem(appSorter) - const nodekey = nodedata.id - if (tmpView === null || tmpView === undefined) { - const basedata = {} - basedata[nodekey] = 1 - localStorage.setItem(appSorter, JSON.stringify(basedata)) - } else { - try { - var parsed = JSON.parse(tmpView) - try { - parsed[nodekey] += 1 - } catch { - parsed[nodekey] = 1 - } - localStorage.setItem(appSorter, JSON.stringify(parsed)) - } catch { - console.log("Bad data in tmpView: ", tmpView) - } - } - console.log("FAVORITeS: ", tmpView) - */ if (workflow.actions.length === 1 && workflow.actions[0].id === workflow.start) { const newEdgeUuid = uuidv4() @@ -2785,16 +2391,12 @@ const AngularWorkflow = (props) => { } if (nodedata.name !== "User Input" && nodedata.name !== "Shuffle Workflow") { - //workflow.branches.push(newbranch) if (workflow.actions !== undefined && workflow.actions !== null && workflow.actions.length > 0) { cy.add(edgeToBeAdded) } } - //if (data.trigger_type === "WEBHOOK") { - // newWebhook(newAppData) - // saveWorkflow(workflow) - //} + setWorkflow(workflow) } @@ -2810,58 +2412,6 @@ const AngularWorkflow = (props) => { setHistoryIndex(history.length) } - //if (nodedata.app_name !== undefined && (( - // nodedata.app_name !== "Shuffle Tools" && - // nodedata.app_name !== "Testing" && - // nodedata.app_name !== "Shuffle Workflow" && - // nodedata.app_name !== "User Input" && - // nodedata.app_name !== "Webhook" && - // nodedata.app_name !== "Schedule" && - // nodedata.app_name !== "Email") || nodedata.isStartNode) - //) { - // const allNodes = cy.nodes().jsons() - // var found = false - // for (var key in allNodes) { - // const currentNode = allNodes[key] - // if (currentNode.data.attachedTo === nodedata.id && currentNode.data.isDescriptor) { - // found = true - // console.log("FOUND THE NODE!") - // break - // } - // } - - // // Readding the icon after moving the node - // if (!found) { - // console.log("Node wasn't found") - // const iconInfo = GetIconInfo(nodedata) - // const svg_pin = `` - // const svgpin_Url = encodeURI("data:image/svg+xml;utf-8," + svg_pin) - - // const offset = nodedata.isStartNode ? 36 : 44 - // const decoratorNode = { - // position: { - // x: event.target.position().x+offset, - // y: event.target.position().y+offset, - // }, - // locked: true, - // data: { - // "isDescriptor": true, - // "isValid": true, - // "is_valid": true, - // "label": "", - // "image": svgpin_Url, - // "imageColor": iconInfo.iconBackgroundColor, - // "attachedTo": nodedata.id, - // }, - // } - - // cy.add(decoratorNode) - // } else { - // console.log("Node already exists - don't add descriptor node") - // } - //} else { - // //console.log("Shouldnt re-add info? ") - //} } const onEdgeRemoved = (event) => { @@ -2875,12 +2425,8 @@ const AngularWorkflow = (props) => { // trigger as source check const indexcheck = workflow.triggers.findIndex(data => edge.data()["source"] === data.id) if (indexcheck !== -1) { - //alert.error("Can't remove edge from a trigger") console.log("Shouldnt remove edge from trigger") - //const edgeToBeAdded = { - // group: "edges", - // data: newcybranch, - //} + } if (edge.data().source !== undefined) { @@ -2902,7 +2448,6 @@ const AngularWorkflow = (props) => { return } - //setLastSaved(false) workflow.actions = workflow.actions.filter(a => a.id !== data.id) workflow.triggers = workflow.triggers.filter(a => a.id !== data.id) @@ -2925,21 +2470,10 @@ const AngularWorkflow = (props) => { } } - //cy.nodes().some(function( ele ) { - // if (ele.id() !== workflow.start && ele.data()["label"] !== undefined) { - // //alert.success("Changed startnode to "+ele.data()["label"]) - // ele.data("isStartNode", true) - // workflow.start = ele.id() - // throw BreakException - // return false - // } - //}) } if (data.app_name !== undefined) { - //console.log("Trying to remove friendly nodes") const allNodes = cy.nodes().jsons() - //console.log("NOT UNDEFINED IN HOVEROUT!", allNodes) for (var key in allNodes) { const currentNode = allNodes[key] if (currentNode.data.attachedTo === data.id) { @@ -2965,18 +2499,13 @@ const AngularWorkflow = (props) => { var previouskey = 0 const handleKeyDown = (event) => { - // SHIFT = 16 - // CTRL = 17 - //console.log(event.keyCode) switch( event.keyCode ) { case 27: - //console.log("ESCAPE") if (configureWorkflowModalOpen === true) { setConfigureWorkflowModalOpen(false) } break; case 46: - //removeNode() console.log("DELETE") break; case 38: @@ -2994,29 +2523,13 @@ const AngularWorkflow = (props) => { case 90: if (previouskey === 17) { console.log("CTRL+Z") - //handleHistoryUndo() } break; case 67: if (previouskey === 17) { console.log("CTRL+C") - //const filteredelements = cy.filter(function(element, i){ - // return element.hasClass('selected') - //}) - //for (var key in filteredelements) { - //} - - //var copyText = document.getElementById("copy_element_shuffle") - //if (copyText !== undefined && copyText !== null) { - // const clipboard = navigator.clipboard - // if (clipboard === undefined) { - // alert.error("Can only copy over HTTPS (port 3443)") - // return - // } - //} - //console.log("FILTERED: ", filteredelements) } break; case 86: @@ -3030,33 +2543,16 @@ const AngularWorkflow = (props) => { } break; case 83: - //if (previouskey === 17) { - // event.preventDefault() - // saveWorkflow() - //} + break; case 70: - //if (previouskey === 17) { - // event.preventDefault() - // cy.fit(null, 50) - //} - //break; + break; case 65: // As a poweruser myself, I found myself hitting this a few // too many times to just edit text. Need a better bind - // - //if (previouskey === 17) { - // event.preventDefault() - // if (executionRunning || executionRequestStarted) { - // abortExecution() - // } else { - // executeWorkflow() - // } - // cy.fit(null, 50) - //} + break; default: - //console.log(event.keyCode) break; } @@ -3126,15 +2622,10 @@ const AngularWorkflow = (props) => { if (!firstrequest && graphSetup && established && props.match.params.key !== workflow.id && workflow.id !== undefined && workflow.id !== null && workflow.id.length > 0) { - //console.log(props.match.params.key, workflow.id) - //getWorkflow() - //setCy() - //getWorkflowExecution(props.match.params.key, "") - //setEstablished(false) - //setGraphSetup(false) window.location.pathname = "/workflows/"+props.match.params.key } + // eslint-disable-next-line react-hooks/exhaustive-deps useEffect(() => { if (firstrequest) { setFirstrequest(false) @@ -3159,25 +2650,17 @@ const AngularWorkflow = (props) => { // App length necessary cus of cy initialization - //console.log("PRE ELEMENTS: !", workflow.actions, graphSetup, apps, authLoaded, cy) if (elements.length === 0 && workflow.actions !== undefined && !graphSetup && Object.getOwnPropertyNames(workflow).length > 0) { setGraphSetup(true) setupGraph() - //console.log("IN ELEMENT CHECK!") } else if (!established && cy !== undefined && apps !== null && apps !== undefined && apps.length > 0 && Object.getOwnPropertyNames(workflow).length > 0 && authLoaded){ //This part has to load LAST, as it's kind of not async. //This means we need everything else to happen first. - // - //console.log("IN THIS PART AGAIN") - - //console.log("IN ESTABLISHED!") + setEstablished(true) // Validate if the node is just a node lol - //console.log("CY: ", cy) - //console.log("CY: ", cy.edgehandles()) - //try { cy.edgehandles({ handleNodes: (el) => el.isNode() && !el.data("isButton") && !el.data("isDescriptor"), preview: false, @@ -3186,9 +2669,6 @@ const AngularWorkflow = (props) => { return false; }, }) - //} catch (e) { - // console.log("Error in edgehandles: ", e) - //} cy.fit(null, 200) @@ -3203,12 +2683,10 @@ const AngularWorkflow = (props) => { cy.on('boxstart', (e) => { console.log("START") cy.removeListener('select') - //onNodeSelect(e, appAuthentication) }) cy.on('boxend', (e) => { console.log("END") cy.removeListener('select') - //onNodeSelect(e, appAuthentication) }) cy.on('select', 'node', (e) => { @@ -3234,62 +2712,12 @@ const AngularWorkflow = (props) => { cy.on('cxttap', "node", (e) => onCtxTap(e)) - //let popper2 = cy.popper({ - // content: () => { - // let div = document.createElement('div'); - // - // div.innerHTML = 'Popper content' - // - // document.body.appendChild(div) - // - // return div - // }, - // renderedPosition: () => ({ x: 100, y: 200 }), - // popper: {} // my popper options here - //}); - - //let popper1 = cy.nodes()[0].popper({ - // content: () => { - // let div = document.createElement('div') - // - // div.innerHTML = 'Popper content' - // document.body.appendChild(div) - // - // return div - // }, - // popper: {} // my popper options here - //}) - //let update = () => { - // popper.update() - //} - - //let node = cy.nodes().first() - //node.on('position', update) - - - - - - //cy.on('mouseover', 'node', () => $(targetElement).addClass('mouseover')); - - //cy.on('cxttapstart', 'node', (e) => edgeHandler.start(e.target)) - //cy.on('cxttapend', 'node', (e) => edgeHandler.stop()) - //cy.on('cxtdragover', 'node', (e) => edgeHandler.preview(e.target)) - //cy.on('cxtdragout', 'node', (e) => edgeHandler.unpreview(e.target)) - document.title = "Workflow - "+workflow.name registerKeys() - //setStartNode(workflow.start) - } else if (established) { - //console.log("established - should fix colors of things") - //console.log(cy.elements()) } }) - //}, [selectedAction]) - var previousnodecolor = "" - //var previousedgecolor = "" const animationDuration = 150 const onNodeHoverOut = (event) => { const nodedata = event.target.data() @@ -3343,7 +2771,6 @@ const AngularWorkflow = (props) => { return } - //parentNode.lock() const px = parentNode.position('x') - 65 const py = parentNode.position('y') - 45 const circleId = newNodeId = uuidv4() @@ -3375,7 +2802,6 @@ const AngularWorkflow = (props) => { position: { x: px, y: py }, locked: true }) - //.unselectify() } const addCopyButton = (event) => { @@ -3383,7 +2809,6 @@ const AngularWorkflow = (props) => { if (parentNode.data('isButton') || parentNode.data('buttonId')) return - //parentNode.lock() const px = parentNode.position('x') - 65 const py = parentNode.position('y') - 5 const circleId = newNodeId = uuidv4() @@ -3415,7 +2840,6 @@ const AngularWorkflow = (props) => { position: { x: px, y: py }, locked: true }) - //.unselectify() } const addDeleteButton = (event) => { @@ -3423,7 +2847,6 @@ const AngularWorkflow = (props) => { if (parentNode.data('isButton') || parentNode.data('buttonId')) return - //parentNode.lock() const px = parentNode.position('x') - 65 const py = parentNode.position('y') + 35 const circleId = newNodeId = uuidv4() @@ -3454,11 +2877,9 @@ const AngularWorkflow = (props) => { position: { x: px, y: py }, locked: true }) - //.unselectify() } const onNodeHover = (event) => { - //console.log("TAR: ", event.target) const nodedata = event.target.data() if (nodedata.finished === false) { return @@ -3504,7 +2925,6 @@ const AngularWorkflow = (props) => { duration: animationDuration, }) - previousnodecolor = event.target.style("border-color") const outgoingEdges = event.target.outgoers('edge') const incomingEdges = event.target.incomers('edge') @@ -3570,13 +2990,9 @@ const AngularWorkflow = (props) => { action.fillstyle = "solid" if (action.fillGradient !== undefined && action.fillGradient !== null && action.fillGradient.length > 0) { action.fillstyle = 'linear-gradient' - //console.log("GRADIENT!: ", action) - //action.fillstyle = - //'background-fill': 'data(fillstyle)', } else { action.iconBackground = iconInfo.iconBackgroundColor } - //console.log("FOUND NODE INFO: ", action) } node.position = action.position @@ -3628,7 +3044,6 @@ const AngularWorkflow = (props) => { }, } return decoratorNode - return null }) const triggers = workflow.triggers.map(trigger => { @@ -3647,7 +3062,6 @@ const AngularWorkflow = (props) => { insertedNodes = insertedNodes.filter(node => node !== null) var edges = workflow.branches.map((branch, index) => { - //workflow.branches[index].conditions = [{ const edge = { }; var conditions = workflow.branches[index].conditions @@ -3790,7 +3204,6 @@ const AngularWorkflow = (props) => { } const stopSchedule = (trigger, triggerindex) => { - //alert.info("Stopping schedule") fetch(globalUrl+"/api/v1/workflows/"+props.match.params.key+"/schedule/"+trigger.id, { method: 'DELETE', headers: { @@ -3827,13 +3240,7 @@ const AngularWorkflow = (props) => { }); } - //const submitSchedule = (id, name, frequency, executionArg) => { const submitSchedule = (trigger, triggerindex) => { - //const cronSplit = workflow.triggers[triggerindex].parameters[0].value.split("*") - //if (cronSplit.length <= 5 || cronSplit.length > 6) { - // alert.error("Error: Bad cron, example run every 1 minute: */1 * * * *") - // return - //} if (trigger.name.length <= 0) { alert.error("Error: name can't be empty") @@ -4017,7 +3424,7 @@ const AngularWorkflow = (props) => { }}>New workflow variable - What are EXECUTION variables? + What are EXECUTION variables? {workflow.execution_variables === null || workflow.execution_variables === undefined ? null : workflow.execution_variables.map(variable=> { return ( @@ -4085,7 +3492,6 @@ const AngularWorkflow = (props) => { ) } - const curTab = 0 const handleSetTab = (event, newValue) => { setCurrentView(newValue) } @@ -4303,7 +3709,6 @@ const AngularWorkflow = (props) => { const handleTriggerDrag = (e, data) => { const cycontainer = cy.container() // Chrome lol - //if (e.srcElement !== undefined && e.srcElement.localName === "canvas") { if (e.pageX > cycontainer.offsetLeft && e.pageX < cycontainer.offsetLeft+cycontainer.offsetWidth && e.pageY > cycontainer.offsetTop && e.pageY < cycontainer.offsetTop+cycontainer.offsetHeight) { if (newNodeId.length > 0) { var currentnode = cy.getElementById(newNodeId) @@ -4319,10 +3724,6 @@ const AngularWorkflow = (props) => { return } - //if (data.is_valid === false) { - // alert.error(data.name+" requires hybrid version of Shuffle") - // return - //} const triggerLabel = getNextActionName(data.name) @@ -4354,10 +3755,6 @@ const AngularWorkflow = (props) => { position: newposition, } - //if (data.trigger_type === "WEBHOOK") { - // newAppData.status = "running" - //} - // Can all the data be in here? hmm const nodeToBeAdded = { group: "nodes", @@ -4373,11 +3770,6 @@ const AngularWorkflow = (props) => { } const handleDragStop = (e, app) => { - //console.log("STOP!: ", e) - //console.log("APP!: ", parsedApp) - //const onNodeAdded = (event) => { - //const node = event.target - //const nodedata = event.target.data() var currentnode = cy.getElementById(newNodeId) if (currentnode === undefined || currentnode === null || currentnode.length === 0) { return @@ -4432,16 +3824,6 @@ const AngularWorkflow = (props) => { } } - //newAppData.authentication = authenticationOptions - //if (newAppData.selectedAuthentication === null || newAppData.selectedAuthentication === undefined || newAppData.selectedAuthentication.length === "") { - // newAppData.selectedAuthentication = {} - //} else { - // console.log("CAN WE SELECT AUTH?: ", authenticationOptions) - //} - // - // - - //console.log(parsedApp) } else { newAppData.authentication = [] newAppData.authentication_id = "" @@ -4472,7 +3854,6 @@ const AngularWorkflow = (props) => { const cycontainer = cy.container() // Chrome lol - //if (e.srcElement !== undefined && e.srcElement.localName === "canvas") { if (e.pageX > cycontainer.offsetLeft && e.pageX < cycontainer.offsetLeft+cycontainer.offsetWidth && e.pageY > cycontainer.offsetTop && e.pageY < cycontainer.offsetTop+cycontainer.offsetHeight) { if (newNodeId.length > 0) { var currentnode = cy.getElementById(newNodeId) @@ -4542,8 +3923,6 @@ const AngularWorkflow = (props) => { group: "nodes", data: newAppData, renderedPosition: { - //x: e.layerX, - //y: e.layerY, x: e.pageX-cycontainer.offsetLeft, y: e.pageY-cycontainer.offsetTop, } @@ -4572,7 +3951,6 @@ const AngularWorkflow = (props) => { } newAppname = newAppname.replaceAll("_", " ") - //const image = "url("+app.large_image+")" const image = app.large_image const newAppStyle = JSON.parse(JSON.stringify(paperAppStyle)) const pixelSize = !hover ? "2px" : "4px" @@ -4638,8 +4016,6 @@ const AngularWorkflow = (props) => { }) } - //setFilteredApps(responseJson.filter(app => !internalIds.includes(app.name) && !(!app.activated && app.generated))) - //console.log("FOUND: ", newApps) setVisibleApps(newApps) } else { setVisibleApps(prioritizedApps.concat(filteredApps.filter(innerapp => !internalIds.includes(innerapp.id)))) @@ -4715,7 +4091,6 @@ const AngularWorkflow = (props) => { const getNextActionName = (appName) => { var highest = "" - //label = name + _number const allitems = workflow.actions.concat(workflow.triggers) for (var key in allitems) { const item = allitems[key] @@ -4760,8 +4135,6 @@ const AngularWorkflow = (props) => { if (newSelectedAction.fillGradient !== undefined && newSelectedAction.fillGradient !== null && newSelectedAction.fillGradient.length > 0) { newSelectedAction.fillstyle = 'linear-gradient' console.log("GRADIENT!: ", newSelectedAction) - //action.fillstyle = - //'background-fill': 'data(fillstyle)', } else { newSelectedAction.iconBackground = iconInfo.iconBackgroundColor } @@ -4818,7 +4191,6 @@ const AngularWorkflow = (props) => { // ACTION select // const selectedNameChange = (event) => { - //console.log("OLDNAME: ", selectedAction.name) event.target.value = event.target.value.replaceAll("(", "") event.target.value = event.target.value.replaceAll(")", "") event.target.value = event.target.value.replaceAll("]", "") @@ -4839,34 +4211,6 @@ const AngularWorkflow = (props) => { selectedAction.label = event.target.value setSelectedAction(selectedAction) - //console.log("SHOULD CHANGE NAME EVERYWHERE ITS USED TOO BASED ON OLD NAME!") - - /* - if (nodeaction.label !== curaction.label) { - console.log("BEACH!") - - var params = [] - const fixedName = "$"+curaction.label.toLowerCase().replace(" ", "_") - for (var actionkey in workflow.actions) { - if (workflow.actions[actionkey].id === curaction.id) { - continue - } - - for (var paramkey in workflow.actions[actionkey].parameters) { - const param = workflow.actions[actionkey].parameters[paramkey] - if (param.value === null || param.value === undefined || !param.value.includes("$")) { - continue - } - - const innername = param.value.toLowerCase().replace(" ", "_") - if (innername.includes(fixedName)) { - //workflow.actions[actionkey].parameters[paramkey].replace( - //console.log("FOUND!: ", innername) - } - } - } - } - */ } const selectedTriggerChange = (event) => { @@ -4893,7 +4237,6 @@ const AngularWorkflow = (props) => { } if (currentnode.data() === undefined) { - //console.log("Node doesn't have any data (getParents)! Probably a trigger.") handled.push(allkeys[key]) results.push({"id": allkeys[key], "type": "TRIGGER"}) } else { @@ -4957,21 +4300,6 @@ const AngularWorkflow = (props) => { overflow: "auto", } - // Old static one - //var rightsidebarStyle = { - // position: "fixed", - // right: 0, - // top: appBarSize+1, - // height: "100%", - // bottom: 0, - // minWidth: 350, - // maxWidth: 350, - // borderLeft: "1px solid rgb(91, 96, 100)", - // overflow: "scroll", - // overflowX: "auto", - // overflowY: "auto", - // zIndex: 1000, - //} var rightsidebarStyle = { position: "fixed", @@ -5019,35 +4347,6 @@ const AngularWorkflow = (props) => { setWorkflow(workflow) }; - //const setTriggerFolderWrapper = (event) => { - // if (selectedTrigger.parameters === null) { - // selectedTrigger.parameters = [] - // workflow.triggers[selectedTriggerIndex].parameters = [] - // } - - // const folder = triggerFolders.find(a => a.displayName === event.target.value) - // console.log(event.target.value) - // console.log(folder) - // - // if (folder !== undefined) { - // workflow.triggers[selectedTriggerIndex].parameters[0] = {"value": folder.displayName, "name": "outlookfolder", "id": folder.id} - // selectedTrigger.parameters[0] = {"value": folder.displayName, "name": "outlookfolder", "id": folder.id} - // setWorkflow(workflow) - - // // This resets state for some reason (: - // setSelectedActionEnvironment({}) - // setSelectedAction({}) - // setSelectedTrigger({}) - // setSelectedApp({}) - // setSelectedEdge({}) - - // // Set value - // setSelectedTrigger(selectedTrigger) - - // } else { - // alert.error("Some error occurred with folder "+event.target.value) - // } - //} const setTriggerCronWrapper = (value) => { if (selectedTrigger.parameters === null) { @@ -5125,11 +4424,9 @@ const AngularWorkflow = (props) => { // Set actions based on NEXT node, since it should be able to involve those two - //console.log("IN APPACTIONARG: ", selectedEdge) if (actionlist.length === 0) { // FIXME: Have previous execution values in here actionlist.push({"type": "Execution Argument", "name": "Execution Argument", "value": "$exec", "highlight": "exec", "autocomplete": "exec", "example": "hello"}) - //actionlist.push({"type": "Key:Value store", "name": "Shuffle KV store", "value": "$shuffle_cache", "highlight": "shuffle_cache", "autocomplete": "shuffle_cache", "example": ""}) if (workflow.workflow_variables !== null && workflow.workflow_variables !== undefined && workflow.workflow_variables.length > 0) { for (var key in workflow.workflow_variables) { @@ -5147,7 +4444,6 @@ const AngularWorkflow = (props) => { } const destAction = cy.getElementById(selectedEdge.target) - //console.log(destAction.data()) var parents = getParents(destAction.data()) if (parents.length > 1) { for (var key in parents) { @@ -5165,9 +4461,6 @@ const AngularWorkflow = (props) => { setActionlist(actionlist) } - var staticcolor = "inherit" - var actioncolor = "inherit" - var varcolor = "inherit" if (data.multiline !== undefined && data.multiline !== null && data.multiline === true) { setMultiline(true) } @@ -5201,9 +4494,7 @@ const AngularWorkflow = (props) => { : null } - onClick={() => { - //console.log("CHANGE FIELD") - }} + onBlur={(e) => { changeActionVariable(data.action_field, e.target.value) setUpdate(Math.random()) @@ -5215,51 +4506,11 @@ const AngularWorkflow = (props) => { data.value = value data.action_field = variable - //setConditionValue({}) if (type === "source") { setSourceValue(data) - //setDestinationValue(destinationValue) } else if (type === "destination") { setDestinationValue(data) - //setSourceValue(sourceValue) - } - } - - const changeActionParameterVariant = (variant) => { - if (data.variant === variant) { - return - } - - data.variant = variant - data.value = "" - - if (variant === "ACTION_RESULT") { - console.log("SHOULD FIND PARENTS OF EDGE") - - // Uses the target's parents, as the target should be executing the checks (I think) - var parents = getParents(workflow.actions.find(a => a.id === selectedEdge["target"])) - if (parents.length > 0) { - data.action_field = parents[0].label - } else { - data.action_field = "" - } - } else if (variant === "WORKFLOW_VARIABLE") { - if (workflow.workflow_variables !== null && workflow.workflow_variables !== undefined && workflow.workflow_variables.length > 0) { - data.action_field = workflow.workflow_variables[0].name - } - } - - setSourceValue({}) - setConditionValue({}) - setDestinationValue({}) - - if (type === "source") { - setSourceValue(data) - setDestinationValue(destinationValue) - } else if (type === "destination") { - setDestinationValue(data) - setSourceValue(sourceValue) } } @@ -5285,9 +4536,6 @@ const AngularWorkflow = (props) => { onClose={() => { setShowAutocomplete(false) - //if (!selectedActionParameters[count].value[selectedActionParameters[count].value.length-1] === "$") { - // setShowDropdown(false) - //} setUpdate(Math.random()) }} @@ -5300,7 +4548,6 @@ const AngularWorkflow = (props) => { onChange={(e) => { const autocomplete = e.target.value.autocomplete const newValue = autocomplete.startsWith("$") ? data.value+autocomplete : `${data.value}$${autocomplete}` - changeActionVariable(data.action_field, newValue) }} > @@ -5796,9 +5043,7 @@ const AngularWorkflow = (props) => { setLocalFirstrequest(false) } - const handleButtonRequest = () => { - } const gmailButton = selectedTrigger.name !== "Gmail" ? null : @@ -5885,7 +5128,6 @@ const AngularWorkflow = (props) => { //const client_id = "fd55c175-aa30-4fa6-b303-09a29fb3f750" const client_id = "bb4bff85-0d0b-4f5d-8a69-3cee8029b11a" - //isCloud ? userdata.username : const username = userdata.id console.log(redirectUri) console.log("USER: ", username, userdata) @@ -5896,7 +5138,6 @@ const AngularWorkflow = (props) => { return } - //console.log("SELECTED: ", selectedTrigger. console.log("BRANCH: ", branch) const startnode = branch.destination_id @@ -5984,7 +5225,6 @@ const AngularWorkflow = (props) => { } }} onChange={(e) => { - //setTriggerFolderWrapper(e) setTriggerFolderWrapperMulti(e) }} fullWidth @@ -5992,8 +5232,6 @@ const AngularWorkflow = (props) => { key={selectedTrigger} > {triggerFolders.map(folder => { - //console.log("FOLDER: ", folder) - //var folderItem =