added robotics
parent
c080c2a9af
commit
4acbe50f8b
|
@ -21,7 +21,11 @@
|
||||||
"updatedAt": "Aktualisiert am:",
|
"updatedAt": "Aktualisiert am:",
|
||||||
"createdBy": "Erstellt von:",
|
"createdBy": "Erstellt von:",
|
||||||
"endedAt": "Beendet am:",
|
"endedAt": "Beendet am:",
|
||||||
"type": "Typ:"
|
"type": "Typ:",
|
||||||
|
"edit": "Bearbeiten",
|
||||||
|
"authorize": "Autorisieren",
|
||||||
|
"deny": "Ablehnen",
|
||||||
|
"disconnect": "Verbindung trennen"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"sideMenu": {
|
"sideMenu": {
|
||||||
|
@ -33,6 +37,10 @@
|
||||||
"overview": "Kategorien",
|
"overview": "Kategorien",
|
||||||
"history": "Verlauf"
|
"history": "Verlauf"
|
||||||
},
|
},
|
||||||
|
"robotics": {
|
||||||
|
"menuCategory": "Robotik",
|
||||||
|
"robots": "Roboter"
|
||||||
|
},
|
||||||
"adminArea": {
|
"adminArea": {
|
||||||
"menuCategory": "Adminbereich",
|
"menuCategory": "Adminbereich",
|
||||||
"roles": "Rollen",
|
"roles": "Rollen",
|
||||||
|
@ -155,6 +163,35 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"robotics": {
|
||||||
|
"robots": {
|
||||||
|
"header": "Roboter",
|
||||||
|
"column": {
|
||||||
|
"id": "ID",
|
||||||
|
"type": "Typ",
|
||||||
|
"name": "Name",
|
||||||
|
"status": "Status",
|
||||||
|
"currentJob": "Aktueller Job",
|
||||||
|
"jobsWaiting": "Wartende Jobs",
|
||||||
|
"address": "Adresse",
|
||||||
|
"connectedAt": "Verbunden am",
|
||||||
|
"firmwareVersion": "Firmware Version",
|
||||||
|
"createdAt": "Erstellt am",
|
||||||
|
"actions": "Maßnahmen"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"unauthorizedRobots": {
|
||||||
|
"header": "Nicht autorisierte Roboter",
|
||||||
|
"popconfirmDeny": {
|
||||||
|
"title": "Sind Sie sicher, dass Sie diesen Roboter ablehnen wollen?",
|
||||||
|
"description": "Der Roboter wird getrennt und muss sich ernuet verbinden"
|
||||||
|
},
|
||||||
|
"popconfirmAuthorize": {
|
||||||
|
"title": "Sind Sie sicher, dass Sie diesen Roboter autorisieren wollen?",
|
||||||
|
"description": "Der Roboter wird autorisiert und kann dann für Aufträge verwendet werden"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"logCard": {
|
"logCard": {
|
||||||
"popover": {
|
"popover": {
|
||||||
"groupTaskId.title": "Gruppenaufgabe",
|
"groupTaskId.title": "Gruppenaufgabe",
|
||||||
|
|
|
@ -21,7 +21,11 @@
|
||||||
"updatedAt": "Updated at:",
|
"updatedAt": "Updated at:",
|
||||||
"createdBy": "Created by:",
|
"createdBy": "Created by:",
|
||||||
"endedAt": "Ended at:",
|
"endedAt": "Ended at:",
|
||||||
"type": "Type:"
|
"type": "Type:",
|
||||||
|
"edit": "Edit",
|
||||||
|
"authorize": "Authorize",
|
||||||
|
"deny": "Deny",
|
||||||
|
"disconnect": "Disconnect"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"sideMenu": {
|
"sideMenu": {
|
||||||
|
@ -33,6 +37,10 @@
|
||||||
"overview": "Categories",
|
"overview": "Categories",
|
||||||
"history": "History"
|
"history": "History"
|
||||||
},
|
},
|
||||||
|
"robotics": {
|
||||||
|
"menuCategory": "Robotics",
|
||||||
|
"robots": "Robots"
|
||||||
|
},
|
||||||
"adminArea": {
|
"adminArea": {
|
||||||
"menuCategory": "Admin Area",
|
"menuCategory": "Admin Area",
|
||||||
"roles": "Roles",
|
"roles": "Roles",
|
||||||
|
@ -155,6 +163,35 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"robotics": {
|
||||||
|
"robots": {
|
||||||
|
"header": "Robots",
|
||||||
|
"column": {
|
||||||
|
"id": "ID",
|
||||||
|
"type": "Type",
|
||||||
|
"name": "Name",
|
||||||
|
"status": "Status",
|
||||||
|
"currentJob": "Current job",
|
||||||
|
"jobsWaiting": "Jobs waiting",
|
||||||
|
"address": "Address",
|
||||||
|
"connectedAt": "Connected at",
|
||||||
|
"firmwareVersion": "Firmware version",
|
||||||
|
"createdAt": "Created At",
|
||||||
|
"actions": "Actions"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"unauthorizedRobots": {
|
||||||
|
"header": "Unauthorized Robots",
|
||||||
|
"popconfirmDeny": {
|
||||||
|
"title": "Are you sure you want to deny this robot?",
|
||||||
|
"description": "The robot will be disconnected and needs to reconnect"
|
||||||
|
},
|
||||||
|
"popconfirmAuthorize": {
|
||||||
|
"title": "Are you sure you want to authorize this robot?",
|
||||||
|
"description": "The robot can than be used for jobs"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"logCard": {
|
"logCard": {
|
||||||
"popover": {
|
"popover": {
|
||||||
"groupTaskId.title": "Group Task",
|
"groupTaskId.title": "Group Task",
|
||||||
|
|
29
src/App.js
29
src/App.js
|
@ -14,6 +14,7 @@ import { UserProfileProvider } from "./Contexts/UserProfileContext";
|
||||||
import { UsersProvider } from "./Contexts/UsersContext";
|
import { UsersProvider } from "./Contexts/UsersContext";
|
||||||
import HeaderProvider from "./Contexts/HeaderContext";
|
import HeaderProvider from "./Contexts/HeaderContext";
|
||||||
import ConsolesProvider from "./Contexts/ConsolesContext";
|
import ConsolesProvider from "./Contexts/ConsolesContext";
|
||||||
|
import { RoboticsRobotProvider } from "./Contexts/RoboticsRobot";
|
||||||
|
|
||||||
export default function App() {
|
export default function App() {
|
||||||
const [notificationApi, notificationContextHolder] =
|
const [notificationApi, notificationContextHolder] =
|
||||||
|
@ -44,20 +45,24 @@ export default function App() {
|
||||||
<UserProfileProvider>
|
<UserProfileProvider>
|
||||||
<UsersProvider>
|
<UsersProvider>
|
||||||
<ConsolesProvider>
|
<ConsolesProvider>
|
||||||
<WebSocketProvider
|
<RoboticsRobotProvider>
|
||||||
userSession={userSession}
|
<WebSocketProvider
|
||||||
setUserSession={setUserSession}
|
|
||||||
isWebSocketReady={isWebSocketReady}
|
|
||||||
setIsWebSocketReady={setIsWebSocketReady}
|
|
||||||
notificationApi={notificationApi}
|
|
||||||
>
|
|
||||||
<ReconnectingView isWebSocketReady={isWebSocketReady} />
|
|
||||||
|
|
||||||
<DashboardLayout
|
|
||||||
userSession={userSession}
|
userSession={userSession}
|
||||||
setUserSession={setUserSession}
|
setUserSession={setUserSession}
|
||||||
/>
|
isWebSocketReady={isWebSocketReady}
|
||||||
</WebSocketProvider>
|
setIsWebSocketReady={setIsWebSocketReady}
|
||||||
|
notificationApi={notificationApi}
|
||||||
|
>
|
||||||
|
<ReconnectingView
|
||||||
|
isWebSocketReady={isWebSocketReady}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<DashboardLayout
|
||||||
|
userSession={userSession}
|
||||||
|
setUserSession={setUserSession}
|
||||||
|
/>
|
||||||
|
</WebSocketProvider>
|
||||||
|
</RoboticsRobotProvider>
|
||||||
</ConsolesProvider>
|
</ConsolesProvider>
|
||||||
</UsersProvider>
|
</UsersProvider>
|
||||||
</UserProfileProvider>
|
</UserProfileProvider>
|
||||||
|
|
|
@ -22,6 +22,7 @@ const ViewEquipmentDocumentations = lazy(() =>
|
||||||
import("../../Pages/EquipmentDocumentation/ViewEquipmentDocumentation")
|
import("../../Pages/EquipmentDocumentation/ViewEquipmentDocumentation")
|
||||||
);
|
);
|
||||||
const Consoles = lazy(() => import("../../Pages/Consoles"));
|
const Consoles = lazy(() => import("../../Pages/Consoles"));
|
||||||
|
const RoboticsRobots = lazy(() => import("../../Pages/Robotics/Robots"));
|
||||||
|
|
||||||
function SuspenseFallback({ children }) {
|
function SuspenseFallback({ children }) {
|
||||||
return (
|
return (
|
||||||
|
@ -251,6 +252,20 @@ export default function AppRoutes() {
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{hasPermission(
|
||||||
|
appContext.userPermissions,
|
||||||
|
Constants.PERMISSIONS.ROBOTICS.ROBOTS
|
||||||
|
) && (
|
||||||
|
<Route
|
||||||
|
path={Constants.ROUTE_PATHS.ROBOTICS_ROBOTS}
|
||||||
|
element={
|
||||||
|
<SuspenseFallback>
|
||||||
|
<RoboticsRobots />
|
||||||
|
</SuspenseFallback>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
<Route
|
<Route
|
||||||
path="*"
|
path="*"
|
||||||
element={
|
element={
|
||||||
|
|
|
@ -92,8 +92,6 @@ export default function LogCard({
|
||||||
sseEventSource.current.onmessage = (event) => {
|
sseEventSource.current.onmessage = (event) => {
|
||||||
const data = JSON.parse(event.data);
|
const data = JSON.parse(event.data);
|
||||||
|
|
||||||
let newLogLength = 0;
|
|
||||||
|
|
||||||
setLogs((prevLogs) => {
|
setLogs((prevLogs) => {
|
||||||
const newLogs = [...prevLogs];
|
const newLogs = [...prevLogs];
|
||||||
|
|
||||||
|
@ -101,8 +99,6 @@ export default function LogCard({
|
||||||
newLogs.push(log);
|
newLogs.push(log);
|
||||||
});
|
});
|
||||||
|
|
||||||
newLogLength = newLogs.length;
|
|
||||||
|
|
||||||
return newLogs;
|
return newLogs;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -6,6 +6,7 @@ import {
|
||||||
FileTextOutlined,
|
FileTextOutlined,
|
||||||
HistoryOutlined,
|
HistoryOutlined,
|
||||||
LogoutOutlined,
|
LogoutOutlined,
|
||||||
|
RobotOutlined,
|
||||||
ScanOutlined,
|
ScanOutlined,
|
||||||
SettingOutlined,
|
SettingOutlined,
|
||||||
SnippetsOutlined,
|
SnippetsOutlined,
|
||||||
|
@ -101,7 +102,6 @@ export default function SideMenu({
|
||||||
let groupTasksGroup = {
|
let groupTasksGroup = {
|
||||||
label: t("sideMenu.groupTasks.menuCategory"),
|
label: t("sideMenu.groupTasks.menuCategory"),
|
||||||
type: "group",
|
type: "group",
|
||||||
icon: <SnippetsOutlined />,
|
|
||||||
children: [],
|
children: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -148,6 +148,28 @@ export default function SideMenu({
|
||||||
|
|
||||||
items.push(groupTasksGroup);
|
items.push(groupTasksGroup);
|
||||||
|
|
||||||
|
// robotics
|
||||||
|
if (
|
||||||
|
hasPermission(
|
||||||
|
appContext.userPermissions,
|
||||||
|
Constants.PERMISSIONS.ROBOTICS.ROBOTS
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
let roboticsGroup = {
|
||||||
|
label: t("sideMenu.robotics.menuCategory"),
|
||||||
|
type: "group",
|
||||||
|
children: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
roboticsGroup.children.push({
|
||||||
|
label: t("sideMenu.robotics.robots"),
|
||||||
|
icon: <RobotOutlined />,
|
||||||
|
key: Constants.ROUTE_PATHS.ROBOTICS_ROBOTS,
|
||||||
|
});
|
||||||
|
|
||||||
|
items.push(roboticsGroup);
|
||||||
|
}
|
||||||
|
|
||||||
// admin area
|
// admin area
|
||||||
if (
|
if (
|
||||||
hasOnePermission(
|
hasOnePermission(
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
import { createContext, useContext, useState } from "react";
|
||||||
|
|
||||||
|
const preview = {
|
||||||
|
robots: [],
|
||||||
|
robotsTotalPages: 0,
|
||||||
|
unauthorizedRobots: [],
|
||||||
|
unauthorizedRobotsTotalPages: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
const RoboticsRobot = createContext(preview);
|
||||||
|
|
||||||
|
export const useRoboticsRobotContext = () => useContext(RoboticsRobot);
|
||||||
|
|
||||||
|
export function RoboticsRobotProvider({ children }) {
|
||||||
|
const [robots, setRobots] = useState([]);
|
||||||
|
const [robotsTotalPages, setRobotsTotalPages] = useState(0);
|
||||||
|
const [unauthorizedRobots, setUnauthorizedRobots] = useState([]);
|
||||||
|
const [unauthorizedRobotsTotalPages, setUnauthorizedRobotsTotalPages] =
|
||||||
|
useState(0);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<RoboticsRobot.Provider
|
||||||
|
value={{
|
||||||
|
robots,
|
||||||
|
setRobots,
|
||||||
|
robotsTotalPages,
|
||||||
|
setRobotsTotalPages,
|
||||||
|
unauthorizedRobots,
|
||||||
|
setUnauthorizedRobots,
|
||||||
|
unauthorizedRobotsTotalPages,
|
||||||
|
setUnauthorizedRobotsTotalPages,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</RoboticsRobot.Provider>
|
||||||
|
);
|
||||||
|
}
|
|
@ -109,7 +109,7 @@ export function handleWebSocketMessage(
|
||||||
sideBarContext.setConnectedUsers(body);
|
sideBarContext.setConnectedUsers(body);
|
||||||
break;
|
break;
|
||||||
case ReceivedMessagesCommands.NewGroupTaskStarted:
|
case ReceivedMessagesCommands.NewGroupTaskStarted:
|
||||||
// add new group task to list and remove latest group task if list length will be greater than 5
|
// add new group task to list and remove latest group task if list length will be greater than pagination limit
|
||||||
if (groupTasksContext.paginationPageRef.current === 1) {
|
if (groupTasksContext.paginationPageRef.current === 1) {
|
||||||
groupTasksContext.setGroupTasks((arr) => {
|
groupTasksContext.setGroupTasks((arr) => {
|
||||||
const newArr = [...arr];
|
const newArr = [...arr];
|
||||||
|
|
|
@ -0,0 +1,404 @@
|
||||||
|
import { Badge, Popconfirm, Space, Table, Typography } from "antd";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { useRoboticsRobotContext } from "../../../Contexts/RoboticsRobot";
|
||||||
|
import { useEffect, useRef, useState } from "react";
|
||||||
|
import {
|
||||||
|
Constants,
|
||||||
|
FormatDatetime,
|
||||||
|
myFetch,
|
||||||
|
myFetchContentType,
|
||||||
|
} from "../../../utils";
|
||||||
|
import MyPagination from "../../../Components/MyPagination";
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
|
|
||||||
|
const ReceivedSSECommands = {
|
||||||
|
UpdateRobotStatus: 1,
|
||||||
|
AddUnauthorizedRobot: 2,
|
||||||
|
AddRobot: 3,
|
||||||
|
RemoveUnauthorizedRobot: 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
function getRobotTypeString(type) {
|
||||||
|
switch (type) {
|
||||||
|
case 1:
|
||||||
|
return "Rex";
|
||||||
|
case 2:
|
||||||
|
return "Yeet";
|
||||||
|
default:
|
||||||
|
return "Unknown";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function Robots() {
|
||||||
|
const robotsContext = useRoboticsRobotContext();
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
const [robotsPaginationPage, setRobotsPaginationPage] = useState(1);
|
||||||
|
const [
|
||||||
|
unauthorizedRobotsPaginationPage,
|
||||||
|
setUnauthorizedRobotsPaginationPage,
|
||||||
|
] = useState(1);
|
||||||
|
|
||||||
|
const sseEventSource = useRef(null);
|
||||||
|
|
||||||
|
const getRobotStatusBadge = (status) => {
|
||||||
|
switch (status) {
|
||||||
|
case 1:
|
||||||
|
return <Badge status="success" text={"Idle"} />;
|
||||||
|
case 2:
|
||||||
|
return <Badge status="processing" text={"Running"} />;
|
||||||
|
case 3:
|
||||||
|
return <Badge status="warning" text={"Connecting"} />;
|
||||||
|
case 4:
|
||||||
|
return <Badge status="warning" text={"Error"} />;
|
||||||
|
case 5:
|
||||||
|
return <Badge status="default" text={"Offline"} />;
|
||||||
|
default:
|
||||||
|
return "Unknown";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getRobotsTableContent = () => {
|
||||||
|
let items = [
|
||||||
|
{
|
||||||
|
title: t("robotics.robots.column.id"),
|
||||||
|
dataIndex: "id",
|
||||||
|
key: "id",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t("robotics.robots.column.type"),
|
||||||
|
dataIndex: "type",
|
||||||
|
key: "type",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t("robotics.robots.column.name"),
|
||||||
|
dataIndex: "name",
|
||||||
|
key: "name",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t("robotics.robots.column.status"),
|
||||||
|
dataIndex: "status",
|
||||||
|
key: "status",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t("robotics.robots.column.currentJob"),
|
||||||
|
dataIndex: "currentJob",
|
||||||
|
key: "currentJob",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t("robotics.robots.column.jobsWaiting"),
|
||||||
|
dataIndex: "jobsWaiting",
|
||||||
|
key: "jobsWaiting",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t("robotics.robots.column.address"),
|
||||||
|
dataIndex: "address",
|
||||||
|
key: "address",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t("robotics.robots.column.connectedAt"),
|
||||||
|
dataIndex: "connectedAt",
|
||||||
|
key: "connectedAt",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t("robotics.robots.column.firmwareVersion"),
|
||||||
|
dataIndex: "firmwareVersion",
|
||||||
|
key: "firmwareVersion",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t("robotics.robots.column.createdAt"),
|
||||||
|
dataIndex: "createdAt",
|
||||||
|
key: "createdAt",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t("robotics.robots.column.actions"),
|
||||||
|
dataIndex: "actions",
|
||||||
|
key: "actions",
|
||||||
|
render: (_, record) => (
|
||||||
|
<Space size="middle">
|
||||||
|
<Link to="#">{t("common.text.edit")}</Link>
|
||||||
|
<Link to="#">{t("common.text.disconnect")}</Link>
|
||||||
|
</Space>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return items;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getRobotsTableItems = (robots) => {
|
||||||
|
let items = [];
|
||||||
|
|
||||||
|
robots.forEach((robot) => {
|
||||||
|
items.push({
|
||||||
|
key: robot.Id,
|
||||||
|
id: robot.Id,
|
||||||
|
type: getRobotTypeString(robot.Type),
|
||||||
|
name: robot.Name,
|
||||||
|
status: getRobotStatusBadge(robot.Status),
|
||||||
|
currentJob: robot.CurrentJob,
|
||||||
|
jobsWaiting: robot.JobsWaitingCount,
|
||||||
|
address: robot.Address,
|
||||||
|
firmwareVersion: robot.FirmwareVersion,
|
||||||
|
connectedAt: FormatDatetime(robot.ConnectedAt),
|
||||||
|
actions: robot.Actions,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return items;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getUnauthorizedTableContent = () => {
|
||||||
|
let items = [
|
||||||
|
{
|
||||||
|
title: t("robotics.robots.column.id"),
|
||||||
|
dataIndex: "id",
|
||||||
|
key: "id",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t("robotics.robots.column.type"),
|
||||||
|
dataIndex: "type",
|
||||||
|
key: "type",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t("robotics.robots.column.address"),
|
||||||
|
dataIndex: "address",
|
||||||
|
key: "address",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t("robotics.robots.column.connectedAt"),
|
||||||
|
dataIndex: "connectedAt",
|
||||||
|
key: "connectedAt",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t("robotics.robots.column.actions"),
|
||||||
|
dataIndex: "actions",
|
||||||
|
key: "actions",
|
||||||
|
render: (_, record) => (
|
||||||
|
<Space size="middle">
|
||||||
|
<Popconfirm
|
||||||
|
placement="left"
|
||||||
|
title={t("robotics.unauthorizedRobots.popconfirmDeny.title")}
|
||||||
|
description={t(
|
||||||
|
"robotics.unauthorizedRobots.popconfirmDeny.description"
|
||||||
|
)}
|
||||||
|
okText={t("common.button.confirm")}
|
||||||
|
cancelText={t("common.button.cancel")}
|
||||||
|
onConfirm={() =>
|
||||||
|
myFetch(
|
||||||
|
`/robot/deny/${record.id}`,
|
||||||
|
"DELETE",
|
||||||
|
null,
|
||||||
|
{},
|
||||||
|
myFetchContentType.JSON,
|
||||||
|
Constants.ROBOTICS_API_ADDRESS
|
||||||
|
).then((data) => {
|
||||||
|
console.log("data", data);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Link to="#">{t("common.text.deny")}</Link>
|
||||||
|
</Popconfirm>
|
||||||
|
|
||||||
|
<Popconfirm
|
||||||
|
placement="left"
|
||||||
|
title={t("robotics.unauthorizedRobots.popconfirmAuthorize.title")}
|
||||||
|
description={t(
|
||||||
|
"robotics.unauthorizedRobots.popconfirmAuthorize.description"
|
||||||
|
)}
|
||||||
|
okText={t("common.button.confirm")}
|
||||||
|
cancelText={t("common.button.cancel")}
|
||||||
|
onConfirm={() =>
|
||||||
|
myFetch(
|
||||||
|
`/robot/authorize/${record.id}`,
|
||||||
|
"POST",
|
||||||
|
null,
|
||||||
|
{},
|
||||||
|
myFetchContentType.JSON,
|
||||||
|
Constants.ROBOTICS_API_ADDRESS
|
||||||
|
).then((data) => {
|
||||||
|
console.log("data", data);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Link to="#">{t("common.text.authorize")}</Link>
|
||||||
|
</Popconfirm>
|
||||||
|
</Space>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return items;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getUnauthorizedTableItems = (unauthorizedRobots) => {
|
||||||
|
let items = [];
|
||||||
|
|
||||||
|
unauthorizedRobots.forEach((robot) => {
|
||||||
|
items.push({
|
||||||
|
key: robot.Id,
|
||||||
|
id: robot.Id,
|
||||||
|
type: getRobotTypeString(robot.Type),
|
||||||
|
address: robot.Address,
|
||||||
|
connectedAt: FormatDatetime(robot.ConnectedAt),
|
||||||
|
actions: robot.Actions,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return items;
|
||||||
|
};
|
||||||
|
|
||||||
|
// type = 0 => robots, type = 1 => unauthorizedRobots
|
||||||
|
const fetchRobots = (type, page = 1) => {
|
||||||
|
myFetch(
|
||||||
|
`/${type === 1 ? "u" : ""}robots?page=${page}`,
|
||||||
|
"GET",
|
||||||
|
null,
|
||||||
|
{},
|
||||||
|
myFetchContentType.JSON,
|
||||||
|
Constants.ROBOTICS_API_ADDRESS
|
||||||
|
).then((data) => {
|
||||||
|
if (type === 1) {
|
||||||
|
robotsContext.setUnauthorizedRobots(
|
||||||
|
data.UnauthorizedRobots === null ? [] : data.UnauthorizedRobots
|
||||||
|
);
|
||||||
|
|
||||||
|
robotsContext.setUnauthorizedRobotsTotalPages(data.TotalPages);
|
||||||
|
} else {
|
||||||
|
robotsContext.setRobots(data.Robots === null ? [] : data.Robots);
|
||||||
|
robotsContext.setRobotsTotalPages(data.TotalPages);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetchRobots(0);
|
||||||
|
|
||||||
|
fetchRobots(1);
|
||||||
|
|
||||||
|
sseEventSource.current = new EventSource(
|
||||||
|
`${Constants.ROBOTICS_API_ADDRESS}/sse`
|
||||||
|
);
|
||||||
|
|
||||||
|
sseEventSource.current.onmessage = (event) => {
|
||||||
|
const data = JSON.parse(event.data);
|
||||||
|
|
||||||
|
const cmd = data.Cmd;
|
||||||
|
const body = data.Body;
|
||||||
|
|
||||||
|
console.log("sse message", data);
|
||||||
|
|
||||||
|
switch (cmd) {
|
||||||
|
case ReceivedSSECommands.UpdateRobotStatus:
|
||||||
|
robotsContext.setRobots((arr) => {
|
||||||
|
const newArr = [...arr];
|
||||||
|
|
||||||
|
console.log("arr", arr);
|
||||||
|
|
||||||
|
const index = arr.findIndex((x) => x.Id === body.RobotId);
|
||||||
|
|
||||||
|
console.log("index", index);
|
||||||
|
|
||||||
|
if (index !== -1) {
|
||||||
|
newArr[index].Status = body.Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
return newArr;
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case ReceivedSSECommands.AddUnauthorizedRobot:
|
||||||
|
robotsContext.setUnauthorizedRobots((arr) => {
|
||||||
|
const newArr = [...arr];
|
||||||
|
|
||||||
|
const index = arr.findIndex((x) => x.Id === body.Id);
|
||||||
|
|
||||||
|
if (index !== -1) {
|
||||||
|
newArr[index] = body;
|
||||||
|
} else {
|
||||||
|
newArr.push(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
return newArr;
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case ReceivedSSECommands.AddRobot:
|
||||||
|
robotsContext.setRobots((arr) => {
|
||||||
|
const newArr = [...arr];
|
||||||
|
|
||||||
|
const index = arr.findIndex((x) => x.Id === body.Id);
|
||||||
|
|
||||||
|
if (index !== -1) {
|
||||||
|
newArr[index] = body;
|
||||||
|
} else {
|
||||||
|
newArr.push(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
return newArr;
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case ReceivedSSECommands.RemoveUnauthorizedRobot:
|
||||||
|
robotsContext.setUnauthorizedRobots((arr) => {
|
||||||
|
const newArr = [...arr];
|
||||||
|
|
||||||
|
const index = arr.findIndex((x) => x.Id === body);
|
||||||
|
|
||||||
|
if (index !== -1) {
|
||||||
|
newArr.splice(index, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return newArr;
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
sseEventSource.current.onerror = (event) => console.log("sse error", event);
|
||||||
|
|
||||||
|
sseEventSource.current.onopen = (event) => console.log("sse open", event);
|
||||||
|
|
||||||
|
sseEventSource.current.onclose = (event) => console.log("sse close", event);
|
||||||
|
|
||||||
|
return () => sseEventSource.current.close();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Typography.Title level={4}>
|
||||||
|
{t("robotics.robots.header")} ({robotsContext.robots.length})
|
||||||
|
</Typography.Title>
|
||||||
|
|
||||||
|
<Table
|
||||||
|
scroll={{ x: "max-content" }}
|
||||||
|
columns={getRobotsTableContent()}
|
||||||
|
dataSource={getRobotsTableItems(robotsContext.robots)}
|
||||||
|
pagination={false}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<MyPagination
|
||||||
|
paginationPage={robotsPaginationPage}
|
||||||
|
setPaginationPage={(page) => setRobotsPaginationPage(page)}
|
||||||
|
totalPages={robotsContext.robotsTotalPages}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Typography.Title level={4}>
|
||||||
|
{t("robotics.unauthorizedRobots.header")} (
|
||||||
|
{robotsContext.unauthorizedRobots.length})
|
||||||
|
</Typography.Title>
|
||||||
|
|
||||||
|
<Table
|
||||||
|
scroll={{ x: "max-content" }}
|
||||||
|
columns={getUnauthorizedTableContent()}
|
||||||
|
dataSource={getUnauthorizedTableItems(robotsContext.unauthorizedRobots)}
|
||||||
|
pagination={false}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<MyPagination
|
||||||
|
paginationPage={unauthorizedRobotsPaginationPage}
|
||||||
|
setPaginationPage={(page) => setUnauthorizedRobotsPaginationPage(page)}
|
||||||
|
totalPages={robotsContext.unauthorizedRobotsTotalPages}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
|
@ -88,7 +88,7 @@ export default function UserProfile() {
|
||||||
return (
|
return (
|
||||||
<Space size="middle">
|
<Space size="middle">
|
||||||
<Link
|
<Link
|
||||||
href="#"
|
to="#"
|
||||||
onClick={() => myFetch(`/user/session/${record.key}`, "DELETE")}
|
onClick={() => myFetch(`/user/session/${record.key}`, "DELETE")}
|
||||||
>
|
>
|
||||||
{t("userProfile.column.action.signOut")}
|
{t("userProfile.column.action.signOut")}
|
||||||
|
|
18
src/utils.js
18
src/utils.js
|
@ -12,6 +12,7 @@ let apiAddress = "";
|
||||||
let staticContentAddress = "";
|
let staticContentAddress = "";
|
||||||
let wsAddress = "";
|
let wsAddress = "";
|
||||||
let logApiAddress = "";
|
let logApiAddress = "";
|
||||||
|
let roboticsApiAddress = "";
|
||||||
|
|
||||||
if (window.location.hostname === "localhost" && window.location.port === "") {
|
if (window.location.hostname === "localhost" && window.location.port === "") {
|
||||||
// for docker container testing on localhost
|
// for docker container testing on localhost
|
||||||
|
@ -19,12 +20,14 @@ if (window.location.hostname === "localhost" && window.location.port === "") {
|
||||||
staticContentAddress = "http://localhost/api/";
|
staticContentAddress = "http://localhost/api/";
|
||||||
wsAddress = "ws://localhost/ws";
|
wsAddress = "ws://localhost/ws";
|
||||||
logApiAddress = "http://localhost/lm/v1/log";
|
logApiAddress = "http://localhost/lm/v1/log";
|
||||||
|
roboticsApiAddress = "http://localhost/rcm/v1";
|
||||||
} else if (window.location.hostname === "localhost") {
|
} else if (window.location.hostname === "localhost") {
|
||||||
// programming on localhost
|
// programming on localhost
|
||||||
apiAddress = "http://localhost:50050/v1";
|
apiAddress = "http://localhost:50050/v1";
|
||||||
staticContentAddress = "http://localhost:50050/";
|
staticContentAddress = "http://localhost:50050/";
|
||||||
wsAddress = "ws://localhost:50050/ws";
|
wsAddress = "ws://localhost:50050/ws";
|
||||||
logApiAddress = "http://127.0.0.1:50110/v1/log";
|
logApiAddress = "http://127.0.0.1:50110/v1/log";
|
||||||
|
roboticsApiAddress = "http://localhost:50055/v1";
|
||||||
/*} else if (window.location.hostname === "192.168.178.93") {
|
/*} else if (window.location.hostname === "192.168.178.93") {
|
||||||
apiAddress = "http://192.168.178.93:50050/v1";
|
apiAddress = "http://192.168.178.93:50050/v1";
|
||||||
staticContentAddress = "http://192.168.178.93:50050/";
|
staticContentAddress = "http://192.168.178.93:50050/";
|
||||||
|
@ -34,7 +37,8 @@ if (window.location.hostname === "localhost" && window.location.port === "") {
|
||||||
apiAddress = `${window.location.protocol}//${window.location.hostname}/api/v1`;
|
apiAddress = `${window.location.protocol}//${window.location.hostname}/api/v1`;
|
||||||
staticContentAddress = `${window.location.protocol}//${window.location.hostname}/api/`;
|
staticContentAddress = `${window.location.protocol}//${window.location.hostname}/api/`;
|
||||||
wsAddress = `${wssProtocol}${window.location.hostname}/ws`;
|
wsAddress = `${wssProtocol}${window.location.hostname}/ws`;
|
||||||
logApiAddress = `${wssProtocol}${window.location.hostname}/lm/v1/log`;
|
logApiAddress = `${window.location.protocol}${window.location.hostname}/lm/v1/log`;
|
||||||
|
roboticsApiAddress = `${window.location.protocol}${window.location.hostname}/rcm/v1`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Constants = {
|
export const Constants = {
|
||||||
|
@ -56,6 +60,7 @@ export const Constants = {
|
||||||
STATIC_CONTENT_ADDRESS: staticContentAddress,
|
STATIC_CONTENT_ADDRESS: staticContentAddress,
|
||||||
WS_ADDRESS: wsAddress,
|
WS_ADDRESS: wsAddress,
|
||||||
LOG_API_ADDRESS: logApiAddress,
|
LOG_API_ADDRESS: logApiAddress,
|
||||||
|
ROBOTICS_API_ADDRESS: roboticsApiAddress, // robot-control-manager
|
||||||
ROUTE_PATHS: {
|
ROUTE_PATHS: {
|
||||||
EQUIPMENT_DOCUMENTATION: "/equipment-documentation",
|
EQUIPMENT_DOCUMENTATION: "/equipment-documentation",
|
||||||
EQUIPMENT_DOCUMENTATION_VIEW: "/equipment-documentation/",
|
EQUIPMENT_DOCUMENTATION_VIEW: "/equipment-documentation/",
|
||||||
|
@ -69,6 +74,7 @@ export const Constants = {
|
||||||
ADMIN_AREA_LOGS: "/admin-area/logs",
|
ADMIN_AREA_LOGS: "/admin-area/logs",
|
||||||
ADMIN_AREA_MANAGE: "/admin-area/manage",
|
ADMIN_AREA_MANAGE: "/admin-area/manage",
|
||||||
CONSOLES: "/consoles",
|
CONSOLES: "/consoles",
|
||||||
|
ROBOTICS_ROBOTS: "/robotics/robots",
|
||||||
},
|
},
|
||||||
GROUP_TASKS_STATUS: {
|
GROUP_TASKS_STATUS: {
|
||||||
FINISHED: 1,
|
FINISHED: 1,
|
||||||
|
@ -161,6 +167,9 @@ export const Constants = {
|
||||||
CONSOLES: {
|
CONSOLES: {
|
||||||
VIEW: "consoles.view",
|
VIEW: "consoles.view",
|
||||||
},
|
},
|
||||||
|
ROBOTICS: {
|
||||||
|
ROBOTS: "robotics.view",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
SYSTEM_LOG_TYPE: {
|
SYSTEM_LOG_TYPE: {
|
||||||
INFO: 0,
|
INFO: 0,
|
||||||
|
@ -1384,7 +1393,12 @@ export function myFetch(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return response.json();
|
// check if response is json
|
||||||
|
if (response.headers.get("content-type")?.includes("application/json")) {
|
||||||
|
return response.json();
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.text();
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error("myFetch error:", error);
|
console.error("myFetch error:", error);
|
||||||
|
|
Loading…
Reference in New Issue