797 lines
22 KiB
JavaScript
797 lines
22 KiB
JavaScript
import {
|
|
Badge,
|
|
Button,
|
|
Input,
|
|
Popconfirm,
|
|
Popover,
|
|
Space,
|
|
Table,
|
|
Tooltip,
|
|
Typography,
|
|
notification,
|
|
} from "antd";
|
|
import { useTranslation } from "react-i18next";
|
|
import { useEffect, useRef, useState } from "react";
|
|
import {
|
|
Constants,
|
|
FormatDatetime,
|
|
hasOnePermission,
|
|
hasPermission,
|
|
myFetch,
|
|
myFetchContentType,
|
|
} from "../../../utils";
|
|
import MyPagination from "../../../Components/MyPagination";
|
|
import { Link } from "react-router-dom";
|
|
import {
|
|
FileTextOutlined,
|
|
LoadingOutlined,
|
|
PlusOutlined,
|
|
} from "@ant-design/icons";
|
|
import { MyCopyIcon, MyShowHiddenIcon } from "../../../Components/MyIcon";
|
|
import { useAppContext } from "../../../Contexts/AppContext";
|
|
|
|
const ReceivedSSECommands = {
|
|
UpdateRobotStatus: 1,
|
|
AddUnauthorizedRobot: 2,
|
|
AddRobot: 3,
|
|
RemoveUnauthorizedRobot: 4,
|
|
RemoveRobot: 5,
|
|
RobotUpdated: 6,
|
|
UpdateRobotCurrentJob: 7,
|
|
UpdateRobotJobsWaitingCount: 8,
|
|
PermitJoinUpdated: 9,
|
|
};
|
|
|
|
function getRobotTypeString(type) {
|
|
switch (type) {
|
|
case 1:
|
|
return "Rex";
|
|
case 2:
|
|
return "Yeet";
|
|
default:
|
|
return "Unknown";
|
|
}
|
|
}
|
|
|
|
export default function Robots() {
|
|
const { t } = useTranslation();
|
|
const appContext = useAppContext();
|
|
const [notificationApi, notificationContextHolder] =
|
|
notification.useNotification();
|
|
|
|
const [robots, setRobots] = useState([]);
|
|
const [robotsTotalPages, setRobotsTotalPages] = useState(0);
|
|
const [robotsPaginationPage, setRobotsPaginationPage] = useState(1);
|
|
const robotsPaginationPageRef = useRef(1);
|
|
|
|
const [unauthorizedRobots, setUnauthorizedRobots] = useState([]);
|
|
const [unauthorizedRobotsTotalPages, setUnauthorizedRobotsTotalPages] =
|
|
useState(0);
|
|
const [
|
|
unauthorizedRobotsPaginationPage,
|
|
setUnauthorizedRobotsPaginationPage,
|
|
] = useState(1);
|
|
const unauthorizedRobotsPaginationPageRef = useRef(1);
|
|
|
|
const [selectedRobotName, setSelectedRobotName] = useState("");
|
|
const [permitJoinEnabled, setPermitJoinEnabled] = useState(false);
|
|
const [showAddress, setShowAddress] = useState(false);
|
|
|
|
const sseEventSource = useRef(null);
|
|
|
|
const getRobotStatusBadge = (status) => {
|
|
switch (status) {
|
|
case 1:
|
|
return (
|
|
<Badge status="success" text={t("robotics.robots.status.idle")} />
|
|
);
|
|
case 2:
|
|
return (
|
|
<Badge
|
|
status="processing"
|
|
text={t("robotics.robots.status.processing")}
|
|
/>
|
|
);
|
|
case 3:
|
|
return (
|
|
<Badge
|
|
status="warning"
|
|
text={t("robotics.robots.status.connecting")}
|
|
/>
|
|
);
|
|
case 4:
|
|
return (
|
|
<Badge status="warning" text={t("robotics.robots.status.error")} />
|
|
);
|
|
case 5:
|
|
return (
|
|
<Badge status="default" text={t("robotics.robots.status.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: "currentJobName",
|
|
key: "currentJobName",
|
|
},
|
|
{
|
|
title: t("robotics.robots.column.jobsWaiting"),
|
|
dataIndex: "jobsWaitingCount",
|
|
key: "jobsWaitingCount",
|
|
render: (parameter, record) => (
|
|
<>
|
|
{parameter > 0 ? (
|
|
<Popover
|
|
title="Jobs waiting"
|
|
content={
|
|
record._jobsWaitingNameList !== null && (
|
|
<ul style={{ paddingLeft: 14 }}>
|
|
{record._jobsWaitingNameList.map((jobName, index) => (
|
|
<li key={index}>{jobName}</li>
|
|
))}
|
|
</ul>
|
|
)
|
|
}
|
|
>
|
|
{parameter}
|
|
</Popover>
|
|
) : (
|
|
parameter
|
|
)}
|
|
</>
|
|
),
|
|
},
|
|
];
|
|
|
|
if (
|
|
hasPermission(
|
|
appContext.userPermissions,
|
|
Constants.PERMISSIONS.ROBOTICS.ROBOTS.VIEW_ROBOTS_ADDRESSES
|
|
)
|
|
) {
|
|
items.push({
|
|
title: t("robotics.robots.column.address"),
|
|
dataIndex: "address",
|
|
key: "address",
|
|
render: (text) => (
|
|
<Space>
|
|
{showAddress ? text : "XXXXXX"}
|
|
|
|
<MyShowHiddenIcon
|
|
isHidden={showAddress}
|
|
setIsHidden={setShowAddress}
|
|
/>
|
|
|
|
<MyCopyIcon notificationApi={notificationApi} text={text} />
|
|
</Space>
|
|
),
|
|
});
|
|
}
|
|
|
|
items.push(
|
|
{
|
|
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",
|
|
}
|
|
);
|
|
|
|
if (
|
|
hasOnePermission(
|
|
appContext.userPermissions,
|
|
Constants.PERMISSIONS.ROBOTICS.ROBOTS.EDIT_ROBOT_NAME,
|
|
Constants.PERMISSIONS.ROBOTICS.ROBOTS.DISCONNECT_ROBOT
|
|
)
|
|
) {
|
|
items.push({
|
|
title: t("robotics.robots.column.actions"),
|
|
dataIndex: "actions",
|
|
key: "actions",
|
|
render: (_, record) => (
|
|
<Space size="middle">
|
|
{hasPermission(
|
|
appContext.userPermissions,
|
|
Constants.PERMISSIONS.ROBOTICS.ROBOTS.EDIT_ROBOT_NAME
|
|
) && (
|
|
<Popconfirm
|
|
placement="left"
|
|
title={t("robotics.robots.popconfirmEdit.title")}
|
|
description={
|
|
<Input
|
|
placeholder="Name"
|
|
value={selectedRobotName}
|
|
onChange={(e) => setSelectedRobotName(e.target.value)}
|
|
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,
|
|
robotName: 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>
|
|
)}
|
|
|
|
{hasPermission(
|
|
appContext.userPermissions,
|
|
Constants.PERMISSIONS.ROBOTICS.ROBOTS.DISCONNECT_ROBOT
|
|
) && (
|
|
<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>
|
|
</Popconfirm>
|
|
)}
|
|
</Space>
|
|
),
|
|
});
|
|
}
|
|
|
|
return items;
|
|
};
|
|
|
|
const getRobotsTableItems = (robots) => {
|
|
let items = [];
|
|
|
|
robots.sort((a, b) => a.Status - b.Status);
|
|
|
|
robots.forEach((robot) =>
|
|
items.push({
|
|
key: robot.Id,
|
|
id: robot.Id,
|
|
type: getRobotTypeString(robot.Type),
|
|
name: robot.Name,
|
|
status: getRobotStatusBadge(robot.Status),
|
|
currentJobName:
|
|
robot.CurrentJobName === ""
|
|
? Constants.TEXT_EMPTY_PLACEHOLDER
|
|
: robot.CurrentJobName,
|
|
jobsWaitingCount: robot.JobsWaitingCount,
|
|
_jobsWaitingNameList: robot.JobsWaitingNameList,
|
|
address: robot.Address,
|
|
firmwareVersion: robot.FirmwareVersion,
|
|
connectedAt: FormatDatetime(robot.ConnectedAt),
|
|
createdAt: FormatDatetime(robot.CreatedAt),
|
|
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.firmwareVersion"),
|
|
dataIndex: "firmwareVersion",
|
|
key: "firmwareVersion",
|
|
},
|
|
];
|
|
|
|
if (
|
|
hasPermission(
|
|
appContext.userPermissions,
|
|
Constants.PERMISSIONS.ROBOTICS.ROBOTS.AUTHORIZE_DENY_UNAUTHORIZED_ROBOTS
|
|
)
|
|
) {
|
|
items.push({
|
|
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
|
|
)
|
|
}
|
|
>
|
|
<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
|
|
)
|
|
}
|
|
>
|
|
<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),
|
|
firmwareVersion: robot.FirmwareVersion,
|
|
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) {
|
|
setUnauthorizedRobots(
|
|
data.UnauthorizedRobots === null ? [] : data.UnauthorizedRobots
|
|
);
|
|
|
|
setUnauthorizedRobotsTotalPages(data.TotalPages);
|
|
} else {
|
|
setRobots(data.Robots === null ? [] : data.Robots);
|
|
setRobotsTotalPages(data.TotalPages);
|
|
}
|
|
});
|
|
};
|
|
|
|
useEffect(() => fetchRobots(0, robotsPaginationPage), [robotsPaginationPage]);
|
|
|
|
useEffect(
|
|
() => fetchRobots(1, unauthorizedRobotsPaginationPage),
|
|
[unauthorizedRobotsPaginationPage]
|
|
);
|
|
|
|
useEffect(() => {
|
|
myFetch(
|
|
"/permitjoin",
|
|
"GET",
|
|
null,
|
|
{},
|
|
myFetchContentType.JSON,
|
|
Constants.ROBOTICS_API_ADDRESS
|
|
).then((data) => setPermitJoinEnabled(data.Enabled));
|
|
|
|
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:
|
|
setRobots((arr) => {
|
|
const newArr = [...arr];
|
|
|
|
const index = arr.findIndex((x) => x.Id === body.RobotId);
|
|
|
|
if (index !== -1) {
|
|
newArr[index].Status = body.Status;
|
|
}
|
|
|
|
return newArr;
|
|
});
|
|
break;
|
|
case ReceivedSSECommands.AddUnauthorizedRobot:
|
|
console.log("a", unauthorizedRobotsPaginationPageRef.current);
|
|
|
|
if (unauthorizedRobotsPaginationPageRef.current === 1) {
|
|
setUnauthorizedRobots((arr) => {
|
|
const newArr = [...arr];
|
|
|
|
const index = arr.findIndex(
|
|
(x) => x.Id === body.UnauthorizedRobot.Id
|
|
);
|
|
|
|
if (index !== -1) {
|
|
newArr[index] = body.UnauthorizedRobot;
|
|
} else {
|
|
if (
|
|
newArr.length ===
|
|
Constants.GLOBALS.ROBOTICS_UNAUTHORIZED_PAGINATION_LIMIT
|
|
) {
|
|
newArr.pop();
|
|
}
|
|
|
|
newArr.unshift(body.UnauthorizedRobot);
|
|
}
|
|
|
|
return newArr;
|
|
});
|
|
}
|
|
|
|
setUnauthorizedRobotsTotalPages(body.TotalPages);
|
|
break;
|
|
case ReceivedSSECommands.AddRobot:
|
|
if (robotsPaginationPageRef.current === 1) {
|
|
setRobots((arr) => {
|
|
const newArr = [...arr];
|
|
|
|
const index = arr.findIndex((x) => x.Id === body.Robot.Id);
|
|
|
|
if (index !== -1) {
|
|
newArr[index] = body.Robot;
|
|
} else {
|
|
if (
|
|
newArr.length ===
|
|
Constants.GLOBALS.ROBOTICS_ROBOTS_PAGINATION_LIMIT
|
|
) {
|
|
newArr.pop();
|
|
}
|
|
|
|
newArr.unshift(body.Robot);
|
|
}
|
|
|
|
return newArr;
|
|
});
|
|
}
|
|
|
|
setRobotsTotalPages(body.TotalPages);
|
|
|
|
// remove from unauthorized robots
|
|
setUnauthorizedRobots((arr) => {
|
|
const newArr = [...arr];
|
|
|
|
const index = arr.findIndex((x) => x.Id === body.Robot.Id);
|
|
|
|
if (index !== -1) {
|
|
newArr.splice(index, 1);
|
|
}
|
|
|
|
return newArr;
|
|
});
|
|
|
|
setUnauthorizedRobotsTotalPages(body.UnauthorizedRobotsTotalPages);
|
|
|
|
// if user is on the last page and the last item is removed, we need to go back one page
|
|
if (
|
|
body.UnauthorizedRobotsTotalPages > 0 &&
|
|
unauthorizedRobotsPaginationPageRef.current >
|
|
body.UnauthorizedRobotsTotalPages
|
|
) {
|
|
unauthorizedRobotsPaginationPageRef.current--;
|
|
setUnauthorizedRobotsPaginationPage(
|
|
unauthorizedRobotsPaginationPageRef.current
|
|
);
|
|
}
|
|
break;
|
|
case ReceivedSSECommands.RemoveUnauthorizedRobot:
|
|
setUnauthorizedRobots((arr) => {
|
|
const newArr = [...arr];
|
|
|
|
const index = arr.findIndex(
|
|
(x) => x.Id === body.UnauthorizedRobotId
|
|
);
|
|
|
|
if (index !== -1) {
|
|
newArr.splice(index, 1);
|
|
}
|
|
|
|
return newArr;
|
|
});
|
|
|
|
setUnauthorizedRobotsTotalPages(body.TotalPages);
|
|
|
|
// if user is on the last page and the last item is removed, we need to go back one page
|
|
if (
|
|
body.TotalPages > 0 &&
|
|
unauthorizedRobotsPaginationPageRef.current > body.TotalPages
|
|
) {
|
|
unauthorizedRobotsPaginationPageRef.current--;
|
|
setUnauthorizedRobotsPaginationPage(
|
|
unauthorizedRobotsPaginationPageRef.current
|
|
);
|
|
}
|
|
break;
|
|
case ReceivedSSECommands.RemoveRobot:
|
|
setRobots((arr) => {
|
|
const newArr = [...arr];
|
|
|
|
const index = arr.findIndex((x) => x.Id === body.RobotId);
|
|
|
|
if (index !== -1) {
|
|
newArr.splice(index, 1);
|
|
}
|
|
|
|
return newArr;
|
|
});
|
|
|
|
setRobotsTotalPages(body.TotalPages);
|
|
|
|
// if user is on the last page and the last item is removed, we need to go back one page
|
|
if (
|
|
body.TotalPages > 0 &&
|
|
robotsPaginationPageRef.current > body.TotalPages
|
|
) {
|
|
robotsPaginationPageRef.current--;
|
|
setRobotsPaginationPage(robotsPaginationPageRef.current);
|
|
}
|
|
break;
|
|
case ReceivedSSECommands.RobotUpdated:
|
|
setRobots((arr) => {
|
|
const newArr = [...arr];
|
|
|
|
const index = arr.findIndex((x) => x.Id === body.RobotId);
|
|
|
|
if (index !== -1) {
|
|
newArr[index].Name = body.RobotName;
|
|
}
|
|
|
|
return newArr;
|
|
});
|
|
break;
|
|
case ReceivedSSECommands.UpdateRobotCurrentJob:
|
|
setRobots((arr) => {
|
|
const newArr = [...arr];
|
|
|
|
const index = arr.findIndex((x) => x.Id === body.RobotId);
|
|
|
|
if (index !== -1) {
|
|
newArr[index].CurrentJobName = body.JobName;
|
|
newArr[index].JobsWaitingNameList = body.JobsWaitingNameList;
|
|
}
|
|
|
|
return newArr;
|
|
});
|
|
break;
|
|
case ReceivedSSECommands.UpdateRobotJobsWaitingCount:
|
|
setRobots((arr) => {
|
|
const newArr = [...arr];
|
|
|
|
const index = arr.findIndex((x) => x.Id === body.RobotId);
|
|
|
|
if (index !== -1) {
|
|
newArr[index].JobsWaitingCount = body.JobsWaitingCount;
|
|
newArr[index].JobsWaitingNameList = body.JobsWaitingNameList;
|
|
}
|
|
|
|
return newArr;
|
|
});
|
|
break;
|
|
case ReceivedSSECommands.PermitJoinUpdated:
|
|
setPermitJoinEnabled(body);
|
|
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 (
|
|
<>
|
|
{notificationContextHolder}
|
|
|
|
<div
|
|
style={{
|
|
display: "flex",
|
|
justifyContent: "space-between",
|
|
}}
|
|
>
|
|
<Typography.Title level={4}>
|
|
{t("robotics.robots.header")}{" "}
|
|
<Tooltip title={t("robotics.robots.viewApiDoc")}>
|
|
<Link target="_blank" to={Constants.ROBOTICS_SWAGGER_ADDRESS}>
|
|
<FileTextOutlined style={{ fontSize: 16 }} />
|
|
</Link>
|
|
</Tooltip>
|
|
</Typography.Title>
|
|
|
|
<Button
|
|
disabled={
|
|
!hasPermission(
|
|
appContext.userPermissions,
|
|
Constants.PERMISSIONS.ROBOTICS.ROBOTS.ENABLE_PERMIT_JOIN
|
|
)
|
|
}
|
|
onClick={() => {
|
|
console.log("click");
|
|
myFetch(
|
|
`/permitjoin/${permitJoinEnabled ? 0 : 1}`,
|
|
"POST",
|
|
null,
|
|
{},
|
|
myFetchContentType.JSON,
|
|
Constants.ROBOTICS_API_ADDRESS
|
|
);
|
|
}}
|
|
icon={permitJoinEnabled ? <LoadingOutlined /> : <PlusOutlined />}
|
|
>
|
|
{!permitJoinEnabled
|
|
? t("robotics.robots.button.permitJoin")
|
|
: t("robotics.robots.button.disableJoin")}
|
|
</Button>
|
|
</div>
|
|
|
|
<Table
|
|
scroll={{ x: "max-content" }}
|
|
columns={getRobotsTableContent()}
|
|
dataSource={getRobotsTableItems(robots)}
|
|
pagination={false}
|
|
/>
|
|
|
|
<MyPagination
|
|
paginationPage={robotsPaginationPage}
|
|
setPaginationPage={(page) => {
|
|
setRobotsPaginationPage(page);
|
|
robotsPaginationPageRef.current = page;
|
|
}}
|
|
totalPages={robotsTotalPages}
|
|
/>
|
|
|
|
<Typography.Title level={4}>
|
|
{t("robotics.unauthorizedRobots.header")}
|
|
</Typography.Title>
|
|
|
|
<Table
|
|
scroll={{ x: "max-content" }}
|
|
columns={getUnauthorizedTableContent()}
|
|
dataSource={getUnauthorizedTableItems(unauthorizedRobots)}
|
|
pagination={false}
|
|
/>
|
|
|
|
<MyPagination
|
|
paginationPage={unauthorizedRobotsPaginationPage}
|
|
setPaginationPage={(page) => {
|
|
setUnauthorizedRobotsPaginationPage(page);
|
|
unauthorizedRobotsPaginationPageRef.current = page;
|
|
}}
|
|
totalPages={unauthorizedRobotsTotalPages}
|
|
/>
|
|
</>
|
|
);
|
|
}
|