feat: гармонизация секции AWG в дашборде и изоляция маршрутизации FPTN

This commit is contained in:
Dushnilin
2026-09-17 19:42:54 +03:00
parent 44e93b1f16
commit 623ea59797
11 changed files with 3313 additions and 3079 deletions
@@ -1862,6 +1862,18 @@ function formatServiceStatusMessage(msg) {
}
// src/tachyon/tabs/dashboard/partials/renderSections.ts
var CONNECTION_ACTION_LABELS = {
awg: "AmneziaWG",
warp: "WARP",
anytls: "AnyTLS",
snell: "Snell",
mieru: "Mieru",
sudoku: "Sudoku",
masque: "MASQUE",
openvpn: "OpenVPN",
fptn: "FPTN",
vpn: "VPN"
};
function renderFailedState() {
return E(
"div",
@@ -2209,80 +2221,64 @@ function renderDefaultState({
outboundSwitching ? "tachyon_dashboard-page__outbound-grid__item--switching" : ""
].filter(Boolean).join(" ");
if (isConnectionNode) {
const statusText = latencyFetching ? _("Checking...") : outbound.latency === -1 || outbound.latency < 0 ? _("Not responding") : outbound.runtimeAvailable ? _("Connected") : _("Not connected");
const statusColor = latencyFetching ? "var(--warn-color-medium, orange)" : outbound.latency === -1 || outbound.latency < 0 ? "var(--error-color-medium, red)" : outbound.runtimeAvailable ? "var(--success-color-medium, green)" : "var(--error-color-medium, red)";
const latencyDisplay = outbound.latency && outbound.latency > 0 ? `${outbound.latency} ms` : "";
return E(
"div",
{
class: className,
style: "display: flex; align-items: center; justify-content: space-between; padding: 12px; min-width: 0; gap: 16px;"
style: "display: flex; flex-direction: column; justify-content: space-between; padding: 12px; min-width: 0;"
},
[
E(
"div",
{
style: "display: flex; align-items: center; gap: 12px; min-width: 0;"
class: "tachyon_dashboard-page__outbound-grid__item__header",
style: "margin-bottom: 8px;"
},
[
E(
"b",
"div",
{
style: "overflow-wrap: anywhere; word-break: break-all; min-width: 0;"
class: "tachyon_dashboard-page__outbound-grid__item__title-wrapper"
},
[
E(
"span",
{
style: `color: ${statusColor}; font-weight: 500; font-size: 13px;`
},
statusText
)
]
)
]
),
E(
"div",
{
class: "tachyon_dashboard-page__outbound-grid__item__footer",
style: "display: flex; align-items: center; justify-content: space-between; gap: 8px;"
},
[
E(
"div",
{
class: "tachyon_dashboard-page__outbound-grid__item__type",
style: "overflow: hidden; text-overflow: ellipsis; white-space: nowrap;"
},
renderFlagEmojis(outbound.displayName)
),
outbound.prefix ? E(
"span",
{
class: "tachyon_dashboard-page__outbound-grid__item__prefix-badge"
},
renderFlagEmojis(outbound.prefix)
) : "",
E(
"span",
{
style: "opacity: 0.7; font-size: 13px; white-space: nowrap; flex-shrink: 0;"
},
[formatOutboundType(outbound.type, outbound.transport)].filter(
Boolean
)
),
E(
latencyDisplay ? E(
"div",
{
class: getLatencyClass(),
style: "white-space: nowrap; flex-shrink: 0;"
},
connectionStatusText
)
latencyDisplay
) : ""
]
),
E(
"button",
{
type: "button",
class: "btn dashboard-sections-grid-item-test-latency",
style: "padding: 4px 12px; height: 30px; flex-shrink: 0;",
disabled: latencyFetching ? true : void 0,
click: (event) => {
event.preventDefault();
event.stopPropagation();
if (latencyFetching) return;
testLatency();
}
},
latencyFetching ? [
renderLoaderCircleIcon24(),
E(
"span",
{
class: "dashboard-sections-grid-item-test-latency__label"
},
_("Checking...")
)
] : E(
"span",
{ class: "dashboard-sections-grid-item-test-latency__label" },
_("Check Connection")
)
)
]
);
@@ -2435,24 +2431,6 @@ function renderDefaultState({
]
);
}
if (isConnectionNode) {
return E(
"div",
{
class: "tachyon_dashboard-page__outbound-section",
style: "border: none; padding: 0;"
},
[
E(
"div",
{
style: "display: flex; flex-direction: column; gap: 8px; padding: 0;"
},
[...section.outbounds.map((outbound) => renderOutbound(outbound))]
)
]
);
}
const metadataNodes = (section.subscriptionMetadata || []).map((metadata) => renderSubscriptionMetadata(metadata)).filter(Boolean);
const subscriptionUpdateAction = renderSubscriptionUpdateAction(
section,
@@ -2512,6 +2490,7 @@ function renderDefaultState({
"masque",
"openvpn"
].includes(section.action || "");
const connectionTitle = section.action && CONNECTION_ACTION_LABELS[section.action] || selectedOutbound.displayName;
function getLatencyColor() {
if (isConnectionNode2) {
if (latencyFetching)
@@ -2552,7 +2531,7 @@ function renderDefaultState({
E(
"span",
{ style: "opacity: 0.7;" },
selectedOutbound.displayName
isConnectionNode2 ? connectionTitle : selectedOutbound.prefix || selectedOutbound.displayName
),
latencyText ? E(
"span",
@@ -2561,6 +2540,22 @@ function renderDefaultState({
) : ""
]
);
})() : isConnectionNode ? (() => {
const selectedOutbound = section.outbounds.find(
(o) => o.selected
);
if (!selectedOutbound) return "";
const connectionTitle = section.action && CONNECTION_ACTION_LABELS[section.action] || selectedOutbound.displayName;
if (section.displayName.toLowerCase().trim() === connectionTitle.toLowerCase().trim()) {
return "";
}
return E(
"span",
{
style: "font-size: 13px; font-weight: normal; margin-left: 8px; opacity: 0.7;"
},
connectionTitle
);
})() : ""
]
),