Clear terminal scrollback; format report output
Append a CLEAR_TERMINAL_SCROLL_BACK marker on disconnect and consume it in the frontend to effectively clear terminal scrollback. Backend: add marker on client close and in socket provider, import convertFromKilobytesString and use it to format MEMORY and FLASH values in the report, and compute/list missing ports (separating PoE vs SFP) in the summary HTML. Frontend: emit the marker on line_disconnected and have TerminalXTerm replace the marker with multiple newlines (varying by miniSize) before writing/initializing terminal content to scroll to bottom.
This commit is contained in:
parent
0cc78e8715
commit
7d3c5ad069
|
|
@ -6,6 +6,7 @@ import {
|
||||||
buildBody,
|
buildBody,
|
||||||
classifyLog,
|
classifyLog,
|
||||||
cleanData,
|
cleanData,
|
||||||
|
convertFromKilobytesString,
|
||||||
detectConfigRamByModel,
|
detectConfigRamByModel,
|
||||||
detectScenarioByModel,
|
detectScenarioByModel,
|
||||||
escapeHtml,
|
escapeHtml,
|
||||||
|
|
@ -282,6 +283,7 @@ export default class LineConnection {
|
||||||
this.client.on('close', async () => {
|
this.client.on('close', async () => {
|
||||||
console.log(`[${Date.now()}] 🔌 Line ${lineNumber} disconnected`)
|
console.log(`[${Date.now()}] 🔌 Line ${lineNumber} disconnected`)
|
||||||
this.config.status = 'disconnected'
|
this.config.status = 'disconnected'
|
||||||
|
this.config.output += this.config.output + '[CLEAR_TERMINAL_SCROLL_BACK]'
|
||||||
// this.config.inventory = undefined
|
// this.config.inventory = undefined
|
||||||
this.socketIO.emit('line_disconnected', {
|
this.socketIO.emit('line_disconnected', {
|
||||||
stationId,
|
stationId,
|
||||||
|
|
@ -1693,6 +1695,9 @@ ${log}
|
||||||
|
|
||||||
sendReportSummary = async () => {
|
sendReportSummary = async () => {
|
||||||
const portPhysical = Array.from(this.physicalTest.ports.values())
|
const portPhysical = Array.from(this.physicalTest.ports.values())
|
||||||
|
const missing = portPhysical.filter((p) => !p.tested)
|
||||||
|
const missingPoE = missing.filter((p) => !p.name.includes('SFP'))
|
||||||
|
const missingSFP = missing.filter((p) => p.name.includes('SFP'))
|
||||||
const showVersion = this.config?.data?.find(
|
const showVersion = this.config?.data?.find(
|
||||||
(d) => d.command?.trim()?.includes('show ver') || d.command?.trim()?.includes('sh ver')
|
(d) => d.command?.trim()?.includes('show ver') || d.command?.trim()?.includes('sh ver')
|
||||||
)
|
)
|
||||||
|
|
@ -1718,8 +1723,8 @@ ${log}
|
||||||
Serial Number: <b>${this.config?.inventory?.sn ?? 'N/A'}</b><br/>
|
Serial Number: <b>${this.config?.inventory?.sn ?? 'N/A'}</b><br/>
|
||||||
MAC: <b>${dataShowVersion?.MAC_ADDRESS ?? ''}</b><br/>
|
MAC: <b>${dataShowVersion?.MAC_ADDRESS ?? ''}</b><br/>
|
||||||
IOS: <b>${dataShowVersion?.SOFTWARE_IMAGE ?? ''}</b> <b>${dataShowVersion?.VERSION ?? ''}</b><br/>
|
IOS: <b>${dataShowVersion?.SOFTWARE_IMAGE ?? ''}</b> <b>${dataShowVersion?.VERSION ?? ''}</b><br/>
|
||||||
MEM: <b>${dataShowVersion?.MEMORY ?? ''}</b><br/>
|
MEM: <b>${dataShowVersion?.MEMORY ? convertFromKilobytesString(dataShowVersion?.MEMORY) : ''}</b><br/>
|
||||||
FLASH: <b>${dataShowVersion?.USB_FLASH ?? ''}</b><br/>
|
FLASH: <b>${dataShowVersion?.USB_FLASH ? convertFromKilobytesString(dataShowVersion?.USB_FLASH) : ''}</b><br/>
|
||||||
Licenses: <b>${
|
Licenses: <b>${
|
||||||
dataShowLic
|
dataShowLic
|
||||||
? dataShowLic
|
? dataShowLic
|
||||||
|
|
@ -1735,6 +1740,23 @@ ${log}
|
||||||
Total Ports: ${portPhysical?.length}<br/>
|
Total Ports: ${portPhysical?.length}<br/>
|
||||||
Ports Tested (Link UP): <b style="color: #008000;">${portPhysical.filter((p) => p.tested).length}</b><br/>
|
Ports Tested (Link UP): <b style="color: #008000;">${portPhysical.filter((p) => p.tested).length}</b><br/>
|
||||||
Ports Missing/Down: <b style="color: #ff0000;">${portPhysical.filter((p) => !p.tested).length}</b><br/>
|
Ports Missing/Down: <b style="color: #ff0000;">${portPhysical.filter((p) => !p.tested).length}</b><br/>
|
||||||
|
${
|
||||||
|
missingPoE?.length
|
||||||
|
? `
|
||||||
|
<br/><b style="color: #ff0000;">Ports Missing PoE</b><br/>
|
||||||
|
────────────────────────────────<br/>
|
||||||
|
<div style="column-count: 12;">${missingPoE.map((p) => this.physicalTest.normalizePortName(p.name)).join('<br/>')}</div>
|
||||||
|
`
|
||||||
|
: ''
|
||||||
|
}
|
||||||
|
${
|
||||||
|
missingSFP?.length
|
||||||
|
? `
|
||||||
|
<br/><b style="color: #ff0000;">Ports Missing SFP</b><br/>
|
||||||
|
────────────────────────────────<br/>
|
||||||
|
<div style="column-count: 12;">${missingSFP.map((p) => this.physicalTest.normalizePortName(p.name)).join('<br/>')}</div>`
|
||||||
|
: ''
|
||||||
|
}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>`
|
</table>`
|
||||||
|
|
|
||||||
|
|
@ -140,6 +140,7 @@ export class WebSocketIo {
|
||||||
if (config.status !== 'connected') {
|
if (config.status !== 'connected') {
|
||||||
config.runningScenario = ''
|
config.runningScenario = ''
|
||||||
config.runningPhysical = false
|
config.runningPhysical = false
|
||||||
|
config.output = config.output + '[CLEAR_TERMINAL_SCROLL_BACK]'
|
||||||
}
|
}
|
||||||
return config
|
return config
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -250,7 +250,12 @@ function App() {
|
||||||
socket.on("line_disconnected", (data) =>
|
socket.on("line_disconnected", (data) =>
|
||||||
updateValueLineStation(
|
updateValueLineStation(
|
||||||
data?.lineId,
|
data?.lineId,
|
||||||
{ status: data.status, connecting: false },
|
{
|
||||||
|
status: data.status,
|
||||||
|
connecting: false,
|
||||||
|
netOutput: "[CLEAR_TERMINAL_SCROLL_BACK]",
|
||||||
|
output: "[CLEAR_TERMINAL_SCROLL_BACK]",
|
||||||
|
},
|
||||||
data?.stationId
|
data?.stationId
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -142,7 +142,13 @@ const TerminalCLI: React.FC<TerminalCLIProps> = ({
|
||||||
if (cliOpened && isInit) {
|
if (cliOpened && isInit) {
|
||||||
if (terminal.current)
|
if (terminal.current)
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
terminal.current?.write(content);
|
const valueContent = content.replaceAll(
|
||||||
|
"[CLEAR_TERMINAL_SCROLL_BACK]",
|
||||||
|
Array(miniSize ? 20 : 70)
|
||||||
|
.fill("\r\n")
|
||||||
|
.join("")
|
||||||
|
);
|
||||||
|
terminal.current?.write(valueContent);
|
||||||
terminal.current?.scrollToBottom();
|
terminal.current?.scrollToBottom();
|
||||||
}, 200);
|
}, 200);
|
||||||
|
|
||||||
|
|
@ -166,7 +172,13 @@ const TerminalCLI: React.FC<TerminalCLIProps> = ({
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!loading && !isInit) {
|
if (!loading && !isInit) {
|
||||||
if (terminal.current) {
|
if (terminal.current) {
|
||||||
terminal.current?.write(initContent);
|
const valueContent = initContent.replaceAll(
|
||||||
|
"[CLEAR_TERMINAL_SCROLL_BACK]",
|
||||||
|
Array(miniSize ? 20 : 70)
|
||||||
|
.fill("\r\n")
|
||||||
|
.join("")
|
||||||
|
);
|
||||||
|
terminal.current?.write(valueContent);
|
||||||
setIsInit(true);
|
setIsInit(true);
|
||||||
if (!miniSize && !isDisabled) terminal.current?.focus();
|
if (!miniSize && !isDisabled) terminal.current?.focus();
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue