commit
1a85da603c
|
|
@ -58,7 +58,7 @@ user@user-laptop:~$ cd oktopus/deploy/compose
|
|||
user@user-laptop:~/oktopus/deploy/compose$ COMPOSE_PROFILES=nats,controller,cwmp,mqtt,stomp,ws,adapter,frontend,portainer docker compose up -d
|
||||
</pre>
|
||||
Oktopus deployment in <u><b>Kubernetes</b></u> still is in beta phase: <a href="https://github.com/OktopUSP/oktopus/blob/main/deploy/kubernetes/README.md"> Instructions for Kubernetes deployment</a><p></p>
|
||||
UI will open at port 3000:
|
||||
UI will open at port 80:
|
||||
<img src="https://github.com/OktopUSP/oktopus/assets/83298718/65f7c5b9-c08d-479a-8a13-fdfc634b5ca2"/><br/><br/>
|
||||
<h1>Agent</h1>
|
||||
|
||||
|
|
|
|||
|
|
@ -73,6 +73,8 @@ func NewConfig() *Config {
|
|||
|
||||
ctx := context.TODO()
|
||||
|
||||
log.Printf("Connection Request User: %q and Password: %q", *connReqUser, *connReqPasswd)
|
||||
|
||||
return &Config{
|
||||
Nats: Nats{
|
||||
Url: *natsUrl,
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ func (h *Handler) CwmpHandler(w http.ResponseWriter, r *http.Request) {
|
|||
} else if e.KindOf() == "SetParameterValuesResponse" {
|
||||
log.Println("Receive SetParameterValuesResponse from CPE:", cpe.SerialNumber)
|
||||
msgAnswer(cpe.Waiting.Callback, cpe.Waiting.Time, h.acsConfig.DeviceAnswerTimeout, tmp)
|
||||
}else if e.KindOf() == "Fault" {
|
||||
} else if e.KindOf() == "Fault" {
|
||||
log.Println("Receive FaultResponse from CPE:", cpe.SerialNumber)
|
||||
msgAnswer(cpe.Waiting.Callback, cpe.Waiting.Time, h.acsConfig.DeviceAnswerTimeout, tmp)
|
||||
log.Println(body)
|
||||
|
|
@ -156,9 +156,11 @@ func (h *Handler) ConnectionRequest(cpe CPE) error {
|
|||
ok, err := auth.Auth(h.acsConfig.ConnReqUsername, h.acsConfig.ConnReqPassword, cpe.ConnectionRequestURL)
|
||||
if !ok {
|
||||
cpe.Queue.Dequeue()
|
||||
log.Println("Error while authenticating to CPE: ", err)
|
||||
log.Println("Error while authenticating to CPE, err:", err)
|
||||
} else {
|
||||
log.Println("<-- Successfully authenticated to CPE", cpe.SerialNumber)
|
||||
}
|
||||
log.Println("<-- Successfully authenticated to CPE", cpe.SerialNumber)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,16 +24,11 @@ type Api struct {
|
|||
db db.Database
|
||||
kv jetstream.KeyValue
|
||||
ctx context.Context
|
||||
enterpise bool
|
||||
enterpise config.Enterprise
|
||||
}
|
||||
|
||||
const REQUEST_TIMEOUT = time.Second * 30
|
||||
|
||||
const (
|
||||
NormalUser = iota
|
||||
AdminUser
|
||||
)
|
||||
|
||||
func NewApi(c *config.Config, js jetstream.JetStream, nc *nats.Conn, bridge bridge.Bridge, d db.Database, kv jetstream.KeyValue) Api {
|
||||
return Api{
|
||||
port: c.RestApi.Port,
|
||||
|
|
@ -48,6 +43,11 @@ func NewApi(c *config.Config, js jetstream.JetStream, nc *nats.Conn, bridge brid
|
|||
}
|
||||
|
||||
func (a *Api) StartApi() {
|
||||
|
||||
if a.enterpise.SupportPassword != "" && a.enterpise.SupportEmail != "" {
|
||||
go registerEnterpriseSupport(a.enterpise.SupportEmail, a.enterpise.SupportPassword, a.db)
|
||||
}
|
||||
|
||||
r := mux.NewRouter()
|
||||
authentication := r.PathPrefix("/api/auth").Subrouter()
|
||||
authentication.HandleFunc("/login", a.generateToken).Methods("PUT")
|
||||
|
|
@ -77,7 +77,7 @@ func (a *Api) StartApi() {
|
|||
iot.HandleFunc("/{sn}/{mtp}/instances", a.deviceGetParameterInstances).Methods("PUT")
|
||||
iot.HandleFunc("/{sn}/{mtp}/operate", a.deviceOperateMsg).Methods("PUT")
|
||||
iot.HandleFunc("/{sn}/{mtp}/fw_update", a.deviceFwUpdate).Methods("PUT") //TODO: put it to work and generalize for usp and cwmp
|
||||
if a.enterpise {
|
||||
if a.enterpise.Enable {
|
||||
iot.HandleFunc("/{sn}/sitesurvey", a.deviceSiteSurvey).Methods("GET")
|
||||
iot.HandleFunc("/{sn}/connecteddevices", a.deviceConnectedDevices).Methods("GET")
|
||||
iot.HandleFunc("/{sn}/traceroute", a.deviceTraceRoute).Methods("GET", "PUT")
|
||||
|
|
@ -124,3 +124,32 @@ func (a *Api) StartApi() {
|
|||
}()
|
||||
log.Println("Running REST API at port", a.port)
|
||||
}
|
||||
|
||||
func registerEnterpriseSupport(email, password string, d db.Database) {
|
||||
|
||||
user := db.User{
|
||||
Email: email,
|
||||
Password: password,
|
||||
Name: "Enterprise Support",
|
||||
Level: db.AdminUser,
|
||||
}
|
||||
|
||||
for {
|
||||
if err := user.HashPassword(password); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err := d.RegisterUser(user)
|
||||
if err != nil {
|
||||
if err == db.ErrorUserExists {
|
||||
log.Println("Enterprise support user already registered.")
|
||||
return
|
||||
}
|
||||
log.Println("Error to register enterprise support user:", err)
|
||||
time.Sleep(time.Second * 5)
|
||||
continue
|
||||
}
|
||||
log.Println("Enterprise support user registered successfully.")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import (
|
|||
"strconv"
|
||||
|
||||
"github.com/leandrofars/oktopus/internal/bridge"
|
||||
"github.com/leandrofars/oktopus/internal/db"
|
||||
local "github.com/leandrofars/oktopus/internal/nats"
|
||||
"github.com/leandrofars/oktopus/internal/utils"
|
||||
"github.com/nats-io/nats.go/jetstream"
|
||||
|
|
@ -134,7 +135,7 @@ func (a *Api) deviceAuth(w http.ResponseWriter, r *http.Request) {
|
|||
utils.MarshallEncoder(err, w)
|
||||
return
|
||||
}
|
||||
if user.Level != AdminUser {
|
||||
if user.Level != db.AdminUser {
|
||||
w.WriteHeader(http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ func (a *Api) registerUser(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
//Check if user which is requesting creation has the necessary privileges
|
||||
rUser, err := a.db.FindUser(email)
|
||||
if rUser.Level != AdminUser {
|
||||
if rUser.Level != db.AdminUser {
|
||||
w.WriteHeader(http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
|
@ -63,7 +63,7 @@ func (a *Api) registerUser(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
user.Level = NormalUser
|
||||
user.Level = db.NormalUser
|
||||
|
||||
if err := user.HashPassword(user.Password); err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
|
|
@ -112,7 +112,7 @@ func (a *Api) deleteUser(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
userEmail := mux.Vars(r)["user"]
|
||||
|
||||
if rUser.Email == userEmail || (rUser.Level == AdminUser && rUser.Email != userEmail) { //Admin can delete any account, but admin account can never be deleted
|
||||
if rUser.Email == userEmail || (rUser.Level == db.AdminUser) { //Admin can delete any account
|
||||
if err := a.db.DeleteUser(userEmail); err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
json.NewEncoder(w).Encode(err)
|
||||
|
|
@ -138,7 +138,7 @@ func (a *Api) changePassword(w http.ResponseWriter, r *http.Request) {
|
|||
userToChangePasswd := mux.Vars(r)["user"]
|
||||
if userToChangePasswd != "" && userToChangePasswd != email {
|
||||
rUser, _ := a.db.FindUser(email)
|
||||
if rUser.Level != AdminUser {
|
||||
if rUser.Level != db.AdminUser {
|
||||
w.WriteHeader(http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
|
@ -168,28 +168,61 @@ func (a *Api) changePassword(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
func (a *Api) registerAdminUser(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
tokenString := r.Header.Get("Authorization")
|
||||
if tokenString == "" {
|
||||
users, err := a.db.FindAllUsers()
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
utils.MarshallEncoder(err, w)
|
||||
}
|
||||
|
||||
if !adminUserExists(users, a.enterpise.SupportEmail) {
|
||||
var user db.User
|
||||
err = json.NewDecoder(r.Body).Decode(&user)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
user.Level = db.AdminUser
|
||||
|
||||
if err := user.HashPassword(user.Password); err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
if err := a.db.RegisterUser(user); err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
w.WriteHeader(http.StatusForbidden)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
email, err := auth.ValidateToken(tokenString)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
//Check if user which is requesting creation has the necessary privileges
|
||||
rUser, err := a.db.FindUser(email)
|
||||
if rUser.Level != db.AdminUser {
|
||||
w.WriteHeader(http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
var user db.User
|
||||
err := json.NewDecoder(r.Body).Decode(&user)
|
||||
err = json.NewDecoder(r.Body).Decode(&user)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
users, err := a.db.FindAllUsers()
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
adminExists := adminUserExists(users)
|
||||
if adminExists {
|
||||
log.Println("There might exist only one admin")
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
json.NewEncoder(w).Encode("There might exist only one admin")
|
||||
return
|
||||
}
|
||||
|
||||
user.Level = AdminUser
|
||||
user.Level = db.AdminUser
|
||||
|
||||
if err := user.HashPassword(user.Password); err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
|
|
@ -202,9 +235,14 @@ func (a *Api) registerAdminUser(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
}
|
||||
|
||||
func adminUserExists(users []map[string]interface{}) bool {
|
||||
func adminUserExists(users []map[string]interface{}, supportEmail string) bool {
|
||||
|
||||
if len(users) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, x := range users {
|
||||
if x["level"].(int32) == AdminUser {
|
||||
if db.UserLevels(x["level"].(int32)) == db.AdminUser && x["email"].(string) != supportEmail {
|
||||
log.Println("Admin exists")
|
||||
return true
|
||||
}
|
||||
|
|
@ -220,7 +258,7 @@ func (a *Api) adminUserExists(w http.ResponseWriter, r *http.Request) {
|
|||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
adminExits := adminUserExists(users)
|
||||
adminExits := adminUserExists(users, a.enterpise.SupportEmail)
|
||||
json.NewEncoder(w).Encode(adminExits)
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -213,7 +213,7 @@ func (a *Api) deviceWifi(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
if device.Cwmp == entity.Online {
|
||||
|
||||
if a.enterpise {
|
||||
if a.enterpise.Enable {
|
||||
a.getEnterpriseResource("wifi", "get", device, sn, w, []byte{}, "cwmp", "098")
|
||||
return
|
||||
}
|
||||
|
|
@ -347,7 +347,7 @@ func (a *Api) deviceWifi(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
if device.Cwmp == entity.Online {
|
||||
|
||||
if a.enterpise {
|
||||
if a.enterpise.Enable {
|
||||
payload, err := io.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
|
|
|
|||
|
|
@ -29,11 +29,17 @@ type RestApi struct {
|
|||
Ctx context.Context
|
||||
}
|
||||
|
||||
type Enterprise struct {
|
||||
Enable bool
|
||||
SupportPassword string
|
||||
SupportEmail string
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
RestApi RestApi
|
||||
Nats Nats
|
||||
Mongo Mongo
|
||||
Enterprise bool
|
||||
Enterprise Enterprise
|
||||
}
|
||||
|
||||
func NewConfig() *Config {
|
||||
|
|
@ -47,6 +53,8 @@ func NewConfig() *Config {
|
|||
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")
|
||||
enterprise_support_password := flag.String("enterprise_support_password", lookupEnvOrString("ENTERPRISE_SUPPORT_PASSWORD", ""), "enterprise support password")
|
||||
enterpise_support_email := flag.String("enterprise_support_email", lookupEnvOrString("ENTERPRISE_SUPPORT_EMAIL", ""), "enterprise support email")
|
||||
flHelp := flag.Bool("help", false, "Help")
|
||||
|
||||
/*
|
||||
|
|
@ -80,7 +88,11 @@ func NewConfig() *Config {
|
|||
Uri: *mongoUri,
|
||||
Ctx: ctx,
|
||||
},
|
||||
Enterprise: *enterpise,
|
||||
Enterprise: Enterprise{
|
||||
Enable: *enterpise,
|
||||
SupportPassword: *enterprise_support_password,
|
||||
SupportEmail: *enterpise_support_email,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,12 +9,19 @@ import (
|
|||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
type UserLevels int32
|
||||
|
||||
const (
|
||||
NormalUser UserLevels = iota
|
||||
AdminUser
|
||||
)
|
||||
|
||||
type User struct {
|
||||
Email string `json:"email"`
|
||||
Name string `json:"name"`
|
||||
Password string `json:"password,omitempty"`
|
||||
Level int `json:"level"`
|
||||
Phone string `json:"phone"`
|
||||
Email string `json:"email"`
|
||||
Name string `json:"name"`
|
||||
Password string `json:"password,omitempty"`
|
||||
Level UserLevels `json:"level"`
|
||||
Phone string `json:"phone"`
|
||||
}
|
||||
|
||||
var ErrorUserExists = errors.New("User already exists")
|
||||
|
|
|
|||
|
|
@ -1,17 +0,0 @@
|
|||
# ----------------------------- Local Environment ---------------------------- #
|
||||
|
||||
NEXT_PUBLIC_REST_ENDPOINT="http://localhost:8000/api"
|
||||
NEXT_PUBLIC_WS_ENDPOINT="http://localhost:5000/"
|
||||
# ---------------------------------------------------------------------------- #
|
||||
|
||||
# -------------------------- Production Environment -------------------------- #
|
||||
|
||||
#NEXT_PUBLIC_REST_ENPOINT="https://demo.oktopus.app.br/api"
|
||||
#NEXT_PUBLIC_WS_ENPOINT="https://demo.oktopus.app.br/"
|
||||
# ---------------------------------------------------------------------------- #
|
||||
|
||||
# ---------------------------- Mocked Environment ---------------------------- #
|
||||
|
||||
#NEXT_PUBLIC_REST_ENPOINT="https://d9962fd9-2464-4a30-9a86-a15a04b57ad0.mock.pstmn.io"
|
||||
|
||||
# ---------------------------------------------------------------------------- #
|
||||
|
|
@ -151,10 +151,8 @@ services:
|
|||
|
||||
#/* -------------------------------- Frontend -------------------------------- */
|
||||
frontend:
|
||||
image: 'oktopusp/frontend'
|
||||
image: 'oktopusp/frontend-ce'
|
||||
container_name: frontend
|
||||
env_file:
|
||||
- .env.frontend
|
||||
ports:
|
||||
- 3000:3000
|
||||
networks:
|
||||
|
|
@ -187,6 +185,21 @@ services:
|
|||
usp_network:
|
||||
ipv4_address: 172.16.235.16
|
||||
profiles: [cwmp]
|
||||
|
||||
nginx:
|
||||
image: nginx:latest
|
||||
container_name: nginx
|
||||
ports:
|
||||
- 80:80
|
||||
depends_on:
|
||||
- frontend
|
||||
- controller
|
||||
- socketio
|
||||
volumes:
|
||||
- ./nginx.conf:/etc/nginx/conf.d/default.conf
|
||||
networks:
|
||||
usp_network:
|
||||
ipv4_address: 172.16.235.17
|
||||
|
||||
networks:
|
||||
usp_network:
|
||||
|
|
|
|||
41
deploy/compose/nginx.conf
Normal file
41
deploy/compose/nginx.conf
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name _;
|
||||
root /usr/share/nginx/html;
|
||||
|
||||
include /etc/nginx/default.d/*.conf;
|
||||
|
||||
error_page 404 /404.html;
|
||||
location = /404.html {
|
||||
}
|
||||
|
||||
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_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;
|
||||
}
|
||||
|
||||
error_page 500 502 503 504 /50x.html;
|
||||
location = /50x.html {
|
||||
}
|
||||
}
|
||||
1
deploy/compose/run.sh
Normal file
1
deploy/compose/run.sh
Normal file
|
|
@ -0,0 +1 @@
|
|||
COMPOSE_PROFILES=nats,controller,cwmp,mqtt,stomp,ws,adapter,frontend,portainer docker compose up -d
|
||||
1
deploy/compose/stop.sh
Normal file
1
deploy/compose/stop.sh
Normal file
|
|
@ -0,0 +1 @@
|
|||
COMPOSE_PROFILES=nats,controller,cwmp,mqtt,stomp,ws,adapter,frontend,portainer docker compose down
|
||||
|
|
@ -1,8 +1,9 @@
|
|||
# ----------------------------- Local Environment ---------------------------- #
|
||||
|
||||
NEXT_PUBLIC_REST_ENDPOINT="http://localhost:8000/api"
|
||||
NEXT_PUBLIC_REST_ENDPOINT="http://localhost:8000"
|
||||
NEXT_PUBLIC_WS_ENDPOINT="http://localhost:5000/"
|
||||
NEXT_PUBLIC_ENTERPRISE_VERSION="false"
|
||||
NEXT_PUBLIC_GOOGLE_MAPS_KEY=""
|
||||
# ---------------------------------------------------------------------------- #
|
||||
|
||||
# -------------------------- Production Environment -------------------------- #
|
||||
|
|
|
|||
|
|
@ -1 +1,4 @@
|
|||
.next/
|
||||
../.next/
|
||||
../node_modules/
|
||||
../.env
|
||||
../.env.local
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
FROM node:18.17.0-alpine as builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY ../ ./
|
||||
|
||||
RUN npm install
|
||||
|
||||
RUN NEXT_PUBLIC_REST_ENDPOINT=REST_API_URL NEXT_PUBLIC_WS_ENDPOINT=WS_URL NEXT_PUBLIC_ENTERPRISE_VERSION=ENTERPRISE_VERSION npm run build
|
||||
|
||||
RUN ls -la && echo "Listing directory contents done"
|
||||
|
||||
FROM node:18.17.0-alpine as runner
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY --from=builder /app/.next ./.next
|
||||
COPY --from=builder /app/package.json ./package.json
|
||||
COPY --from=builder /app/build/entrypoint.sh ./entrypoint.sh
|
||||
COPY --from=builder /app/public ./public
|
||||
|
||||
|
||||
RUN npm install
|
||||
|
||||
RUN chmod 755 entrypoint.sh
|
||||
|
||||
ENTRYPOINT ["/app/entrypoint.sh"]
|
||||
|
||||
CMD [ "npm", "run", "start" ]
|
||||
22
frontend/build/Dockerfile.ce
Normal file
22
frontend/build/Dockerfile.ce
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
FROM node:18.18.0-alpine as builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY ../ ./
|
||||
RUN rm .env && rm .env.local || true
|
||||
|
||||
RUN npm install
|
||||
|
||||
RUN NEXT_PUBLIC_ENTERPRISE_VERSION="false" npm run build
|
||||
|
||||
FROM node:18.18.0-alpine as runner
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY --from=builder /app/.next ./.next
|
||||
COPY --from=builder /app/package.json ./package.json
|
||||
COPY --from=builder /app/public ./public
|
||||
|
||||
RUN npm install
|
||||
|
||||
CMD [ "npm", "run", "start" ]
|
||||
22
frontend/build/Dockerfile.ee
Normal file
22
frontend/build/Dockerfile.ee
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
FROM node:18.18.0-alpine as builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY ../ ./
|
||||
RUN rm .env && rm .env.local || true
|
||||
|
||||
RUN npm install
|
||||
|
||||
RUN NEXT_PUBLIC_ENTERPRISE_VERSION="true" npm run build
|
||||
|
||||
FROM node:18.18.0-alpine as runner
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY --from=builder /app/.next ./.next
|
||||
COPY --from=builder /app/package.json ./package.json
|
||||
COPY --from=builder /app/public ./public
|
||||
|
||||
RUN npm install
|
||||
|
||||
CMD [ "npm", "run", "start" ]
|
||||
|
|
@ -18,48 +18,16 @@ help:
|
|||
@echo "Makefile commands:"
|
||||
@echo ""
|
||||
@echo "build - docker image build"
|
||||
@echo "push - push docker image 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"
|
||||
@echo "tag - tag image as latest"
|
||||
|
||||
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}
|
||||
@docker build -t ${DOCKER_USER}/${DOCKER_APP}-ce:${DOCKER_TAG} -f Dockerfile.ce ../
|
||||
@docker build -t ${DOCKER_USER}/${DOCKER_APP}-ee:${DOCKER_TAG} -f Dockerfile.ee ../
|
||||
|
||||
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
|
||||
|
||||
tag:
|
||||
docker tag ${DOCKER_USER}/${DOCKER_APP}:${DOCKER_TAG} ${DOCKER_USER}/${DOCKER_APP}:latest
|
||||
@docker push ${DOCKER_USER}/${DOCKER_APP}-ce:${DOCKER_TAG}
|
||||
@docker push ${DOCKER_USER}/${DOCKER_APP}-ee:${DOCKER_TAG}
|
||||
@docker tag ${DOCKER_USER}/${DOCKER_APP}-ce:${DOCKER_TAG} ${DOCKER_USER}/${DOCKER_APP}-ce:latest
|
||||
@docker tag ${DOCKER_USER}/${DOCKER_APP}-ee:${DOCKER_TAG} ${DOCKER_USER}/${DOCKER_APP}-ee:latest
|
||||
@docker push ${DOCKER_USER}/${DOCKER_APP}-ce:latest
|
||||
@docker push ${DOCKER_USER}/${DOCKER_APP}-ee:latest
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
#!/usr/bin/env sh
|
||||
set -Ex
|
||||
|
||||
function apply_path {
|
||||
|
||||
echo "Check that we have NEXT_PUBLIC_REST_ENDPOINT vars"
|
||||
test -n "$NEXT_PUBLIC_REST_ENDPOINT"
|
||||
|
||||
echo "Check that we have NEXT_PUBLIC_WS_ENDPOINT vars"
|
||||
test -n "$NEXT_PUBLIC_WS_ENDPOINT"
|
||||
|
||||
echo "Check that we have NEXT_PUBLIC_ENTERPRISE_VERSION vars"
|
||||
test -n "$NEXT_PUBLIC_ENTERPRISE_VERSION"
|
||||
|
||||
find /app/.next \( -type d -name .git -prune \) -o -type f -print0 | xargs -0 sed -i "s#REST_API_URL#$NEXT_PUBLIC_REST_ENDPOINT#g"
|
||||
find /app/.next \( -type d -name .git -prune \) -o -type f -print0 | xargs -0 sed -i "s#WS_URL#$NEXT_PUBLIC_WS_ENDPOINT#g"
|
||||
find /app/.next \( -type d -name .git -prune \) -o -type f -print0 | xargs -0 sed -i "s#ENTERPRISE_VERSION#$NEXT_PUBLIC_ENTERPRISE_VERSION#g"
|
||||
}
|
||||
|
||||
apply_path
|
||||
echo "Starting Nextjs"
|
||||
exec "$@"
|
||||
143
frontend/package-lock.json
generated
143
frontend/package-lock.json
generated
|
|
@ -17,6 +17,7 @@
|
|||
"@mui/material": "5.11.10",
|
||||
"@mui/system": "5.11.9",
|
||||
"@mui/x-date-pickers": "5.0.19",
|
||||
"@react-google-maps/api": "^2.19.3",
|
||||
"apexcharts": "3.37.0",
|
||||
"date-fns": "2.29.3",
|
||||
"formik": "2.2.9",
|
||||
|
|
@ -499,6 +500,23 @@
|
|||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/@googlemaps/js-api-loader": {
|
||||
"version": "1.16.2",
|
||||
"resolved": "https://registry.npmjs.org/@googlemaps/js-api-loader/-/js-api-loader-1.16.2.tgz",
|
||||
"integrity": "sha512-psGw5u0QM6humao48Hn4lrChOM2/rA43ZCm3tKK9qQsEj1/VzqkCqnvGfEOshDbBQflydfaRovbKwZMF4AyqbA==",
|
||||
"dependencies": {
|
||||
"fast-deep-equal": "^3.1.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@googlemaps/markerclusterer": {
|
||||
"version": "2.5.3",
|
||||
"resolved": "https://registry.npmjs.org/@googlemaps/markerclusterer/-/markerclusterer-2.5.3.tgz",
|
||||
"integrity": "sha512-x7lX0R5yYOoiNectr10wLgCBasNcXFHiADIBdmn7jQllF2B5ENQw5XtZK+hIw4xnV0Df0xhN4LN98XqA5jaiOw==",
|
||||
"dependencies": {
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
"supercluster": "^8.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@heroicons/react": {
|
||||
"version": "2.0.16",
|
||||
"resolved": "https://registry.npmjs.org/@heroicons/react/-/react-2.0.16.tgz",
|
||||
|
|
@ -1215,6 +1233,33 @@
|
|||
"url": "https://opencollective.com/popperjs"
|
||||
}
|
||||
},
|
||||
"node_modules/@react-google-maps/api": {
|
||||
"version": "2.19.3",
|
||||
"resolved": "https://registry.npmjs.org/@react-google-maps/api/-/api-2.19.3.tgz",
|
||||
"integrity": "sha512-jiLqvuOt5lOowkLeq7d077AByTyJp+s6hZVlLhlq7SBacBD37aUNpXBz2OsazfeR6Aw4a+9RRhAEjEFvrR1f5A==",
|
||||
"dependencies": {
|
||||
"@googlemaps/js-api-loader": "1.16.2",
|
||||
"@googlemaps/markerclusterer": "2.5.3",
|
||||
"@react-google-maps/infobox": "2.19.2",
|
||||
"@react-google-maps/marker-clusterer": "2.19.2",
|
||||
"@types/google.maps": "3.55.2",
|
||||
"invariant": "2.2.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.8 || ^17 || ^18",
|
||||
"react-dom": "^16.8 || ^17 || ^18"
|
||||
}
|
||||
},
|
||||
"node_modules/@react-google-maps/infobox": {
|
||||
"version": "2.19.2",
|
||||
"resolved": "https://registry.npmjs.org/@react-google-maps/infobox/-/infobox-2.19.2.tgz",
|
||||
"integrity": "sha512-6wvBqeJsQ/eFSvoxg+9VoncQvNoVCdmxzxRpLvmjPD+nNC6mHM0vJH1xSqaKijkMrfLJT0nfkTGpovrF896jwg=="
|
||||
},
|
||||
"node_modules/@react-google-maps/marker-clusterer": {
|
||||
"version": "2.19.2",
|
||||
"resolved": "https://registry.npmjs.org/@react-google-maps/marker-clusterer/-/marker-clusterer-2.19.2.tgz",
|
||||
"integrity": "sha512-x9ibmsP0ZVqzyCo1Pitbw+4b6iEXRw/r1TCy3vOUR3eKrzWLnHYZMR325BkZW2r8fnuWE/V3Fp4QZOP9qYORCw=="
|
||||
},
|
||||
"node_modules/@rushstack/eslint-patch": {
|
||||
"version": "1.10.3",
|
||||
"resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.10.3.tgz",
|
||||
|
|
@ -1245,6 +1290,11 @@
|
|||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz",
|
||||
"integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ=="
|
||||
},
|
||||
"node_modules/@types/google.maps": {
|
||||
"version": "3.55.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/google.maps/-/google.maps-3.55.2.tgz",
|
||||
"integrity": "sha512-JcTwzkxskR8DN/nnX96Pie3gGN3WHiPpuxzuQ9z3516o1bB243d8w8DHUJ8BohuzoT1o3HUFta2ns/mkZC8KRw=="
|
||||
},
|
||||
"node_modules/@types/json5": {
|
||||
"version": "0.0.29",
|
||||
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
|
||||
|
|
@ -2981,8 +3031,7 @@
|
|||
"node_modules/fast-deep-equal": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
||||
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
|
||||
"dev": true
|
||||
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
|
||||
},
|
||||
"node_modules/fast-glob": {
|
||||
"version": "3.3.2",
|
||||
|
|
@ -3529,6 +3578,14 @@
|
|||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/invariant": {
|
||||
"version": "2.2.4",
|
||||
"resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
|
||||
"integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
|
||||
"dependencies": {
|
||||
"loose-envify": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/is-array-buffer": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz",
|
||||
|
|
@ -4018,6 +4075,11 @@
|
|||
"node": ">=4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/kdbush": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/kdbush/-/kdbush-4.0.2.tgz",
|
||||
"integrity": "sha512-WbCVYJ27Sz8zi9Q7Q0xHC+05iwkm3Znipc2XTlrnJbsHMYktW4hPhXUE8Ys1engBrvffoSCqbil1JQAa7clRpA=="
|
||||
},
|
||||
"node_modules/keyv": {
|
||||
"version": "4.5.4",
|
||||
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
|
||||
|
|
@ -5445,6 +5507,14 @@
|
|||
"resolved": "https://registry.npmjs.org/stylis/-/stylis-4.1.3.tgz",
|
||||
"integrity": "sha512-GP6WDNWf+o403jrEp9c5jibKavrtLW+/qYGhFxFrG8maXhwTBI7gLLhiBb0o7uFccWN+EOS9aMO6cGHWAO07OA=="
|
||||
},
|
||||
"node_modules/supercluster": {
|
||||
"version": "8.0.1",
|
||||
"resolved": "https://registry.npmjs.org/supercluster/-/supercluster-8.0.1.tgz",
|
||||
"integrity": "sha512-IiOea5kJ9iqzD2t7QJq/cREyLHTtSmUT6gQsweojg9WH2sYJqZK9SswTu6jrscO6D1G5v5vYZ9ru/eq85lXeZQ==",
|
||||
"dependencies": {
|
||||
"kdbush": "^4.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/supports-color": {
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
||||
|
|
@ -6440,6 +6510,23 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"@googlemaps/js-api-loader": {
|
||||
"version": "1.16.2",
|
||||
"resolved": "https://registry.npmjs.org/@googlemaps/js-api-loader/-/js-api-loader-1.16.2.tgz",
|
||||
"integrity": "sha512-psGw5u0QM6humao48Hn4lrChOM2/rA43ZCm3tKK9qQsEj1/VzqkCqnvGfEOshDbBQflydfaRovbKwZMF4AyqbA==",
|
||||
"requires": {
|
||||
"fast-deep-equal": "^3.1.3"
|
||||
}
|
||||
},
|
||||
"@googlemaps/markerclusterer": {
|
||||
"version": "2.5.3",
|
||||
"resolved": "https://registry.npmjs.org/@googlemaps/markerclusterer/-/markerclusterer-2.5.3.tgz",
|
||||
"integrity": "sha512-x7lX0R5yYOoiNectr10wLgCBasNcXFHiADIBdmn7jQllF2B5ENQw5XtZK+hIw4xnV0Df0xhN4LN98XqA5jaiOw==",
|
||||
"requires": {
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
"supercluster": "^8.0.1"
|
||||
}
|
||||
},
|
||||
"@heroicons/react": {
|
||||
"version": "2.0.16",
|
||||
"resolved": "https://registry.npmjs.org/@heroicons/react/-/react-2.0.16.tgz",
|
||||
|
|
@ -6818,6 +6905,29 @@
|
|||
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz",
|
||||
"integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A=="
|
||||
},
|
||||
"@react-google-maps/api": {
|
||||
"version": "2.19.3",
|
||||
"resolved": "https://registry.npmjs.org/@react-google-maps/api/-/api-2.19.3.tgz",
|
||||
"integrity": "sha512-jiLqvuOt5lOowkLeq7d077AByTyJp+s6hZVlLhlq7SBacBD37aUNpXBz2OsazfeR6Aw4a+9RRhAEjEFvrR1f5A==",
|
||||
"requires": {
|
||||
"@googlemaps/js-api-loader": "1.16.2",
|
||||
"@googlemaps/markerclusterer": "2.5.3",
|
||||
"@react-google-maps/infobox": "2.19.2",
|
||||
"@react-google-maps/marker-clusterer": "2.19.2",
|
||||
"@types/google.maps": "3.55.2",
|
||||
"invariant": "2.2.4"
|
||||
}
|
||||
},
|
||||
"@react-google-maps/infobox": {
|
||||
"version": "2.19.2",
|
||||
"resolved": "https://registry.npmjs.org/@react-google-maps/infobox/-/infobox-2.19.2.tgz",
|
||||
"integrity": "sha512-6wvBqeJsQ/eFSvoxg+9VoncQvNoVCdmxzxRpLvmjPD+nNC6mHM0vJH1xSqaKijkMrfLJT0nfkTGpovrF896jwg=="
|
||||
},
|
||||
"@react-google-maps/marker-clusterer": {
|
||||
"version": "2.19.2",
|
||||
"resolved": "https://registry.npmjs.org/@react-google-maps/marker-clusterer/-/marker-clusterer-2.19.2.tgz",
|
||||
"integrity": "sha512-x9ibmsP0ZVqzyCo1Pitbw+4b6iEXRw/r1TCy3vOUR3eKrzWLnHYZMR325BkZW2r8fnuWE/V3Fp4QZOP9qYORCw=="
|
||||
},
|
||||
"@rushstack/eslint-patch": {
|
||||
"version": "1.10.3",
|
||||
"resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.10.3.tgz",
|
||||
|
|
@ -6850,6 +6960,11 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"@types/google.maps": {
|
||||
"version": "3.55.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/google.maps/-/google.maps-3.55.2.tgz",
|
||||
"integrity": "sha512-JcTwzkxskR8DN/nnX96Pie3gGN3WHiPpuxzuQ9z3516o1bB243d8w8DHUJ8BohuzoT1o3HUFta2ns/mkZC8KRw=="
|
||||
},
|
||||
"@types/json5": {
|
||||
"version": "0.0.29",
|
||||
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
|
||||
|
|
@ -8149,8 +8264,7 @@
|
|||
"fast-deep-equal": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
||||
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
|
||||
"dev": true
|
||||
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
|
||||
},
|
||||
"fast-glob": {
|
||||
"version": "3.3.2",
|
||||
|
|
@ -8547,6 +8661,14 @@
|
|||
"side-channel": "^1.0.4"
|
||||
}
|
||||
},
|
||||
"invariant": {
|
||||
"version": "2.2.4",
|
||||
"resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
|
||||
"integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
|
||||
"requires": {
|
||||
"loose-envify": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"is-array-buffer": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz",
|
||||
|
|
@ -8874,6 +8996,11 @@
|
|||
"object.values": "^1.1.6"
|
||||
}
|
||||
},
|
||||
"kdbush": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/kdbush/-/kdbush-4.0.2.tgz",
|
||||
"integrity": "sha512-WbCVYJ27Sz8zi9Q7Q0xHC+05iwkm3Znipc2XTlrnJbsHMYktW4hPhXUE8Ys1engBrvffoSCqbil1JQAa7clRpA=="
|
||||
},
|
||||
"keyv": {
|
||||
"version": "4.5.4",
|
||||
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
|
||||
|
|
@ -9849,6 +9976,14 @@
|
|||
"resolved": "https://registry.npmjs.org/stylis/-/stylis-4.1.3.tgz",
|
||||
"integrity": "sha512-GP6WDNWf+o403jrEp9c5jibKavrtLW+/qYGhFxFrG8maXhwTBI7gLLhiBb0o7uFccWN+EOS9aMO6cGHWAO07OA=="
|
||||
},
|
||||
"supercluster": {
|
||||
"version": "8.0.1",
|
||||
"resolved": "https://registry.npmjs.org/supercluster/-/supercluster-8.0.1.tgz",
|
||||
"integrity": "sha512-IiOea5kJ9iqzD2t7QJq/cREyLHTtSmUT6gQsweojg9WH2sYJqZK9SswTu6jrscO6D1G5v5vYZ9ru/eq85lXeZQ==",
|
||||
"requires": {
|
||||
"kdbush": "^4.0.2"
|
||||
}
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
"@mui/material": "5.11.10",
|
||||
"@mui/system": "5.11.9",
|
||||
"@mui/x-date-pickers": "5.0.19",
|
||||
"@react-google-maps/api": "^2.19.3",
|
||||
"apexcharts": "3.37.0",
|
||||
"date-fns": "2.29.3",
|
||||
"formik": "2.2.9",
|
||||
|
|
|
|||
|
|
@ -150,7 +150,7 @@ export const AuthProvider = (props) => {
|
|||
redirect: 'follow'
|
||||
};
|
||||
|
||||
let result = await fetch(process.env.NEXT_PUBLIC_REST_ENDPOINT+"/auth/login", requestOptions)
|
||||
let result = await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/auth/login`, requestOptions)
|
||||
|
||||
if (result.status != 200) {
|
||||
throw new Error('Please check your email and password');
|
||||
|
|
@ -199,7 +199,7 @@ export const AuthProvider = (props) => {
|
|||
redirect: 'follow'
|
||||
};
|
||||
|
||||
let result = await fetch(process.env.NEXT_PUBLIC_REST_ENDPOINT+"/auth/admin/register", requestOptions)
|
||||
let result = await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/auth/admin/register`, requestOptions)
|
||||
|
||||
if (result.status == 200) {
|
||||
router.push("/auth/login")
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ export const items = [
|
|||
// <SvgIcon fontSize="small">
|
||||
// <MapIcon/>
|
||||
// </SvgIcon>
|
||||
// )
|
||||
// ),
|
||||
// },
|
||||
{
|
||||
title: 'Credentials',
|
||||
|
|
|
|||
|
|
@ -49,12 +49,11 @@ export const Layout = withAuthGuard((props) => {
|
|||
|
||||
return (
|
||||
<>
|
||||
<TopNav onNavOpen={() => setOpenNav(true)} />
|
||||
{pathname != "/map" && <TopNav onNavOpen={() => setOpenNav(true)} />}
|
||||
<SideNav
|
||||
onClose={() => setOpenNav(false)}
|
||||
open={openNav}
|
||||
/>
|
||||
|
||||
<LayoutRoot>
|
||||
<LayoutContainer>
|
||||
{children}
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ const Page = () => {
|
|||
redirect: 'follow',
|
||||
};
|
||||
|
||||
let result = await (await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT}/auth/admin/exists`, requestOptions))
|
||||
let result = await (await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/auth/admin/exists`, requestOptions))
|
||||
let content = await result.json()
|
||||
console.log("content: ", content)
|
||||
if (result.status != 200) {
|
||||
|
|
@ -131,12 +131,12 @@ const Page = () => {
|
|||
<Typography variant="h4">
|
||||
Login
|
||||
</Typography>
|
||||
<Typography
|
||||
{!(process.env.NEXT_PUBLIC_ENTERPRISE_VERSION == "true") && <Typography
|
||||
color="text.secondary"
|
||||
variant="body2"
|
||||
>
|
||||
This project is open source, reach out at <Link href='https://github.com/OktopUSP/oktopus'>Github</Link> or <Link href='https://join.slack.com/t/oktopustr-369/shared_invite/zt-1znmrbr52-3AXgOlSeQTPQW8_Qhn3C4g'>Slack</Link>
|
||||
</Typography>
|
||||
This project is open source, reach out at <Link href='https://github.com/OktopUSP/oktopus'>Github</Link> or <Link href='https://join.slack.com/t/oktopustr-369/shared_invite/zt-1znmrbr52-3AXgOlSeQTPQW8_Qhn3C4g'>Slack</Link>
|
||||
</Typography>}
|
||||
</Stack>
|
||||
{/*<Tabs
|
||||
onChange={handleMethodChange}
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ const Page = () => {
|
|||
redirect: 'follow'
|
||||
};
|
||||
|
||||
fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT}/users`,requestOptions)
|
||||
fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/users`,requestOptions)
|
||||
.then(response => response.json())
|
||||
.then(result => {
|
||||
// let teste = JSON.stringify(JSON.parse(result), null, 2)
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ const Page = () => {
|
|||
redirect: 'follow'
|
||||
}
|
||||
|
||||
return fetch(process.env.NEXT_PUBLIC_REST_ENDPOINT + '/device/auth?id='+id, requestOptions)
|
||||
return fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/device/auth?id=${id}`, requestOptions)
|
||||
.then(response => {
|
||||
if (response.status === 401) {
|
||||
router.push("/auth/login")
|
||||
|
|
@ -81,7 +81,7 @@ const Page = () => {
|
|||
redirect: 'follow'
|
||||
};
|
||||
|
||||
let result = await fetch(process.env.NEXT_PUBLIC_REST_ENDPOINT+"/device/auth", requestOptions)
|
||||
let result = await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/device/auth`, requestOptions)
|
||||
|
||||
if (result.status == 200) {
|
||||
console.log("user created: deu boa raça !!")
|
||||
|
|
@ -134,7 +134,7 @@ const Page = () => {
|
|||
redirect: 'follow'
|
||||
}
|
||||
|
||||
let url = process.env.NEXT_PUBLIC_REST_ENDPOINT + '/device/auth'
|
||||
let url = `${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/device/auth`
|
||||
if (id !== undefined && id !== "") {
|
||||
url += "?id="+id
|
||||
}
|
||||
|
|
@ -224,7 +224,7 @@ const Page = () => {
|
|||
<OutlinedInput
|
||||
defaultValue=""
|
||||
fullWidth
|
||||
placeholder="Search customer"
|
||||
placeholder="Search credentials by username"
|
||||
onKeyDownCapture={(e) => {
|
||||
if (e.key === 'Enter') {
|
||||
console.log("Fetch credentials per username: ", e.target.value)
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ const Page = () => {
|
|||
redirect: 'follow'
|
||||
}
|
||||
|
||||
fetch(process.env.NEXT_PUBLIC_REST_ENDPOINT+'/device', requestOptions)
|
||||
fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/device`, requestOptions)
|
||||
.then(response => {
|
||||
if (response.status === 401)
|
||||
router.push("/auth/login")
|
||||
|
|
@ -86,7 +86,7 @@ const Page = () => {
|
|||
p = p - 1
|
||||
p = p.toString()
|
||||
|
||||
fetch(process.env.NEXT_PUBLIC_REST_ENDPOINT+'/device?page_number='+p, requestOptions)
|
||||
fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/device?page_number=+${p}`, requestOptions)
|
||||
.then(response => {
|
||||
if (response.status === 401)
|
||||
router.push("/auth/login")
|
||||
|
|
@ -116,7 +116,7 @@ const Page = () => {
|
|||
}
|
||||
|
||||
if (id == ""){
|
||||
return fetch(process.env.NEXT_PUBLIC_REST_ENDPOINT+'/device', requestOptions)
|
||||
return fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/device`, requestOptions)
|
||||
.then(response => {
|
||||
if (response.status === 401)
|
||||
router.push("/auth/login")
|
||||
|
|
@ -134,7 +134,7 @@ const Page = () => {
|
|||
});
|
||||
}
|
||||
|
||||
let response = await fetch(process.env.NEXT_PUBLIC_REST_ENDPOINT+'/device?id='+id, requestOptions)
|
||||
let response = await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/device?id=${id}`, requestOptions)
|
||||
if (response.status === 401)
|
||||
router.push("/auth/login")
|
||||
let json = await response.json()
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ const Page = () => {
|
|||
redirect: 'follow',
|
||||
};
|
||||
|
||||
let result = await (await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT}/info/general`, requestOptions))
|
||||
let result = await (await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/info/general`, requestOptions))
|
||||
if (result.status === 401){
|
||||
router.push("/auth/login")
|
||||
}else if (result.status != 200){
|
||||
|
|
|
|||
86
frontend/src/pages/map.js
Normal file
86
frontend/src/pages/map.js
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
import Head from 'next/head';
|
||||
import { GoogleMap, useLoadScript } 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';
|
||||
|
||||
const Page = () => {
|
||||
|
||||
const libraries = useMemo(() => ['places'], []);
|
||||
|
||||
const [mapCenter, setMapCenter] = useState(null);
|
||||
|
||||
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.");
|
||||
}
|
||||
},[])
|
||||
|
||||
const mapOptions = useMemo(
|
||||
() => ({
|
||||
disableDefaultUI: false,
|
||||
clickableIcons: true,
|
||||
zoomControl: true,
|
||||
controlSize: 23,
|
||||
styles: mapStyles,
|
||||
mapTypeControlOptions: {
|
||||
mapTypeIds: ['roadmap', 'satellite'],
|
||||
}
|
||||
}),
|
||||
[]
|
||||
);
|
||||
|
||||
const { isLoaded } = useLoadScript({
|
||||
googleMapsApiKey: process.env.NEXT_PUBLIC_GOOGLE_MAPS_KEY,
|
||||
libraries: libraries,
|
||||
});
|
||||
|
||||
if (!isLoaded) {
|
||||
return <p>Loading...</p>;
|
||||
}
|
||||
|
||||
return ( mapCenter &&
|
||||
<>
|
||||
<Head>
|
||||
<title>
|
||||
Maps | Oktopus
|
||||
</title>
|
||||
</Head>
|
||||
<GoogleMap
|
||||
options={mapOptions}
|
||||
zoom={14}
|
||||
center={mapCenter}
|
||||
mapContainerStyle={{ width: '100%', height: '100%' }}
|
||||
onLoad={() => console.log('Map Component Loaded...')}
|
||||
clickableIcons={false}
|
||||
/>
|
||||
</>
|
||||
)};
|
||||
|
||||
Page.getLayout = (page) => (
|
||||
<DashboardLayout>
|
||||
{page}
|
||||
</DashboardLayout>
|
||||
);
|
||||
|
||||
export default Page;
|
||||
|
|
@ -8,7 +8,7 @@ const Page = () => (
|
|||
<>
|
||||
<Head>
|
||||
<title>
|
||||
Settings | Devias Kit
|
||||
Settings | Oktopus
|
||||
</title>
|
||||
</Head>
|
||||
<Box
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ const Page = () => {
|
|||
redirect: 'follow'
|
||||
}
|
||||
|
||||
return fetch(process.env.NEXT_PUBLIC_REST_ENDPOINT + '/auth/delete/' + id, requestOptions)
|
||||
return fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/auth/delete/${id}`, requestOptions)
|
||||
.then(response => {
|
||||
if (response.status === 401) {
|
||||
router.push("/auth/login")
|
||||
|
|
@ -82,7 +82,7 @@ const Page = () => {
|
|||
redirect: 'follow'
|
||||
}
|
||||
|
||||
return fetch(process.env.NEXT_PUBLIC_REST_ENDPOINT + '/users', requestOptions)
|
||||
return fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/users`, requestOptions)
|
||||
.then(response => {
|
||||
if (response.status === 401) {
|
||||
router.push("/auth/login")
|
||||
|
|
@ -142,7 +142,7 @@ const Page = () => {
|
|||
redirect: 'follow'
|
||||
};
|
||||
|
||||
let result = await fetch(process.env.NEXT_PUBLIC_REST_ENDPOINT+"/auth/register", requestOptions)
|
||||
let result = await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/auth/register`, requestOptions)
|
||||
|
||||
if (result.status == 200) {
|
||||
console.log("user created: deu boa raça !!")
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ export const ConnectedDevices = () => {
|
|||
redirect: 'follow'
|
||||
};
|
||||
|
||||
fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT}/device/${router.query.id[0]}/connecteddevices`, requestOptions)
|
||||
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")
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ export const DevicesDiagnostic = () => {
|
|||
redirect: 'follow'
|
||||
};
|
||||
|
||||
fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT}/device/${router.query.id[0]}/ping`, requestOptions)
|
||||
fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/device/${router.query.id[0]}/ping`, requestOptions)
|
||||
.then(response => {
|
||||
if (response.status === 401) {
|
||||
router.push("/auth/login")
|
||||
|
|
@ -95,7 +95,7 @@ export const DevicesDiagnostic = () => {
|
|||
body: JSON.stringify(content)
|
||||
};
|
||||
|
||||
fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT}/device/${router.query.id[0]}/ping`, requestOptions)
|
||||
fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/device/${router.query.id[0]}/ping`, requestOptions)
|
||||
.then(response => {
|
||||
if (response.status === 401) {
|
||||
router.push("/auth/login")
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ const handleOpen = () => {
|
|||
}
|
||||
|
||||
|
||||
fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT}/device/cwmp/${router.query.id[0]}/${method}`, requestOptions)
|
||||
fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/device/cwmp/${router.query.id[0]}/${method}`, requestOptions)
|
||||
.then(response => response.text())
|
||||
.then(result => {
|
||||
if (result.status === 401){
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ export const DevicesWiFi = () => {
|
|||
redirect: 'follow'
|
||||
};
|
||||
|
||||
fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT}/device/${router.query.id[0]}/wifi`, requestOptions)
|
||||
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")
|
||||
|
|
@ -197,7 +197,7 @@ export const DevicesWiFi = () => {
|
|||
body: data,
|
||||
redirect: 'follow'
|
||||
};
|
||||
fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT}/device/${router.query.id[0]}/wifi`, requestOptions)
|
||||
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")
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ export const SiteSurvey = (props) => {
|
|||
redirect: 'follow'
|
||||
};
|
||||
|
||||
fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT}/device/${router.query.id[0]}/sitesurvey`, requestOptions)
|
||||
fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/device/${router.query.id[0]}/sitesurvey`, requestOptions)
|
||||
.then(response => {
|
||||
if (response.status === 401) {
|
||||
router.push("/auth/login")
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ const addDeviceObj = async(obj, setShowLoading, router, updateDeviceParameters)
|
|||
body: raw
|
||||
};
|
||||
setShowLoading(true)
|
||||
let result = await (await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT}/device/${router.query.id[0]}/any/add`, requestOptions))
|
||||
let result = await (await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/device/${router.query.id[0]}/any/add`, requestOptions))
|
||||
if (result.status != 200) {
|
||||
if (result.status === 401){
|
||||
router.push("/auth/login")
|
||||
|
|
@ -131,7 +131,7 @@ const deleteDeviceObj = async(obj, setShowLoading, router, updateDeviceParameter
|
|||
body: raw
|
||||
};
|
||||
setShowLoading(true)
|
||||
let result = await (await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT}/device/${router.query.id[0]}/any/del`, requestOptions))
|
||||
let result = await (await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/device/${router.query.id[0]}/any/del`, requestOptions))
|
||||
if (result.status != 200) {
|
||||
if (result.status === 401){
|
||||
router.push("/auth/login")
|
||||
|
|
@ -481,7 +481,7 @@ const getDeviceParameters = async (raw) =>{
|
|||
body: raw
|
||||
};
|
||||
|
||||
let result = await (await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT}/device/${router.query.id[0]}/any/parameters`, requestOptions))
|
||||
let result = await (await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/device/${router.query.id[0]}/any/parameters`, requestOptions))
|
||||
if (result.status != 200) {
|
||||
if (result.status === 401){
|
||||
router.push("/auth/login")
|
||||
|
|
@ -505,7 +505,7 @@ const getDeviceParameterInstances = async (raw) =>{
|
|||
body: raw
|
||||
};
|
||||
|
||||
let result = await (await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT}/device/${router.query.id[0]}/any/instances`, requestOptions))
|
||||
let result = await (await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/device/${router.query.id[0]}/any/instances`, requestOptions))
|
||||
if (result.status != 200) {
|
||||
throw new Error('Please check your email and password');
|
||||
}else if (result.status === 401){
|
||||
|
|
@ -779,7 +779,7 @@ const getDeviceParameterInstances = async (raw) =>{
|
|||
body: raw
|
||||
};
|
||||
|
||||
let result = await (await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT}/device/${router.query.id[0]}/any/get`, requestOptions))
|
||||
let result = await (await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/device/${router.query.id[0]}/any/get`, requestOptions))
|
||||
if (result.status != 200) {
|
||||
if (result.status === 401){
|
||||
router.push("/auth/login")
|
||||
|
|
@ -1029,7 +1029,7 @@ const getDeviceParameterInstances = async (raw) =>{
|
|||
|
||||
setOpen(false)
|
||||
setShowLoading(true)
|
||||
let result = await (await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT}/device/${router.query.id[0]}/any/set`, requestOptions))
|
||||
let result = await (await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/device/${router.query.id[0]}/any/set`, requestOptions))
|
||||
if (result.status != 200) {
|
||||
if (result.status === 401){
|
||||
router.push("/auth/login")
|
||||
|
|
@ -1172,7 +1172,7 @@ const getDeviceParameterInstances = async (raw) =>{
|
|||
body: raw
|
||||
};
|
||||
setShowLoading(true)
|
||||
let result = await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT}/device/${router.query.id[0]}/any/operate`, requestOptions)
|
||||
let result = await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/device/${router.query.id[0]}/any/operate`, requestOptions)
|
||||
let content = await result.json()
|
||||
if (result.status != 200) {
|
||||
setShowLoading(false)
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ const handleOpen = () => {
|
|||
}
|
||||
|
||||
|
||||
fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT}/device/${router.query.id[0]}/any/${method}`, requestOptions)
|
||||
fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/device/${router.query.id[0]}/any/${method}`, requestOptions)
|
||||
.then(response => response.text())
|
||||
.then(result => {
|
||||
if (result.status === 401){
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ export const OverviewLatestOrders = (props) => {
|
|||
redirect: 'follow'
|
||||
};
|
||||
|
||||
let result = await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT}/device/alias?id=${sn}`, requestOptions)
|
||||
let result = await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/device/alias?id=${sn}`, requestOptions)
|
||||
console.log("result:", result)
|
||||
if (result.status === 401){
|
||||
router.push("/auth/login")
|
||||
|
|
@ -199,13 +199,6 @@ export const OverviewLatestOrders = (props) => {
|
|||
setDeviceAlias(order.Alias)
|
||||
setShowSetDeviceAlias(true)
|
||||
}}
|
||||
onKeyDown={e => {
|
||||
if (e.key === 'Enter') {
|
||||
setDeviceToBeChanged(index)
|
||||
setDeviceAlias(order.Alias)
|
||||
setShowSetDeviceAlias(true)
|
||||
}
|
||||
}}
|
||||
>
|
||||
<SvgIcon
|
||||
fontSize="small"
|
||||
|
|
@ -239,10 +232,16 @@ export const OverviewLatestOrders = (props) => {
|
|||
</Button>
|
||||
</CardActions>*/}
|
||||
</Card>
|
||||
{showSetDeviceAlias&&
|
||||
<Dialog open={showSetDeviceAlias}>
|
||||
<DialogContent>
|
||||
<InputLabel>Device Alias</InputLabel>
|
||||
<Input value={deviceAlias} onChange={(e)=>{setDeviceAlias(e.target.value)}}>
|
||||
<Input value={deviceAlias} onChange={(e)=>{setDeviceAlias(e.target.value)}}
|
||||
onKeyUp={e => {
|
||||
if (e.key === 'Enter') {
|
||||
setNewDeviceAlias(deviceAlias, orders[deviceToBeChanged].SN)
|
||||
}
|
||||
}}>
|
||||
</Input>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
|
|
@ -255,7 +254,7 @@ export const OverviewLatestOrders = (props) => {
|
|||
setNewDeviceAlias(deviceAlias, orders[deviceToBeChanged].SN)
|
||||
}}>Save</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
</Dialog>}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
20
frontend/src/utils/mapStyles.json
Normal file
20
frontend/src/utils/mapStyles.json
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
[
|
||||
{
|
||||
"featureType": "all",
|
||||
"elementType": "labels.text",
|
||||
"stylers": [
|
||||
{
|
||||
"visibility": "on"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"featureType": "poi",
|
||||
"elementType": "labels.icon",
|
||||
"stylers": [
|
||||
{
|
||||
"visibility": "off"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
Loading…
Reference in New Issue
Block a user