Improved app execution configuration

This commit is contained in:
frikky
2021-04-21 08:20:35 +02:00
parent 00323689e2
commit 2c1d5ba74e
9 changed files with 82 additions and 37 deletions
+2 -1
View File
@@ -2,7 +2,7 @@ module shuffle
go 1.13 go 1.13
//replace github.com/frikky/shuffle-shared => ../../../../git/shuffle-shared replace github.com/frikky/shuffle-shared => ../../../../git/shuffle-shared
//replace github.com/frikky/kin-openapi => ../../../../git/kin-openapi //replace github.com/frikky/kin-openapi => ../../../../git/kin-openapi
@@ -14,6 +14,7 @@ require (
github.com/Masterminds/semver v1.5.0 // indirect github.com/Masterminds/semver v1.5.0 // indirect
github.com/Microsoft/go-winio v0.4.14 // indirect github.com/Microsoft/go-winio v0.4.14 // indirect
github.com/basgys/goxml2json v1.1.0 github.com/basgys/goxml2json v1.1.0
github.com/bradfitz/slice v0.0.0-20180809154707-2b758aa73013 // indirect
github.com/carlescere/scheduler v0.0.0-20170109141437-ee74d2f83d82 github.com/carlescere/scheduler v0.0.0-20170109141437-ee74d2f83d82
github.com/docker/distribution v2.7.1+incompatible // indirect github.com/docker/distribution v2.7.1+incompatible // indirect
github.com/docker/docker v1.13.1 github.com/docker/docker v1.13.1
+2
View File
@@ -57,6 +57,8 @@ github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYU
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/basgys/goxml2json v1.1.0 h1:4ln5i4rseYfXNd86lGEB+Vi652IsIXIvggKM/BhUKVw= github.com/basgys/goxml2json v1.1.0 h1:4ln5i4rseYfXNd86lGEB+Vi652IsIXIvggKM/BhUKVw=
github.com/basgys/goxml2json v1.1.0/go.mod h1:wH7a5Np/Q4QoECFIU8zTQlZwZkrilY0itPfecMw41Dw= github.com/basgys/goxml2json v1.1.0/go.mod h1:wH7a5Np/Q4QoECFIU8zTQlZwZkrilY0itPfecMw41Dw=
github.com/bradfitz/slice v0.0.0-20180809154707-2b758aa73013 h1:/P9/RL0xgWE+ehnCUUN5h3RpG3dmoMCOONO1CCvq23Y=
github.com/bradfitz/slice v0.0.0-20180809154707-2b758aa73013/go.mod h1:pccXHIvs3TV/TUqSNyEvF99sxjX2r4FFRIyw6TZY9+w=
github.com/carlescere/scheduler v0.0.0-20170109141437-ee74d2f83d82 h1:9bAydALqAjBfPHd/eAiJBHnMZUYov8m2PkXVr+YGQeI= github.com/carlescere/scheduler v0.0.0-20170109141437-ee74d2f83d82 h1:9bAydALqAjBfPHd/eAiJBHnMZUYov8m2PkXVr+YGQeI=
github.com/carlescere/scheduler v0.0.0-20170109141437-ee74d2f83d82/go.mod h1:tyA14J0sA3Hph4dt+AfCjPrYR13+vVodshQSM7km9qw= github.com/carlescere/scheduler v0.0.0-20170109141437-ee74d2f83d82/go.mod h1:tyA14J0sA3Hph4dt+AfCjPrYR13+vVodshQSM7km9qw=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
+6 -1
View File
@@ -5208,9 +5208,14 @@ func runInit(ctx context.Context) {
} }
// Fixing workflows to have real activeorg IDs // Fixing workflows to have real activeorg IDs
//workflowQ := datastore.NewQuery("workflow")
//ret, err := dbclient.GetAll(ctx, workflowQ, &workflows)
//log.Printf("[INFO] Found %d workflows during startup", workflowCount)
//log.Printf("%#v, %s", ret, err)
var workflows []shuffle.Workflow
if len(activeOrgs) == 1 { if len(activeOrgs) == 1 {
q := datastore.NewQuery("workflow").Limit(35) q := datastore.NewQuery("workflow").Limit(35)
var workflows []shuffle.Workflow
_, err = dbclient.GetAll(ctx, q, &workflows) _, err = dbclient.GetAll(ctx, q, &workflows)
if err != nil && len(workflows) == 0 { if err != nil && len(workflows) == 0 {
log.Printf("Error getting workflows in runinit: %s", err) log.Printf("Error getting workflows in runinit: %s", err)
+3 -1
View File
@@ -1,7 +1,7 @@
version: '3' version: '3'
services: services:
frontend: frontend:
#build: ./frontend build: ./frontend
image: ghcr.io/frikky/shuffle-frontend:0.8.74 image: ghcr.io/frikky/shuffle-frontend:0.8.74
container_name: shuffle-frontend container_name: shuffle-frontend
hostname: shuffle-frontend hostname: shuffle-frontend
@@ -79,6 +79,8 @@ services:
- "8000:8000" - "8000:8000"
networks: networks:
- shuffle - shuffle
environment:
- _JAVA_OPTIONS="-Xmx2g"
restart: unless-stopped restart: unless-stopped
volumes: volumes:
- ${DB_LOCATION}:/etc/shuffle - ${DB_LOCATION}:/etc/shuffle
+4
View File
@@ -546,6 +546,10 @@ const ParsedAction = (props) => {
var disabled = false var disabled = false
var rows = "5" var rows = "5"
var openApiHelperText = "This is an OpenAPI specific field" var openApiHelperText = "This is an OpenAPI specific field"
if (selectedApp.generated && data.name === "url" && data.required && data.configuration && hideExtraTypes) {
console.log("GENERATED WITH DATA: ", data)
return null
}
if (selectedApp.generated && data.name === "body") { if (selectedApp.generated && data.name === "body") {
const regex = /\${(\w+)}/g const regex = /\${(\w+)}/g
const found = placeholder.match(regex) const found = placeholder.match(regex)
+62 -32
View File
@@ -688,6 +688,13 @@ const AngularWorkflow = (props) => {
const saveWorkflow = (curworkflow) => { const saveWorkflow = (curworkflow) => {
var success = false var success = false
if (isCloud && !isLoggedIn) {
console.log("Should redirect to register with redirect.")
window.location.href = `/register?view=/workflows/${props.match.params.key}&message=You need sign up to use workflows with Shuffle`
return
}
setSavingState(2) setSavingState(2)
// This might not be the right course of action, but seems logical, as items could be running already // This might not be the right course of action, but seems logical, as items could be running already
@@ -1163,7 +1170,7 @@ const AngularWorkflow = (props) => {
if (responseJson.public) { if (responseJson.public) {
alert.info("This workflow is public. You will have to save it to make it your own!") alert.info("This workflow is public. You will have to save it to make it your own!")
setLastSaved(false) //setLastSaved(false)
} }
setWorkflow(responseJson) setWorkflow(responseJson)
@@ -1267,8 +1274,9 @@ const AngularWorkflow = (props) => {
// Comparing locations between nodes and setting views // Comparing locations between nodes and setting views
const onNodeDrag = (event) => { const onNodeDrag = (event) => {
//console.log("DRAGGING: ", event.target) if (Object.getOwnPropertyNames(selectedAction).length === 0) {
//console.log("LEN2: ", event.target.edges.length) return
}
const nodedata = event.target.data() const nodedata = event.target.data()
if (nodedata.app_name == "Shuffle Tools" || nodedata.app_name == "Testing") { if (nodedata.app_name == "Shuffle Tools" || nodedata.app_name == "Testing") {
@@ -1281,6 +1289,12 @@ const AngularWorkflow = (props) => {
// 3. If it is, then hide text // 3. If it is, then hide text
} }
console.log(nodedata)
var x = event.clientX, y = event.clientY,
elementMouseIsOver = document.elementFromPoint(x, y)
console.log("ELEMENT: ", elementMouseIsOver)
/* /*
event.target.animate({ event.target.animate({
@@ -2952,10 +2966,11 @@ const AngularWorkflow = (props) => {
id="appsearch" id="appsearch"
onKeyPress={(event) => { onKeyPress={(event) => {
if (event.key === "Enter") { if (event.key === "Enter") {
runSearch(event.target.value) event.target.blur(event)
} }
}} }}
onBlur={(event) => { onBlur={(event) => {
console.log("BLUR: ", event.target.value)
runSearch(event.target.value) runSearch(event.target.value)
}} }}
/> />
@@ -2972,12 +2987,19 @@ const AngularWorkflow = (props) => {
})} })}
</div> </div>
: :
<div style={{textAlign: "center", width: leftBarSize}}> apps.length > 0 ?
<CircularProgress style={{marginTop: 25, height: 35, width: 35, marginLeft: "auto", marginRight: "auto", }} /> <div style={{textAlign: "center", width: leftBarSize, marginTop: 10, }}>
<Typography variant="body1" color="textSecondary"> <Typography variant="body1" color="textSecondary">
Loading apps Couldn't find app. Is it active?
</Typography> </Typography>
</div> </div>
:
<div style={{textAlign: "center", width: leftBarSize}}>
<CircularProgress style={{marginTop: 25, height: 35, width: 35, marginLeft: "auto", marginRight: "auto", }} />
<Typography variant="body1" color="textSecondary">
Loading apps
</Typography>
</div>
} }
</div> </div>
</div> </div>
@@ -5385,25 +5407,27 @@ const AngularWorkflow = (props) => {
<div style={bottomBarStyle}> <div style={bottomBarStyle}>
{executionButton} {executionButton}
<div style={{marginLeft: "10px", left: boxSize, bottom: 0, position: "absolute"}}> <div style={{marginLeft: "10px", left: boxSize, bottom: 0, position: "absolute"}}>
<Tooltip color="primary" title="An argument to be used for execution. This is a variable available to every node in your workflow." placement="top"> {workflow.public ? null :
<TextField <Tooltip color="primary" title="An argument to be used for execution. This is a variable available to every node in your workflow." placement="top">
id="execution_argument_input_field" <TextField
style={theme.palette.textFieldStyle} id="execution_argument_input_field"
disabled={workflow.public} style={theme.palette.textFieldStyle}
InputProps={{ disabled={workflow.public}
style: theme.palette.innerTextfieldStyle, InputProps={{
}} style: theme.palette.innerTextfieldStyle,
color="secondary" }}
placeholder={"Execution Argument"} color="secondary"
defaultValue={executionText} placeholder={"Execution Argument"}
onBlur={(e) => { defaultValue={executionText}
setExecutionText(e.target.value) onBlur={(e) => {
}} setExecutionText(e.target.value)
/> }}
</Tooltip> />
</Tooltip>
}
<Tooltip color="primary" title="Save (ctrl+s)" placement="top"> <Tooltip color="primary" title="Save (ctrl+s)" placement="top">
<span> <span>
<Button disabled={savingState !== 0} color="primary" style={{height: 50, width: 64, marginLeft: 10, }} variant={lastSaved ? "outlined" : "contained"} onClick={() => saveWorkflow()}> <Button disabled={savingState !== 0} color="primary" style={{height: workflow.public ? 100 : 50, width: workflow.public ? 100 : 64, marginLeft: 10, }} variant={lastSaved && !(workflow.public) ? "outlined" : "contained"} onClick={() => saveWorkflow()}>
{savingState === 2 ? <CircularProgress style={{height: 35, width: 35}} /> : savingState === 1 ? <DoneIcon style={{color: green}} /> : <SaveIcon /> } {savingState === 2 ? <CircularProgress style={{height: 35, width: 35}} /> : savingState === 1 ? <DoneIcon style={{color: green}} /> : <SaveIcon /> }
</Button> </Button>
</span> </span>
@@ -5411,7 +5435,7 @@ const AngularWorkflow = (props) => {
{workflow.public ? {workflow.public ?
<Tooltip color="secondary" title="Download workflow" placement="top-start"> <Tooltip color="secondary" title="Download workflow" placement="top-start">
<span> <span>
<Button color="primary" style={{height: 50, marginLeft: 10, }} variant="contained" onClick={() => { <Button color="primary" style={{height: 50, marginLeft: 10, }} variant="outlined" onClick={() => {
//setExecutionModalOpen(true) //setExecutionModalOpen(true)
//getWorkflowExecution(props.match.params.key, "") //getWorkflowExecution(props.match.params.key, "")
//data = sanitizeWorkflow(workflow) //data = sanitizeWorkflow(workflow)
@@ -6519,10 +6543,16 @@ const AngularWorkflow = (props) => {
//return //return
} }
// Automatically mapping fields that already exist (predefined).
// Warning if fields are NOT filled
for (var key in selectedApp.authentication.parameters) { for (var key in selectedApp.authentication.parameters) {
if (authenticationOption.fields[selectedApp.authentication.parameters[key].name].length === 0) { if (authenticationOption.fields[selectedApp.authentication.parameters[key].name].length === 0) {
alert.info("Field "+selectedApp.authentication.parameters[key].name+" can't be empty") if (selectedApp.authentication.parameters[key].value !== undefined && selectedApp.authentication.parameters[key].value !== null && selectedApp.authentication.parameters[key].value.length > 0) {
return authenticationOption.fields[selectedApp.authentication.parameters[key].name] = selectedApp.authentication.parameters[key].value
} else {
alert.info("Field "+selectedApp.authentication.parameters[key].name+" can't be empty")
return
}
} }
} }
@@ -6597,8 +6627,8 @@ const AngularWorkflow = (props) => {
authenticationOption.label = event.target.value authenticationOption.label = event.target.value
}} }}
/> />
{selectedApp.link.length > 0 ? <div style={{marginTop: 15}}><EndpointData /></div> : null}
<Divider style={{marginTop: 15, marginBottom: 15, backgroundColor: "rgb(91, 96, 100)"}}/> <Divider style={{marginTop: 15, marginBottom: 15, backgroundColor: "rgb(91, 96, 100)"}}/>
{/*selectedApp.link.length > 0 ? <div style={{marginTop: 15}}><EndpointData /></div> : null*/}
<div style={{}}/> <div style={{}}/>
{selectedApp.authentication.parameters.map((data, index) => { {selectedApp.authentication.parameters.map((data, index) => {
return ( return (
@@ -6619,6 +6649,7 @@ const AngularWorkflow = (props) => {
fullWidth fullWidth
type={data.example !== undefined && data.example.includes("***") ? "password" : "text"} type={data.example !== undefined && data.example.includes("***") ? "password" : "text"}
color="primary" color="primary"
defaultValue={data.value !== undefined && data.value !== null ? data.value : ""}
placeholder={data.example} placeholder={data.example}
onChange={(event) => { onChange={(event) => {
authenticationOption.fields[data.name] = event.target.value authenticationOption.fields[data.name] = event.target.value
@@ -6664,7 +6695,6 @@ const AngularWorkflow = (props) => {
fullWidth fullWidth
type="text" type="text"
color="primary" color="primary"
disabled={true}
placeholder="Bearer token" placeholder="Bearer token"
defaultValue={selectedApp.link} defaultValue={selectedApp.link}
onChange={(event) => { onChange={(event) => {
+1 -1
View File
@@ -1994,7 +1994,7 @@ const AppCreator = (props) => {
setUpdate(Math.random()) setUpdate(Math.random())
} else if (parsedurl.startsWith("curl")) { } else if (parsedurl.startsWith("curl")) {
const request = parseCurl(event.target.value) const request = parseCurl(event.target.value)
if (request !== event.target.value) { if (request !== event.target.value && request.method !== undefined && request.method !== null) {
if (request.method.toUpperCase() !== currentAction.Method) { if (request.method.toUpperCase() !== currentAction.Method) {
setCurrentActionMethod(request.method.toUpperCase()) setCurrentActionMethod(request.method.toUpperCase())
setActionField("method", request.method.toUpperCase()) setActionField("method", request.method.toUpperCase())
+1
View File
@@ -110,6 +110,7 @@ const LoginDialog = props => {
} }
setIsLoggedIn(true) setIsLoggedIn(true)
window.location.pathname = "/workflows" window.location.pathname = "/workflows"
} }
}), }),
+1 -1
View File
@@ -658,7 +658,7 @@ const Workflows = (props) => {
const exportWorkflow = (data) => { const exportWorkflow = (data) => {
let exportFileDefaultName = data.name+'.json'; let exportFileDefaultName = data.name+'.json';
data = sanitizeWorkflow(data) data = sanitizeWorkflow(data)
return //return
// Add correct ID's for triggers // Add correct ID's for triggers
// Add mag // Add mag