@@ -101,7 +101,7 @@ class AppBase:
|
||||
except requests.exceptions.ConnectionError as e:
|
||||
print("Connectionerror: %s" % e)
|
||||
|
||||
action_result["result"] = "Bad setup during startup: %d" % e
|
||||
action_result["result"] = "Bad setup during startup: %s" % e
|
||||
self.send_result(action_result, headers, stream_path)
|
||||
return
|
||||
|
||||
@@ -288,7 +288,7 @@ class AppBase:
|
||||
# Do stuff here.
|
||||
innervalue = parse_nested_param(data, maxDepth(data)-0)
|
||||
outervalue = parse_nested_param(data, maxDepth(data)-1)
|
||||
print("INNER: ", outervalue)
|
||||
print("INNER: ", innervalue)
|
||||
print("OUTER: ", outervalue)
|
||||
|
||||
if outervalue != innervalue:
|
||||
@@ -710,7 +710,17 @@ class AppBase:
|
||||
continue
|
||||
|
||||
#print(destinationvalue)
|
||||
if not run_validation(sourcevalue, condition["condition"]["value"], destinationvalue):
|
||||
# NEGATE
|
||||
validation = run_validation(sourcevalue, condition["condition"]["value"], destinationvalue)
|
||||
|
||||
# Configuration = negated because of WorkflowAppActionParam..
|
||||
try:
|
||||
if condition["condition"]["configuration"]:
|
||||
validation = not validation
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
if not validation:
|
||||
self.logger.info("Failed condition check for %s %s %s." % (sourcevalue, condition["condition"]["value"], destinationvalue))
|
||||
return False, "Failed condition: %s %s %s" % (sourcevalue, condition["condition"]["value"], destinationvalue)
|
||||
|
||||
|
||||
@@ -398,7 +398,7 @@ func makePythoncode(swagger *openapi3.Swagger, name, url, method string, paramet
|
||||
verifyAddin,
|
||||
)
|
||||
|
||||
log.Printf("%s", data)
|
||||
//log.Printf("%s", data)
|
||||
return functionname, data
|
||||
}
|
||||
|
||||
|
||||
+14
-4
@@ -662,7 +662,7 @@ func handleApiAuthentication(resp http.ResponseWriter, request *http.Request) (U
|
||||
if len(Userdata.Username) > 0 {
|
||||
return Userdata, nil
|
||||
} else {
|
||||
return Userdata, errors.New("User is invalid")
|
||||
return Userdata, errors.New(fmt.Sprintf("User is invalid - no username found: %#v", Userdata))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1605,8 +1605,11 @@ func handleInfo(resp http.ResponseWriter, request *http.Request) {
|
||||
}
|
||||
|
||||
// This is a long check to see if an inactive admin can access the site
|
||||
parsedAdmin := "false"
|
||||
if !userInfo.Active {
|
||||
if userInfo.Role == "admin" {
|
||||
parsedAdmin = "true"
|
||||
|
||||
ctx := context.Background()
|
||||
q := datastore.NewQuery("Users")
|
||||
var users []User
|
||||
@@ -1672,7 +1675,14 @@ func handleInfo(resp http.ResponseWriter, request *http.Request) {
|
||||
Expires: expiration,
|
||||
})
|
||||
|
||||
returnData := fmt.Sprintf(`{"success": true, "cookies": [{"key": "session_token", "value": "%s", "expiration": %d}]}`, userInfo.Session, expiration.Unix())
|
||||
returnData := fmt.Sprintf(`
|
||||
{
|
||||
"success": true,
|
||||
"admin": %s,
|
||||
"orgs": [{"name": "Shuffle", "id": "123", "role": "admin"}],
|
||||
"selected_org": {"name": "Shuffle", "id": "123", "role": "admin"},
|
||||
"cookies": [{"key": "session_token", "value": "%s", "expiration": %d}]
|
||||
}`, parsedAdmin, userInfo.Session, expiration.Unix())
|
||||
|
||||
resp.WriteHeader(200)
|
||||
resp.Write([]byte(returnData))
|
||||
@@ -6134,7 +6144,7 @@ func handleAppHotload(location string) error {
|
||||
}
|
||||
|
||||
//log.Printf("Reading app folder: %#v", dir)
|
||||
err = iterateAppGithubFolders(fs, dir, "", "")
|
||||
err = iterateAppGithubFolders(fs, dir, "", "", false)
|
||||
if err != nil {
|
||||
log.Printf("Err: %s", err)
|
||||
return err
|
||||
@@ -6345,7 +6355,7 @@ func runInit(ctx context.Context) {
|
||||
//iterateAppGithubFolders(fs, dir, "", "testing")
|
||||
|
||||
// FIXME: Get all the apps?
|
||||
iterateAppGithubFolders(fs, dir, "", "")
|
||||
iterateAppGithubFolders(fs, dir, "", "", false)
|
||||
|
||||
// Hotloads locally
|
||||
location := os.Getenv("APP_HOTLOAD_FOLDER")
|
||||
|
||||
@@ -94,6 +94,7 @@ type AuthenticationUsage struct {
|
||||
}
|
||||
|
||||
// An app inside Shuffle
|
||||
// Source string `json:"source" datastore:"soure" yaml:"source"` - downloadlocation
|
||||
type WorkflowApp struct {
|
||||
Name string `json:"name" yaml:"name" required:true datastore:"name"`
|
||||
IsValid bool `json:"is_valid" yaml:"is_valid" required:true datastore:"is_valid"`
|
||||
@@ -4224,6 +4225,7 @@ func loadSpecificApps(resp http.ResponseWriter, request *http.Request) {
|
||||
URL string `json:"url"`
|
||||
Field1 string `json:"field_1"`
|
||||
Field2 string `json:"field_2"`
|
||||
ForceUpdate bool `json:"force_update"`
|
||||
}
|
||||
//log.Printf("Body: %s", string(body))
|
||||
|
||||
@@ -4265,7 +4267,13 @@ func loadSpecificApps(resp http.ResponseWriter, request *http.Request) {
|
||||
log.Printf("FAiled reading folder: %s", err)
|
||||
}
|
||||
_ = r
|
||||
iterateAppGithubFolders(fs, dir, "", "")
|
||||
|
||||
if tmpBody.ForceUpdate {
|
||||
log.Printf("Running with force update!")
|
||||
} else {
|
||||
log.Printf("Updating apps with updates")
|
||||
}
|
||||
iterateAppGithubFolders(fs, dir, "", "", tmpBody.ForceUpdate)
|
||||
|
||||
} else if strings.Contains(tmpBody.URL, "s3") {
|
||||
//https://docs.aws.amazon.com/sdk-for-go/api/service/s3/
|
||||
@@ -4490,8 +4498,13 @@ func iterateWorkflowGithubFolders(fs billy.Filesystem, dir []os.FileInfo, extra
|
||||
}
|
||||
|
||||
// Onlyname is used to
|
||||
func iterateAppGithubFolders(fs billy.Filesystem, dir []os.FileInfo, extra string, onlyname string) error {
|
||||
func iterateAppGithubFolders(fs billy.Filesystem, dir []os.FileInfo, extra string, onlyname string, forceUpdate bool) error {
|
||||
var err error
|
||||
|
||||
allapps := []WorkflowApp{}
|
||||
|
||||
// It's here to prevent getting them in every iteration
|
||||
ctx := context.Background()
|
||||
for _, file := range dir {
|
||||
if len(onlyname) > 0 && file.Name() != onlyname {
|
||||
continue
|
||||
@@ -4508,7 +4521,7 @@ func iterateAppGithubFolders(fs billy.Filesystem, dir []os.FileInfo, extra strin
|
||||
}
|
||||
|
||||
// Go routine? Hmm, this can be super quick I guess
|
||||
err = iterateAppGithubFolders(fs, dir, tmpExtra, "")
|
||||
err = iterateAppGithubFolders(fs, dir, tmpExtra, "", forceUpdate)
|
||||
if err != nil {
|
||||
log.Printf("Error reading folder: %s", err)
|
||||
continue
|
||||
@@ -4591,12 +4604,12 @@ func iterateAppGithubFolders(fs billy.Filesystem, dir []os.FileInfo, extra strin
|
||||
fmt.Sprintf("%s:%s_%s", baseDockerName, newName, workflowapp.AppVersion),
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
allapps, err := getAllWorkflowApps(ctx)
|
||||
if len(allapps) == 0 {
|
||||
allapps, err = getAllWorkflowApps(ctx)
|
||||
if err != nil {
|
||||
log.Printf("Failed getting apps to verify: %s", err)
|
||||
continue
|
||||
//return err
|
||||
}
|
||||
}
|
||||
|
||||
// Make an option to override existing apps?
|
||||
@@ -4607,7 +4620,7 @@ func iterateAppGithubFolders(fs billy.Filesystem, dir []os.FileInfo, extra strin
|
||||
if app.Name == workflowapp.Name && app.AppVersion == workflowapp.AppVersion {
|
||||
// FIXME: Check if there's a new APP_SDK as well.
|
||||
// Skip this check if app_sdk is new.
|
||||
if app.Hash == md5 && app.Hash != "" {
|
||||
if app.Hash == md5 && app.Hash != "" && !forceUpdate {
|
||||
skip = true
|
||||
break
|
||||
}
|
||||
@@ -4617,7 +4630,7 @@ func iterateAppGithubFolders(fs billy.Filesystem, dir []os.FileInfo, extra strin
|
||||
}
|
||||
}
|
||||
|
||||
if skip {
|
||||
if skip && !forceUpdate {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -4677,6 +4690,7 @@ func iterateAppGithubFolders(fs billy.Filesystem, dir []os.FileInfo, extra strin
|
||||
|
||||
if len(removeApps) > 0 {
|
||||
for _, item := range removeApps {
|
||||
log.Printf("Removing duplicate: %s", item)
|
||||
err = DeleteKey(ctx, "workflowapp", item)
|
||||
if err != nil {
|
||||
log.Printf("Failed deleting %s", item)
|
||||
|
||||
Generated
+13
-13
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "shuffler",
|
||||
"version": "0.3.0",
|
||||
"version": "0.6.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
@@ -3733,9 +3733,9 @@
|
||||
"integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA=="
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "14.0.13",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.13.tgz",
|
||||
"integrity": "sha512-rouEWBImiRaSJsVA+ITTFM6ZxibuAlTuNOCyxVbwreu6k6+ujs7DfnU9o+PShFhET78pMBl3eH+AGSI5eOTkPA=="
|
||||
"version": "14.0.24",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.24.tgz",
|
||||
"integrity": "sha512-btt/oNOiDWcSuI721MdL8VQGnjsKjlTMdrKyTcLCKeQp/n4AAMFJ961wMbp+09y8WuGPClDEv07RIItdXKIXAA=="
|
||||
},
|
||||
"@types/object-assign": {
|
||||
"version": "4.0.30",
|
||||
@@ -3748,9 +3748,9 @@
|
||||
"integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA=="
|
||||
},
|
||||
"@types/prop-types": {
|
||||
"version": "15.7.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.1.tgz",
|
||||
"integrity": "sha512-CFzn9idOEpHrgdw8JsoTkaDDyRWk1jrzIV8djzcgpq0y9tG4B4lFT+Nxh52DVpDXV+n4+NPNv7M1Dj5uMp6XFg=="
|
||||
"version": "15.7.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.3.tgz",
|
||||
"integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw=="
|
||||
},
|
||||
"@types/q": {
|
||||
"version": "1.5.4",
|
||||
@@ -3758,9 +3758,9 @@
|
||||
"integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug=="
|
||||
},
|
||||
"@types/react": {
|
||||
"version": "16.8.20",
|
||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-16.8.20.tgz",
|
||||
"integrity": "sha512-ZLmI+ubSJpfUIlQuULDDrdyuFQORBuGOvNnMue8HeA0GVrAJbWtZQhcBvnBPNRBI/GrfSfrKPFhthzC2SLEtLQ==",
|
||||
"version": "16.9.43",
|
||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.43.tgz",
|
||||
"integrity": "sha512-PxshAFcnJqIWYpJbLPriClH53Z2WlJcVZE+NP2etUtWQs2s7yIMj3/LDKZT/5CHJ/F62iyjVCDu2H3jHEXIxSg==",
|
||||
"requires": {
|
||||
"@types/prop-types": "*",
|
||||
"csstype": "^2.2.0"
|
||||
@@ -11944,9 +11944,9 @@
|
||||
}
|
||||
},
|
||||
"lodash": {
|
||||
"version": "4.17.15",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
|
||||
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
|
||||
"version": "4.17.19",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz",
|
||||
"integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ=="
|
||||
},
|
||||
"lodash._reinterpolate": {
|
||||
"version": "3.0.0",
|
||||
|
||||
@@ -1,169 +0,0 @@
|
||||
import React, {useState, useEffect} from 'react';
|
||||
|
||||
import {Route} from 'react-router';
|
||||
import {BrowserRouter} from 'react-router-dom';
|
||||
import { CookiesProvider } from 'react-cookie';
|
||||
import { useCookies } from 'react-cookie';
|
||||
|
||||
import EditSchedule from "./EditSchedule";
|
||||
import Schedules from "./Schedules";
|
||||
import Webhooks from "./Webhooks";
|
||||
import Workflows from "./Workflows";
|
||||
import EditWebhook from "./EditWebhook";
|
||||
import AngularWorkflow from "./AngularWorkflow";
|
||||
import ForgotPassword from "./ForgotPassword";
|
||||
import ForgotPasswordLink from "./ForgotPasswordLink";
|
||||
|
||||
import Header from './Header';
|
||||
import Apps from './Apps';
|
||||
import AppCreator from './AppCreator';
|
||||
import Contact from './Contact';
|
||||
import Oauth2 from './Oauth2';
|
||||
import About from "./About";
|
||||
import Post from "./Post";
|
||||
import Dashboard from "./Dashboard";
|
||||
import AdminSetup from "./AdminSetup";
|
||||
import Admin from "./Admin";
|
||||
import Docs from "./Docs";
|
||||
import RegisterLink from "./RegisterLink";
|
||||
import LandingPage from "./Landingpage";
|
||||
import LandingPageNew from "./LandingpageNew";
|
||||
import LoginPage from "./LoginPage";
|
||||
import SettingsPage from "./SettingsPage";
|
||||
|
||||
import MuiThemeProvider from '@material-ui/core/styles/MuiThemeProvider';
|
||||
import { createMuiTheme } from '@material-ui/core/styles';
|
||||
|
||||
import AlertTemplate from "react-alert-template-basic";
|
||||
import { positions, Provider } from "react-alert";
|
||||
|
||||
// Production - backend proxy forwarding in nginx
|
||||
var globalUrl = window.location.origin
|
||||
|
||||
// CORS used for testing purposes. Should only happen with specific port and http
|
||||
if (window.location.protocol == "http:" && window.location.port === "3000") {
|
||||
globalUrl = "http://localhost:5001"
|
||||
}
|
||||
|
||||
const surfaceColor = "#27292D"
|
||||
const inputColor = "#383B40"
|
||||
|
||||
const theme = createMuiTheme({
|
||||
palette: {
|
||||
primary: {
|
||||
main: "#f85a3e"
|
||||
},
|
||||
secondary: {
|
||||
main: '#e8eaf6',
|
||||
},
|
||||
},
|
||||
typography: {
|
||||
useNextVariants: true
|
||||
},
|
||||
overrides: {
|
||||
MuiMenu: {
|
||||
list: {
|
||||
backgroundColor: inputColor,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
// FIXME - set client side cookies
|
||||
const App = (message, props) => {
|
||||
const [userdata, setUserData] = useState({});
|
||||
//const [homePage, ] = useState(true);
|
||||
const [cookies, setCookie, removeCookie] = useCookies([]);
|
||||
const [isLoggedIn, setIsLoggedIn] = useState(false);
|
||||
const [dataset, setDataset] = useState(false);
|
||||
const [isLoaded, setIsLoaded] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (dataset === false) {
|
||||
checkLogin()
|
||||
setDataset(true)
|
||||
}})
|
||||
|
||||
if (isLoaded && !isLoggedIn && (!window.location.pathname.startsWith("/login") && (!window.location.pathname.startsWith("/docs") && (!window.location.pathname.startsWith("/adminsetup"))))) {
|
||||
window.location = "/login"
|
||||
}
|
||||
|
||||
const checkLogin = () => {
|
||||
var baseurl = globalUrl
|
||||
fetch(baseurl+"/api/v1/users/getinfo", {
|
||||
credentials: "include",
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(responseJson => {
|
||||
if (responseJson.success === true) {
|
||||
setUserData(responseJson)
|
||||
setIsLoggedIn(true)
|
||||
|
||||
// Updating cookie every request
|
||||
for (var key in responseJson["cookies"]) {
|
||||
setCookie(responseJson["cookies"][key].key, responseJson["cookies"][key].value, {path: "/"})
|
||||
}
|
||||
}
|
||||
setIsLoaded(true)
|
||||
})
|
||||
.catch(error => {
|
||||
setIsLoaded(true)
|
||||
});
|
||||
}
|
||||
|
||||
// Dumb for content load (per now), but good for making the site not suddenly reload parts (ajax thingies)
|
||||
|
||||
const options = {
|
||||
timeout: 5000,
|
||||
position: positions.BOTTOM_CENTER
|
||||
};
|
||||
|
||||
const includedData = window.location.pathname === "/home" || window.location.pathname === "/features" ?
|
||||
<div>
|
||||
<Route exact path="/home" render={props => <LandingPageNew isLoaded={isLoaded} {...props} /> } />
|
||||
</div> :
|
||||
<div style={{backgroundColor: "#1F2023", color: "rgba(255, 255, 255, 0.65)", minHeight: "100vh"}}>
|
||||
<Header removeCookie={removeCookie} isLoaded={isLoaded} globalUrl={globalUrl} setIsLoggedIn={setIsLoggedIn} isLoggedIn={isLoggedIn} surfaceColor={surfaceColor} inputColor={inputColor}{...props} />
|
||||
<Route exact path="/oauth2" render={props => <Oauth2 isLoaded={isLoaded} globalUrl={globalUrl} surfaceColor={surfaceColor} inputColor={inputColor}{...props} /> } />
|
||||
<Route exact path="/contact" render={props => <Contact isLoaded={isLoaded} globalUrl={globalUrl} surfaceColor={surfaceColor} inputColor={inputColor} {...props} /> } />
|
||||
<Route exact path="/login" render={props => <LoginPage isLoggedIn={isLoggedIn} setIsLoggedIn={setIsLoggedIn} register={true} isLoaded={isLoaded} globalUrl={globalUrl} setCookie={setCookie} cookies={cookies} surfaceColor={surfaceColor} inputColor={inputColor} {...props} /> } />
|
||||
<Route exact path="/admin" render={props => <Admin isLoggedIn={isLoggedIn} setIsLoggedIn={setIsLoggedIn} register={true} isLoaded={isLoaded} globalUrl={globalUrl} setCookie={setCookie} cookies={cookies} surfaceColor={surfaceColor} inputColor={inputColor} {...props} /> } />
|
||||
<Route exact path="/settings" render={props => <SettingsPage isLoaded={isLoaded} userdata={userdata} globalUrl={globalUrl} surfaceColor={surfaceColor} inputColor={inputColor} {...props} /> } />
|
||||
<Route exact path="/AdminSetup" render={props => <AdminSetup isLoaded={isLoaded} userdata={userdata} globalUrl={globalUrl} surfaceColor={surfaceColor} inputColor={inputColor} {...props} /> } />
|
||||
<Route exact path="/webhooks" render={props => <Webhooks isLoaded={isLoaded} globalUrl={globalUrl} {...props} /> } />
|
||||
<Route exact path="/webhooks/:key" render={props => <EditWebhook isLoaded={isLoaded} globalUrl={globalUrl} surfaceColor={surfaceColor} inputColor={inputColor} {...props} /> } />
|
||||
<Route exact path="/schedules" render={props => <Schedules globalUrl={globalUrl} surfaceColor={surfaceColor} inputColor={inputColor} {...props} /> } />
|
||||
<Route exact path="/dashboard" render={props => <Dashboard isLoaded={isLoaded} isLoggedIn={isLoggedIn} globalUrl={globalUrl} surfaceColor={surfaceColor} inputColor={inputColor} {...props} /> } />
|
||||
<Route exact path="/apps" render={props => <Apps isLoaded={isLoaded} isLoggedIn={isLoggedIn} globalUrl={globalUrl} surfaceColor={surfaceColor} inputColor={inputColor} {...props} /> } />
|
||||
<Route exact path="/apps/new" render={props => <AppCreator isLoaded={isLoaded} isLoggedIn={isLoggedIn} globalUrl={globalUrl} surfaceColor={surfaceColor} inputColor={inputColor} {...props} /> } />
|
||||
<Route exact path="/apps/edit/:appid" render={props => <AppCreator isLoaded={isLoaded} isLoggedIn={isLoggedIn} globalUrl={globalUrl} surfaceColor={surfaceColor} inputColor={inputColor} {...props} /> } />
|
||||
<Route exact path="/schedules/:key" render={props => <EditSchedule globalUrl={globalUrl} surfaceColor={surfaceColor} inputColor={inputColor} {...props} /> } />
|
||||
<Route exact path="/workflows" render={props => <Workflows isLoaded={isLoaded} isLoggedIn={isLoggedIn} globalUrl={globalUrl} cookies={cookies} surfaceColor={surfaceColor} inputColor={inputColor}{...props} /> } />
|
||||
<Route exact path="/workflows/:key" render={props => <AngularWorkflow globalUrl={globalUrl} isLoaded={isLoaded} isLoggedIn={isLoggedIn} surfaceColor={surfaceColor} inputColor={inputColor}{...props} /> } />
|
||||
<Route exact path="/docs/:key" render={props => <Docs isLoaded={isLoaded} globalUrl={globalUrl} surfaceColor={surfaceColor} inputColor={inputColor}{...props} /> } />
|
||||
<Route exact path="/docs" render={props => {window.location.pathname = "/docs/about"}} />
|
||||
<Route exact path="/" render={props => {window.location.pathname = "/login"}} />
|
||||
</div>
|
||||
|
||||
// <div style={{backgroundColor: "rgba(21, 32, 43, 1)", color: "#fffff", minHeight: "100vh"}}>
|
||||
// backgroundColor: "#213243",
|
||||
// This is a mess hahahah
|
||||
return (
|
||||
<MuiThemeProvider theme={theme}>
|
||||
<CookiesProvider>
|
||||
<BrowserRouter>
|
||||
<Provider template={AlertTemplate} {...options}>
|
||||
{includedData}
|
||||
</Provider>
|
||||
</BrowserRouter>
|
||||
</CookiesProvider>
|
||||
</MuiThemeProvider>
|
||||
);
|
||||
};
|
||||
|
||||
export default App;
|
||||
|
||||
@@ -0,0 +1,163 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
|
||||
import { Route } from 'react-router';
|
||||
import { BrowserRouter } from 'react-router-dom';
|
||||
import { CookiesProvider } from 'react-cookie';
|
||||
import { useCookies } from 'react-cookie';
|
||||
|
||||
import EditSchedule from "./views/EditSchedule";
|
||||
import Schedules from "./views/Schedules";
|
||||
import Webhooks from "./views/Webhooks";
|
||||
import Workflows from "./views/Workflows";
|
||||
import EditWebhook from "./views/EditWebhook";
|
||||
import AngularWorkflow from "./views/AngularWorkflow";
|
||||
|
||||
import Header from './components/Header';
|
||||
import Apps from './views/Apps';
|
||||
import AppCreator from './views/AppCreator';
|
||||
import Contact from './views/Contact';
|
||||
import Oauth2 from './views/Oauth2';
|
||||
|
||||
import Dashboard from "./views/Dashboard";
|
||||
import AdminSetup from "./views/AdminSetup";
|
||||
import Admin from "./views/Admin";
|
||||
import Docs from "./views/Docs";
|
||||
|
||||
import LandingPageNew from "./views/LandingpageNew";
|
||||
import LoginPage from "./views/LoginPage";
|
||||
import SettingsPage from "./views/SettingsPage";
|
||||
|
||||
import { createMuiTheme, MuiThemeProvider } from '@material-ui/core/styles';
|
||||
|
||||
import AlertTemplate from "react-alert-template-basic";
|
||||
import { positions, Provider } from "react-alert";
|
||||
|
||||
// Production - backend proxy forwarding in nginx
|
||||
var globalUrl = window.location.origin
|
||||
|
||||
// CORS used for testing purposes. Should only happen with specific port and http
|
||||
if (window.location.protocol == "http:" && window.location.port === "3000") {
|
||||
globalUrl = "http://localhost:5001"
|
||||
}
|
||||
|
||||
const theme = createMuiTheme({
|
||||
palette: {
|
||||
primary: {
|
||||
main: "#f85a3e"
|
||||
},
|
||||
secondary: {
|
||||
main: '#e8eaf6',
|
||||
},
|
||||
surfaceColor: "#27292d",
|
||||
inputColor: "#383B40"
|
||||
},
|
||||
typography: {
|
||||
useNextVariants: true
|
||||
},
|
||||
overrides: {
|
||||
MuiMenu: {
|
||||
list: {
|
||||
backgroundColor: "#383B40",
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
// FIXME - set client side cookies
|
||||
const App = (message, props) => {
|
||||
const [userdata, setUserData] = useState({});
|
||||
//const [homePage, ] = useState(true);
|
||||
const [cookies, setCookie, removeCookie] = useCookies([]);
|
||||
const [isLoggedIn, setIsLoggedIn] = useState(false);
|
||||
const [dataset, setDataset] = useState(false);
|
||||
const [isLoaded, setIsLoaded] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (dataset === false) {
|
||||
checkLogin()
|
||||
setDataset(true)
|
||||
}
|
||||
})
|
||||
|
||||
if (isLoaded && !isLoggedIn && (!window.location.pathname.startsWith("/login") && (!window.location.pathname.startsWith("/docs") && (!window.location.pathname.startsWith("/adminsetup"))))) {
|
||||
window.location = "/login"
|
||||
}
|
||||
|
||||
const checkLogin = () => {
|
||||
var baseurl = globalUrl
|
||||
fetch(baseurl + "/api/v1/users/getinfo", {
|
||||
credentials: "include",
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(responseJson => {
|
||||
if (responseJson.success === true) {
|
||||
setUserData(responseJson)
|
||||
setIsLoggedIn(true)
|
||||
|
||||
// Updating cookie every request
|
||||
for (var key in responseJson["cookies"]) {
|
||||
setCookie(responseJson["cookies"][key].key, responseJson["cookies"][key].value, { path: "/" })
|
||||
}
|
||||
}
|
||||
setIsLoaded(true)
|
||||
})
|
||||
.catch(error => {
|
||||
setIsLoaded(true)
|
||||
});
|
||||
}
|
||||
|
||||
// Dumb for content load (per now), but good for making the site not suddenly reload parts (ajax thingies)
|
||||
|
||||
const options = {
|
||||
timeout: 5000,
|
||||
position: positions.BOTTOM_CENTER
|
||||
};
|
||||
|
||||
const includedData = window.location.pathname === "/home" || window.location.pathname === "/features" ?
|
||||
<div>
|
||||
<Route exact path="/home" render={props => <LandingPageNew isLoaded={isLoaded} {...props} />} />
|
||||
</div> :
|
||||
<div style={{ backgroundColor: "#1F2023", color: "rgba(255, 255, 255, 0.65)", minHeight: "100vh" }}>
|
||||
<Header removeCookie={removeCookie} isLoaded={isLoaded} globalUrl={globalUrl} setIsLoggedIn={setIsLoggedIn} isLoggedIn={isLoggedIn} userdata={userdata} {...props} />
|
||||
<Route exact path="/oauth2" render={props => <Oauth2 isLoaded={isLoaded} globalUrl={globalUrl} {...props} />} />
|
||||
<Route exact path="/contact" render={props => <Contact isLoaded={isLoaded} globalUrl={globalUrl} {...props} />} />
|
||||
<Route exact path="/login" render={props => <LoginPage isLoggedIn={isLoggedIn} setIsLoggedIn={setIsLoggedIn} register={true} isLoaded={isLoaded} globalUrl={globalUrl} setCookie={setCookie} cookies={cookies} {...props} />} />
|
||||
<Route exact path="/admin" render={props => <Admin isLoggedIn={isLoggedIn} setIsLoggedIn={setIsLoggedIn} register={true} isLoaded={isLoaded} globalUrl={globalUrl} setCookie={setCookie} cookies={cookies} {...props} />} />
|
||||
<Route exact path="/settings" render={props => <SettingsPage isLoaded={isLoaded} userdata={userdata} globalUrl={globalUrl} {...props} />} />
|
||||
<Route exact path="/AdminSetup" render={props => <AdminSetup isLoaded={isLoaded} userdata={userdata} globalUrl={globalUrl} {...props} />} />
|
||||
<Route exact path="/webhooks" render={props => <Webhooks isLoaded={isLoaded} globalUrl={globalUrl} {...props} />} />
|
||||
<Route exact path="/webhooks/:key" render={props => <EditWebhook isLoaded={isLoaded} globalUrl={globalUrl} {...props} />} />
|
||||
<Route exact path="/schedules" render={props => <Schedules globalUrl={globalUrl} {...props} />} />
|
||||
<Route exact path="/dashboard" render={props => <Dashboard isLoaded={isLoaded} isLoggedIn={isLoggedIn} globalUrl={globalUrl} {...props} />} />
|
||||
<Route exact path="/apps" render={props => <Apps isLoaded={isLoaded} isLoggedIn={isLoggedIn} globalUrl={globalUrl} {...props} />} />
|
||||
<Route exact path="/apps/new" render={props => <AppCreator isLoaded={isLoaded} isLoggedIn={isLoggedIn} globalUrl={globalUrl} {...props} />} />
|
||||
<Route exact path="/apps/edit/:appid" render={props => <AppCreator isLoaded={isLoaded} isLoggedIn={isLoggedIn} globalUrl={globalUrl} {...props} />} />
|
||||
<Route exact path="/schedules/:key" render={props => <EditSchedule globalUrl={globalUrl} {...props} />} />
|
||||
<Route exact path="/workflows" render={props => <Workflows isLoaded={isLoaded} isLoggedIn={isLoggedIn} globalUrl={globalUrl} cookies={cookies} {...props} />} />
|
||||
<Route exact path="/workflows/:key" render={props => <AngularWorkflow globalUrl={globalUrl} isLoaded={isLoaded} isLoggedIn={isLoggedIn} {...props} />} />
|
||||
<Route exact path="/docs/:key" render={props => <Docs isLoaded={isLoaded} globalUrl={globalUrl} {...props} />} />
|
||||
<Route exact path="/docs" render={props => { window.location.pathname = "/docs/about" }} />
|
||||
<Route exact path="/" render={props => { window.location.pathname = "/login" }} />
|
||||
</div>
|
||||
|
||||
// <div style={{backgroundColor: "rgba(21, 32, 43, 1)", color: "#fffff", minHeight: "100vh"}}>
|
||||
// backgroundColor: "#213243",
|
||||
// This is a mess hahahah
|
||||
return (
|
||||
<MuiThemeProvider theme={theme}>
|
||||
<CookiesProvider>
|
||||
<BrowserRouter>
|
||||
<Provider template={AlertTemplate} {...options}>
|
||||
{includedData}
|
||||
</Provider>
|
||||
</BrowserRouter>
|
||||
</CookiesProvider>
|
||||
</MuiThemeProvider>
|
||||
);
|
||||
};
|
||||
|
||||
export default App;
|
||||
@@ -1,25 +0,0 @@
|
||||
import React from 'react';
|
||||
|
||||
const Flows = () => {
|
||||
return (
|
||||
<div>
|
||||
<h1>Flows</h1>
|
||||
|
||||
<p>
|
||||
Built to suit any organization
|
||||
</p>
|
||||
|
||||
<p>
|
||||
WAT
|
||||
</p>
|
||||
|
||||
<p>
|
||||
</p>
|
||||
|
||||
<p></p>
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Flows;
|
||||
@@ -1,25 +0,0 @@
|
||||
import React from 'react';
|
||||
|
||||
const Hooks = () => {
|
||||
return (
|
||||
<div>
|
||||
<h1>Hooks</h1>
|
||||
|
||||
<p>
|
||||
Built to suit any organization
|
||||
</p>
|
||||
|
||||
<p>
|
||||
WAT
|
||||
</p>
|
||||
|
||||
<p>
|
||||
</p>
|
||||
|
||||
<p></p>
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Hooks;
|
||||
@@ -1,25 +0,0 @@
|
||||
import React from 'react';
|
||||
|
||||
const Schedules = () => {
|
||||
return (
|
||||
<div>
|
||||
<h1>Schedules</h1>
|
||||
|
||||
<p>
|
||||
Built to suit any organization
|
||||
</p>
|
||||
|
||||
<p>
|
||||
WAT
|
||||
</p>
|
||||
|
||||
<p>
|
||||
</p>
|
||||
|
||||
<p></p>
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Schedules;
|
||||
@@ -5,19 +5,22 @@ import {Link} from 'react-router-dom';
|
||||
|
||||
import List from '@material-ui/core/List';
|
||||
import ListItem from '@material-ui/core/ListItem';
|
||||
|
||||
import MenuItem from '@material-ui/core/MenuItem';
|
||||
import Select from '@material-ui/core/Select';
|
||||
import Button from '@material-ui/core/Button';
|
||||
import HomeIcon from '@material-ui/icons/Home';
|
||||
import PolymerIcon from '@material-ui/icons/Polymer';
|
||||
import AppsIcon from '@material-ui/icons/Apps';
|
||||
import DescriptionIcon from '@material-ui/icons/Description';
|
||||
import Grid from '@material-ui/core/Grid';
|
||||
import { useTheme } from '@material-ui/core/styles';
|
||||
|
||||
const hoverColor = "#f85a3e"
|
||||
const hoverOutColor = "#e8eaf6"
|
||||
|
||||
const Header = props => {
|
||||
const { globalUrl, isLoggedIn, removeCookie, homePage, isLoaded } = props;
|
||||
const { globalUrl, isLoggedIn, removeCookie, homePage, isLoaded, userdata } = props;
|
||||
const theme = useTheme();
|
||||
|
||||
const [HomeHoverColor, setHomeHoverColor] = useState(hoverOutColor);
|
||||
const [SoarHoverColor, setSoarHoverColor] = useState(hoverOutColor);
|
||||
@@ -192,6 +195,32 @@ const Header = props => {
|
||||
</Button>
|
||||
</Link>
|
||||
</ListItem>
|
||||
{userdata === undefined || userdata.orgs.length <= 1 ? null :
|
||||
<ListItem>
|
||||
<Select
|
||||
SelectDisplayProps={{
|
||||
style: {
|
||||
marginLeft: 10,
|
||||
}
|
||||
}}
|
||||
value={userdata.selected_org}
|
||||
fullWidth
|
||||
style={{backgroundColor: theme.palette.surfaceColor, color: "white", height: "50px"}}
|
||||
onChange={(e) => {
|
||||
console.log("SET ORG TO ", e.target.value)
|
||||
}}
|
||||
>
|
||||
{userdata.orgs.map(data => {
|
||||
return (
|
||||
<MenuItem key={data.id} style={{backgroundColor: theme.palette.inputColor, color: "white"}} value={data}>
|
||||
{data.name}
|
||||
</MenuItem>
|
||||
)
|
||||
})}
|
||||
</Select>
|
||||
</ListItem>
|
||||
}
|
||||
|
||||
</List>
|
||||
</div>
|
||||
</div>
|
||||
@@ -287,7 +316,7 @@ const Header = props => {
|
||||
<div>
|
||||
{loadedCheck}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
)
|
||||
}
|
||||
|
||||
export default Header;
|
||||
@@ -2,6 +2,8 @@ import React, { useEffect} from 'react';
|
||||
|
||||
import {Link} from 'react-router-dom';
|
||||
import Paper from '@material-ui/core/Paper';
|
||||
import FormControlLabel from '@material-ui/core/FormControlLabel';
|
||||
import Switch from '@material-ui/core/Switch';
|
||||
import Select from '@material-ui/core/Select';
|
||||
import MenuItem from '@material-ui/core/MenuItem';
|
||||
import List from '@material-ui/core/List';
|
||||
@@ -16,17 +18,21 @@ import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction';
|
||||
|
||||
import { useAlert } from "react-alert";
|
||||
|
||||
import Dialog from '@material-ui/core/Dialog';
|
||||
import DialogTitle from '@material-ui/core/DialogTitle';
|
||||
import DialogActions from '@material-ui/core/DialogActions';
|
||||
import DialogContent from '@material-ui/core/DialogContent';
|
||||
import { Dialog, DialogTitle, DialogActions, DialogContent } from '@material-ui/core';
|
||||
import { useTheme } from '@material-ui/core/styles';
|
||||
|
||||
import CachedIcon from '@material-ui/icons/Cached';
|
||||
import AccessibilityNewIcon from '@material-ui/icons/AccessibilityNew';
|
||||
import LockIcon from '@material-ui/icons/Lock';
|
||||
import EcoIcon from '@material-ui/icons/Eco';
|
||||
import ScheduleIcon from '@material-ui/icons/Schedule';
|
||||
import CloudIcon from '@material-ui/icons/Cloud';
|
||||
import BusinessIcon from '@material-ui/icons/Business';
|
||||
|
||||
const surfaceColor = "#27292D"
|
||||
const inputColor = "#383B40"
|
||||
const Admin = (props) => {
|
||||
const { globalUrl, } = props;
|
||||
const { globalUrl } = props;
|
||||
|
||||
const theme = useTheme();
|
||||
const [firstRequest, setFirstRequest] = React.useState(true);
|
||||
const [modalUser, setModalUser] = React.useState({});
|
||||
const [modalOpen, setModalOpen] = React.useState(false);
|
||||
@@ -106,6 +112,7 @@ const Admin = (props) => {
|
||||
const onPasswordChange = () => {
|
||||
const data = { "username": selectedUser.username, "newpassword": newPassword }
|
||||
const url = globalUrl + '/api/v1/users/passwordchange';
|
||||
|
||||
fetch(url, {
|
||||
mode: 'cors',
|
||||
method: 'POST',
|
||||
@@ -378,7 +385,7 @@ const Admin = (props) => {
|
||||
maxWidth: 1250,
|
||||
margin: "auto",
|
||||
color: "white",
|
||||
backgroundColor: surfaceColor,
|
||||
backgroundColor: theme.palette.surfaceColor,
|
||||
marginBottom: 10,
|
||||
padding: 20,
|
||||
}
|
||||
@@ -464,7 +471,7 @@ const Admin = (props) => {
|
||||
onClose={() => { setSelectedAuthenticationModalOpen(false) }}
|
||||
PaperProps={{
|
||||
style: {
|
||||
backgroundColor: surfaceColor,
|
||||
backgroundColor: theme.palette.surfaceColor,
|
||||
color: "white",
|
||||
minWidth: "800px",
|
||||
minHeight: "320px",
|
||||
@@ -475,7 +482,7 @@ const Admin = (props) => {
|
||||
<DialogContent>
|
||||
<div style={{ display: "flex" }}>
|
||||
<TextField
|
||||
style={{backgroundColor: inputColor, flex: 3}}
|
||||
style={{ backgroundColor: theme.palette.inputColor, flex: 3 }}
|
||||
InputProps={{
|
||||
style: {
|
||||
height: 50,
|
||||
@@ -502,7 +509,7 @@ const Admin = (props) => {
|
||||
Submit
|
||||
</Button>
|
||||
</div>
|
||||
<Divider style={{marginTop: 20, marginBottom: 20, backgroundColor: inputColor}}/>
|
||||
<Divider style={{ marginTop: 20, marginBottom: 20, backgroundColor: theme.palette.inputColor }} />
|
||||
<Button
|
||||
style={{}}
|
||||
variant="outlined"
|
||||
@@ -528,7 +535,7 @@ const Admin = (props) => {
|
||||
onClose={() => { setSelectedUserModalOpen(false) }}
|
||||
PaperProps={{
|
||||
style: {
|
||||
backgroundColor: surfaceColor,
|
||||
backgroundColor: theme.palette.surfaceColor,
|
||||
color: "white",
|
||||
minWidth: "800px",
|
||||
minHeight: "320px",
|
||||
@@ -539,7 +546,7 @@ const Admin = (props) => {
|
||||
<DialogContent>
|
||||
<div style={{ display: "flex" }}>
|
||||
<TextField
|
||||
style={{marginTop: 0, backgroundColor: inputColor, flex: 3}}
|
||||
style={{ marginTop: 0, backgroundColor: theme.palette.inputColor, flex: 3 }}
|
||||
InputProps={{
|
||||
style: {
|
||||
height: 50,
|
||||
@@ -566,7 +573,7 @@ const Admin = (props) => {
|
||||
Submit
|
||||
</Button>
|
||||
</div>
|
||||
<Divider style={{marginTop: 20, marginBottom: 20, backgroundColor: inputColor}}/>
|
||||
<Divider style={{ marginTop: 20, marginBottom: 20, backgroundColor: theme.palette.inputColor }} />
|
||||
<Button
|
||||
style={{}}
|
||||
variant="outlined"
|
||||
@@ -592,7 +599,7 @@ const Admin = (props) => {
|
||||
onClose={() => { setModalOpen(false) }}
|
||||
PaperProps={{
|
||||
style: {
|
||||
backgroundColor: surfaceColor,
|
||||
backgroundColor: theme.palette.surfaceColor,
|
||||
color: "white",
|
||||
minWidth: "800px",
|
||||
minHeight: "320px",
|
||||
@@ -608,7 +615,7 @@ const Admin = (props) => {
|
||||
Username
|
||||
<TextField
|
||||
color="primary"
|
||||
style={{backgroundColor: inputColor}}
|
||||
style={{ backgroundColor: theme.palette.inputColor }}
|
||||
autoFocus
|
||||
InputProps={{
|
||||
style: {
|
||||
@@ -629,7 +636,7 @@ const Admin = (props) => {
|
||||
Password
|
||||
<TextField
|
||||
color="primary"
|
||||
style={{backgroundColor: inputColor}}
|
||||
style={{ backgroundColor: theme.palette.inputColor }}
|
||||
InputProps={{
|
||||
style: {
|
||||
height: "50px",
|
||||
@@ -653,7 +660,7 @@ const Admin = (props) => {
|
||||
Environment Name
|
||||
<TextField
|
||||
color="primary"
|
||||
style={{backgroundColor: inputColor}}
|
||||
style={{ backgroundColor: theme.palette.inputColor }}
|
||||
autoFocus
|
||||
InputProps={{
|
||||
style: {
|
||||
@@ -705,7 +712,7 @@ const Admin = (props) => {
|
||||
>
|
||||
Add user
|
||||
</Button>
|
||||
<Divider style={{marginTop: 20, marginBottom: 20, backgroundColor: inputColor}}/>
|
||||
<Divider style={{ marginTop: 20, marginBottom: 20, backgroundColor: theme.palette.inputColor }} />
|
||||
<List>
|
||||
<ListItem>
|
||||
<ListItemText
|
||||
@@ -742,7 +749,7 @@ const Admin = (props) => {
|
||||
/>
|
||||
<ListItemText
|
||||
primary=
|
||||
<Select
|
||||
{<Select
|
||||
PaperProps={{
|
||||
style: {
|
||||
}
|
||||
@@ -758,15 +765,15 @@ const Admin = (props) => {
|
||||
console.log("VALUE: ", e.target.value)
|
||||
setUser(data.id, "role", e.target.value)
|
||||
}}
|
||||
style={{backgroundColor: surfaceColor, color: "white", height: "50px"}}
|
||||
style={{ backgroundColor: theme.palette.surfaceColor, color: "white", height: "50px" }}
|
||||
>
|
||||
<MenuItem style={{backgroundColor: inputColor, color: "white"}} value={"admin"}>
|
||||
<MenuItem style={{ backgroundColor: theme.palette.inputColor, color: "white" }} value={"admin"}>
|
||||
Admin
|
||||
</MenuItem>
|
||||
<MenuItem style={{backgroundColor: inputColor, color: "white"}} value={"user"}>
|
||||
<MenuItem style={{ backgroundColor: theme.palette.inputColor, color: "white" }} value={"user"}>
|
||||
User
|
||||
</MenuItem>
|
||||
</Select>
|
||||
</Select>}
|
||||
style = {{ minWidth: 150, maxWidth: 150}}
|
||||
/>
|
||||
<ListItemText
|
||||
@@ -799,7 +806,7 @@ const Admin = (props) => {
|
||||
<h2 style={{display: "inline",}}>Schedules</h2>
|
||||
<span style={{marginLeft: 25}}>Schedules used in Workflows. Makes locating and control easier.</span>
|
||||
</div>
|
||||
<Divider style={{marginTop: 20, marginBottom: 20, backgroundColor: inputColor}}/>
|
||||
<Divider style={{marginTop: 20, marginBottom: 20, backgroundColor: theme.palette.inputColor}}/>
|
||||
<List>
|
||||
<ListItem>
|
||||
<ListItemText
|
||||
@@ -848,7 +855,7 @@ const Admin = (props) => {
|
||||
<h2 style={{display: "inline",}}>App Authentication</h2>
|
||||
<span style={{marginLeft: 25}}>Control the authentication options for individual apps. <b>Actions can be destructive!</b></span>
|
||||
</div>
|
||||
<Divider style={{marginTop: 20, marginBottom: 20, backgroundColor: inputColor}}/>
|
||||
<Divider style={{marginTop: 20, marginBottom: 20, backgroundColor: theme.palette.inputColor}}/>
|
||||
<List>
|
||||
<ListItem>
|
||||
<ListItemText
|
||||
@@ -949,7 +956,7 @@ const Admin = (props) => {
|
||||
>
|
||||
<CachedIcon />
|
||||
</Button>
|
||||
<Divider style={{marginTop: 20, marginBottom: 20, backgroundColor: inputColor}}/>
|
||||
<Divider style={{marginTop: 20, marginBottom: 20, backgroundColor: theme.palette.inputColor}}/>
|
||||
<List>
|
||||
<ListItem>
|
||||
<ListItemText
|
||||
@@ -977,7 +984,7 @@ const Admin = (props) => {
|
||||
style={{minWidth: 200, maxWidth: 200, overflow: "hidden"}}
|
||||
/>
|
||||
<ListItemText>
|
||||
<Button type="outlined" style={{borderRadius: "0px"}} onClick={() => deleteEnvironment(environment.Name)} color="primary">Delete</Button>
|
||||
<Button variant="outlined" style={{borderRadius: "0px"}} onClick={() => deleteEnvironment(environment.Name)} color="primary">Delete</Button>
|
||||
</ListItemText>
|
||||
</ListItem>
|
||||
)
|
||||
@@ -986,6 +993,94 @@ const Admin = (props) => {
|
||||
</div>
|
||||
: null
|
||||
|
||||
const organizationsTab = curTab === 5 ?
|
||||
<div>
|
||||
<div style={{marginTop: 20, marginBottom: 20,}}>
|
||||
<h2 style={{display: "inline",}}>Organizations</h2>
|
||||
<span style={{marginLeft: 25}}>Global admin: control organizations</span>
|
||||
</div>
|
||||
<Button
|
||||
style={{}}
|
||||
variant="contained"
|
||||
color="primary"
|
||||
onClick={() => setModalOpen(true)}
|
||||
>
|
||||
Add organization
|
||||
</Button>
|
||||
<Divider style={{marginTop: 20, marginBottom: 20, backgroundColor: theme.palette.inputColor}}/>
|
||||
<List>
|
||||
<ListItem>
|
||||
<ListItemText
|
||||
primary="Name"
|
||||
style={{minWidth: 150, maxWidth: 150}}
|
||||
/>
|
||||
<ListItemText
|
||||
primary="Orborus running (TBD)"
|
||||
style={{minWidth: 200, maxWidth: 200}}
|
||||
/>
|
||||
<ListItemText
|
||||
primary="Actions"
|
||||
style={{minWidth: 150, maxWidth: 150}}
|
||||
/>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<ListItemText
|
||||
primary="Enabled"
|
||||
style={{minWidth: 150, maxWidth: 150}}
|
||||
/>
|
||||
<ListItemText
|
||||
primary="false"
|
||||
style={{minWidth: 200, maxWidth: 200}}
|
||||
/>
|
||||
<ListItemText
|
||||
primary=<Switch checked={false} onChange={() => {console.log("INVERT")}} />
|
||||
style={{minWidth: 150, maxWidth: 150}}
|
||||
/>
|
||||
</ListItem>
|
||||
</List>
|
||||
</div>
|
||||
: null
|
||||
|
||||
const hybridTab = curTab === 4 ?
|
||||
<div>
|
||||
<div style={{marginTop: 20, marginBottom: 20,}}>
|
||||
<h2 style={{display: "inline",}}>Hybrid</h2>
|
||||
<span style={{marginLeft: 25}}></span>
|
||||
</div>
|
||||
<Divider style={{marginTop: 20, marginBottom: 20, backgroundColor: theme.palette.inputColor}}/>
|
||||
<List>
|
||||
<ListItem>
|
||||
<ListItemText
|
||||
primary="Name"
|
||||
style={{minWidth: 150, maxWidth: 150}}
|
||||
/>
|
||||
<ListItemText
|
||||
primary="Orborus running (TBD)"
|
||||
style={{minWidth: 200, maxWidth: 200}}
|
||||
/>
|
||||
<ListItemText
|
||||
primary="Actions"
|
||||
style={{minWidth: 150, maxWidth: 150}}
|
||||
/>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<ListItemText
|
||||
primary="Enabled"
|
||||
style={{minWidth: 150, maxWidth: 150}}
|
||||
/>
|
||||
<ListItemText
|
||||
primary="false"
|
||||
style={{minWidth: 200, maxWidth: 200}}
|
||||
/>
|
||||
<ListItemText
|
||||
primary=<Switch checked={false} onChange={() => {console.log("INVERT")}} />
|
||||
style={{minWidth: 150, maxWidth: 150}}
|
||||
/>
|
||||
</ListItem>
|
||||
</List>
|
||||
</div>
|
||||
: null
|
||||
|
||||
// primary={environment.Registered ? "true" : "false"}
|
||||
|
||||
const setConfig = (event, newValue) => {
|
||||
@@ -1001,20 +1096,22 @@ const Admin = (props) => {
|
||||
setCurTab(newValue)
|
||||
}
|
||||
|
||||
const iconStyle = {marginRight: 10}
|
||||
const data =
|
||||
<div style={{minWidth: 1366, margin: "auto"}}>
|
||||
<Paper style={paperStyle}>
|
||||
<Tabs
|
||||
value={curTab}
|
||||
indicatorColor="primary"
|
||||
textColor="white"
|
||||
onChange={setConfig}
|
||||
aria-label="disabled tabs example"
|
||||
>
|
||||
<Tab label="Users" />
|
||||
<Tab label="App Authentication"/>
|
||||
<Tab label="Environments"/>
|
||||
<Tab label="Schedules"/>
|
||||
<Tab label=<span><AccessibilityNewIcon style={iconStyle} />Users</span> />
|
||||
<Tab label=<span><LockIcon style={iconStyle} />App Authentication</span>/>
|
||||
<Tab label=<span><EcoIcon style={iconStyle} />Environments</span>/>
|
||||
<Tab label=<span><ScheduleIcon style={iconStyle} />Schedules</span> />
|
||||
{window.location.protocol == "http:" && window.location.port === "3000" ? <Tab label=<span><CloudIcon style={iconStyle} /> Hybrid</span>/> : null}
|
||||
{window.location.protocol == "http:" && window.location.port === "3000" ? <Tab label=<span><BusinessIcon style={iconStyle} /> Organizations</span>/> : null}
|
||||
</Tabs>
|
||||
<Divider style={{marginTop: 0, marginBottom: 10, backgroundColor: "rgb(91, 96, 100)"}} />
|
||||
<div style={{padding: 15}}>
|
||||
@@ -1022,6 +1119,8 @@ const Admin = (props) => {
|
||||
{usersView}
|
||||
{environmentView}
|
||||
{schedulesView}
|
||||
{hybridTab}
|
||||
{organizationsTab}
|
||||
</div>
|
||||
</Paper>
|
||||
</div>
|
||||
@@ -68,8 +68,7 @@ import CytoscapeComponent from 'react-cytoscapejs';
|
||||
import undoRedo from 'cytoscape-undo-redo';
|
||||
import Draggable from 'react-draggable';
|
||||
|
||||
import environmentdata from './environmentdata';
|
||||
import cytoscapestyle from './defaultCytoscapeStyle';
|
||||
import cytoscapestyle from '../defaultCytoscapeStyle';
|
||||
import cxtmenu from 'cytoscape-cxtmenu';
|
||||
|
||||
import { w3cwebsocket as W3CWebSocket } from "websocket";
|
||||
@@ -950,6 +949,10 @@ const AngularWorkflow = (props) => {
|
||||
if (curaction.selectedAuthentication === null || curaction.selectedAuthentication === undefined || curaction.selectedAuthentication.length === "") {
|
||||
curaction.selectedAuthentication = {}
|
||||
}
|
||||
} else {
|
||||
curaction.authentication = []
|
||||
curaction.authentication_id = ""
|
||||
curaction.selectedAuthentication = {}
|
||||
}
|
||||
|
||||
setSelectedApp(curapp)
|
||||
@@ -2998,7 +3001,7 @@ const AngularWorkflow = (props) => {
|
||||
paddingLeft: 10,
|
||||
minHeight: "100%",
|
||||
zIndex: 1000,
|
||||
resize: "horizontal",
|
||||
resize: "vertical",
|
||||
overflow: "auto",
|
||||
}
|
||||
|
||||
@@ -3513,14 +3516,6 @@ const AngularWorkflow = (props) => {
|
||||
<div style={{flex: "10"}}>
|
||||
<b>{data.name} </b>
|
||||
</div>
|
||||
<Tooltip color="primary" title="Static data" placement="top">
|
||||
<div style={{cursor: "pointer", color: staticcolor}} onClick={(e) => {
|
||||
e.preventDefault()
|
||||
changeActionParameterVariant("STATIC_VALUE")
|
||||
}}>
|
||||
<CreateIcon />
|
||||
</div>
|
||||
</Tooltip>
|
||||
</div>
|
||||
{datafield}
|
||||
</div>
|
||||
@@ -3553,10 +3548,20 @@ const AngularWorkflow = (props) => {
|
||||
<FormControl>
|
||||
<DialogTitle><div style={{color:"white"}}>Condition</div></DialogTitle>
|
||||
<DialogContent style={{display: "flex"}}>
|
||||
<Tooltip color="primary" title={conditionValue.configuration ? "Negated" : "Default"} placement="top">
|
||||
<Button color="primary" variant={conditionValue.configuration ? "contained" : "outlined"} style={{margin: "auto", height: 50, marginBottom: 0, marginRight: 5}} onClick={(e) => {
|
||||
console.log("VALUE: ", conditionValue.configuration)
|
||||
conditionValue.configuration = !conditionValue.configuration
|
||||
setConditionValue(conditionValue)
|
||||
setUpdate("condition "+conditionValue.configuration)
|
||||
}}>
|
||||
{conditionValue.configuration ? "!" : "="}
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<div style={{flex: "2"}}>
|
||||
<AppConditionHandler tmpdata={sourceValue} setData={setSourceValue} type={"source"} />
|
||||
</div>
|
||||
<div style={{flex: "1", margin: "auto", marginBottom: "0px"}}>
|
||||
<div style={{flex: "1", margin: "auto", marginBottom: 0, marginLeft: 5, marginRight: 5,}}>
|
||||
<Button color="primary" variant="outlined" style={{height: "50px",}} fullWidth aria-haspopup="true" onClick={(e) => {setVariableAnchorEl(e.currentTarget)}}>
|
||||
{conditionValue.value}
|
||||
</Button>
|
||||
@@ -3621,7 +3626,6 @@ const AngularWorkflow = (props) => {
|
||||
setVariableAnchorEl(null)
|
||||
}} key={"less than"}>less than</MenuItem>
|
||||
</Menu>
|
||||
|
||||
</div>
|
||||
<div style={{flex: "2"}}>
|
||||
<AppConditionHandler tmpdata={destinationValue} setData={setDestinationValue} type={"destination"} />
|
||||
@@ -4774,7 +4778,7 @@ const AngularWorkflow = (props) => {
|
||||
<Divider style={{backgroundColor: "white", marginTop: 10, marginBottom: 10,}}/>
|
||||
<FormControlLabel
|
||||
style={{marginBottom: 15, color: "white",}}
|
||||
label=<div style={{color: "white"}}>Exit on Error</div>
|
||||
label={<div style={{color: "white"}}>Exit on Error</div>}
|
||||
control={
|
||||
<Switch checked={workflow.configuration.exit_on_error} onChange={() => {
|
||||
workflow.configuration.exit_on_error = !workflow.configuration.exit_on_error
|
||||
@@ -4786,7 +4790,7 @@ const AngularWorkflow = (props) => {
|
||||
/>
|
||||
<FormControlLabel
|
||||
style={{marginBottom: 15, color: "white",}}
|
||||
label=<div style={{color: "white"}}>Start from top</div>
|
||||
label={<div style={{color: "white"}}>Start from top</div>}
|
||||
control={
|
||||
<Switch checked={workflow.configuration.start_from_top} onChange={() => {
|
||||
workflow.configuration.start_from_top = !workflow.configuration.start_from_top
|
||||
@@ -5114,7 +5118,7 @@ const AngularWorkflow = (props) => {
|
||||
<h2>Executing Workflow</h2>
|
||||
<FormControlLabel
|
||||
style={{color: "white", marginBottom: "0px", marginTop: "10px"}}
|
||||
label=<div style={{color: "white"}}>Show failed / skipped actions</div>
|
||||
label={<div style={{color: "white"}}>Show failed / skipped actions</div>}
|
||||
control={
|
||||
<Switch checked={showSkippedActions} onChange={() => {setShowSkippedActions(!showSkippedActions)}} />
|
||||
}
|
||||
@@ -286,7 +286,7 @@ const Apps = (props) => {
|
||||
}
|
||||
|
||||
return (
|
||||
<Paper square style={paperAppStyle} onClick={() => {
|
||||
<Paper square key={data.id} style={paperAppStyle} onClick={() => {
|
||||
if (selectedApp.id !== data.id) {
|
||||
setSelectedApp(data)
|
||||
console.log(data)
|
||||
@@ -515,7 +515,7 @@ const Apps = (props) => {
|
||||
newActionname = newActionname.replace("_", " ")
|
||||
newActionname = newActionname.charAt(0).toUpperCase()+newActionname.substring(1)
|
||||
return (
|
||||
<MenuItem style={{backgroundColor: inputColor, color: "white"}} value={data}>
|
||||
<MenuItem key={data.name} style={{backgroundColor: inputColor, color: "white"}} value={data}>
|
||||
{newActionname}
|
||||
|
||||
</MenuItem>
|
||||
@@ -540,7 +540,7 @@ const Apps = (props) => {
|
||||
|
||||
const circleSize = 10
|
||||
return (
|
||||
<MenuItem style={{backgroundColor: inputColor, color: "white"}} value={data}>
|
||||
<MenuItem key={data.name} style={{backgroundColor: inputColor, color: "white"}} value={data}>
|
||||
<div style={{width: circleSize, height: circleSize, borderRadius: circleSize / 2, backgroundColor: itemColor, marginRight: "10px"}}/>
|
||||
{data.name}
|
||||
|
||||
@@ -654,7 +654,7 @@ const Apps = (props) => {
|
||||
{isLoading ? <CircularProgress style={{marginTop: 13, marginRight: 15}} /> : null}
|
||||
<FormControlLabel
|
||||
style={{color: "white", marginBottom: "0px", marginTop: "10px"}}
|
||||
label=<div style={{color: "white"}}>Search OpenAPI</div>
|
||||
label={<div style={{color: "white"}}>Search OpenAPI</div>}
|
||||
control={<Switch checked={searchBackend} onChange={() => {
|
||||
handleSearchChange("")
|
||||
setSearchBackend(!searchBackend)}
|
||||
@@ -743,7 +743,7 @@ const Apps = (props) => {
|
||||
null
|
||||
|
||||
// Load data e.g. from github
|
||||
const getSpecificApps = (url) => {
|
||||
const getSpecificApps = (url, forceUpdate) => {
|
||||
setValidation(true)
|
||||
|
||||
setIsLoading(true)
|
||||
@@ -761,6 +761,8 @@ const Apps = (props) => {
|
||||
parsedData["field_2"] = field2
|
||||
}
|
||||
|
||||
parsedData["force_update"] = forceUpdate
|
||||
|
||||
alert.success("Getting specific apps from your URL.")
|
||||
var cors = "cors"
|
||||
fetch(globalUrl+"/api/v1/apps/get_existing", {
|
||||
@@ -977,8 +979,8 @@ const Apps = (props) => {
|
||||
window.location.href = "/apps/new?id="+appValidation
|
||||
}
|
||||
|
||||
const handleGithubValidation = () => {
|
||||
getSpecificApps(openApi)
|
||||
const handleGithubValidation = (forceUpdate) => {
|
||||
getSpecificApps(openApi, forceUpdate)
|
||||
setLoadAppsModalOpen(false)
|
||||
}
|
||||
|
||||
@@ -1098,7 +1100,12 @@ const Apps = (props) => {
|
||||
Cancel
|
||||
</Button>
|
||||
<Button style={{borderRadius: "0px"}} disabled={openApi.length === 0 || !openApi.includes("http")} onClick={() => {
|
||||
handleGithubValidation()
|
||||
handleGithubValidation(true)
|
||||
}} color="primary">
|
||||
Force update
|
||||
</Button>
|
||||
<Button variant="outlined" style={{float: "left", borderRadius: "0px"}} disabled={openApi.length === 0 || !openApi.includes("http")} onClick={() => {
|
||||
handleGithubValidation(false)
|
||||
}} color="primary">
|
||||
Submit
|
||||
</Button>
|
||||
@@ -6,6 +6,8 @@ import Button from '@material-ui/core/Button';
|
||||
|
||||
import TextField from '@material-ui/core/TextField';
|
||||
|
||||
import { useTheme } from '@material-ui/core/styles';
|
||||
|
||||
const bodyDivStyle = {
|
||||
margin: "auto",
|
||||
textAlign: "center",
|
||||
@@ -13,11 +15,11 @@ const bodyDivStyle = {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Should be different if logged in :|
|
||||
const Contact = (props) => {
|
||||
const { globalUrl, isLoaded, surfaceColor, inputColor } = props;
|
||||
const { globalUrl, isLoaded } = props;
|
||||
|
||||
const theme = useTheme();
|
||||
|
||||
const boxStyle = {
|
||||
flex: "1",
|
||||
@@ -27,7 +29,7 @@ const Contact = (props) => {
|
||||
paddingRight: "30px",
|
||||
paddingBottom: "30px",
|
||||
paddingTop: "30px",
|
||||
backgroundColor: surfaceColor,
|
||||
backgroundColor: theme.palette.surfaceColor,
|
||||
display: "flex",
|
||||
flexDirection: "column"
|
||||
}
|
||||
@@ -92,7 +94,7 @@ const Contact = (props) => {
|
||||
<div style={{ flex: "1", display: "flex", flexDirection: "row" }}>
|
||||
<TextField
|
||||
required
|
||||
style={{flex: "1", marginRight: "15px", backgroundColor: inputColor}}
|
||||
style={{ flex: "1", marginRight: "15px", backgroundColor: theme.palette.inputColor }}
|
||||
InputProps={{
|
||||
style: {
|
||||
color: "white",
|
||||
@@ -109,7 +111,7 @@ const Contact = (props) => {
|
||||
onChange={e => setFirstname(e.target.value)}
|
||||
/>
|
||||
<TextField
|
||||
style={{flex: "1", marginLeft: "15px", backgroundColor: inputColor}}
|
||||
style={{ flex: "1", marginLeft: "15px", backgroundColor: theme.palette.inputColor }}
|
||||
InputProps={{
|
||||
style: {
|
||||
color: "white",
|
||||
@@ -128,7 +130,7 @@ const Contact = (props) => {
|
||||
</div>
|
||||
<div style={{ flex: "1", display: "flex", flexDirection: "row" }}>
|
||||
<TextField
|
||||
style={{flex: "1", marginRight: "15px", backgroundColor: inputColor}}
|
||||
style={{ flex: "1", marginRight: "15px", backgroundColor: theme.palette.inputColor }}
|
||||
InputProps={{
|
||||
style: {
|
||||
color: "white",
|
||||
@@ -145,7 +147,7 @@ const Contact = (props) => {
|
||||
onChange={e => setTitle(e.target.value)}
|
||||
/>
|
||||
<TextField
|
||||
style={{flex: "1", marginLeft: "15px", backgroundColor: inputColor}}
|
||||
style={{ flex: "1", marginLeft: "15px", backgroundColor: theme.palette.inputColor }}
|
||||
InputProps={{
|
||||
style: {
|
||||
color: "white",
|
||||
@@ -165,7 +167,7 @@ const Contact = (props) => {
|
||||
<div style={{ flex: "1", display: "flex", flexDirection: "row" }}>
|
||||
<TextField
|
||||
required
|
||||
style={{flex: "1", marginRight: "15px", backgroundColor: inputColor}}
|
||||
style={{ flex: "1", marginRight: "15px", backgroundColor: theme.palette.inputColor }}
|
||||
InputProps={{
|
||||
style: {
|
||||
color: "white",
|
||||
@@ -182,7 +184,7 @@ const Contact = (props) => {
|
||||
onChange={e => setEmail(e.target.value)}
|
||||
/>
|
||||
<TextField
|
||||
style={{flex: "1", marginLeft: "15px", backgroundColor: inputColor}}
|
||||
style={{ flex: "1", marginLeft: "15px", backgroundColor: theme.palette.inputColor }}
|
||||
InputProps={{
|
||||
style: {
|
||||
color: "white",
|
||||
@@ -211,7 +213,7 @@ const Contact = (props) => {
|
||||
},
|
||||
}}
|
||||
color="primary"
|
||||
style={{flex: "1", backgroundColor: inputColor}}
|
||||
style={{ flex: "1", backgroundColor: theme.palette.inputColor }}
|
||||
rows="6"
|
||||
fullWidth={true}
|
||||
placeholder="What can we help you with?"
|
||||
@@ -247,7 +249,7 @@ const Contact = (props) => {
|
||||
<div style={{ flex: "1", display: "flex", flexDirection: "row" }}>
|
||||
<TextField
|
||||
required
|
||||
style={{flex: "1", backgroundColor: inputColor}}
|
||||
style={{ flex: "1", backgroundColor: theme.palette.inputColor }}
|
||||
InputProps={{
|
||||
style: {
|
||||
color: "white",
|
||||
@@ -267,7 +269,7 @@ const Contact = (props) => {
|
||||
<div style={{ flex: "1", display: "flex", flexDirection: "row" }}>
|
||||
<TextField
|
||||
required
|
||||
style={{flex: "1", backgroundColor: inputColor}}
|
||||
style={{ flex: "1", backgroundColor: theme.palette.inputColor }}
|
||||
InputProps={{
|
||||
style: {
|
||||
color: "white",
|
||||
@@ -290,7 +292,7 @@ const Contact = (props) => {
|
||||
<div style={{ flex: 4 }}>
|
||||
<TextField
|
||||
multiline
|
||||
style={{flex: "1", backgroundColor: inputColor}}
|
||||
style={{ flex: "1", backgroundColor: theme.palette.inputColor }}
|
||||
InputProps={{
|
||||
style: {
|
||||
color: "white",
|
||||
@@ -35,7 +35,7 @@ import {
|
||||
chartExample2,
|
||||
chartExample3,
|
||||
chartExample4
|
||||
} from "./charts.js";
|
||||
} from "../charts.js";
|
||||
|
||||
// This is the start of a dashboard that can be used.
|
||||
// What data do we fill in here? Idk
|
||||
@@ -34,9 +34,6 @@ import DeleteIcon from '@material-ui/icons/Delete';
|
||||
import Downshift from 'downshift';
|
||||
import deburr from 'lodash/deburr';
|
||||
|
||||
//import appdata from './appdata';
|
||||
|
||||
|
||||
const EditSchedule = (props) => {
|
||||
const { globalUrl } = props;
|
||||
|
||||
@@ -6,8 +6,8 @@ import Divider from '@material-ui/core/Divider';
|
||||
import Select from '@material-ui/core/Select';
|
||||
import MenuItem from '@material-ui/core/MenuItem';
|
||||
|
||||
import WebhookImage from './assets/img/webhook.png';
|
||||
import KafkaImage from './assets/img/kafka.png';
|
||||
import WebhookImage from '../assets/img/webhook.png';
|
||||
import KafkaImage from '../assets/img/kafka.png';
|
||||
|
||||
import EditWorkflow from "./EditWorkflow";
|
||||
|
||||
@@ -5,6 +5,8 @@ import { makeStyles } from '@material-ui/styles';
|
||||
import TextField from '@material-ui/core/TextField';
|
||||
import Button from '@material-ui/core/Button';
|
||||
import Paper from '@material-ui/core/Paper';
|
||||
import { useTheme } from '@material-ui/core/styles';
|
||||
|
||||
|
||||
const hrefStyle = {
|
||||
color: "white",
|
||||
@@ -17,16 +19,6 @@ const bodyDivStyle = {
|
||||
width: "500px",
|
||||
}
|
||||
|
||||
const surfaceColor = "#27292D"
|
||||
const inputColor = "#383B40"
|
||||
|
||||
const boxStyle = {
|
||||
paddingLeft: "30px",
|
||||
paddingRight: "30px",
|
||||
paddingBottom: "30px",
|
||||
paddingTop: "30px",
|
||||
backgroundColor: surfaceColor,
|
||||
}
|
||||
|
||||
const useStyles = makeStyles({
|
||||
notchedOutline: {
|
||||
@@ -35,6 +27,8 @@ const useStyles = makeStyles({
|
||||
});
|
||||
|
||||
const LoginDialog = props => {
|
||||
const theme = useTheme();
|
||||
|
||||
const { globalUrl, isLoaded, isLoggedIn, setIsLoggedIn, setCookie, register } = props;
|
||||
const [username, setUsername] = useState("");
|
||||
const [password, setPassword] = useState("");
|
||||
@@ -169,16 +163,23 @@ const LoginDialog = props => {
|
||||
|
||||
// <DialogTitle>{formtitle}</DialogTitle>
|
||||
|
||||
console.log("THEME: ", theme.palette.surfaceColor)
|
||||
const basedata =
|
||||
<div style={bodyDivStyle}>
|
||||
<Paper style={boxStyle}>
|
||||
<Paper style={{
|
||||
paddingLeft: "30px",
|
||||
paddingRight: "30px",
|
||||
paddingBottom: "30px",
|
||||
paddingTop: "30px",
|
||||
backgroundColor: theme.palette.surfaceColor,
|
||||
}}>
|
||||
<form onSubmit={onSubmit} style={{ margin: "15px 15px 15px 15px", color: "white", }}>
|
||||
<h2>{formtitle}</h2>
|
||||
Username
|
||||
<div>
|
||||
<TextField
|
||||
color="primary"
|
||||
style={{backgroundColor: inputColor}}
|
||||
style={{ backgroundColor: theme.palette.inputColor }}
|
||||
autoFocus
|
||||
InputProps={{
|
||||
classes: {
|
||||
@@ -204,7 +205,7 @@ const LoginDialog = props => {
|
||||
<div>
|
||||
<TextField
|
||||
color="primary"
|
||||
style={{backgroundColor: inputColor,}}
|
||||
style={{ backgroundColor: theme.palette.inputColor }}
|
||||
InputProps={{
|
||||
classes: {
|
||||
notchedOutline: classes.notchedOutline,
|
||||
@@ -7,23 +7,11 @@ import {Link} from 'react-router-dom';
|
||||
|
||||
import TextField from '@material-ui/core/TextField';
|
||||
import { useAlert } from "react-alert";
|
||||
import { useTheme } from '@material-ui/core/styles';
|
||||
|
||||
|
||||
//const tmpdata = {
|
||||
// "username": "frikky",
|
||||
// "firstname": "fred",
|
||||
// "lastname": "ode",
|
||||
// "title": "topkek",
|
||||
// "companyname": "company here",
|
||||
// "email": "your email pls",
|
||||
// "phone": "PHONE!!",
|
||||
//}
|
||||
|
||||
// FIXME - add fetch for data fields
|
||||
// FIXME - remove tmpdata
|
||||
// FIXME: Use isLoggedIn :)
|
||||
const Settings = (props) => {
|
||||
const { globalUrl, isLoaded, userdata, surfaceColor, inputColor } = props;
|
||||
const { globalUrl, isLoaded, userdata, } = props;
|
||||
const theme = useTheme();
|
||||
const alert = useAlert()
|
||||
|
||||
const [username, setUsername] = useState("");
|
||||
@@ -61,7 +49,7 @@ const Settings = (props) => {
|
||||
paddingRight: "30px",
|
||||
paddingBottom: "30px",
|
||||
paddingTop: "30px",
|
||||
backgroundColor: surfaceColor,
|
||||
backgroundColor: theme.palette.surfaceColor,
|
||||
display: "flex",
|
||||
flexDirection: "column"
|
||||
}
|
||||
@@ -190,7 +178,7 @@ const Settings = (props) => {
|
||||
<h2>APIKEY</h2>
|
||||
<Link to="/docs/API#authentication" style={{textDecoration: "none", color: "#f85a3e"}}>What is the API key used for?</Link>
|
||||
<TextField
|
||||
style={{backgroundColor: inputColor, flex: "1"}}
|
||||
style={{backgroundColor: theme.palette.inputColor, flex: "1"}}
|
||||
InputProps={{
|
||||
style:{
|
||||
height: "50px",
|
||||
@@ -218,7 +206,7 @@ const Settings = (props) => {
|
||||
<h2>Settings</h2>
|
||||
<div style={{flex: "1", display: "flex", flexDirection: "row"}}>
|
||||
<TextField
|
||||
style={{backgroundColor: inputColor, flex: "1"}}
|
||||
style={{backgroundColor: theme.palette.inputColor, flex: "1"}}
|
||||
InputProps={{
|
||||
style:{
|
||||
height: "50px",
|
||||
@@ -240,7 +228,7 @@ const Settings = (props) => {
|
||||
</div>
|
||||
<div style={{flex: "1", display: "flex", flexDirection: "row"}}>
|
||||
<TextField
|
||||
style={{backgroundColor: inputColor, flex: "1", marginRight: "15px"}}
|
||||
style={{backgroundColor: theme.palette.inputColor, flex: "1", marginRight: "15px"}}
|
||||
InputProps={{
|
||||
style:{
|
||||
height: "50px",
|
||||
@@ -260,7 +248,7 @@ const Settings = (props) => {
|
||||
onChange={e => setFirstname(e.target.value)}
|
||||
/>
|
||||
<TextField
|
||||
style={{backgroundColor: inputColor, flex: "1", marginLeft: "15px"}}
|
||||
style={{backgroundColor: theme.palette.inputColor, flex: "1", marginLeft: "15px"}}
|
||||
InputProps={{
|
||||
style:{
|
||||
height: "50px",
|
||||
@@ -282,7 +270,7 @@ const Settings = (props) => {
|
||||
</div>
|
||||
<div style={{flex: "1", display: "flex", flexDirection: "row"}}>
|
||||
<TextField
|
||||
style={{backgroundColor: inputColor, flex: "1", marginRight: "15px",}}
|
||||
style={{backgroundColor: theme.palette.inputColor, flex: "1", marginRight: "15px",}}
|
||||
InputProps={{
|
||||
style:{
|
||||
height: "50px",
|
||||
@@ -302,7 +290,7 @@ const Settings = (props) => {
|
||||
onChange={e => setTitle(e.target.value)}
|
||||
/>
|
||||
<TextField
|
||||
style={{backgroundColor: inputColor, flex: "1", marginLeft: "15px"}}
|
||||
style={{backgroundColor: theme.palette.inputColor, flex: "1", marginLeft: "15px"}}
|
||||
InputProps={{
|
||||
style:{
|
||||
height: "50px",
|
||||
@@ -324,7 +312,7 @@ const Settings = (props) => {
|
||||
</div>
|
||||
<div style={{flex: "1", display: "flex", flexDirection: "row"}}>
|
||||
<TextField
|
||||
style={{backgroundColor: inputColor, flex: "1", marginRight: "15px",}}
|
||||
style={{backgroundColor: theme.palette.inputColor, flex: "1", marginRight: "15px",}}
|
||||
InputProps={{
|
||||
style:{
|
||||
height: "50px",
|
||||
@@ -344,7 +332,7 @@ const Settings = (props) => {
|
||||
onChange={e => setEmail(e.target.value)}
|
||||
/>
|
||||
<TextField
|
||||
style={{backgroundColor: inputColor, flex: "1", marginLeft: "15px",}}
|
||||
style={{backgroundColor: theme.palette.inputColor, flex: "1", marginLeft: "15px",}}
|
||||
InputProps={{
|
||||
style:{
|
||||
height: "50px",
|
||||
@@ -379,7 +367,7 @@ const Settings = (props) => {
|
||||
<h2>Password</h2>
|
||||
<div style={{flex: "1", display: "flex", flexDirection: "row"}}>
|
||||
<TextField
|
||||
style={{backgroundColor: inputColor, flex: "1"}}
|
||||
style={{backgroundColor: theme.palette.inputColor, flex: "1"}}
|
||||
InputProps={{
|
||||
style:{
|
||||
height: "50px",
|
||||
@@ -400,7 +388,7 @@ const Settings = (props) => {
|
||||
</div>
|
||||
<div style={{flex: "1", display: "flex", flexDirection: "row"}}>
|
||||
<TextField
|
||||
style={{backgroundColor: inputColor, flex: "1", marginRight: "15px",}}
|
||||
style={{backgroundColor: theme.palette.inputColor, flex: "1", marginRight: "15px",}}
|
||||
InputProps={{
|
||||
style:{
|
||||
height: "50px",
|
||||
@@ -419,7 +407,7 @@ const Settings = (props) => {
|
||||
onChange={e => setNewPassword(e.target.value)}
|
||||
/>
|
||||
<TextField
|
||||
style={{backgroundColor: inputColor, flex: "1", marginLeft: "15px",}}
|
||||
style={{backgroundColor: theme.palette.inputColor, flex: "1", marginLeft: "15px",}}
|
||||
InputProps={{
|
||||
style:{
|
||||
height: "50px",
|
||||
@@ -15,8 +15,8 @@ import DialogTitle from '@material-ui/core/DialogTitle';
|
||||
import DialogActions from '@material-ui/core/DialogActions';
|
||||
import DialogContent from '@material-ui/core/DialogContent';
|
||||
|
||||
import WebhookImage from './assets/img/webhook.png';
|
||||
import KafkaImage from './assets/img/kafka.png';
|
||||
import WebhookImage from '../assets/img/webhook.png';
|
||||
import KafkaImage from '../assets/img/kafka.png';
|
||||
|
||||
const Webhooks = (props) => {
|
||||
const { globalUrl, isLoaded } = props;
|
||||
@@ -563,7 +563,7 @@ const Workflows = (props) => {
|
||||
}
|
||||
|
||||
return (
|
||||
<Paper square style={resultPaperAppStyle} onClick={() => {}}>
|
||||
<Paper key={data.id} square style={resultPaperAppStyle} onClick={() => {}}>
|
||||
<div style={{marginLeft: "10px", marginTop: "5px", marginBottom: "5px", marginRight: "5px", width: boxWidth, backgroundColor: boxColor}}>
|
||||
</div>
|
||||
<Grid container style={{margin: "10px 10px 10px 10px", flex: "1"}}>
|
||||
@@ -988,7 +988,7 @@ const Workflows = (props) => {
|
||||
<div style={{flex: "1"}}>
|
||||
<FormControlLabel
|
||||
style={{color: "white", marginBottom: "0px", marginTop: "10px"}}
|
||||
label=<div style={{color: "white"}}>Collapse results</div>
|
||||
label={<div style={{color: "white"}}>Collapse results</div>}
|
||||
control={<Switch checked={collapseJson} onChange={() => {setCollapseJson(!collapseJson)}} />}
|
||||
/>
|
||||
</div>
|
||||
@@ -78,10 +78,11 @@ func init() {
|
||||
// Skip random containers. Only handle things related to Shuffle.
|
||||
for _, container := range containers {
|
||||
found := false
|
||||
//log.Printf("Running? %#v", container)
|
||||
if container.State != "running" {
|
||||
continue
|
||||
}
|
||||
|
||||
// Bad states - it might just be created sometimes, leading to now netowkr
|
||||
//if container.State == "restarting" || container.State == "paused" || container.State == "exited" || container.State == "dead" {
|
||||
// continue
|
||||
//}
|
||||
|
||||
for _, name := range container.Names {
|
||||
if !strings.Contains(strings.ToLower(name), containerIdentifier) {
|
||||
@@ -120,17 +121,10 @@ func deployWorker(image string, identifier string, env []string) {
|
||||
},
|
||||
}
|
||||
|
||||
// ROFL: https://docker-py.readthedocs.io/en/1.4.0/volumes/
|
||||
config := &container.Config{
|
||||
Image: image,
|
||||
Env: env,
|
||||
}
|
||||
|
||||
// Look for Shuffle network and set it
|
||||
|
||||
// FIXME: Move this out of here and have it be a global setting. During init?
|
||||
networkConfig := &network.NetworkingConfig{}
|
||||
if len(shuffleNetwork) > 0 {
|
||||
log.Printf("Starting worker with network %s", shuffleNetwork)
|
||||
networkConfig = &network.NetworkingConfig{
|
||||
EndpointsConfig: map[string]*network.EndpointSettings{
|
||||
shuffleNetwork: {
|
||||
@@ -139,7 +133,15 @@ func deployWorker(image string, identifier string, env []string) {
|
||||
},
|
||||
}
|
||||
|
||||
env = append(env, fmt.Sprintf("DOCKER_NETWORK", shuffleNetwork))
|
||||
env = append(env, fmt.Sprintf("DOCKER_NETWORK=%s", shuffleNetwork))
|
||||
} else {
|
||||
log.Printf("Starting worker WITHOUT any specified network: %s", shuffleNetwork)
|
||||
}
|
||||
|
||||
// ROFL: https://docker-py.readthedocs.io/en/1.4.0/volumes/
|
||||
config := &container.Config{
|
||||
Image: image,
|
||||
Env: env,
|
||||
}
|
||||
|
||||
//test := &network.EndpointSettings{
|
||||
|
||||
@@ -1107,6 +1107,13 @@ func main() {
|
||||
}
|
||||
}
|
||||
|
||||
shuffleNetwork := os.Getenv("DOCKER_NETWORK")
|
||||
if len(shuffleNetwork) > 0 {
|
||||
log.Printf("Running with Docker network %s", shuffleNetwork)
|
||||
} else {
|
||||
log.Printf("No docker network specified for Worker.")
|
||||
}
|
||||
|
||||
// WORKER_TESTING_WORKFLOW should be a workflow ID
|
||||
authorization := ""
|
||||
executionId := ""
|
||||
|
||||
Reference in New Issue
Block a user