diff --git a/BACKEND/app/services/line_connection.ts b/BACKEND/app/services/line_connection.ts index 40cad37..fe1c529 100644 --- a/BACKEND/app/services/line_connection.ts +++ b/BACKEND/app/services/line_connection.ts @@ -1908,6 +1908,12 @@ ${log} `[ATC] - [${config.stationName} - Line: ${config.lineNumber}] - Summary of Testing Results`, body ) + this.socketIO.emit('summary_tested', { + stationId: this.config.stationId, + lineId: this.config.id, + body: body, + title: `[${config.stationName} - Line: ${config.lineNumber}] - Summary of Testing Results`, + }) } /** diff --git a/BACKEND/app/services/physical_test_service.ts b/BACKEND/app/services/physical_test_service.ts index 22bbfde..d3ab5c6 100644 --- a/BACKEND/app/services/physical_test_service.ts +++ b/BACKEND/app/services/physical_test_service.ts @@ -162,7 +162,7 @@ export class PhysicalPortTest { const missingPoE = missing.filter((p) => !p.name.includes('SFP')) const missingSFP = missing.filter((p) => p.name.includes('SFP')) - const status = missing.length === 0 ? 'PASS' : 'WARNING' + const status = missing.length === 0 && tested.length > 0 ? 'PASS' : 'WARNING' return ` Physical Ports Test Report
@@ -181,29 +181,32 @@ export class PhysicalPortTest {
- ${missing.length - ? ` + ${ + missing.length + ? ` ────────────────────────────────
Missing Ports
- ${missingPoE?.length - ? `` - : '' - } - ${missingSFP?.length - ? `` - : '' - } + : '' + }
+ ${ + missingPoE?.length + ? `
${missingPoE.map((p) => this.normalizePortName(p.name)).join('
')}
+ : '' + } + ${ + missingSFP?.length + ? `
${missingSFP.map((p) => this.normalizePortName(p.name)).join('
')}
` - : '' - } + : '' + }

`.trim() diff --git a/FRONTEND/src/App.tsx b/FRONTEND/src/App.tsx index 3e5b644..87f9bfa 100644 --- a/FRONTEND/src/App.tsx +++ b/FRONTEND/src/App.tsx @@ -26,6 +26,7 @@ import { Box, } from "@mantine/core"; import type { + DataSummaryTested, FileInfo, IScenario, ReceivedFile, @@ -57,6 +58,7 @@ import { isJsonString } from "./untils/helper"; import BottomToolBar from "./components/BottomToolBar"; import ModalConfirmSkipTestPort from "./components/Modal/ModalConfirmSkipTestPort"; import ModalConfirmRunPhysical from "./components/Modal/ModalConfirmRunPhysicalTest"; +import ModalSummaryTested from "./components/Modal/ModalSummaryTested"; // import ModalConfirmRunScenario from "./components/Modal/ModalConfirmRunScenario"; const apiUrl = import.meta.env.VITE_BACKEND_URL; @@ -115,6 +117,8 @@ function App() { const [linesConfirmRunPhysical, setLinesConfirmRunPhysical] = useState< TLine[] >([]); + const [dataSummaryTested, setDataSummaryTested] = + useState(null); const connectApcSwitch = (station: TStation) => { if (!station?.is_active) return; @@ -499,6 +503,15 @@ function App() { } }); + socket?.on("summary_tested", (data) => { + if (data?.body) { + setDataSummaryTested({ + body: data?.body || "", + title: data?.title || "", + }); + } + }); + // ✅ cleanup on unmount or when socket changes return () => { socket.off("init"); @@ -518,6 +531,7 @@ function App() { socket.off("user_clear_terminal"); socket.off("test_port_physical"); socket.off("feature_tested"); + socket.off("summary_tested"); }; }, [socket, stations, selectedLine]); @@ -990,6 +1004,7 @@ function App() { listCategories={listCategories} setLinesConfirmSkipPort={setLinesConfirmSkipPort} linesConfirmSkipPort={linesConfirmSkipPort} + dataSummaryTested={dataSummaryTested} /> {/* el.id === Number(activeTab))} /> + + ); } diff --git a/FRONTEND/src/components/Modal/ModalConfirmRunPhysicalTest.tsx b/FRONTEND/src/components/Modal/ModalConfirmRunPhysicalTest.tsx index e34228d..f65c33d 100644 --- a/FRONTEND/src/components/Modal/ModalConfirmRunPhysicalTest.tsx +++ b/FRONTEND/src/components/Modal/ModalConfirmRunPhysicalTest.tsx @@ -65,7 +65,7 @@ export default function ModalConfirmRunPhysical({ title="Confirm Run Test Ports" > - + {dataLines.map((line, i) => ( - + Line: {line.lineNumber} - + PID: {line.pid || ""} - + SN: {line.sn || ""} - + VID: {line.vid || ""} diff --git a/FRONTEND/src/components/Modal/ModalSummaryTested.tsx b/FRONTEND/src/components/Modal/ModalSummaryTested.tsx new file mode 100644 index 0000000..c7630bd --- /dev/null +++ b/FRONTEND/src/components/Modal/ModalSummaryTested.tsx @@ -0,0 +1,32 @@ +import { Modal, Box, Text } from "@mantine/core"; +import type { DataSummaryTested } from "../../untils/types"; + +interface Props { + data: DataSummaryTested | null; + setData: (value: React.SetStateAction) => void; +} + +export default function ModalSummaryTested({ data, setData }: Props) { + return ( + { + setData(null); + }} + title="Summary" + > + + + + {data?.title} + + + + + + + + ); +} diff --git a/FRONTEND/src/components/Modal/ModalTerminal.tsx b/FRONTEND/src/components/Modal/ModalTerminal.tsx index 60a38d7..8ee94e7 100644 --- a/FRONTEND/src/components/Modal/ModalTerminal.tsx +++ b/FRONTEND/src/components/Modal/ModalTerminal.tsx @@ -17,6 +17,7 @@ import { Tooltip, } from "@mantine/core"; import type { + DataSummaryTested, FileInfo, IScenario, SwitchPortsProps, @@ -83,6 +84,7 @@ const ModalTerminal = ({ setScenarios, setLinesConfirmSkipPort, linesConfirmSkipPort, + dataSummaryTested, }: { opened: boolean; onClose: () => void; @@ -100,6 +102,7 @@ const ModalTerminal = ({ setScenarios: (value: React.SetStateAction) => void; setLinesConfirmSkipPort: (value: React.SetStateAction) => void; linesConfirmSkipPort: TLine[]; + dataSummaryTested: DataSummaryTested | null; }) => { const user = useMemo(() => { return localStorage.getItem("user") && @@ -547,8 +550,13 @@ const ModalTerminal = ({ setOpenScenarioModal(false); return; } - if (openSelectIos) return; - if (linesConfirmSkipPort.length) return; + if ( + openSelectIos || + linesConfirmSkipPort.length > 0 || + (dataSummaryTested && dataSummaryTested?.body) + ) + return; + onClose(); if ( line?.userOpenCLI === user?.userName && diff --git a/FRONTEND/src/untils/types.ts b/FRONTEND/src/untils/types.ts index d660a6f..e1ef1fe 100644 --- a/FRONTEND/src/untils/types.ts +++ b/FRONTEND/src/untils/types.ts @@ -300,3 +300,8 @@ export type Keywords = { match_type: string; is_active: boolean; }; + +export type DataSummaryTested = { + body: string; + title: string; +};