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 || ""}
-
-
-
-
-
-
- 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
+
+
+
+
+
+
+
+
+
-
-
-
-
- Mem:
-
-
- {findDataShowVersion()
- ? findDataShowVersion()?.MEMORY || ""
- : ""}
-
-
-
-
- Flash:
-
-
- {findDataShowVersion()
- ? findDataShowVersion()?.USB_FLASH
- : ""}
-
-
-
-
-
-
- Warning from test report: AI
-
+
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
- {line?.runningPhysical ? (
+
+
+
+ {line?.runningPhysical && line?.ports
+ ? line.ports.map((port, i) => (
+
+ {normalizePortName(port)}
+
+ ))
+ : null}
+
+
+
+
- ) : (
-
- )}
-
-
+ {line?.runningPhysical ? (
+
+ ) : (
+
+ )}
+
+
+