robots table
parent
4acbe50f8b
commit
28c823bc41
|
@ -0,0 +1,7 @@
|
||||||
|
git add *
|
||||||
|
|
||||||
|
read -p "Commit message: " commit_message
|
||||||
|
|
||||||
|
git commit -m "$commit_message"
|
||||||
|
|
||||||
|
git push -u origin main
|
|
@ -178,13 +178,31 @@
|
||||||
"firmwareVersion": "Firmware Version",
|
"firmwareVersion": "Firmware Version",
|
||||||
"createdAt": "Erstellt am",
|
"createdAt": "Erstellt am",
|
||||||
"actions": "Maßnahmen"
|
"actions": "Maßnahmen"
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
"idle": "Inaktiv",
|
||||||
|
"processing": "Verarbeitung",
|
||||||
|
"connecting": "Verbinden",
|
||||||
|
"error": "Fehler",
|
||||||
|
"offline": "Offline"
|
||||||
|
},
|
||||||
|
"popconfirmEdit": {
|
||||||
|
"title": "Sind Sie sicher, dass Sie diesen Roboter bearbeiten wollen?",
|
||||||
|
"errorNotification": {
|
||||||
|
"message": "Roboter konnte nicht bearbeitet werden",
|
||||||
|
"description": "Name bereits vergeben"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"popconfirmDisconnect": {
|
||||||
|
"title": "Sind Sie sicher, dass Sie diesen Roboter trennen wollen?",
|
||||||
|
"description": "Der Roboter wird getrennt und kann nicht mehr für Aufträge verwendet werden"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"unauthorizedRobots": {
|
"unauthorizedRobots": {
|
||||||
"header": "Nicht autorisierte Roboter",
|
"header": "Nicht autorisierte Roboter",
|
||||||
"popconfirmDeny": {
|
"popconfirmDeny": {
|
||||||
"title": "Sind Sie sicher, dass Sie diesen Roboter ablehnen wollen?",
|
"title": "Sind Sie sicher, dass Sie diesen Roboter ablehnen wollen?",
|
||||||
"description": "Der Roboter wird getrennt und muss sich ernuet verbinden"
|
"description": "Der Roboter wird getrennt und muss sich erneut verbinden"
|
||||||
},
|
},
|
||||||
"popconfirmAuthorize": {
|
"popconfirmAuthorize": {
|
||||||
"title": "Sind Sie sicher, dass Sie diesen Roboter autorisieren wollen?",
|
"title": "Sind Sie sicher, dass Sie diesen Roboter autorisieren wollen?",
|
||||||
|
|
|
@ -178,6 +178,24 @@
|
||||||
"firmwareVersion": "Firmware version",
|
"firmwareVersion": "Firmware version",
|
||||||
"createdAt": "Created At",
|
"createdAt": "Created At",
|
||||||
"actions": "Actions"
|
"actions": "Actions"
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
"idle": "Idle",
|
||||||
|
"processing": "Processing",
|
||||||
|
"connecting": "Connecting",
|
||||||
|
"error": "Error",
|
||||||
|
"offline": "Offline"
|
||||||
|
},
|
||||||
|
"popconfirmEdit": {
|
||||||
|
"title": "Are you sure you want to edit this robot?",
|
||||||
|
"errorNotification": {
|
||||||
|
"message": "Robot could not be edited",
|
||||||
|
"description": "Name already taken"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"popconfirmDisconnect": {
|
||||||
|
"title": "Are you sure you want to disconnect this robot?",
|
||||||
|
"description": "The robot will be disconnected and cannot be longer used for jobs"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"unauthorizedRobots": {
|
"unauthorizedRobots": {
|
||||||
|
|
|
@ -1,4 +1,12 @@
|
||||||
import { Badge, Popconfirm, Space, Table, Typography } from "antd";
|
import {
|
||||||
|
Badge,
|
||||||
|
Input,
|
||||||
|
Popconfirm,
|
||||||
|
Space,
|
||||||
|
Table,
|
||||||
|
Typography,
|
||||||
|
notification,
|
||||||
|
} from "antd";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { useRoboticsRobotContext } from "../../../Contexts/RoboticsRobot";
|
import { useRoboticsRobotContext } from "../../../Contexts/RoboticsRobot";
|
||||||
import { useEffect, useRef, useState } from "react";
|
import { useEffect, useRef, useState } from "react";
|
||||||
|
@ -16,6 +24,8 @@ const ReceivedSSECommands = {
|
||||||
AddUnauthorizedRobot: 2,
|
AddUnauthorizedRobot: 2,
|
||||||
AddRobot: 3,
|
AddRobot: 3,
|
||||||
RemoveUnauthorizedRobot: 4,
|
RemoveUnauthorizedRobot: 4,
|
||||||
|
RemoveRobot: 5,
|
||||||
|
RobotUpdated: 6,
|
||||||
};
|
};
|
||||||
|
|
||||||
function getRobotTypeString(type) {
|
function getRobotTypeString(type) {
|
||||||
|
@ -32,27 +42,46 @@ function getRobotTypeString(type) {
|
||||||
export default function Robots() {
|
export default function Robots() {
|
||||||
const robotsContext = useRoboticsRobotContext();
|
const robotsContext = useRoboticsRobotContext();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
const [notificationApi, notificationContextHolder] =
|
||||||
|
notification.useNotification();
|
||||||
|
|
||||||
const [robotsPaginationPage, setRobotsPaginationPage] = useState(1);
|
const [robotsPaginationPage, setRobotsPaginationPage] = useState(1);
|
||||||
const [
|
const [
|
||||||
unauthorizedRobotsPaginationPage,
|
unauthorizedRobotsPaginationPage,
|
||||||
setUnauthorizedRobotsPaginationPage,
|
setUnauthorizedRobotsPaginationPage,
|
||||||
] = useState(1);
|
] = useState(1);
|
||||||
|
const [selectedRobotName, setSelectedRobotName] = useState("");
|
||||||
|
|
||||||
const sseEventSource = useRef(null);
|
const sseEventSource = useRef(null);
|
||||||
|
|
||||||
const getRobotStatusBadge = (status) => {
|
const getRobotStatusBadge = (status) => {
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case 1:
|
case 1:
|
||||||
return <Badge status="success" text={"Idle"} />;
|
return (
|
||||||
|
<Badge status="success" text={t("robotics.robots.status.idle")} />
|
||||||
|
);
|
||||||
case 2:
|
case 2:
|
||||||
return <Badge status="processing" text={"Running"} />;
|
return (
|
||||||
|
<Badge
|
||||||
|
status="processing"
|
||||||
|
text={t("robotics.robots.status.processing")}
|
||||||
|
/>
|
||||||
|
);
|
||||||
case 3:
|
case 3:
|
||||||
return <Badge status="warning" text={"Connecting"} />;
|
return (
|
||||||
|
<Badge
|
||||||
|
status="warning"
|
||||||
|
text={t("robotics.robots.status.connecting")}
|
||||||
|
/>
|
||||||
|
);
|
||||||
case 4:
|
case 4:
|
||||||
return <Badge status="warning" text={"Error"} />;
|
return (
|
||||||
|
<Badge status="warning" text={t("robotics.robots.status.error")} />
|
||||||
|
);
|
||||||
case 5:
|
case 5:
|
||||||
return <Badge status="default" text={"Offline"} />;
|
return (
|
||||||
|
<Badge status="default" text={t("robotics.robots.status.offline")} />
|
||||||
|
);
|
||||||
default:
|
default:
|
||||||
return "Unknown";
|
return "Unknown";
|
||||||
}
|
}
|
||||||
|
@ -116,8 +145,78 @@ export default function Robots() {
|
||||||
key: "actions",
|
key: "actions",
|
||||||
render: (_, record) => (
|
render: (_, record) => (
|
||||||
<Space size="middle">
|
<Space size="middle">
|
||||||
<Link to="#">{t("common.text.edit")}</Link>
|
<Popconfirm
|
||||||
|
placement="left"
|
||||||
|
title={t("robotics.robots.popconfirmEdit.title")}
|
||||||
|
description={
|
||||||
|
<Input
|
||||||
|
placeholder="Name"
|
||||||
|
value={selectedRobotName}
|
||||||
|
onChange={(e) => setSelectedRobotName(e.target.value)}
|
||||||
|
minLength={Constants.GLOBALS.MIN_ROBOTICS_ROBOT_NAME_LENGTH}
|
||||||
|
maxLength={Constants.GLOBALS.MAX_ROBOTICS_ROBOT_NAME_LENGTH}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
okButtonProps={{
|
||||||
|
disabled:
|
||||||
|
selectedRobotName.length <
|
||||||
|
Constants.GLOBALS.MIN_ROBOTICS_ROBOT_NAME_LENGTH ||
|
||||||
|
selectedRobotName.length >
|
||||||
|
Constants.GLOBALS.MAX_ROBOTICS_ROBOT_NAME_LENGTH,
|
||||||
|
}}
|
||||||
|
okText={t("common.button.confirm")}
|
||||||
|
cancelText={t("common.button.cancel")}
|
||||||
|
onConfirm={() =>
|
||||||
|
myFetch(
|
||||||
|
`/robot`,
|
||||||
|
"PATCH",
|
||||||
|
{
|
||||||
|
robotId: record.id,
|
||||||
|
name: selectedRobotName,
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
myFetchContentType.JSON,
|
||||||
|
Constants.ROBOTICS_API_ADDRESS
|
||||||
|
).catch((err) => {
|
||||||
|
if (err === 422) {
|
||||||
|
notificationApi["error"]({
|
||||||
|
message: t(
|
||||||
|
"robotics.robots.popconfirmEdit.errorNotification.message"
|
||||||
|
),
|
||||||
|
description: t(
|
||||||
|
"robotics.robots.popconfirmEdit.errorNotification.description"
|
||||||
|
),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Link to="#" onClick={() => setSelectedRobotName(record.name)}>
|
||||||
|
{t("common.text.edit")}
|
||||||
|
</Link>
|
||||||
|
</Popconfirm>
|
||||||
|
|
||||||
|
<Popconfirm
|
||||||
|
placement="left"
|
||||||
|
title={t("robotics.robots.popconfirmDisconnect.title")}
|
||||||
|
description={t(
|
||||||
|
"robotics.robots.popconfirmDisconnect.description"
|
||||||
|
)}
|
||||||
|
okText={t("common.button.confirm")}
|
||||||
|
cancelText={t("common.button.cancel")}
|
||||||
|
onConfirm={() =>
|
||||||
|
myFetch(
|
||||||
|
`/robot/${record.id}`,
|
||||||
|
"DELETE",
|
||||||
|
null,
|
||||||
|
{},
|
||||||
|
myFetchContentType.JSON,
|
||||||
|
Constants.ROBOTICS_API_ADDRESS
|
||||||
|
)
|
||||||
|
}
|
||||||
|
>
|
||||||
<Link to="#">{t("common.text.disconnect")}</Link>
|
<Link to="#">{t("common.text.disconnect")}</Link>
|
||||||
|
</Popconfirm>
|
||||||
</Space>
|
</Space>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
@ -129,21 +228,27 @@ export default function Robots() {
|
||||||
const getRobotsTableItems = (robots) => {
|
const getRobotsTableItems = (robots) => {
|
||||||
let items = [];
|
let items = [];
|
||||||
|
|
||||||
robots.forEach((robot) => {
|
robots.sort((a, b) => a.Status - b.Status);
|
||||||
|
|
||||||
|
robots.forEach((robot) =>
|
||||||
items.push({
|
items.push({
|
||||||
key: robot.Id,
|
key: robot.Id,
|
||||||
id: robot.Id,
|
id: robot.Id,
|
||||||
type: getRobotTypeString(robot.Type),
|
type: getRobotTypeString(robot.Type),
|
||||||
name: robot.Name,
|
name: robot.Name,
|
||||||
status: getRobotStatusBadge(robot.Status),
|
status: getRobotStatusBadge(robot.Status),
|
||||||
currentJob: robot.CurrentJob,
|
currentJob:
|
||||||
|
robot.CurrentJobId === ""
|
||||||
|
? Constants.TEXT_EMPTY_PLACEHOLDER
|
||||||
|
: robot.CurrentJobId,
|
||||||
jobsWaiting: robot.JobsWaitingCount,
|
jobsWaiting: robot.JobsWaitingCount,
|
||||||
address: robot.Address,
|
address: robot.Address,
|
||||||
firmwareVersion: robot.FirmwareVersion,
|
firmwareVersion: robot.FirmwareVersion,
|
||||||
connectedAt: FormatDatetime(robot.ConnectedAt),
|
connectedAt: FormatDatetime(robot.ConnectedAt),
|
||||||
|
createdAt: FormatDatetime(robot.CreatedAt),
|
||||||
actions: robot.Actions,
|
actions: robot.Actions,
|
||||||
});
|
})
|
||||||
});
|
);
|
||||||
|
|
||||||
return items;
|
return items;
|
||||||
};
|
};
|
||||||
|
@ -170,6 +275,11 @@ export default function Robots() {
|
||||||
dataIndex: "connectedAt",
|
dataIndex: "connectedAt",
|
||||||
key: "connectedAt",
|
key: "connectedAt",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: t("robotics.robots.column.firmwareVersion"),
|
||||||
|
dataIndex: "firmwareVersion",
|
||||||
|
key: "firmwareVersion",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: t("robotics.robots.column.actions"),
|
title: t("robotics.robots.column.actions"),
|
||||||
dataIndex: "actions",
|
dataIndex: "actions",
|
||||||
|
@ -192,9 +302,7 @@ export default function Robots() {
|
||||||
{},
|
{},
|
||||||
myFetchContentType.JSON,
|
myFetchContentType.JSON,
|
||||||
Constants.ROBOTICS_API_ADDRESS
|
Constants.ROBOTICS_API_ADDRESS
|
||||||
).then((data) => {
|
)
|
||||||
console.log("data", data);
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Link to="#">{t("common.text.deny")}</Link>
|
<Link to="#">{t("common.text.deny")}</Link>
|
||||||
|
@ -216,9 +324,7 @@ export default function Robots() {
|
||||||
{},
|
{},
|
||||||
myFetchContentType.JSON,
|
myFetchContentType.JSON,
|
||||||
Constants.ROBOTICS_API_ADDRESS
|
Constants.ROBOTICS_API_ADDRESS
|
||||||
).then((data) => {
|
)
|
||||||
console.log("data", data);
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Link to="#">{t("common.text.authorize")}</Link>
|
<Link to="#">{t("common.text.authorize")}</Link>
|
||||||
|
@ -241,6 +347,7 @@ export default function Robots() {
|
||||||
type: getRobotTypeString(robot.Type),
|
type: getRobotTypeString(robot.Type),
|
||||||
address: robot.Address,
|
address: robot.Address,
|
||||||
connectedAt: FormatDatetime(robot.ConnectedAt),
|
connectedAt: FormatDatetime(robot.ConnectedAt),
|
||||||
|
firmwareVersion: robot.FirmwareVersion,
|
||||||
actions: robot.Actions,
|
actions: robot.Actions,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -293,12 +400,8 @@ export default function Robots() {
|
||||||
robotsContext.setRobots((arr) => {
|
robotsContext.setRobots((arr) => {
|
||||||
const newArr = [...arr];
|
const newArr = [...arr];
|
||||||
|
|
||||||
console.log("arr", arr);
|
|
||||||
|
|
||||||
const index = arr.findIndex((x) => x.Id === body.RobotId);
|
const index = arr.findIndex((x) => x.Id === body.RobotId);
|
||||||
|
|
||||||
console.log("index", index);
|
|
||||||
|
|
||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
newArr[index].Status = body.Status;
|
newArr[index].Status = body.Status;
|
||||||
}
|
}
|
||||||
|
@ -335,6 +438,19 @@ export default function Robots() {
|
||||||
|
|
||||||
return newArr;
|
return newArr;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// remove from unauthorized robots
|
||||||
|
robotsContext.setUnauthorizedRobots((arr) => {
|
||||||
|
const newArr = [...arr];
|
||||||
|
|
||||||
|
const index = arr.findIndex((x) => x.Id === body.Id);
|
||||||
|
|
||||||
|
if (index !== -1) {
|
||||||
|
newArr.splice(index, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return newArr;
|
||||||
|
});
|
||||||
break;
|
break;
|
||||||
case ReceivedSSECommands.RemoveUnauthorizedRobot:
|
case ReceivedSSECommands.RemoveUnauthorizedRobot:
|
||||||
robotsContext.setUnauthorizedRobots((arr) => {
|
robotsContext.setUnauthorizedRobots((arr) => {
|
||||||
|
@ -349,6 +465,32 @@ export default function Robots() {
|
||||||
return newArr;
|
return newArr;
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
case ReceivedSSECommands.RemoveRobot:
|
||||||
|
robotsContext.setRobots((arr) => {
|
||||||
|
const newArr = [...arr];
|
||||||
|
|
||||||
|
const index = arr.findIndex((x) => x.Id === body);
|
||||||
|
|
||||||
|
if (index !== -1) {
|
||||||
|
newArr.splice(index, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return newArr;
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case ReceivedSSECommands.RobotUpdated:
|
||||||
|
robotsContext.setRobots((arr) => {
|
||||||
|
const newArr = [...arr];
|
||||||
|
|
||||||
|
const index = arr.findIndex((x) => x.Id === body.RobotId);
|
||||||
|
|
||||||
|
if (index !== -1) {
|
||||||
|
newArr[index].Name = body.Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
return newArr;
|
||||||
|
});
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -365,6 +507,8 @@ export default function Robots() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
{notificationContextHolder}
|
||||||
|
|
||||||
<Typography.Title level={4}>
|
<Typography.Title level={4}>
|
||||||
{t("robotics.robots.header")} ({robotsContext.robots.length})
|
{t("robotics.robots.header")} ({robotsContext.robots.length})
|
||||||
</Typography.Title>
|
</Typography.Title>
|
||||||
|
|
|
@ -102,6 +102,8 @@ export const Constants = {
|
||||||
MAX_LOG_MANAGER_DISPLAY_NAME_LENGTH: 16,
|
MAX_LOG_MANAGER_DISPLAY_NAME_LENGTH: 16,
|
||||||
MIN_LOG_MANAGER_ADDRESS_LENGTH: 3,
|
MIN_LOG_MANAGER_ADDRESS_LENGTH: 3,
|
||||||
MAX_LOG_MANAGER_ADDRESS_LENGTH: 100,
|
MAX_LOG_MANAGER_ADDRESS_LENGTH: 100,
|
||||||
|
MIN_ROBOTICS_ROBOT_NAME_LENGTH: 2,
|
||||||
|
MAX_ROBOTICS_ROBOT_NAME_LENGTH: 30,
|
||||||
},
|
},
|
||||||
MAX_AVATAR_SIZE: 5 * 1024 * 1024,
|
MAX_AVATAR_SIZE: 5 * 1024 * 1024,
|
||||||
ACCEPTED_AVATAR_FILE_TYPES: [
|
ACCEPTED_AVATAR_FILE_TYPES: [
|
||||||
|
@ -1390,7 +1392,7 @@ export function myFetch(
|
||||||
window.location.href = "/";
|
window.location.href = "/";
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
throw response.status;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if response is json
|
// check if response is json
|
||||||
|
|
Loading…
Reference in New Issue