Merge branch 'main' of https://gitea.nswteam.net/andrew.ng/ATC_SIMPLE
This commit is contained in:
commit
13a3788c4a
|
|
@ -286,6 +286,11 @@ export default class LineConnection {
|
||||||
if (!this.client || this.client.destroyed) {
|
if (!this.client || this.client.destroyed) {
|
||||||
console.log('Not connected')
|
console.log('Not connected')
|
||||||
this.isRunningScript = false
|
this.isRunningScript = false
|
||||||
|
this.socketIO.emit('running_scenario', {
|
||||||
|
stationId: this.config.stationId,
|
||||||
|
lineId: this.config.id,
|
||||||
|
title: '',
|
||||||
|
})
|
||||||
this.outputBuffer = ''
|
this.outputBuffer = ''
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -299,6 +304,11 @@ export default class LineConnection {
|
||||||
)
|
)
|
||||||
if (script?.title === 'DPELP') this.dataDPELP = ''
|
if (script?.title === 'DPELP') this.dataDPELP = ''
|
||||||
this.isRunningScript = true
|
this.isRunningScript = true
|
||||||
|
this.socketIO.emit('running_scenario', {
|
||||||
|
stationId: this.config.stationId,
|
||||||
|
lineId: this.config.id,
|
||||||
|
title: script?.title,
|
||||||
|
})
|
||||||
const now = Date.now()
|
const now = Date.now()
|
||||||
this.outputScenario += `\n\n---start-scenarios---${now}---${userName}---${script?.title}---\n---scenario---${script?.title}---${now}---\n`
|
this.outputScenario += `\n\n---start-scenarios---${now}---${userName}---${script?.title}---\n---scenario---${script?.title}---${now}---\n`
|
||||||
appendLog(
|
appendLog(
|
||||||
|
|
@ -318,6 +328,11 @@ export default class LineConnection {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const timeoutTimer = setTimeout(() => {
|
const timeoutTimer = setTimeout(() => {
|
||||||
this.isRunningScript = false
|
this.isRunningScript = false
|
||||||
|
this.socketIO.emit('running_scenario', {
|
||||||
|
stationId: this.config.stationId,
|
||||||
|
lineId: this.config.id,
|
||||||
|
title: '',
|
||||||
|
})
|
||||||
this.outputBuffer = ''
|
this.outputBuffer = ''
|
||||||
this.outputScenario = ''
|
this.outputScenario = ''
|
||||||
this.config.output += 'Timeout run scenario'
|
this.config.output += 'Timeout run scenario'
|
||||||
|
|
@ -347,6 +362,11 @@ export default class LineConnection {
|
||||||
return
|
return
|
||||||
} else clearTimeout(timeoutTimer)
|
} else clearTimeout(timeoutTimer)
|
||||||
this.isRunningScript = false
|
this.isRunningScript = false
|
||||||
|
this.socketIO.emit('running_scenario', {
|
||||||
|
stationId: this.config.stationId,
|
||||||
|
lineId: this.config.id,
|
||||||
|
title: '',
|
||||||
|
})
|
||||||
this.outputBuffer = ''
|
this.outputBuffer = ''
|
||||||
this.outputScenario += `\n---end-scenarios---${now}---${userName}---\n`
|
this.outputScenario += `\n---end-scenarios---${now}---${userName}---\n`
|
||||||
appendLog(
|
appendLog(
|
||||||
|
|
@ -676,7 +696,7 @@ export default class LineConnection {
|
||||||
(Tóm tắt trạng thái tổng thể của hệ thống trong 2–4 ý)
|
(Tóm tắt trạng thái tổng thể của hệ thống trong 2–4 ý)
|
||||||
|
|
||||||
issue:
|
issue:
|
||||||
(Tóm tắt cực ngắn gọn các lỗi/dấu hiệu bất thường, mỗi vấn đề 1 dòng)
|
(Tóm tắt cực ngắn gọn các lỗi/dấu hiệu bất thường, mỗi vấn đề 1 dòng, bỏ qua các vấn đề không quan trọng như về port up/down hay Invalid input, Incomplete command)
|
||||||
|
|
||||||
Quy tắc:
|
Quy tắc:
|
||||||
Không giải thích dài dòng.
|
Không giải thích dài dòng.
|
||||||
|
|
|
||||||
|
|
@ -281,7 +281,7 @@ export default class SwitchController {
|
||||||
|
|
||||||
public async getPorts(): Promise<boolean> {
|
public async getPorts(): Promise<boolean> {
|
||||||
this._send(' terminal length 0')
|
this._send(' terminal length 0')
|
||||||
this._send('show interface status')
|
this._send('show interface')
|
||||||
this._send(' ')
|
this._send(' ')
|
||||||
await this.sleep(2000)
|
await this.sleep(2000)
|
||||||
const statusOutput = this.buffer
|
const statusOutput = this.buffer
|
||||||
|
|
@ -289,17 +289,25 @@ export default class SwitchController {
|
||||||
|
|
||||||
const lines = statusOutput.split('\n')
|
const lines = statusOutput.split('\n')
|
||||||
const ports = this.ports?.length > 0 ? [...this.ports] : []
|
const ports = this.ports?.length > 0 ? [...this.ports] : []
|
||||||
|
|
||||||
for (const line of lines) {
|
for (const line of lines) {
|
||||||
const match = line.match(/^(\S+)\s+(connected|notconnect|disabled|inactive)/i)
|
// Match: "Gi0/1 is up, line protocol is up"
|
||||||
|
const match = line.match(
|
||||||
|
/^(TenGigabitEthernet|GigabitEthernet|FastEthernet|Ethernet)\S*\s+is\s+(\S+),\s+line protocol is\s+(\S+)/i
|
||||||
|
)
|
||||||
if (match) {
|
if (match) {
|
||||||
const name = match[1]
|
const name = match[1] + line.split(' ')[0].replace(match[1], '')
|
||||||
const rawStatus = match[2].toLowerCase()
|
const status1 = match[2].toLowerCase() // up / down / administratively
|
||||||
const status = rawStatus === 'connected' ? 'ON' : 'OFF'
|
const status2 = match[3].toLowerCase() // up / down
|
||||||
|
|
||||||
|
// Rule: interface is considered ON only when both are "up"
|
||||||
|
const status = status1 === 'up' && status2 === 'up' ? 'ON' : 'OFF'
|
||||||
|
|
||||||
const port = ports.find((p) => p.name === name)
|
const port = ports.find((p) => p.name === name)
|
||||||
if (port) {
|
if (port) {
|
||||||
port.status = status
|
port.status = status
|
||||||
} else ports.push({ name, status, poe: 'UNKNOWN' })
|
} else {
|
||||||
|
ports.push({ name, status, poe: 'UNKNOWN' })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -346,6 +346,16 @@ function App() {
|
||||||
}, 100);
|
}, 100);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
socket?.on("running_scenario", (data) => {
|
||||||
|
setTimeout(() => {
|
||||||
|
updateValueLineStation(
|
||||||
|
data?.lineId,
|
||||||
|
{ runningScenario: data?.title || "" },
|
||||||
|
data?.stationId
|
||||||
|
);
|
||||||
|
}, 100);
|
||||||
|
});
|
||||||
|
|
||||||
// ✅ cleanup on unmount or when socket changes
|
// ✅ cleanup on unmount or when socket changes
|
||||||
return () => {
|
return () => {
|
||||||
socket.off("init");
|
socket.off("init");
|
||||||
|
|
@ -359,6 +369,9 @@ function App() {
|
||||||
socket.off("response_content_log");
|
socket.off("response_content_log");
|
||||||
socket.off("data_textfsm");
|
socket.off("data_textfsm");
|
||||||
socket.off("update_ticket");
|
socket.off("update_ticket");
|
||||||
|
socket.off("update_baud");
|
||||||
|
socket.off("line_connecting");
|
||||||
|
socket.off("running_scenario");
|
||||||
};
|
};
|
||||||
}, [socket, stations, selectedLine]);
|
}, [socket, stations, selectedLine]);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -284,6 +284,19 @@ const CardLine = ({
|
||||||
connecting...
|
connecting...
|
||||||
</motion.div>
|
</motion.div>
|
||||||
)}
|
)}
|
||||||
|
{line?.runningScenario && (
|
||||||
|
<motion.div
|
||||||
|
style={{ fontSize: "11px", color: "red" }}
|
||||||
|
animate={{ opacity: [0.2, 1, 0.2] }}
|
||||||
|
transition={{
|
||||||
|
duration: 1.2,
|
||||||
|
repeat: Infinity,
|
||||||
|
ease: "easeInOut",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Running {line?.runningScenario}
|
||||||
|
</motion.div>
|
||||||
|
)}
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex justify={"space-between"} w={"100%"} display={"none"}>
|
<Flex justify={"space-between"} w={"100%"} display={"none"}>
|
||||||
<Box>
|
<Box>
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@ import axios from "axios";
|
||||||
import { notifications } from "@mantine/notifications";
|
import { notifications } from "@mantine/notifications";
|
||||||
import classes from "./Component.module.css";
|
import classes from "./Component.module.css";
|
||||||
import { listBaudDefault } from "../untils/constanst";
|
import { listBaudDefault } from "../untils/constanst";
|
||||||
|
import { motion } from "motion/react";
|
||||||
const apiUrl = import.meta.env.VITE_BACKEND_URL;
|
const apiUrl = import.meta.env.VITE_BACKEND_URL;
|
||||||
|
|
||||||
const INIT_TICKET = {
|
const INIT_TICKET = {
|
||||||
|
|
@ -427,6 +428,34 @@ const ModalTerminal = ({
|
||||||
>
|
>
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.Col span={3}>
|
<Grid.Col span={3}>
|
||||||
|
<Flex style={{ height: "20px" }}>
|
||||||
|
{line?.connecting && (
|
||||||
|
<motion.div
|
||||||
|
style={{ fontSize: "12px", color: "red" }}
|
||||||
|
animate={{ opacity: [0.2, 1, 0.2] }}
|
||||||
|
transition={{
|
||||||
|
duration: 1.2,
|
||||||
|
repeat: Infinity,
|
||||||
|
ease: "easeInOut",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
connecting...
|
||||||
|
</motion.div>
|
||||||
|
)}
|
||||||
|
{line?.runningScenario && (
|
||||||
|
<motion.div
|
||||||
|
style={{ fontSize: "12px", color: "red" }}
|
||||||
|
animate={{ opacity: [0.2, 1, 0.2] }}
|
||||||
|
transition={{
|
||||||
|
duration: 1.2,
|
||||||
|
repeat: Infinity,
|
||||||
|
ease: "easeInOut",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Running {line?.runningScenario}
|
||||||
|
</motion.div>
|
||||||
|
)}
|
||||||
|
</Flex>
|
||||||
<Flex justify={"space-between"} direction={"column"} h={"95%"}>
|
<Flex justify={"space-between"} direction={"column"} h={"95%"}>
|
||||||
<Box>
|
<Box>
|
||||||
<Flex gap={"sm"} justify={"center"} align={"center"}>
|
<Flex gap={"sm"} justify={"center"} align={"center"}>
|
||||||
|
|
|
||||||
|
|
@ -134,7 +134,10 @@ const TerminalCLI: React.FC<TerminalCLIProps> = ({
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (cliOpened && isInit) {
|
if (cliOpened && isInit) {
|
||||||
if (terminal.current)
|
if (terminal.current)
|
||||||
setTimeout(() => terminal.current?.write(content), 200);
|
setTimeout(() => {
|
||||||
|
terminal.current?.write(content);
|
||||||
|
terminal.current?.scrollToBottom();
|
||||||
|
}, 200);
|
||||||
|
|
||||||
if (fitRef.current) setTimeout(() => fitRef.current?.fit(), 500);
|
if (fitRef.current) setTimeout(() => fitRef.current?.fit(), 500);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -101,6 +101,7 @@ export type TLine = {
|
||||||
baud?: number;
|
baud?: number;
|
||||||
tickets?: TDataTicket[];
|
tickets?: TDataTicket[];
|
||||||
connecting?: boolean;
|
connecting?: boolean;
|
||||||
|
runningScenario?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TUser = {
|
export type TUser = {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue