refactor(route-optimizer): enhance layout and structure of optimized routes table in RouteOptimizerPage component
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 1m53s
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 1m53s
This commit is contained in:
@@ -320,80 +320,86 @@ export default function RouteOptimizerPage() {
|
||||
</div>
|
||||
|
||||
<div className="mt-4">
|
||||
<h3 className="mb-3">Оптимизированные маршруты Home -> JumpHost -> Exit по BGP community</h3>
|
||||
<div className="text-muted small mb-3">
|
||||
Таблица показывает лучший полный маршрут для каждой community с учетом рекомендованного
|
||||
gateway на Jumphost.
|
||||
</div>
|
||||
<div className="table-responsive mb-4">
|
||||
<table className="table table-vcenter card-table align-middle" style={OPT_TABLE_STYLE}>
|
||||
<OptimizerColgroup />
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Community</th>
|
||||
<th>Маршрут (Home -> JumpHost -> Exit)</th>
|
||||
<th>Сегменты</th>
|
||||
<th>Gateway / Действие</th>
|
||||
<th>Вероятность</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{communityFullRoutes.length === 0 ? (
|
||||
<tr>
|
||||
<td colSpan={5} className="text-muted">Недостаточно данных для построения полных маршрутов по community.</td>
|
||||
</tr>
|
||||
) : communityFullRoutes.map((r, idx) => (
|
||||
<tr key={`${r.community}-${routeNodeKey(r.home)}-${routeNodeKey(r.jumphost)}-${routeNodeKey(r.exit)}-${idx}`}>
|
||||
<td className="text-break">
|
||||
<div className="fw-semibold">{r.community}</div>
|
||||
{(r.communityInfo?.name || r.communityInfo?.description) && (
|
||||
<div className="small text-muted">{r.communityInfo?.name || r.communityInfo?.description}</div>
|
||||
)}
|
||||
</td>
|
||||
<td className="small text-break">
|
||||
<span className="fw-semibold">{r.home?.label || r.home?.dns || r.home?.ip || 'home'}</span>
|
||||
<span className="text-muted"> → </span>
|
||||
<span className="fw-semibold">{r.jumphost?.label || r.jumphost?.dns || r.jumphost?.ip || 'jumphost'}</span>
|
||||
<span className="text-muted"> → </span>
|
||||
<span className="fw-semibold">{r.exit?.label || r.exit?.dns || r.exit?.ip || 'exit'}</span>
|
||||
</td>
|
||||
<td className="small text-break">
|
||||
<div>
|
||||
H→J: ping {r.homeToJumphost?.pingMs ?? '—'} ms, {fmtSpeed(
|
||||
r.homeToJumphost?.speedDownloadMbps,
|
||||
r.homeToJumphost?.speedUploadMbps,
|
||||
r.homeToJumphost?.speedMbps
|
||||
)}
|
||||
</div>
|
||||
<div className="text-muted">
|
||||
J→E: ping {r.jumphostToExit?.pingMs ?? '—'} ms, {fmtSpeed(
|
||||
r.jumphostToExit?.speedDownloadMbps,
|
||||
r.jumphostToExit?.speedUploadMbps,
|
||||
r.jumphostToExit?.speedMbps
|
||||
)}
|
||||
</div>
|
||||
</td>
|
||||
<td className="small text-break">
|
||||
<div>{r.recommendedGateway || '—'}</div>
|
||||
{r.tunnelGateway && <div className="text-muted">{'->'} {r.tunnelGateway}</div>}
|
||||
<div className="mt-1">
|
||||
{r.pinnedBySettings ? (
|
||||
<span className="badge bg-blue-lt text-blue">pin</span>
|
||||
) : r.shouldSwitch ? (
|
||||
<span className="badge bg-orange-lt text-orange">switch</span>
|
||||
) : (
|
||||
<span className="badge bg-green-lt text-green">ok</span>
|
||||
)}
|
||||
</div>
|
||||
</td>
|
||||
<td className="small">
|
||||
<div>{fmtProb(r.fullRouteProbability)}</div>
|
||||
<div className="text-muted">score {r.fullRouteScore} / conf {r.fullRouteConfidence ?? '—'}</div>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
<div className="card">
|
||||
<div className="card-header">
|
||||
<h3 className="card-title mb-0">Оптимизированные маршруты Home -> JumpHost -> Exit по BGP community</h3>
|
||||
</div>
|
||||
<div className="card-body">
|
||||
<div className="text-muted small mb-3">
|
||||
Таблица показывает лучший полный маршрут для каждой community с учетом рекомендованного
|
||||
gateway на Jumphost.
|
||||
</div>
|
||||
<div className="table-responsive mb-0">
|
||||
<table className="table table-vcenter card-table align-middle" style={OPT_TABLE_STYLE}>
|
||||
<OptimizerColgroup />
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Community</th>
|
||||
<th>Маршрут (Home -> JumpHost -> Exit)</th>
|
||||
<th>Сегменты</th>
|
||||
<th>Gateway / Действие</th>
|
||||
<th>Вероятность</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{communityFullRoutes.length === 0 ? (
|
||||
<tr>
|
||||
<td colSpan={5} className="text-muted">Недостаточно данных для построения полных маршрутов по community.</td>
|
||||
</tr>
|
||||
) : communityFullRoutes.map((r, idx) => (
|
||||
<tr key={`${r.community}-${routeNodeKey(r.home)}-${routeNodeKey(r.jumphost)}-${routeNodeKey(r.exit)}-${idx}`}>
|
||||
<td className="text-break">
|
||||
<div className="fw-semibold">{r.community}</div>
|
||||
{(r.communityInfo?.name || r.communityInfo?.description) && (
|
||||
<div className="small text-muted">{r.communityInfo?.name || r.communityInfo?.description}</div>
|
||||
)}
|
||||
</td>
|
||||
<td className="small text-break">
|
||||
<span className="fw-semibold">{r.home?.label || r.home?.dns || r.home?.ip || 'home'}</span>
|
||||
<span className="text-muted"> → </span>
|
||||
<span className="fw-semibold">{r.jumphost?.label || r.jumphost?.dns || r.jumphost?.ip || 'jumphost'}</span>
|
||||
<span className="text-muted"> → </span>
|
||||
<span className="fw-semibold">{r.exit?.label || r.exit?.dns || r.exit?.ip || 'exit'}</span>
|
||||
</td>
|
||||
<td className="small text-break">
|
||||
<div>
|
||||
H→J: ping {r.homeToJumphost?.pingMs ?? '—'} ms, {fmtSpeed(
|
||||
r.homeToJumphost?.speedDownloadMbps,
|
||||
r.homeToJumphost?.speedUploadMbps,
|
||||
r.homeToJumphost?.speedMbps
|
||||
)}
|
||||
</div>
|
||||
<div className="text-muted">
|
||||
J→E: ping {r.jumphostToExit?.pingMs ?? '—'} ms, {fmtSpeed(
|
||||
r.jumphostToExit?.speedDownloadMbps,
|
||||
r.jumphostToExit?.speedUploadMbps,
|
||||
r.jumphostToExit?.speedMbps
|
||||
)}
|
||||
</div>
|
||||
</td>
|
||||
<td className="small text-break">
|
||||
<div>{r.recommendedGateway || '—'}</div>
|
||||
{r.tunnelGateway && <div className="text-muted">{'->'} {r.tunnelGateway}</div>}
|
||||
<div className="mt-1">
|
||||
{r.pinnedBySettings ? (
|
||||
<span className="badge bg-blue-lt text-blue">pin</span>
|
||||
) : r.shouldSwitch ? (
|
||||
<span className="badge bg-orange-lt text-orange">switch</span>
|
||||
) : (
|
||||
<span className="badge bg-green-lt text-green">ok</span>
|
||||
)}
|
||||
</div>
|
||||
</td>
|
||||
<td className="small">
|
||||
<div>{fmtProb(r.fullRouteProbability)}</div>
|
||||
<div className="text-muted">score {r.fullRouteScore} / conf {r.fullRouteConfidence ?? '—'}</div>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user