diff --git a/backend/services/controller/internal/api/api.go b/backend/services/controller/internal/api/api.go index 7e16a65..de3be17 100644 --- a/backend/services/controller/internal/api/api.go +++ b/backend/services/controller/internal/api/api.go @@ -58,6 +58,7 @@ func (a *Api) StartApi() { authentication.HandleFunc("/admin/register", a.registerAdminUser).Methods("POST") authentication.HandleFunc("/admin/exists", a.adminUserExists).Methods("GET") iot := r.PathPrefix("/api/device").Subrouter() + iot.HandleFunc("/alias", a.setDeviceAlias).Methods("PUT") iot.HandleFunc("/auth", a.deviceAuth).Methods("GET", "POST", "DELETE") iot.HandleFunc("/cwmp/{sn}/getParameterNames", a.cwmpGetParameterNamesMsg).Methods("PUT") iot.HandleFunc("/cwmp/{sn}/getParameterValues", a.cwmpGetParameterValuesMsg).Methods("PUT") @@ -79,6 +80,8 @@ func (a *Api) StartApi() { if a.enterpise { 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") + iot.HandleFunc("/{sn}/speedtest", a.deviceSpeedTest).Methods("PUT") } iot.HandleFunc("/{sn}/wifi", a.deviceWifi).Methods("PUT", "GET") dash := r.PathPrefix("/api/info").Subrouter() diff --git a/backend/services/controller/internal/bridge/bridge.go b/backend/services/controller/internal/bridge/bridge.go index 542f8a3..a972e22 100644 --- a/backend/services/controller/internal/bridge/bridge.go +++ b/backend/services/controller/internal/bridge/bridge.go @@ -164,7 +164,7 @@ func NatsReq[T entity.DataType]( return nil, err } - log.Printf("Error message received, msg: %s, code: %d", *errMsg.Msg, errMsg.Code) + log.Printf("message received, msg: %s, code: %d", *errMsg.Msg, errMsg.Code) w.WriteHeader(errMsg.Code) w.Write(utils.Marshall(*errMsg.Msg)) return nil, errNatsMsgReceivedWithErrorData diff --git a/backend/services/controller/internal/entity/device.go b/backend/services/controller/internal/entity/device.go index f3a0923..12948a7 100644 --- a/backend/services/controller/internal/entity/device.go +++ b/backend/services/controller/internal/entity/device.go @@ -7,6 +7,7 @@ type Device struct { Vendor string Version string ProductClass string + Alias string Status Status Mqtt Status Stomp Status diff --git a/backend/services/mtp/adapter/internal/db/device.go b/backend/services/mtp/adapter/internal/db/device.go index 3fc3cfb..c78ac6a 100644 --- a/backend/services/mtp/adapter/internal/db/device.go +++ b/backend/services/mtp/adapter/internal/db/device.go @@ -33,6 +33,7 @@ type Device struct { Vendor string Version string ProductClass string + Alias string Status Status Mqtt Status Stomp Status @@ -145,6 +146,11 @@ func (d *Database) DeleteDevice() { } +func (d *Database) SetDeviceAlias(sn string, newAlias string) error { + err := d.devices.FindOneAndUpdate(d.ctx, bson.D{{"sn", sn}}, bson.D{{"$set", bson.D{{"alias", newAlias}}}}).Err() + return err +} + func (d *Database) DeviceExists(sn string) (bool, error) { _, err := d.RetrieveDevice(sn) if err != nil { diff --git a/backend/services/mtp/adapter/internal/reqs/reqs.go b/backend/services/mtp/adapter/internal/reqs/reqs.go index e6d5f0a..166651d 100644 --- a/backend/services/mtp/adapter/internal/reqs/reqs.go +++ b/backend/services/mtp/adapter/internal/reqs/reqs.go @@ -89,6 +89,22 @@ func StartRequestsListener(ctx context.Context, nc *nats.Conn, db db.Database) { } respondMsg(msg.Respond, 200, productClassCount) }) + + nc.Subscribe(local.ADAPTER_SUBJECT+"*.device.alias", func(msg *nats.Msg) { + subject := strings.Split(msg.Subject, ".") + device := subject[len(subject)-3] + + err := db.SetDeviceAlias(device, string(msg.Data)) + if err != nil { + if err == mongo.ErrNoDocuments { + respondMsg(msg.Respond, 404, "Device not found") + } else { + respondMsg(msg.Respond, 500, err.Error()) + } + return + } + respondMsg(msg.Respond, 200, "Alias updated") + }) } func respondMsg(respond func(data []byte) error, code int, msgData any) { diff --git a/frontend/src/sections/overview/overview-latest-orders.js b/frontend/src/sections/overview/overview-latest-orders.js index 4d3e14a..ba3e2ae 100644 --- a/frontend/src/sections/overview/overview-latest-orders.js +++ b/frontend/src/sections/overview/overview-latest-orders.js @@ -8,17 +8,26 @@ import { Card, CardActions, CardHeader, + Dialog, + DialogActions, + DialogContent, + DialogTitle, Divider, + Input, + InputLabel, SvgIcon, Table, TableBody, TableCell, TableHead, - TableRow + TableRow, + Tooltip } from '@mui/material'; import { Scrollbar } from 'src/components/scrollbar'; import { SeverityPill } from 'src/components/severity-pill'; import { useRouter } from 'next/router'; +import { useState } from 'react'; +import PencilIcon from '@heroicons/react/24/outline/PencilIcon'; const statusMap = { 1: 'warning', @@ -51,7 +60,60 @@ export const OverviewLatestOrders = (props) => { const router = useRouter() - return ( + const [showSetDeviceAlias, setShowSetDeviceAlias] = useState(false); + const [deviceAlias, setDeviceAlias] = useState(null); + const [deviceToBeChanged, setDeviceToBeChanged] = useState(null); + + const setNewDeviceAlias = async (alias,sn) => { + var myHeaders = new Headers(); + myHeaders.append("Content-Type", "application/json"); + myHeaders.append("Authorization", localStorage.getItem("token")); + + var requestOptions = { + method: 'PUT', + headers: myHeaders, + body: alias, + redirect: 'follow' + }; + + let result = await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT}/device/alias?id=${sn}`, requestOptions) + console.log("result:", result) + if (result.status === 401){ + router.push("/auth/login") + }else if (result.status != 200){ + console.log("Status:", result.status) + let content = await result.json() + console.log("Message:", content) + setShowSetDeviceAlias(false) + setDeviceAlias(null) + setDeviceToBeChanged(null) + }else{ + let content = await result.json() + console.log("set alias result:", content) + setShowSetDeviceAlias(false) + setDeviceAlias(null) + orders[deviceToBeChanged].Alias = alias + setDeviceToBeChanged(null) + } + // .then(response => { + // if (response.status === 401) { + // router.push("/auth/login") + // } + // return response.json() + // }) + // .then(result => { + // console.log("alias result:", result) + // setShowSetDeviceAlias(false) + // setDeviceAlias(null) + // }) + // .catch(error => { + // console.log('error:', error) + // setShowSetDeviceAlias(false) + // setDeviceAlias(null) + // }) + } + + return (
@@ -62,6 +124,9 @@ export const OverviewLatestOrders = (props) => { Serial Number + + Alias + Model @@ -74,13 +139,13 @@ export const OverviewLatestOrders = (props) => { Status - - Access + + Actions - {orders && orders.map((order) => { + {orders && orders.map((order, index) => { return ( { {order.SN} - {order.Model} + {order.Alias} + + + {order.Model || order.ProductClass} {order.Vendor} @@ -104,24 +172,49 @@ export const OverviewLatestOrders = (props) => { {status(order.Status)} - + {order.Status == 2 && - } + + + + + } + + + ); @@ -146,6 +239,24 @@ export const OverviewLatestOrders = (props) => { */} + + + Device Alias + {setDeviceAlias(e.target.value)}}> + + + + + + + +
); };