Skip to content

Commit 05fbeff

Browse files
feat(TenantOverview): bars instead of circles (#792)
1 parent b021fe0 commit 05fbeff

File tree

16 files changed

+391
-149
lines changed

16 files changed

+391
-149
lines changed

src/components/DiskPageTitle/DiskPageTitle.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,8 @@
1414

1515
color: var(--g-color-text-secondary);
1616
}
17+
18+
&__icon {
19+
margin-right: 8px;
20+
}
1721
}

src/components/DiskPageTitle/DiskPageTitle.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export function DiskPageTitle({entityName, status, id, className}: DiskPageTitle
1717
return (
1818
<div className={b(null, className)}>
1919
<span className={b('prefix')}>{entityName}</span>
20-
<StatusIcon status={status} size="s" />
20+
<StatusIcon className={b('icon')} status={status} size="s" />
2121
{id}
2222
</div>
2323
);

src/components/EntityStatus/EntityStatus.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@
99

1010
@include body-2-typography();
1111

12+
&__icon {
13+
margin-right: 8px;
14+
}
15+
1216
&__clipboard-button {
1317
visibility: hidden;
1418

src/components/EntityStatus/EntityStatus.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ export function EntityStatus({
5555
return null;
5656
}
5757

58-
return <StatusIcon status={status} size={size} mode={mode} />;
58+
return <StatusIcon className={b('icon')} status={status} size={size} mode={mode} />;
5959
};
6060
const renderStatusLink = (href: string) => {
6161
return (

src/components/ProgressViewer/ProgressViewer.tsx

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import {useTheme} from '@gravity-ui/uikit';
22

3-
import type {ValueOf} from '../../types/common';
43
import {cn} from '../../utils/cn';
54
import {formatNumber, roundToPrecision} from '../../utils/dataFormatters/dataFormatters';
65
import {isNumeric} from '../../utils/utils';
@@ -9,23 +8,20 @@ import './ProgressViewer.scss';
98

109
const b = cn('progress-viewer');
1110

12-
export const PROGRESS_VIEWER_SIZE_IDS = {
13-
xs: 'xs',
14-
s: 's',
15-
ns: 'ns',
16-
m: 'm',
17-
n: 'n',
18-
l: 'l',
19-
head: 'head',
20-
} as const;
11+
type ProgressViewerSize = 'xs' | 's' | 'ns' | 'm' | 'n' | 'l' | 'head';
2112

22-
type ProgressViewerSize = ValueOf<typeof PROGRESS_VIEWER_SIZE_IDS>;
13+
type ProgressViewerStatus = 'good' | 'warning' | 'danger';
14+
15+
type FormatProgressViewerValues = (
16+
value?: number,
17+
capacity?: number,
18+
) => (string | number | undefined)[];
2319

2420
const formatValue = (value?: number) => {
2521
return formatNumber(roundToPrecision(Number(value), 2));
2622
};
2723

28-
const defaultFormatValues = (value?: number, total?: number) => {
24+
const defaultFormatValues: FormatProgressViewerValues = (value, total) => {
2925
return [formatValue(value), formatValue(total)];
3026
};
3127

@@ -42,10 +38,10 @@ Props description:
4238
8) dangerThreshold - the percentage of fullness at which the color of the progress bar changes to red
4339
*/
4440

45-
interface ProgressViewerProps {
41+
export interface ProgressViewerProps {
4642
value?: number | string;
4743
capacity?: number | string;
48-
formatValues?: (value?: number, capacity?: number) => (string | number | undefined)[];
44+
formatValues?: FormatProgressViewerValues;
4945
percents?: boolean;
5046
className?: string;
5147
size?: ProgressViewerSize;
@@ -61,7 +57,7 @@ export function ProgressViewer({
6157
formatValues = defaultFormatValues,
6258
percents,
6359
className,
64-
size = PROGRESS_VIEWER_SIZE_IDS.xs,
60+
size = 'xs',
6561
colorizeProgress,
6662
inverseColorize,
6763
warningThreshold = 60,
@@ -83,7 +79,7 @@ export function ProgressViewer({
8379
[valueText, capacityText] = formatValues(Number(value), Number(capacity));
8480
}
8581

86-
let status = inverseColorize ? 'danger' : 'good';
82+
let status: ProgressViewerStatus = inverseColorize ? 'danger' : 'good';
8783
if (colorizeProgress) {
8884
if (fillWidth > warningThreshold && fillWidth <= dangerThreshold) {
8985
status = 'warning';

src/components/StatusIcon/StatusIcon.scss

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,6 @@
3939
&__status-icon {
4040
flex-shrink: 0;
4141

42-
margin-right: 8px;
43-
4442
border-radius: 3px;
4543
&_size_xs {
4644
aspect-ratio: 1;
@@ -62,8 +60,8 @@
6260
}
6361

6462
&_size_l {
65-
width: 27px;
66-
height: 27px;
63+
width: 24px;
64+
height: 24px;
6765
}
6866
}
6967
}

src/components/StatusIcon/StatusIcon.tsx

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import {cn} from '../../utils/cn';
55

66
import CircleExclamationFillIcon from '@gravity-ui/icons/svgs/circle-exclamation-fill.svg';
77
import CircleInfoFillIcon from '@gravity-ui/icons/svgs/circle-info-fill.svg';
8-
import CircleXmarkFillIcon from '@gravity-ui/icons/svgs/circle-xmark-fill.svg';
98
import TriangleExclamationFillIcon from '@gravity-ui/icons/svgs/triangle-exclamation-fill.svg';
109

1110
import './StatusIcon.scss';
@@ -16,7 +15,7 @@ const icons = {
1615
[EFlag.Blue]: CircleInfoFillIcon,
1716
[EFlag.Yellow]: CircleExclamationFillIcon,
1817
[EFlag.Orange]: TriangleExclamationFillIcon,
19-
[EFlag.Red]: CircleXmarkFillIcon,
18+
[EFlag.Red]: CircleExclamationFillIcon,
2019
};
2120

2221
export type StatusIconMode = 'color' | 'icons';
@@ -26,19 +25,25 @@ interface StatusIconProps {
2625
status?: EFlag;
2726
size?: StatusIconSize;
2827
mode?: StatusIconMode;
28+
className?: string;
2929
}
3030

31-
export function StatusIcon({status = EFlag.Grey, size = 's', mode = 'color'}: StatusIconProps) {
31+
export function StatusIcon({
32+
status = EFlag.Grey,
33+
size = 's',
34+
mode = 'color',
35+
className,
36+
}: StatusIconProps) {
3237
const modifiers = {state: status.toLowerCase(), size};
3338

3439
if (mode === 'icons' && status in icons) {
3540
return (
3641
<Icon
37-
className={b('status-icon', modifiers)}
42+
className={b('status-icon', modifiers, className)}
3843
data={icons[status as keyof typeof icons]}
3944
/>
4045
);
4146
}
4247

43-
return <div className={b('status-color', modifiers)} />;
48+
return <div className={b('status-color', modifiers, className)} />;
4449
}

src/containers/Tenant/Diagnostics/TenantOverview/Healthcheck/Healthcheck.scss

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@
3737

3838
&__preview-title {
3939
font-weight: 600;
40+
41+
color: var(--g-color-text-link);
42+
4043
@include lead-typography();
4144
}
4245

src/containers/Tenant/Diagnostics/TenantOverview/MetricsCards/MetricCard/MetricCard.scss

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,51 +2,40 @@
22

33
.ydb-metrics-card {
44
$b: &;
5+
6+
min-height: 252px;
7+
58
&__header {
69
display: flex;
710
justify-content: space-between;
811
align-items: center;
12+
gap: 8px;
913

1014
margin-bottom: 10px;
1115
}
1216

1317
&__label {
1418
font-weight: 600;
19+
20+
color: var(--g-color-text-link);
1521
@include lead-typography();
1622
}
1723

1824
&__content {
1925
display: flex;
2026
flex-direction: column;
21-
align-items: center;
22-
23-
text-align: center;
27+
gap: 10px;
2428

2529
color: var(--g-color-text-secondary);
26-
27-
@include header-1-typography();
2830
}
2931

30-
&__progress {
31-
font-size: 36px;
32-
font-weight: 500;
33-
line-height: 40px;
34-
text-align: center;
35-
}
36-
37-
&__resources {
38-
font-size: var(--g-text-body-1-font-size);
39-
40-
color: var(--g-color-text-secondary);
32+
&__metric-title {
33+
height: var(--g-text-body-2-line-height);
4134
}
4235

4336
&_active {
4437
#{$b}__content {
4538
color: var(--g-color-text-complementary);
4639
}
47-
48-
#{$b}__progress-bar-circle-bg {
49-
stroke: var(--g-color-base-float);
50-
}
5140
}
5241
}
Lines changed: 40 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,61 @@
1-
import {CircularProgressBar} from '../../../../../../components/CircularProgressBar/CircularProgressBar';
21
import {DiagnosticCard} from '../../../../../../components/DiagnosticCard/DiagnosticCard';
2+
import {ProgressViewer} from '../../../../../../components/ProgressViewer/ProgressViewer';
3+
import type {ProgressViewerProps} from '../../../../../../components/ProgressViewer/ProgressViewer';
4+
import {StatusIcon} from '../../../../../../components/StatusIcon/StatusIcon';
35
import type {MetricStatus} from '../../../../../../store/reducers/tenants/types';
4-
import {formatUsage} from '../../../../../../store/reducers/tenants/utils';
6+
import {EFlag} from '../../../../../../types/api/enums';
57
import {cn} from '../../../../../../utils/cn';
6-
import i18n from '../../i18n';
78

89
import './MetricCard.scss';
910

1011
const b = cn('ydb-metrics-card');
1112

13+
const getStatusIcon = (status?: MetricStatus) => {
14+
let colorStatus: EFlag | undefined;
15+
16+
if (status === 'Warning') {
17+
colorStatus = EFlag.Yellow;
18+
}
19+
if (status === 'Danger') {
20+
colorStatus = EFlag.Red;
21+
}
22+
23+
if (colorStatus) {
24+
return <StatusIcon status={colorStatus} mode="icons" size="l" />;
25+
}
26+
27+
return null;
28+
};
29+
30+
export interface DiagnosticsCardMetric extends ProgressViewerProps {
31+
title?: React.ReactNode;
32+
}
33+
1234
interface MetricCardProps {
1335
active?: boolean;
14-
progress?: number;
1536
label?: string;
1637
status?: MetricStatus;
17-
resourcesUsed?: string;
38+
metrics: DiagnosticsCardMetric[];
1839
}
1940

20-
export function MetricCard({active, progress, label, status, resourcesUsed}: MetricCardProps) {
41+
export function MetricCard({active, label, status, metrics}: MetricCardProps) {
2142
const renderContent = () => {
22-
if (progress === undefined && resourcesUsed === undefined) {
23-
return <div className={b('content')}>{i18n('no-data')}</div>;
24-
}
25-
26-
return (
27-
<div className={b('content')}>
28-
{progress && <div className={b('progress')}>{formatUsage(progress)}</div>}
29-
{resourcesUsed && <div className={b('resources')}>{resourcesUsed}</div>}
30-
</div>
31-
);
43+
return metrics.map(({title, ...progressViewerProps}, index) => {
44+
return (
45+
<div key={index} className={b('metric')}>
46+
<div className={b('metric-title')}>{title}</div>
47+
<ProgressViewer size="xs" colorizeProgress={true} {...progressViewerProps} />
48+
</div>
49+
);
50+
});
3251
};
3352
return (
3453
<DiagnosticCard className={b({active})} active={active}>
35-
<div className={b('header')}>{label && <div className={b('label')}>{label}</div>}</div>
36-
<CircularProgressBar
37-
size={172}
38-
strokeWidth={11}
39-
progress={progress || 0}
40-
content={renderContent()}
41-
status={status}
42-
circleBgClassName={b('progress-bar-circle-bg')}
43-
/>
54+
<div className={b('header')}>
55+
{label && <div className={b('label')}>{label}</div>}
56+
{getStatusIcon(status)}
57+
</div>
58+
<div className={b('content')}>{renderContent()}</div>
4459
</DiagnosticCard>
4560
);
4661
}

0 commit comments

Comments
 (0)