Added icons and better execution view

This commit is contained in:
frikky
2020-05-13 15:35:03 +02:00
parent 1abc8a7b54
commit e3dca4c17e
6 changed files with 130 additions and 62 deletions
+2 -2
View File
@@ -84,13 +84,13 @@ There will be a major overhaul to the backend specifically. I'm currently moving
- * Configuration - Write setup documentation - Did for docker
- * Remove orborus? Can deploy straight, but that would be weird - Won't do this yet
- * Full OpenAPI support with authentication schemes in App creator (not Oauth2 yet)
- * Change workflow name
- Workflows - IMPORT DEFAULT WORKFLOWS - Create some towards e.g. TheHive & MISP.
- Documentation - General documentation /docs rewrite
- API doc - 1. In Shuffle. 2. In e.g. python
- Add random secret to orborus
- Change workflow name
- Fix scheduler
- Use variables in e.g. JSON body
- Add random secret to orborus
```
# 1. export DATASTORE_EMULATOR_HOST=0.0.0.0:8000
+38 -26
View File
@@ -24,7 +24,7 @@ import FormGroup from '@material-ui/core/FormGroup';
import FormControlLabel from '@material-ui/core/FormControlLabel';
import Checkbox from '@material-ui/core/Checkbox';
import CreateIcon from '@material-ui/icons/Create';
import PlayArrowIcon from '@material-ui/icons/PlayArrow';
import AspectRatioIcon from '@material-ui/icons/AspectRatio';
import MoreVertIcon from '@material-ui/icons/MoreVert';
@@ -215,6 +215,8 @@ const AngularWorkflow = (props) => {
});
}
// Controls the colors and direction of execution results.
// Style is in defaultCytoscapeStyle.js
const handleUpdateResults = (responseJson) => {
//console.log(responseJson)
// Loop nodes and find results
@@ -243,8 +245,8 @@ const AngularWorkflow = (props) => {
currentnode.removeClass('success-highlight')
currentnode.removeClass('failure-highlight')
currentnode.removeClass('awaiting-data-highlight')
currentnode.addClass('executing-highlight')
incomingEdges.addClass('success-highlight')
currentnode.addClass('executing-highlight')
break
case "WAITING":
currentnode.removeClass('not-executing-highlight')
@@ -325,11 +327,11 @@ const AngularWorkflow = (props) => {
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')
//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')
}
}
} else if (responseJson.status === "FINISHED") {
@@ -412,7 +414,7 @@ const AngularWorkflow = (props) => {
setLastSaved(true)
fetch(globalUrl+"/api/v1/workflows/"+props.match.params.key, {
method: 'PUT',
method: 'PUT',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
@@ -1378,7 +1380,7 @@ const AngularWorkflow = (props) => {
return (
<div style={appViewStyle}>
<div style={appScrollStyle}>
<div style={variableScrollStyle}>
{workflow.workflow_variables.map(variable=> {
return (
<div>
@@ -2265,23 +2267,29 @@ const AngularWorkflow = (props) => {
<div style={{flex: "10"}}>
<b>{data.name}: </b>
</div>
<div style={{cursor: "pointer", color: staticcolor}} onClick={() => {
changeActionParameterVariant("STATIC_VALUE", count)
<Tooltip color="primary" title="Static data" placement="top">
<div style={{cursor: "pointer", color: staticcolor}} onClick={() => {
changeActionParameterVariant("STATIC_VALUE", count)
}}>
<CreateIcon />
</div>
</Tooltip>
&nbsp;|&nbsp;
<Tooltip color="primary" title="Data from previous action" placement="top">
<div style={{cursor: "pointer", color: actioncolor}} onClick={() => {
changeActionParameterVariant("ACTION_RESULT", count)
}}>
static
</div>
<AppsIcon />
</div>
</Tooltip>
&nbsp;|&nbsp;
<div style={{cursor: "pointer", color: actioncolor}} onClick={() => {
changeActionParameterVariant("ACTION_RESULT", count)
}}>
action
</div>
&nbsp;|&nbsp;
<div style={{cursor: "pointer", color: varcolor}} onClick={() => {
changeActionParameterVariant("WORKFLOW_VARIABLE", count)
}}>
var
</div>
<Tooltip color="primary" title="Use local variable" placement="top">
<div style={{cursor: "pointer", color: varcolor}} onClick={() => {
changeActionParameterVariant("WORKFLOW_VARIABLE", count)
}}>
<FavoriteBorderIcon />
</div>
</Tooltip>
</div>
{datafield}
</div>
@@ -3941,14 +3949,17 @@ const AngularWorkflow = (props) => {
return null
}
const cytoscapeViewWidths = 600
const bottomBarStyle = {
position: "fixed",
right: 20,
left: leftBarSize,
bottom: 0,
minWidth: "100%",
minWidth: cytoscapeViewWidths,
maxWidth: cytoscapeViewWidths,
marginLeft: 20,
marginBottom: 20,
zIndex: 10,
}
const topBarStyle= {
@@ -3956,7 +3967,8 @@ const AngularWorkflow = (props) => {
right: 0,
left: leftBarSize,
top: appBarSize,
minWidth: "60%",
minWidth: cytoscapeViewWidths,
maxWidth: cytoscapeViewWidths,
marginLeft: 20,
marginBottom: 20,
}
+2 -2
View File
@@ -38,12 +38,12 @@ import AlertTemplate from "react-alert-template-basic";
import { positions, Provider } from "react-alert";
// Testing - localhost
//const globalUrl = "http://192.168.3.6:5001"
const globalUrl = "http://192.168.3.6:5001"
//console.log("HOST: ", process.env)
// Production - backend proxy forwarding in nginx
const globalUrl = window.location.origin
//const globalUrl = window.location.origin
const surfaceColor = "#27292D"
const inputColor = "#383B40"
+15 -3
View File
@@ -8,6 +8,9 @@ import ListItem from '@material-ui/core/ListItem';
import Button from '@material-ui/core/Button';
import HomeIcon from '@material-ui/icons/Home';
import PolymerIcon from '@material-ui/icons/Polymer';
import AppsIcon from '@material-ui/icons/Apps';
import DescriptionIcon from '@material-ui/icons/Description';
import Grid from '@material-ui/core/Grid';
const hoverColor = "#f85a3e"
@@ -138,12 +141,18 @@ const Header = props => {
<List style={{display: "flex", flexDirect: "row", flex: "1"}} component="nav">
<ListItem style={{textAlign: "center"}}>
<Link to="/workflows" style={hrefStyle}>
<div onMouseOver={handleSoarHover} onMouseOut={handleSoarHoverOut} style={{color: SoarHoverColor, cursor: "pointer"}}>Workflows</div>
<div onMouseOver={handleSoarHover} onMouseOut={handleSoarHoverOut} style={{color: SoarHoverColor, cursor: "pointer", display: "flex"}}>
<PolymerIcon style={{marginRight: "5px"}} />
<span style={{marginTop: 2}}>Workflows</span>
</div>
</Link>
</ListItem>
<ListItem style={{textAlign: "center"}}>
<Link to="/apps" style={hrefStyle}>
<div onMouseOver={handleHelpHover} onMouseOut={handleHelpHoverOut} style={{color: HelpHoverColor, cursor: "pointer"}}>Apps</div>
<div onMouseOver={handleHelpHover} onMouseOut={handleHelpHoverOut} style={{color: HelpHoverColor, cursor: "pointer", display: "flex",}}>
<AppsIcon style={{marginRight: "5px"}} />
<span style={{marginTop: 2}}>Apps</span>
</div>
</Link>
</ListItem>
{/*
@@ -155,7 +164,10 @@ const Header = props => {
*/}
<ListItem style={{textAlign: "center"}}>
<Link to="/docs/about" style={hrefStyle}>
<div onMouseOver={handleDocsHover} onMouseOut={handleDocsHoverOut} style={{color: DocsHoverColor, cursor: "pointer"}}>Docs</div>
<div onMouseOver={handleDocsHover} onMouseOut={handleDocsHoverOut} style={{color: DocsHoverColor, cursor: "pointer", display: "flex"}}>
<DescriptionIcon style={{marginRight: "5px"}} />
<span style={{marginTop: 2}}>Docs</span>
</div>
</Link>
</ListItem>
{/*
+65 -28
View File
@@ -3,6 +3,7 @@ import { useInterval } from 'react-powerhooks';
import Grid from '@material-ui/core/Grid';
import Paper from '@material-ui/core/Paper';
import Tooltip from '@material-ui/core/Tooltip';
import Divider from '@material-ui/core/Divider';
import Button from '@material-ui/core/Button';
import TextField from '@material-ui/core/TextField';
@@ -10,10 +11,13 @@ import FormControl from '@material-ui/core/FormControl';
import IconButton from '@material-ui/core/IconButton';
import Menu from '@material-ui/core/Menu';
import MenuItem from '@material-ui/core/MenuItem';
import MoreVertIcon from '@material-ui/icons/MoreVert';
import FormControlLabel from '@material-ui/core/FormControlLabel';
import Switch from '@material-ui/core/Switch';
import CachedIcon from '@material-ui/icons/Cached';
import EditIcon from '@material-ui/icons/Edit';
import MoreVertIcon from '@material-ui/icons/MoreVert';
import PlayArrowIcon from '@material-ui/icons/PlayArrow';
//import JSONPretty from 'react-json-pretty';
//import JSONPrettyMon from 'react-json-pretty/dist/monikai'
import ReactJson from 'react-json-view'
@@ -43,8 +47,9 @@ const Workflows = (props) => {
const [collapseJson, setCollapseJson] = React.useState(false)
const [modalOpen, setModalOpen] = React.useState(false);
const [newWorkflowName, setNewWorkflowname] = React.useState("");
const [newWorkflowName, setNewWorkflowName] = React.useState("");
const [newWorkflowDescription, setNewWorkflowDescription] = React.useState("");
const [editingWorkflow, setEditingWorkflow] = React.useState({})
const { start, stop } = useInterval({
duration: 5000,
startImmediate: false,
@@ -347,21 +352,28 @@ const Workflows = (props) => {
aria-label="more"
aria-controls="long-menu"
aria-haspopup="true"
style={{color: "white"}}
onClick={menuClick}
>
<MoreVertIcon />
</IconButton>
<Menu
id="long-menu"
anchorEl={anchorEl}
keepMounted
open={open}
onClose={() => {
id="long-menu"
anchorEl={anchorEl}
keepMounted
open={open}
onClose={() => {
setOpen(false)
setAnchorEl(null)
}}
>
>
<MenuItem style={{backgroundColor: surfaceColor, color: "white"}} onClick={() => {
setModalOpen(true)
setEditingWorkflow(data)
setNewWorkflowName(data.name)
setNewWorkflowDescription(data.description)
}} key={"change"}>{"Change name"}</MenuItem>
<MenuItem style={{backgroundColor: surfaceColor, color: "white"}} onClick={() => {
copyWorkflow(data)
setOpen(false)
@@ -381,9 +393,17 @@ const Workflows = (props) => {
<div style={{display: "flex", flex: "1"}}>
<Grid item style={{flex: "1", justifyContent: "center"}}>
<a href={"/workflows/"+data.id}>
<Button style={{}} color="primary" variant="outlined" onClick={() => {}}>Edit</Button>
<Tooltip color="primary" title="Edit workflow" placement="bottom">
<Button style={{}} color="primary" variant="outlined" style={{marginRight: 10}} onClick={() => {}}>
<EditIcon />
</Button>
</Tooltip>
</a>
<Button style={{}} color="primary" variant="outlined" onClick={() => executeWorkflow(data.id)}>Execute</Button>
<Tooltip color="primary" title="Execute workflow" placement="bottom">
<Button style={{}} color="primary" variant="outlined" onClick={() => executeWorkflow(data.id)}>
<PlayArrowIcon />
</Button>
</Tooltip>
</Grid>
</div>
</Grid>
@@ -504,7 +524,6 @@ const Workflows = (props) => {
*/
}
console.log(data)
return (
<Paper square style={resultPaperAppStyle} onClick={() => {}}>
<div style={{marginLeft: "10px", marginTop: "5px", marginBottom: "5px", marginRight: "5px", width: boxWidth, backgroundColor: boxColor}}>
@@ -555,7 +574,6 @@ const Workflows = (props) => {
const ExecutionDetails = () => {
var starttime = new Date(selectedExecution.started_at*1000)
var endtime = new Date(selectedExecution.started_at*1000)
console.log(selectedExecution)
const arg = selectedExecution.execution_argument !== undefined && selectedExecution.execution_argument.length > 0 ?
<div>
@@ -629,13 +647,24 @@ const Workflows = (props) => {
if (newWorkflowName.length === 0) {
return
}
var workflowdata = {
"name": newWorkflowName,
"description": newWorkflowDescription,
var method = "POST"
var extraData = ""
var workflowdata = {}
if (editingWorkflow.id !== undefined) {
method = "PUT"
extraData = "/"+editingWorkflow.id
workflowdata = editingWorkflow
}
fetch(globalUrl+"/api/v1/workflows", {
method: 'POST',
workflowdata["name"] = newWorkflowName
workflowdata["description"] = newWorkflowDescription
//console.log(workflowdata)
//return
fetch(globalUrl+"/api/v1/workflows"+extraData, {
method: method,
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
@@ -650,9 +679,13 @@ const Workflows = (props) => {
}
return response.json()
})
.then((responseJson) => {
window.location.pathname = "/workflows/"+responseJson["id"]
})
.then((responseJson) => {
if (method === "POST") {
window.location.pathname = "/workflows/"+responseJson["id"]
} else {
alert.info("Successfully changed basic info for workflow")
}
})
.catch(error => {
alert.error(error.toString())
});
@@ -674,7 +707,7 @@ const Workflows = (props) => {
<DialogTitle><div style={{color: "white"}}>New workflow</div></DialogTitle>
<DialogContent>
<TextField
onBlur={(event) => setNewWorkflowname(event.target.value)}
onBlur={(event) => setNewWorkflowName(event.target.value)}
InputProps={{
style:{
color: "white",
@@ -683,6 +716,7 @@ const Workflows = (props) => {
color="primary"
placeholder="Name"
margin="dense"
defaultValue={newWorkflowName}
fullWidth
/>
<TextField
@@ -693,6 +727,7 @@ const Workflows = (props) => {
},
}}
color="primary"
defaultValue={newWorkflowDescription}
placeholder="Description"
margin="dense"
fullWidth
@@ -700,15 +735,15 @@ const Workflows = (props) => {
</DialogContent>
<DialogActions>
<Button style={{}} onClick={() => setModalOpen(false)} color="primary">
Cancel
</Button>
<Button style={{}} disabled={newWorkflowName.length === 0} onClick={() => {
<Button style={{}} onClick={() => setModalOpen(false)} color="primary">
Cancel
</Button>
<Button style={{}} disabled={newWorkflowName.length === 0} onClick={() => {
setNewWorkflow()
setModalOpen(false)
}} color="primary">
Submit
</Button>
Submit
</Button>
</DialogActions>
</FormControl>
</Dialog>
@@ -763,7 +798,9 @@ const Workflows = (props) => {
<h2>Executions</h2>
</div>
<div style={{flex: "1"}}>
<Button color="primary" style={{marginTop: "20px"}} variant="outlined" onClick={() => {alert.info("Refreshing executions"); getWorkflowExecution(selectedWorkflow.id)}}>Refresh</Button>
<Button color="primary" style={{marginTop: "20px"}} variant="outlined" onClick={() => {alert.info("Refreshing executions"); getWorkflowExecution(selectedWorkflow.id)}}>
<CachedIcon />
</Button>
</div>
</div>
<Divider style={{marginBottom: "10px", height: "1px", width: "100%", backgroundColor: dividerColor}}/>
+8 -1
View File
@@ -115,6 +115,8 @@ const data = [{
selector: '.success-highlight',
css: {
'background-color': '#399645',
'border-color': '#399645',
'border-width': '5px',
'transition-property': 'background-color',
'transition-duration': '0.5s',
},
@@ -123,6 +125,8 @@ const data = [{
selector: '.failure-highlight',
css: {
'background-color': '#8e3530',
'border-color': '#8e3530',
'border-width': '5px',
'transition-property': 'background-color',
'transition-duration': '0.5s',
},
@@ -141,7 +145,8 @@ const data = [{
css: {
'background-color': '#ffef47',
'border-color': '#ffef47',
'transition-property': '#ffef47',
'border-width': '5px',
'transition-property': 'border-width',
'transition-duration': '0.25s',
},
},
@@ -149,6 +154,8 @@ const data = [{
selector: '.awaiting-data-highlight',
css: {
'background-color': '#f4ad42',
'border-color': '#f4ad42',
'border-width': '5px',
'transition-property': 'background-color',
'transition-duration': '0.5s',
},