diff --git a/FRONTEND/src/components/Components/GroupButtonTerminal.tsx b/FRONTEND/src/components/Components/GroupButtonTerminal.tsx new file mode 100644 index 0000000..5f8a5d1 --- /dev/null +++ b/FRONTEND/src/components/Components/GroupButtonTerminal.tsx @@ -0,0 +1,32 @@ +import { Box, Flex, Text } from "@mantine/core"; + +interface GroupButtonProps { + title: string; + children: React.ReactNode; +} + +export default function GroupButtonTerminal({ + title, + children, +}: GroupButtonProps) { + return ( + + + + {title} + + + + {children} + + + + ); +} diff --git a/FRONTEND/src/components/Modal/ModalTerminal.tsx b/FRONTEND/src/components/Modal/ModalTerminal.tsx index 330afde..e52c583 100644 --- a/FRONTEND/src/components/Modal/ModalTerminal.tsx +++ b/FRONTEND/src/components/Modal/ModalTerminal.tsx @@ -2,6 +2,7 @@ import { ActionIcon, Box, Button, + Card, CloseButton, Flex, Grid, @@ -58,6 +59,7 @@ import ModalLineHistory from "./ModalLineHistory"; import AutoProgress from "../Components/AutoProgress"; import LoaderOverlay from "../Components/LoaderOverlay"; import { bodyDPELP, convertFromKilobytesString } from "../../untils/helper"; +import GroupButtonTerminal from "../Components/GroupButtonTerminal"; const apiUrl = import.meta.env.VITE_BACKEND_URL; const INIT_TICKET = { @@ -69,6 +71,83 @@ const INIT_TICKET = { status: "open", }; +// Sub-component: Switch Connection Status +interface SwitchConnectionStatusProps { + line: TLine | undefined; + findSwitchPort: (portName: string) => SwitchPortsProps | null; + normalizePortName: (port: string) => string; +} + +const SwitchConnectionStatus = ({ + line, + findSwitchPort, + normalizePortName, +}: SwitchConnectionStatusProps) => { + const port = line?.interface ? findSwitchPort(line.interface) : null; + const isConnected = port?.status === "ON"; + const portName = line?.interface ? normalizePortName(line.interface) : ""; + + return ( + + + + Internet + {line?.interface ? ( + + {isConnected ? "Connected" : "Not Connected"} ({portName}) + + ) : ( + + Not config + + )} + + + ); +}; + +// Sub-component: Switch Control Buttons +interface SwitchControlButtonsProps { + isDisable: boolean; + hasInterface: boolean; + onSwitchOn: () => void; + onSwitchOff: () => void; + onSwitchRestart: () => void; +} + +const SwitchControlButtons = ({ + isDisable, + hasInterface, + onSwitchOn, + onSwitchOff, + onSwitchRestart, +}: SwitchControlButtonsProps) => { + const SWITCH_ACTIONS = [ + { label: "ON", color: "green", handler: onSwitchOn }, + { label: "OFF", color: "red", handler: onSwitchOff }, + { label: "Restart", color: "orange", handler: onSwitchRestart }, + ] as const; + + return ( + + {SWITCH_ACTIONS.map(({ label, color, handler }) => ( + + ))} + + ); +}; + const ModalTerminal = ({ opened, onClose, @@ -817,177 +896,187 @@ const ModalTerminal = ({ )} - - - - BAUD: - - - {line?.baud || ""} - - - - - {}} - > - - - - - - {listBaudDefault.map((el, i) => ( - - ))} - setValueBaud(e.target.value)} - onKeyDown={(e) => { - if (e.key === "Enter") { - socket?.emit("set_baud", { - lineId: line?.id, - baud: Number(valueBaud), - stationId: Number(stationItem?.id), - }); - setValueBaud(""); - setIsDisable(true); - setTimeout(() => { - setIsDisable(false); - }, 5000); - } + + + BAUD: + + + {line?.baud || ""} + + + + + {}} + > + + + + + - - - - - - - PID: - - { - e.preventDefault(); - e.stopPropagation(); - if (!line?.inventory?.pid) return; - navigator.clipboard.writeText( - line.inventory?.pid || "", - ); - }} - > - {line?.inventory?.pid || ""} - - {line?.inventory?.vid ? ( - - {line?.inventory?.vid} + > + {listBaudDefault.map((el, i) => ( + + ))} + setValueBaud(e.target.value)} + onKeyDown={(e) => { + if (e.key === "Enter") { + socket?.emit("set_baud", { + lineId: line?.id, + baud: Number(valueBaud), + stationId: Number(stationItem?.id), + }); + setValueBaud(""); + setIsDisable(true); + setTimeout(() => { + setIsDisable(false); + }, 5000); + } + }} + /> + + + + + + + PID: - ) : ( - "" - )} - - - - - SN: - - { - e.preventDefault(); - e.stopPropagation(); - if (!line?.inventory?.sn) return; - navigator.clipboard.writeText(line.inventory?.sn || ""); - }} - > - {line?.inventory?.sn || ""} - - - - + { + e.preventDefault(); + e.stopPropagation(); + if (!line?.inventory?.pid) return; + navigator.clipboard.writeText( + line.inventory?.pid || "", + ); + }} + > + {line?.inventory?.pid || ""} + + {line?.inventory?.vid ? ( + + {line?.inventory?.vid} + + ) : ( + "" + )} + + + + + SN: + + { + e.preventDefault(); + e.stopPropagation(); + if (!line?.inventory?.sn) return; + navigator.clipboard.writeText( + line.inventory?.sn || "", + ); + }} + > + {line?.inventory?.sn || ""} + + + + + - - - IOS: - - - {findDataShowVersion() - ? findDataShowVersion()?.SOFTWARE_IMAGE - ? findDataShowVersion()?.SOFTWARE_IMAGE + - " " + - (findDataShowVersion()?.VERSION || "") - : "" - : ""} - - - - - MAC: - - - {findDataShowVersion() - ? findDataShowVersion()?.MAC_ADDRESS || "" - : ""} - - - - - License: - - - {findDataShowLicense() - ? findDataShowLicense() - ?.filter((el: TextTSMLicense) => - el.LICENSE_TYPE?.toLowerCase()?.includes( - "permanent", - ), - ) - ?.map((v: TextTSMLicense) => v.FEATURE) - ?.join(", ") - : ""} - - - - - - Sh env/module: - - - - {findDataShowEnv() - ? findDataShowEnv()?.map( - (v: TextTSMEnvironment, i) => ( - - - {v} - - ), - ) - : ""} - - - - - - Memory: - - - {findDataShowVersion() && - findDataShowVersion()?.MEMORY - ? convertFromKilobytesString( - findDataShowVersion()?.MEMORY, - ) - : ""} - - - - - Flash: - - - {findDataShowVersion() && - findDataShowVersion()?.USB_FLASH - ? convertFromKilobytesString( - findDataShowVersion()?.USB_FLASH, - ) - : ""} - - - - - - - Warning from test report: AI - - - - - - -