feat(route-optimizer): implement community optimization logic and enhance UI for server filters recommendations
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 1m38s
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 1m38s
This commit is contained in:
@@ -43,6 +43,9 @@ export default function RouteOptimizerPage() {
|
||||
}, [load]);
|
||||
|
||||
const homes = Array.isArray(data?.homes) ? data.homes : [];
|
||||
const communityOptimization = Array.isArray(data?.communityOptimizationByJumphost)
|
||||
? data.communityOptimizationByJumphost
|
||||
: [];
|
||||
|
||||
return (
|
||||
<div>
|
||||
@@ -81,7 +84,7 @@ export default function RouteOptimizerPage() {
|
||||
const home = entry.home || {};
|
||||
const routes = Array.isArray(entry.fullRouteCandidates) ? entry.fullRouteCandidates : [];
|
||||
return (
|
||||
<div className="col-12" key={home.id || home.ip || home.dns || Math.random()}>
|
||||
<div className="col-12" key={home.id || home.ip || home.dns || home.label || 'home'}>
|
||||
<div className="card">
|
||||
<div className="card-header d-flex flex-wrap gap-2 align-items-center justify-content-between">
|
||||
<h3 className="card-title mb-0 d-flex align-items-center">
|
||||
@@ -162,6 +165,84 @@ export default function RouteOptimizerPage() {
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
<div className="mt-4">
|
||||
<h3 className="mb-3">Оптимизация по community и filters</h3>
|
||||
<div className="text-muted small mb-3">
|
||||
Рекомендации строятся на основе ваших `server-filters` (`community -> gateway`) и текущих метрик канала
|
||||
`jumphost -> exit`.
|
||||
</div>
|
||||
|
||||
{communityOptimization.length === 0 ? (
|
||||
<div className="alert alert-info">Нет данных по `server-filters` для jumphost.</div>
|
||||
) : (
|
||||
<div className="row g-3">
|
||||
{communityOptimization.map((item) => {
|
||||
const jh = item.jumphost || {};
|
||||
const rows = Array.isArray(item.recommendations) ? item.recommendations : [];
|
||||
return (
|
||||
<div className="col-12" key={jh.id || jh.ip || jh.dns || jh.label || 'jumphost'}>
|
||||
<div className="card">
|
||||
<div className="card-header d-flex flex-wrap align-items-center justify-content-between gap-2">
|
||||
<h3 className="card-title mb-0">
|
||||
Jumphost: {jh.label || jh.dns || jh.ip || 'unknown'}
|
||||
</h3>
|
||||
<MetricBadge label="Communities" value={rows.length} tone="blue" />
|
||||
</div>
|
||||
<div className="card-body">
|
||||
<div className="table-responsive">
|
||||
<table className="table table-vcenter card-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Community</th>
|
||||
<th>Текущий gateway</th>
|
||||
<th>Рекомендуемый gateway</th>
|
||||
<th>Вероятность (тек/реком)</th>
|
||||
<th>Действие</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{rows.length === 0 ? (
|
||||
<tr>
|
||||
<td colSpan={5} className="text-muted">
|
||||
Для этого jumphost нет фильтров.
|
||||
</td>
|
||||
</tr>
|
||||
) : rows.map((r) => (
|
||||
<tr key={`${jh.label}-${r.community}`}>
|
||||
<td>
|
||||
<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">{r.current?.gateway || r.currentGateway || '—'}</td>
|
||||
<td className="small">{r.recommended?.gateway || '—'}</td>
|
||||
<td className="small">
|
||||
{r.current?.probabilityOptimal ?? '—'}% / {r.recommended?.probabilityOptimal ?? '—'}%
|
||||
</td>
|
||||
<td>
|
||||
{r.shouldSwitch ? (
|
||||
<span className="badge bg-orange-lt text-orange">Рекомендовано переключить</span>
|
||||
) : (
|
||||
<span className="badge bg-green-lt text-green">Оставить текущий</span>
|
||||
)}
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user