Skip to content

Commit 8ed4756

Browse files
committed
feat(Cluster): redesign query dashboard
1 parent 3bdd9e2 commit 8ed4756

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+867
-626
lines changed

src/assets/icons/overview.svg

Lines changed: 1 addition & 0 deletions
Loading

src/assets/icons/user-check.svg

Lines changed: 0 additions & 1 deletion
This file was deleted.

src/components/DoughnutMetrics/DoughnutMetrics.scss

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
.ydb-doughnut-metrics {
2-
--doughnut-border: 11px;
2+
--doughnut-border: 16px;
33
--doughnut-color: var(--ydb-color-status-green);
4+
--doughnut-backdrop-color: var(--g-color-base-positive-light);
5+
--doughnut-overlap-color: var(--g-color-base-positive-heavy-hover);
46
&__doughnut {
57
position: relative;
68

7-
width: 172px;
9+
width: 100px;
810
aspect-ratio: 1;
911

1012
border-radius: 50%;
11-
background-color: var(--doughnut-color);
13+
14+
transform: rotate(180deg);
1215
&::before {
1316
display: block;
1417

@@ -25,9 +28,13 @@
2528
}
2629
&__doughnut_status_warning {
2730
--doughnut-color: var(--ydb-color-status-yellow);
31+
--doughnut-backdrop-color: var(--g-color-base-warning-light);
32+
--doughnut-overlap-color: var(--g-color-base-warning-heavy-hover);
2833
}
2934
&__doughnut_status_danger {
3035
--doughnut-color: var(--ydb-color-status-red);
36+
--doughnut-backdrop-color: var(--g-color-base-danger-light);
37+
--doughnut-overlap-color: var(--g-color-base-danger-heavy-hover);
3138
}
3239
&__text-wrapper {
3340
--wrapper-indent: calc(var(--doughnut-border) + 5px);
@@ -44,15 +51,15 @@
4451
width: calc(100% - calc(var(--wrapper-indent) * 2));
4552

4653
text-align: center;
54+
55+
transform: rotate(180deg);
4756
aspect-ratio: 1;
4857
}
4958
&__value {
5059
position: absolute;
5160
bottom: 20px;
5261
}
53-
&__legend {
54-
height: 50%;
55-
56-
white-space: pre-wrap;
62+
&__legend-note {
63+
display: flex;
5764
}
5865
}

src/components/DoughnutMetrics/DoughnutMetrics.tsx

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React from 'react';
22

33
import type {TextProps} from '@gravity-ui/uikit';
4-
import {Text} from '@gravity-ui/uikit';
4+
import {Flex, HelpMark, Text} from '@gravity-ui/uikit';
55

66
import {cn} from '../../utils/cn';
77
import type {ProgressStatus} from '../../utils/progress';
@@ -13,18 +13,23 @@ const b = cn('ydb-doughnut-metrics');
1313
interface LegendProps {
1414
children?: React.ReactNode;
1515
variant?: TextProps['variant'];
16+
color?: TextProps['color'];
17+
note?: React.ReactNode;
1618
}
1719

18-
function Legend({children, variant = 'subheader-3'}: LegendProps) {
20+
function Legend({children, variant = 'subheader-3', color = 'primary', note}: LegendProps) {
1921
return (
20-
<Text variant={variant} color="secondary" className={b('legend')}>
21-
{children}
22-
</Text>
22+
<Flex gap={1} alignItems="center">
23+
<Text variant={variant} color={color} className={b('legend')} as="div">
24+
{children}
25+
</Text>
26+
{note && <HelpMark className={b('legend-note')}>{note}</HelpMark>}
27+
</Flex>
2328
);
2429
}
2530
function Value({children, variant = 'subheader-2'}: LegendProps) {
2631
return (
27-
<Text variant={variant} color="secondary" className={b('value')}>
32+
<Text variant={variant} className={b('value')}>
2833
{children}
2934
</Text>
3035
);
@@ -38,19 +43,21 @@ interface DoughnutProps {
3843
}
3944

4045
export function DoughnutMetrics({status, fillWidth, children, className}: DoughnutProps) {
41-
let gradientFill = 'var(--g-color-line-generic-solid)';
42-
let filledDegrees = fillWidth * 3.6 - 90;
46+
let filledDegrees = fillWidth * 3.6;
47+
let doughnutFillVar = 'var(--doughnut-color)';
48+
let doughnutBackdropVar = 'var(--doughnut-backdrop-color)';
4349

44-
if (fillWidth > 50) {
45-
gradientFill = 'var(--doughnut-color)';
46-
filledDegrees = fillWidth * 3.6 + 90;
50+
if (filledDegrees > 360) {
51+
filledDegrees -= 360;
52+
doughnutBackdropVar = 'var(--doughnut-color)';
53+
doughnutFillVar = 'var(--doughnut-overlap-color)';
4754
}
48-
const gradientDegrees = filledDegrees;
55+
4956
return (
5057
<div className={b(null, className)}>
5158
<div
5259
style={{
53-
backgroundImage: `linear-gradient(${gradientDegrees}deg, transparent 50%, ${gradientFill} 50%), linear-gradient(-90deg, var(--g-color-line-generic-solid) 50%, transparent 50%)`,
60+
background: `conic-gradient(${doughnutFillVar} 0deg ${filledDegrees}deg, ${doughnutBackdropVar} ${filledDegrees}deg 360deg)`,
5461
}}
5562
className={b('doughnut', {status})}
5663
>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
.ydb-entity-status-new {
2+
.g-help-mark__button {
3+
color: inherit;
4+
}
5+
6+
&_orange.g-label {
7+
color: var(--g-color-private-orange-500);
8+
background-color: var(--g-color-private-orange-100);
9+
}
10+
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import React from 'react';
2+
3+
import type {LabelProps} from '@gravity-ui/uikit';
4+
import {ActionTooltip, Flex, HelpMark, Label} from '@gravity-ui/uikit';
5+
6+
import {EFlag} from '../../types/api/enums';
7+
import {cn} from '../../utils/cn';
8+
import {StatusIcon} from '../StatusIconNew/StatusIcon';
9+
10+
import i18n from './i18n';
11+
import {EFlagToDescription} from './utils';
12+
13+
import './EntityStatus.scss';
14+
15+
const b = cn('ydb-entity-status-new');
16+
17+
const EFlagToLabelTheme: Record<EFlag, LabelProps['theme'] | 'orange'> = {
18+
[EFlag.Red]: 'danger',
19+
[EFlag.Blue]: 'info',
20+
[EFlag.Green]: 'success',
21+
[EFlag.Grey]: 'unknown',
22+
[EFlag.Orange]: 'orange',
23+
[EFlag.Yellow]: 'warning',
24+
};
25+
26+
const EFlagToStatusName: Record<EFlag, string> = {
27+
get [EFlag.Red]() {
28+
return i18n('title_red');
29+
},
30+
get [EFlag.Yellow]() {
31+
return i18n('title_yellow');
32+
},
33+
get [EFlag.Orange]() {
34+
return i18n('title_orange');
35+
},
36+
get [EFlag.Green]() {
37+
return i18n('title_green');
38+
},
39+
get [EFlag.Grey]() {
40+
return i18n('title_grey');
41+
},
42+
get [EFlag.Blue]() {
43+
return i18n('title_blue');
44+
},
45+
};
46+
47+
interface EntityStatusLabelProps {
48+
status: EFlag;
49+
note?: React.ReactNode;
50+
children?: React.ReactNode;
51+
withStatusName?: boolean;
52+
size?: LabelProps['size'];
53+
}
54+
55+
function EntityStatusLabel({
56+
children,
57+
status,
58+
withStatusName = true,
59+
note,
60+
size = 'm',
61+
}: EntityStatusLabelProps) {
62+
const theme = EFlagToLabelTheme[status];
63+
return (
64+
<ActionTooltip title={EFlagToDescription[status]} disabled={Boolean(note)}>
65+
<Label
66+
theme={theme === 'orange' ? undefined : theme}
67+
icon={<StatusIcon status={status} />}
68+
size={size}
69+
className={b({orange: theme === 'orange'})}
70+
>
71+
<Flex gap="2" wrap="nowrap">
72+
{children}
73+
{withStatusName ? EFlagToStatusName[status] : null}
74+
{note && <HelpMark>{note}</HelpMark>}
75+
</Flex>
76+
</Label>
77+
</ActionTooltip>
78+
);
79+
}
80+
81+
interface EntityStatusProps {
82+
children?: React.ReactNode;
83+
className?: string;
84+
}
85+
86+
export function EntityStatus({className, children}: EntityStatusProps) {
87+
return (
88+
<Flex gap="2" wrap="nowrap" alignItems="center" className={b(null, className)}>
89+
{children}
90+
</Flex>
91+
);
92+
}
93+
94+
EntityStatus.Label = EntityStatusLabel;
95+
EntityStatus.displayName = 'EntityStatus';
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"title_red": "Failed",
3+
"title_blue": "Normal",
4+
"title_green": "Good",
5+
"title_grey": "Unknown",
6+
"title_orange": "Caution",
7+
"title_yellow": "Warning",
8+
"context_red": "Some systems are failed and not available",
9+
"context_yellow": "There are minor issues",
10+
"context_orange": "Critical state, requires immediate attention",
11+
"context_green": "Everything is working as expected",
12+
"context_grey": "The condition cannot be determined",
13+
"context_blue": "All good, some parts of the system are restoring"
14+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import {registerKeysets} from '../../../utils/i18n';
2+
3+
import en from './en.json';
4+
5+
const COMPONENT = 'ydb-entity-status';
6+
7+
export default registerKeysets(COMPONENT, {en});
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"403.title": "Доступ запрещен",
3+
"403.description": "У вас недостаточно прав для просмотра данной страницы.",
4+
"responseError.defaultMessage": "Ошибка запроса",
5+
"error.title": "Ошибка"
6+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import {EFlag} from '../../types/api/enums';
2+
3+
import i18n from './i18n';
4+
5+
export const EFlagToDescription: Record<EFlag, string> = {
6+
get [EFlag.Red]() {
7+
return i18n('context_red');
8+
},
9+
get [EFlag.Yellow]() {
10+
return i18n('context_yellow');
11+
},
12+
get [EFlag.Orange]() {
13+
return i18n('context_orange');
14+
},
15+
get [EFlag.Green]() {
16+
return i18n('context_green');
17+
},
18+
get [EFlag.Grey]() {
19+
return i18n('context_grey');
20+
},
21+
get [EFlag.Blue]() {
22+
return i18n('context_blue');
23+
},
24+
};

0 commit comments

Comments
 (0)