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 || ""}
-
-
-
-
-
-
- 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
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
@@ -1438,219 +1492,227 @@ const ModalTerminal = ({
loadingClearTerminal={line?.loadingClearTerminal}
isClearKeepScrollBack={isClearKeepScrollBack}
/>
-
-
-
-
-
-
-
+
+
+
+
-
-
-
-
- 0
- ? true
- : false)
- }
- onClick={() => {
- socket?.emit("run_all_dpelp", {
- lineIds: [line?.id],
- stationName: stationItem?.name,
- stationId: Number(stationItem?.id),
- });
- setIsDisable(true);
- setTimeout(() => {
- setIsDisable(false);
- }, 10000);
- }}
- dataDPELP={scenarios?.find(
- (el) => el.title.toUpperCase() === "DPELP",
- )}
- userName={
- user?.firstName
- ? `${user.firstName} ${user.lastName || ""}`
- : user?.userName || "Unknown User"
- }
- />
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+ 0
+ ? true
+ : false)
+ }
+ onClick={() => {
+ socket?.emit("run_all_dpelp", {
+ lineIds: [line?.id],
+ stationName: stationItem?.name,
+ stationId: Number(stationItem?.id),
+ });
+ setIsDisable(true);
+ setTimeout(() => {
+ setIsDisable(false);
+ }, 10000);
+ }}
+ dataDPELP={scenarios?.find(
+ (el) => el.title.toUpperCase() === "DPELP",
+ )}
+ userName={
+ user?.firstName
+ ? `${user.firstName} ${user.lastName || ""}`
+ : user?.userName || "Unknown User"
+ }
+ />
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
diff --git a/FRONTEND/src/components/TerminalXTerm.tsx b/FRONTEND/src/components/TerminalXTerm.tsx
index 2e5915f..b4c9923 100644
--- a/FRONTEND/src/components/TerminalXTerm.tsx
+++ b/FRONTEND/src/components/TerminalXTerm.tsx
@@ -295,6 +295,7 @@ const TerminalCLI: React.FC = ({
backgroundColor: "black",
paddingBottom: customStyle.paddingBottom ?? "10px",
maxHeight: customStyle.maxHeight ?? "70vh",
+ borderRadius: "8px",
}}
>