refactor(MikrotikTools): improve table layout and enhance row display with severity indicators for traceroute results
Publish Fast Tabler Docker image / build-and-push-fast (push) Failing after 3m18s
Publish Fast Tabler Docker image / build-and-push-fast (push) Failing after 3m18s
This commit is contained in:
@@ -464,15 +464,15 @@ function MikrotikTools() {
|
|||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="table-responsive">
|
<div className="table-responsive">
|
||||||
<table className="table table-sm table-hover table-striped mb-0">
|
<table className="table table-vcenter card-table table-hover mb-0">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th style={{ width: 60 }}>Хоп</th>
|
<th style={{ width: 70 }}>Хоп</th>
|
||||||
<th>Адрес / узел</th>
|
<th>Адрес / узел</th>
|
||||||
<th style={{ width: 120 }}>Среднее, мс</th>
|
<th style={{ width: 130 }}>Среднее, мс</th>
|
||||||
<th style={{ width: 120 }}>Мин / Макс, мс</th>
|
<th style={{ width: 140 }}>Мин / Макс, мс</th>
|
||||||
<th style={{ width: 100 }}>Потери</th>
|
<th style={{ width: 110 }}>Потери</th>
|
||||||
<th style={{ width: 160 }}>Статус</th>
|
<th style={{ width: 200 }}>Статус</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@@ -488,19 +488,100 @@ function MikrotikTools() {
|
|||||||
mainLabel = ip || dns || h.host || '—';
|
mainLabel = ip || dns || h.host || '—';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const avg = typeof h.avgMs === 'number' ? h.avgMs : null;
|
||||||
|
const loss = typeof h.loss === 'number' ? h.loss : null;
|
||||||
|
const statusRaw = (h.status || '').toString();
|
||||||
|
const statusLower = statusRaw.toLowerCase();
|
||||||
|
const hasTimeout =
|
||||||
|
statusLower.includes('timeout') ||
|
||||||
|
statusLower.includes('no reply') ||
|
||||||
|
statusLower.includes('unreachable');
|
||||||
|
|
||||||
|
let severity = 'ok';
|
||||||
|
if (hasTimeout || (loss != null && loss >= 50)) {
|
||||||
|
severity = 'danger';
|
||||||
|
} else if ((loss != null && loss > 0) || (avg != null && avg > 200)) {
|
||||||
|
severity = 'warn';
|
||||||
|
}
|
||||||
|
|
||||||
|
const rowClass =
|
||||||
|
severity === 'danger'
|
||||||
|
? 'table-danger'
|
||||||
|
: severity === 'warn'
|
||||||
|
? 'table-warning'
|
||||||
|
: '';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<tr key={h.hop || `${ip || h.host}-${Math.random()}`}>
|
<tr key={h.hop || `${ip || h.host}-${Math.random()}`} className={rowClass}>
|
||||||
<td>{h.hop}</td>
|
<td>
|
||||||
<td>{mainLabel}</td>
|
<span className="badge bg-blue-lt text-blue">
|
||||||
<td>{h.avgMs != null ? h.avgMs.toFixed(1) : '—'}</td>
|
{h.hop}
|
||||||
<td>
|
</span>
|
||||||
{h.bestMs != null ? h.bestMs.toFixed(1) : '—'} /{' '}
|
</td>
|
||||||
{h.worstMs != null ? h.worstMs.toFixed(1) : '—'}
|
<td>
|
||||||
</td>
|
<div className="d-flex flex-column">
|
||||||
<td>{h.loss != null ? `${h.loss}%` : '—'}</td>
|
<span className="fw-semibold text-truncate" title={mainLabel}>
|
||||||
<td>{h.status || '—'}</td>
|
{mainLabel}
|
||||||
</tr>
|
</span>
|
||||||
);})}
|
{ip && dns && (
|
||||||
|
<span className="text-muted small text-truncate" title={ip}>
|
||||||
|
IP: {ip}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{avg != null ? (
|
||||||
|
<span
|
||||||
|
className={
|
||||||
|
avg > 200
|
||||||
|
? 'text-danger fw-semibold'
|
||||||
|
: avg > 120
|
||||||
|
? 'text-warning fw-semibold'
|
||||||
|
: ''
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{avg.toFixed(1)}
|
||||||
|
</span>
|
||||||
|
) : (
|
||||||
|
'—'
|
||||||
|
)}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{h.bestMs != null ? h.bestMs.toFixed(1) : '—'} /{' '}
|
||||||
|
{h.worstMs != null ? h.worstMs.toFixed(1) : '—'}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{loss != null ? (
|
||||||
|
<span
|
||||||
|
className={
|
||||||
|
loss >= 50
|
||||||
|
? 'badge bg-red-lt text-red'
|
||||||
|
: loss > 0
|
||||||
|
? 'badge bg-yellow-lt text-yellow'
|
||||||
|
: 'badge bg-green-lt text-green'
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{loss}%
|
||||||
|
</span>
|
||||||
|
) : (
|
||||||
|
'—'
|
||||||
|
)}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{severity === 'danger' && (
|
||||||
|
<span className="badge bg-red-lt text-red me-1">Проблемный хоп</span>
|
||||||
|
)}
|
||||||
|
{severity === 'warn' && (
|
||||||
|
<span className="badge bg-yellow-lt text-yellow me-1">Возможная проблема</span>
|
||||||
|
)}
|
||||||
|
<span className="text-muted small">
|
||||||
|
{statusRaw || (loss != null || avg != null ? 'OK' : '—')}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
);
|
||||||
|
})}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user