Polish device inventory layout and typography
Build and Deploy Gateway / build-and-push (push) Successful in 14s
Build and Deploy Gateway / deploy (push) Successful in 7s

This commit is contained in:
2026-08-07 17:58:52 +03:00
parent 0a37121dbe
commit d0c5336b7e
3 changed files with 66 additions and 50 deletions
+2 -2
View File
@@ -1,6 +1,6 @@
export const HARBOR_VERSIONS = Object.freeze({ export const HARBOR_VERSIONS = Object.freeze({
macClient: '0.13.2', macClient: '0.13.4',
gatewayClient: '0.14.2', gatewayClient: '0.14.4',
gatewayBackend: '0.14.0', gatewayBackend: '0.14.0',
}); });
+55 -44
View File
@@ -716,13 +716,21 @@ p {
} }
.client-instructions.client-devices { .client-instructions.client-devices {
width: min(560px, 100vw); width: min(580px, 100vw);
} }
.client-devices-header { .client-devices-header {
margin-bottom: 28px; margin-bottom: 28px;
} }
.client-devices-header h2 {
font-size: 24px;
}
.client-devices-header .client-instructions-intro {
font-size: 12px;
}
.client-devices-kicker { .client-devices-kicker {
width: max-content; width: max-content;
display: flex; display: flex;
@@ -730,9 +738,13 @@ p {
gap: 8px; gap: 8px;
} }
.client-devices-kicker > span:first-child {
font-size: 10px;
}
.client-devices-refresh-wrap { .client-devices-refresh-wrap {
width: 24px; width: 28px;
height: 24px; height: 28px;
display: grid; display: grid;
place-items: center; place-items: center;
} }
@@ -742,7 +754,7 @@ p {
} }
.client-devices-sort { .client-devices-sort {
min-height: 24px; min-height: 28px;
display: flex; display: flex;
align-items: center; align-items: center;
gap: 4px; gap: 4px;
@@ -750,7 +762,7 @@ p {
border: 0; border: 0;
background: transparent; background: transparent;
color: var(--client-muted); color: var(--client-muted);
font: 700 9px/1 'JetBrains Mono', 'SF Mono', ui-monospace, Menlo, monospace; font: 700 10px/1 'JetBrains Mono', 'SF Mono', ui-monospace, Menlo, monospace;
cursor: pointer; cursor: pointer;
transition: color 220ms ease, filter 300ms ease; transition: color 220ms ease, filter 300ms ease;
} }
@@ -774,8 +786,8 @@ p {
.client-devices-refresh { .client-devices-refresh {
position: relative; position: relative;
width: 24px; width: 28px;
height: 24px; height: 28px;
display: grid; display: grid;
place-items: center; place-items: center;
padding: 0; padding: 0;
@@ -828,8 +840,8 @@ p {
} }
.client-devices-refresh-icon { .client-devices-refresh-icon {
width: 12px; width: 14px;
height: 12px; height: 14px;
stroke-width: 1.8; stroke-width: 1.8;
} }
@@ -856,7 +868,7 @@ p {
.client-devices-empty { .client-devices-empty {
margin: 0 8px 20px; margin: 0 8px 20px;
color: var(--client-muted); color: var(--client-muted);
font-size: 10px; font-size: 11px;
line-height: 1.6; line-height: 1.6;
} }
@@ -889,10 +901,10 @@ p {
.client-device { .client-device {
display: grid; display: grid;
grid-template-columns: 32px minmax(0, 1fr) 104px 32px; grid-template-columns: 34px minmax(0, 1fr) 112px 34px;
align-items: center; align-items: center;
gap: 6px; gap: 8px;
padding: 8px; padding: 10px 8px;
border-top: 1px solid color-mix(in oklch, var(--client-border) 72%, transparent); border-top: 1px solid color-mix(in oklch, var(--client-border) 72%, transparent);
} }
@@ -900,7 +912,7 @@ p {
min-width: 0; min-width: 0;
display: flex; display: flex;
align-items: center; align-items: center;
gap: 7px; gap: 8px;
} }
.client-device-main > h3 { .client-device-main > h3 {
@@ -908,7 +920,7 @@ p {
min-width: 0; min-width: 0;
overflow: hidden; overflow: hidden;
margin: 0; margin: 0;
font-size: 14px; font-size: 15px;
letter-spacing: -0.03em; letter-spacing: -0.03em;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
@@ -923,7 +935,7 @@ p {
border: 0; border: 0;
background: transparent; background: transparent;
color: var(--client-text); color: var(--client-text);
font: 700 14px/1.2 'JetBrains Mono', 'SF Mono', ui-monospace, Menlo, monospace; font: 700 15px/1.2 'JetBrains Mono', 'SF Mono', ui-monospace, Menlo, monospace;
letter-spacing: -0.03em; letter-spacing: -0.03em;
text-align: left; text-align: left;
cursor: copy; cursor: copy;
@@ -932,14 +944,13 @@ p {
.client-device-name > span { .client-device-name > span {
grid-area: 1 / 1; grid-area: 1 / 1;
overflow: hidden; overflow: hidden;
opacity: 1; opacity: 0;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
} }
.client-device-name-ip, .client-device-name > .client-device-name-primary {
.client-device-name-feedback { opacity: 1;
opacity: 0;
} }
.client-device-name:hover .client-device-name-primary, .client-device-name:hover .client-device-name-primary,
@@ -980,8 +991,8 @@ p {
.client-device-edit-wrap, .client-device-edit-wrap,
.client-device-pin-wrap { .client-device-pin-wrap {
width: 28px; width: 32px;
height: 28px; height: 32px;
display: grid; display: grid;
place-items: center; place-items: center;
} }
@@ -998,14 +1009,14 @@ p {
} }
.client-device-pin-wrap { .client-device-pin-wrap {
width: 32px; width: 34px;
height: 32px; height: 34px;
} }
.client-device-edit, .client-device-edit,
.client-device-pin { .client-device-pin {
width: 28px; width: 32px;
height: 28px; height: 32px;
display: grid; display: grid;
place-items: center; place-items: center;
color: var(--client-muted); color: var(--client-muted);
@@ -1013,8 +1024,8 @@ p {
.client-device-edit svg, .client-device-edit svg,
.client-device-pin svg { .client-device-pin svg {
width: 15px; width: 17px;
height: 15px; height: 17px;
fill: none; fill: none;
stroke: currentColor; stroke: currentColor;
stroke-width: 1.7; stroke-width: 1.7;
@@ -1059,7 +1070,7 @@ p {
min-width: 0; min-width: 0;
max-width: 116px; max-width: 116px;
overflow: hidden; overflow: hidden;
font-size: 8px; font-size: 10px;
text-overflow: ellipsis; text-overflow: ellipsis;
color: var(--client-text); color: var(--client-text);
cursor: default; cursor: default;
@@ -1132,7 +1143,7 @@ p {
} }
.client-device-traffic { .client-device-traffic {
width: 104px; width: 112px;
display: grid; display: grid;
align-items: center; align-items: center;
color: var(--client-text); color: var(--client-text);
@@ -1146,21 +1157,21 @@ p {
.client-device-traffic-sources span { .client-device-traffic-sources span {
display: grid; display: grid;
grid-template-columns: 41px minmax(0, 1fr); grid-template-columns: 46px minmax(0, 1fr);
align-items: baseline; align-items: baseline;
gap: 4px; gap: 4px;
} }
.client-device-traffic-sources b { .client-device-traffic-sources b {
color: var(--client-muted); color: var(--client-muted);
font-size: 7px; font-size: 8px;
letter-spacing: 0.03em; letter-spacing: 0.03em;
text-transform: uppercase; text-transform: uppercase;
} }
.client-device-traffic-sources strong { .client-device-traffic-sources strong {
overflow: hidden; overflow: hidden;
font-size: 8px; font-size: 10px;
font-weight: 600; font-weight: 600;
text-align: right; text-align: right;
text-overflow: ellipsis; text-overflow: ellipsis;
@@ -1176,13 +1187,13 @@ p {
} }
.client-device-policy-wrap { .client-device-policy-wrap {
width: 32px; width: 34px;
position: relative; position: relative;
} }
.client-device-policy { .client-device-policy {
width: 32px; width: 34px;
height: 32px; height: 34px;
display: grid; display: grid;
place-items: center; place-items: center;
padding: 0; padding: 0;
@@ -1195,8 +1206,8 @@ p {
} }
.client-device-policy svg { .client-device-policy svg {
width: 18px; width: 20px;
height: 18px; height: 20px;
fill: none; fill: none;
stroke: currentColor; stroke: currentColor;
stroke-width: 1.7; stroke-width: 1.7;
@@ -1259,7 +1270,7 @@ p {
flex: 1 1 auto; flex: 1 1 auto;
min-width: 0; min-width: 0;
display: grid; display: grid;
grid-template-columns: minmax(0, 1fr) 28px 28px; grid-template-columns: minmax(0, 1fr) 32px 32px;
align-items: center; align-items: center;
gap: 3px; gap: 3px;
} }
@@ -1272,7 +1283,7 @@ p {
outline: 0; outline: 0;
background: transparent; background: transparent;
color: var(--client-text); color: var(--client-text);
font-size: 12px; font-size: 14px;
} }
.client-device-alias input:focus { .client-device-alias input:focus {
@@ -1280,14 +1291,14 @@ p {
} }
.client-device-alias button { .client-device-alias button {
width: 28px; width: 32px;
height: 28px; height: 32px;
font-size: 14px; font-size: 16px;
} }
.client-devices-error button { .client-devices-error button {
justify-self: start; justify-self: start;
font-size: 9px; font-size: 10px;
font-weight: 700; font-weight: 700;
} }
+9 -4
View File
@@ -62,12 +62,17 @@ test('Gateway device inventory uses the existing accessible responsive drawer',
assert.match(panel, /aria-pressed=\{device\.pinned\}/); assert.match(panel, /aria-pressed=\{device\.pinned\}/);
assert.doesNotMatch(panel, /Закрепите устройство, чтобы изменить маршрут|Сначала верните маршрут через Gateway/); assert.doesNotMatch(panel, /Закрепите устройство, чтобы изменить маршрут|Сначала верните маршрут через Gateway/);
assert.match(panel, /maxLength="64"[\s\S]*autoFocus/); assert.match(panel, /maxLength="64"[\s\S]*autoFocus/);
assert.match(styles, /\.client-devices \{\s*width: min\(560px, 100vw\)/); assert.match(styles, /\.client-devices \{\s*width: min\(580px, 100vw\)/);
assert.match(styles, /\.client-device \{[\s\S]*grid-template-columns: 32px minmax\(0, 1fr\) 104px 32px;[\s\S]*padding: 8px/); assert.match(styles, /\.client-device \{[\s\S]*grid-template-columns: 34px minmax\(0, 1fr\) 112px 34px;[\s\S]*padding: 10px 8px/);
assert.match(styles, /\.client-device-main \{[\s\S]*display: flex;[\s\S]*align-items: center/); assert.match(styles, /\.client-device-main \{[\s\S]*display: flex;[\s\S]*align-items: center/);
assert.match(styles, /\.client-device-traffic-sources \{[\s\S]*display: grid/); assert.match(styles, /\.client-device-traffic-sources \{[\s\S]*display: grid/);
assert.match(styles, /\.client-device-traffic-sources span \{[\s\S]*grid-template-columns: 41px minmax\(0, 1fr\)/); assert.match(styles, /\.client-device-traffic-sources span \{[\s\S]*grid-template-columns: 46px minmax\(0, 1fr\)/);
assert.match(styles, /\.client-device-policy \{[\s\S]*width: 32px;[\s\S]*border-radius: 50%/); assert.match(styles, /\.client-device-policy \{[\s\S]*width: 34px;[\s\S]*border-radius: 50%/);
assert.match(styles, /\.client-device-name \{[\s\S]*font: 700 15px\/1\.2/);
assert.match(styles, /\.client-device-last-seen \{[\s\S]*font-size: 10px/);
assert.match(styles, /\.client-device-traffic-sources strong \{[\s\S]*font-size: 10px/);
assert.match(styles, /\.client-device-name > span \{[^}]*opacity: 0/);
assert.match(styles, /\.client-device-name > \.client-device-name-primary \{[^}]*opacity: 1/);
assert.match(styles, /\.client-device-name:hover \.client-device-name-ip[\s\S]*opacity: 1/); assert.match(styles, /\.client-device-name:hover \.client-device-name-ip[\s\S]*opacity: 1/);
assert.match(styles, /\.client-device-name\.is-copied \.client-device-name-feedback[\s\S]*opacity: 1/); assert.match(styles, /\.client-device-name\.is-copied \.client-device-name-feedback[\s\S]*opacity: 1/);
assert.doesNotMatch(styles, /\.client-device-name > span \{[^}]*transition:/); assert.doesNotMatch(styles, /\.client-device-name > span \{[^}]*transition:/);