From b2a2ed7104437111c09c17a061753e659310b897 Mon Sep 17 00:00:00 2001 From: Dmitriy Petrov Date: Fri, 7 Aug 2026 22:03:18 +0300 Subject: [PATCH] Improve startup animation and traffic chart headroom --- src/shared/versions.js | 4 ++-- src/web/components/ClientOverviewPage.jsx | 4 ++-- src/web/components/DevicesPanel.jsx | 22 ++++++++++++----- src/web/styles.css | 26 ++++++++++++++------- test/web/device-inventory-contract.test.js | 6 +++++ test/web/responsive-layout-contract.test.js | 11 +++++++++ 6 files changed, 54 insertions(+), 19 deletions(-) diff --git a/src/shared/versions.js b/src/shared/versions.js index 39f5443..305702d 100644 --- a/src/shared/versions.js +++ b/src/shared/versions.js @@ -1,6 +1,6 @@ export const HARBOR_VERSIONS = Object.freeze({ - macClient: '0.17.3', - gatewayClient: '0.18.3', + macClient: '0.17.5', + gatewayClient: '0.18.5', gatewayBackend: '0.18.0', }); diff --git a/src/web/components/ClientOverviewPage.jsx b/src/web/components/ClientOverviewPage.jsx index 16abec8..e929a92 100644 --- a/src/web/components/ClientOverviewPage.jsx +++ b/src/web/components/ClientOverviewPage.jsx @@ -627,7 +627,7 @@ export function ClientOverviewPage({ } }); const [editingSubscription, setEditingSubscription] = useState(!state?.hasSubscription); - const [showIntro, setShowIntro] = useState(!hasSubscription); + const [showIntro, setShowIntro] = useState(true); const [subscriptionContentReady, setSubscriptionContentReady] = useState(hasSubscription); const [copyFeedback, setCopyFeedback] = useState(null); const [subscriptionValidation, setSubscriptionValidation] = useState({ @@ -1113,7 +1113,7 @@ export function ClientOverviewPage({ return (
diff --git a/src/web/components/DevicesPanel.jsx b/src/web/components/DevicesPanel.jsx index 5ced2cc..7ec4075 100644 --- a/src/web/components/DevicesPanel.jsx +++ b/src/web/components/DevicesPanel.jsx @@ -16,6 +16,8 @@ const AUTO_REFRESH_MS = 15_000; const DEVICE_MOVE_MS = 520; const COPY_FEEDBACK_MS = 800; const TRAFFIC_DELTA_MS = 2_200; +const TRAFFIC_CHART_HEADROOM = 10; +const trafficChartY = (ratio) => 100 - ratio * (100 - TRAFFIC_CHART_HEADROOM); function Tooltip({ children }) { return {children}; @@ -62,8 +64,8 @@ function TrafficChart({ samples, scale, capacity, routeLabel, pinned }) { x: (firstSlot + index) * 100 / Math.max(1, capacity - 1), gateway, proxy, - gatewayY: 100 - trafficScaleRatio(gateway, max, scale) * 100, - proxyY: 100 - trafficScaleRatio(proxy, max, scale) * 100, + gatewayY: trafficChartY(trafficScaleRatio(gateway, max, scale)), + proxyY: trafficChartY(trafficScaleRatio(proxy, max, scale)), }; }); const previous = points.slice(0, -1); @@ -108,7 +110,15 @@ function TrafficChart({ samples, scale, capacity, routeLabel, pinned }) { document.body, ); - return + return {pinned && max > 0n &&