Improve gateway traffic dashboard and connection branding
This commit is contained in:
@@ -537,14 +537,6 @@ export function ClientOverviewPage({
|
||||
<div className="client-live-region" role="status" aria-live="polite" aria-atomic="true">
|
||||
<span key={copyAnnouncement.cycle}>{copyAnnouncement.text}</span>
|
||||
</div>
|
||||
<HarborBrand
|
||||
isGateway={isGateway}
|
||||
connected={connected}
|
||||
gatewayAvailable={gatewayAvailable}
|
||||
gatewayDirect={gatewayDirect}
|
||||
blocked={gatewayAutoBlocked}
|
||||
onSetGatewayAuto={onSetGatewayAuto}
|
||||
/>
|
||||
{(isGateway || (hasSubscription && subscriptionContentReady)) && <nav className="client-secondary-menu" aria-label="Дополнительные меню">
|
||||
{isGateway && <SubscriptionToggle
|
||||
feature={subscriptionFeature}
|
||||
@@ -609,6 +601,14 @@ export function ClientOverviewPage({
|
||||
proxyPort={state?.clientRuntime?.proxyPort}
|
||||
now={now}
|
||||
blocked={connectionBlocked}
|
||||
brandSlot={<HarborBrand
|
||||
isGateway={isGateway}
|
||||
connected={connected}
|
||||
gatewayAvailable={gatewayAvailable}
|
||||
gatewayDirect={gatewayDirect}
|
||||
blocked={gatewayAutoBlocked}
|
||||
onSetGatewayAuto={onSetGatewayAuto}
|
||||
/>}
|
||||
copyFeedback={copyFeedback}
|
||||
onCopyProxy={copyProxy}
|
||||
onApply={onApply}
|
||||
|
||||
@@ -34,6 +34,7 @@ interface ConnectionPanelProps {
|
||||
proxyPort?: number;
|
||||
now: number;
|
||||
blocked: boolean;
|
||||
brandSlot?: ReactNode;
|
||||
copyFeedback?: Partial<Record<CopyKind, CopyFeedback>>;
|
||||
routingSlot?: ReactNode;
|
||||
serverSlot?: ReactNode;
|
||||
@@ -74,6 +75,7 @@ export function ConnectionPanel({
|
||||
proxyPort,
|
||||
now,
|
||||
blocked,
|
||||
brandSlot,
|
||||
copyFeedback,
|
||||
routingSlot,
|
||||
serverSlot,
|
||||
@@ -161,18 +163,19 @@ export function ConnectionPanel({
|
||||
</button>;
|
||||
|
||||
return <>
|
||||
{visible && <section className={`client-power-section${isGateway ? ' is-gateway' : ''}`} aria-labelledby="connection-title">
|
||||
{isGateway ? <span
|
||||
className="client-power-control client-tooltip-anchor"
|
||||
{visible ? <section className={`client-power-section${isGateway ? ' is-gateway' : ''}`} aria-labelledby="connection-title">
|
||||
<div
|
||||
className={`client-power-control${isGateway ? ' client-tooltip-anchor' : ''}`}
|
||||
tabIndex={powerUnavailable ? 0 : undefined}
|
||||
aria-label={powerUnavailable ? 'VPN недоступен' : undefined}
|
||||
aria-describedby={powerUnavailable ? 'gateway-power-unavailable' : undefined}
|
||||
>
|
||||
{brandSlot}
|
||||
{powerButton}
|
||||
{powerUnavailable && <span className="client-tooltip" id="gateway-power-unavailable" role="tooltip">
|
||||
Сначала добавьте подписку и выберите сервер
|
||||
</span>}
|
||||
</span> : powerButton}
|
||||
</div>
|
||||
<div className="client-state-detail">
|
||||
{connected ? (
|
||||
<button
|
||||
@@ -266,7 +269,7 @@ export function ConnectionPanel({
|
||||
</div>
|
||||
</section>
|
||||
{statusSlot}
|
||||
</section>}
|
||||
</section> : brandSlot}
|
||||
|
||||
<ConfirmationDialog
|
||||
open={confirmingStop}
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
}
|
||||
|
||||
.client-power-control {
|
||||
position: relative;
|
||||
width: 96px;
|
||||
height: 96px;
|
||||
display: grid;
|
||||
@@ -38,18 +39,31 @@
|
||||
|
||||
.client-power-section.is-gateway .client-power-control,
|
||||
.client-power-section.is-gateway .client-power {
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
width: 84px;
|
||||
height: 84px;
|
||||
}
|
||||
|
||||
.client-power-section.is-gateway .client-power svg {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
}
|
||||
|
||||
.client-power-section.is-gateway .client-power::before {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
width: 52px;
|
||||
height: 52px;
|
||||
}
|
||||
|
||||
.client-power-control > .client-tooltip {
|
||||
top: calc(100% + 12px);
|
||||
right: auto;
|
||||
bottom: auto;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -2px);
|
||||
}
|
||||
|
||||
.client-power-control.client-tooltip-anchor:hover > .client-tooltip,
|
||||
.client-power-control.client-tooltip-anchor:focus-visible > .client-tooltip {
|
||||
transform: translate(-50%, 0);
|
||||
}
|
||||
|
||||
.client-power-control:focus-visible {
|
||||
|
||||
+19
-11
@@ -152,6 +152,17 @@
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.client-power-control > .harbor-brand {
|
||||
position: absolute;
|
||||
top: auto;
|
||||
right: auto;
|
||||
bottom: calc(100% + 44px);
|
||||
left: 50%;
|
||||
width: max-content;
|
||||
transform: translateX(-50%) scale(3);
|
||||
transform-origin: center bottom;
|
||||
}
|
||||
|
||||
.harbor-brand.is-switchable {
|
||||
pointer-events: auto;
|
||||
}
|
||||
@@ -206,13 +217,6 @@
|
||||
filter: drop-shadow(0 0 5px color-mix(in oklch, var(--client-accent) 44%, transparent));
|
||||
}
|
||||
|
||||
.harbor-brand.is-connected .harbor-brand-content > svg,
|
||||
.harbor-brand.is-connected .harbor-brand-name > strong,
|
||||
.harbor-brand.is-connected .harbor-brand-name > em,
|
||||
.harbor-brand.is-connected .harbor-mode-stack {
|
||||
transform: translateY(-4px);
|
||||
}
|
||||
|
||||
.harbor-brand.is-connected .harbor-brand-name > strong,
|
||||
.harbor-brand.is-connected .harbor-brand-name > em,
|
||||
.harbor-brand.is-connected .harbor-mode-stack {
|
||||
@@ -397,10 +401,6 @@
|
||||
animation: harbor-mode-arrows-discovered 260ms 420ms cubic-bezier(0.16, 1, 0.3, 1) both;
|
||||
}
|
||||
|
||||
.harbor-brand.is-connected .harbor-mode-swap {
|
||||
transform: translateY(calc(-50% - 4px));
|
||||
}
|
||||
|
||||
@keyframes harbor-mode-arrows-discovered {
|
||||
from {
|
||||
opacity: 0;
|
||||
@@ -662,6 +662,10 @@
|
||||
transform: translateX(-50%) scale(1.55);
|
||||
}
|
||||
|
||||
.client-power-control > .harbor-brand {
|
||||
transform: translateX(-50%) scale(1.55);
|
||||
}
|
||||
|
||||
.client-inline-error.is-connection,
|
||||
.client-inline-error.is-subscription {
|
||||
position: static;
|
||||
@@ -719,6 +723,10 @@
|
||||
transform: translateX(-50%) scale(1.35);
|
||||
}
|
||||
|
||||
.client-power-control > .harbor-brand {
|
||||
transform: translateX(-50%) scale(1.35);
|
||||
}
|
||||
|
||||
.client-secondary-menu {
|
||||
right: 8px;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user