commit
88027ae773
|
|
@ -14,7 +14,7 @@ Oktopus is a multi-vendor management platform for CPEs and IoTs. <b>Any device t
|
|||
|
||||
<a href="https://www.inango.com/" target="_blank"><img src="https://github.com/OktopUSP/oktopus/assets/83298718/3b3e65d9-33fa-46c4-8b24-f9e2a84a04a6" width="100px"/></a>
|
||||
|
||||
<p>If you'd like to become a sponsor, start a partnership or somehow to contribute to the project, email <a href="">leandro@oktopus.app.br</a>, every contribution is welcome, and the resources will help the project to move on. Also, if your company uses this project and you'd like your logo to appear up here, contact us.
|
||||
<p>If you'd like to become a sponsor, start a partnership or somehow to contribute to the project, email <a href="">contact@oktopus.app.br</a>, every contribution is welcome, and the resources will help the project to move on. Also, if your company uses this project and you'd like your logo to appear up here, contact us.
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
|
|
@ -23,7 +23,7 @@ Oktopus is a multi-vendor management platform for CPEs and IoTs. <b>Any device t
|
|||
<p>
|
||||
Our solution has an open-source software license, meaning you can modify/study the code and use it for free. You can perform all the configurations, allocate servers, and set it up on your network with the classic "do it yourself" approach, or save time and money: contact us for a quote and get commercial support.
|
||||
</p>
|
||||
<p>Contact <a href="">leandro@oktopus.app.br</a> via email and get a quote.</p>
|
||||
<p>Contact <a href="">sales@oktopus.app.br</a> via email and get a quote.</p>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
|
|
|||
|
|
@ -14,10 +14,11 @@ import (
|
|||
const LOCAL_ENV = ".env.local"
|
||||
|
||||
type Nats struct {
|
||||
Url string
|
||||
Name string
|
||||
VerifyCertificates bool
|
||||
Ctx context.Context
|
||||
Url string
|
||||
Name string
|
||||
EnableTls bool
|
||||
Cert Tls
|
||||
Ctx context.Context
|
||||
}
|
||||
|
||||
type Acs struct {
|
||||
|
|
@ -40,6 +41,12 @@ type Config struct {
|
|||
Nats Nats
|
||||
}
|
||||
|
||||
type Tls struct {
|
||||
CertFile string
|
||||
KeyFile string
|
||||
CaFile string
|
||||
}
|
||||
|
||||
func NewConfig() *Config {
|
||||
|
||||
loadEnvVariables()
|
||||
|
|
@ -47,7 +54,10 @@ func NewConfig() *Config {
|
|||
|
||||
natsUrl := flag.String("nats_url", lookupEnvOrString("NATS_URL", "nats://localhost:4222"), "url for nats server")
|
||||
natsName := flag.String("nats_name", lookupEnvOrString("NATS_NAME", "adapter"), "name for nats client")
|
||||
natsVerifyCertificates := flag.Bool("nats_verify_certificates", lookupEnvOrBool("NATS_VERIFY_CERTIFICATES", false), "verify validity of certificates from nats server")
|
||||
natsEnableTls := flag.Bool("nats_enable_tls", lookupEnvOrBool("NATS_ENABLE_TLS", false), "enbale TLS to nats server")
|
||||
clientCrt := flag.String("client_crt", lookupEnvOrString("CLIENT_CRT", "cert.pem"), "client certificate file to TLS connection")
|
||||
clientKey := flag.String("client_key", lookupEnvOrString("CLIENT_KEY", "key.pem"), "client key file to TLS connection")
|
||||
serverCA := flag.String("server_ca", lookupEnvOrString("SERVER_CA", "rootCA.pem"), "server CA file to TLS connection")
|
||||
acsPort := flag.String("acs_port", lookupEnvOrString("ACS_PORT", ":9292"), "port for acs server")
|
||||
acsRoute := flag.String("acs_route", lookupEnvOrString("ACS_ROUTE", "/acs"), "route for acs server")
|
||||
connReqUser := flag.String("connrq_user", lookupEnvOrString("CONN_RQ_USER", ""), "Connection Request Username")
|
||||
|
|
@ -77,10 +87,15 @@ func NewConfig() *Config {
|
|||
|
||||
return &Config{
|
||||
Nats: Nats{
|
||||
Url: *natsUrl,
|
||||
Name: *natsName,
|
||||
VerifyCertificates: *natsVerifyCertificates,
|
||||
Ctx: ctx,
|
||||
Url: *natsUrl,
|
||||
Name: *natsName,
|
||||
EnableTls: *natsEnableTls,
|
||||
Ctx: ctx,
|
||||
Cert: Tls{
|
||||
CertFile: *clientCrt,
|
||||
KeyFile: *clientKey,
|
||||
CaFile: *serverCA,
|
||||
},
|
||||
},
|
||||
Acs: Acs{
|
||||
Port: *acsPort,
|
||||
|
|
|
|||
|
|
@ -141,8 +141,10 @@ func defineOptions(c config.Nats) []nats.Option {
|
|||
opts = append(opts, nats.ClosedHandler(func(nc *nats.Conn) {
|
||||
log.Printf("Connection closed. Reason: %q\n", nc.LastError())
|
||||
}))
|
||||
if c.VerifyCertificates {
|
||||
opts = append(opts, nats.RootCAs())
|
||||
if c.EnableTls {
|
||||
log.Printf("Load certificates: %s and %s\n", c.Cert.CertFile, c.Cert.KeyFile)
|
||||
opts = append(opts, nats.RootCAs(c.Cert.CaFile))
|
||||
opts = append(opts, nats.ClientCert(c.Cert.CertFile, c.Cert.KeyFile))
|
||||
}
|
||||
|
||||
return opts
|
||||
|
|
|
|||
|
|
@ -13,10 +13,11 @@ import (
|
|||
const LOCAL_ENV = ".env.local"
|
||||
|
||||
type Nats struct {
|
||||
Url string
|
||||
Name string
|
||||
VerifyCertificates bool
|
||||
Ctx context.Context
|
||||
Url string
|
||||
Name string
|
||||
EnableTls bool
|
||||
Cert Tls
|
||||
Ctx context.Context
|
||||
}
|
||||
|
||||
type RestApi struct {
|
||||
|
|
@ -29,6 +30,12 @@ type Config struct {
|
|||
Nats Nats
|
||||
}
|
||||
|
||||
type Tls struct {
|
||||
CertFile string
|
||||
KeyFile string
|
||||
CaFile string
|
||||
}
|
||||
|
||||
func NewConfig() *Config {
|
||||
|
||||
loadEnvVariables()
|
||||
|
|
@ -36,7 +43,10 @@ func NewConfig() *Config {
|
|||
|
||||
natsUrl := flag.String("nats_url", lookupEnvOrString("NATS_URL", "nats://localhost:4222"), "url for nats server")
|
||||
natsName := flag.String("nats_name", lookupEnvOrString("NATS_NAME", "adapter"), "name for nats client")
|
||||
natsVerifyCertificates := flag.Bool("nats_verify_certificates", lookupEnvOrBool("NATS_VERIFY_CERTIFICATES", false), "verify validity of certificates from nats server")
|
||||
natsEnableTls := flag.Bool("nats_enable_tls", lookupEnvOrBool("NATS_ENABLE_TLS", false), "enbale TLS to nats server")
|
||||
clientCrt := flag.String("client_crt", lookupEnvOrString("CLIENT_CRT", "cert.pem"), "client certificate file to TLS connection")
|
||||
clientKey := flag.String("client_key", lookupEnvOrString("CLIENT_KEY", "key.pem"), "client key file to TLS connection")
|
||||
serverCA := flag.String("server_ca", lookupEnvOrString("SERVER_CA", "rootCA.pem"), "server CA file to TLS connection")
|
||||
flApiPort := flag.String("api_port", lookupEnvOrString("REST_API_PORT", "4000"), "Rest api port")
|
||||
flHelp := flag.Bool("help", false, "Help")
|
||||
|
||||
|
|
@ -62,10 +72,15 @@ func NewConfig() *Config {
|
|||
Ctx: ctx,
|
||||
},
|
||||
Nats: Nats{
|
||||
Url: *natsUrl,
|
||||
Name: *natsName,
|
||||
VerifyCertificates: *natsVerifyCertificates,
|
||||
Ctx: ctx,
|
||||
Url: *natsUrl,
|
||||
Name: *natsName,
|
||||
EnableTls: *natsEnableTls,
|
||||
Ctx: ctx,
|
||||
Cert: Tls{
|
||||
CertFile: *clientCrt,
|
||||
KeyFile: *clientKey,
|
||||
CaFile: *serverCA,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,8 +70,10 @@ func defineOptions(c config.Nats) []nats.Option {
|
|||
opts = append(opts, nats.ClosedHandler(func(nc *nats.Conn) {
|
||||
log.Printf("Connection closed. Reason: %q\n", nc.LastError())
|
||||
}))
|
||||
if c.VerifyCertificates {
|
||||
opts = append(opts, nats.RootCAs())
|
||||
if c.EnableTls {
|
||||
log.Printf("Load certificates: %s and %s\n", c.Cert.CertFile, c.Cert.KeyFile)
|
||||
opts = append(opts, nats.RootCAs(c.Cert.CaFile))
|
||||
opts = append(opts, nats.ClientCert(c.Cert.CertFile, c.Cert.KeyFile))
|
||||
}
|
||||
|
||||
return opts
|
||||
|
|
|
|||
|
|
@ -57,6 +57,13 @@ func (a *Api) StartApi() {
|
|||
authentication.HandleFunc("/password", a.changePassword).Methods("PUT")
|
||||
authentication.HandleFunc("/admin/register", a.registerAdminUser).Methods("POST")
|
||||
authentication.HandleFunc("/admin/exists", a.adminUserExists).Methods("GET")
|
||||
if a.enterpise.Enable {
|
||||
mapRoutes := r.PathPrefix("/api/map").Subrouter()
|
||||
mapRoutes.HandleFunc("", a.devicesLocation).Methods("GET")
|
||||
mapRoutes.Use(func(handler http.Handler) http.Handler {
|
||||
return middleware.Middleware(handler)
|
||||
})
|
||||
}
|
||||
iot := r.PathPrefix("/api/device").Subrouter()
|
||||
iot.HandleFunc("/alias", a.setDeviceAlias).Methods("PUT")
|
||||
iot.HandleFunc("/auth", a.deviceAuth).Methods("GET", "POST", "DELETE")
|
||||
|
|
|
|||
|
|
@ -28,6 +28,22 @@ func (a *Api) getEnterpriseResource(
|
|||
return err
|
||||
}
|
||||
|
||||
func (a *Api) getMapsResource(
|
||||
action string,
|
||||
w http.ResponseWriter,
|
||||
body []byte,
|
||||
) error {
|
||||
|
||||
err := bridge.NatsEnterpriseInteraction("geolocation.v1."+action, body, w, a.nc)
|
||||
return err
|
||||
}
|
||||
|
||||
func (a *Api) devicesLocation(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method == http.MethodGet {
|
||||
a.getMapsResource("get", w, []byte{})
|
||||
}
|
||||
}
|
||||
|
||||
func (a *Api) deviceSiteSurvey(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
sn := vars["sn"]
|
||||
|
|
|
|||
|
|
@ -243,7 +243,6 @@ func adminUserExists(users []map[string]interface{}, supportEmail string) bool {
|
|||
|
||||
for _, x := range users {
|
||||
if db.UserLevels(x["level"].(int32)) == db.AdminUser && x["email"].(string) != supportEmail {
|
||||
log.Println("Admin exists")
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -263,7 +263,7 @@ func NatsEnterpriseInteraction(
|
|||
if err != nil {
|
||||
if err == nats.ErrNoResponders {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write(utils.Marshall("You have no enterprise license, to get one contact: leandro@oktopus.app.br"))
|
||||
w.Write(utils.Marshall("You have no enterprise license, to get one contact: sales@oktopus.app.br"))
|
||||
return err
|
||||
}
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
|
|
|
|||
|
|
@ -13,10 +13,11 @@ import (
|
|||
const LOCAL_ENV = ".env.local"
|
||||
|
||||
type Nats struct {
|
||||
Url string
|
||||
Name string
|
||||
VerifyCertificates bool
|
||||
Ctx context.Context
|
||||
Url string
|
||||
Name string
|
||||
EnableTls bool
|
||||
Cert Tls
|
||||
Ctx context.Context
|
||||
}
|
||||
|
||||
type Mongo struct {
|
||||
|
|
@ -42,6 +43,12 @@ type Config struct {
|
|||
Enterprise Enterprise
|
||||
}
|
||||
|
||||
type Tls struct {
|
||||
CertFile string
|
||||
KeyFile string
|
||||
CaFile string
|
||||
}
|
||||
|
||||
func NewConfig() *Config {
|
||||
|
||||
loadEnvVariables()
|
||||
|
|
@ -49,7 +56,10 @@ func NewConfig() *Config {
|
|||
|
||||
natsUrl := flag.String("nats_url", lookupEnvOrString("NATS_URL", "nats://localhost:4222"), "url for nats server")
|
||||
natsName := flag.String("nats_name", lookupEnvOrString("NATS_NAME", "controller"), "name for nats client")
|
||||
natsVerifyCertificates := flag.Bool("nats_verify_certificates", lookupEnvOrBool("NATS_VERIFY_CERTIFICATES", false), "verify validity of certificates from nats server")
|
||||
natsEnableTls := flag.Bool("nats_enable_tls", lookupEnvOrBool("NATS_ENABLE_TLS", false), "enbale TLS to nats server")
|
||||
clientCrt := flag.String("client_crt", lookupEnvOrString("CLIENT_CRT", "cert.pem"), "client certificate file to TLS connection")
|
||||
clientKey := flag.String("client_key", lookupEnvOrString("CLIENT_KEY", "key.pem"), "client key file to TLS connection")
|
||||
serverCA := flag.String("server_ca", lookupEnvOrString("SERVER_CA", "rootCA.pem"), "server CA file to TLS connection")
|
||||
flApiPort := flag.String("api_port", lookupEnvOrString("REST_API_PORT", "8000"), "Rest api port")
|
||||
mongoUri := flag.String("mongo_uri", lookupEnvOrString("MONGO_URI", "mongodb://localhost:27017"), "uri for mongodb server")
|
||||
enterpise := flag.Bool("enterprise", lookupEnvOrBool("ENTERPRISE", false), "enterprise version enable")
|
||||
|
|
@ -79,10 +89,15 @@ func NewConfig() *Config {
|
|||
Ctx: ctx,
|
||||
},
|
||||
Nats: Nats{
|
||||
Url: *natsUrl,
|
||||
Name: *natsName,
|
||||
VerifyCertificates: *natsVerifyCertificates,
|
||||
Ctx: ctx,
|
||||
Url: *natsUrl,
|
||||
Name: *natsName,
|
||||
EnableTls: *natsEnableTls,
|
||||
Ctx: ctx,
|
||||
Cert: Tls{
|
||||
CertFile: *clientCrt,
|
||||
KeyFile: *clientKey,
|
||||
CaFile: *serverCA,
|
||||
},
|
||||
},
|
||||
Mongo: Mongo{
|
||||
Uri: *mongoUri,
|
||||
|
|
|
|||
|
|
@ -77,8 +77,10 @@ func defineOptions(c config.Nats) []nats.Option {
|
|||
opts = append(opts, nats.ClosedHandler(func(nc *nats.Conn) {
|
||||
log.Printf("Connection closed. Reason: %q\n", nc.LastError())
|
||||
}))
|
||||
if c.VerifyCertificates {
|
||||
opts = append(opts, nats.RootCAs())
|
||||
if c.EnableTls {
|
||||
log.Printf("Load certificates: %s and %s\n", c.Cert.CertFile, c.Cert.KeyFile)
|
||||
opts = append(opts, nats.RootCAs(c.Cert.CaFile))
|
||||
opts = append(opts, nats.ClientCert(c.Cert.CertFile, c.Cert.KeyFile))
|
||||
}
|
||||
|
||||
return opts
|
||||
|
|
|
|||
|
|
@ -13,10 +13,17 @@ import (
|
|||
const LOCAL_ENV = ".env.local"
|
||||
|
||||
type Nats struct {
|
||||
Url string
|
||||
Name string
|
||||
VerifyCertificates bool
|
||||
Ctx context.Context
|
||||
Url string
|
||||
Name string
|
||||
EnableTls bool
|
||||
Cert Tls
|
||||
Ctx context.Context
|
||||
}
|
||||
|
||||
type Tls struct {
|
||||
CertFile string
|
||||
KeyFile string
|
||||
CaFile string
|
||||
}
|
||||
|
||||
type Mongo struct {
|
||||
|
|
@ -42,7 +49,10 @@ func NewConfig() *Config {
|
|||
|
||||
natsUrl := flag.String("nats_url", lookupEnvOrString("NATS_URL", "nats://localhost:4222"), "url for nats server")
|
||||
natsName := flag.String("nats_name", lookupEnvOrString("NATS_NAME", "adapter"), "name for nats client")
|
||||
natsVerifyCertificates := flag.Bool("nats_verify_certificates", lookupEnvOrBool("NATS_VERIFY_CERTIFICATES", false), "verify validity of certificates from nats server")
|
||||
natsEnableTls := flag.Bool("nats_enable_tls", lookupEnvOrBool("NATS_ENABLE_TLS", false), "enbale TLS to nats server")
|
||||
clientCrt := flag.String("client_crt", lookupEnvOrString("CLIENT_CRT", "cert.pem"), "client certificate file to TLS connection")
|
||||
clientKey := flag.String("client_key", lookupEnvOrString("CLIENT_KEY", "key.pem"), "client key file to TLS connection")
|
||||
serverCA := flag.String("server_ca", lookupEnvOrString("SERVER_CA", "rootCA.pem"), "server CA file to TLS connection")
|
||||
mongoUri := flag.String("mongo_uri", lookupEnvOrString("MONGO_URI", "mongodb://localhost:27017"), "uri for mongodb server")
|
||||
controllerId := flag.String("controller_id", lookupEnvOrString("CONTROLLER_ID", "oktopusController"), "usp controller endpoint id")
|
||||
controllerPassword := flag.String("controller_passwd", lookupEnvOrString("CONTROLLER_PASSWORD", ""), "usp controller endpoint password to connect to")
|
||||
|
|
@ -66,10 +76,15 @@ func NewConfig() *Config {
|
|||
|
||||
return &Config{
|
||||
Nats: Nats{
|
||||
Url: *natsUrl,
|
||||
Name: *natsName,
|
||||
VerifyCertificates: *natsVerifyCertificates,
|
||||
Ctx: ctx,
|
||||
Url: *natsUrl,
|
||||
Name: *natsName,
|
||||
EnableTls: *natsEnableTls,
|
||||
Ctx: ctx,
|
||||
Cert: Tls{
|
||||
CertFile: *clientCrt,
|
||||
KeyFile: *clientKey,
|
||||
CaFile: *serverCA,
|
||||
},
|
||||
},
|
||||
Mongo: Mongo{
|
||||
Uri: *mongoUri,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package cwmp_handler
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"encoding/xml"
|
||||
"log"
|
||||
|
||||
|
|
@ -12,6 +13,10 @@ func (h *Handler) HandleDeviceInfo(device string, data []byte, ack func()) {
|
|||
defer ack()
|
||||
log.Printf("Device %s info", device)
|
||||
deviceInfo := parseDeviceInfoMsg(data)
|
||||
if deviceExists, _ := h.db.DeviceExists(deviceInfo.SN); !deviceExists {
|
||||
fmtDeviceInfo, _ := json.Marshal(deviceInfo)
|
||||
h.nc.Publish("device.v1.new", fmtDeviceInfo)
|
||||
}
|
||||
err := h.db.CreateDevice(deviceInfo)
|
||||
if err != nil {
|
||||
log.Printf("Failed to create device: %v", err)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package usp_handler
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"log"
|
||||
|
||||
"github.com/OktopUSP/oktopus/backend/services/mtp/adapter/internal/db"
|
||||
|
|
@ -14,6 +15,10 @@ func (h *Handler) HandleDeviceInfo(device, subject string, data []byte, mtp stri
|
|||
defer ack()
|
||||
log.Printf("Device %s info, mtp: %s", device, mtp)
|
||||
deviceInfo := parseDeviceInfoMsg(device, subject, data, getMtp(mtp))
|
||||
if deviceExists, _ := h.db.DeviceExists(deviceInfo.SN); !deviceExists {
|
||||
fmtDeviceInfo, _ := json.Marshal(deviceInfo)
|
||||
h.nc.Publish("device.v1.new", fmtDeviceInfo)
|
||||
}
|
||||
err := h.db.CreateDevice(deviceInfo)
|
||||
if err != nil {
|
||||
log.Printf("Failed to create device: %v", err)
|
||||
|
|
|
|||
|
|
@ -150,8 +150,10 @@ func defineOptions(c config.Nats) []nats.Option {
|
|||
opts = append(opts, nats.ClosedHandler(func(nc *nats.Conn) {
|
||||
log.Printf("Connection closed. Reason: %q\n", nc.LastError())
|
||||
}))
|
||||
if c.VerifyCertificates {
|
||||
opts = append(opts, nats.RootCAs())
|
||||
if c.EnableTls {
|
||||
log.Printf("Load certificates: %s and %s\n", c.Cert.CertFile, c.Cert.KeyFile)
|
||||
opts = append(opts, nats.RootCAs(c.Cert.CaFile))
|
||||
opts = append(opts, nats.ClientCert(c.Cert.CertFile, c.Cert.KeyFile))
|
||||
}
|
||||
|
||||
return opts
|
||||
|
|
|
|||
|
|
@ -13,10 +13,17 @@ import (
|
|||
const LOCAL_ENV = ".env.local"
|
||||
|
||||
type Nats struct {
|
||||
Url string
|
||||
Name string
|
||||
VerifyCertificates bool
|
||||
Ctx context.Context
|
||||
Url string
|
||||
Name string
|
||||
EnableTls bool
|
||||
Cert Tls
|
||||
Ctx context.Context
|
||||
}
|
||||
|
||||
type Tls struct {
|
||||
CertFile string
|
||||
KeyFile string
|
||||
CaFile string
|
||||
}
|
||||
|
||||
type Mqtt struct {
|
||||
|
|
@ -42,7 +49,10 @@ func NewConfig() *Config {
|
|||
|
||||
natsUrl := flag.String("nats_url", lookupEnvOrString("NATS_URL", "nats://localhost:4222"), "url for nats server")
|
||||
natsName := flag.String("nats_name", lookupEnvOrString("NATS_NAME", "mqtt-adapter"), "name for nats client")
|
||||
natsVerifyCertificates := flag.Bool("nats_verify_certificates", lookupEnvOrBool("NATS_VERIFY_CERTIFICATES", false), "verify validity of certificates from nats server")
|
||||
natsEnableTls := flag.Bool("nats_enable_tls", lookupEnvOrBool("NATS_ENABLE_TLS", false), "enbale TLS to nats server")
|
||||
clientCrt := flag.String("client_crt", lookupEnvOrString("CLIENT_CRT", "cert.pem"), "client certificate file to TLS connection")
|
||||
clientKey := flag.String("client_key", lookupEnvOrString("CLIENT_KEY", "key.pem"), "client key file to TLS connection")
|
||||
serverCA := flag.String("server_ca", lookupEnvOrString("SERVER_CA", "rootCA.pem"), "server CA file to TLS connection")
|
||||
mqttUrl := flag.String("mqtt_url", lookupEnvOrString("MQTT_URL", "tcp://localhost:1883"), "url for mqtt server")
|
||||
mqttsUrl := flag.String("mqtts_url", lookupEnvOrString("MQTTS_URL", ""), "url for mqtts server")
|
||||
mqttsSkipVerify := flag.Bool("mqtts_skip_verify", lookupEnvOrBool("MQTTS_SKIP_VERIFY", false), "skip verification of server certificate for mqtts")
|
||||
|
|
@ -69,10 +79,15 @@ func NewConfig() *Config {
|
|||
|
||||
return &Config{
|
||||
Nats: Nats{
|
||||
Url: *natsUrl,
|
||||
Name: *natsName,
|
||||
VerifyCertificates: *natsVerifyCertificates,
|
||||
Ctx: ctx,
|
||||
Url: *natsUrl,
|
||||
Name: *natsName,
|
||||
EnableTls: *natsEnableTls,
|
||||
Ctx: ctx,
|
||||
Cert: Tls{
|
||||
CertFile: *clientCrt,
|
||||
KeyFile: *clientKey,
|
||||
CaFile: *serverCA,
|
||||
},
|
||||
},
|
||||
Mqtt: Mqtt{
|
||||
Url: *mqttUrl,
|
||||
|
|
|
|||
|
|
@ -92,8 +92,10 @@ func defineOptions(c config.Nats) []nats.Option {
|
|||
opts = append(opts, nats.ClosedHandler(func(nc *nats.Conn) {
|
||||
log.Printf("Connection closed. Reason: %q\n", nc.LastError())
|
||||
}))
|
||||
if c.VerifyCertificates {
|
||||
opts = append(opts, nats.RootCAs())
|
||||
if c.EnableTls {
|
||||
log.Printf("Load certificates: %s and %s\n", c.Cert.CertFile, c.Cert.KeyFile)
|
||||
opts = append(opts, nats.RootCAs(c.Cert.CaFile))
|
||||
opts = append(opts, nats.ClientCert(c.Cert.CertFile, c.Cert.KeyFile))
|
||||
}
|
||||
|
||||
return opts
|
||||
|
|
|
|||
|
|
@ -32,10 +32,17 @@ type Config struct {
|
|||
}
|
||||
|
||||
type Nats struct {
|
||||
Url string
|
||||
Name string
|
||||
VerifyCertificates bool
|
||||
Ctx context.Context
|
||||
Url string
|
||||
Name string
|
||||
EnableTls bool
|
||||
Cert Tls
|
||||
Ctx context.Context
|
||||
}
|
||||
|
||||
type Tls struct {
|
||||
CertFile string
|
||||
KeyFile string
|
||||
CaFile string
|
||||
}
|
||||
|
||||
func NewConfig() Config {
|
||||
|
|
@ -66,7 +73,10 @@ func NewConfig() Config {
|
|||
logLevel := flag.Int("log_level", lookupEnvOrInt("LOG_LEVEL", 1), "0=DEBUG, 1=INFO, 2=WARNING, 3=ERROR")
|
||||
natsUrl := flag.String("nats_url", lookupEnvOrString("NATS_URL", "nats://localhost:4222"), "url for nats server")
|
||||
natsName := flag.String("nats_name", lookupEnvOrString("NATS_NAME", "adapter"), "name for nats client")
|
||||
natsVerifyCertificates := flag.Bool("nats_verify_certificates", lookupEnvOrBool("NATS_VERIFY_CERTIFICATES", false), "verify validity of certificates from nats server")
|
||||
natsEnableTls := flag.Bool("nats_enable_tls", lookupEnvOrBool("NATS_ENABLE_TLS", false), "enbale TLS to nats server")
|
||||
clientCrt := flag.String("client_crt", lookupEnvOrString("CLIENT_CRT", "cert.pem"), "client certificate file to TLS connection")
|
||||
clientKey := flag.String("client_key", lookupEnvOrString("CLIENT_KEY", "key.pem"), "client key file to TLS connection")
|
||||
serverCA := flag.String("server_ca", lookupEnvOrString("SERVER_CA", "rootCA.pem"), "server CA file to TLS connection")
|
||||
|
||||
flag.Parse()
|
||||
flHelp := flag.Bool("help", false, "Help")
|
||||
|
|
@ -99,10 +109,15 @@ func NewConfig() Config {
|
|||
HttpPort: *httpPort,
|
||||
LogLevel: *logLevel,
|
||||
Nats: Nats{
|
||||
Url: *natsUrl,
|
||||
Name: *natsName,
|
||||
VerifyCertificates: *natsVerifyCertificates,
|
||||
Ctx: ctx,
|
||||
Url: *natsUrl,
|
||||
Name: *natsName,
|
||||
EnableTls: *natsEnableTls,
|
||||
Ctx: ctx,
|
||||
Cert: Tls{
|
||||
CertFile: *clientCrt,
|
||||
KeyFile: *clientKey,
|
||||
CaFile: *serverCA,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -74,8 +74,10 @@ func defineOptions(c config.Nats) []nats.Option {
|
|||
opts = append(opts, nats.ClosedHandler(func(nc *nats.Conn) {
|
||||
log.Printf("Connection closed. Reason: %q\n", nc.LastError())
|
||||
}))
|
||||
if c.VerifyCertificates {
|
||||
opts = append(opts, nats.RootCAs())
|
||||
if c.EnableTls {
|
||||
log.Printf("Load certificates: %s and %s\n", c.Cert.CertFile, c.Cert.KeyFile)
|
||||
opts = append(opts, nats.RootCAs(c.Cert.CaFile))
|
||||
opts = append(opts, nats.ClientCert(c.Cert.CertFile, c.Cert.KeyFile))
|
||||
}
|
||||
|
||||
return opts
|
||||
|
|
|
|||
|
|
@ -13,10 +13,17 @@ import (
|
|||
const LOCAL_ENV = ".env.local"
|
||||
|
||||
type Nats struct {
|
||||
Url string
|
||||
Name string
|
||||
VerifyCertificates bool
|
||||
Ctx context.Context
|
||||
Url string
|
||||
Name string
|
||||
EnableTls bool
|
||||
Cert Tls
|
||||
Ctx context.Context
|
||||
}
|
||||
|
||||
type Tls struct {
|
||||
CertFile string
|
||||
KeyFile string
|
||||
CaFile string
|
||||
}
|
||||
|
||||
type Stomp struct {
|
||||
|
|
@ -37,7 +44,10 @@ func NewConfig() *Config {
|
|||
|
||||
natsUrl := flag.String("nats_url", lookupEnvOrString("NATS_URL", "nats://localhost:4222"), "url for nats server")
|
||||
natsName := flag.String("nats_name", lookupEnvOrString("NATS_NAME", "mqtt-adapter"), "name for nats client")
|
||||
natsVerifyCertificates := flag.Bool("nats_verify_certificates", lookupEnvOrBool("NATS_VERIFY_CERTIFICATES", false), "verify validity of certificates from nats server")
|
||||
natsEnableTls := flag.Bool("nats_enable_tls", lookupEnvOrBool("NATS_ENABLE_TLS", false), "enbale TLS to nats server")
|
||||
clientCrt := flag.String("client_crt", lookupEnvOrString("CLIENT_CRT", "cert.pem"), "client certificate file to TLS connection")
|
||||
clientKey := flag.String("client_key", lookupEnvOrString("CLIENT_KEY", "key.pem"), "client key file to TLS connection")
|
||||
serverCA := flag.String("server_ca", lookupEnvOrString("SERVER_CA", "rootCA.pem"), "server CA file to TLS connection")
|
||||
stompAddr := flag.String("stomp_server", lookupEnvOrString("STOMP_SERVER", "localhost:61613"), "STOMP server endpoint")
|
||||
stompUser := flag.String("stomp_user", lookupEnvOrString("STOMP_USER", ""), "stomp server user")
|
||||
stompPassword := flag.String("stomp_passsword", lookupEnvOrString("STOMP_PASSWD", ""), "stomp server password")
|
||||
|
|
@ -61,10 +71,15 @@ func NewConfig() *Config {
|
|||
|
||||
return &Config{
|
||||
Nats: Nats{
|
||||
Url: *natsUrl,
|
||||
Name: *natsName,
|
||||
VerifyCertificates: *natsVerifyCertificates,
|
||||
Ctx: ctx,
|
||||
Url: *natsUrl,
|
||||
Name: *natsName,
|
||||
EnableTls: *natsEnableTls,
|
||||
Ctx: ctx,
|
||||
Cert: Tls{
|
||||
CertFile: *clientCrt,
|
||||
KeyFile: *clientKey,
|
||||
CaFile: *serverCA,
|
||||
},
|
||||
},
|
||||
Stomp: Stomp{
|
||||
Url: *stompAddr,
|
||||
|
|
|
|||
|
|
@ -81,9 +81,10 @@ func defineOptions(c config.Nats) []nats.Option {
|
|||
opts = append(opts, nats.ClosedHandler(func(nc *nats.Conn) {
|
||||
log.Printf("Connection closed. Reason: %q\n", nc.LastError())
|
||||
}))
|
||||
if c.VerifyCertificates {
|
||||
opts = append(opts, nats.RootCAs())
|
||||
if c.EnableTls {
|
||||
log.Printf("Load certificates: %s and %s\n", c.Cert.CertFile, c.Cert.KeyFile)
|
||||
opts = append(opts, nats.RootCAs(c.Cert.CaFile))
|
||||
opts = append(opts, nats.ClientCert(c.Cert.CertFile, c.Cert.KeyFile))
|
||||
}
|
||||
|
||||
return opts
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,10 +13,17 @@ import (
|
|||
const LOCAL_ENV = ".env.local"
|
||||
|
||||
type Nats struct {
|
||||
Url string
|
||||
Name string
|
||||
VerifyCertificates bool
|
||||
Ctx context.Context
|
||||
Url string
|
||||
Name string
|
||||
EnableTls bool
|
||||
Cert Tls
|
||||
Ctx context.Context
|
||||
}
|
||||
|
||||
type Tls struct {
|
||||
CertFile string
|
||||
KeyFile string
|
||||
CaFile string
|
||||
}
|
||||
|
||||
type Ws struct {
|
||||
|
|
@ -42,7 +49,10 @@ func NewConfig() *Config {
|
|||
|
||||
natsUrl := flag.String("nats_url", lookupEnvOrString("NATS_URL", "nats://localhost:4222"), "url for nats server")
|
||||
natsName := flag.String("nats_name", lookupEnvOrString("NATS_NAME", "ws-adapter"), "name for nats client")
|
||||
natsVerifyCertificates := flag.Bool("nats_verify_certificates", lookupEnvOrBool("NATS_VERIFY_CERTIFICATES", false), "verify validity of certificates from nats server")
|
||||
natsEnableTls := flag.Bool("nats_enable_tls", lookupEnvOrBool("NATS_ENABLE_TLS", false), "enbale TLS to nats server")
|
||||
clientCrt := flag.String("client_crt", lookupEnvOrString("CLIENT_CRT", "cert.pem"), "client certificate file to TLS connection")
|
||||
clientKey := flag.String("client_key", lookupEnvOrString("CLIENT_KEY", "key.pem"), "client key file to TLS connection")
|
||||
serverCA := flag.String("server_ca", lookupEnvOrString("SERVER_CA", "rootCA.pem"), "server CA file to TLS connection")
|
||||
wsAuthEnable := flag.Bool("ws_auth_enable", lookupEnvOrBool("WS_AUTH_ENABLE", false), "enable authentication for websocket server")
|
||||
wsAddr := flag.String("ws_addr", lookupEnvOrString("WS_ADDR", "localhost"), "websocket server address (domain or ip)")
|
||||
wsPort := flag.String("ws_port", lookupEnvOrString("WS_PORT", ":8080"), "websocket server port")
|
||||
|
|
@ -68,10 +78,15 @@ func NewConfig() *Config {
|
|||
|
||||
return &Config{
|
||||
Nats: Nats{
|
||||
Url: *natsUrl,
|
||||
Name: *natsName,
|
||||
VerifyCertificates: *natsVerifyCertificates,
|
||||
Ctx: ctx,
|
||||
Url: *natsUrl,
|
||||
Name: *natsName,
|
||||
EnableTls: *natsEnableTls,
|
||||
Ctx: ctx,
|
||||
Cert: Tls{
|
||||
CertFile: *clientCrt,
|
||||
KeyFile: *clientKey,
|
||||
CaFile: *serverCA,
|
||||
},
|
||||
},
|
||||
Ws: Ws{
|
||||
AuthEnable: *wsAuthEnable,
|
||||
|
|
|
|||
|
|
@ -91,8 +91,10 @@ func defineOptions(c config.Nats) []nats.Option {
|
|||
opts = append(opts, nats.ClosedHandler(func(nc *nats.Conn) {
|
||||
log.Printf("Connection closed. Reason: %q\n", nc.LastError())
|
||||
}))
|
||||
if c.VerifyCertificates {
|
||||
opts = append(opts, nats.RootCAs())
|
||||
if c.EnableTls {
|
||||
log.Printf("Load certificates: %s and %s\n", c.Cert.CertFile, c.Cert.KeyFile)
|
||||
opts = append(opts, nats.RootCAs(c.Cert.CaFile))
|
||||
opts = append(opts, nats.ClientCert(c.Cert.CertFile, c.Cert.KeyFile))
|
||||
}
|
||||
|
||||
return opts
|
||||
|
|
|
|||
|
|
@ -24,10 +24,17 @@ type Config struct {
|
|||
}
|
||||
|
||||
type Nats struct {
|
||||
Url string
|
||||
Name string
|
||||
VerifyCertificates bool
|
||||
Ctx context.Context
|
||||
Url string
|
||||
Name string
|
||||
EnableTls bool
|
||||
Cert Tls
|
||||
Ctx context.Context
|
||||
}
|
||||
|
||||
type Tls struct {
|
||||
CertFile string
|
||||
KeyFile string
|
||||
CaFile string
|
||||
}
|
||||
|
||||
func NewConfig() Config {
|
||||
|
|
@ -47,7 +54,10 @@ func NewConfig() Config {
|
|||
/* ------------------------------ define flags ------------------------------ */
|
||||
natsUrl := flag.String("nats_url", lookupEnvOrString("NATS_URL", "nats://localhost:4222"), "url for nats server")
|
||||
natsName := flag.String("nats_name", lookupEnvOrString("NATS_NAME", "ws-adapter"), "name for nats client")
|
||||
natsVerifyCertificates := flag.Bool("nats_verify_certificates", lookupEnvOrBool("NATS_VERIFY_CERTIFICATES", false), "verify validity of certificates from nats server")
|
||||
natsEnableTls := flag.Bool("nats_enable_tls", lookupEnvOrBool("NATS_ENABLE_TLS", false), "enbale TLS to nats server")
|
||||
clientCrt := flag.String("client_crt", lookupEnvOrString("CLIENT_CRT", "cert.pem"), "client certificate file to TLS connection")
|
||||
clientKey := flag.String("client_key", lookupEnvOrString("CLIENT_KEY", "key.pem"), "client key file to TLS connection")
|
||||
serverCA := flag.String("server_ca", lookupEnvOrString("SERVER_CA", "rootCA.pem"), "server CA file to TLS connection")
|
||||
flPort := flag.String("port", lookupEnvOrString("SERVER_PORT", ":8080"), "Server port")
|
||||
flAuth := flag.Bool("auth", lookupEnvOrBool("SERVER_AUTH_ENABLE", false), "Server auth enable/disable")
|
||||
flControllerEid := flag.String("controller-eid", lookupEnvOrString("CONTROLLER_EID", "oktopusController"), "Controller eid")
|
||||
|
|
@ -81,10 +91,15 @@ func NewConfig() Config {
|
|||
FullChain: *flFullchain,
|
||||
PrivateKey: *flPrivKey,
|
||||
Nats: Nats{
|
||||
Url: *natsUrl,
|
||||
Name: *natsName,
|
||||
VerifyCertificates: *natsVerifyCertificates,
|
||||
Ctx: ctx,
|
||||
Url: *natsUrl,
|
||||
Name: *natsName,
|
||||
EnableTls: *natsEnableTls,
|
||||
Ctx: ctx,
|
||||
Cert: Tls{
|
||||
CertFile: *clientCrt,
|
||||
KeyFile: *clientKey,
|
||||
CaFile: *serverCA,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,8 +66,10 @@ func defineOptions(c config.Nats) []nats.Option {
|
|||
opts = append(opts, nats.ClosedHandler(func(nc *nats.Conn) {
|
||||
log.Printf("Connection closed. Reason: %q\n", nc.LastError())
|
||||
}))
|
||||
if c.VerifyCertificates {
|
||||
opts = append(opts, nats.RootCAs())
|
||||
if c.EnableTls {
|
||||
log.Printf("Load certificates: %s and %s\n", c.Cert.CertFile, c.Cert.KeyFile)
|
||||
opts = append(opts, nats.RootCAs(c.Cert.CaFile))
|
||||
opts = append(opts, nats.ClientCert(c.Cert.CertFile, c.Cert.KeyFile))
|
||||
}
|
||||
|
||||
return opts
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
DIRECTORY_PATH="./firmwares"
|
||||
DIRECTORY_PATH="."
|
||||
SERVER_PORT=":8004"
|
||||
|
|
@ -1,2 +1,3 @@
|
|||
firmwares/
|
||||
.env.local
|
||||
images/
|
||||
8
backend/services/utils/file-server/build/Dockerfile
Normal file
8
backend/services/utils/file-server/build/Dockerfile
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
FROM golang:1.22.2@sha256:450e3822c7a135e1463cd83e51c8e2eb03b86a02113c89424e6f0f8344bb4168 as builder
|
||||
WORKDIR /app
|
||||
COPY ../ .
|
||||
RUN CGO_ENABLED=0 GOOS=linux go build -o file-server main.go
|
||||
|
||||
FROM alpine:3.14@sha256:0f2d5c38dd7a4f4f733e688e3a6733cb5ab1ac6e3cb4603a5dd564e5bfb80eed
|
||||
COPY --from=builder /app/file-server /
|
||||
ENTRYPOINT ["/file-server"]
|
||||
61
backend/services/utils/file-server/build/Makefile
Normal file
61
backend/services/utils/file-server/build/Makefile
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
.PHONY: help build push start stop release remove delete run logs bash
|
||||
|
||||
DOCKER_USER ?= oktopusp
|
||||
DOCKER_APP ?= file-server
|
||||
DOCKER_TAG ?= $(shell git log --format="%h" -n 1)
|
||||
CONTAINER_SHELL ?= /bin/sh
|
||||
|
||||
.DEFAULT_GOAL := help
|
||||
|
||||
help:
|
||||
@echo "Makefile arguments:"
|
||||
@echo ""
|
||||
@echo "DOCKER_USER - docker user to build image"
|
||||
@echo "DOCKER_APP - docker image name"
|
||||
@echo "DOCKER_TAG - docker image tag"
|
||||
@echo "CONTAINER_SHELL - container shell e.g:'/bin/bash'"
|
||||
@echo ""
|
||||
@echo "Makefile commands:"
|
||||
@echo ""
|
||||
@echo "build - docker image build"
|
||||
@echo "push - push docker iamge to registry"
|
||||
@echo "run - create and start docker container with the image"
|
||||
@echo "start - start existent docker container with the image"
|
||||
@echo "stop - stop docker container running the image"
|
||||
@echo "remove - remove docker container running the image"
|
||||
@echo "delete - delete docker image"
|
||||
@echo "logs - show logs of docker container"
|
||||
@echo "bash - access container shell"
|
||||
@echo "release - tag image as latest and push to registry"
|
||||
|
||||
build:
|
||||
@docker build -t ${DOCKER_USER}/${DOCKER_APP}:${DOCKER_TAG} -f Dockerfile ../
|
||||
|
||||
run:
|
||||
@docker run -d --name ${DOCKER_USER}-${DOCKER_APP} ${DOCKER_USER}/${DOCKER_APP}:${DOCKER_TAG}
|
||||
|
||||
stop:
|
||||
@docker stop ${DOCKER_USER}-${DOCKER_APP}
|
||||
|
||||
remove: stop
|
||||
@docker rm ${DOCKER_USER}-${DOCKER_APP}
|
||||
|
||||
delete:
|
||||
@docker rmi ${DOCKER_USER}/${DOCKER_APP}:${DOCKER_TAG}
|
||||
|
||||
start:
|
||||
@docker start ${DOCKER_USER}-${DOCKER_APP}
|
||||
|
||||
push:
|
||||
@docker push ${DOCKER_USER}/${DOCKER_APP}:${DOCKER_TAG}
|
||||
|
||||
logs:
|
||||
@docker logs -f ${DOCKER_USER}-${DOCKER_APP}
|
||||
|
||||
bash:
|
||||
@docker exec -it ${DOCKER_USER}-${DOCKER_APP} ${CONTAINER_SHELL}
|
||||
|
||||
release: build
|
||||
@docker push ${DOCKER_USER}/${DOCKER_APP}:${DOCKER_TAG}
|
||||
@docker tag ${DOCKER_USER}/${DOCKER_APP}:${DOCKER_TAG} ${DOCKER_USER}/${DOCKER_APP}:latest
|
||||
@docker push ${DOCKER_USER}/${DOCKER_APP}:latest
|
||||
|
|
@ -42,7 +42,7 @@ func main() {
|
|||
http.Handle("/", fileServer)
|
||||
|
||||
port := os.Getenv("SERVER_PORT")
|
||||
fmt.Printf("Server started at http://localhost:%s\n", port)
|
||||
fmt.Printf("Server started at http://localhost%s\n", port)
|
||||
err = http.ListenAndServe(port, nil)
|
||||
if err != nil {
|
||||
fmt.Printf("Error starting server: %s\n", err)
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ build-backend:
|
|||
@make build -C ../backend/services/controller/build/ DOCKER_USER=${DOCKER_USER}
|
||||
@make build -C ../backend/services/acs/build/ DOCKER_USER=${DOCKER_USER}
|
||||
@make build -C ../backend/services/utils/socketio/build/ DOCKER_USER=${DOCKER_USER}
|
||||
@make build -C ../backend/services/utils/file-server/build/ DOCKER_USER=${DOCKER_USER}
|
||||
@make build -C ../backend/services/mtp/adapter/build/ DOCKER_USER=${DOCKER_USER}
|
||||
@make build -C ../backend/services/mtp/ws-adapter/build/ DOCKER_USER=${DOCKER_USER}
|
||||
@make build -C ../backend/services/mtp/ws/build/ DOCKER_USER=${DOCKER_USER}
|
||||
|
|
@ -43,6 +44,7 @@ release-backend:
|
|||
@make release -C ../backend/services/controller/build/ DOCKER_USER=${DOCKER_USER}
|
||||
@make release -C ../backend/services/acs/build/ DOCKER_USER=${DOCKER_USER}
|
||||
@make release -C ../backend/services/utils/socketio/build/ DOCKER_USER=${DOCKER_USER}
|
||||
@make release -C ../backend/services/utils/file-server/build/ DOCKER_USER=${DOCKER_USER}
|
||||
@make release -C ../backend/services/mtp/adapter/build/ DOCKER_USER=${DOCKER_USER}
|
||||
@make release -C ../backend/services/mtp/ws-adapter/build/ DOCKER_USER=${DOCKER_USER}
|
||||
@make release -C ../backend/services/mtp/ws/build/ DOCKER_USER=${DOCKER_USER}
|
||||
|
|
|
|||
|
|
@ -1 +1,5 @@
|
|||
NATS_URL=nats://msg_broker:4222
|
||||
NATS_URL=nats://oktopususer:oktopuspw@msg_broker:4222
|
||||
NATS_ENABLE_TLS="true"
|
||||
CLIENT_CRT=/tmp/nats/config/cert.pem
|
||||
CLIENT_KEY=/tmp/nats/config/key.pem
|
||||
SERVER_CA=/tmp/nats/config/rootCA.pem
|
||||
|
|
|
|||
|
|
@ -1,2 +1,6 @@
|
|||
NATS_URL=nats://msg_broker:4222
|
||||
MONGO_URI=mongodb://mongo_usp:27017
|
||||
NATS_URL=nats://oktopususer:oktopuspw@msg_broker:4222
|
||||
NATS_ENABLE_TLS="true"
|
||||
CLIENT_CRT=/tmp/nats/config/cert.pem
|
||||
CLIENT_KEY=/tmp/nats/config/key.pem
|
||||
SERVER_CA=/tmp/nats/config/rootCA.pem
|
||||
|
|
|
|||
|
|
@ -1,2 +1,6 @@
|
|||
NATS_URL=nats://msg_broker:4222
|
||||
MONGO_URI=mongodb://mongo_usp:27017
|
||||
NATS_URL=nats://oktopususer:oktopuspw@msg_broker:4222
|
||||
NATS_ENABLE_TLS="true"
|
||||
CLIENT_CRT=/tmp/nats/config/cert.pem
|
||||
CLIENT_KEY=/tmp/nats/config/key.pem
|
||||
SERVER_CA=/tmp/nats/config/rootCA.pem
|
||||
|
|
|
|||
2
deploy/compose/.env.file-server
Normal file
2
deploy/compose/.env.file-server
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
DIRECTORY_PATH="."
|
||||
SERVER_PORT=":8004"
|
||||
|
|
@ -1,3 +1,7 @@
|
|||
REDIS_ENABLE=false
|
||||
REDIS_ADDR=redis_usp:6379
|
||||
NATS_URL=nats://msg_broker:4222
|
||||
NATS_URL=nats://oktopususer:oktopuspw@msg_broker:4222
|
||||
NATS_ENABLE_TLS="true"
|
||||
CLIENT_CRT=/tmp/nats/config/cert.pem
|
||||
CLIENT_KEY=/tmp/nats/config/key.pem
|
||||
SERVER_CA=/tmp/nats/config/rootCA.pem
|
||||
|
|
|
|||
|
|
@ -1,2 +1,6 @@
|
|||
NATS_URL=nats://msg_broker:4222
|
||||
MQTT_URL=tcp://mqtt:1883
|
||||
NATS_URL=nats://oktopususer:oktopuspw@msg_broker:4222
|
||||
NATS_ENABLE_TLS="true"
|
||||
CLIENT_CRT=/tmp/nats/config/cert.pem
|
||||
CLIENT_KEY=/tmp/nats/config/key.pem
|
||||
SERVER_CA=/tmp/nats/config/rootCA.pem
|
||||
|
|
|
|||
3
deploy/compose/.env.nats
Normal file
3
deploy/compose/.env.nats
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
NATS_NAME=oktopus
|
||||
NATS_USER=oktopususer
|
||||
NATS_PW=oktopuspw
|
||||
|
|
@ -1 +1,5 @@
|
|||
NATS_URL=nats://msg_broker:4222
|
||||
NATS_URL=nats://oktopususer:oktopuspw@msg_broker:4222
|
||||
NATS_ENABLE_TLS="true"
|
||||
CLIENT_CRT=/tmp/nats/config/cert.pem
|
||||
CLIENT_KEY=/tmp/nats/config/key.pem
|
||||
SERVER_CA=/tmp/nats/config/rootCA.pem
|
||||
|
|
|
|||
|
|
@ -1,2 +1,6 @@
|
|||
NATS_URL=nats://msg_broker:4222
|
||||
STOMP_SERVER=stomp:61613
|
||||
NATS_URL=nats://oktopususer:oktopuspw@msg_broker:4222
|
||||
NATS_ENABLE_TLS="true"
|
||||
CLIENT_CRT=/tmp/nats/config/cert.pem
|
||||
CLIENT_KEY=/tmp/nats/config/key.pem
|
||||
SERVER_CA=/tmp/nats/config/rootCA.pem
|
||||
|
|
|
|||
|
|
@ -1 +1,5 @@
|
|||
NATS_URL=nats://msg_broker:4222
|
||||
NATS_URL=nats://oktopususer:oktopuspw@msg_broker:4222
|
||||
NATS_ENABLE_TLS="true"
|
||||
CLIENT_CRT=/tmp/nats/config/cert.pem
|
||||
CLIENT_KEY=/tmp/nats/config/key.pem
|
||||
SERVER_CA=/tmp/nats/config/rootCA.pem
|
||||
|
|
|
|||
|
|
@ -1,2 +1,6 @@
|
|||
NATS_URL=nats://msg_broker:4222
|
||||
WS_ADDR=ws
|
||||
NATS_URL=nats://oktopususer:oktopuspw@msg_broker:4222
|
||||
NATS_ENABLE_TLS="true"
|
||||
CLIENT_CRT=/tmp/nats/config/cert.pem
|
||||
CLIENT_KEY=/tmp/nats/config/key.pem
|
||||
SERVER_CA=/tmp/nats/config/rootCA.pem
|
||||
|
|
|
|||
4
deploy/compose/.gitignore
vendored
4
deploy/compose/.gitignore
vendored
|
|
@ -4,3 +4,7 @@ mongo_data/*
|
|||
!mongo_data/.gitkeep
|
||||
nats_data/*
|
||||
!nats_data/.gitkeep
|
||||
firmwares/*
|
||||
!firmwares/.gitkeep
|
||||
images/*
|
||||
!images/logo.png
|
||||
|
|
@ -1,38 +1,42 @@
|
|||
services:
|
||||
|
||||
#/* ----------------------------- Message Broker ----------------------------- */
|
||||
#/* ----------------------------- Message Broker ----------------------------- */
|
||||
msg_broker:
|
||||
image: 'nats:latest'
|
||||
image: "nats:latest"
|
||||
container_name: nats
|
||||
ports:
|
||||
- 4222:4222
|
||||
- 8222:8222
|
||||
command: -n oktopus -m 8222 -js
|
||||
command: -c /tmp/nats/config/nats.cfg
|
||||
env_file:
|
||||
- .env.nats
|
||||
volumes:
|
||||
- ./nats_data:/tmp/nats/jetstream
|
||||
- ./nats_config:/tmp/nats/config
|
||||
networks:
|
||||
usp_network:
|
||||
ipv4_address: 172.16.235.2
|
||||
profiles: [nats]
|
||||
#/* -------------------------------------------------------------------------- */
|
||||
#/* -------------------------------------------------------------------------- */
|
||||
|
||||
#/* ------------------------ API REST / USP Controller ----------------------- */
|
||||
#/* ------------------------ API REST / USP Controller ----------------------- */
|
||||
controller:
|
||||
image: 'oktopusp/controller'
|
||||
image: "oktopusp/controller"
|
||||
container_name: controller
|
||||
ports:
|
||||
- 8000:8000
|
||||
- 8000:8000
|
||||
depends_on:
|
||||
- mongo_usp
|
||||
- mongo_usp
|
||||
env_file:
|
||||
- .env.controller
|
||||
volumes:
|
||||
- ./nats_config:/tmp/nats/config
|
||||
networks:
|
||||
usp_network:
|
||||
ipv4_address: 172.16.235.3
|
||||
profiles: [controller]
|
||||
#/* -------------------------------------------------------------------------- */
|
||||
#/* -------------------------------------------------------------------------- */
|
||||
|
||||
#/* ---------------------------- Databases / Cache --------------------------- */
|
||||
#/* ---------------------------- Databases / Cache --------------------------- */
|
||||
mongo_usp:
|
||||
image: mongo
|
||||
container_name: mongo_usp
|
||||
|
|
@ -43,115 +47,128 @@ services:
|
|||
ipv4_address: 172.16.235.4
|
||||
volumes:
|
||||
- ./mongo_data:/data/db
|
||||
profiles: [controller,adapter]
|
||||
profiles: [controller, adapter]
|
||||
|
||||
#/* -------------------------------------------------------------------------- */
|
||||
#/* -------------------------------------------------------------------------- */
|
||||
|
||||
#/* ----------------------- Message Transfer Protocols ----------------------- */
|
||||
#/* ----------------------- Message Transfer Protocols ----------------------- */
|
||||
mqtt:
|
||||
image: 'oktopusp/mqtt'
|
||||
image: "oktopusp/mqtt"
|
||||
container_name: mqtt
|
||||
ports:
|
||||
- 1883:1883
|
||||
- 8883:8883
|
||||
- 1883:1883
|
||||
- 8883:8883
|
||||
env_file:
|
||||
- .env.mqtt
|
||||
volumes:
|
||||
- ./nats_config:/tmp/nats/config
|
||||
networks:
|
||||
usp_network:
|
||||
ipv4_address: 172.16.235.6
|
||||
profiles: [mqtt]
|
||||
|
||||
ws:
|
||||
image: 'oktopusp/ws'
|
||||
image: "oktopusp/ws"
|
||||
container_name: websockets
|
||||
ports:
|
||||
- 8080:8080
|
||||
- 8080:8080
|
||||
env_file:
|
||||
- .env.ws
|
||||
volumes:
|
||||
- ./nats_config:/tmp/nats/config
|
||||
networks:
|
||||
usp_network:
|
||||
ipv4_address: 172.16.235.7
|
||||
profiles: [ws]
|
||||
|
||||
stomp:
|
||||
image: 'oktopusp/stomp'
|
||||
image: "oktopusp/stomp"
|
||||
container_name: stomp
|
||||
ports:
|
||||
- 61613:61613
|
||||
- 61613:61613
|
||||
networks:
|
||||
usp_network:
|
||||
ipv4_address: 172.16.235.8
|
||||
profiles: [stomp]
|
||||
#/* -------------------------------------------------------------------------- */
|
||||
#/* -------------------------------------------------------------------------- */
|
||||
|
||||
#/* --------------- Message transfer Protocols Adapters to NATS -------------- */
|
||||
#/* --------------- Message transfer Protocols Adapters to NATS -------------- */
|
||||
mqtt-adapter:
|
||||
image: 'oktopusp/mqtt-adapter'
|
||||
image: "oktopusp/mqtt-adapter"
|
||||
container_name: mqtt-adapter
|
||||
depends_on:
|
||||
- mqtt
|
||||
env_file:
|
||||
- .env.mqtt-adapter
|
||||
volumes:
|
||||
- ./nats_config:/tmp/nats/config
|
||||
networks:
|
||||
usp_network:
|
||||
ipv4_address: 172.16.235.9
|
||||
profiles: [mqtt]
|
||||
|
||||
|
||||
ws-adapter:
|
||||
image: 'oktopusp/ws-adapter'
|
||||
image: "oktopusp/ws-adapter"
|
||||
container_name: ws-adapter
|
||||
depends_on:
|
||||
- ws
|
||||
env_file:
|
||||
- .env.ws-adapter
|
||||
volumes:
|
||||
- ./nats_config:/tmp/nats/config
|
||||
networks:
|
||||
usp_network:
|
||||
ipv4_address: 172.16.235.10
|
||||
profiles: [ws]
|
||||
|
||||
stomp-adapter:
|
||||
image: 'oktopusp/stomp-adapter'
|
||||
image: "oktopusp/stomp-adapter"
|
||||
container_name: stomp-adapter
|
||||
depends_on:
|
||||
- stomp
|
||||
env_file:
|
||||
- .env.stomp-adapter
|
||||
volumes:
|
||||
- ./nats_config:/tmp/nats/config
|
||||
networks:
|
||||
usp_network:
|
||||
ipv4_address: 172.16.235.11
|
||||
profiles: [stomp]
|
||||
|
||||
adapter:
|
||||
image: 'oktopusp/adapter'
|
||||
image: "oktopusp/adapter"
|
||||
container_name: adapter
|
||||
depends_on:
|
||||
- mongo_usp
|
||||
env_file:
|
||||
- .env.adapter
|
||||
volumes:
|
||||
- ./nats_config:/tmp/nats/config
|
||||
networks:
|
||||
usp_network:
|
||||
ipv4_address: 172.16.235.12
|
||||
profiles: [adapter]
|
||||
#/* -------------------------------------------------------------------------- */
|
||||
#/* -------------------------------------------------------------------------- */
|
||||
|
||||
#/* ------------- SocketIO Real Time Communication With Frontend ------------- */
|
||||
#/* ------------- SocketIO Real Time Communication With Frontend ------------- */
|
||||
socketio:
|
||||
image: 'oktopusp/socketio'
|
||||
image: "oktopusp/socketio"
|
||||
container_name: socketio
|
||||
ports:
|
||||
- 5000:5000
|
||||
- 5000:5000
|
||||
env_file:
|
||||
- .env.socketio
|
||||
volumes:
|
||||
- ./nats_config:/tmp/nats/config
|
||||
networks:
|
||||
usp_network:
|
||||
ipv4_address: 172.16.235.13
|
||||
profiles: [frontend]
|
||||
#/* -------------------------------------------------------------------------- */
|
||||
#/* -------------------------------------------------------------------------- */
|
||||
|
||||
#/* -------------------------------- Frontend -------------------------------- */
|
||||
#/* -------------------------------- Frontend -------------------------------- */
|
||||
frontend:
|
||||
image: 'oktopusp/frontend-ce'
|
||||
image: "oktopusp/frontend-ce"
|
||||
container_name: frontend
|
||||
ports:
|
||||
- 3000:3000
|
||||
|
|
@ -159,7 +176,7 @@ services:
|
|||
usp_network:
|
||||
ipv4_address: 172.16.235.14
|
||||
profiles: [frontend]
|
||||
#/* -------------------------------------------------------------------------- */
|
||||
#/* -------------------------------------------------------------------------- */
|
||||
|
||||
portainer:
|
||||
image: portainer/portainer-ce:latest
|
||||
|
|
@ -175,12 +192,14 @@ services:
|
|||
- ./portainer_data:/data
|
||||
|
||||
acs:
|
||||
image: oktopusp/acs
|
||||
image: "oktopusp/acs"
|
||||
container_name: acs
|
||||
ports:
|
||||
- 9292:9292
|
||||
env_file:
|
||||
- .env.acs
|
||||
volumes:
|
||||
- ./nats_config:/tmp/nats/config
|
||||
networks:
|
||||
usp_network:
|
||||
ipv4_address: 172.16.235.16
|
||||
|
|
@ -191,18 +210,30 @@ services:
|
|||
container_name: nginx
|
||||
ports:
|
||||
- 80:80
|
||||
depends_on:
|
||||
- frontend
|
||||
- controller
|
||||
- socketio
|
||||
volumes:
|
||||
- ./nginx.conf:/etc/nginx/conf.d/default.conf
|
||||
extra_hosts:
|
||||
- "host.docker.internal:host-gateway"
|
||||
networks:
|
||||
usp_network:
|
||||
ipv4_address: 172.16.235.17
|
||||
|
||||
file-server:
|
||||
image: oktopusp/file-server
|
||||
container_name: file-server
|
||||
ports:
|
||||
- 8004:8004
|
||||
volumes:
|
||||
- ./firmwares:/app/firmwares
|
||||
- ./images:/app/images
|
||||
env_file:
|
||||
- .env.file-server
|
||||
networks:
|
||||
usp_network:
|
||||
ipv4_address: 172.16.235.18
|
||||
|
||||
networks:
|
||||
usp_network:
|
||||
usp_network:
|
||||
driver: bridge
|
||||
ipam:
|
||||
driver: default
|
||||
|
|
|
|||
0
deploy/compose/firmwares/.gitkeep
Normal file
0
deploy/compose/firmwares/.gitkeep
Normal file
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
26
deploy/compose/nats_config/cert.pem
Normal file
26
deploy/compose/nats_config/cert.pem
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIEeTCCAuGgAwIBAgIRAJenDys60PD3Cjh9VXeAzsowDQYJKoZIhvcNAQELBQAw
|
||||
gY0xHjAcBgNVBAoTFW1rY2VydCBkZXZlbG9wbWVudCBDQTExMC8GA1UECwwoY2hp
|
||||
ZXNhQEFkcmlhbm9NYWMubG9jYWwgKEFkcmlhbm8gQ2hpZXNhKTE4MDYGA1UEAwwv
|
||||
bWtjZXJ0IGNoaWVzYUBBZHJpYW5vTWFjLmxvY2FsIChBZHJpYW5vIENoaWVzYSkw
|
||||
HhcNMjQwNzA2MTQzODQ2WhcNMjYxMDA2MTQzODQ2WjBcMScwJQYDVQQKEx5ta2Nl
|
||||
cnQgZGV2ZWxvcG1lbnQgY2VydGlmaWNhdGUxMTAvBgNVBAsMKGNoaWVzYUBBZHJp
|
||||
YW5vTWFjLmxvY2FsIChBZHJpYW5vIENoaWVzYSkwggEiMA0GCSqGSIb3DQEBAQUA
|
||||
A4IBDwAwggEKAoIBAQCdQCgwn7M5jtkNzYv/yUelUV84ehsYjPTQspCXCjDdUltO
|
||||
E6jafRM/2SopUWwzPTorIZkerIpqq/avi77e6wSdCKJZBA5DsrMSOmFjjMqG4H2b
|
||||
euzr5b+ZKzKnw4nF/CuB2cmWkz/qAiluqVdRl+Gef/Ouyuer/NuhJhK6Mgy1VuAd
|
||||
ynwizGsAgQ/oAGDuHWmcMhGw/2NVTnXqHei5ntr+F4r08YOgXnRsGId+16nJU5xd
|
||||
Xs80sw2dFl+1zQiFJxWjVQk65CyZfLDcwC7e3PAMsT+8obzuBKCn6fW3JiIZ68tc
|
||||
o8GZClHSkeS7IMp+/wtjMXf1iipE0bRWzzdl1xQnAgMBAAGjgYMwgYAwDgYDVR0P
|
||||
AQH/BAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMB8GA1UdIwQYMBaAFH2KEsMw
|
||||
S7/Qu1eE1DxRhZTI0Z7RMDgGA1UdEQQxMC+CCm1zZ19icm9rZXKCCWxvY2FsaG9z
|
||||
dIcEfwAAAYcQAAAAAAAAAAAAAAAAAAAAATANBgkqhkiG9w0BAQsFAAOCAYEAVr06
|
||||
Kg/FaWxUbD6Q+e5OLzckeeFZOKcb/2mmEH+e99HebnCuydiiGebZVWcLsoOw+gmb
|
||||
WG/4rFyp9D/ZYFiQxWNRm/nCcxiHIV+JHDxhBn3vKENxYNNbr+WTMBTqmaYqPARK
|
||||
SelnX+XDRTZUnoRBo03wZFYwOYwHUFWrlMFz+o6jOo2KZa4J+pcEDbttkJEoVhiV
|
||||
C8EKIxSsG9TuW4lh5UySfB62ZfQBNd8SyhD4LF5JHFbBV9ysnylg/8gVvavjHWtM
|
||||
FleOk/lNi9oj2n8uQEGbBT6FpTaKKJDiF85E3J4fuv8iNiFy2nWhCpJFF9K5/hu6
|
||||
s41Y2ZRb7luBoUj+CQWlTpGjCJPzzWmSkZUjf5kRP6b01bAXoLBzBBn50KWf8DWw
|
||||
Rx7VaHtzbBRxfzESQxslGRgZvz2KxjY/x2jH6xdW+bzt93aHkgeGkDrjpY9q/uQF
|
||||
SyEJYHIDt+FZupcc3KjvTY2p+icbckOrwQAtVWXzEjCsnDjf33+O7VGdACDm
|
||||
-----END CERTIFICATE-----
|
||||
28
deploy/compose/nats_config/key.pem
Normal file
28
deploy/compose/nats_config/key.pem
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCdQCgwn7M5jtkN
|
||||
zYv/yUelUV84ehsYjPTQspCXCjDdUltOE6jafRM/2SopUWwzPTorIZkerIpqq/av
|
||||
i77e6wSdCKJZBA5DsrMSOmFjjMqG4H2beuzr5b+ZKzKnw4nF/CuB2cmWkz/qAilu
|
||||
qVdRl+Gef/Ouyuer/NuhJhK6Mgy1VuAdynwizGsAgQ/oAGDuHWmcMhGw/2NVTnXq
|
||||
Hei5ntr+F4r08YOgXnRsGId+16nJU5xdXs80sw2dFl+1zQiFJxWjVQk65CyZfLDc
|
||||
wC7e3PAMsT+8obzuBKCn6fW3JiIZ68tco8GZClHSkeS7IMp+/wtjMXf1iipE0bRW
|
||||
zzdl1xQnAgMBAAECggEAMRDQuYNLJ/2DioQFV/WVDmdaf8PR6pIo3WmqJga/An/t
|
||||
D2qg+DOoqvZ26leGnGJRYR3lqiWKNwibO2EuWF4anWkRRxc14DfFGj3vH2HR2832
|
||||
Q2pSvLR+WSuabbBcr9MkPCsZdItTmQ+9n9Lk9QegFZW1Emgra4XFff3kQAbX4kjR
|
||||
ATyEsvZsgnkK5jHi5bzVHEKY730MKyhYzmHmUgxH1ibD5x+tnFtRiBGK+qY24erW
|
||||
rw+wu0YKu1ESp62orYDnaA8MH7aWlFZLniPB4liA0h0bElrgHA8Zndx+cEtXqF4m
|
||||
5+igR3MjXbg2at80ah++z6EGUTtEPccRSpcA7qFqMQKBgQDFVp1msdn45Xwquw+8
|
||||
CSZ45KAurvQEPNxtK/GMHtR5LjRZlKQEpNy3AVjz56azv72kqUfhNsP+ZNokMQTH
|
||||
NTMvdkLzcwKe3qCnsfBRlSkRBVCwan266oCJW8SSX8pdaoME9lzc2BfMVAxJ1n+Y
|
||||
289ZHXyyPYdNd+L4FxjreJDkKQKBgQDL/uD+kCSKZ/dYVZqwF06DIzYiBv1Xjne3
|
||||
3H90J0h/2iU9/yX9UsCS7D5RWbVROUyMh64fpH0f2lVFT8Xo3SjBWISrMovOxEzl
|
||||
C2wZwM2VQmrfhiUg9h46drJSl/JL9/V/QOnpuQe35bVWjROtFStaZagUK/3vx1hh
|
||||
xCV4iVS/zwKBgQC2Ea3zvA/x9jlTa3ee84pNbBLmP4DgEA8Hos2fjCpZC+o85ElY
|
||||
B4ukRVf+4TILEdM1AwJQpii6o+4oChnwegMZvTEUUH6QebMcRa4Gd2qGS7MgsYAD
|
||||
XqztDoAU1NBu1ADCKVOQZse+O6WC0qazL8rk27Ha+a3GKeB9KUJSrtBv0QKBgCi5
|
||||
IftPlSvYI2WL+Uxr6q19KwJR+OMwuq+Goh7y9KMpTkP5GoFesrjh1nLxAKRNVv26
|
||||
3ETO1ne0Y09p5G1fMRKf9CQk/Anz4BHdXOArQB8q2iDzK5hP6arsJR8d3C3UOzsD
|
||||
H28cE/FfNvsnQKVN05DBOHOGcLQcTIV/3acZa0S7AoGBAJqSujzhVkewH7wJWOOh
|
||||
92F66vMnCsE4Qn10h84GQQWORgjr8z8d8UbW7VrobVfZP74IBqo3ZUBYm85+lUFu
|
||||
FWHjTkXoZzwP8IvMW0gE2iC3W4QSr2Z96a6RlRJdxC70LB+Pm6FFwLTloKBGK8Bf
|
||||
Kp53gUDjsvJcQGv6nOty0uHQ
|
||||
-----END PRIVATE KEY-----
|
||||
18
deploy/compose/nats_config/nats.cfg
Normal file
18
deploy/compose/nats_config/nats.cfg
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
server_name: $NATS_NAME
|
||||
port: 4222
|
||||
http_port: 8222
|
||||
authorization: {
|
||||
users: [
|
||||
{user: $NATS_USER, password: $NATS_PW}
|
||||
]
|
||||
}
|
||||
tls: {
|
||||
cert_file: "/tmp/nats/config/cert.pem"
|
||||
key_file: "/tmp/nats/config/key.pem"
|
||||
ca_file: "/tmp/nats/config/rootCA.pem"
|
||||
}
|
||||
// enables jetstream, an empty block will enable and use defaults
|
||||
jetstream {
|
||||
// jetstream data will be in /data/nats-server/jetstream
|
||||
store_dir: "/tmp/nats/jetstream"
|
||||
}
|
||||
29
deploy/compose/nats_config/rootCA.pem
Normal file
29
deploy/compose/nats_config/rootCA.pem
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIE6zCCA1OgAwIBAgIQcw3hWvi1nfQFSkUzrcdrhTANBgkqhkiG9w0BAQsFADCB
|
||||
jTEeMBwGA1UEChMVbWtjZXJ0IGRldmVsb3BtZW50IENBMTEwLwYDVQQLDChjaGll
|
||||
c2FAQWRyaWFub01hYy5sb2NhbCAoQWRyaWFubyBDaGllc2EpMTgwNgYDVQQDDC9t
|
||||
a2NlcnQgY2hpZXNhQEFkcmlhbm9NYWMubG9jYWwgKEFkcmlhbm8gQ2hpZXNhKTAe
|
||||
Fw0yMjA4MTIxNTM1NDdaFw0zMjA4MTIxNTM1NDdaMIGNMR4wHAYDVQQKExVta2Nl
|
||||
cnQgZGV2ZWxvcG1lbnQgQ0ExMTAvBgNVBAsMKGNoaWVzYUBBZHJpYW5vTWFjLmxv
|
||||
Y2FsIChBZHJpYW5vIENoaWVzYSkxODA2BgNVBAMML21rY2VydCBjaGllc2FAQWRy
|
||||
aWFub01hYy5sb2NhbCAoQWRyaWFubyBDaGllc2EpMIIBojANBgkqhkiG9w0BAQEF
|
||||
AAOCAY8AMIIBigKCAYEA4HBEZqDbKPB0StZX/ILPU1q2Tm/U4j32/HvaWOGt528q
|
||||
15y5eqa4OqpYQ7waVhkSR+M6258yAk9BCCOGrI+oXcllO7LKv4bg/y+HVhfEg4E0
|
||||
fnZS583+VWrIcIKOENQQX1cbFnIqLldBL/ph6YNMDT8wOoLqtQ2vp1EiXFA3ghQs
|
||||
fK3iqDL31SQ7cZhdw7hnNACgvIM6MipwFLYbMsm27eMa9fCL4ZB3xokhbYVBmEcT
|
||||
RTdhGvcRBs+QF8fcP/Y6uC9y7q2ddeIYEAf5xCVc15QepPqVskuAM3rktzVpBKEl
|
||||
lzJGtW3EWu3kojrrW8dYZkZFJkHy9ymZVNUPjpAGiIIylp1Rik/o9VttXi+BQmrV
|
||||
l1tpkrU1JfhLcktjBtRxtvRJTARpSkMM8gVc1rA2KgNsULzF4Zaas12wUh7r/VzW
|
||||
4lwKiV3vgAM0wE5Fo4NLmv53/j3w7yX9GtSq0Ck/cKu2k0cOe+PTlG9aQ5MdhLCx
|
||||
+BwMij/ohBfh0qtgPVPdAgMBAAGjRTBDMA4GA1UdDwEB/wQEAwICBDASBgNVHRMB
|
||||
Af8ECDAGAQH/AgEAMB0GA1UdDgQWBBR9ihLDMEu/0LtXhNQ8UYWUyNGe0TANBgkq
|
||||
hkiG9w0BAQsFAAOCAYEAyGNw197jniIGfCpcArC2lHbzNIQCq97BXsOj4h+CaUB+
|
||||
ZfTpTOdtS5DK2fSQ4jwH6nzm7VQvrnHcbP2pCgVDWW9da+Acnh1U6dYXI1VPDDVA
|
||||
KZGDiK63M6PneX3IDl2N2fubRDP1ALkZQ6zwjtJLC2nT6IVjAJdRNt8egbCUAyMb
|
||||
nOb4F+Zrr0L2SILM0jHq9diJVpX4Lxqggldmd+5HdVGHoR8BGzw4MReuoRWOZtf/
|
||||
H+opFtJ2f8GNTWsWtmN7FsjrGOOBgREB/Tz7WCWgGEeXQveJEfkOIddVVgb/n9Ly
|
||||
mEOTbtJj36o4JJzv0v42SdT1WUkdvc6AmLVmYFn0uaLohNLVelJmU+aGavuVFpFb
|
||||
08uVsSl8JMBWwVO23CpuvZFbI/1BFVix85UZgDj8BnpAWlsJxPYV1HqxS2oJJJbn
|
||||
zRf8/0xzFPrLirXzebIr4jiCRVBRamacQTxlvPUz6c6FLTQLaqQdUV/IZaXsXX38
|
||||
byH1ABmJPGjXLm1r2RWD
|
||||
-----END CERTIFICATE-----
|
||||
|
|
@ -11,19 +11,7 @@ server {
|
|||
}
|
||||
|
||||
location / {
|
||||
proxy_pass http://frontend:3000;
|
||||
proxy_read_timeout 60;
|
||||
proxy_connect_timeout 60;
|
||||
proxy_redirect off;
|
||||
}
|
||||
location /api {
|
||||
proxy_pass http://controller:8000;
|
||||
proxy_read_timeout 60;
|
||||
proxy_connect_timeout 60;
|
||||
proxy_redirect off;
|
||||
}
|
||||
location /socket.io {
|
||||
proxy_pass http://socketio:5000;
|
||||
proxy_pass http://host.docker.internal:3000;
|
||||
proxy_read_timeout 60;
|
||||
proxy_connect_timeout 60;
|
||||
proxy_redirect off;
|
||||
|
|
@ -34,6 +22,33 @@ server {
|
|||
proxy_set_header Host $host;
|
||||
proxy_cache_bypass $http_upgrade;
|
||||
}
|
||||
location /api {
|
||||
proxy_pass http://host.docker.internal:8000;
|
||||
proxy_read_timeout 60;
|
||||
proxy_connect_timeout 60;
|
||||
proxy_redirect off;
|
||||
}
|
||||
location /custom-frontend {
|
||||
proxy_pass http://host.docker.internal:8005;
|
||||
proxy_read_timeout 60;
|
||||
proxy_connect_timeout 60;
|
||||
proxy_redirect off;
|
||||
}
|
||||
location /socket.io {
|
||||
proxy_pass http://host.docker.internal:5000;
|
||||
proxy_read_timeout 60;
|
||||
proxy_connect_timeout 60;
|
||||
proxy_redirect off;
|
||||
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection 'upgrade';
|
||||
proxy_set_header Host $host;
|
||||
proxy_cache_bypass $http_upgrade;
|
||||
}
|
||||
location /companylink {
|
||||
return 301 https://oktopus.app.br/controller;
|
||||
}
|
||||
|
||||
error_page 500 502 503 504 /50x.html;
|
||||
location = /50x.html {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
# ----------------------------- Local Environment ---------------------------- #
|
||||
|
||||
NEXT_PUBLIC_REST_ENDPOINT="http://localhost:8000"
|
||||
NEXT_PUBLIC_WS_ENDPOINT="http://localhost:5000/"
|
||||
NEXT_PUBLIC_ENTERPRISE_VERSION="false"
|
||||
NEXT_PUBLIC_GOOGLE_MAPS_KEY=""
|
||||
|
|
|
|||
46
frontend/package-lock.json
generated
46
frontend/package-lock.json
generated
|
|
@ -18,14 +18,14 @@
|
|||
"@mui/system": "5.11.9",
|
||||
"@mui/x-date-pickers": "5.0.19",
|
||||
"@react-google-maps/api": "^2.19.3",
|
||||
"apexcharts": "3.37.0",
|
||||
"apexcharts": "^3.37.0",
|
||||
"date-fns": "2.29.3",
|
||||
"formik": "2.2.9",
|
||||
"next": "^14.2.4",
|
||||
"nprogress": "0.2.0",
|
||||
"prop-types": "15.8.1",
|
||||
"react": "^18.3.1",
|
||||
"react-apexcharts": "1.4.0",
|
||||
"react-apexcharts": "^1.4.0",
|
||||
"react-dom": "^18.3.1",
|
||||
"simple-peer": "^9.11.1",
|
||||
"simplebar-react": "^3.2.1",
|
||||
|
|
@ -1480,6 +1480,11 @@
|
|||
"url": "https://opencollective.com/typescript-eslint"
|
||||
}
|
||||
},
|
||||
"node_modules/@yr/monotone-cubic-spline": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@yr/monotone-cubic-spline/-/monotone-cubic-spline-1.0.3.tgz",
|
||||
"integrity": "sha512-FQXkOta0XBSUPHndIKON2Y9JeQz5ZeMqLYZVVK93FliNBFm7LNMIZmY6FrMEB9XPcDbE2bekMbZD6kzDkxwYjA=="
|
||||
},
|
||||
"node_modules/acorn": {
|
||||
"version": "8.11.3",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz",
|
||||
|
|
@ -1538,10 +1543,11 @@
|
|||
}
|
||||
},
|
||||
"node_modules/apexcharts": {
|
||||
"version": "3.37.0",
|
||||
"resolved": "https://registry.npmjs.org/apexcharts/-/apexcharts-3.37.0.tgz",
|
||||
"integrity": "sha512-0mg1gDKUo3JG00Q//LK0jEXBS6OLjpuglqZ8ec9cqfA5oP8owopD9n5EhfARbWROb5o8GSPzFuohTJiCm2ecWw==",
|
||||
"version": "3.50.0",
|
||||
"resolved": "https://registry.npmjs.org/apexcharts/-/apexcharts-3.50.0.tgz",
|
||||
"integrity": "sha512-LJT1PNAm+NoIU3aogL2P+ViC0y/Cjik54FdzzGV54UNnGQLBoLe5ok3fxsJDTgyez45BGYT8gqNpYKqhdfy5sg==",
|
||||
"dependencies": {
|
||||
"@yr/monotone-cubic-spline": "^1.0.3",
|
||||
"svg.draggable.js": "^2.2.2",
|
||||
"svg.easing.js": "^2.0.0",
|
||||
"svg.filter.js": "^2.0.2",
|
||||
|
|
@ -4722,14 +4728,14 @@
|
|||
}
|
||||
},
|
||||
"node_modules/react-apexcharts": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/react-apexcharts/-/react-apexcharts-1.4.0.tgz",
|
||||
"integrity": "sha512-DrcMV4aAMrUG+n6412yzyATWEyCDWlpPBBhVbpzBC4PDeuYU6iF84SmExbck+jx5MUm4U5PM3/T307Mc3kzc9Q==",
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/react-apexcharts/-/react-apexcharts-1.4.1.tgz",
|
||||
"integrity": "sha512-G14nVaD64Bnbgy8tYxkjuXEUp/7h30Q0U33xc3AwtGFijJB9nHqOt1a6eG0WBn055RgRg+NwqbKGtqPxy15d0Q==",
|
||||
"dependencies": {
|
||||
"prop-types": "^15.5.7"
|
||||
"prop-types": "^15.8.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"apexcharts": "^3.18.0",
|
||||
"apexcharts": "^3.41.0",
|
||||
"react": ">=0.13"
|
||||
}
|
||||
},
|
||||
|
|
@ -7102,6 +7108,11 @@
|
|||
"eslint-visitor-keys": "^3.3.0"
|
||||
}
|
||||
},
|
||||
"@yr/monotone-cubic-spline": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@yr/monotone-cubic-spline/-/monotone-cubic-spline-1.0.3.tgz",
|
||||
"integrity": "sha512-FQXkOta0XBSUPHndIKON2Y9JeQz5ZeMqLYZVVK93FliNBFm7LNMIZmY6FrMEB9XPcDbE2bekMbZD6kzDkxwYjA=="
|
||||
},
|
||||
"acorn": {
|
||||
"version": "8.11.3",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz",
|
||||
|
|
@ -7142,10 +7153,11 @@
|
|||
}
|
||||
},
|
||||
"apexcharts": {
|
||||
"version": "3.37.0",
|
||||
"resolved": "https://registry.npmjs.org/apexcharts/-/apexcharts-3.37.0.tgz",
|
||||
"integrity": "sha512-0mg1gDKUo3JG00Q//LK0jEXBS6OLjpuglqZ8ec9cqfA5oP8owopD9n5EhfARbWROb5o8GSPzFuohTJiCm2ecWw==",
|
||||
"version": "3.50.0",
|
||||
"resolved": "https://registry.npmjs.org/apexcharts/-/apexcharts-3.50.0.tgz",
|
||||
"integrity": "sha512-LJT1PNAm+NoIU3aogL2P+ViC0y/Cjik54FdzzGV54UNnGQLBoLe5ok3fxsJDTgyez45BGYT8gqNpYKqhdfy5sg==",
|
||||
"requires": {
|
||||
"@yr/monotone-cubic-spline": "^1.0.3",
|
||||
"svg.draggable.js": "^2.2.2",
|
||||
"svg.easing.js": "^2.0.0",
|
||||
"svg.filter.js": "^2.0.2",
|
||||
|
|
@ -9444,11 +9456,11 @@
|
|||
}
|
||||
},
|
||||
"react-apexcharts": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/react-apexcharts/-/react-apexcharts-1.4.0.tgz",
|
||||
"integrity": "sha512-DrcMV4aAMrUG+n6412yzyATWEyCDWlpPBBhVbpzBC4PDeuYU6iF84SmExbck+jx5MUm4U5PM3/T307Mc3kzc9Q==",
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/react-apexcharts/-/react-apexcharts-1.4.1.tgz",
|
||||
"integrity": "sha512-G14nVaD64Bnbgy8tYxkjuXEUp/7h30Q0U33xc3AwtGFijJB9nHqOt1a6eG0WBn055RgRg+NwqbKGtqPxy15d0Q==",
|
||||
"requires": {
|
||||
"prop-types": "^15.5.7"
|
||||
"prop-types": "^15.8.1"
|
||||
}
|
||||
},
|
||||
"react-dom": {
|
||||
|
|
|
|||
|
|
@ -24,14 +24,14 @@
|
|||
"@mui/system": "5.11.9",
|
||||
"@mui/x-date-pickers": "5.0.19",
|
||||
"@react-google-maps/api": "^2.19.3",
|
||||
"apexcharts": "3.37.0",
|
||||
"apexcharts": "^3.37.0",
|
||||
"date-fns": "2.29.3",
|
||||
"formik": "2.2.9",
|
||||
"next": "^14.2.4",
|
||||
"nprogress": "0.2.0",
|
||||
"prop-types": "15.8.1",
|
||||
"react": "^18.3.1",
|
||||
"react-apexcharts": "1.4.0",
|
||||
"react-apexcharts": "^1.4.0",
|
||||
"react-dom": "^18.3.1",
|
||||
"simple-peer": "^9.11.1",
|
||||
"simplebar-react": "^3.2.1",
|
||||
|
|
|
|||
BIN
frontend/public/assets/logo.png
Normal file
BIN
frontend/public/assets/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 19 KiB |
|
|
@ -1,13 +1,16 @@
|
|||
import PropTypes from 'prop-types';
|
||||
import NextLink from 'next/link';
|
||||
import Link from 'next/link'
|
||||
import { Box, Typography, Unstable_Grid2 as Grid } from '@mui/material';
|
||||
import { Box, Typography, Unstable_Grid2 as Grid, Stack } from '@mui/material';
|
||||
import { Logo } from 'src/components/logo';
|
||||
|
||||
// TODO: Change subtitle text
|
||||
import { useTheme, useMediaQuery } from '@mui/material'
|
||||
|
||||
export const Layout = (props) => {
|
||||
const { children } = props;
|
||||
const lgUp = useMediaQuery((theme) => theme.breakpoints.up('lg'));
|
||||
const theme = useTheme();
|
||||
|
||||
console.log("logUp", lgUp)
|
||||
|
||||
return (
|
||||
<Box
|
||||
|
|
@ -60,7 +63,7 @@ export const Layout = (props) => {
|
|||
lg={6}
|
||||
sx={{
|
||||
alignItems: 'center',
|
||||
background: 'radial-gradient(50% 50% at 50% 50%, #306D6F 0%, #255355 100%)',
|
||||
background: `radial-gradient(50% 50% at 50% 50%, ${theme.palette.primary.main} 0%, ${theme.palette.primary.dark } 100%)`,
|
||||
color: 'white',
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
|
|
@ -70,20 +73,32 @@ export const Layout = (props) => {
|
|||
}}
|
||||
>
|
||||
<Box sx={{ p: 3 }}>
|
||||
<Link href="https://oktopus.app.br" target="_blank">
|
||||
<img
|
||||
alt=""
|
||||
src="/assets/oktopus.png"
|
||||
/>
|
||||
</Link>
|
||||
<Typography
|
||||
align="center"
|
||||
sx={{ mb: 3 }}
|
||||
>
|
||||
</Typography>
|
||||
<Link href="http://localhost/companylink" target="_blank">
|
||||
<img
|
||||
alt=""
|
||||
src="http://localhost:8004/images/logo.png"
|
||||
/>
|
||||
</Link>
|
||||
</Box>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Stack style={{position:"absolute", bottom:"2px", left:"2px"}} direction={"row"} spacing={"1"}>
|
||||
<Typography
|
||||
align="center"
|
||||
color={lgUp ? 'neutral[900]' : 'primary.contrastText'}
|
||||
component="footer"
|
||||
variant="body2"
|
||||
sx={{ p: 2 }}
|
||||
>
|
||||
Powered by
|
||||
</Typography>
|
||||
</Stack>
|
||||
<a href='https://oktopus.app.br' style={{position:"absolute", bottom:"10px", left:"100px"}} target='_blank'>
|
||||
<img
|
||||
src="/assets/logo.png"
|
||||
alt="Oktopus logo image"
|
||||
width={80}/>
|
||||
</a>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -35,15 +35,15 @@ export const items = [
|
|||
// </SvgIcon>
|
||||
// )
|
||||
// },
|
||||
// {
|
||||
// title: 'Map',
|
||||
// path: '/map',
|
||||
// icon: (
|
||||
// <SvgIcon fontSize="small">
|
||||
// <MapIcon/>
|
||||
// </SvgIcon>
|
||||
// ),
|
||||
// },
|
||||
{
|
||||
title: 'Map',
|
||||
path: '/map',
|
||||
icon: (
|
||||
<SvgIcon fontSize="small">
|
||||
<MapIcon/>
|
||||
</SvgIcon>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: 'Credentials',
|
||||
path: '/credentials',
|
||||
|
|
|
|||
|
|
@ -4,8 +4,6 @@ import { styled } from '@mui/material/styles';
|
|||
import { withAuthGuard } from 'src/hocs/with-auth-guard';
|
||||
import { SideNav } from './side-nav';
|
||||
import { TopNav } from './top-nav';
|
||||
import Image from 'next/image'
|
||||
import { Link } from '@mui/material';
|
||||
|
||||
const SIDE_NAV_WIDTH = 280;
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@ import NextLink from 'next/link';
|
|||
import { usePathname } from 'next/navigation';
|
||||
import PropTypes from 'prop-types';
|
||||
import Link from 'next/link'
|
||||
import ArrowTopRightOnSquareIcon from '@heroicons/react/24/solid/ArrowTopRightOnSquareIcon';
|
||||
import ChevronUpDownIcon from '@heroicons/react/24/solid/ChevronUpDownIcon';
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
|
|
@ -18,12 +16,15 @@ import { Logo } from 'src/components/logo';
|
|||
import { Scrollbar } from 'src/components/scrollbar';
|
||||
import { items } from './config';
|
||||
import { SideNavItem } from './side-nav-item';
|
||||
import { useTheme } from '@mui/material';
|
||||
|
||||
export const SideNav = (props) => {
|
||||
const { open, onClose } = props;
|
||||
const pathname = usePathname();
|
||||
const lgUp = useMediaQuery((theme) => theme.breakpoints.up('lg'));
|
||||
|
||||
const theme = useTheme();
|
||||
|
||||
const isItemActive = (currentPath, itemPath) => {
|
||||
if (currentPath === itemPath) {
|
||||
return true;
|
||||
|
|
@ -34,7 +35,6 @@ export const SideNav = (props) => {
|
|||
}
|
||||
|
||||
return false;
|
||||
//TODO: test frontend with color of the landing page
|
||||
}
|
||||
|
||||
const content = (
|
||||
|
|
@ -80,9 +80,9 @@ export const SideNav = (props) => {
|
|||
p: '12px'
|
||||
}}
|
||||
>
|
||||
<Link href="https://oktopus.app.br" target="_blank">
|
||||
<Link href="http://localhost/companylink" target="_blank">
|
||||
<div style={{display:'flex',justifyContent:'center'}}>
|
||||
<img src="/assets/oktopus.png"
|
||||
<img src="http://localhost:8004/images/logo.png"
|
||||
width={'60%'}
|
||||
/>
|
||||
</div>
|
||||
|
|
@ -113,6 +113,9 @@ export const SideNav = (props) => {
|
|||
}}
|
||||
>
|
||||
{items.map((item) => {
|
||||
if (item.title == "Map" && process.env.NEXT_PUBLIC_ENTERPRISE_VERSION != "true"){
|
||||
return
|
||||
}
|
||||
const active = isItemActive(pathname, item.path);
|
||||
|
||||
return (
|
||||
|
|
@ -129,7 +132,24 @@ export const SideNav = (props) => {
|
|||
})}
|
||||
</Stack>
|
||||
</Box>
|
||||
<Divider sx={{ borderColor: 'neutral.700' }} />
|
||||
<Stack style={{position:"absolute", bottom:"2px", left:"2px"}} direction={"row"} spacing={"1"} zIndex={9999}>
|
||||
<Typography
|
||||
align="center"
|
||||
color="primary.contrastText"
|
||||
component="footer"
|
||||
variant="body2"
|
||||
sx={{ p: 2 }}
|
||||
>
|
||||
Powered by
|
||||
</Typography>
|
||||
</Stack>
|
||||
<a href='https://oktopus.app.br' style={{position:"absolute", bottom:"10px", left:"100px"}} target='_blank'>
|
||||
<img
|
||||
src="/assets/logo.png"
|
||||
alt="Oktopus logo image"
|
||||
width={80}
|
||||
/>
|
||||
</a>
|
||||
</Box>
|
||||
</Scrollbar>
|
||||
);
|
||||
|
|
@ -141,7 +161,7 @@ export const SideNav = (props) => {
|
|||
open
|
||||
PaperProps={{
|
||||
sx: {
|
||||
backgroundColor: 'neutral.800',
|
||||
background: `linear-gradient(0deg, ${theme.palette.neutral["800"]} 0%, ${theme.palette.primary.dark} 90%);`,
|
||||
color: 'common.white',
|
||||
width: 280
|
||||
}
|
||||
|
|
@ -160,7 +180,7 @@ export const SideNav = (props) => {
|
|||
open={open}
|
||||
PaperProps={{
|
||||
sx: {
|
||||
backgroundColor: 'neutral.800',
|
||||
background: `linear-gradient(0deg, ${theme.palette.primary.main} 0%, ${theme.palette.primary.dark} 90%);`,
|
||||
color: 'common.white',
|
||||
width: 280
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,21 +10,26 @@ import { createTheme } from 'src/theme';
|
|||
import { createEmotionCache } from 'src/utils/create-emotion-cache';
|
||||
import 'simplebar-react/dist/simplebar.min.css';
|
||||
import { WsProvider } from 'src/contexts/socketio-context';
|
||||
import '../utils/map.css';
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
const clientSideEmotionCache = createEmotionCache();
|
||||
|
||||
const SplashScreen = () => null;
|
||||
|
||||
const App = (props) => {
|
||||
const [theme, setTheme] = useState(null);
|
||||
const { Component, emotionCache = clientSideEmotionCache, pageProps } = props;
|
||||
|
||||
useNProgress();
|
||||
|
||||
const getLayout = Component.getLayout ?? ((page) => page);
|
||||
|
||||
const theme = createTheme();
|
||||
useEffect(() => {
|
||||
setTheme(createTheme());
|
||||
}, []);
|
||||
|
||||
return (
|
||||
return theme && (
|
||||
<CacheProvider value={emotionCache}>
|
||||
<Head>
|
||||
<title>
|
||||
|
|
|
|||
|
|
@ -1,39 +1,163 @@
|
|||
import Head from 'next/head';
|
||||
import { GoogleMap, useLoadScript } from "@react-google-maps/api"
|
||||
import { GoogleMap, useLoadScript, Marker, OverlayView } from "@react-google-maps/api"
|
||||
import { Layout as DashboardLayout } from 'src/layouts/dashboard/layout';
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
import mapStyles from '../utils/mapStyles.json';
|
||||
import { useRouter } from 'next/router';
|
||||
|
||||
const getPixelPositionOffset = pixelOffset => (width, height) => ({
|
||||
x: -(width / 2) + pixelOffset.x,
|
||||
y: -(height / 2) + pixelOffset.y
|
||||
});
|
||||
|
||||
const Popup = props => {
|
||||
return (
|
||||
<OverlayView
|
||||
position={props.anchorPosition}
|
||||
mapPaneName={OverlayView.OVERLAY_MOUSE_TARGET}
|
||||
getPixelPositionOffset={getPixelPositionOffset(props.markerPixelOffset)}
|
||||
>
|
||||
<div className="popup-tip-anchor">
|
||||
<div className="popup-bubble-anchor">
|
||||
<div className="popup-bubble-content">{props.content}</div>
|
||||
</div>
|
||||
</div>
|
||||
</OverlayView>
|
||||
);
|
||||
};
|
||||
|
||||
const Page = () => {
|
||||
|
||||
const libraries = useMemo(() => ['places'], []);
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
const [mapRef, setMapRef] = useState(null);
|
||||
|
||||
const [mapCenter, setMapCenter] = useState(null);
|
||||
const [markers, setMarkers] = useState([]);
|
||||
const [activeMarker, setActiveMarker] = useState(null);
|
||||
const [activeMarkerdata, setActiveMarkerdata] = useState(null);
|
||||
const [zoom, setZoom] = useState(null)
|
||||
|
||||
const handleDragEnd = () => {
|
||||
if (mapRef) {
|
||||
const newCenter = mapRef.getCenter();
|
||||
console.log("newCenter:",newCenter.lat(), newCenter.lng());
|
||||
localStorage.setItem("mapCenter", JSON.stringify({"lat":newCenter.lat(),"lng":newCenter.lng()}))
|
||||
}
|
||||
}
|
||||
|
||||
const handleZoomChange = () => {
|
||||
if (mapRef) {
|
||||
const newZoom = mapRef.getZoom();
|
||||
console.log("new zoom", newZoom)
|
||||
localStorage.setItem("zoom", newZoom)
|
||||
}
|
||||
}
|
||||
|
||||
const handleOnLoad = map => {
|
||||
setMapRef(map);
|
||||
};
|
||||
|
||||
const fetchMarkers = async () => {
|
||||
|
||||
var myHeaders = new Headers();
|
||||
myHeaders.append("Content-Type", "application/json");
|
||||
myHeaders.append("Authorization", localStorage.getItem("token"));
|
||||
|
||||
var requestOptions = {
|
||||
method: 'GET',
|
||||
headers: myHeaders,
|
||||
redirect: 'follow'
|
||||
};
|
||||
|
||||
let result = await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/map`, requestOptions)
|
||||
|
||||
if (result.status == 200) {
|
||||
const content = await result.json()
|
||||
setMarkers(content)
|
||||
}else if (result.status == 403) {
|
||||
console.log("num tenx permissão, seu boca de sandália")
|
||||
return router.push("/403")
|
||||
}else if (result.status == 401){
|
||||
console.log("taix nem autenticado, sai fora oh")
|
||||
return router.push("/auth/login")
|
||||
} else {
|
||||
setMarkers([])
|
||||
console.log("error to get map markers")
|
||||
}
|
||||
}
|
||||
|
||||
const fetchActiveMarkerData = async (id) => {
|
||||
var myHeaders = new Headers();
|
||||
myHeaders.append("Content-Type", "application/json");
|
||||
myHeaders.append("Authorization", localStorage.getItem("token"));
|
||||
|
||||
var requestOptions = {
|
||||
method: 'GET',
|
||||
headers: myHeaders,
|
||||
redirect: 'follow'
|
||||
};
|
||||
|
||||
let result = await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/device?id=`+id, requestOptions)
|
||||
|
||||
if (result.status == 200) {
|
||||
const content = await result.json()
|
||||
setActiveMarkerdata(content)
|
||||
}else if (result.status == 403) {
|
||||
return router.push("/403")
|
||||
}else if (result.status == 401){
|
||||
return router.push("/auth/login")
|
||||
} else {
|
||||
console.log("no device info found")
|
||||
const content = await result.json()
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(()=> {
|
||||
// Check if geolocation is supported by the browser
|
||||
if ("geolocation" in navigator) {
|
||||
// Prompt user for permission to access their location
|
||||
navigator.geolocation.getCurrentPosition(
|
||||
// Get the user's latitude and longitude coordinates
|
||||
// Success callback function
|
||||
function(position) {
|
||||
// Update the map with the user's new location
|
||||
setMapCenter({
|
||||
lat: position.coords.latitude,
|
||||
lng: position.coords.longitude,
|
||||
})
|
||||
},
|
||||
// Error callback function
|
||||
function(error) {
|
||||
// Handle errors, e.g. user denied location sharing permissions
|
||||
console.error("Error getting user location:", error);
|
||||
}
|
||||
);
|
||||
} else {
|
||||
// Geolocation is not supported by the browser
|
||||
console.error("Geolocation is not supported by this browser.");
|
||||
}
|
||||
fetchMarkers();
|
||||
|
||||
let zoomFromLocalStorage = localStorage.getItem("zoom")
|
||||
if (zoomFromLocalStorage) {
|
||||
setZoom(Number(zoomFromLocalStorage))
|
||||
}else{
|
||||
setZoom(25)
|
||||
}
|
||||
|
||||
let mapCenterFromLocalStorage = localStorage.getItem("mapCenter")
|
||||
if (mapCenterFromLocalStorage){
|
||||
let fmtMapCenter = JSON.parse(localStorage.getItem("mapCenter"))
|
||||
console.log("mapCenterFromLocalStorage:", fmtMapCenter)
|
||||
setMapCenter({
|
||||
lat: Number(fmtMapCenter.lat),
|
||||
lng: Number(fmtMapCenter.lng),
|
||||
})
|
||||
return
|
||||
}
|
||||
// Check if geolocation is supported by the browser
|
||||
if ("geolocation" in navigator) {
|
||||
// Prompt user for permission to access their location
|
||||
navigator.geolocation.getCurrentPosition(
|
||||
// Get the user's latitude and longitude coordinates
|
||||
// Success callback function
|
||||
function(position) {
|
||||
// Update the map with the user's new location
|
||||
setMapCenter({
|
||||
lat: position.coords.latitude,
|
||||
lng: position.coords.longitude,
|
||||
})
|
||||
},
|
||||
// Error callback function
|
||||
function(error) {
|
||||
// Handle errors, e.g. user denied location sharing permissions
|
||||
console.log("Error getting user location:", error);
|
||||
}
|
||||
);
|
||||
} else {
|
||||
// Geolocation is not supported by the browser
|
||||
console.log("Geolocation is not supported by this browser, or the user denied access");
|
||||
}
|
||||
},[])
|
||||
|
||||
const mapOptions = useMemo(
|
||||
|
|
@ -59,7 +183,7 @@ const Page = () => {
|
|||
return <p>Loading...</p>;
|
||||
}
|
||||
|
||||
return ( mapCenter &&
|
||||
return ( markers && zoom &&
|
||||
<>
|
||||
<Head>
|
||||
<title>
|
||||
|
|
@ -68,12 +192,61 @@ const Page = () => {
|
|||
</Head>
|
||||
<GoogleMap
|
||||
options={mapOptions}
|
||||
zoom={14}
|
||||
center={mapCenter}
|
||||
zoom={zoom}
|
||||
center={mapCenter ? mapCenter : {
|
||||
lat: 0.0,
|
||||
lng: 0.0,
|
||||
}}
|
||||
mapContainerStyle={{ width: '100%', height: '100%' }}
|
||||
onLoad={() => console.log('Map Component Loaded...')}
|
||||
onLoad={handleOnLoad}
|
||||
clickableIcons={false}
|
||||
/>
|
||||
onDragEnd={handleDragEnd}
|
||||
onZoomChanged={handleZoomChange}
|
||||
>
|
||||
{
|
||||
markers.map((marker, index) => (
|
||||
<Marker
|
||||
key={index}
|
||||
position={{ lat: marker.coordinates.lat, lng: marker.coordinates.lng }}
|
||||
icon={{
|
||||
url: marker.img,
|
||||
scaledSize: new window.google.maps.Size(50, 50),
|
||||
anchor: new window.google.maps.Point(25, 25),
|
||||
}}
|
||||
draggable={false}
|
||||
clickable={true}
|
||||
onClick={() => {
|
||||
setActiveMarkerdata(null);
|
||||
if (activeMarker?.sn === marker.sn) {
|
||||
setActiveMarker(null);
|
||||
return;
|
||||
}
|
||||
fetchActiveMarkerData(marker.sn);
|
||||
setActiveMarker({
|
||||
sn: marker.sn,
|
||||
position: { lat: marker.coordinates.lat, lng: marker.coordinates.lng }
|
||||
});
|
||||
}}
|
||||
>
|
||||
</Marker>
|
||||
))
|
||||
}
|
||||
{activeMarker &&
|
||||
<Popup
|
||||
anchorPosition={activeMarker.position}
|
||||
markerPixelOffset={{ x: 0, y: -32 }}
|
||||
content={activeMarkerdata ?
|
||||
<div>
|
||||
<div>SN: {activeMarker.sn}</div>
|
||||
<div>
|
||||
<div>Model: {activeMarkerdata.Model?activeMarkerdata.Model:activeMarkerdata.ProductClass}</div>
|
||||
<div>Alias: {activeMarkerdata.Alias}</div>
|
||||
<div>Status: {activeMarkerdata.Status == 2 ? <span style={{color:"green"}}>online</span> : <span style={{color:"red"}}>offline</span>}</div>
|
||||
</div>
|
||||
</div>
|
||||
: <p>no device info found</p>}
|
||||
/>}
|
||||
</GoogleMap>
|
||||
</>
|
||||
)};
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,19 @@ export const ConnectedDevices = () => {
|
|||
const [interfaces, setInterfaces] = useState([]);
|
||||
const [interfaceValue, setInterfaceValue] = useState(null);
|
||||
|
||||
const getConnectionState = (rssi) => {
|
||||
let connectionStatus = "Signal "
|
||||
if (rssi > -30) {
|
||||
return connectionStatus + "Excellent"
|
||||
} else if (rssi > -60) {
|
||||
return connectionStatus + "Good"
|
||||
} else if (rssi > -70) {
|
||||
return connectionStatus + "Bad"
|
||||
} else {
|
||||
return connectionStatus + "Awful"
|
||||
}
|
||||
}
|
||||
|
||||
const fetchConnectedDevicesData = async () => {
|
||||
|
||||
var myHeaders = new Headers();
|
||||
|
|
@ -23,95 +36,113 @@ export const ConnectedDevices = () => {
|
|||
myHeaders.append("Authorization", localStorage.getItem("token"));
|
||||
|
||||
var requestOptions = {
|
||||
method: 'GET',
|
||||
headers: myHeaders,
|
||||
redirect: 'follow'
|
||||
method: 'GET',
|
||||
headers: myHeaders,
|
||||
redirect: 'follow'
|
||||
};
|
||||
|
||||
fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/device/${router.query.id[0]}/connecteddevices`, requestOptions)
|
||||
.then(response => {
|
||||
if (response.status === 401) {
|
||||
router.push("/auth/login")
|
||||
}
|
||||
return response.json()
|
||||
})
|
||||
.then(result => {
|
||||
console.log("connecteddevices content", result)
|
||||
let interfaces = Object.keys(result)
|
||||
setInterfaces(interfaces)
|
||||
setInterfaceValue(interfaces[0])
|
||||
setContent(result)
|
||||
})
|
||||
.catch(error => console.log('error', error));
|
||||
.then(response => {
|
||||
if (response.status === 401) {
|
||||
router.push("/auth/login")
|
||||
}
|
||||
return response.json()
|
||||
})
|
||||
.then(result => {
|
||||
console.log("connecteddevices content", result)
|
||||
let interfaces = Object.keys(result)
|
||||
setInterfaces(interfaces)
|
||||
setInterfaceValue(interfaces[0])
|
||||
setContent(result)
|
||||
})
|
||||
.catch(error => console.log('error', error));
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
fetchConnectedDevicesData();
|
||||
},[])
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<Stack
|
||||
justifyContent="center"
|
||||
alignItems={(!content || interfaces.length == 0) &&"center"}
|
||||
<Stack
|
||||
justifyContent="center"
|
||||
alignItems={(!content || interfaces.length == 0) && "center"}
|
||||
>
|
||||
{content && interfaces.length > 0 ?
|
||||
<Card>
|
||||
<CardContent>
|
||||
<Grid mb={3}>
|
||||
<InputLabel> Interface </InputLabel>
|
||||
<Select label="interface" variant="standard" value={interfaceValue} onChange={(e)=> setInterfaceValue(e.target.value)}>
|
||||
{(
|
||||
interfaces.map((item, index) => (
|
||||
<MenuItem key={index} value={item}>
|
||||
{item}
|
||||
</MenuItem>
|
||||
{content && interfaces.length > 0 ?
|
||||
<Card>
|
||||
<CardContent>
|
||||
<Grid mb={3}>
|
||||
<InputLabel> Interface </InputLabel>
|
||||
<Select label="interface" variant="standard" value={interfaceValue} onChange={(e) => setInterfaceValue(e.target.value)}>
|
||||
{(
|
||||
interfaces.map((item, index) => (
|
||||
<MenuItem key={index} value={item}>
|
||||
{item}
|
||||
</MenuItem>
|
||||
))
|
||||
)}
|
||||
</Select>
|
||||
</Grid>
|
||||
{
|
||||
content[interfaceValue].map((property, index) => (
|
||||
<Card key={index}>
|
||||
<CardContent>
|
||||
<Grid container justifyContent={"center"}>
|
||||
<Stack direction="row" spacing={5}>
|
||||
<Stack justifyItems={"center"} direction={"row"} mt={2}>
|
||||
<Tooltip title={property.active ? "Online" : "Offline"}>
|
||||
<SvgIcon>
|
||||
<CpuChipIcon color={property.active ? theme.palette.success.main : theme.palette.error.main}></CpuChipIcon>
|
||||
</SvgIcon>
|
||||
</Tooltip>
|
||||
<Typography ml={"10px"}>
|
||||
{property.hostname}
|
||||
</Typography>
|
||||
</Stack>
|
||||
<Divider orientation="vertical" />
|
||||
<Stack spacing={2}>
|
||||
<Typography>
|
||||
IP address: {property.ip_adress}
|
||||
</Typography>
|
||||
<Typography>
|
||||
MAC: {property.mac}
|
||||
</Typography>
|
||||
</Stack>
|
||||
<Stack spacing={2}>
|
||||
<Typography>
|
||||
Source: {property.adress_source}
|
||||
</Typography>
|
||||
<Tooltip title={getConnectionState(property.rssi)}>
|
||||
<Typography display={"flex"} color={() => {
|
||||
let rssi = property.rssi
|
||||
if(rssi == 0){
|
||||
return theme.palette.neutral[900]
|
||||
} else if (rssi > -30) {
|
||||
return theme.palette.success.main
|
||||
} else if (rssi > -60) {
|
||||
return theme.palette.success.main
|
||||
} else if (rssi > -70) {
|
||||
return theme.palette.warning.main
|
||||
} else {
|
||||
return theme.palette.error.main
|
||||
}
|
||||
}}>
|
||||
<Typography color={theme.palette.neutral[900]} sx={{pr:"5px"}}>
|
||||
RSSI:
|
||||
</Typography>
|
||||
{property.rssi} dbm
|
||||
</Typography>
|
||||
</Tooltip>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</Grid>
|
||||
</CardContent>
|
||||
</Card>
|
||||
))
|
||||
)}
|
||||
</Select>
|
||||
</Grid>
|
||||
{
|
||||
content[interfaceValue].map((property,index) => (
|
||||
<Card key={index}>
|
||||
<CardContent>
|
||||
<Grid container justifyContent={"center"}>
|
||||
<Stack direction="row" spacing={5}>
|
||||
<Stack justifyItems={"center"} direction={"row"} mt={2}>
|
||||
<Tooltip title={property.active ? "Online": "Offline"}>
|
||||
<SvgIcon>
|
||||
<CpuChipIcon color={property.active ? theme.palette.success.main : theme.palette.error.main}></CpuChipIcon>
|
||||
</SvgIcon>
|
||||
</Tooltip>
|
||||
<Typography ml={"10px"}>
|
||||
{property.hostname}
|
||||
</Typography>
|
||||
</Stack>
|
||||
<Divider orientation="vertical"/>
|
||||
<Stack spacing={2}>
|
||||
<Typography>
|
||||
IP address: {property.ip_adress}
|
||||
</Typography>
|
||||
<Typography>
|
||||
MAC: {property.mac}
|
||||
</Typography>
|
||||
</Stack>
|
||||
<Stack spacing={2}>
|
||||
<Typography>
|
||||
RSSI: {property.rssi} dbm
|
||||
</Typography>
|
||||
<Typography>
|
||||
Source: {property.adress_source}
|
||||
</Typography>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</Grid>
|
||||
</CardContent>
|
||||
</Card>
|
||||
))
|
||||
}
|
||||
</CardContent>
|
||||
</Card>: (
|
||||
content ? <Typography> No connected devices found </Typography> : <CircularProgress/>
|
||||
)}
|
||||
}
|
||||
</CardContent>
|
||||
</Card> : (
|
||||
content ? <Typography> No connected devices found </Typography> : <CircularProgress />
|
||||
)}
|
||||
</Stack>
|
||||
)
|
||||
}
|
||||
|
|
@ -1,31 +1,31 @@
|
|||
import { useCallback, useEffect, useState } from 'react';
|
||||
import {
|
||||
Button,
|
||||
Card,
|
||||
CardActions,
|
||||
CardContent,
|
||||
CardHeader,
|
||||
Divider,
|
||||
Stack,
|
||||
TextField,
|
||||
InputLabel,
|
||||
MenuItem,
|
||||
Select,
|
||||
FormControl,
|
||||
SvgIcon,
|
||||
Dialog,
|
||||
DialogTitle,
|
||||
DialogContent,
|
||||
DialogContentText,
|
||||
DialogActions,
|
||||
Box,
|
||||
IconButton,
|
||||
Icon,
|
||||
SnackbarContent,
|
||||
Snackbar,
|
||||
Checkbox,
|
||||
FormControlLabel,
|
||||
useTheme,
|
||||
Button,
|
||||
Card,
|
||||
CardActions,
|
||||
CardContent,
|
||||
CardHeader,
|
||||
Divider,
|
||||
Stack,
|
||||
TextField,
|
||||
InputLabel,
|
||||
MenuItem,
|
||||
Select,
|
||||
FormControl,
|
||||
SvgIcon,
|
||||
Dialog,
|
||||
DialogTitle,
|
||||
DialogContent,
|
||||
DialogContentText,
|
||||
DialogActions,
|
||||
Box,
|
||||
IconButton,
|
||||
Icon,
|
||||
SnackbarContent,
|
||||
Snackbar,
|
||||
Checkbox,
|
||||
FormControlLabel,
|
||||
useTheme,
|
||||
} from '@mui/material';
|
||||
import XMarkIcon from '@heroicons/react/24/outline/XMarkIcon';
|
||||
import Check from '@heroicons/react/24/outline/CheckIcon';
|
||||
|
|
@ -54,42 +54,42 @@ export const DevicesWiFi = () => {
|
|||
myHeaders.append("Authorization", localStorage.getItem("token"));
|
||||
|
||||
var requestOptions = {
|
||||
method: 'GET',
|
||||
headers: myHeaders,
|
||||
redirect: 'follow'
|
||||
method: 'GET',
|
||||
headers: myHeaders,
|
||||
redirect: 'follow'
|
||||
};
|
||||
|
||||
fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/device/${router.query.id[0]}/wifi`, requestOptions)
|
||||
.then(response => {
|
||||
if (response.status === 401) {
|
||||
router.push("/auth/login")
|
||||
}
|
||||
return response.json()
|
||||
})
|
||||
.then(result => {
|
||||
console.log("wifi content", result)
|
||||
result.map((item) => {
|
||||
let contentToApply = {
|
||||
hasChanges: false,
|
||||
path: item.path,
|
||||
.then(response => {
|
||||
if (response.status === 401) {
|
||||
router.push("/auth/login")
|
||||
}
|
||||
setApplyContent(oldValue => [...oldValue, contentToApply])
|
||||
return response.json()
|
||||
})
|
||||
setContent(result)
|
||||
})
|
||||
.catch(error => console.log('error', error));
|
||||
.then(result => {
|
||||
console.log("wifi content", result)
|
||||
result.map((item) => {
|
||||
let contentToApply = {
|
||||
hasChanges: false,
|
||||
path: item.path,
|
||||
}
|
||||
setApplyContent(oldValue => [...oldValue, contentToApply])
|
||||
})
|
||||
setContent(result)
|
||||
})
|
||||
.catch(error => console.log('error', error));
|
||||
};
|
||||
|
||||
useEffect(()=>{
|
||||
useEffect(() => {
|
||||
fetchWifiData()
|
||||
},[])
|
||||
}, [])
|
||||
|
||||
return (<div>
|
||||
<Stack
|
||||
direction="row"
|
||||
spacing={2}
|
||||
justifyContent="center"
|
||||
alignItems="center"
|
||||
direction="row"
|
||||
spacing={2}
|
||||
justifyContent="center"
|
||||
alignItems="center"
|
||||
>
|
||||
{content.length > 1 ?
|
||||
(content.map((item, index) => {
|
||||
|
|
@ -99,25 +99,25 @@ export const DevicesWiFi = () => {
|
|||
title={item.name.value}
|
||||
avatar={
|
||||
<SvgIcon>
|
||||
<GlobeAltIcon/>
|
||||
<GlobeAltIcon />
|
||||
</SvgIcon>
|
||||
}
|
||||
/>
|
||||
<CardContent>
|
||||
<Stack spacing={3}>
|
||||
{ item.enable.value != null &&
|
||||
<FormControlLabel control={<Checkbox defaultChecked={item.enable.value == 1 ? true : false}
|
||||
onChange={(e) => {
|
||||
let enable = item.enable.value == 1 ? "0" : "1"
|
||||
console.log(enable)
|
||||
applyContent[index].hasChanges = true
|
||||
applyContent[index].enable = {
|
||||
value : enable
|
||||
}
|
||||
setApplyContent([...applyContent])
|
||||
item.enable.value = enable
|
||||
}}/>}
|
||||
label="Enabled" />}
|
||||
{item.enable.value != null &&
|
||||
<FormControlLabel control={<Checkbox defaultChecked={item.enable.value == 1 ? true : false}
|
||||
onChange={(e) => {
|
||||
let enable = item.enable.value == 1 ? "0" : "1"
|
||||
console.log(enable)
|
||||
applyContent[index].hasChanges = true
|
||||
applyContent[index].enable = {
|
||||
value: enable
|
||||
}
|
||||
setApplyContent([...applyContent])
|
||||
item.enable.value = enable
|
||||
}} />}
|
||||
label="Enabled" />}
|
||||
{item.ssid.value != null && <TextField
|
||||
fullWidth
|
||||
label="SSID"
|
||||
|
|
@ -126,62 +126,86 @@ export const DevicesWiFi = () => {
|
|||
onChange={(e) => {
|
||||
applyContent[index].hasChanges = true
|
||||
applyContent[index].ssid = {
|
||||
value : e.target.value
|
||||
value: e.target.value
|
||||
}
|
||||
setApplyContent([...applyContent])
|
||||
item.ssid.value = e.target.value
|
||||
}}
|
||||
/>}
|
||||
{item.securityCapabilities &&
|
||||
<TextField
|
||||
fullWidth
|
||||
label="Encryption"
|
||||
value={""}
|
||||
/>}
|
||||
<TextField
|
||||
fullWidth
|
||||
label="Encryption"
|
||||
value={""}
|
||||
/>}
|
||||
{item.password.value != null &&
|
||||
<TextField
|
||||
fullWidth
|
||||
type="password"
|
||||
label="Password"
|
||||
disabled={!item.password.writable}
|
||||
value={item.password.value}
|
||||
onChange={(e) => {
|
||||
if (e.target.value.length >= 8) {
|
||||
applyContent[index].hasChanges = true
|
||||
}else{
|
||||
applyContent[index].hasChanges = false
|
||||
}
|
||||
applyContent[index].password = {
|
||||
value : e.target.value
|
||||
}
|
||||
setApplyContent([...applyContent])
|
||||
item.password.value = e.target.value
|
||||
console.log("applyContent: ", applyContent)
|
||||
}}
|
||||
/>}
|
||||
<TextField
|
||||
fullWidth
|
||||
type="password"
|
||||
label="Password"
|
||||
disabled={!item.password.writable}
|
||||
value={item.password.value}
|
||||
onChange={(e) => {
|
||||
if (e.target.value.length >= 8) {
|
||||
applyContent[index].hasChanges = true
|
||||
} else {
|
||||
applyContent[index].hasChanges = false
|
||||
}
|
||||
applyContent[index].password = {
|
||||
value: e.target.value
|
||||
}
|
||||
setApplyContent([...applyContent])
|
||||
item.password.value = e.target.value
|
||||
console.log("applyContent: ", applyContent)
|
||||
}}
|
||||
/>}
|
||||
{item.channel?.value != null && item.possibleChannels?.value != null &&
|
||||
<FormControl variant='filled'>
|
||||
<InputLabel id="channel">Channel</InputLabel>
|
||||
<Select
|
||||
fullWidth
|
||||
defaultValue={item.channel.value}
|
||||
value={item.channel.value}
|
||||
onChange={(e) => {
|
||||
applyContent[index].hasChanges = true
|
||||
applyContent[index].channel = {
|
||||
value: e.target.value
|
||||
}
|
||||
setApplyContent([...applyContent])
|
||||
item.channel.value = e.target.value
|
||||
}}
|
||||
label="Channel"
|
||||
>
|
||||
{item.possibleChannels.value.map((channel, index) => {
|
||||
return (
|
||||
<MenuItem key={index} value={channel}>{channel}</MenuItem>)
|
||||
})}
|
||||
</Select>
|
||||
</FormControl>
|
||||
}
|
||||
{item.standard.value != null &&
|
||||
<TextField
|
||||
fullWidth
|
||||
label="Standard"
|
||||
disabled={!item.standard.writable}
|
||||
value={item.standard.value}
|
||||
onChange={(e) => {
|
||||
applyContent[index].hasChanges = true
|
||||
applyContent[index].standard = {
|
||||
value : e.target.value
|
||||
}
|
||||
setApplyContent([...applyContent])
|
||||
item.standard.value = e.target.value
|
||||
}}
|
||||
/>}
|
||||
<TextField
|
||||
fullWidth
|
||||
label="Standard"
|
||||
disabled={!item.standard.writable}
|
||||
value={item.standard.value}
|
||||
onChange={(e) => {
|
||||
applyContent[index].hasChanges = true
|
||||
applyContent[index].standard = {
|
||||
value: e.target.value
|
||||
}
|
||||
setApplyContent([...applyContent])
|
||||
item.standard.value = e.target.value
|
||||
}}
|
||||
/>}
|
||||
</Stack>
|
||||
<CardActions sx={{display:"flex", justifyContent:"flex-end"}}>
|
||||
<CardActions sx={{ display: "flex", justifyContent: "flex-end" }}>
|
||||
<Button
|
||||
variant="contained"
|
||||
disabled={!applyContent[index].hasChanges}
|
||||
endIcon={<SvgIcon><Check /></SvgIcon>}
|
||||
onClick={
|
||||
()=>{
|
||||
() => {
|
||||
setApply(true)
|
||||
var myHeaders = new Headers();
|
||||
myHeaders.append("Content-Type", "application/json");
|
||||
|
|
@ -198,38 +222,38 @@ export const DevicesWiFi = () => {
|
|||
redirect: 'follow'
|
||||
};
|
||||
fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/device/${router.query.id[0]}/wifi`, requestOptions)
|
||||
.then(response => {
|
||||
if (response.status === 401) {
|
||||
router.push("/auth/login")
|
||||
}
|
||||
if (response.status == 500) {
|
||||
setErrorModal(true)
|
||||
}
|
||||
return response.json()
|
||||
})
|
||||
.then(result => {
|
||||
if (errorModal) {
|
||||
setErrorModalText(result)
|
||||
}
|
||||
setApply(false)
|
||||
if (result == 1) {
|
||||
setErrorModalText("This change could not be applied, or It's gonna be applied later on")
|
||||
setErrorModal(true)
|
||||
//TODO: fetch wifi data again
|
||||
}
|
||||
})
|
||||
.catch(error => console.log('error', error));
|
||||
.then(response => {
|
||||
if (response.status === 401) {
|
||||
router.push("/auth/login")
|
||||
}
|
||||
if (response.status == 500) {
|
||||
setErrorModal(true)
|
||||
}
|
||||
return response.json()
|
||||
})
|
||||
.then(result => {
|
||||
if (errorModal) {
|
||||
setErrorModalText(result)
|
||||
}
|
||||
setApply(false)
|
||||
if (result == 1) {
|
||||
setErrorModalText("This change could not be applied, or It's gonna be applied later on")
|
||||
setErrorModal(true)
|
||||
//TODO: fetch wifi data again
|
||||
}
|
||||
})
|
||||
.catch(error => console.log('error', error));
|
||||
}
|
||||
}
|
||||
sx={{mt:'25px', mb:'-15px'}}
|
||||
>
|
||||
sx={{ mt: '25px', mb: '-15px' }}
|
||||
>
|
||||
Apply
|
||||
</Button>
|
||||
</CardActions>
|
||||
</CardContent>
|
||||
</Card>
|
||||
)
|
||||
})):
|
||||
})) :
|
||||
<CircularProgress />
|
||||
}
|
||||
</Stack>
|
||||
|
|
@ -240,43 +264,43 @@ export const DevicesWiFi = () => {
|
|||
<CircularProgress color="inherit" />
|
||||
</Backdrop>
|
||||
<Dialog open={errorModal && errorModalText != ""}
|
||||
slotProps={{ backdrop: { style: { backgroundColor: 'rgba(255,255,255,0.5)' } } }}
|
||||
fullWidth={ true }
|
||||
maxWidth={"md"}
|
||||
scroll={"paper"}
|
||||
aria-labelledby="scroll-dialog-title"
|
||||
aria-describedby="scroll-dialog-description"
|
||||
>
|
||||
<DialogTitle id="scroll-dialog-title">
|
||||
slotProps={{ backdrop: { style: { backgroundColor: 'rgba(255,255,255,0.5)' } } }}
|
||||
fullWidth={true}
|
||||
maxWidth={"md"}
|
||||
scroll={"paper"}
|
||||
aria-labelledby="scroll-dialog-title"
|
||||
aria-describedby="scroll-dialog-description"
|
||||
>
|
||||
<DialogTitle id="scroll-dialog-title">
|
||||
<Box display="flex" alignItems="center">
|
||||
<Box flexGrow={1} >Response</Box>
|
||||
<Box>
|
||||
<IconButton onClick={()=>{
|
||||
setErrorModalText("")
|
||||
setErrorModal(false)
|
||||
}}>
|
||||
<SvgIcon
|
||||
>
|
||||
< XMarkIcon/>
|
||||
<IconButton onClick={() => {
|
||||
setErrorModalText("")
|
||||
setErrorModal(false)
|
||||
}}>
|
||||
<SvgIcon
|
||||
>
|
||||
< XMarkIcon />
|
||||
</SvgIcon>
|
||||
</IconButton>
|
||||
</Box>
|
||||
</Box>
|
||||
</DialogTitle>
|
||||
<DialogContent dividers={scroll === 'paper'}>
|
||||
<DialogContentText id="scroll-dialog-description"tabIndex={-1}>
|
||||
<pre style={{color: 'black'}}>
|
||||
</DialogTitle>
|
||||
<DialogContent dividers={scroll === 'paper'}>
|
||||
<DialogContentText id="scroll-dialog-description" tabIndex={-1}>
|
||||
<pre style={{ color: 'black' }}>
|
||||
{errorModalText}
|
||||
</pre>
|
||||
</DialogContentText>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button onClick={()=>{
|
||||
setErrorModalText("")
|
||||
setErrorModal(false)
|
||||
}}>OK</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
</div>
|
||||
);
|
||||
</DialogContentText>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button onClick={() => {
|
||||
setErrorModalText("")
|
||||
setErrorModal(false)
|
||||
}}>OK</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,3 @@
|
|||
import PropTypes from 'prop-types';
|
||||
import ArrowPathIcon from '@heroicons/react/24/solid/ArrowPathIcon';
|
||||
import ArrowRightIcon from '@heroicons/react/24/solid/ArrowRightIcon';
|
||||
import {
|
||||
Button,
|
||||
Card,
|
||||
|
|
@ -22,12 +19,11 @@ import {
|
|||
TableHead,
|
||||
TableRow,
|
||||
TableContainer,
|
||||
Paper,
|
||||
Container,
|
||||
CircularProgress
|
||||
CircularProgress,
|
||||
ToggleButton,
|
||||
ToggleButtonGroup
|
||||
} from '@mui/material';
|
||||
import { Scrollbar } from 'src/components/scrollbar';
|
||||
import { alpha, useTheme } from '@mui/material/styles';
|
||||
import { useTheme } from '@mui/material/styles';
|
||||
import { Chart } from 'src/components/chart';
|
||||
import ChartBarSquareIcon from '@heroicons/react/24/outline/ChartBarSquareIcon';
|
||||
import ListBulletIcon from '@heroicons/react/24/outline/ListBulletIcon';
|
||||
|
|
@ -35,109 +31,256 @@ import { useRouter } from 'next/router';
|
|||
import { Stack } from '@mui/system';
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
const useChartOptions = () => {
|
||||
const theme = useTheme();
|
||||
|
||||
return {
|
||||
chart: {
|
||||
background: 'transparent',
|
||||
stacked: false,
|
||||
toolbar: {
|
||||
show: true
|
||||
}
|
||||
},
|
||||
colors: [
|
||||
theme.palette.graphics.dark,
|
||||
theme.palette.graphics.darkest,
|
||||
theme.palette.graphics.light,
|
||||
theme.palette.graphics.main,
|
||||
theme.palette.graphics.lightest,
|
||||
],
|
||||
dataLabels: {
|
||||
enabled: false
|
||||
},
|
||||
fill: {
|
||||
opacity: 1,
|
||||
type: 'solid'
|
||||
},
|
||||
grid: {
|
||||
borderColor: theme.palette.divider,
|
||||
strokeDashArray: 2,
|
||||
xaxis: {
|
||||
lines: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
yaxis: {
|
||||
lines: {
|
||||
show: true
|
||||
}
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
show: true
|
||||
},
|
||||
plotOptions: {
|
||||
bar: {
|
||||
columnWidth: '40px'
|
||||
}
|
||||
},
|
||||
stroke: {
|
||||
colors: ['transparent'],
|
||||
show: true,
|
||||
width: 2
|
||||
},
|
||||
theme: {
|
||||
mode: theme.palette.mode
|
||||
},
|
||||
xaxis: {
|
||||
axisBorder: {
|
||||
color: theme.palette.divider,
|
||||
show: true
|
||||
},
|
||||
axisTicks: {
|
||||
color: theme.palette.divider,
|
||||
show: true
|
||||
},
|
||||
categories: [
|
||||
'Jan',
|
||||
'Feb',
|
||||
'Mar',
|
||||
'Apr',
|
||||
'May',
|
||||
'Jun',
|
||||
'Jul',
|
||||
'Aug',
|
||||
'Sep',
|
||||
'Oct',
|
||||
'Nov',
|
||||
'Dec'
|
||||
],
|
||||
labels: {
|
||||
offsetY: 5,
|
||||
style: {
|
||||
colors: theme.palette.text.secondary
|
||||
}
|
||||
}
|
||||
},
|
||||
yaxis: {
|
||||
labels: {
|
||||
formatter: (value) => (value > 0 ? `${value}K` : `${value}`),
|
||||
offsetX: -10,
|
||||
style: {
|
||||
colors: theme.palette.text.secondary
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
export const SiteSurvey = (props) => {
|
||||
const chartSeries = [{ name: 'This year', data: [18, 16, 5, 8, 3, 14, 14, 16, 17, 19, 18, 20] }, { name: 'Last year', data: [12, 11, 4, 6, 2, 9, 9, 10, 11, 12, 13, 13] }]
|
||||
|
||||
// const getMaxChannel = () => {
|
||||
// if (frequency == "2.4GHz") {
|
||||
// return 13;
|
||||
// } else {
|
||||
// return 128;
|
||||
// }
|
||||
// }
|
||||
|
||||
// const geMinChannel = () => {
|
||||
// if (frequency == "2.4GHz") {
|
||||
// return 0;
|
||||
// } else {
|
||||
// return 36;
|
||||
// }
|
||||
// }
|
||||
|
||||
// const getChannelSpacing = () => {
|
||||
// if (frequency == "2.4GHz") {
|
||||
// return 1;
|
||||
// } else {
|
||||
// return 4;
|
||||
// }
|
||||
// }
|
||||
|
||||
// const getChannelAmount = () => {
|
||||
// if (frequency == "2.4GHz") {
|
||||
// return 13;
|
||||
// } else {
|
||||
// return 20;
|
||||
// }
|
||||
// }
|
||||
|
||||
const getCategories = () => {
|
||||
|
||||
}
|
||||
|
||||
const router = useRouter();
|
||||
const [content, setContent] = useState(null);
|
||||
|
||||
const [frequency, setFrequency] = useState("2.4GHz");
|
||||
const [view, setView] = useState("chart");
|
||||
const [content, setContent] = useState(null);
|
||||
|
||||
const getSeries = () => {
|
||||
let series = []
|
||||
content[frequency].map((network) => {
|
||||
|
||||
let data = []
|
||||
|
||||
if (frequency == "2.4GHz") {
|
||||
if (Number(network.bandwidth) == 20) {
|
||||
data.push({"x": Number(network.channel) -2, "y": -100})
|
||||
data.push({"x": Number(network.channel), "y": Number(network.signal_level)})
|
||||
data.push({"x": Number(network.channel) +2, "y": -100})
|
||||
}
|
||||
if (Number(network.bandwidth) == 40) {
|
||||
data.push({"x": Number(network.channel) -4, "y": -100})
|
||||
data.push({"x": Number(network.channel), "y": Number(network.signal_level)})
|
||||
data.push({"x": Number(network.channel) +4, "y": -100})
|
||||
}
|
||||
}else {
|
||||
if (Number(network.bandwidth) == 20) {
|
||||
data.push({"x": Number(network.channel) -4, "y": -100})
|
||||
data.push({"x": Number(network.channel), "y": Number(network.signal_level)})
|
||||
data.push({"x": Number(network.channel) +4, "y": -100})
|
||||
}
|
||||
if (Number(network.bandwidth) == 40) {
|
||||
data.push({"x": Number(network.channel) -8, "y": -100})
|
||||
data.push({"x": Number(network.channel), "y": Number(network.signal_level)})
|
||||
data.push({"x": Number(network.channel) +8, "y": -100})
|
||||
}
|
||||
if (Number(network.bandwidth) == 80) {
|
||||
data.push({"x": Number(network.channel) -16, "y": -100})
|
||||
data.push({"x": Number(network.channel), "y": Number(network.signal_level)})
|
||||
data.push({"x": Number(network.channel) +16, "y": -100})
|
||||
}
|
||||
if (Number(network.bandwidth) == 160) {
|
||||
data.push({"x": Number(network.channel) -32, "y": -100})
|
||||
data.push({"x": Number(network.channel), "y": Number(network.signal_level)})
|
||||
data.push({"x": Number(network.channel) +32, "y": -100})
|
||||
}
|
||||
}
|
||||
|
||||
let ssid = network.ssid
|
||||
if ( ssid == "") {
|
||||
ssid = " "
|
||||
}
|
||||
return series.push({
|
||||
name: ssid,
|
||||
data: data
|
||||
})
|
||||
})
|
||||
return series;
|
||||
}
|
||||
|
||||
const useChartOptions = () => {
|
||||
const theme = useTheme();
|
||||
|
||||
return {
|
||||
chart: {
|
||||
background: 'transparent',
|
||||
stacked: false,
|
||||
toolbar: {
|
||||
show: true
|
||||
},
|
||||
zoom: {
|
||||
enabled: false
|
||||
},
|
||||
},
|
||||
title: {
|
||||
text: 'Site Survey Results',
|
||||
},
|
||||
// markers: {
|
||||
// size: 5,
|
||||
// hover: {
|
||||
// size: 9
|
||||
// }
|
||||
// },
|
||||
colors: [
|
||||
theme.palette.graphics.dark,
|
||||
theme.palette.warning.main,
|
||||
theme.palette.graphics.darkest,
|
||||
theme.palette.graphics.main,
|
||||
theme.palette.info.light,
|
||||
theme.palette.graphics.lightest,
|
||||
theme.palette.primary.main,
|
||||
theme.palette.graphics.light,
|
||||
theme.palette.error.light,
|
||||
theme.palette.error.dark
|
||||
],
|
||||
dataLabels: {
|
||||
enabled: false
|
||||
},
|
||||
grid: {
|
||||
//borderColor: theme.palette.divider,
|
||||
strokeDashArray: 2,
|
||||
xaxis: {
|
||||
lines: {
|
||||
show: true
|
||||
}
|
||||
},
|
||||
yaxis: {
|
||||
lines: {
|
||||
show: true
|
||||
},
|
||||
},
|
||||
},
|
||||
legend: {
|
||||
show: true,
|
||||
showForSingleSeries: true,
|
||||
},
|
||||
plotOptions: {
|
||||
area: {
|
||||
fillTo: 'end',
|
||||
}
|
||||
},
|
||||
stroke: {
|
||||
show: true,
|
||||
curve: 'smooth',
|
||||
lineCap: 'round',
|
||||
},
|
||||
theme: {
|
||||
mode: theme.palette.mode
|
||||
},
|
||||
yaxis: {
|
||||
min: -100,
|
||||
max: 0,
|
||||
labels: {
|
||||
formatter: function (value) {
|
||||
return value + ' dBm';
|
||||
},
|
||||
//offsetY: -10,
|
||||
style: {
|
||||
//colors: theme.palette.text.secondary
|
||||
}
|
||||
},
|
||||
},
|
||||
// annotations: {
|
||||
// xaxis: [
|
||||
// {
|
||||
// x: 9,
|
||||
// x2: 10,
|
||||
// borderColor: '#0b54ff',
|
||||
// label: {
|
||||
// style: {
|
||||
// color: 'black',
|
||||
// },
|
||||
// text: 'Channel 10',
|
||||
// offsetX: 45,
|
||||
// borderColor: 'transparent',
|
||||
// style: {
|
||||
// background: 'transparent',
|
||||
// color: theme.palette.text.secondary,
|
||||
// fontSize: '17px',
|
||||
// },
|
||||
// }
|
||||
// }
|
||||
// ]
|
||||
// },
|
||||
// annotations: {
|
||||
// points: [{
|
||||
// x: 9,
|
||||
// y: -5,
|
||||
// label: {
|
||||
// borderColor: '#775DD0',
|
||||
// offsetY: 0,
|
||||
// style: {
|
||||
// color: '#fff',
|
||||
// background: '#775DD0',
|
||||
// },
|
||||
// rotate: -45,
|
||||
// text: 'Bananas are good',
|
||||
// }
|
||||
// }]
|
||||
// },
|
||||
xaxis: {
|
||||
// tickPlacement: 'on',
|
||||
// tickAmount: getChannelAmount(),
|
||||
tickPlacement: 'on',
|
||||
labels: {
|
||||
show: true,
|
||||
style: {
|
||||
//colors: theme.palette.text.secondary
|
||||
},
|
||||
trim: true,
|
||||
},
|
||||
// max: getMaxChannel(),
|
||||
// min: geMinChannel(),
|
||||
// stepSize: getChannelSpacing(),
|
||||
//type: 'category',
|
||||
//categories: [getCategories()],
|
||||
type: 'numeric',
|
||||
decimalsInFloat: 0,
|
||||
},
|
||||
tooltip: {
|
||||
x: {
|
||||
show: true,
|
||||
formatter: (seriesName) => "Channel "+ seriesName,
|
||||
},
|
||||
followCursor: false,
|
||||
intersect: false,
|
||||
shared: true,
|
||||
enabled: true,
|
||||
onDatasetHover: {
|
||||
highlightDataSeries: true,
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
const chartOptions = useChartOptions();
|
||||
|
||||
|
|
@ -181,23 +324,30 @@ export const SiteSurvey = (props) => {
|
|||
<Grid spacing={1}>
|
||||
<Grid container>
|
||||
<Card>
|
||||
<Button
|
||||
color="inherit"
|
||||
size="small"
|
||||
disabled="true"
|
||||
<ToggleButtonGroup
|
||||
value={view}
|
||||
exclusive
|
||||
onChange={(e, value) => {
|
||||
setView(value)
|
||||
}}
|
||||
>
|
||||
<SvgIcon>
|
||||
<ChartBarSquareIcon />
|
||||
</SvgIcon>
|
||||
</Button>
|
||||
<Button
|
||||
color="inherit"
|
||||
size="small"
|
||||
>
|
||||
<SvgIcon>
|
||||
<ListBulletIcon />
|
||||
</SvgIcon>
|
||||
</Button>
|
||||
<ToggleButton
|
||||
size="small"
|
||||
value="chart"
|
||||
>
|
||||
<SvgIcon>
|
||||
<ChartBarSquareIcon />
|
||||
</SvgIcon>
|
||||
</ToggleButton>
|
||||
<ToggleButton
|
||||
size="small"
|
||||
value="list"
|
||||
>
|
||||
<SvgIcon>
|
||||
<ListBulletIcon />
|
||||
</SvgIcon>
|
||||
</ToggleButton>
|
||||
</ToggleButtonGroup>
|
||||
</Card>
|
||||
</Grid>
|
||||
<Box display="flex"
|
||||
|
|
@ -221,7 +371,7 @@ export const SiteSurvey = (props) => {
|
|||
</RadioGroup>
|
||||
</FormControl>
|
||||
</Box>
|
||||
<Card sx={{ height: '100%' }}>
|
||||
{view == "list" && <Card sx={{ height: '100%' }}>
|
||||
<Box sx={{ minWidth: 800, }}>
|
||||
<TableContainer sx={{ maxHeight: 600 }}>
|
||||
<Table exportButton={true}>
|
||||
|
|
@ -273,31 +423,18 @@ export const SiteSurvey = (props) => {
|
|||
</Table>
|
||||
</TableContainer>
|
||||
</Box>
|
||||
{/* <CardContent>
|
||||
<Chart
|
||||
height={500}
|
||||
options={chartOptions}
|
||||
series={chartSeries}
|
||||
type="bar"
|
||||
width="100%"
|
||||
/>
|
||||
</CardContent>
|
||||
<Divider />
|
||||
<CardActions sx={{ justifyContent: 'center' }}>
|
||||
<FormControl xs={2}>
|
||||
<RadioGroup
|
||||
aria-labelledby="demo-controlled-radio-buttons-group"
|
||||
name="controlled-radio-buttons-group"
|
||||
value={"2.4GHz"}
|
||||
>
|
||||
<Grid container>
|
||||
<FormControlLabel value="2.4GHz" control={<Radio />} label="2.4GHz" />
|
||||
<FormControlLabel value="5GHz" control={<Radio />} label="5GHz" />
|
||||
</Grid>
|
||||
</RadioGroup>
|
||||
</FormControl>
|
||||
</CardActions> */}
|
||||
</Card>
|
||||
</Card>}
|
||||
{view == "chart" && <Card>
|
||||
<CardContent>
|
||||
<Chart
|
||||
height={500}
|
||||
options={chartOptions}
|
||||
series={getSeries()}
|
||||
type="area"
|
||||
width="100%"
|
||||
/>
|
||||
</CardContent>
|
||||
</Card>}
|
||||
</Grid>: <CircularProgress></CircularProgress>}
|
||||
</Stack>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ const showIcon = (mtpType) => {
|
|||
</Stack>
|
||||
<Avatar
|
||||
sx={{
|
||||
backgroundColor: '#f28950',
|
||||
backgroundColor: 'primary.darkest',
|
||||
height: 56,
|
||||
width: 56
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -70,7 +70,6 @@ const useChartOptions = (labels,title) => {
|
|||
}
|
||||
else{
|
||||
options.colors = [
|
||||
theme.palette.primary.main,
|
||||
theme.palette.info.main,
|
||||
theme.palette.warning.main,
|
||||
theme.palette.graphics.lightest,
|
||||
|
|
|
|||
|
|
@ -11,8 +11,16 @@ const withAlphas = (color) => {
|
|||
};
|
||||
};
|
||||
|
||||
export const neutral = {
|
||||
50: '#306d6f',
|
||||
export const neutral = (colors) => {
|
||||
console.log("neutral colors:", colors);
|
||||
let parsedColors = JSON.parse(colors);
|
||||
|
||||
let tableColor = parsedColors["tables"]
|
||||
let sidebarColorInitial = parsedColors["sidebar_initial"]
|
||||
let wordsOutsideSidebarColor = parsedColors["words_outside_sidebar"]
|
||||
|
||||
return {
|
||||
50: tableColor,
|
||||
100: '#F3F4F6',
|
||||
200: '#E5E7EB',
|
||||
300: '#D2D6DB',
|
||||
|
|
@ -20,18 +28,29 @@ export const neutral = {
|
|||
500: '#6C737F',
|
||||
600: '#4D5761',
|
||||
700: '#FFFFFF',
|
||||
800: '#306d6f',
|
||||
900: '#30596f'
|
||||
800: sidebarColorInitial,
|
||||
900: wordsOutsideSidebarColor,
|
||||
}
|
||||
};
|
||||
|
||||
export const indigo = withAlphas({
|
||||
lightest: '#FFFFFF',
|
||||
light: '#306D6F',
|
||||
main: '#306D6F',
|
||||
dark: '#255355',
|
||||
darkest: '#00a0b8',
|
||||
contrastText: '#FFFFFF'
|
||||
});
|
||||
export const indigo = (colors) => {
|
||||
|
||||
console.log("indigo colors:", colors);
|
||||
let parsedColors = JSON.parse(colors);
|
||||
|
||||
let buttonColor = parsedColors["buttons"]
|
||||
let sidebarColorEnd = parsedColors["sidebar_end"]
|
||||
let mtpsColor = parsedColors["connected_mtps_color"]
|
||||
|
||||
return withAlphas({
|
||||
lightest: '#FFFFFF',
|
||||
light: '#ff3383',
|
||||
main: buttonColor,
|
||||
dark: sidebarColorEnd,
|
||||
darkest: mtpsColor,
|
||||
contrastText: '#FFFFFF'
|
||||
});
|
||||
}
|
||||
|
||||
export const success = withAlphas({
|
||||
lightest: '#F0FDF9',
|
||||
|
|
|
|||
|
|
@ -2,15 +2,62 @@ import { common } from '@mui/material/colors';
|
|||
import { alpha } from '@mui/material/styles';
|
||||
import { error, indigo, info, neutral, success, warning, graphics } from './colors';
|
||||
|
||||
const getColorScheme = async () => {
|
||||
|
||||
let result = await fetch('http://localhost/custom-frontend/colors').catch((error) => {
|
||||
console.log('Error fetching colors');
|
||||
sessionStorage.setItem('colors', JSON.stringify({
|
||||
"buttons": "#306d6f",
|
||||
"sidebar_end": "#306d6f",
|
||||
"sidebar_initial": "#306d6f",
|
||||
"tables": "#306d6f",
|
||||
"words_outside_sidebar": "#30596f",
|
||||
"connected_mtps_color": "#f28950"
|
||||
}));
|
||||
location.reload();
|
||||
return
|
||||
});
|
||||
if (result.status!=200) {
|
||||
console.log('Error fetching colors');
|
||||
sessionStorage.setItem('colors', JSON.stringify({
|
||||
"buttons": "#306d6f",
|
||||
"sidebar_end": "#306d6f",
|
||||
"sidebar_initial": "#306d6f",
|
||||
"tables": "#306d6f",
|
||||
"words_outside_sidebar": "#30596f",
|
||||
"connected_mtps_color": "#f28950"
|
||||
}));
|
||||
location.reload();
|
||||
return
|
||||
}
|
||||
|
||||
let response = await result.json();
|
||||
let fmtresponse = JSON.stringify(response);
|
||||
sessionStorage.setItem('colors', fmtresponse);
|
||||
location.reload();
|
||||
}
|
||||
|
||||
export function createPalette() {
|
||||
|
||||
let colors = sessionStorage.getItem('colors');
|
||||
|
||||
if (colors !== null) {
|
||||
console.log('colors already fetched');
|
||||
} else {
|
||||
getColorScheme();
|
||||
}
|
||||
console.log("colors scheme:", colors);
|
||||
|
||||
let neutralColors = neutral(colors);
|
||||
|
||||
return {
|
||||
action: {
|
||||
active: neutral[500],
|
||||
disabled: alpha(neutral[900], 0.38),
|
||||
disabledBackground: alpha(neutral[900], 0.12),
|
||||
focus: alpha(neutral[900], 0.16),
|
||||
hover: alpha(neutral[900], 0.04),
|
||||
selected: alpha(neutral[900], 0.12)
|
||||
active: neutralColors[500],
|
||||
disabled: alpha(neutralColors[900], 0.38),
|
||||
disabledBackground: alpha(neutralColors[900], 0.12),
|
||||
focus: alpha(neutralColors[900], 0.16),
|
||||
hover: alpha(neutralColors[900], 0.04),
|
||||
selected: alpha(neutralColors[900], 0.12)
|
||||
},
|
||||
background: {
|
||||
default: common.white,
|
||||
|
|
@ -21,13 +68,13 @@ export function createPalette() {
|
|||
graphics,
|
||||
info,
|
||||
mode: 'light',
|
||||
neutral,
|
||||
primary: indigo,
|
||||
neutral: neutralColors,
|
||||
primary: indigo(colors),
|
||||
success,
|
||||
text: {
|
||||
primary: neutral[900],
|
||||
secondary: neutral[500],
|
||||
disabled: alpha(neutral[900], 0.38)
|
||||
primary: neutralColors[900],
|
||||
secondary: neutralColors[500],
|
||||
disabled: alpha(neutralColors[900], 0.38)
|
||||
},
|
||||
warning
|
||||
};
|
||||
|
|
|
|||
47
frontend/src/utils/map.css
Normal file
47
frontend/src/utils/map.css
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
/* The location pointed to by the popup tip. */
|
||||
.popup-tip-anchor {
|
||||
height: 0;
|
||||
position: absolute;
|
||||
/* The max width of the info window. */
|
||||
width: 200px;
|
||||
}
|
||||
/* The bubble is anchored above the tip. */
|
||||
.popup-bubble-anchor {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
bottom: /* TIP_HEIGHT= */ 8px;
|
||||
left: 0;
|
||||
}
|
||||
/* Draw the tip. */
|
||||
.popup-bubble-anchor::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
/* Center the tip horizontally. */
|
||||
transform: translate(-50%, 0);
|
||||
/* The tip is a https://css-tricks.com/snippets/css/css-triangle/ */
|
||||
width: 0;
|
||||
height: 0;
|
||||
/* The tip is 8px high, and 12px wide. */
|
||||
border-left: 6px solid transparent;
|
||||
border-right: 6px solid transparent;
|
||||
border-top: /* TIP_HEIGHT= */ 8px solid white;
|
||||
}
|
||||
/* The popup bubble itself. */
|
||||
.popup-bubble-content {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
transform: translate(-50%, -100%);
|
||||
/* Style the info window. */
|
||||
background-color: white;
|
||||
padding: 5px;
|
||||
border-radius: 5px;
|
||||
font-family: sans-serif;
|
||||
font-size: 14px ;
|
||||
overflow-y: auto;
|
||||
max-height: 80px;
|
||||
box-shadow: 0px 2px 10px 1px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user