feat(route-optimizer): add country and interface name display in route optimization UI
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 1m33s
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 1m33s
This commit is contained in:
@@ -114,6 +114,7 @@ function compactServer(server) {
|
|||||||
ip: server?.ip || null,
|
ip: server?.ip || null,
|
||||||
dns: server?.dns || null,
|
dns: server?.dns || null,
|
||||||
type: server?.type || null,
|
type: server?.type || null,
|
||||||
|
country: server?.country || null,
|
||||||
label: server?.dns || server?.ip || server?.id || 'unknown',
|
label: server?.dns || server?.ip || server?.id || 'unknown',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -482,6 +483,7 @@ function buildRecursiveGatewayOptionsForJumphost({
|
|||||||
recursiveGatewayId: rgw.id || null,
|
recursiveGatewayId: rgw.id || null,
|
||||||
recursiveDescription: rgw.description || '',
|
recursiveDescription: rgw.description || '',
|
||||||
tunnelGatewayIp: best.physicalGatewayIp,
|
tunnelGatewayIp: best.physicalGatewayIp,
|
||||||
|
interfaceName: best.candidate.interfaceName || null,
|
||||||
distance: best.distance,
|
distance: best.distance,
|
||||||
exit: best.candidate.exit,
|
exit: best.candidate.exit,
|
||||||
baseScore: best.candidate.score,
|
baseScore: best.candidate.score,
|
||||||
@@ -574,6 +576,7 @@ function buildCommunityOptimization({
|
|||||||
current: currentCandidate ? {
|
current: currentCandidate ? {
|
||||||
gateway: currentCandidate.recursiveGateway || currentCandidate.gatewayIpForJumphost || null,
|
gateway: currentCandidate.recursiveGateway || currentCandidate.gatewayIpForJumphost || null,
|
||||||
tunnelGateway: currentCandidate.tunnelGatewayIp || currentCandidate.gatewayIpForJumphost || null,
|
tunnelGateway: currentCandidate.tunnelGatewayIp || currentCandidate.gatewayIpForJumphost || null,
|
||||||
|
interfaceName: currentCandidate.interfaceName || null,
|
||||||
distance: currentCandidate.distance != null ? currentCandidate.distance : null,
|
distance: currentCandidate.distance != null ? currentCandidate.distance : null,
|
||||||
exit: currentCandidate.exit,
|
exit: currentCandidate.exit,
|
||||||
score: currentCandidate.score,
|
score: currentCandidate.score,
|
||||||
@@ -584,6 +587,7 @@ function buildCommunityOptimization({
|
|||||||
recommended: recommendedCandidate ? {
|
recommended: recommendedCandidate ? {
|
||||||
gateway: recommendedCandidate.recursiveGateway || recommendedCandidate.gatewayIpForJumphost || null,
|
gateway: recommendedCandidate.recursiveGateway || recommendedCandidate.gatewayIpForJumphost || null,
|
||||||
tunnelGateway: recommendedCandidate.tunnelGatewayIp || recommendedCandidate.gatewayIpForJumphost || null,
|
tunnelGateway: recommendedCandidate.tunnelGatewayIp || recommendedCandidate.gatewayIpForJumphost || null,
|
||||||
|
interfaceName: recommendedCandidate.interfaceName || null,
|
||||||
distance: recommendedCandidate.distance != null ? recommendedCandidate.distance : null,
|
distance: recommendedCandidate.distance != null ? recommendedCandidate.distance : null,
|
||||||
exit: recommendedCandidate.exit,
|
exit: recommendedCandidate.exit,
|
||||||
score: recommendedCandidate.score,
|
score: recommendedCandidate.score,
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import {
|
|||||||
} from '@tabler/icons-react';
|
} from '@tabler/icons-react';
|
||||||
import api from './lib/api.js';
|
import api from './lib/api.js';
|
||||||
import PageHeader from './components/PageHeader.jsx';
|
import PageHeader from './components/PageHeader.jsx';
|
||||||
|
import { countryToFlag } from './utils/serverUtils.js';
|
||||||
|
|
||||||
function MetricBadge({ label, value, tone = 'secondary' }) {
|
function MetricBadge({ label, value, tone = 'secondary' }) {
|
||||||
return (
|
return (
|
||||||
@@ -237,6 +238,12 @@ export default function RouteOptimizerPage() {
|
|||||||
{r.current.distance != null ? ` (dist ${r.current.distance})` : ''}
|
{r.current.distance != null ? ` (dist ${r.current.distance})` : ''}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
{(r.current?.interfaceName || r.current?.exit?.country) && (
|
||||||
|
<div className="text-muted">
|
||||||
|
{r.current?.exit?.country ? `${countryToFlag(r.current.exit.country)} ` : ''}
|
||||||
|
{r.current?.interfaceName ? `iface: ${r.current.interfaceName}` : ''}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</td>
|
</td>
|
||||||
<td className="small">
|
<td className="small">
|
||||||
<div>{r.recommended?.gateway || '—'}</div>
|
<div>{r.recommended?.gateway || '—'}</div>
|
||||||
@@ -246,6 +253,12 @@ export default function RouteOptimizerPage() {
|
|||||||
{r.recommended.distance != null ? ` (dist ${r.recommended.distance})` : ''}
|
{r.recommended.distance != null ? ` (dist ${r.recommended.distance})` : ''}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
{(r.recommended?.interfaceName || r.recommended?.exit?.country) && (
|
||||||
|
<div className="text-muted">
|
||||||
|
{r.recommended?.exit?.country ? `${countryToFlag(r.recommended.exit.country)} ` : ''}
|
||||||
|
{r.recommended?.interfaceName ? `iface: ${r.recommended.interfaceName}` : ''}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</td>
|
</td>
|
||||||
<td className="small">
|
<td className="small">
|
||||||
{fmtProb(r.current?.probabilityOptimal)} / {fmtProb(r.recommended?.probabilityOptimal)}
|
{fmtProb(r.current?.probabilityOptimal)} / {fmtProb(r.recommended?.probabilityOptimal)}
|
||||||
|
|||||||
Reference in New Issue
Block a user