Feature: added popuut result
This commit is contained in:
@@ -19,6 +19,7 @@ import Select from '@material-ui/core/Select';
|
|||||||
import MenuItem from '@material-ui/core/MenuItem';
|
import MenuItem from '@material-ui/core/MenuItem';
|
||||||
import Divider from '@material-ui/core/Divider';
|
import Divider from '@material-ui/core/Divider';
|
||||||
import Dialog from '@material-ui/core/Dialog';
|
import Dialog from '@material-ui/core/Dialog';
|
||||||
|
import Modal from '@material-ui/core/Modal';
|
||||||
import DialogActions from '@material-ui/core/DialogActions';
|
import DialogActions from '@material-ui/core/DialogActions';
|
||||||
import DialogTitle from '@material-ui/core/DialogTitle';
|
import DialogTitle from '@material-ui/core/DialogTitle';
|
||||||
import InputLabel from '@material-ui/core/InputLabel';
|
import InputLabel from '@material-ui/core/InputLabel';
|
||||||
@@ -37,8 +38,11 @@ import Switch from '@material-ui/core/Switch';
|
|||||||
import ReactJson from 'react-json-view'
|
import ReactJson from 'react-json-view'
|
||||||
import { useBeforeunload } from 'react-beforeunload';
|
import { useBeforeunload } from 'react-beforeunload';
|
||||||
import NestedMenuItem from "material-ui-nested-menu-item";
|
import NestedMenuItem from "material-ui-nested-menu-item";
|
||||||
|
import Fade from '@material-ui/core/Fade';
|
||||||
|
|
||||||
import ArrowUpwardIcon from '@material-ui/icons/ArrowUpward';
|
import ArrowUpwardIcon from '@material-ui/icons/ArrowUpward';
|
||||||
|
import CloseIcon from '@material-ui/icons/Close';
|
||||||
|
import ArrowLeftIcon from '@material-ui/icons/ArrowLeft';
|
||||||
import CachedIcon from '@material-ui/icons/Cached';
|
import CachedIcon from '@material-ui/icons/Cached';
|
||||||
import AddIcon from '@material-ui/icons/Add';
|
import AddIcon from '@material-ui/icons/Add';
|
||||||
import DirectionsRunIcon from '@material-ui/icons/DirectionsRun';
|
import DirectionsRunIcon from '@material-ui/icons/DirectionsRun';
|
||||||
@@ -75,6 +79,7 @@ import cxtmenu from 'cytoscape-cxtmenu';
|
|||||||
|
|
||||||
import { w3cwebsocket as W3CWebSocket } from "websocket";
|
import { w3cwebsocket as W3CWebSocket } from "websocket";
|
||||||
import { useAlert } from "react-alert";
|
import { useAlert } from "react-alert";
|
||||||
|
import { validateJson } from "./Workflows";
|
||||||
import { GetParsedPaths } from "./Apps";
|
import { GetParsedPaths } from "./Apps";
|
||||||
|
|
||||||
const surfaceColor = "#27292D"
|
const surfaceColor = "#27292D"
|
||||||
@@ -112,6 +117,7 @@ const AngularWorkflow = (props) => {
|
|||||||
|
|
||||||
const [bodyWidth, bodyHeight] = useWindowSize();
|
const [bodyWidth, bodyHeight] = useWindowSize();
|
||||||
const appBarSize = 74
|
const appBarSize = 74
|
||||||
|
var to_be_copied = ""
|
||||||
const [cystyle, ] = useState(cytoscapestyle)
|
const [cystyle, ] = useState(cytoscapestyle)
|
||||||
const [cy, setCy] = React.useState()
|
const [cy, setCy] = React.useState()
|
||||||
|
|
||||||
@@ -141,6 +147,9 @@ const AngularWorkflow = (props) => {
|
|||||||
const [rightSideBarOpen, setRightSideBarOpen] = React.useState(false)
|
const [rightSideBarOpen, setRightSideBarOpen] = React.useState(false)
|
||||||
const [showSkippedActions, setShowSkippedActions] = React.useState(false)
|
const [showSkippedActions, setShowSkippedActions] = React.useState(false)
|
||||||
|
|
||||||
|
const [selectedResult, setSelectedResult] = React.useState({})
|
||||||
|
const [codeModalOpen, setCodeModalOpen] = React.useState(false);
|
||||||
|
|
||||||
const [variableAnchorEl, setVariableAnchorEl] = React.useState(null)
|
const [variableAnchorEl, setVariableAnchorEl] = React.useState(null)
|
||||||
|
|
||||||
const [sourceValue, setSourceValue] = React.useState({})
|
const [sourceValue, setSourceValue] = React.useState({})
|
||||||
@@ -5957,11 +5966,10 @@ const AngularWorkflow = (props) => {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const HandleJsonCopy = (base, copy, base_node_name) => {
|
const HandleJsonCopy = (base, copy, base_node_name) => {
|
||||||
console.log("COPY: ", copy)
|
console.log("COPY: ", copy)
|
||||||
var newitem = JSON.parse(base)
|
var newitem = JSON.parse(base)
|
||||||
var to_be_copied = "$"+base_node_name
|
to_be_copied = "$"+base_node_name
|
||||||
for (var key in copy.namespace) {
|
for (var key in copy.namespace) {
|
||||||
if (copy.namespace[key].includes("Results for")) {
|
if (copy.namespace[key].includes("Results for")) {
|
||||||
continue
|
continue
|
||||||
@@ -5986,16 +5994,18 @@ const AngularWorkflow = (props) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(to_be_copied)
|
to_be_copied.replace(" ", "_")
|
||||||
//var copyText = document.getElementById("copy_element_shuffle");
|
var copyText = document.getElementById("copy_element_shuffle");
|
||||||
//if (copyText !== null) {
|
if (copyText !== null) {
|
||||||
//navigator.clipboard.writeText(to_be_copied)
|
navigator.clipboard.writeText(to_be_copied)
|
||||||
//copyText.select();
|
copyText.select();
|
||||||
//copyText.setSelectionRange(0, 99999); /* For mobile devices */
|
copyText.setSelectionRange(0, 99999); /* For mobile devices */
|
||||||
|
|
||||||
///* Copy the text inside the text field */
|
/* Copy the text inside the text field */
|
||||||
//document.execCommand("copy");
|
document.execCommand("copy");
|
||||||
//}
|
}
|
||||||
|
|
||||||
|
alert.success("Copied "+to_be_copied)
|
||||||
}
|
}
|
||||||
|
|
||||||
const executionModal =
|
const executionModal =
|
||||||
@@ -6124,6 +6134,7 @@ const AngularWorkflow = (props) => {
|
|||||||
if (executionData.results.length !== 1 && !showSkippedActions && (data.status === "SKIPPED" || data.status === "FAILURE")) {
|
if (executionData.results.length !== 1 && !showSkippedActions && (data.status === "SKIPPED" || data.status === "FAILURE")) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
console.log(data)
|
||||||
|
|
||||||
|
|
||||||
// showResult = replaceAll(showResult, " None", " \"None\"")
|
// showResult = replaceAll(showResult, " None", " \"None\"")
|
||||||
@@ -6165,6 +6176,14 @@ const AngularWorkflow = (props) => {
|
|||||||
return (
|
return (
|
||||||
<div key={index} style={{marginBottom: 40,}}>
|
<div key={index} style={{marginBottom: 40,}}>
|
||||||
<div style={{display: "flex", marginBottom: 15,}}>
|
<div style={{display: "flex", marginBottom: 15,}}>
|
||||||
|
<IconButton style={{marginTop: "auto", marginBottom: "auto", height: 30, width: 30}} onClick={() => {
|
||||||
|
setSelectedResult(data)
|
||||||
|
setCodeModalOpen(true)
|
||||||
|
}}>
|
||||||
|
<Tooltip color="primary" title="Expand result window" placement="top">
|
||||||
|
<ArrowLeftIcon style={{color: "white"}}/>
|
||||||
|
</Tooltip>
|
||||||
|
</IconButton>
|
||||||
{actionimg}
|
{actionimg}
|
||||||
<div>
|
<div>
|
||||||
<div style={{fontSize: 24, marginTop: "auto", marginBottom: "auto"}}><b>{data.action.label}</b></div>
|
<div style={{fontSize: 24, marginTop: "auto", marginBottom: "auto"}}><b>{data.action.label}</b></div>
|
||||||
@@ -6178,7 +6197,7 @@ const AngularWorkflow = (props) => {
|
|||||||
collapsed={true}
|
collapsed={true}
|
||||||
displayDataTypes={false}
|
displayDataTypes={false}
|
||||||
onSelect={(select) => {
|
onSelect={(select) => {
|
||||||
HandleJsonCopy(showResult, select, data.action.name)
|
HandleJsonCopy(showResult, select, data.action.label)
|
||||||
console.log("SELECTED!: ", select)
|
console.log("SELECTED!: ", select)
|
||||||
}}
|
}}
|
||||||
name={"Results for "+data.action.label}
|
name={"Results for "+data.action.label}
|
||||||
@@ -6620,6 +6639,89 @@ const AngularWorkflow = (props) => {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const CodePopoutModal = (props) => {
|
||||||
|
const {codeModalOpen, setCodeModalOpen, selectedResult} = props
|
||||||
|
if (!codeModalOpen) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
const curapp = apps.find(a => a.name === selectedResult.action.app_name && a.app_version === selectedResult.action.app_version)
|
||||||
|
const imgsize = 50
|
||||||
|
const statusColor = selectedResult.status === "FINISHED" || selectedResult.status === "SUCCESS" ? "green" : selectedResult.status === "ABORTED" || selectedResult.status === "FAILURE" ? "red" : "orange"
|
||||||
|
const validate = validateJson(selectedResult.result.trim())
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Draggable>
|
||||||
|
<Dialog
|
||||||
|
open={codeModalOpen}
|
||||||
|
transition={Fade}
|
||||||
|
hasBackdrop={false}
|
||||||
|
onClose={() => {
|
||||||
|
//setCodeModalOpen(false)
|
||||||
|
}}
|
||||||
|
PaperComponent=<Draggable />
|
||||||
|
BackdropProps={{
|
||||||
|
invisible: false,
|
||||||
|
open: false,
|
||||||
|
style: {
|
||||||
|
height: 0,
|
||||||
|
width: 0,
|
||||||
|
padding: 0,
|
||||||
|
margin: 0,
|
||||||
|
background: "none",
|
||||||
|
boxShadow: "none",
|
||||||
|
backgroundColor: "transparent",
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
PaperProps={{
|
||||||
|
style: {
|
||||||
|
backgroundColor: surfaceColor,
|
||||||
|
color: "white",
|
||||||
|
minWidth: 750,
|
||||||
|
padding: 30,
|
||||||
|
maxHeight: 700,
|
||||||
|
overflow: "auto",
|
||||||
|
//backgroundColor: "transparent",
|
||||||
|
boxShadow: "none",
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<IconButton style={{zIndex: 5000, position: "absolute", top: 34, right: 34,}} onClick={() => {
|
||||||
|
setCodeModalOpen(false)
|
||||||
|
}}>
|
||||||
|
<CloseIcon style={{color: "white"}}/>
|
||||||
|
</IconButton>
|
||||||
|
<div style={{marginBottom: 40,}}>
|
||||||
|
<div style={{display: "flex", marginBottom: 15,}}>
|
||||||
|
{curapp === null ? null : <img alt={selectedResult.app_name} src={curapp === undefined ? "" : curapp.large_image} style={{marginRight: 20, width: imgsize, height: imgsize, border: `2px solid ${statusColor}`}} />}
|
||||||
|
<div>
|
||||||
|
<div style={{fontSize: 24, marginTop: "auto", marginBottom: "auto"}}><b>{selectedResult.action.label}</b></div>
|
||||||
|
<div style={{fontSize: 14}}>{selectedResult.action.name}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div style={{marginBottom: 5}}><b>Status </b> {selectedResult.status}</div>
|
||||||
|
{validate.valid ? <ReactJson
|
||||||
|
src={validate.result}
|
||||||
|
theme="solarized"
|
||||||
|
collapsed={false}
|
||||||
|
displayDataTypes={false}
|
||||||
|
onSelect={(select) => {
|
||||||
|
HandleJsonCopy(JSON.stringify(validate.result), select, selectedResult.action.label)
|
||||||
|
}}
|
||||||
|
name={"Results for "+selectedResult.action.label}
|
||||||
|
/>
|
||||||
|
:
|
||||||
|
<div>
|
||||||
|
<b>Result</b>
|
||||||
|
{selectedResult.result}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</Dialog>
|
||||||
|
</Draggable>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// This whole part is redundant. Made it part of Arguments instead.
|
// This whole part is redundant. Made it part of Arguments instead.
|
||||||
const authenticationModal = authenticationModalOpen ?
|
const authenticationModal = authenticationModalOpen ?
|
||||||
<Dialog
|
<Dialog
|
||||||
@@ -6647,6 +6749,15 @@ const AngularWorkflow = (props) => {
|
|||||||
{executionVariableModal}
|
{executionVariableModal}
|
||||||
{conditionsModal}
|
{conditionsModal}
|
||||||
{authenticationModal}
|
{authenticationModal}
|
||||||
|
<CodePopoutModal selectedResult={selectedResult} codeModalOpen={codeModalOpen} setCodeModalOpen={setCodeModalOpen}/>
|
||||||
|
{/*
|
||||||
|
<TextField
|
||||||
|
id="copy_element_shuffle"
|
||||||
|
value={to_be_copied}
|
||||||
|
disabled={true}
|
||||||
|
style={{height: 0, width: 0, margin: 0, padding: 0,}}
|
||||||
|
/>
|
||||||
|
*/}
|
||||||
</div>
|
</div>
|
||||||
:
|
:
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -43,6 +43,37 @@ import CloudDownloadIcon from '@material-ui/icons/CloudDownload';
|
|||||||
const inputColor = "#383B40"
|
const inputColor = "#383B40"
|
||||||
const surfaceColor = "#27292D"
|
const surfaceColor = "#27292D"
|
||||||
|
|
||||||
|
export const validateJson = (showResult) => {
|
||||||
|
showResult = showResult.split(" None").join(" \"None\"")
|
||||||
|
showResult = showResult.split(" False").join(" false")
|
||||||
|
showResult = showResult.split(" True").join(" true")
|
||||||
|
|
||||||
|
var jsonvalid = true
|
||||||
|
try {
|
||||||
|
const tmp = String(JSON.parse(showResult))
|
||||||
|
if (!showResult.includes("{") && !showResult.includes("[")) {
|
||||||
|
jsonvalid = false
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
showResult = showResult.split("\'").join("\"")
|
||||||
|
|
||||||
|
try {
|
||||||
|
const tmp = String(JSON.parse(showResult))
|
||||||
|
if (!showResult.includes("{") && !showResult.includes("[")) {
|
||||||
|
jsonvalid = false
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
jsonvalid = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("VALID: ", jsonvalid)
|
||||||
|
return {
|
||||||
|
"valid": jsonvalid,
|
||||||
|
"result": jsonvalid ? JSON.parse(showResult) : showResult,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const Workflows = (props) => {
|
const Workflows = (props) => {
|
||||||
const { globalUrl, isLoggedIn, isLoaded, removeCookie, cookies, userdata} = props;
|
const { globalUrl, isLoggedIn, isLoaded, removeCookie, cookies, userdata} = props;
|
||||||
document.title = "Shuffle - Workflows"
|
document.title = "Shuffle - Workflows"
|
||||||
@@ -684,22 +715,12 @@ const Workflows = (props) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var t = new Date(data.started_at*1000)
|
var t = new Date(data.started_at*1000)
|
||||||
var jsonvalid = true
|
|
||||||
var showResult = data.result.trim()
|
var showResult = data.result.trim()
|
||||||
showResult = replaceAll(showResult, " None", " \"None\"");
|
const validate = validateJson(showResult)
|
||||||
try {
|
|
||||||
const tmp = String(JSON.parse(showResult))
|
|
||||||
if (!tmp.includes("{") && !tmp.includes("[")) {
|
|
||||||
jsonvalid = false
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
jsonvalid = false
|
|
||||||
}
|
|
||||||
|
|
||||||
//console.log("VALID: ", jsonvalid)
|
if (validate.valid) {
|
||||||
if (jsonvalid) {
|
|
||||||
showResult = <ReactJson
|
showResult = <ReactJson
|
||||||
src={JSON.parse(showResult)}
|
src={validate.result}
|
||||||
theme="solarized"
|
theme="solarized"
|
||||||
collapsed={collapseJson}
|
collapsed={collapseJson}
|
||||||
displayDataTypes={false}
|
displayDataTypes={false}
|
||||||
@@ -707,7 +728,7 @@ const Workflows = (props) => {
|
|||||||
/>
|
/>
|
||||||
} else {
|
} else {
|
||||||
// FIXME - have everything parsed as json, either just for frontend
|
// FIXME - have everything parsed as json, either just for frontend
|
||||||
// or in the backend
|
// or in the backend?
|
||||||
/*
|
/*
|
||||||
const newdata = {"result": data.result}
|
const newdata = {"result": data.result}
|
||||||
showResult = <ReactJson
|
showResult = <ReactJson
|
||||||
@@ -780,23 +801,12 @@ const Workflows = (props) => {
|
|||||||
|
|
||||||
var arg = null
|
var arg = null
|
||||||
if (selectedExecution.execution_argument !== undefined && selectedExecution.execution_argument.length > 0) {
|
if (selectedExecution.execution_argument !== undefined && selectedExecution.execution_argument.length > 0) {
|
||||||
var jsonvalid = true
|
|
||||||
|
|
||||||
var showResult = selectedExecution.execution_argument.trim()
|
var showResult = selectedExecution.execution_argument.trim()
|
||||||
showResult = replaceAll(showResult, " None", " \"None\"");
|
const validate = validateJson(showResult)
|
||||||
|
|
||||||
try {
|
arg = validate.valid ?
|
||||||
const tmp = String(JSON.parse(showResult))
|
|
||||||
if (!tmp.includes("{") && !tmp.includes("[")) {
|
|
||||||
jsonvalid = false
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
jsonvalid = false
|
|
||||||
}
|
|
||||||
|
|
||||||
arg = jsonvalid ?
|
|
||||||
<ReactJson
|
<ReactJson
|
||||||
src={JSON.parse(showResult)}
|
src={validate.result}
|
||||||
theme="solarized"
|
theme="solarized"
|
||||||
collapsed={true}
|
collapsed={true}
|
||||||
displayDataTypes={false}
|
displayDataTypes={false}
|
||||||
@@ -807,22 +817,13 @@ const Workflows = (props) => {
|
|||||||
|
|
||||||
var lastresult = null
|
var lastresult = null
|
||||||
if (selectedExecution.result !== undefined && selectedExecution.result.length > 0) {
|
if (selectedExecution.result !== undefined && selectedExecution.result.length > 0) {
|
||||||
var jsonvalid = true
|
|
||||||
var showResult = selectedExecution.result.trim()
|
var showResult = selectedExecution.result.trim()
|
||||||
showResult = replaceAll(showResult, " None", " \"None\"");
|
const validate = validateJson(showResult)
|
||||||
|
console.log("VALID: ", validate)
|
||||||
|
|
||||||
try {
|
lastresult = validate.valid ?
|
||||||
const tmp = JSON.parse(showResult)
|
|
||||||
if (!tmp.includes("{") && !tmp.includes("[")) {
|
|
||||||
jsonvalid = false
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
jsonvalid = false
|
|
||||||
}
|
|
||||||
|
|
||||||
lastresult = jsonvalid ?
|
|
||||||
<ReactJson
|
<ReactJson
|
||||||
src={JSON.parse(showResult)}
|
src={validate.result}
|
||||||
theme="solarized"
|
theme="solarized"
|
||||||
collapsed={true}
|
collapsed={true}
|
||||||
displayDataTypes={false}
|
displayDataTypes={false}
|
||||||
|
|||||||
Reference in New Issue
Block a user