Added basic frontend elements for timing actions
This commit is contained in:
@@ -10,7 +10,7 @@ go 1.15
|
|||||||
require (
|
require (
|
||||||
cloud.google.com/go/datastore v1.6.0
|
cloud.google.com/go/datastore v1.6.0
|
||||||
cloud.google.com/go/pubsub v1.17.0
|
cloud.google.com/go/pubsub v1.17.0
|
||||||
cloud.google.com/go/storage v1.18.1
|
cloud.google.com/go/storage v1.18.2
|
||||||
github.com/basgys/goxml2json v1.1.0
|
github.com/basgys/goxml2json v1.1.0
|
||||||
github.com/carlescere/scheduler v0.0.0-20170109141437-ee74d2f83d82
|
github.com/carlescere/scheduler v0.0.0-20170109141437-ee74d2f83d82
|
||||||
github.com/docker/docker v20.10.9+incompatible
|
github.com/docker/docker v20.10.9+incompatible
|
||||||
@@ -22,7 +22,7 @@ require (
|
|||||||
github.com/gorilla/mux v1.8.0
|
github.com/gorilla/mux v1.8.0
|
||||||
github.com/h2non/filetype v1.1.1
|
github.com/h2non/filetype v1.1.1
|
||||||
github.com/satori/go.uuid v1.2.0
|
github.com/satori/go.uuid v1.2.0
|
||||||
github.com/shuffle/shuffle-shared v0.1.70
|
github.com/shuffle/shuffle-shared v0.1.72
|
||||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e // indirect
|
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e // indirect
|
||||||
go4.org v0.0.0-20201209231011-d4a079459e60 // indirect
|
go4.org v0.0.0-20201209231011-d4a079459e60 // indirect
|
||||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519
|
||||||
|
|||||||
@@ -3960,7 +3960,7 @@ func runInitEs(ctx context.Context) {
|
|||||||
|
|
||||||
for _, org := range activeOrgs {
|
for _, org := range activeOrgs {
|
||||||
if !org.CloudSync {
|
if !org.CloudSync {
|
||||||
log.Printf("[WARNING] Skipping org syncCheck for %s because sync isn't set (1).", org.Id)
|
log.Printf("[INFO] Skipping org syncCheck for %s because sync isn't set (1).", org.Id)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -419,7 +419,7 @@ func handleWorkflowQueue(resp http.ResponseWriter, request *http.Request) {
|
|||||||
resp.Write([]byte(fmt.Sprintf(`{"success": true, "reason": "success"}`)))
|
resp.Write([]byte(fmt.Sprintf(`{"success": true, "reason": "success"}`)))
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
log.Printf("[DEBUG] Handling other execution variant: %s", err)
|
log.Printf("[DEBUG] Handling other execution variant (subflow): %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var actionResult shuffle.ActionResult
|
var actionResult shuffle.ActionResult
|
||||||
@@ -1058,6 +1058,9 @@ func executeWorkflow(resp http.ResponseWriter, request *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fileId = location[4]
|
fileId = location[4]
|
||||||
|
if strings.Contains(fileId, "?") {
|
||||||
|
fileId = strings.Split(fileId, "?")[0]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(fileId) != 36 {
|
if len(fileId) != 36 {
|
||||||
@@ -1072,7 +1075,7 @@ func executeWorkflow(resp http.ResponseWriter, request *http.Request) {
|
|||||||
if err != nil && workflow.ID == "" {
|
if err != nil && workflow.ID == "" {
|
||||||
log.Printf("[WARNING] Failed getting the workflow locally (execute workflow): %s", err)
|
log.Printf("[WARNING] Failed getting the workflow locally (execute workflow): %s", err)
|
||||||
resp.WriteHeader(401)
|
resp.WriteHeader(401)
|
||||||
resp.Write([]byte(`{"success": false}`))
|
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Workflow with ID %s doesn't exist."}`, fileId)))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -16,7 +16,7 @@ services:
|
|||||||
depends_on:
|
depends_on:
|
||||||
- backend
|
- backend
|
||||||
backend:
|
backend:
|
||||||
build: ./backend
|
#build: ./backend
|
||||||
image: ghcr.io/frikky/shuffle-backend:nightly
|
image: ghcr.io/frikky/shuffle-backend:nightly
|
||||||
container_name: shuffle-backend
|
container_name: shuffle-backend
|
||||||
hostname: ${BACKEND_HOSTNAME}
|
hostname: ${BACKEND_HOSTNAME}
|
||||||
|
|||||||
@@ -161,6 +161,8 @@ const ParsedAction = (props) => {
|
|||||||
authenticationType,
|
authenticationType,
|
||||||
appAuthentication,
|
appAuthentication,
|
||||||
getAppAuthentication,
|
getAppAuthentication,
|
||||||
|
actionDelayChange,
|
||||||
|
isCloud,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
//const theme = useTheme();
|
//const theme = useTheme();
|
||||||
@@ -1015,6 +1017,26 @@ const ParsedAction = (props) => {
|
|||||||
<b>Parameters</b>
|
<b>Parameters</b>
|
||||||
</Button>
|
</Button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
{selectedAction.description !== undefined && selectedAction.description !== null && selectedAction.description.length > 0 && hiddenDescription === false ? (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
border: "1px solid rgba(255,255,255,0.6)",
|
||||||
|
borderRadius: theme.palette.borderRadius,
|
||||||
|
marginTop: 15,
|
||||||
|
marginBottom: 10,
|
||||||
|
maxHeight: 70,
|
||||||
|
overflow: "auto",
|
||||||
|
padding: 15,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Typography style={{}}>
|
||||||
|
<b>Description</b>
|
||||||
|
</Typography>
|
||||||
|
<Typography style={{}}>
|
||||||
|
{selectedAction.description}
|
||||||
|
</Typography>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
{selectedActionParameters.map((data, count) => {
|
{selectedActionParameters.map((data, count) => {
|
||||||
if (data.variant === "") {
|
if (data.variant === "") {
|
||||||
data.variant = "STATIC_VALUE";
|
data.variant = "STATIC_VALUE";
|
||||||
@@ -2282,6 +2304,7 @@ const ParsedAction = (props) => {
|
|||||||
<AutoFixHighIcon style={{ color: selectedAction.run_magic_output === undefined || selectedAction.run_magic_output === null || selectedAction.run_magic_output === false ? "white" : "#f86a3e"}} />
|
<AutoFixHighIcon style={{ color: selectedAction.run_magic_output === undefined || selectedAction.run_magic_output === null || selectedAction.run_magic_output === false ? "white" : "#f86a3e"}} />
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</IconButton>
|
</IconButton>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div style={{ display: "flex", flexDirection: "column" }}>
|
<div style={{ display: "flex", flexDirection: "column" }}>
|
||||||
@@ -2351,39 +2374,76 @@ const ParsedAction = (props) => {
|
|||||||
backgroundColor: "rgb(91, 96, 100)",
|
backgroundColor: "rgb(91, 96, 100)",
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Typography>Name</Typography>
|
<div style={{display: "flex"}}>
|
||||||
<TextField
|
<div style={{flex: 5}}>
|
||||||
style={theme.palette.textFieldStyle}
|
<Typography>Name</Typography>
|
||||||
InputProps={{
|
<TextField
|
||||||
style: theme.palette.innerTextfieldStyle,
|
style={theme.palette.textFieldStyle}
|
||||||
}}
|
InputProps={{
|
||||||
fullWidth
|
style: theme.palette.innerTextfieldStyle,
|
||||||
color="primary"
|
}}
|
||||||
placeholder={selectedAction.label}
|
fullWidth
|
||||||
defaultValue={selectedAction.label}
|
color="primary"
|
||||||
onChange={selectedNameChange}
|
placeholder={selectedAction.label}
|
||||||
onBlur={(e) => {
|
defaultValue={selectedAction.label}
|
||||||
const name = e.target.value;
|
onChange={selectedNameChange}
|
||||||
console.log("CHANGED FROM2: ", baselabel);
|
onBlur={(e) => {
|
||||||
console.log("CHANGED TO: ", name);
|
const name = e.target.value;
|
||||||
for (var key in workflow.actions) {
|
console.log("CHANGED FROM2: ", baselabel);
|
||||||
for (var subkey in workflow.actions[key].parameters) {
|
console.log("CHANGED TO: ", name);
|
||||||
const param = workflow.actions[key].parameters[subkey];
|
for (var key in workflow.actions) {
|
||||||
if (param.value.includes(baselabel)) {
|
for (var subkey in workflow.actions[key].parameters) {
|
||||||
//if (param.value.toLowerCase().includes(baselabel)) {
|
const param = workflow.actions[key].parameters[subkey];
|
||||||
console.log("FOUND: ", param);
|
if (param.value.includes(baselabel)) {
|
||||||
workflow.actions[key].parameters[subkey].value.replaceAll(
|
//if (param.value.toLowerCase().includes(baselabel)) {
|
||||||
baselabel,
|
console.log("FOUND: ", param);
|
||||||
e.target.value
|
workflow.actions[key].parameters[subkey].value.replaceAll(
|
||||||
);
|
baselabel,
|
||||||
}
|
e.target.value
|
||||||
}
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
console.log("DID REPLACE ACTUALLY WORK?? - Something is buggy.");
|
console.log("DID REPLACE ACTUALLY WORK?? - Something is buggy.");
|
||||||
setWorkflow(workflow);
|
setWorkflow(workflow);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
|
{!isCloud ? null :
|
||||||
|
<div style={{flex: 1, marginLeft: 5,}}>
|
||||||
|
<Tooltip
|
||||||
|
color="primary"
|
||||||
|
title={"Delay before action executes (in seconds)"}
|
||||||
|
placement="top"
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
<Typography>Delay</Typography>
|
||||||
|
<TextField
|
||||||
|
style={{
|
||||||
|
backgroundColor: theme.palette.inputColor,
|
||||||
|
borderRadius: theme.palette.borderRadius,
|
||||||
|
color: "white",
|
||||||
|
width: 50,
|
||||||
|
height: 50,
|
||||||
|
fontSize: "1em",
|
||||||
|
}}
|
||||||
|
InputProps={{
|
||||||
|
style: theme.palette.innerTextfieldStyle,
|
||||||
|
}}
|
||||||
|
placeholder={selectedAction.execution_delay}
|
||||||
|
defaultValue={selectedAction.execution_delay}
|
||||||
|
onChange={(event) => {
|
||||||
|
if (actionDelayChange !== undefined) {
|
||||||
|
actionDelayChange(event)
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
</Tooltip>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
{selectedApp.name !== undefined &&
|
{selectedApp.name !== undefined &&
|
||||||
@@ -2792,27 +2852,6 @@ const ParsedAction = (props) => {
|
|||||||
</Select>
|
</Select>
|
||||||
: null*/}
|
: null*/}
|
||||||
|
|
||||||
{selectedAction.description !== undefined && selectedAction.description !== null && selectedAction.description.length > 0 && hiddenDescription === false ? (
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
border: "1px solid rgba(255,255,255,0.6)",
|
|
||||||
borderRadius: theme.palette.borderRadius,
|
|
||||||
marginTop: 15,
|
|
||||||
marginBottom: 10,
|
|
||||||
maxHeight: 60,
|
|
||||||
overflow: "hidden",
|
|
||||||
padding: 15,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Typography style={{}}>
|
|
||||||
<b>Description</b>
|
|
||||||
</Typography>
|
|
||||||
<Typography style={{}}>
|
|
||||||
{selectedAction.description}
|
|
||||||
</Typography>
|
|
||||||
</div>
|
|
||||||
) : null}
|
|
||||||
|
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
marginTop: "10px",
|
marginTop: "10px",
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ import {
|
|||||||
} from "@material-ui/icons";
|
} from "@material-ui/icons";
|
||||||
|
|
||||||
import { useTheme } from '@material-ui/core/styles';
|
import { useTheme } from '@material-ui/core/styles';
|
||||||
|
import { validateJson } from "../views/Workflows.jsx";
|
||||||
|
import ReactJson from "react-json-view";
|
||||||
|
|
||||||
import CodeMirror from '@uiw/react-codemirror';
|
import CodeMirror from '@uiw/react-codemirror';
|
||||||
import 'codemirror/keymap/sublime';
|
import 'codemirror/keymap/sublime';
|
||||||
@@ -23,18 +25,9 @@ const CodeEditor = (props) => {
|
|||||||
const [localcodedata, setlocalcodedata] = React.useState(codedata === undefined || codedata === null || codedata.length === 0 ? "" : codedata);
|
const [localcodedata, setlocalcodedata] = React.useState(codedata === undefined || codedata === null || codedata.length === 0 ? "" : codedata);
|
||||||
// const {codelang, setcodelang} = props
|
// const {codelang, setcodelang} = props
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const [validation, setvalidation] = React.useState(" ");
|
const [validation, setValidation] = React.useState(false);
|
||||||
const [expOutput, setexpOutput] = React.useState(" ");
|
const [expOutput, setExpOutput] = React.useState(" ");
|
||||||
|
|
||||||
function IsJsonString(str) {
|
|
||||||
try {
|
|
||||||
var o = JSON.parse(str);
|
|
||||||
if (o && typeof o === "object") {
|
|
||||||
setvalidation("Correct!")
|
|
||||||
}
|
|
||||||
} catch (e) {setvalidation("Incorrect!");}
|
|
||||||
}
|
|
||||||
|
|
||||||
function expectedOutput(input) {
|
function expectedOutput(input) {
|
||||||
|
|
||||||
const found = input.match(/[$]{1}([a-zA-Z0-9_-]+\.?){1}([a-zA-Z0-9#_-]+\.?){0,}/g)
|
const found = input.match(/[$]{1}([a-zA-Z0-9_-]+\.?){1}([a-zA-Z0-9#_-]+\.?){0,}/g)
|
||||||
@@ -56,21 +49,15 @@ const CodeEditor = (props) => {
|
|||||||
}
|
}
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
|
|
||||||
try {
|
const tmpValidation = validateJson(input.valueOf())
|
||||||
// var x = document.getElementById("expOutput");
|
//setValidation(true)
|
||||||
// x.innerHTML = JSON.stringify(JSON.parse(input), null, 4)
|
if (tmpValidation.valid === true) {
|
||||||
setexpOutput(JSON.stringify(JSON.parse(input), null, 4))
|
setValidation(true)
|
||||||
} catch (e) {
|
setExpOutput(tmpValidation.result)
|
||||||
setexpOutput(input)
|
} else {
|
||||||
|
setExpOutput(input.valueOf())
|
||||||
|
setValidation(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// const obj = JSON.parse(input);
|
|
||||||
// setexpOutput(JSON.stringify(JSON.parse(input), null, 4))
|
|
||||||
// x.innerHTML = "<span style='font-size: 30px'>" + JSON.stringify(input, null, 4) + "</span>"
|
|
||||||
// x.appendChild(document.createTextNode(JSON.stringify(JSON.parse(input), null, 4)));
|
|
||||||
// setexpOutput(JSON.stringify(input, undefined, 4).replace('\ ', '\n'))
|
|
||||||
// setexpOutput("Hi there \n Hey there")
|
|
||||||
// Variables + Syntax highlighting + Validation
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -108,14 +95,12 @@ const CodeEditor = (props) => {
|
|||||||
}}>
|
}}>
|
||||||
<CodeMirror
|
<CodeMirror
|
||||||
value = {localcodedata}
|
value = {localcodedata}
|
||||||
height="200px"
|
height="250px"
|
||||||
style={{
|
style={{
|
||||||
}}
|
}}
|
||||||
onChange={(value) => {
|
onChange={(value) => {
|
||||||
setlocalcodedata(value.getValue())
|
setlocalcodedata(value.getValue())
|
||||||
expectedOutput(value.getValue())
|
expectedOutput(value.getValue())
|
||||||
IsJsonString(value.getValue())
|
|
||||||
// console.log(actionlist.slice(-1))
|
|
||||||
}}
|
}}
|
||||||
options={{
|
options={{
|
||||||
theme: 'gruvbox-dark',
|
theme: 'gruvbox-dark',
|
||||||
@@ -141,22 +126,47 @@ const CodeEditor = (props) => {
|
|||||||
Output
|
Output
|
||||||
</span>
|
</span>
|
||||||
</DialogTitle>
|
</DialogTitle>
|
||||||
<p
|
{validation === true ?
|
||||||
id='expOutput'
|
<ReactJson
|
||||||
style={{
|
src={expOutput}
|
||||||
whiteSpace: "pre-wrap",
|
theme={theme.palette.jsonTheme}
|
||||||
color: "#f85a3e",
|
style={{
|
||||||
fontFamily: "monospace",
|
borderRadius: 5,
|
||||||
backgroundColor: "#282828",
|
border: "1px solid rgba(255,255,255,0.7)",
|
||||||
padding: 20,
|
padding: 5,
|
||||||
marginTop: -2,
|
maxHeight: 250,
|
||||||
border: `2px solid ${theme.palette.inputColor}`,
|
minheight: 250,
|
||||||
borderRadius: theme.palette.borderRadius,
|
overflow: "auto",
|
||||||
maxHeight: 400,
|
}}
|
||||||
}}
|
collapsed={false}
|
||||||
>
|
enableClipboard={(copy) => {
|
||||||
{expOutput}
|
//handleReactJsonClipboard(copy);
|
||||||
</p>
|
}}
|
||||||
|
displayDataTypes={false}
|
||||||
|
onSelect={(select) => {
|
||||||
|
//HandleJsonCopy(validate.result, select, "exec");
|
||||||
|
}}
|
||||||
|
name={"JSON autocompletion"}
|
||||||
|
/>
|
||||||
|
:
|
||||||
|
<p
|
||||||
|
id='expOutput'
|
||||||
|
style={{
|
||||||
|
whiteSpace: "pre-wrap",
|
||||||
|
color: "#f85a3e",
|
||||||
|
fontFamily: "monospace",
|
||||||
|
backgroundColor: "#282828",
|
||||||
|
padding: 20,
|
||||||
|
marginTop: -2,
|
||||||
|
border: `2px solid ${theme.palette.inputColor}`,
|
||||||
|
borderRadius: theme.palette.borderRadius,
|
||||||
|
maxHeight: 250,
|
||||||
|
overflow: "auto",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{expOutput}
|
||||||
|
</p>
|
||||||
|
}
|
||||||
<p
|
<p
|
||||||
style={{
|
style={{
|
||||||
color: "white",
|
color: "white",
|
||||||
@@ -166,7 +176,7 @@ const CodeEditor = (props) => {
|
|||||||
marginTop: -15,
|
marginTop: -15,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
JSON Validation: {validation}
|
JSON Validation: {validation ? "Correct" : "Incorrect"}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -2173,11 +2173,9 @@ const AngularWorkflow = (defaultprops) => {
|
|||||||
// FIXME: Trust it to just work?
|
// FIXME: Trust it to just work?
|
||||||
//event.target.data()
|
//event.target.data()
|
||||||
var curaction = workflow.actions.find((a) => a.id === data.id);
|
var curaction = workflow.actions.find((a) => a.id === data.id);
|
||||||
var newapps = JSON.parse(JSON.stringify(apps))
|
|
||||||
if (!curaction || curaction === undefined) {
|
if (!curaction || curaction === undefined) {
|
||||||
console.log("NOT FOUND DATA: ", event.target.data())
|
console.log("NOT FOUND DATA: ", event.target.data())
|
||||||
if (data.id !== undefined && data.app_name !== undefined) {
|
if (data.id !== undefined && data.app_name !== undefined) {
|
||||||
//newapps.push(data)
|
|
||||||
workflow.actions.push(data)
|
workflow.actions.push(data)
|
||||||
setWorkflow(workflow)
|
setWorkflow(workflow)
|
||||||
curaction = data
|
curaction = data
|
||||||
@@ -2188,6 +2186,7 @@ const AngularWorkflow = (defaultprops) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var newapps = JSON.parse(JSON.stringify(apps))
|
||||||
const curapp = newapps.find(
|
const curapp = newapps.find(
|
||||||
(a) =>
|
(a) =>
|
||||||
a.name === curaction.app_name &&
|
a.name === curaction.app_name &&
|
||||||
@@ -5310,13 +5309,10 @@ const AngularWorkflow = (defaultprops) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const newParamIndex = newSelectedAction.parameters.findIndex(paramdata => paramdata.name === param.name)
|
const newParamIndex = newSelectedAction.parameters.findIndex(paramdata => paramdata.name === param.name)
|
||||||
console.log("INDEX: ", newParamIndex)
|
|
||||||
if (newParamIndex < 0) {
|
if (newParamIndex < 0) {
|
||||||
console.log("NOT FOUND: ", param)
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("FOUND: ", param)
|
|
||||||
newSelectedAction.parameters[newParamIndex].value = param.value
|
newSelectedAction.parameters[newParamIndex].value = param.value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5352,8 +5348,6 @@ const AngularWorkflow = (defaultprops) => {
|
|||||||
// based on previous actions'
|
// based on previous actions'
|
||||||
newSelectedAction = RunAutocompleter(newSelectedAction);
|
newSelectedAction = RunAutocompleter(newSelectedAction);
|
||||||
|
|
||||||
console.log("ACTION: ", newSelectedAction);
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
newaction.returns.example !== undefined &&
|
newaction.returns.example !== undefined &&
|
||||||
newaction.returns.example !== null &&
|
newaction.returns.example !== null &&
|
||||||
@@ -5377,7 +5371,17 @@ const AngularWorkflow = (defaultprops) => {
|
|||||||
//}
|
//}
|
||||||
//setSelectedActionEnvironment(env)
|
//setSelectedActionEnvironment(env)
|
||||||
|
|
||||||
|
|
||||||
|
console.log("ACTION: ", newSelectedAction);
|
||||||
setSelectedAction(newSelectedAction);
|
setSelectedAction(newSelectedAction);
|
||||||
|
if (workflow.actions !== undefined && workflow.actions !== null && workflow.actions.length > 0) {
|
||||||
|
const foundActionIndex = workflow.actions.findIndex(actiondata => actiondata.id === newSelectedAction.id)
|
||||||
|
console.log("Found action on index ", foundActionIndex)
|
||||||
|
if (foundActionIndex >= 0) {
|
||||||
|
workflow.actions[foundActionIndex] = newSelectedAction
|
||||||
|
setWorkflow(workflow)
|
||||||
|
}
|
||||||
|
}
|
||||||
setUpdate(Math.random());
|
setUpdate(Math.random());
|
||||||
|
|
||||||
// FIXME - should change icon-node (descriptor) as well
|
// FIXME - should change icon-node (descriptor) as well
|
||||||
@@ -5406,7 +5410,6 @@ const AngularWorkflow = (defaultprops) => {
|
|||||||
// appname & version
|
// appname & version
|
||||||
// description
|
// description
|
||||||
// ACTION select
|
// ACTION select
|
||||||
//
|
|
||||||
const selectedNameChange = (event) => {
|
const selectedNameChange = (event) => {
|
||||||
event.target.value = event.target.value.replaceAll("(", "");
|
event.target.value = event.target.value.replaceAll("(", "");
|
||||||
event.target.value = event.target.value.replaceAll(")", "");
|
event.target.value = event.target.value.replaceAll(")", "");
|
||||||
@@ -5429,6 +5432,22 @@ const AngularWorkflow = (defaultprops) => {
|
|||||||
setSelectedAction(selectedAction);
|
setSelectedAction(selectedAction);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const actionDelayChange = (event) => {
|
||||||
|
if (isNaN(event.target.value)) {
|
||||||
|
console.log("NAN: ", event.target.value)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const parsedNumber = parseInt(event.target.value)
|
||||||
|
if (parsedNumber > 86400) {
|
||||||
|
console.log("Max number is 1 day (86400)")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
selectedAction.execution_delay = parsedNumber
|
||||||
|
setSelectedAction(selectedAction)
|
||||||
|
}
|
||||||
|
|
||||||
const selectedTriggerChange = (event) => {
|
const selectedTriggerChange = (event) => {
|
||||||
selectedTrigger.label = event.target.value;
|
selectedTrigger.label = event.target.value;
|
||||||
setSelectedTrigger(selectedTrigger);
|
setSelectedTrigger(selectedTrigger);
|
||||||
@@ -7595,6 +7614,10 @@ const AngularWorkflow = (defaultprops) => {
|
|||||||
const handleSubflowStartnodeSelection = (e) => {
|
const handleSubflowStartnodeSelection = (e) => {
|
||||||
setSubworkflowStartnode(e.target.value);
|
setSubworkflowStartnode(e.target.value);
|
||||||
|
|
||||||
|
if (e.target.value === null || e.target.value === undefined) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const branchId = uuidv4();
|
const branchId = uuidv4();
|
||||||
const newbranch = {
|
const newbranch = {
|
||||||
source_id: workflow.triggers[selectedTriggerIndex].id,
|
source_id: workflow.triggers[selectedTriggerIndex].id,
|
||||||
@@ -7736,26 +7759,75 @@ const AngularWorkflow = (defaultprops) => {
|
|||||||
backgroundColor: "rgb(91, 96, 100)",
|
backgroundColor: "rgb(91, 96, 100)",
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<div>Name</div>
|
<div style={{display: "flex"}}>
|
||||||
<TextField
|
<div style={{flex: 5}}>
|
||||||
style={{
|
<Typography>Name</Typography>
|
||||||
backgroundColor: inputColor,
|
<TextField
|
||||||
borderRadius: theme.palette.borderRadius,
|
style={{
|
||||||
}}
|
backgroundColor: inputColor,
|
||||||
InputProps={{
|
borderRadius: theme.palette.borderRadius,
|
||||||
style: {
|
}}
|
||||||
color: "white",
|
InputProps={{
|
||||||
marginLeft: "5px",
|
style: {
|
||||||
maxWidth: "95%",
|
color: "white",
|
||||||
height: 50,
|
marginLeft: "5px",
|
||||||
fontSize: "1em",
|
maxWidth: "95%",
|
||||||
},
|
height: 50,
|
||||||
}}
|
fontSize: "1em",
|
||||||
fullWidth
|
},
|
||||||
color="primary"
|
}}
|
||||||
placeholder={selectedTrigger.label}
|
fullWidth
|
||||||
onChange={selectedTriggerChange}
|
color="primary"
|
||||||
/>
|
placeholder={selectedTrigger.label}
|
||||||
|
onChange={selectedTriggerChange}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{!isCloud ? null :
|
||||||
|
<div style={{flex: 1, marginLeft: 5,}}>
|
||||||
|
<Tooltip
|
||||||
|
color="primary"
|
||||||
|
title={"Delay before action executes (in seconds)"}
|
||||||
|
placement="top"
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
<Typography>Delay</Typography>
|
||||||
|
<TextField
|
||||||
|
style={{
|
||||||
|
backgroundColor: theme.palette.inputColor,
|
||||||
|
borderRadius: theme.palette.borderRadius,
|
||||||
|
color: "white",
|
||||||
|
width: 50,
|
||||||
|
height: 50,
|
||||||
|
fontSize: "1em",
|
||||||
|
}}
|
||||||
|
InputProps={{
|
||||||
|
style: theme.palette.innerTextfieldStyle,
|
||||||
|
}}
|
||||||
|
placeholder={selectedTrigger.execution_delay}
|
||||||
|
defaultValue={selectedAction.execution_delay}
|
||||||
|
onChange={(event) => {
|
||||||
|
if (isNaN(event.target.value)) {
|
||||||
|
console.log("NAN: ", event.target.value)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const parsedNumber = parseInt(event.target.value)
|
||||||
|
if (parsedNumber > 86400) {
|
||||||
|
console.log("Max number is 1 day (86400)")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
selectedTrigger.execution_delay = parseInt(event.target.value)
|
||||||
|
setSelectedTrigger(selectedTrigger)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
</Tooltip>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<FormControlLabel
|
<FormControlLabel
|
||||||
control={
|
control={
|
||||||
<Checkbox
|
<Checkbox
|
||||||
@@ -7798,18 +7870,39 @@ const AngularWorkflow = (defaultprops) => {
|
|||||||
/>
|
/>
|
||||||
<div style={{ flex: "6", marginTop: "20px" }}>
|
<div style={{ flex: "6", marginTop: "20px" }}>
|
||||||
<div>
|
<div>
|
||||||
<b>Parameters</b>
|
<div style={{display: "flex"}}>
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
marginTop: "20px",
|
marginTop: "20px",
|
||||||
marginBottom: "7px",
|
marginBottom: "7px",
|
||||||
display: "flex",
|
display: "flex",
|
||||||
}}
|
flex: 5,
|
||||||
>
|
}}
|
||||||
<div style={{ flex: "10" }}>
|
>
|
||||||
<b>Select a workflow to execute </b>
|
<div style={{ flex: "10" }}>
|
||||||
</div>
|
<b>Select a workflow to execute </b>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
{workflow.triggers[selectedTriggerIndex].parameters[0].value
|
||||||
|
.length === 0 ? null : workflow.triggers[selectedTriggerIndex]
|
||||||
|
.parameters[0].value === props.match.params.key ? null : (
|
||||||
|
<div style={{marginLeft: 5, flex: 1}}>
|
||||||
|
<a
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
href={`/workflows/${workflow.triggers[selectedTriggerIndex].parameters[0].value}`}
|
||||||
|
target="_blank"
|
||||||
|
style={{
|
||||||
|
textDecoration: "none",
|
||||||
|
color: "#f85a3e",
|
||||||
|
marginLeft: 5,
|
||||||
|
marginTop: 10,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<OpenInNewIcon />
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
{workflows === undefined ||
|
{workflows === undefined ||
|
||||||
workflows === null ||
|
workflows === null ||
|
||||||
workflows.length === 0 ? null : (
|
workflows.length === 0 ? null : (
|
||||||
@@ -7832,7 +7925,7 @@ const AngularWorkflow = (defaultprops) => {
|
|||||||
option.name === undefined ||
|
option.name === undefined ||
|
||||||
option.name === null
|
option.name === null
|
||||||
) {
|
) {
|
||||||
return "Loading";
|
return "No Workflow Selected";
|
||||||
}
|
}
|
||||||
|
|
||||||
const newname = (
|
const newname = (
|
||||||
@@ -7883,24 +7976,6 @@ const AngularWorkflow = (defaultprops) => {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{workflow.triggers[selectedTriggerIndex].parameters[0].value
|
|
||||||
.length === 0 ? null : workflow.triggers[selectedTriggerIndex]
|
|
||||||
.parameters[0].value === props.match.params.key ? null : (
|
|
||||||
<span style={{ marginTop: 5 }}>
|
|
||||||
<a
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
href={`/workflows/${workflow.triggers[selectedTriggerIndex].parameters[0].value}`}
|
|
||||||
target="_blank"
|
|
||||||
style={{
|
|
||||||
textDecoration: "none",
|
|
||||||
color: "#f85a3e",
|
|
||||||
marginLeft: 5,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Explore selected workflow
|
|
||||||
</a>
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{subworkflow === undefined ||
|
{subworkflow === undefined ||
|
||||||
subworkflow === null ||
|
subworkflow === null ||
|
||||||
@@ -8131,7 +8206,7 @@ const AngularWorkflow = (defaultprops) => {
|
|||||||
} else {
|
} else {
|
||||||
// Always update
|
// Always update
|
||||||
const newUrl = referenceUrl+"webhook_"+selectedTrigger.id
|
const newUrl = referenceUrl+"webhook_"+selectedTrigger.id
|
||||||
console.log("Validating webhook url: ", newUrl)
|
//console.log("Validating webhook url: ", newUrl)
|
||||||
if (newUrl !== workflow.triggers[selectedTriggerIndex].parameters[0].value) {
|
if (newUrl !== workflow.triggers[selectedTriggerIndex].parameters[0].value) {
|
||||||
console.log("Url is wrong - updating")
|
console.log("Url is wrong - updating")
|
||||||
workflow.triggers[selectedTriggerIndex].parameters[0].value = newUrl
|
workflow.triggers[selectedTriggerIndex].parameters[0].value = newUrl
|
||||||
@@ -8336,7 +8411,7 @@ const AngularWorkflow = (defaultprops) => {
|
|||||||
} else {
|
} else {
|
||||||
// Always update
|
// Always update
|
||||||
const newUrl = referenceUrl + "webhook_" + selectedTrigger.id;
|
const newUrl = referenceUrl + "webhook_" + selectedTrigger.id;
|
||||||
console.log("Validating webhook url: ", newUrl);
|
//console.log("Validating webhook url: ", newUrl);
|
||||||
if (
|
if (
|
||||||
newUrl !== workflow.triggers[selectedTriggerIndex].parameters[0].value
|
newUrl !== workflow.triggers[selectedTriggerIndex].parameters[0].value
|
||||||
) {
|
) {
|
||||||
@@ -10079,6 +10154,8 @@ const AngularWorkflow = (defaultprops) => {
|
|||||||
<div id="rightside_actions" style={rightsidebarStyle}>
|
<div id="rightside_actions" style={rightsidebarStyle}>
|
||||||
<ParsedAction
|
<ParsedAction
|
||||||
id="rightside_subactions"
|
id="rightside_subactions"
|
||||||
|
isCloud={isCloud}
|
||||||
|
actionDelayChange={actionDelayChange}
|
||||||
getAppAuthentication={getAppAuthentication}
|
getAppAuthentication={getAppAuthentication}
|
||||||
appAuthentication={appAuthentication}
|
appAuthentication={appAuthentication}
|
||||||
authenticationType={authenticationType}
|
authenticationType={authenticationType}
|
||||||
@@ -11275,7 +11352,7 @@ const AngularWorkflow = (defaultprops) => {
|
|||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
See sub-execution
|
<OpenInNewIcon />
|
||||||
</span>
|
</span>
|
||||||
) : (
|
) : (
|
||||||
<a
|
<a
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
NAME=shuffle-worker
|
NAME=shuffle-worker
|
||||||
VERSION=0.9.46
|
VERSION=0.9.47
|
||||||
|
|
||||||
echo "Running docker build with $NAME:$VERSION"
|
echo "Running docker build with $NAME:$VERSION"
|
||||||
#CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o worker.bin .
|
#CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o worker.bin .
|
||||||
|
|||||||
@@ -10,6 +10,6 @@ require (
|
|||||||
github.com/docker/go-connections v0.4.0 // indirect
|
github.com/docker/go-connections v0.4.0 // indirect
|
||||||
github.com/gorilla/mux v1.8.0
|
github.com/gorilla/mux v1.8.0
|
||||||
github.com/patrickmn/go-cache v2.1.0+incompatible
|
github.com/patrickmn/go-cache v2.1.0+incompatible
|
||||||
github.com/shuffle/shuffle-shared v0.1.70
|
github.com/shuffle/shuffle-shared v0.1.72
|
||||||
go4.org v0.0.0-20201209231011-d4a079459e60 // indirect
|
go4.org v0.0.0-20201209231011-d4a079459e60 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user