diff --git a/frontend/src/views/Workflows.jsx b/frontend/src/views/Workflows.jsx index 5805dd78..0280c52e 100644 --- a/frontend/src/views/Workflows.jsx +++ b/frontend/src/views/Workflows.jsx @@ -1,15 +1,14 @@ import React, { useEffect} from 'react'; -import { useInterval } from 'react-powerhooks'; import { makeStyles } from '@material-ui/core/styles'; import { useTheme } from '@material-ui/core/styles'; -import {Avatar, Grid, Paper, Tooltip, Divider, Button, TextField, FormControl, IconButton, Menu, MenuItem, FormControlLabel, Chip, Switch, Typography, Zoom, CircularProgress, Dialog, DialogTitle, DialogActions, DialogContent} from '@material-ui/core'; -import {GridOn as GridOnIcon, List as ListIcon, Close as CloseIcon, Compare as CompareIcon, Maximize as MaximizeIcon, Minimize as MinimizeIcon, AddCircle as AddCircleIcon, Toc as TocIcon, Send as SendIcon, Search as SearchIcon, FileCopy as FileCopyIcon, Delete as DeleteIcon, BubbleChart as BubbleChartIcon, Restore as RestoreIcon, Cached as CachedIcon, GetApp as GetAppIcon, Apps as AppsIcon, Edit as EditIcon, MoreVert as MoreVertIcon, PlayArrow as PlayArrowIcon, Add as AddIcon, Publish as PublishIcon, CloudUpload as CloudUploadIcon, CloudDownload as CloudDownloadIcon} from '@material-ui/icons'; +import { Grid, Paper, Tooltip, Button, TextField, FormControl, IconButton, Menu, MenuItem, Chip, Typography, CircularProgress, Dialog, DialogTitle, DialogActions, DialogContent} from '@material-ui/core'; +import {GridOn as GridOnIcon, List as ListIcon, Close as CloseIcon, Compare as CompareIcon, Maximize as MaximizeIcon, Minimize as MinimizeIcon, AddCircle as AddCircleIcon, Toc as TocIcon, Send as SendIcon, Search as SearchIcon, FileCopy as FileCopyIcon, Delete as DeleteIcon, BubbleChart as BubbleChartIcon, Restore as RestoreIcon, Cached as CachedIcon, GetApp as GetAppIcon, Edit as EditIcon, MoreVert as MoreVertIcon, PlayArrow as PlayArrowIcon, Add as AddIcon, Publish as PublishIcon, CloudUpload as CloudUploadIcon, CloudDownload as CloudDownloadIcon} from '@material-ui/icons'; import NestedMenuItem from "material-ui-nested-menu-item"; //import {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'; //https://next.material-ui.com/components/material-icons/ -import {DataGrid, GridToolbarContainer, GridDensitySelector, GridToolbar} from '@material-ui/data-grid'; +import {DataGrid, GridToolbar} from '@material-ui/data-grid'; //import JSONPretty from 'react-json-pretty'; //import JSONPrettyMon from 'react-json-pretty/dist/monikai' @@ -19,33 +18,14 @@ import {Link} from 'react-router-dom'; import { useAlert } from "react-alert"; import ChipInput from 'material-ui-chip-input' import { v4 as uuidv4 } from 'uuid'; -import CytoscapeWrapper from '../components/RenderCytoscape' -//import mobileImage from '../assets/img/mobile.svg'; -//import bagImage from '../assets/img/bag.svg'; -//import bookImage from '../assets/img/book.svg'; const inputColor = "#383B40" const surfaceColor = "#27292D" const svgSize = 24 const imagesize = 22 -const flexContainerStyle = { - display: "flex", - flexDirection: "row", - justifyContent: "left", - alignContent: "space-between", -} -const flexBoxStyle = { - height: 125, - borderRadius: 4, - boxSizing: "border-box", - letterSpacing: "0.4px", - color: "#D6791E", - margin: 10, - flex: 1, -} const useStyles = makeStyles((theme) => ({ datagrid: { @@ -258,42 +238,22 @@ export const GetIconInfo = (action) => { console.log(`MISSING PATH FOR ${selectedKey} (find in scope): `, selectedItem.originalIcon.type.type) } - if (selectedItem.originalIcon === undefined || selectedItem.originalIcon === "" && (selectedItem.icon !== "" && selectedItem.icon !== undefined)) { + if ((selectedItem.originalIcon === undefined || selectedItem.originalIcon === "") && (selectedItem.icon !== "" && selectedItem.icon !== undefined)) { const svg_pin = - //const svgpin_Url = encodeURI("data:image/svg+xml;utf-8," + svg_pin) selectedItem.originalIcon = svg_pin - //parsedIcons[selectedKey].originalIcon = svg_pin - //console.log("ADDED ICON: ", svg_pin) + } return selectedItem } -//const activeWorkflowStyle = {backgroundColor: "#FFF5EE"} -//const notificationStyle = {backgroundColor: "#E5F9FF"} -//const activeWorkflowStyle = {backgroundColor: "#3d3f43"} -const availableWorkflowStyle = {backgroundColor: "#3d3f43"} -const notificationStyle = {backgroundColor: "#3d3f43"} -const activeWorkflowStyle = {backgroundColor: "#3d3f43"} -const fontSize_16 = {fontSize: "16px",} -const counterStyle = {fontSize: "36px",fontWeight:"bold"} -const blockRightStyle = {textAlign: "right",padding: "20px 20px 0px 0px",width:"100%"} const chipStyle = { - backgroundColor: "#3d3f43", height: 30, marginRight: 5, paddingLeft: 5, paddingRight: 5, height: 28, cursor: "pointer", borderColor: "#3d3f43", color: "white", + backgroundColor: "#3d3f43", marginRight: 5, paddingLeft: 5, paddingRight: 5, height: 28, cursor: "pointer", borderColor: "#3d3f43", color: "white", } -const flexContentStyle = { - display: "flex", - flexDirection: "row" -} -const iconStyle = { - width: "75px", - height: "75px", - padding: "20px" -} export const validateJson = (showResult) => { //showResult = showResult.split(" None").join(" \"None\"") @@ -302,15 +262,13 @@ export const validateJson = (showResult) => { var jsonvalid = true try { - const tmp = String(JSON.parse(showResult)) if (!showResult.includes("{") && !showResult.includes("[")) { jsonvalid = false } } catch (e) { - showResult = showResult.split("\'").join("\"") + showResult = showResult.split("'").join("\"") try { - const tmp = String(JSON.parse(showResult)) if (!showResult.includes("{") && !showResult.includes("[")) { jsonvalid = false } @@ -328,7 +286,7 @@ export const validateJson = (showResult) => { } const Workflows = (props) => { - const { globalUrl, isLoggedIn, isLoaded, removeCookie, cookies, userdata} = props; + const { globalUrl, isLoggedIn, isLoaded, userdata} = props; document.title = "Shuffle - Workflows" const theme = useTheme(); const alert = useAlert() @@ -337,19 +295,14 @@ const Workflows = (props) => { const referenceUrl = globalUrl+"/api/v1/hooks/" var upload = "" - const [file, setFile] = React.useState(""); const [workflows, setWorkflows] = React.useState([]); const [filteredWorkflows, setFilteredWorkflows] = React.useState([]); const [selectedWorkflow, setSelectedWorkflow] = React.useState({}); - const [selectedExecution, setSelectedExecution] = React.useState({}); - const [workflowExecutions, setWorkflowExecutions] = React.useState([]); const [firstrequest, setFirstrequest] = React.useState(true) const [workflowDone, setWorkflowDone] = React.useState(false) - const [, setTrackingId] = React.useState("") const [selectedWorkflowId, setSelectedWorkflowId] = React.useState("") - const [collapseJson, setCollapseJson] = React.useState(false) const [field1, setField1] = React.useState("") const [field2, setField2] = React.useState("") const [downloadUrl, setDownloadUrl] = React.useState("https://github.com/frikky/shuffle-workflows") @@ -363,14 +316,11 @@ const Workflows = (props) => { const [newWorkflowDescription, setNewWorkflowDescription] = React.useState(""); const [newWorkflowTags, setNewWorkflowTags] = React.useState([]); - const [showExtraOptions, setShowExtraOptions] = React.useState(true); const [defaultReturnValue, setDefaultReturnValue] = React.useState(""); - const [update, setUpdate] = React.useState("test"); const [deleteModalOpen, setDeleteModalOpen] = React.useState(false); const [publishModalOpen, setPublishModalOpen] = React.useState(false); const [editingWorkflow, setEditingWorkflow] = React.useState({}) - const [executionLoading, setExecutionLoading] = React.useState(false) const [importLoading, setImportLoading] = React.useState(false) const [isDropzone, setIsDropzone] = React.useState(false); const [view, setView] = React.useState("grid") @@ -420,8 +370,6 @@ const Workflows = (props) => { }) } - //console.log("FOUND: ", found) - //if (found) { if (found.every(v => v === true)) { newWorkflows.push(curWorkflow) continue @@ -461,9 +409,7 @@ const Workflows = (props) => { } - //console.log("Removing filter index", index) newfilters.splice(index, 1) - //console.log("FILTER LENGTH: ", filters.length) if (newfilters.length === 0) { newfilters = [] @@ -471,7 +417,6 @@ const Workflows = (props) => { } else { setFilters(newfilters) } - //console.log("FILTERS: ", newfilters) findWorkflow(newfilters) } @@ -623,14 +568,14 @@ const Workflows = (props) => { } // Initialize the workflow itself - const ret = setNewWorkflow(data.name, data.description, data.tags, data.default_return_value, {}, false) + setNewWorkflow(data.name, data.description, data.tags, data.default_return_value, {}, false) .then((response) => { if (response !== undefined) { // SET THE FULL THING data.id = response.id // Actually create it - const ret = setNewWorkflow(data.name, data.description, data.tags, data.default_return_value, data, false) + setNewWorkflow(data.name, data.description, data.tags, data.default_return_value, data, false) .then((response) => { if (response !== undefined) { alert.success(`Successfully imported ${data.name}`) @@ -651,10 +596,10 @@ const Workflows = (props) => { useEffect(() => { if (isDropzone) { - //redirectOpenApi(); setIsDropzone(false); } }, [isDropzone]); + const getAvailableWorkflows = () => { fetch(globalUrl+"/api/v1/workflows", { @@ -681,9 +626,6 @@ const Workflows = (props) => { return response.json() }) .then((responseJson) => { - setSelectedExecution({}) - setWorkflowExecutions([]) - //console.log(responseJson) if (responseJson !== undefined) { setWorkflows(responseJson) @@ -697,16 +639,14 @@ const Workflows = (props) => { return } - if (responseJson.length > 0){ - //setSelectedWorkflow(responseJson[0]) - //getWorkflowExecution(responseJson[0].id) - } + }) .catch(error => { alert.error(error.toString()) }); } + // eslint-disable-next-line react-hooks/exhaustive-deps useEffect(() => { if (workflows.length <= 0 && firstrequest) { const tmpView = localStorage.getItem('view'); @@ -717,7 +657,7 @@ const Workflows = (props) => { setFirstrequest(false) getAvailableWorkflows() } - }) + }) const viewStyle = { color: "#ffffff", @@ -726,7 +666,6 @@ const Workflows = (props) => { minWidth: 1024, maxWidth: 1024, margin: "auto", - /*maxHeight: "90vh",*/ } const emptyWorkflowStyle = { @@ -746,14 +685,6 @@ const Workflows = (props) => { } - const scrollStyle = { - marginTop: "10px", - overflow: "scroll", - height: "90%", - overflowX: "hidden", - overflowY: "auto", - } - const paperAppContainer = { display: "flex", flexWrap: 'wrap', @@ -789,38 +720,6 @@ const Workflows = (props) => { justifyContent: "space-between", } - const executeWorkflow = (id) => { - alert.show("Executing workflow "+id) - setTrackingId(id) - fetch(globalUrl+"/api/v1/workflows/"+id+"/execute", { - method: 'GET', - headers: { - 'Content-Type': 'application/json', - 'Accept': 'application/json', - }, - credentials: "include", - }) - .then((response) => { - if (response.status !== 200) { - console.log("Status not 200 for WORKFLOW EXECUTION :O!") - } - - return response.json() - }) - .then((responseJson) => { - if (!responseJson.success) { - alert.error(responseJson.reason) - } - }) - .catch(error => { - alert.error(error.toString()) - }); - } - - function sleep (time) { - return new Promise((resolve) => setTimeout(resolve, time)); - } - const exportAllWorkflows = () => { for (var key in workflows) { exportWorkflow(workflows[key], false) @@ -837,13 +736,12 @@ const Workflows = (props) => { } } - if (trigger.status == "running") { + if (trigger.status === "running") { trigger.status = "stopped" } const newId = uuidv4() if (trigger.trigger_type === "WEBHOOK") { - const hookname = "webhook_"+newId if (trigger.parameters !== undefined && trigger.parameters !== null && trigger.parameters.length === 2) { trigger.parameters[0].value = referenceUrl+"webhook_"+trigger.id trigger.parameters[1].value = "webhook_"+trigger.id @@ -873,7 +771,7 @@ const Workflows = (props) => { } if (data.actions !== null && data.actions !== undefined) { - for (var key in data.actions) { + for (key in data.actions) { data.actions[key].authentication_id = "" for (var subkey in data.actions[key].parameters) { @@ -890,7 +788,7 @@ const Workflows = (props) => { } const newId = uuidv4() - for (var branchkey in data.branches) { + for ( branchkey in data.branches) { const branch = data.branches[branchkey] if (branch.source_id === data.actions[key].id) { branch.source_id = newId @@ -905,14 +803,13 @@ const Workflows = (props) => { data.start = newId } - //data.actions[key].environment = isCloud ? "cloud" : "Shuffle" data.actions[key].environment = "" data.actions[key].id = newId } } if (data.workflow_variables !== null && data.workflow_variables !== undefined) { - for (var key in data.workflow_variables) { + for (key in data.workflow_variables) { const param = data.workflow_variables[key] if (param.name.includes("key") || param.name.includes("user") || param.name.includes("pass") || param.name.includes("api") || param.name.includes("auth") || param.name.includes("secret") || param.name.includes("email")) { param.value = "" @@ -949,7 +846,6 @@ const Workflows = (props) => { if (sanitize === true) { data = sanitizeWorkflow(data) } - //return // Add correct ID's for triggers // Add mag @@ -1008,8 +904,7 @@ const Workflows = (props) => { data.id = "" data.name = data.name+"_copy" data = deduplicateIds(data) - //console.log("COPIED DATA: ", data) - //return + fetch(globalUrl+"/api/v1/workflows", { method: 'POST', @@ -1027,7 +922,7 @@ const Workflows = (props) => { } return response.json() }) - .then((responseJson) => { + .then(() => { setTimeout(() => { getAvailableWorkflows() }, 1000) @@ -1057,7 +952,7 @@ const Workflows = (props) => { return response.json() }) - .then((responseJson) => { + .then(() => { setTimeout(() => { getAvailableWorkflows() }, 1000) @@ -1073,7 +968,7 @@ const Workflows = (props) => { } - const NewWorkflowPaper = (props) => { + const NewWorkflowPaper = () => { const [hover, setHover] = React.useState(false) const innerColor = "rgba(255,255,255,0.3)" @@ -1109,10 +1004,7 @@ const Workflows = (props) => { const [open, setOpen] = React.useState(false); const [anchorEl, setAnchorEl] = React.useState(null); - var boxWidth = "2px" - if (selectedWorkflow.id === data.id) { - boxWidth = "4px" - } + var boxColor = "#FECC00" if (data.is_valid) { @@ -1134,8 +1026,7 @@ const Workflows = (props) => { } const actions = data.actions !== null ? data.actions.length : 0 - const [triggers, schedules, webhooks, subflows] = getWorkflowMeta(data) - + const [triggers, subflows] = getWorkflowMeta(data) const workflowMenuButtons =