|
|
|
@ -545,10 +545,11 @@ export default class LineConnection {
|
|
|
|
if (
|
|
|
|
if (
|
|
|
|
['show inventory', 'sh inventory', 'show inv', 'sh inv'].includes(item.command)
|
|
|
|
['show inventory', 'sh inventory', 'show inv', 'sh inv'].includes(item.command)
|
|
|
|
) {
|
|
|
|
) {
|
|
|
|
const dataInventory = JSON.parse(item.textfsm)[0]
|
|
|
|
const listInventory = JSON.parse(item.textfsm)
|
|
|
|
|
|
|
|
const dataInventory = listInventory[0]
|
|
|
|
this.config.inventory = this.config.inventory
|
|
|
|
this.config.inventory = this.config.inventory
|
|
|
|
? { ...this.config.inventory, ...dataInventory }
|
|
|
|
? { ...this.config.inventory, ...dataInventory, listInventory }
|
|
|
|
: dataInventory
|
|
|
|
: { ...dataInventory, listInventory }
|
|
|
|
pid = dataInventory?.pid || ''
|
|
|
|
pid = dataInventory?.pid || ''
|
|
|
|
this.addHistory(this.config.stationId, this.config.id, {
|
|
|
|
this.addHistory(this.config.stationId, this.config.id, {
|
|
|
|
id: this.config.id,
|
|
|
|
id: this.config.id,
|
|
|
|
@ -807,9 +808,10 @@ export default class LineConnection {
|
|
|
|
data.forEach((item) => {
|
|
|
|
data.forEach((item) => {
|
|
|
|
if (item?.textfsm && isValidJson(item?.textfsm)) {
|
|
|
|
if (item?.textfsm && isValidJson(item?.textfsm)) {
|
|
|
|
if (['show inventory', 'sh inventory', 'show inv', 'sh inv'].includes(item.command)) {
|
|
|
|
if (['show inventory', 'sh inventory', 'show inv', 'sh inv'].includes(item.command)) {
|
|
|
|
const dataInventory = JSON.parse(item.textfsm)[0]
|
|
|
|
const listInventory = JSON.parse(item.textfsm)
|
|
|
|
|
|
|
|
const dataInventory = listInventory[0]
|
|
|
|
this.config.inventory = this.config.inventory
|
|
|
|
this.config.inventory = this.config.inventory
|
|
|
|
? { ...this.config.inventory, ...dataInventory }
|
|
|
|
? { ...this.config.inventory, ...dataInventory, listInventory }
|
|
|
|
: dataInventory
|
|
|
|
: dataInventory
|
|
|
|
}
|
|
|
|
}
|
|
|
|
item.textfsm = JSON.parse(item.textfsm)
|
|
|
|
item.textfsm = JSON.parse(item.textfsm)
|
|
|
|
@ -1164,7 +1166,7 @@ Ports Missing/Down: ${missing.length}\n\n`
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* Starting physical test (PoE ports testing)
|
|
|
|
* Starting physical test (PoE ports testing)
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
async runPhysicalTest() {
|
|
|
|
async runPhysicalTest(userName?: string) {
|
|
|
|
if (this.config.runningPhysical) {
|
|
|
|
if (this.config.runningPhysical) {
|
|
|
|
console.log('Running physical test')
|
|
|
|
console.log('Running physical test')
|
|
|
|
return
|
|
|
|
return
|
|
|
|
@ -1964,13 +1966,13 @@ Ports Missing/Down: ${missing.length}\n\n`
|
|
|
|
: '—'
|
|
|
|
: '—'
|
|
|
|
|
|
|
|
|
|
|
|
// ---- Template-fallback values (use file's hardcoded content when no real data) ----
|
|
|
|
// ---- Template-fallback values (use file's hardcoded content when no real data) ----
|
|
|
|
const productName = 'Cisco Catalyst 9300-48P-A'
|
|
|
|
const productName = escapeHtml(String(config?.inventory?.name || ''))
|
|
|
|
const productPN = escapeHtml(String(config?.inventory?.pid || 'C9300-48P-A'))
|
|
|
|
const productPN = escapeHtml(String(config?.inventory?.pid || ''))
|
|
|
|
const productSN = escapeHtml(String(config?.inventory?.sn || 'FCW2425L0KP'))
|
|
|
|
const productSN = escapeHtml(String(config?.inventory?.sn || ''))
|
|
|
|
const productVid = escapeHtml(String(config?.inventory?.vid || 'V02'))
|
|
|
|
const productVid = escapeHtml(String(config?.inventory?.vid || ''))
|
|
|
|
const iosVersion = escapeHtml(String(dataShowVersion?.VERSION || '17.09.04a'))
|
|
|
|
const iosVersion = escapeHtml(String(dataShowVersion?.VERSION || ''))
|
|
|
|
const memDisplay = escapeHtml(memText !== '—' ? memText : '8 GB')
|
|
|
|
const memDisplay = escapeHtml(memText !== '—' ? memText : '')
|
|
|
|
const flashDisplay = escapeHtml(flashText !== '—' ? flashText : '16 GB')
|
|
|
|
const flashDisplay = escapeHtml(flashText !== '—' ? flashText : '')
|
|
|
|
|
|
|
|
|
|
|
|
// AI issue rows (one per real AI issue, fall back to file's hardcoded row when none)
|
|
|
|
// AI issue rows (one per real AI issue, fall back to file's hardcoded row when none)
|
|
|
|
const aiIssueRowsHtml =
|
|
|
|
const aiIssueRowsHtml =
|
|
|
|
@ -1988,6 +1990,7 @@ Ports Missing/Down: ${missing.length}\n\n`
|
|
|
|
const licenseBoxesHtml =
|
|
|
|
const licenseBoxesHtml =
|
|
|
|
dataShowLic && dataShowLic.length > 0
|
|
|
|
dataShowLic && dataShowLic.length > 0
|
|
|
|
? dataShowLic
|
|
|
|
? dataShowLic
|
|
|
|
|
|
|
|
.filter((l) => l.LICENSE_TYPE && l.FEATURE)
|
|
|
|
.map(
|
|
|
|
.map(
|
|
|
|
(l: any) =>
|
|
|
|
(l: any) =>
|
|
|
|
`<div style="background:#f9fafb;border:1px solid #f0f1f3;border-radius:6px;padding:8px 12px;margin-bottom:6px;"><div style="font-weight:700;color:#3b82f6;font-size:13px;">${escapeHtml(String(l.FEATURE || ''))}</div><div style="font-size:10px;color:#9ca3af;">${escapeHtml(String(l.LICENSE_TYPE || ''))}${l.STATUS ? ' · ' + escapeHtml(String(l.STATUS)) : ''}</div></div>`
|
|
|
|
`<div style="background:#f9fafb;border:1px solid #f0f1f3;border-radius:6px;padding:8px 12px;margin-bottom:6px;"><div style="font-weight:700;color:#3b82f6;font-size:13px;">${escapeHtml(String(l.FEATURE || ''))}</div><div style="font-size:10px;color:#9ca3af;">${escapeHtml(String(l.LICENSE_TYPE || ''))}${l.STATUS ? ' · ' + escapeHtml(String(l.STATUS)) : ''}</div></div>`
|
|
|
|
@ -1997,8 +2000,8 @@ Ports Missing/Down: ${missing.length}\n\n`
|
|
|
|
|
|
|
|
|
|
|
|
// Port stat values (real numbers if any port data, else file's defaults)
|
|
|
|
// Port stat values (real numbers if any port data, else file's defaults)
|
|
|
|
const hasPortData = portPhysical.length > 0
|
|
|
|
const hasPortData = portPhysical.length > 0
|
|
|
|
const poeText = hasPortData ? `${testedPoE.length}/${totalPoE}` : '48/48'
|
|
|
|
const poeText = hasPortData ? `${testedPoE.length}/${totalPoE}` : '0/0'
|
|
|
|
const sfpText = hasPortData ? `${testedSFP.length}/${totalSFP}` : '4/4'
|
|
|
|
const sfpText = hasPortData ? `${testedSFP.length}/${totalSFP}` : '0/0'
|
|
|
|
const poeColor =
|
|
|
|
const poeColor =
|
|
|
|
!hasPortData || (totalPoE > 0 && testedPoE.length === totalPoE) ? '#10b981' : '#f59e0b'
|
|
|
|
!hasPortData || (totalPoE > 0 && testedPoE.length === totalPoE) ? '#10b981' : '#f59e0b'
|
|
|
|
const sfpColor =
|
|
|
|
const sfpColor =
|
|
|
|
@ -2104,7 +2107,7 @@ Ports Missing/Down: ${missing.length}\n\n`
|
|
|
|
<table cellpadding="0" cellspacing="0" border="0" width="100%">
|
|
|
|
<table cellpadding="0" cellspacing="0" border="0" width="100%">
|
|
|
|
<tr>
|
|
|
|
<tr>
|
|
|
|
<td width="50%" valign="top" style="padding-right:5px;">
|
|
|
|
<td width="50%" valign="top" style="padding-right:5px;">
|
|
|
|
<table cellpadding="0" cellspacing="0" border="0" height="265px" width="100%" style="background:#fff;border:1px solid #e5e7eb;border-radius:10px;border-collapse:separate;">
|
|
|
|
<table cellpadding="0" cellspacing="0" border="0" height="265px" width="100%" style="background:#fff;border:1px solid #e5e7eb;border-radius:10px;border-collapse:separate; font-size:14px;">
|
|
|
|
<tr><td style="padding:16px 20px;">
|
|
|
|
<tr><td style="padding:16px 20px;">
|
|
|
|
<div style="font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.8px;color:#9ca3af;padding-bottom:7px;border-bottom:1px solid #f0f1f3;margin-bottom:8px;">Product Info</div>
|
|
|
|
<div style="font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.8px;color:#9ca3af;padding-bottom:7px;border-bottom:1px solid #f0f1f3;margin-bottom:8px;">Product Info</div>
|
|
|
|
<table cellpadding="0" cellspacing="0" border="0" width="100%">
|
|
|
|
<table cellpadding="0" cellspacing="0" border="0" width="100%">
|
|
|
|
@ -2220,26 +2223,64 @@ Ports Missing/Down: ${missing.length}\n\n`
|
|
|
|
<table cellpadding="0" cellspacing="0" border="0" width="100%" style="background:#fff;border:1px solid #e5e7eb;border-radius:10px;border-collapse:separate;">
|
|
|
|
<table cellpadding="0" cellspacing="0" border="0" width="100%" style="background:#fff;border:1px solid #e5e7eb;border-radius:10px;border-collapse:separate;">
|
|
|
|
<tr><td style="padding:16px 20px;">
|
|
|
|
<tr><td style="padding:16px 20px;">
|
|
|
|
<table cellpadding="0" cellspacing="0" border="0" width="100%">
|
|
|
|
<table cellpadding="0" cellspacing="0" border="0" width="100%">
|
|
|
|
|
|
|
|
<!-- line -->
|
|
|
|
|
|
|
|
<tbody style="position:relative; z-index:0;">
|
|
|
|
<tr>
|
|
|
|
<tr>
|
|
|
|
<td width="33%" align="center" style="padding:4px;">
|
|
|
|
<td colspan="3" style="padding:0 55px;">
|
|
|
|
<div style="display:inline-block;width:26px;height:26px;background:#fff;border:2px solid #10b981;border-radius:50%;color:#10b981;font-size:14px;font-weight:800;line-height:22px;text-align:center;margin-bottom:8px;">✓</div>
|
|
|
|
<div style="height:2px;background:#e2e8f0;font-size:0;line-height:0; position:absolute; z-index:-1; width: 90%; top: 12px;">
|
|
|
|
<div style="font-size:10px;font-weight:700;text-transform:uppercase;color:#5f6978;margin-bottom:2px;">Received</div>
|
|
|
|
|
|
|
|
<div style="font-size:11px;font-weight:600;color:#1a1d23;">Trung Nguyen</div>
|
|
|
|
</div>
|
|
|
|
<div style="font-size:10px;color:#9ca3af;">06 May 10:30</div>
|
|
|
|
|
|
|
|
</td>
|
|
|
|
|
|
|
|
<td width="33%" align="center" style="padding:4px;">
|
|
|
|
|
|
|
|
<div style="display:inline-block;width:26px;height:26px;background:#fff;border:2px solid #10b981;border-radius:50%;color:#10b981;font-size:14px;font-weight:800;line-height:22px;text-align:center;margin-bottom:8px;">✓</div>
|
|
|
|
|
|
|
|
<div style="font-size:10px;font-weight:700;text-transform:uppercase;color:#5f6978;margin-bottom:2px;">Physical Check</div>
|
|
|
|
|
|
|
|
<div style="font-size:11px;font-weight:600;color:#1a1d23;">Khanh Le</div>
|
|
|
|
|
|
|
|
<div style="font-size:10px;color:#9ca3af;">06 May 11:15</div>
|
|
|
|
|
|
|
|
</td>
|
|
|
|
|
|
|
|
<td width="34%" align="center" style="padding:4px;">
|
|
|
|
|
|
|
|
<div style="display:inline-block;width:26px;height:26px;background:#fff;border:2px solid #10b981;border-radius:50%;color:#10b981;font-size:14px;font-weight:800;line-height:22px;text-align:center;margin-bottom:8px;">✓</div>
|
|
|
|
|
|
|
|
<div style="font-size:10px;font-weight:700;text-transform:uppercase;color:#5f6978;margin-bottom:2px;">Software Test</div>
|
|
|
|
|
|
|
|
<div style="font-size:11px;font-weight:600;color:#1a1d23;">Duy Pham (remote)</div>
|
|
|
|
|
|
|
|
<div style="font-size:10px;color:#9ca3af;">06 May 14:00</div>
|
|
|
|
|
|
|
|
</td>
|
|
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
</tr>
|
|
|
|
|
|
|
|
<!-- steps -->
|
|
|
|
|
|
|
|
<tr>
|
|
|
|
|
|
|
|
<!-- Step 1 -->
|
|
|
|
|
|
|
|
<td width="33%" align="center" valign="top" style="padding:0 4px 4px 4px;">
|
|
|
|
|
|
|
|
<div style="display:inline-block;width:26px;height:26px;background:#fff;border:2px solid #10b981;border-radius:50%;color:#10b981;font-size:14px;font-weight:800;line-height:22px;text-align:center;margin-top:-14px;margin-bottom:8px;">
|
|
|
|
|
|
|
|
✓
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div style="font-size:10px;font-weight:700;text-transform:uppercase;color:#5f6978;margin-bottom:2px;">
|
|
|
|
|
|
|
|
Received
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div style="font-size:11px;font-weight:600;color:#1a1d23;">
|
|
|
|
|
|
|
|
Trung Nguyen
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div style="font-size:10px;color:#9ca3af;">
|
|
|
|
|
|
|
|
06 May 10:30
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</td>
|
|
|
|
|
|
|
|
<!-- Step 2 -->
|
|
|
|
|
|
|
|
<td width="33%" align="center" valign="top" style="padding:0 4px 4px 4px;">
|
|
|
|
|
|
|
|
<div style="display:inline-block;width:26px;height:26px;background:#fff;border:2px solid #10b981;border-radius:50%;color:#10b981;font-size:14px;font-weight:800;line-height:22px;text-align:center;margin-top:-14px;margin-bottom:8px;">
|
|
|
|
|
|
|
|
✓
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div style="font-size:10px;font-weight:700;text-transform:uppercase;color:#5f6978;margin-bottom:2px;">
|
|
|
|
|
|
|
|
Physical Check
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div style="font-size:11px;font-weight:600;color:#1a1d23;">
|
|
|
|
|
|
|
|
Khanh Le
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div style="font-size:10px;color:#9ca3af;">
|
|
|
|
|
|
|
|
06 May 11:15
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</td>
|
|
|
|
|
|
|
|
<!-- Step 3 -->
|
|
|
|
|
|
|
|
<td width="34%" align="center" valign="top" style="padding:0 4px 4px 4px;">
|
|
|
|
|
|
|
|
<div style="display:inline-block;width:26px;height:26px;background:#fff;border:2px solid #10b981;border-radius:50%;color:#10b981;font-size:14px;font-weight:800;line-height:22px;text-align:center;margin-top:-14px;margin-bottom:8px;">
|
|
|
|
|
|
|
|
✓
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div style="font-size:10px;font-weight:700;text-transform:uppercase;color:#5f6978;margin-bottom:2px;">
|
|
|
|
|
|
|
|
Software Test
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div style="font-size:11px;font-weight:600;color:#1a1d23;">
|
|
|
|
|
|
|
|
Duy Pham (remote)
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div style="font-size:10px;color:#9ca3af;">
|
|
|
|
|
|
|
|
06 May 14:00
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</td>
|
|
|
|
|
|
|
|
</tr></tbody>
|
|
|
|
</table>
|
|
|
|
</table>
|
|
|
|
</td></tr>
|
|
|
|
</td></tr>
|
|
|
|
</table>
|
|
|
|
</table>
|
|
|
|
@ -2310,10 +2351,14 @@ Ports Missing/Down: ${missing.length}\n\n`
|
|
|
|
<td width="33%" valign="top" style="padding-right:8px;">
|
|
|
|
<td width="33%" valign="top" style="padding-right:8px;">
|
|
|
|
<div style="font-size:10px;font-weight:700;text-transform:uppercase;color:#9ca3af;letter-spacing:.5px;margin-bottom:8px;">Hardware Inventory</div>
|
|
|
|
<div style="font-size:10px;font-weight:700;text-transform:uppercase;color:#9ca3af;letter-spacing:.5px;margin-bottom:8px;">Hardware Inventory</div>
|
|
|
|
<table cellpadding="0" cellspacing="0" border="0" width="100%" style="font-size:11px;">
|
|
|
|
<table cellpadding="0" cellspacing="0" border="0" width="100%" style="font-size:11px;">
|
|
|
|
<tr><td style="padding:2px 0;border-bottom:1px solid #f0f1f3;font-weight:600;color:#5f6978;">${productPN}</td><td style="padding:2px 0;border-bottom:1px solid #f0f1f3;font-family:Consolas,monospace;color:#9ca3af;text-align:right;">${productSN}</td></tr>
|
|
|
|
${
|
|
|
|
<tr><td style="padding:2px 0;border-bottom:1px solid #f0f1f3;font-weight:600;color:#5f6978;">PWR-C1-715WAC-P</td><td style="padding:2px 0;border-bottom:1px solid #f0f1f3;font-family:Consolas,monospace;color:#9ca3af;text-align:right;">LIT241525W1</td></tr>
|
|
|
|
this.config?.inventory?.listInventory
|
|
|
|
<tr><td style="padding:2px 0;border-bottom:1px solid #f0f1f3;font-weight:600;color:#5f6978;">C9300-NM-4G</td><td style="padding:2px 0;border-bottom:1px solid #f0f1f3;font-family:Consolas,monospace;color:#9ca3af;text-align:right;">FDO2420H0X1</td></tr>
|
|
|
|
?.map(
|
|
|
|
<tr><td style="padding:2px 0;font-weight:600;color:#5f6978;">FAN-T2-GEN2 (x3)</td><td style="padding:2px 0;font-family:Consolas,monospace;color:#9ca3af;text-align:right;">OK</td></tr>
|
|
|
|
(item: any) => `
|
|
|
|
|
|
|
|
<tr><td style="padding:2px 0;border-bottom:1px solid #f0f1f3;font-weight:600;color:#5f6978;">${item.pid}</td><td style="padding:2px 0;border-bottom:1px solid #f0f1f3;font-family:Consolas,monospace;color:#9ca3af;text-align:right;">${item.sn}</td></tr>`
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
.join('') || ''
|
|
|
|
|
|
|
|
}
|
|
|
|
</table>
|
|
|
|
</table>
|
|
|
|
</td>
|
|
|
|
</td>
|
|
|
|
<td width="33%" valign="top" style="padding:0 4px;">
|
|
|
|
<td width="33%" valign="top" style="padding:0 4px;">
|
|
|
|
@ -2328,8 +2373,8 @@ Ports Missing/Down: ${missing.length}\n\n`
|
|
|
|
<td width="50%" style="padding:0 0 6px 3px;"><table cellpadding="0" cellspacing="0" border="0" width="100%" style="background:#f8fafc;border:1px solid #e2e8f0;border-radius:6px;border-collapse:separate;"><tr><td align="center" style="padding:6px;"><div style="font-weight:800;font-size:14px;color:${sfpColor};">${escapeHtml(sfpText)}</div><div style="font-size:9px;font-weight:600;color:#9ca3af;text-transform:uppercase;">SFP+ UP</div></td></tr></table></td>
|
|
|
|
<td width="50%" style="padding:0 0 6px 3px;"><table cellpadding="0" cellspacing="0" border="0" width="100%" style="background:#f8fafc;border:1px solid #e2e8f0;border-radius:6px;border-collapse:separate;"><tr><td align="center" style="padding:6px;"><div style="font-weight:800;font-size:14px;color:${sfpColor};">${escapeHtml(sfpText)}</div><div style="font-size:9px;font-weight:600;color:#9ca3af;text-transform:uppercase;">SFP+ UP</div></td></tr></table></td>
|
|
|
|
</tr>
|
|
|
|
</tr>
|
|
|
|
<tr>
|
|
|
|
<tr>
|
|
|
|
<td width="50%" style="padding:0 3px 0 0;"><table cellpadding="0" cellspacing="0" border="0" width="100%" style="background:#f8fafc;border:1px solid #e2e8f0;border-radius:6px;border-collapse:separate;"><tr><td align="center" style="padding:6px;"><div style="font-weight:800;font-size:14px;color:#10b981;">${missingSFP.length > 0 || missingPoE.length > 0 ? 'FAIL' : 'PASS'}</div><div style="font-size:9px;font-weight:600;color:#9ca3af;text-transform:uppercase;">PoE+ Test</div></td></tr></table></td>
|
|
|
|
<td width="50%" style="padding:0 3px 0 0;"><table cellpadding="0" cellspacing="0" border="0" width="100%" style="background:#f8fafc;border:1px solid #e2e8f0;border-radius:6px;border-collapse:separate;"><tr><td align="center" style="padding:6px;"><div style="font-weight:800;font-size:14px;color: ${missingSFP.length > 0 || missingPoE.length > 0 ? '#dc2626' : '#10b981'};">${missingSFP.length > 0 || missingPoE.length > 0 ? 'FAIL' : 'PASS'}</div><div style="font-size:9px;font-weight:600;color:#9ca3af;text-transform:uppercase;">PoE+ Test</div></td></tr></table></td>
|
|
|
|
<td width="50%" style="padding:0 0 0 3px;"><table cellpadding="0" cellspacing="0" border="0" width="100%" style="background:#f8fafc;border:1px solid #e2e8f0;border-radius:6px;border-collapse:separate;"><tr><td align="center" style="padding:6px;"><div style="font-weight:800;font-size:14px;color:#10b981;">${Math.round(((totalPoE + totalSFP - (missingPoE.length + missingSFP.length)) / (totalPoE + totalSFP)) * 100)}%</div><div style="font-size:9px;font-weight:600;color:#9ca3af;text-transform:uppercase;">Throughput</div></td></tr></table></td>
|
|
|
|
<td width="50%" style="padding:0 0 0 3px;"><table cellpadding="0" cellspacing="0" border="0" width="100%" style="background:#f8fafc;border:1px solid #e2e8f0;border-radius:6px;border-collapse:separate;"><tr><td align="center" style="padding:6px;"><div style="font-weight:800;font-size:14px;color: ${missingSFP.length > 0 || missingPoE.length > 0 ? '#dc2626' : '#10b981'};">${totalPoE + totalSFP === 0 ? 100 : Math.round(((totalPoE + totalSFP - (missingPoE.length + missingSFP.length)) / (totalPoE + totalSFP)) * 100)}%</div><div style="font-size:9px;font-weight:600;color:#9ca3af;text-transform:uppercase;">Throughput</div></td></tr></table></td>
|
|
|
|
</tr>
|
|
|
|
</tr>
|
|
|
|
</table>
|
|
|
|
</table>
|
|
|
|
${missingDetailsHtml}
|
|
|
|
${missingDetailsHtml}
|
|
|
|
@ -2340,7 +2385,7 @@ Ports Missing/Down: ${missing.length}\n\n`
|
|
|
|
<!-- CONSOLE RAW OUTPUT -->
|
|
|
|
<!-- CONSOLE RAW OUTPUT -->
|
|
|
|
<table cellpadding="0" cellspacing="0" border="0" width="100%" style="margin-top:16px;background:#1e293b;border-radius:6px;border:1px solid #334155;border-collapse:separate;">
|
|
|
|
<table cellpadding="0" cellspacing="0" border="0" width="100%" style="margin-top:16px;background:#1e293b;border-radius:6px;border:1px solid #334155;border-collapse:separate;">
|
|
|
|
<tr><td style="padding:6px 12px;background:#334155;color:#94a3b8;font-size:10px;font-weight:700;letter-spacing:.5px;border-radius:6px 6px 0 0;">CONSOLE RAW OUTPUT (Boot Log snippet)</td></tr>
|
|
|
|
<tr><td style="padding:6px 12px;background:#334155;color:#94a3b8;font-size:10px;font-weight:700;letter-spacing:.5px;border-radius:6px 6px 0 0;">CONSOLE RAW OUTPUT (Boot Log snippet)</td></tr>
|
|
|
|
<tr><pre style="overflow-y: auto; max-height: 300px; padding:12px;color:#cbd5e1;font-family:Consolas,'Courier New',monospace;font-size:11px;line-height:1.6;white-space:pre-wrap;word-break:break-all;">${snapshot?.outputTestLog || 'No test log available'}</pre></tr>
|
|
|
|
<tr><td><pre style="overflow-y: auto; max-height: 300px; padding:12px;color:#cbd5e1;font-family:Consolas,'Courier New',monospace;font-size:11px;line-height:1.6;white-space:pre-wrap;word-break:break-all;">${snapshot?.outputTestLog || 'No test log available'}</pre></td></tr>
|
|
|
|
</table>
|
|
|
|
</table>
|
|
|
|
</td></tr>
|
|
|
|
</td></tr>
|
|
|
|
</table>
|
|
|
|
</table>
|
|
|
|
|