Started work on user input trigger

This commit is contained in:
frikky
2020-11-13 14:24:17 +01:00
parent 3ece0857af
commit 83089d2d39
3 changed files with 196 additions and 29 deletions
+18
View File
@@ -280,6 +280,7 @@ type ScheduleOld struct {
LastModificationtime int64 `json:"lastmodificationtime" datastore:"lastmodificationtime,noindex"` LastModificationtime int64 `json:"lastmodificationtime" datastore:"lastmodificationtime,noindex"`
LastRuntime int64 `json:"lastruntime" datastore:"lastruntime,noindex"` LastRuntime int64 `json:"lastruntime" datastore:"lastruntime,noindex"`
Frequency string `json:"frequency" datastore:"frequency,noindex"` Frequency string `json:"frequency" datastore:"frequency,noindex"`
Environment string `json:"environment" datastore:"environment"`
} }
// Returned from /GET /schedules // Returned from /GET /schedules
@@ -1184,6 +1185,7 @@ func createNewUser(username, password, role, apikey string, org Org) error {
} }
neworg, err := getOrg(ctx, org.Id) neworg, err := getOrg(ctx, org.Id)
log.Printf("Users: %d", len(org.Users))
if err == nil { if err == nil {
log.Printf("Updating org %s with user %s", org.Name, newUser.Username) log.Printf("Updating org %s with user %s", org.Name, newUser.Username)
neworg.Users = append(org.Users, *newUser) neworg.Users = append(org.Users, *newUser)
@@ -2817,6 +2819,8 @@ func fixUserOrg(ctx context.Context, user *User) *User {
continue continue
} }
log.Printf("Org users: %d", len(org.Users))
orgIndex := 0 orgIndex := 0
userFound := false userFound := false
for index, orgUser := range org.Users { for index, orgUser := range org.Users {
@@ -2838,6 +2842,7 @@ func fixUserOrg(ctx context.Context, user *User) *User {
org.Users = append(org.Users, *user) org.Users = append(org.Users, *user)
} }
log.Printf("Users 2: %d", len(org.Users))
err = setOrg(ctx, *org, orgId) err = setOrg(ctx, *org, orgId)
if err != nil { if err != nil {
log.Printf("Failed setting org %s", orgId) log.Printf("Failed setting org %s", orgId)
@@ -7190,6 +7195,12 @@ func runInit(ctx context.Context) {
continue continue
} }
log.Printf("ENV: %s", item.Environment)
if item.Environment == "cloud" {
log.Printf("Skipping cloud schedule")
continue
}
item.Org = activeOrgs[0].Id item.Org = activeOrgs[0].Id
err = setSchedule(ctx, item) err = setSchedule(ctx, item)
if err != nil { if err != nil {
@@ -7241,6 +7252,11 @@ func runInit(ctx context.Context) {
} else { } else {
log.Printf("Setting up %d schedule(s)", len(schedules)) log.Printf("Setting up %d schedule(s)", len(schedules))
for _, schedule := range schedules { for _, schedule := range schedules {
if schedule.Environment == "cloud" {
log.Printf("Skipping cloud schedule")
continue
}
//log.Printf("Schedule: %#v", schedule) //log.Printf("Schedule: %#v", schedule)
job := func() { job := func() {
request := &http.Request{ request := &http.Request{
@@ -8146,6 +8162,8 @@ func initHandlers() {
// NEW for 0.8.0 // NEW for 0.8.0
r.HandleFunc("/api/v1/cloud/setup", handleCloudSetup).Methods("POST", "OPTIONS") r.HandleFunc("/api/v1/cloud/setup", handleCloudSetup).Methods("POST", "OPTIONS")
// Orgs
r.HandleFunc("/api/v1/orgs", handleGetOrgs).Methods("GET", "OPTIONS") r.HandleFunc("/api/v1/orgs", handleGetOrgs).Methods("GET", "OPTIONS")
r.HandleFunc("/api/v1/orgs/{orgId}", handleGetOrg).Methods("GET", "OPTIONS") r.HandleFunc("/api/v1/orgs/{orgId}", handleGetOrg).Methods("GET", "OPTIONS")
r.HandleFunc("/api/v1/orgs/{orgId}", handleEditOrg).Methods("POST", "OPTIONS") r.HandleFunc("/api/v1/orgs/{orgId}", handleEditOrg).Methods("POST", "OPTIONS")
+99 -2
View File
@@ -85,6 +85,8 @@ type SyncData struct {
Name string `json:"name" datastore:"name"` Name string `json:"name" datastore:"name"`
Description string `json:"description" datastore:"description"` Description string `json:"description" datastore:"description"`
Limit int64 `json:"limit" datastore:"limit"` Limit int64 `json:"limit" datastore:"limit"`
StartDate int64 `json:"start_date" datastore:"start_date"`
EndDate int64 `json:"end_date" datastore:"end_date"`
} }
type SyncConfig struct { type SyncConfig struct {
@@ -354,6 +356,7 @@ type Workflow struct {
Name string `json:"name" datastore:"name"` Name string `json:"name" datastore:"name"`
Value string `json:"value" datastore:"value,noindex"` Value string `json:"value" datastore:"value,noindex"`
} `json:"execution_variables,omitempty" datastore:"execution_variables"` } `json:"execution_variables,omitempty" datastore:"execution_variables"`
ExecutionEnvironment string `json:"execution_environment" datastore:"execution_environment"`
} }
type ActionResult struct { type ActionResult struct {
@@ -572,6 +575,7 @@ func createSchedule(ctx context.Context, scheduleId, workflowId, name, startNode
LastModificationtime: timeNow, LastModificationtime: timeNow,
LastRuntime: timeNow, LastRuntime: timeNow,
Org: orgId, Org: orgId,
Environment: "onprem",
} }
err = setSchedule(ctx, schedule) err = setSchedule(ctx, schedule)
@@ -1461,7 +1465,27 @@ func setNewWorkflow(resp http.ResponseWriter, request *http.Request) {
log.Printf("Has %d actions already", len(newActions)) log.Printf("Has %d actions already", len(newActions))
} }
for _, item := range workflow.Actions {
item.ID = uuid.NewV4().String()
newActions = append(newActions, item)
}
newTriggers := []Trigger{}
for _, item := range workflow.Triggers {
item.Status = "uninitialized"
item.ID = uuid.NewV4().String()
newTriggers = append(newTriggers, item)
}
newSchedules := []Schedule{}
for _, item := range workflow.Schedules {
item.Id = uuid.NewV4().String()
newSchedules = append(newSchedules, item)
}
workflow.Actions = newActions workflow.Actions = newActions
workflow.Triggers = newTriggers
workflow.Schedules = newSchedules
workflow.IsValid = true workflow.IsValid = true
workflow.Configuration.ExitOnError = false workflow.Configuration.ExitOnError = false
@@ -3025,10 +3049,61 @@ func stopSchedule(resp http.ResponseWriter, request *http.Request) {
return return
} }
schedule, err := getSchedule(ctx, scheduleId)
if err != nil {
log.Printf("Failed finding schedule %s", scheduleId)
resp.WriteHeader(401)
resp.Write([]byte(`{"success": false}`))
return
}
log.Printf("Schedule: %#v", schedule)
if schedule.Environment == "cloud" {
log.Printf("[INFO] Should STOP a cloud schedule for workflow %s with schedule ID %s", fileId, scheduleId)
// https://shuffler.io/v1/hooks/webhook_80184973-3e82-4852-842e-0290f7f34d7c
org, err := getOrg(ctx, user.ActiveOrg.Id)
if err != nil {
log.Printf("Failed finding org %s: %s", org.Id, err)
return
}
// 1. Send request to cloud
// 2. Remove schedule if success
action := CloudSyncJob{
Type: "schedule",
Action: "stop",
OrgId: org.Id,
PrimaryItemId: scheduleId,
SecondaryItem: schedule.Frequency,
ThirdItem: workflow.ID,
}
err = executeCloudAction(action, org.SyncConfig.Apikey)
if err != nil {
log.Printf("Failed cloud action STOP schedule", err)
resp.WriteHeader(401)
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "%s"}`, err)))
return
} else {
log.Printf("Successfully ran cloud action STOP schedule")
err = DeleteKey(ctx, "schedules", scheduleId)
if err != nil {
log.Printf("Failed deleting cloud schedule onprem..")
resp.WriteHeader(401)
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed deleting cloud schedule"}`)))
return
}
resp.WriteHeader(200)
resp.Write([]byte(fmt.Sprintf(`{"success": true}`)))
return
}
}
err = deleteSchedule(ctx, scheduleId) err = deleteSchedule(ctx, scheduleId)
if err != nil { if err != nil {
log.Printf("Failed deleting schedule: %s", err) log.Printf("Failed deleting schedule: %s", err)
if strings.Contains(err.Error(), "Job not found") { if strings.Contains(err.Error(), "Job not found") {
resp.WriteHeader(200) resp.WriteHeader(200)
resp.Write([]byte(fmt.Sprintf(`{"success": true}`))) resp.Write([]byte(fmt.Sprintf(`{"success": true}`)))
@@ -3329,8 +3404,30 @@ func scheduleWorkflow(resp http.ResponseWriter, request *http.Request) {
FourthItem: schedule.ExecutionArgument, FourthItem: schedule.ExecutionArgument,
} }
log.Printf("Action: %#v", action) timeNow := int64(time.Now().Unix())
newSchedule := ScheduleOld{
Id: schedule.Id,
WorkflowId: workflow.ID,
StartNode: startNode,
Argument: string(schedule.ExecutionArgument),
WrappedArgument: parsedBody,
CreationTime: timeNow,
LastModificationtime: timeNow,
LastRuntime: timeNow,
Org: org.Id,
Frequency: schedule.Frequency,
Environment: "cloud",
}
err = setSchedule(ctx, newSchedule)
if err != nil {
log.Printf("Failed setting cloud schedule: returning", err)
resp.WriteHeader(401)
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "%s"}`, err)))
return
}
log.Printf("Action: %#v", action)
err = executeCloudAction(action, org.SyncConfig.Apikey) err = executeCloudAction(action, org.SyncConfig.Apikey)
if err != nil { if err != nil {
log.Printf("Failed cloud action START schedule", err) log.Printf("Failed cloud action START schedule", err)
+79 -27
View File
@@ -796,6 +796,7 @@ const AngularWorkflow = (props) => {
"Testing", "Testing",
"Http", "Http",
] ]
const getAppAuthentication = () => { const getAppAuthentication = () => {
fetch(globalUrl+"/api/v1/apps/authentication", { fetch(globalUrl+"/api/v1/apps/authentication", {
method: 'GET', method: 'GET',
@@ -4860,6 +4861,9 @@ const AngularWorkflow = (props) => {
// email,sms,app ... // email,sms,app ...
workflow.triggers[selectedTriggerIndex].parameters[2] = {"name": "type", "value": "email"} workflow.triggers[selectedTriggerIndex].parameters[2] = {"name": "type", "value": "email"}
workflow.triggers[selectedTriggerIndex].parameters[3] = {"name": "email", "value": "test@test.com"}
workflow.triggers[selectedTriggerIndex].parameters[4] = {"name": "sms", "value": "0000000"}
setWorkflow(workflow) setWorkflow(workflow)
} }
@@ -4868,7 +4872,7 @@ const AngularWorkflow = (props) => {
<div style={{display: "flex", height: "40px", marginBottom: "30px"}}> <div style={{display: "flex", height: "40px", marginBottom: "30px"}}>
<div style={{flex: "1"}}> <div style={{flex: "1"}}>
<h3 style={{marginBottom: "5px"}}>{selectedTrigger.app_name}: {selectedTrigger.status}</h3> <h3 style={{marginBottom: "5px"}}>{selectedTrigger.app_name}: {selectedTrigger.status}</h3>
<a href="https://shuffler.io/docs/triggers#user_input" style={{textDecoration: "none", color: "#f85a3e"}}>What are user inputs?</a> <a href="https://shuffler.io/docs/triggers#user_input" style={{textDecoration: "none", color: "#f85a3e"}}>What is the user input trigger?</a>
</div> </div>
</div> </div>
<Divider style={{marginBottom: "10px", marginTop: "10px", height: "1px", width: "100%", backgroundColor: "rgb(91, 96, 100)"}}/> <Divider style={{marginBottom: "10px", marginTop: "10px", height: "1px", width: "100%", backgroundColor: "rgb(91, 96, 100)"}}/>
@@ -4949,33 +4953,79 @@ const AngularWorkflow = (props) => {
</div> </div>
</div> </div>
<FormGroup style={{paddingLeft: 10, backgroundColor: inputColor}} row> <FormGroup style={{paddingLeft: 10, backgroundColor: inputColor}} row>
<FormControlLabel <FormControlLabel
control={ control={
<Checkbox <Checkbox
checked={workflow.triggers[selectedTriggerIndex].parameters[2] !== undefined && workflow.triggers[selectedTriggerIndex].parameters[2].value.includes("email")} checked={workflow.triggers[selectedTriggerIndex].parameters[2] !== undefined && workflow.triggers[selectedTriggerIndex].parameters[2].value.includes("email")}
onChange={() => { onChange={() => {
setTriggerOptionsWrapper("email") setTriggerOptionsWrapper("email")
}} }}
color="primary" color="primary"
value="email" value="email"
/> />
} }
label={<div style={{color: "white"}}>Email</div>} label={<div style={{color: "white"}}>Email</div>}
/> />
<FormControlLabel <FormControlLabel
control={ control={
<Checkbox <Checkbox
checked={workflow.triggers[selectedTriggerIndex].parameters[2].value.includes("sms")} checked={workflow.triggers[selectedTriggerIndex].parameters[2].value.includes("sms")}
onChange={() => { onChange={() => {
setTriggerOptionsWrapper("sms") setTriggerOptionsWrapper("sms")
}} }}
color="primary" color="primary"
value="sms" value="sms"
/> />
} }
label={<div style={{color: "white"}}>SMS</div>} label={<div style={{color: "white"}}>SMS</div>}
/> />
</FormGroup> </FormGroup>
{workflow.triggers[selectedTriggerIndex].parameters[2] !== undefined && workflow.triggers[selectedTriggerIndex].parameters[2].value.includes("email") ?
<TextField
style={{backgroundColor: inputColor, borderRadius: borderRadius,}}
InputProps={{
style:{
color: "white",
marginLeft: "5px",
maxWidth: "95%",
height: "50px",
fontSize: "1em",
},
}}
fullWidth
color="primary"
placeholder={"mail1@company.com,mail2@company.com"}
onChange={(event) => {
workflow.triggers[selectedTriggerIndex].parameters[3].value = event.target.value
setWorkflow(workflow)
setUpdate(Math.random())
}}
/>
: null
}
{workflow.triggers[selectedTriggerIndex].parameters[2] !== undefined && workflow.triggers[selectedTriggerIndex].parameters[2].value.includes("sms") ?
<TextField
style={{backgroundColor: inputColor, borderRadius: borderRadius,}}
InputProps={{
style:{
color: "white",
marginLeft: "5px",
maxWidth: "95%",
height: "50px",
fontSize: "1em",
},
}}
fullWidth
color="primary"
placeholder={"+474823212,+460203042"}
onChange={(event) => {
workflow.triggers[selectedTriggerIndex].parameters[4].value = event.target.value
setWorkflow(workflow)
setUpdate(Math.random())
}}
/>
: null
}
</div> </div>
</div> </div>
) )
@@ -5996,7 +6046,9 @@ const AngularWorkflow = (props) => {
setNewAppAuth(newAuthOption) setNewAppAuth(newAuthOption)
appAuthentication.push(newAuthOption) appAuthentication.push(newAuthOption)
setAppAuthentication(appAuthentication) setAppAuthentication(appAuthentication)
getAppAuthentication()
setUpdate(authenticationOption.id) setUpdate(authenticationOption.id)
} }
return ( return (