diff --git a/BACKEND/providers/socket_io_provider.ts b/BACKEND/providers/socket_io_provider.ts index be1da6e..a36d635 100644 --- a/BACKEND/providers/socket_io_provider.ts +++ b/BACKEND/providers/socket_io_provider.ts @@ -112,8 +112,8 @@ export class WebSocketIo { socket.on('disconnect', () => { console.log(`FE disconnected: ${socket.id}`) this.userConnecting.delete(userId) - const listLineS = Array.from(this.lineMap.values()).map((el) => el?.config || {}) - listLineS.forEach((el) => { + const listLine = Array.from(this.lineMap.values()).map((el) => el?.config || {}) + listLine.forEach((el) => { if (el?.userOpenCLI === userName) { const line = this.lineMap.get(el.id) if (line) { @@ -546,6 +546,7 @@ export class WebSocketIo { if (line && line.config.status === 'connected') { this.lineConnecting = this.lineConnecting.filter((el) => el !== lineId) this.setTimeoutConnect(lineId, line, options.timeout) + await sleep(500) await action(line, options) } else { if (this.lineConnecting.includes(lineId)) continue @@ -567,6 +568,7 @@ export class WebSocketIo { const lineReconnect = this.lineMap.get(lineId) if (lineReconnect) { this.setTimeoutConnect(lineId, lineReconnect, options.timeout) + await sleep(500) await action(lineReconnect, options) } } else { diff --git a/FRONTEND/src/App.tsx b/FRONTEND/src/App.tsx index 5271e23..002e1e9 100644 --- a/FRONTEND/src/App.tsx +++ b/FRONTEND/src/App.tsx @@ -185,6 +185,7 @@ function App() { socket?.on("init", (data) => { if (Array.isArray(data)) { + // console.log(data); data.forEach((value) => { updateValueLineStation( value?.id, @@ -570,6 +571,7 @@ function App() { /> { setOpenModalTerminal(false); diff --git a/FRONTEND/src/components/BottomToolBar.tsx b/FRONTEND/src/components/BottomToolBar.tsx index db67f21..9a384fe 100644 --- a/FRONTEND/src/components/BottomToolBar.tsx +++ b/FRONTEND/src/components/BottomToolBar.tsx @@ -111,11 +111,15 @@ const BottomToolBar = ({ + onClick={() => { setSelectedLines( selectedLines.filter((line) => line.id !== el.id) - ) - } + ); + socket?.emit("close_cli", { + lineId: el?.id, + stationId: el.stationId || el.station_id, + }); + }} /> @@ -174,13 +178,13 @@ const BottomToolBar = ({ stationId: station.id, command: valueInput + "\n", }); - setTimeout(() => { - socket?.emit("write_command_line_from_web", { - lineIds: listLine.map((line) => line.id), - stationId: station.id, - command: " \n", - }); - }, 1000); + // setTimeout(() => { + // socket?.emit("write_command_line_from_web", { + // lineIds: listLine.map((line) => line.id), + // stationId: station.id, + // command: " \n", + // }); + // }, 1000); } setValueInput(""); } @@ -204,13 +208,39 @@ const BottomToolBar = ({ selectedLines={selectedLines} setSelectedLines={setSelectedLines} station={station} + userName={user?.userName} + onClick={() => { + const lines = station.lines.filter( + (line) => + !line?.userOpenCLI || line?.userOpenCLI === user?.userName + ); + if (selectedLines.length !== lines.length) { + setSelectedLines(lines); + lines.forEach((line) => { + socket?.emit("open_cli", { + lineId: line.id, + stationId: line.stationId || line.station_id, + userEmail: user?.email, + userName: user?.userName, + }); + }); + } else { + lines.forEach((line) => { + socket?.emit("close_cli", { + lineId: line?.id, + stationId: line.stationId || line.station_id, + }); + }); + setSelectedLines([]); + } + }} /> { - setSelectedLines([]); + // setSelectedLines([]); setIsDisable(true); setTimeout(() => { setIsDisable(false); @@ -257,7 +287,7 @@ const BottomToolBar = ({ ).length === 0 } onClick={() => { - setSelectedLines([]); + // setSelectedLines([]); setIsDisable(true); setTimeout(() => { setIsDisable(false); diff --git a/FRONTEND/src/components/ButtonAction.tsx b/FRONTEND/src/components/ButtonAction.tsx index a389063..282268d 100644 --- a/FRONTEND/src/components/ButtonAction.tsx +++ b/FRONTEND/src/components/ButtonAction.tsx @@ -223,24 +223,28 @@ export const ButtonCopy = ({ export const ButtonSelect = ({ selectedLines, - setSelectedLines, station, + onClick, + userName, }: { setSelectedLines: (value: React.SetStateAction) => void; selectedLines: TLine[]; station: TStation; + onClick: () => void; + userName: string; }) => { return ( diff --git a/FRONTEND/src/components/CardLine.tsx b/FRONTEND/src/components/CardLine.tsx index 6b5fa3a..caecf8a 100644 --- a/FRONTEND/src/components/CardLine.tsx +++ b/FRONTEND/src/components/CardLine.tsx @@ -3,7 +3,7 @@ import type { IScenario, TLine, TStation } from "../untils/types"; import classes from "./Component.module.css"; import TerminalCLI from "./TerminalXTerm"; import type { Socket } from "socket.io-client"; -import { memo, useMemo, useState } from "react"; +import { memo, useEffect, useMemo, useState } from "react"; import { convertTimestampToDate } from "../untils/helper"; import { ButtonDPELP, ButtonScenario } from "./ButtonAction"; import { notifications } from "@mantine/notifications"; @@ -38,6 +38,17 @@ const CardLine = ({ const [isDisabled, setIsDisabled] = useState(false); const [valueBaud, setValueBaud] = useState(""); + useEffect(() => { + if ( + typeof line?.userOpenCLI !== "undefined" && + typeof line?.userOpenCLI === "string" && + line?.userOpenCLI.length > 0 && + line?.userOpenCLI !== user?.userName + ) + setIsDisabled(true); + else setIsDisabled(false); + }, [line?.userOpenCLI]); + const controlApc = (action: string) => { if (!line.outlet) { notifications.show({ @@ -78,7 +89,35 @@ const CardLine = ({ setIsDisabled(false); }, 5000); }; - console.log("RERENDER", line.lineNumber); + + const handleClick = (isSelect = false) => { + if ( + typeof line?.userOpenCLI !== "undefined" && + typeof line?.userOpenCLI === "string" && + line?.userOpenCLI.length > 0 && + line?.userOpenCLI !== user?.userName + ) + return; + + if (selectedLines.find((val) => val.id === line.id)) { + if (isSelect) { + setSelectedLines(selectedLines.filter((val) => val.id !== line.id)); + socket?.emit("close_cli", { + lineId: line?.id, + stationId: line.stationId || line.station_id, + }); + } + } else { + setSelectedLines((pre) => [...pre, line]); + socket?.emit("open_cli", { + lineId: line.id, + stationId: line.stationId || line.station_id, + userEmail: user?.email, + userName: user?.userName, + }); + } + }; + return ( { e.preventDefault(); e.stopPropagation(); - if (selectedLines.find((val) => val.id === line.id)) - setSelectedLines(selectedLines.filter((val) => val.id !== line.id)); - else setSelectedLines((pre) => [...pre, line]); + handleClick(true); }} onMouseLeave={() => setTimeout(() => setShowMenu(false), 150)} > @@ -131,6 +168,16 @@ const CardLine = ({ { + e.preventDefault(); + e.stopPropagation(); + navigator.clipboard.writeText( + `PID: ${line?.inventory?.pid || ""} | SN: ${ + line?.inventory?.sn || "" + }` + ); + }} + className={classes.buttonCopy} fw={600} style={{ fontSize: "24px", @@ -160,7 +207,19 @@ const CardLine = ({
PID:{" "} - + { + e.preventDefault(); + e.stopPropagation(); + navigator.clipboard.writeText( + `PID: ${line?.inventory?.pid || ""} | SN: ${ + line?.inventory?.sn || "" + }` + ); + }} + className={`${classes.info_line} ${classes.buttonCopy}`} + fs={"italic"} + > {line?.inventory?.pid || ""} {line?.inventory?.vid ? ( @@ -176,19 +235,38 @@ const CardLine = ({ style={{ width: "120px" }} > SN:{" "} - + { + e.preventDefault(); + e.stopPropagation(); + navigator.clipboard.writeText( + `PID: ${line?.inventory?.pid || ""} | SN: ${ + line?.inventory?.sn || "" + }` + ); + }} + className={`${classes.info_line} ${classes.buttonCopy}`} + fs={"italic"} + > {line?.inventory?.sn || ""}
-
- {line?.userOpenCLI ? line?.userOpenCLI + " is using" : ""} -
+ + +
+ {line?.userOpenCLI + ? (line?.userOpenCLI === user?.userName + ? "You are" + : line?.userOpenCLI + " is") + " using" + : ""} +
+
@@ -360,7 +438,7 @@ const CardLine = ({ mt={"8px"} disabled={isDisabled} variant="outline" - color="orange" + color="red" size="xs" onClick={() => { controlApc("off"); @@ -372,7 +450,7 @@ const CardLine = ({ mt={"8px"} disabled={isDisabled} variant="outline" - color="red" + color="orange" size="xs" onClick={() => { controlApc("restart"); @@ -401,12 +479,13 @@ const CardLine = ({ line_id={Number(line?.id)} line={line} station_id={Number(stationItem.id)} - isDisabled={ - typeof line?.userOpenCLI !== "undefined" && - typeof line?.userOpenCLI === "string" && - line?.userOpenCLI.length > 0 && - line?.userOpenCLI !== user?.userName - } + // isDisabled={ + // typeof line?.userOpenCLI !== "undefined" && + // typeof line?.userOpenCLI === "string" && + // line?.userOpenCLI.length > 0 && + // line?.userOpenCLI !== user?.userName + // } + isDisabled={false} line_status={line?.status || ""} fontSize={11} miniSize={true} @@ -421,18 +500,17 @@ const CardLine = ({ openTerminal(line); }} onFocus={() => { - socket?.emit("open_cli", { - lineId: line.id, - stationId: line.stationId || line.station_id, - userEmail: user?.email, - userName: user?.userName, - }); + handleClick(); }} onBlur={() => { - socket?.emit("close_cli", { - lineId: line?.id, - stationId: line.stationId || line.station_id, - }); + if ( + !selectedLines.find((value) => value.id === line?.id) && + line?.userOpenCLI === user?.userName + ) + socket?.emit("close_cli", { + lineId: line?.id, + stationId: line.stationId || line.station_id, + }); }} /> diff --git a/FRONTEND/src/components/Component.module.css b/FRONTEND/src/components/Component.module.css index d87e8cc..4b215df 100644 --- a/FRONTEND/src/components/Component.module.css +++ b/FRONTEND/src/components/Component.module.css @@ -124,3 +124,7 @@ .topBarLine:hover { background-color: #f3f3f3; } + +.buttonCopy:hover { + background-color: #ccc !important; +} diff --git a/FRONTEND/src/components/DrawerControl.tsx b/FRONTEND/src/components/DrawerControl.tsx index b8ba0a7..a845602 100644 --- a/FRONTEND/src/components/DrawerControl.tsx +++ b/FRONTEND/src/components/DrawerControl.tsx @@ -211,9 +211,9 @@ export const DrawerAPCControl: React.FC = ({ default: return ( <> - {/* - WRONG CONFIG - */} + + DISCONNECTED + ); } @@ -799,8 +799,6 @@ export const DrawerSwitchControl: React.FC = ({ case "DISCONNECTED": return ( <> -
- {apc.status} @@ -879,7 +877,13 @@ export const DrawerSwitchControl: React.FC = ({ }} > - {dataStation?.switch ? RenderAPCStatus(dataStation?.switch) : ""} + {dataStation?.switch ? ( + RenderAPCStatus(dataStation?.switch) + ) : ( + + DISCONNECTED + + )} {dataStation?.switch?.status !== "CONNECTED" ? (