diff --git a/BACKEND/app/services/physical_test_service.ts b/BACKEND/app/services/physical_test_service.ts index 4b66b83..e8983e4 100644 --- a/BACKEND/app/services/physical_test_service.ts +++ b/BACKEND/app/services/physical_test_service.ts @@ -68,11 +68,11 @@ export class PhysicalPortTest { } // 3️⃣ POE DISCONNECT - match = line.match(POE_DISCONNECT_REGEX) - if (match) { - iface = normalizeInterface(match[1]) - markTested = true - } + // match = line.match(POE_DISCONNECT_REGEX) + // if (match) { + // iface = normalizeInterface(match[1]) + // markTested = true + // } if (!iface) continue @@ -159,34 +159,37 @@ export class PhysicalPortTest { const status = missing.length === 0 ? 'PASS' : 'WARNING' return ` - Physical Port Test Report
- ────────────────────────────────
- Model : ${report.device.model ?? 'N/A'}
- Serial Number : ${report.device.serial ?? 'N/A'}
- Started At : ${moment(report.startTime).format('YYYY/MM/DD, HH:mm:ss')}
- Finished At : ${moment(report.endTime).format('YYYY/MM/DD, HH:mm:ss')}
- Duration : ${this.formatDuration(report.durationMs)}
- Status : ${status === 'PASS' ? '✅ PASS' : '⚠️ WARNING'}
-
- ────────────────────────────────
- Test Summary
- ────────────
- Total Ports : ${report.ports.length}
+ Physical Port Test Report
+ + + + + +
+ Model : ${report.device.model ?? 'N/A'}
+ Serial Number : ${report.device.serial ?? 'N/A'}
+ Status : ${status === 'PASS' ? '✅ PASS' : '⚠️ WARNING'}
+
+ Total Ports : ${report.ports.length}
Ports Tested (UP) : ${tested.length}
Ports Missing : ${missing.length}
+

────────────────────────────────
Passed Ports
- ────────────
- ${tested.map((p) => p.name).join('
')}
+ ${ + tested.length + ? `
${tested.map((p) => this.normalizePortName(p.name)).join('
')}

+ ` + : '' + }
${ missing.length ? ` ────────────────────────────────
Missing Ports
- ─────────────
- ${missing.map((p) => p.name).join('
')} +
${missing.map((p) => this.normalizePortName(p.name)).join('
')}

` : '' }
@@ -201,4 +204,23 @@ export class PhysicalPortTest { return `${minutes}m ${seconds}s` } + + normalizePortName(port: string): string { + if (!port) return '' + + // Example inputs: "Fa0/1", "Gi0/0/1", "Fa0/0/2" + const match = port.match(/^([A-Za-z]+)([\d/]+)$/) + + if (!match) return port + + const type = match[1] // Fa, Gi, Te, etc. + const numbers = match[2] // "0/1" / "0/0/1" / "0/0/2" + + // Get the last part after slash + const parts = numbers.split('/') + const last = parts[parts.length - 1] + const preLast = parts?.length > 1 ? parts[parts.length - 2] : '' + + return `${type?.slice(0, 2)}${preLast ? preLast + '/' : ''}${last}` + } } diff --git a/FRONTEND/src/components/Modal/ModalTerminal.tsx b/FRONTEND/src/components/Modal/ModalTerminal.tsx index 08ff704..ae547ce 100644 --- a/FRONTEND/src/components/Modal/ModalTerminal.tsx +++ b/FRONTEND/src/components/Modal/ModalTerminal.tsx @@ -447,8 +447,9 @@ const ModalTerminal = ({ // Get the last part after slash const parts = numbers.split("/"); const last = parts[parts.length - 1]; + const preLast = parts?.length > 1 ? parts[parts.length - 2] : ""; - return `${type?.slice(0, 2)}${last}`; + return `${type?.slice(0, 2)}${preLast ? preLast + "/" : ""}${last}`; }; const findDataShowVersion = () => { @@ -593,199 +594,200 @@ const ModalTerminal = ({ - - - - - - - Line {line?.lineNumber || line?.line_number || ""} - + + + + + + Line {line?.lineNumber || line?.line_number || ""} + + + + - {line?.port || ""} + + {line?.status === "connected" && ( + + )} + + + + + BAUD: - - - {line?.port || ""} + + {line?.baud || ""} - {line?.status === "connected" && ( - - )} - - - - 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); - } + + {}} + > + + + + + + {listBaudDefault.map((el, i) => ( + - - - - PID: + > + {el} + + ))} + 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: + + { + e.preventDefault(); + e.stopPropagation(); + if (!line?.inventory?.pid) return; + navigator.clipboard.writeText( + line.inventory?.pid || "" + ); + }} + > + {line?.inventory?.pid || ""} + + {line?.inventory?.vid ? ( + + {line?.inventory?.vid} - { - 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 || ""} - - - - - + ) : ( + "" + )} + + + + + SN: + + { + e.preventDefault(); + e.stopPropagation(); + if (!line?.inventory?.sn) return; + navigator.clipboard.writeText(line.inventory?.sn || ""); + }} + > + {line?.inventory?.sn || ""} + + + + + + + + IOS: @@ -799,307 +801,287 @@ const ModalTerminal = ({ : ""} - - - - License: - - - {findDataShowLicense() - ? findDataShowLicense() - ?.filter( - (el: TextTSMLicense) => - el.LICENSE_TYPE === "Permanent" + + + License: + + + {findDataShowLicense() + ? findDataShowLicense() + ?.filter( + (el: TextTSMLicense) => + el.LICENSE_TYPE === "Permanent" + ) + ?.map((v: TextTSMLicense) => v.FEATURE) + ?.join(", ") + : ""} + + + + + + Sh env/module: + + + + {findDataShowEnv() + ? findDataShowEnv()?.map( + (v: TextTSMEnvironment, i) => ( + + - {v} + + ) ) - ?.map((v: TextTSMLicense) => v.FEATURE) - ?.join(", ") - : ""} - - - - - - Sh env/module: - + : ""} + + + + + Mem: + + + {findDataShowVersion() + ? findDataShowVersion()?.MEMORY || "" + : ""} + + + + + Flash: + + + {findDataShowVersion() + ? findDataShowVersion()?.USB_FLASH + : ""} + + + - {findDataShowEnv() - ? findDataShowEnv()?.map((v: TextTSMEnvironment, i) => ( - - - {v} + + + Warning from test report: AI + + + + + +