Added schedule overview to admin
This commit is contained in:
+61
-2
@@ -238,7 +238,7 @@ type AppInfo struct {
|
||||
type ScheduleOld struct {
|
||||
Id string `json:"id" datastore:"id"`
|
||||
Seconds int `json:"seconds" datastore:"seconds"`
|
||||
WorkflowId string `json:"workflow_id datastore:"workflow_id", `
|
||||
WorkflowId string `json:"workflow_id" datastore:"workflow_id", `
|
||||
Argument string `json:"argument" datastore:"argument"`
|
||||
AppInfo AppInfo `json:"appinfo" datastore:"appinfo,noindex"`
|
||||
Finished bool `json:"finished" finished:"id"`
|
||||
@@ -1803,6 +1803,49 @@ func getUserCount() (int, error) {
|
||||
return count, nil
|
||||
}
|
||||
|
||||
func handleGetSchedules(resp http.ResponseWriter, request *http.Request) {
|
||||
cors := handleCors(resp, request)
|
||||
if cors {
|
||||
return
|
||||
}
|
||||
|
||||
user, err := handleApiAuthentication(resp, request)
|
||||
if err != nil {
|
||||
log.Printf("Api authentication failed in set new workflowhandler: %s", err)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
return
|
||||
}
|
||||
|
||||
if user.Role != "admin" {
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false, "reason": "Admin required"}`))
|
||||
return
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
schedules, err := getAllSchedules(ctx)
|
||||
if err != nil {
|
||||
log.Printf("Failed getting schedules: %s", err)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false, "reason": "Couldn't get schedules"}`))
|
||||
return
|
||||
}
|
||||
|
||||
newjson, err := json.Marshal(schedules)
|
||||
if err != nil {
|
||||
log.Printf("Failed unmarshal: %s", err)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed unpacking environments"}`)))
|
||||
return
|
||||
}
|
||||
|
||||
//log.Printf("Existing environments: %s", string(newjson))
|
||||
|
||||
resp.WriteHeader(200)
|
||||
resp.Write(newjson)
|
||||
}
|
||||
|
||||
func handleGetEnvironments(resp http.ResponseWriter, request *http.Request) {
|
||||
cors := handleCors(resp, request)
|
||||
if cors {
|
||||
@@ -2635,6 +2678,21 @@ func handleDeleteSchedule(resp http.ResponseWriter, request *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
user, err := handleApiAuthentication(resp, request)
|
||||
if err != nil {
|
||||
log.Printf("Api authentication failed in set new workflowhandler: %s", err)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
return
|
||||
}
|
||||
|
||||
// FIXME: IAM - Get workflow and check owner
|
||||
if user.Role != "admin" {
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false, "reason": "Admin required"}`))
|
||||
return
|
||||
}
|
||||
|
||||
location := strings.Split(request.URL.String(), "/")
|
||||
|
||||
var workflowId string
|
||||
@@ -2655,7 +2713,7 @@ func handleDeleteSchedule(resp http.ResponseWriter, request *http.Request) {
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
err := DeleteKey(ctx, "schedules", workflowId)
|
||||
err = DeleteKey(ctx, "schedules", workflowId)
|
||||
if err != nil {
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false, "message": "Can't delete"}`))
|
||||
@@ -5914,6 +5972,7 @@ func init() {
|
||||
/* Everything below here increases the counters*/
|
||||
r.HandleFunc("/api/v1/workflows", getWorkflows).Methods("GET", "OPTIONS")
|
||||
r.HandleFunc("/api/v1/workflows", setNewWorkflow).Methods("POST", "OPTIONS")
|
||||
r.HandleFunc("/api/v1/workflows/schedules", handleGetSchedules).Methods("GET", "OPTIONS")
|
||||
//r.HandleFunc("/api/v1/workflows/{key}/execute_fs", executeWorkflowFS)
|
||||
r.HandleFunc("/api/v1/workflows/{key}/execute", executeWorkflow).Methods("GET", "POST", "OPTIONS")
|
||||
r.HandleFunc("/api/v1/workflows/{key}/schedule", scheduleWorkflow).Methods("POST", "OPTIONS")
|
||||
|
||||
@@ -2021,6 +2021,7 @@ func executeWorkflow(resp http.ResponseWriter, request *http.Request) {
|
||||
}
|
||||
|
||||
func stopSchedule(resp http.ResponseWriter, request *http.Request) {
|
||||
log.Printf("Delete?")
|
||||
cors := handleCors(resp, request)
|
||||
if cors {
|
||||
return
|
||||
@@ -2079,19 +2080,6 @@ func stopSchedule(resp http.ResponseWriter, request *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if len(workflow.Actions) == 0 {
|
||||
workflow.Actions = []Action{}
|
||||
}
|
||||
if len(workflow.Branches) == 0 {
|
||||
workflow.Branches = []Branch{}
|
||||
}
|
||||
if len(workflow.Triggers) == 0 {
|
||||
workflow.Triggers = []Trigger{}
|
||||
}
|
||||
if len(workflow.Errors) == 0 {
|
||||
workflow.Errors = []string{}
|
||||
}
|
||||
|
||||
err = deleteSchedule(ctx, scheduleId)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "Job not found") {
|
||||
|
||||
+109
-1
@@ -8,7 +8,8 @@ import ListItem from '@material-ui/core/ListItem';
|
||||
import Button from '@material-ui/core/Button';
|
||||
import Tabs from '@material-ui/core/Tabs';
|
||||
import Tab from '@material-ui/core/Tab';
|
||||
|
||||
import ListItemText from '@material-ui/core/ListItemText';
|
||||
import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction';
|
||||
|
||||
import { useAlert } from "react-alert";
|
||||
|
||||
@@ -29,9 +30,39 @@ const Admin = (props) => {
|
||||
const [curTab, setCurTab] = React.useState(0);
|
||||
const [users, setUsers] = React.useState([]);
|
||||
const [environments, setEnvironments] = React.useState([]);
|
||||
const [schedules, setSchedules] = React.useState([])
|
||||
|
||||
const alert = useAlert()
|
||||
|
||||
const deleteSchedule = (data) => {
|
||||
// FIXME - add some check here ROFL
|
||||
console.log("INPUT: ", data)
|
||||
|
||||
// Just use this one?
|
||||
const url = globalUrl+'/api/v1/workflows/'+data["workflow_id datastore:"]+"/schedule/"+data.id
|
||||
console.log("URL: ", url)
|
||||
fetch(url, {
|
||||
method: 'DELETE',
|
||||
credentials: "include",
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
})
|
||||
.then(response =>
|
||||
response.json().then(responseJson => {
|
||||
if (responseJson["success"] === false) {
|
||||
alert.error("Failed stopping schedule")
|
||||
} else {
|
||||
getSchedules()
|
||||
alert.success("Successfully stopped schedule!")
|
||||
}
|
||||
}),
|
||||
)
|
||||
.catch(error => {
|
||||
console.log("Error in userdata: ", error)
|
||||
});
|
||||
}
|
||||
|
||||
const submitUser = (data) => {
|
||||
// FIXME - add some check here ROFL
|
||||
console.log("INPUT: ", data)
|
||||
@@ -132,6 +163,31 @@ const Admin = (props) => {
|
||||
});
|
||||
}
|
||||
|
||||
const getSchedules = () => {
|
||||
fetch(globalUrl+"/api/v1/workflows/schedules", {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': 'application/json',
|
||||
},
|
||||
credentials: "include",
|
||||
})
|
||||
.then((response) => {
|
||||
if (response.status !== 200) {
|
||||
console.log("Status not 200 for apps :O!")
|
||||
return
|
||||
}
|
||||
|
||||
return response.json()
|
||||
})
|
||||
.then((responseJson) => {
|
||||
setSchedules(responseJson)
|
||||
})
|
||||
.catch(error => {
|
||||
alert.error(error.toString())
|
||||
});
|
||||
}
|
||||
|
||||
const getEnvironments = () => {
|
||||
fetch(globalUrl+"/api/v1/getenvironments", {
|
||||
method: 'GET',
|
||||
@@ -329,6 +385,54 @@ const Admin = (props) => {
|
||||
</div>
|
||||
: null
|
||||
|
||||
const schedulesView = curTab === 2 ?
|
||||
<div>
|
||||
<h2>
|
||||
Schedules
|
||||
</h2>
|
||||
<Divider style={{marginTop: 20, marginBottom: 20, backgroundColor: inputColor}}/>
|
||||
<List>
|
||||
<ListItem>
|
||||
<ListItemText
|
||||
primary="Interval (seconds)"
|
||||
style={{maxWidth: 200}}
|
||||
/>
|
||||
<ListItemText
|
||||
primary="Argument"
|
||||
style={{maxWidth: 400, overflow: "hidden"}}
|
||||
/>
|
||||
<ListItemText
|
||||
primary="Actions"
|
||||
/>
|
||||
</ListItem>
|
||||
{schedules === undefined || schedules === null ? null : schedules.map(schedule => {
|
||||
return (
|
||||
<ListItem>
|
||||
<ListItemText
|
||||
style={{maxWidth: 200}}
|
||||
primary={schedule.seconds}
|
||||
/>
|
||||
<ListItemText
|
||||
primary={schedule.argument}
|
||||
style={{maxWidth: 400, overflow: "hidden"}}
|
||||
/>
|
||||
<ListItemText>
|
||||
<Button
|
||||
style={{}}
|
||||
variant="contained"
|
||||
color="primary"
|
||||
onClick={() => deleteSchedule(schedule)}
|
||||
>
|
||||
Delete
|
||||
</Button>
|
||||
</ListItemText>
|
||||
</ListItem>
|
||||
)
|
||||
})}
|
||||
</List>
|
||||
</div>
|
||||
: null
|
||||
|
||||
const environmentView = curTab === 1 ?
|
||||
<div>
|
||||
<h2>
|
||||
@@ -359,6 +463,8 @@ const Admin = (props) => {
|
||||
const setConfig = (event, newValue) => {
|
||||
if (newValue === 1) {
|
||||
getEnvironments()
|
||||
} else if (newValue === 2) {
|
||||
getSchedules()
|
||||
}
|
||||
|
||||
setModalUser({})
|
||||
@@ -377,10 +483,12 @@ const Admin = (props) => {
|
||||
>
|
||||
<Tab label="Users" />
|
||||
<Tab label="Environments"/>
|
||||
<Tab label="Schedules"/>
|
||||
</Tabs>
|
||||
<div style={{marginBottom: 10}}/>
|
||||
{usersView}
|
||||
{environmentView}
|
||||
{schedulesView}
|
||||
</Paper>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1588,14 +1588,14 @@ const AppCreator = (props) => {
|
||||
{bearerAuth}
|
||||
{apiKey}
|
||||
|
||||
{authenticationOption === "No authentication" ? null :
|
||||
{/*authenticationOption === "No authentication" ? null :
|
||||
<FormControlLabel
|
||||
style={{color: "white", marginBottom: 0, marginTop: 20}}
|
||||
label=<div style={{color: "white"}}>Authentication required (default true)</div>
|
||||
control={<Switch checked={authenticationRequired} onChange={() => {
|
||||
setAuthenticationRequired(!authenticationRequired)
|
||||
}} />}
|
||||
/>}
|
||||
/>*/}
|
||||
<Divider style={{marginBottom: "10px", marginTop: "30px", height: "1px", width: "100%", backgroundColor: "grey"}}/>
|
||||
<div style={{marginTop: "25px"}}>
|
||||
{actionView}
|
||||
|
||||
Reference in New Issue
Block a user