Started work on user input trigger
This commit is contained in:
@@ -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")
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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 (
|
||||||
|
|||||||
Reference in New Issue
Block a user