diff --git a/backend/go-app/main.go b/backend/go-app/main.go
index 93cb03be..413d3ec8 100644
--- a/backend/go-app/main.go
+++ b/backend/go-app/main.go
@@ -2298,6 +2298,70 @@ func handleGetEnvironments(resp http.ResponseWriter, request *http.Request) {
resp.Write(newjson)
}
+func handleGetOrg(resp http.ResponseWriter, request *http.Request) {
+ cors := handleCors(resp, request)
+ if cors {
+ return
+ }
+
+ var fileId string
+ location := strings.Split(request.URL.String(), "/")
+ if location[1] == "api" {
+ if len(location) <= 4 {
+ log.Printf("Path too short: %d", len(location))
+ resp.WriteHeader(401)
+ resp.Write([]byte(`{"success": false}`))
+ return
+ }
+
+ fileId = location[4]
+ }
+
+ 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
+ }
+
+ ctx := context.Background()
+ org, err := getOrg(ctx, fileId)
+ if err != nil {
+ resp.WriteHeader(401)
+ resp.Write([]byte(`{"success": false, "reason": "Failed getting org users"}`))
+ return
+ }
+
+ //FIXME : cleanup org before marshal
+ userFound := false
+ for _, foundUser := range org.Users {
+ if foundUser.Id == user.Id {
+ userFound = true
+ break
+ }
+ }
+
+ if !userFound {
+ resp.WriteHeader(401)
+ resp.Write([]byte(`{"success": false, "reason": "Use doesn't have access to org"}`))
+ return
+ }
+
+ org.Users = []User{}
+ org.SyncConfig.Apikey = ""
+ newjson, err := json.Marshal(org)
+ if err != nil {
+ log.Printf("Failed unmarshal of org: %s", err)
+ resp.WriteHeader(401)
+ resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed unpacking"}`)))
+ return
+ }
+
+ resp.WriteHeader(200)
+ resp.Write(newjson)
+}
+
func handleGetOrgs(resp http.ResponseWriter, request *http.Request) {
cors := handleCors(resp, request)
if cors {
@@ -2312,7 +2376,7 @@ func handleGetOrgs(resp http.ResponseWriter, request *http.Request) {
return
}
- if user.Role != "admin" {
+ if user.Role != "global_admin" {
resp.WriteHeader(401)
resp.Write([]byte(`{"success": false, "reason": "Not admin"}`))
return
@@ -3507,7 +3571,7 @@ func executeCloudAction(action CloudSyncJob, apikey string) error {
Reason string `json:"reason"`
}
- log.Printf("Data: %s", string(respBody))
+ //log.Printf("Data: %s", string(respBody))
responseData := Result{}
err = json.Unmarshal(respBody, &responseData)
if err != nil {
@@ -3554,7 +3618,7 @@ func handleNewHook(resp http.ResponseWriter, request *http.Request) {
return
}
- log.Printf("Data: %s", string(body))
+ //log.Printf("Data: %s", string(body))
ctx := context.Background()
var requestdata requestData
@@ -6743,7 +6807,7 @@ func remoteOrgJobHandler(org Org, interval int) error {
req.Header.Add("Authorization", fmt.Sprintf(`Bearer %s`, org.SyncConfig.Apikey))
newresp, err := client.Do(req)
if err != nil {
- log.Printf("Failed request in org sync: %s", err)
+ //log.Printf("Failed request in org sync: %s", err)
return err
}
@@ -6753,7 +6817,7 @@ func remoteOrgJobHandler(org Org, interval int) error {
return err
}
- log.Printf("Data: %s", respBody)
+ //log.Printf("Data: %s", respBody)
err = remoteOrgJobController(org, respBody)
if err != nil {
@@ -7958,6 +8022,8 @@ func initHandlers() {
// NEW for 0.8.0
r.HandleFunc("/api/v1/cloud/setup", handleCloudSetup).Methods("POST", "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}", handleEditOrg).Methods("POST", "OPTIONS")
// Important for email, IDS etc. Create this by:
// PS: For cloud, this has to use cloud storage.
diff --git a/backend/go-app/walkoff.go b/backend/go-app/walkoff.go
index ad742389..6ce5a77b 100644
--- a/backend/go-app/walkoff.go
+++ b/backend/go-app/walkoff.go
@@ -68,19 +68,22 @@ type ExecutionRequest struct {
}
type SyncFeatures struct {
+ Webhook SyncData `json:"webhook" datastore:"webhook"`
+ Schedule SyncData `json:"schedule" datastore:"schedule"`
+ UserInput SyncData `json:"user_input" datastore:"user_input"`
+ EmailTrigger SyncData `json:"email_trigger" datastore:"email_trigger"`
Apps SyncData `json:"apps" datastore:"apps"`
Workflows SyncData `json:"workflows" datastore:"workflows"`
Schedules SyncData `json:"schedules" datastore:"schedules"`
Autocomplete SyncData `json:"autocomplete" datastore:"autocomplete"`
Authentication SyncData `json:"authentication" datastore:"authentication"`
- Webhook SyncData `json:"webhook" datastore:"webhook"`
- Schedule SyncData `json:"schedule" datastore:"schedule"`
- UserInput SyncData `json:"user_input" datastore:"user_input"`
- EmailTrigger SyncData `json:"email_trigger" datastore:"email_trigger"`
}
type SyncData struct {
- Active bool `json:"active" datastore:"active"`
+ Active bool `json:"active" datastore:"active"`
+ Name string `json:"name" datastore:"name"`
+ Description string `json:"description" datastore:"description"`
+ Limit int64 `json:"limit" datastore:"limit"`
}
type SyncConfig struct {
@@ -91,6 +94,8 @@ type SyncConfig struct {
// Role is just used for feedback for a user
type Org struct {
Name string `json:"name" datastore:"name"`
+ Description string `json:"description" datastore:"description"`
+ Image string `json:"image" datastore:"image"`
Id string `json:"id" datastore:"id"`
Org string `json:"org" datastore:"org"`
Users []User `json:"users" datastore:"users"`
diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx
index 8e57b486..16c2ca17 100644
--- a/frontend/src/App.jsx
+++ b/frontend/src/App.jsx
@@ -118,7 +118,7 @@ const App = (message, props) => {
const options = {
timeout: 5000,
- position: positions.TOP_CENTER,
+ position: positions.BOTTOM_LEFT,
};
const includedData = window.location.pathname === "/home" || window.location.pathname === "/features" ?
diff --git a/frontend/src/views/Admin.jsx b/frontend/src/views/Admin.jsx
index d3deb492..817a20e2 100644
--- a/frontend/src/views/Admin.jsx
+++ b/frontend/src/views/Admin.jsx
@@ -1,7 +1,10 @@
import React, { useEffect} from 'react';
+import { makeStyles } from '@material-ui/styles';
import {Link} from 'react-router-dom';
import Paper from '@material-ui/core/Paper';
+import Card from '@material-ui/core/Card';
+import Tooltip from '@material-ui/core/Tooltip';
import FormControlLabel from '@material-ui/core/FormControlLabel';
import Typography from '@material-ui/core/Typography';
import Switch from '@material-ui/core/Switch';
@@ -20,6 +23,7 @@ import ListItemAvatar from '@material-ui/core/ListItemAvatar';
import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction';
import IconButton from '@material-ui/core/IconButton';
import Avatar from '@material-ui/core/Avatar';
+import Zoom from '@material-ui/core/Zoom';
import { useAlert } from "react-alert";
@@ -41,19 +45,30 @@ import ScheduleIcon from '@material-ui/icons/Schedule';
import CloudIcon from '@material-ui/icons/Cloud';
import BusinessIcon from '@material-ui/icons/Business';
-const Admin = (props) => {
- const { globalUrl } = props;
+const useStyles = makeStyles({
+ notchedOutline: {
+ borderColor: "#f85a3e !important"
+ },
+})
+const Admin = (props) => {
+ const { globalUrl, userdata } = props;
+
+ var upload = ""
const theme = useTheme();
+ const classes = useStyles();
const [firstRequest, setFirstRequest] = React.useState(true);
const [modalUser, setModalUser] = React.useState({});
const [modalOpen, setModalOpen] = React.useState(false);
+ const [file, setFile] = React.useState("");
+ const [fileBase64, setFileBase64] = React.useState("");
const [cloudSyncModalOpen, setCloudSyncModalOpen] = React.useState(false);
const [cloudSyncApikey, setCloudSyncApikey] = React.useState("");
const [loading, setLoading] = React.useState(false);
const [selectedOrganization, setSelectedOrganization] = React.useState({});
+ const [organizationFeatures, setOrganizationFeatures] = React.useState({});
const [loginInfo, setLoginInfo] = React.useState("");
const [curTab, setCurTab] = React.useState(0);
const [users, setUsers] = React.useState([]);
@@ -244,6 +259,8 @@ const Admin = (props) => {
selectedOrganization.cloud_sync = !selectedOrganization.cloud_sync
setSelectedOrganization(selectedOrganization)
setCloudSyncApikey("")
+
+ handleGetOrg(userdata.active_org.id)
}
})
.catch(error => {
@@ -312,6 +329,50 @@ const Admin = (props) => {
});
}
+ const handleGetOrg = (orgId) => {
+ // Just use this one?
+ var baseurl = globalUrl
+ const url = baseurl + '/api/v1/orgs/'+orgId
+ fetch(url, {
+ method: 'GET',
+ credentials: "include",
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ })
+ .then(response =>
+ response.json().then(responseJson => {
+ if (responseJson["success"] === false) {
+ alert.error("Failed getting org: ", responseJson.readon)
+ } else {
+ setSelectedOrganization(responseJson)
+ var lists = {
+ "active": {
+ "triggers": [],
+ "features": [],
+ "sync": [],
+ },
+ "inactive": {
+ "triggers": [],
+ "features": [],
+ "sync": [],
+ },
+ }
+
+ Object.keys(responseJson.sync_features).map(function(key, index) {
+ console.log(responseJson.sync_features[key])
+ })
+
+ setOrganizationFeatures(lists)
+ }
+ }),
+ )
+ .catch(error => {
+ console.log("Error getting org: ", error)
+ alert.error("Error getting current organization")
+ });
+ }
+
const submitUser = (data) => {
console.log("INPUT: ", data)
@@ -609,6 +670,11 @@ const Admin = (props) => {
getUsers()
}
+ if (selectedOrganization.id === undefined && userdata !== undefined && userdata.active_org !== undefined) {
+ //setSelectedOrganization(userdata.active_org)
+ handleGetOrg(userdata.active_org.id)
+ }
+
const paperStyle = {
maxWidth: 1250,
margin: "auto",
@@ -831,19 +897,21 @@ const Admin = (props) => {