ATC_SIMPLE/FRONTEND/src/components/ModalTerminal.tsx

345 lines
11 KiB
TypeScript

import {
Box,
Button,
Dialog,
Flex,
Grid,
Group,
Modal,
ScrollArea,
Text,
} from "@mantine/core";
import type {
IDataTakeOver,
IScenario,
TLine,
TStation,
} from "../untils/types";
import TerminalCLI from "./TerminalXTerm";
import type { Socket } from "socket.io-client";
import classes from "./Component.module.css";
import { useEffect, useMemo, useRef, useState } from "react";
import { IconCircleCheckFilled } from "@tabler/icons-react";
import { ButtonDPELP } from "./ButtonAction";
const ModalTerminal = ({
opened,
onClose,
line,
socket,
stationItem,
scenarios,
dataRequestTakeOver,
countDownRequest,
disableRequestTakeOver,
setDisableRequestTakeOver,
setCountDownRequest,
setDataRequestTakeOver,
}: {
opened: boolean;
onClose: () => void;
line: TLine | undefined;
socket: Socket | null;
stationItem: TStation | undefined;
scenarios: IScenario[];
dataRequestTakeOver: IDataTakeOver | undefined;
countDownRequest: number;
disableRequestTakeOver: boolean;
setDisableRequestTakeOver: (value: React.SetStateAction<boolean>) => void;
setCountDownRequest: (value: React.SetStateAction<number>) => void;
setDataRequestTakeOver: (
value: React.SetStateAction<IDataTakeOver | undefined>
) => void;
}) => {
const user = useMemo(() => {
return localStorage.getItem("user") &&
typeof localStorage.getItem("user") === "string"
? JSON.parse(localStorage.getItem("user") || "")
: null;
}, []);
const [isDisable, setIsDisable] = useState<boolean>(false);
const intervalTakeOverRef = useRef<NodeJS.Timeout | null>(null);
useEffect(() => {
if (
typeof dataRequestTakeOver?.userName !== "undefined" &&
line?.userOpenCLI === user?.userName &&
dataRequestTakeOver?.userName !== user?.userName
) {
if (dataRequestTakeOver?.userName) {
intervalTakeOverRef.current = setInterval(() => {
socket?.emit("open_cli", {
lineId: line?.id,
stationId: line?.station_id,
userEmail: user?.userName,
userName: user?.userName,
});
socket?.emit("request_take_over", {
station_id: line?.station_id,
});
setDisableRequestTakeOver(false);
setCountDownRequest(0);
if (intervalTakeOverRef.current)
clearInterval(intervalTakeOverRef.current);
}, 20000);
}
} else {
if (intervalTakeOverRef.current)
clearInterval(intervalTakeOverRef.current);
}
}, [dataRequestTakeOver?.userName]);
return (
<Box>
<Modal
opened={opened}
onClose={() => {
onClose();
if (line?.userOpenCLI === user?.userName)
socket?.emit("close_cli", {
lineId: line?.id,
stationId: line?.station_id,
});
}}
size={"80%"}
style={{ position: "absolute", left: 0 }}
title={
<Flex align={"center"} justify={"space-between"} w={"100%"}>
<Box
style={{
display: "flex",
// justifyContent: "center",
width: "400px",
}}
>
<Text size="md" mr={10}>
Line number:{" "}
<strong>{line?.lineNumber || line?.line_number || ""}</strong>
</Text>
<Text size="md" mr={10}>
- <strong>{line?.port || ""}</strong>
</Text>
{line?.status === "connected" && (
<IconCircleCheckFilled color="green" />
)}
<div
style={{
alignItems: "center",
marginLeft: "16px",
fontSize: "12px",
color: "red",
display: "flex",
}}
>
{line?.userOpenCLI
? (line?.userOpenCLI === user?.userName
? "You are"
: line?.userOpenCLI + " is") + " using"
: "Terminal is used"}
</div>
</Box>
<Flex
align={"center"}
justify={"space-between"}
gap={"md"}
style={{
width: "400px",
}}
>
<div className={classes.info_line} style={{ fontSize: "14px" }}>
PID: {line?.inventory?.pid || ""}
</div>
<div className={classes.info_line} style={{ fontSize: "14px" }}>
SN: {line?.inventory?.sn || ""}
</div>
<div className={classes.info_line} style={{ fontSize: "14px" }}>
VID: {line?.inventory?.vid || ""}
</div>
</Flex>
<Box></Box>
</Flex>
}
>
<Grid>
<Grid.Col span={10} style={{ borderRight: "1px solid #ccc" }}>
<TerminalCLI
cliOpened={opened}
socket={socket}
content={line?.output ?? ""}
initContent={line?.netOutput ?? ""}
loadingContent={line?.loadingOutput}
line_id={Number(line?.id)}
station_id={Number(stationItem?.id)}
isDisabled={
typeof line?.userOpenCLI !== "undefined" &&
line?.userOpenCLI !== user?.userName
}
line_status={line?.status || ""}
/>
</Grid.Col>
<Grid.Col span={2}>
<ScrollArea h={"60vh"} style={{ paddingBottom: "12px" }}>
<Flex w={"100%"} direction={"column"} wrap={"wrap"} gap={"6px"}>
<ButtonDPELP
socket={socket}
selectedLines={line ? [line] : []}
isDisable={isDisable}
onClick={() => {
setIsDisable(true);
setTimeout(() => {
setIsDisable(false);
}, 10000);
}}
/>
{scenarios.map((scenario) => (
<Button
disabled={
isDisable ||
(typeof line?.userOpenCLI !== "undefined" &&
line?.userOpenCLI !== user?.userName)
}
className={classes.buttonScenario}
key={scenario.id}
miw={"100px"}
mb={"6px"}
style={{ minHeight: "24px" }}
mr={"5px"}
variant={"outline"}
onClick={async () => {
setIsDisable(true);
setTimeout(() => {
setIsDisable(false);
}, 10000);
if (line)
socket?.emit(
"run_scenario",
Object.assign(line, {
scenario: scenario,
})
);
}}
>
{scenario.title}
</Button>
))}
</Flex>
</ScrollArea>
</Grid.Col>
</Grid>
<Flex justify={"space-between"}>
<Box></Box>
<Button
disabled={
disableRequestTakeOver ||
!line?.userOpenCLI ||
line?.userOpenCLI === user?.userName
}
variant="filled"
size="xs"
radius="xs"
mt={"md"}
ml={"20px"}
onClick={() => {
socket?.emit("request_take_over", {
line_id: line?.id,
station_id: Number(line?.station_id),
userName: user?.userName?.trim() || "",
userEmail: user?.userName || "",
});
setDisableRequestTakeOver(true);
setTimeout(() => {
setDisableRequestTakeOver(false);
}, 20000);
setCountDownRequest(20);
const intervalCount = setInterval(() => {
setCountDownRequest((prev) => {
if (prev <= 1) {
clearInterval(intervalCount);
return 0;
}
return prev - 1;
});
}, 1000);
}}
>
Take over{" "}
{countDownRequest > 0 &&
(typeof dataRequestTakeOver?.userName === "undefined" ||
dataRequestTakeOver?.userEmail === user?.userName)
? `(${countDownRequest}s)`
: ""}
</Button>
</Flex>
</Modal>
<Dialog
opened={
typeof dataRequestTakeOver?.userName !== "undefined" &&
line?.userOpenCLI === user?.userName &&
dataRequestTakeOver?.userName !== user?.userName
}
position={{ bottom: 20, right: 20 }}
withCloseButton
style={{ border: "solid 2px #ff6c6b", left: 0 }}
shadow="md"
onClose={close}
size="lg"
radius="md"
>
<Text size="sm" mb="xs" fw={700} c={"#ff6c6b"}>
{`${`${dataRequestTakeOver?.userName} ${
dataRequestTakeOver?.userEmail
? `(${dataRequestTakeOver?.userEmail})`
: ""
}`} want to take over this line? ${
countDownRequest > 0 &&
typeof dataRequestTakeOver?.userName !== "undefined" &&
line?.userOpenCLI === user?.userName
? `(${countDownRequest}s)`
: ""
}`}
</Text>
<Group style={{ display: "flex", justifyContent: "center" }}>
<Button
variant="gradient"
gradient={{ from: "pink", to: "red", deg: 90 }}
size="xs"
onClick={async () => {
socket?.emit("open_cli", {
lineId: line?.id,
stationId: line?.station_id,
userEmail: dataRequestTakeOver?.userEmail,
userName: dataRequestTakeOver?.userName,
});
socket?.emit("request_take_over", {
station_id: Number(line?.station_id),
});
setDisableRequestTakeOver(false);
setDataRequestTakeOver(undefined);
setCountDownRequest(0);
}}
>
Yes
</Button>
<Button
variant="gradient"
size="xs"
onClick={async () => {
setDisableRequestTakeOver(false);
setDataRequestTakeOver(undefined);
setCountDownRequest(0);
}}
>
No
</Button>
</Group>
</Dialog>
</Box>
);
};
export default ModalTerminal;