Skip to content

Commit 08b44f0

Browse files
committed
fix: refactor
1 parent 7477f0e commit 08b44f0

File tree

11 files changed

+150
-67
lines changed

11 files changed

+150
-67
lines changed

src/components/Errors/ResponseError/ResponseError.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,5 @@ export const ResponseError = ({
1414
}: ResponseErrorProps) => {
1515
const message = prepareErrorMessage(error) || defaultMessage;
1616

17-
return <div className={`error ${className || ''}`}>{message}</div>;
17+
return <div className={`error ${className}`}>{message}</div>;
1818
};

src/components/InfoViewer/InfoViewer.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@
9595
}
9696
}
9797

98-
&_variant_storage {
98+
&_variant_small {
9999
.info-viewer__title {
100100
margin: 0 0 var(--g-spacing-3);
101101

src/components/InfoViewer/InfoViewer.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export interface InfoViewerProps {
1616
info?: InfoViewerItem[];
1717
dots?: boolean;
1818
size?: 's';
19-
variant?: 'default' | 'storage';
19+
variant?: 'default' | 'small';
2020
className?: string;
2121
multilineLabels?: boolean;
2222
renderEmptyState?: (props?: Pick<InfoViewerProps, 'title' | 'size'>) => React.ReactNode;

src/components/ProgressViewer/ProgressViewer.scss

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -109,31 +109,4 @@
109109
font-size: var(--g-text-body-1-font-size);
110110
line-height: 36px;
111111
}
112-
113-
&_size_storage {
114-
position: relative;
115-
116-
width: 400px;
117-
min-width: unset;
118-
height: 10px;
119-
padding: 0;
120-
121-
border-radius: var(--g-border-radius-xs);
122-
background: var(--g-color-private-white-100);
123-
124-
#{$block}__progress-container {
125-
position: relative;
126-
127-
width: 100%;
128-
height: 100%;
129-
130-
border-radius: inherit;
131-
background: inherit;
132-
}
133-
134-
#{$block}__line {
135-
border-radius: var(--g-border-radius-xs);
136-
background-color: var(--g-color-private-green-450);
137-
}
138-
}
139112
}

src/components/ProgressViewer/ProgressViewer.tsx

Lines changed: 3 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,15 @@
1-
import {Flex, Text, useTheme} from '@gravity-ui/uikit';
1+
import {useTheme} from '@gravity-ui/uikit';
22

33
import {cn} from '../../utils/cn';
44
import {formatNumber, roundToPrecision} from '../../utils/dataFormatters/dataFormatters';
55
import {calculateProgressStatus} from '../../utils/progress';
66
import {isNumeric} from '../../utils/utils';
77

8-
import i18n from './i18n';
9-
108
import './ProgressViewer.scss';
119

1210
const b = cn('progress-viewer');
1311

14-
type ProgressViewerSize = 'xs' | 's' | 'ns' | 'm' | 'n' | 'l' | 'head' | 'storage';
12+
type ProgressViewerSize = 'xs' | 's' | 'ns' | 'm' | 'n' | 'l' | 'head';
1513

1614
export type FormatProgressViewerValues = (
1715
value?: number,
@@ -109,29 +107,7 @@ export function ProgressViewer({
109107
return valueText;
110108
};
111109

112-
const isStorageVariant = size === 'storage';
113-
114110
if (isNumeric(value)) {
115-
if (isStorageVariant) {
116-
const storageDisplayText =
117-
isNumeric(capacity) && !hideCapacity
118-
? i18n('value_of_capacity', {value: valueText, capacity: capacityText})
119-
: valueText;
120-
121-
return (
122-
<Flex alignItems="center" gap="2" className={className}>
123-
<div className={b({size, theme, status})}>
124-
<div className={b('progress-container')}>
125-
<div className={b('line')} style={lineStyle}></div>
126-
</div>
127-
</div>
128-
<Text variant="body-2" color="secondary">
129-
{storageDisplayText}
130-
</Text>
131-
</Flex>
132-
);
133-
}
134-
135111
return (
136112
<div className={b({size, theme, status}, className)}>
137113
<div className={b('line')} style={lineStyle}></div>
@@ -140,5 +116,5 @@ export function ProgressViewer({
140116
);
141117
}
142118

143-
return <div className={`${b({size})} ${className || ''} error`}>{i18n('no-data')}</div>;
119+
return <div className={`${b({size})} ${className} error`}>no data</div>;
144120
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
.progress-wrapper {
2+
&__storage-progress {
3+
.g-progress {
4+
// Match Figma design using design tokens
5+
height: 10px;
6+
7+
border-radius: var(--g-border-radius-xs);
8+
9+
// Background color from Figma: rgba(255, 255, 255, 0.1)
10+
background-color: var(--g-color-private-white-100);
11+
}
12+
}
13+
}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
import React from 'react';
2+
3+
import {Flex, Progress, Text} from '@gravity-ui/uikit';
4+
5+
import type {FormatProgressViewerValues} from '../../../../../components/ProgressViewer/ProgressViewer';
6+
import {cn} from '../../../../../utils/cn';
7+
import {isNumeric, safeParseNumber} from '../../../../../utils/utils';
8+
9+
import {DEFAULT_PROGRESS_WIDTH, MAX_PERCENTAGE, MIN_PERCENTAGE, PROGRESS_SIZES} from './constants';
10+
import i18n from './i18n';
11+
12+
import './ProgressWrapper.scss';
13+
14+
interface ProgressWrapperProps {
15+
value?: number | string;
16+
capacity?: number | string;
17+
formatValues?: FormatProgressViewerValues;
18+
size?: 'storage';
19+
className?: string;
20+
width?: number;
21+
}
22+
23+
const defaultFormatValues: FormatProgressViewerValues = (value, total) => {
24+
return [value, total];
25+
};
26+
27+
const b = cn('progress-wrapper');
28+
29+
export function ProgressWrapper({
30+
value,
31+
capacity,
32+
formatValues = defaultFormatValues,
33+
size = 'storage',
34+
className,
35+
width = DEFAULT_PROGRESS_WIDTH,
36+
}: ProgressWrapperProps) {
37+
// Input validation and error handling
38+
if (!isNumeric(value)) {
39+
return <div className={className}>{i18n('alert_no-data')}</div>;
40+
}
41+
42+
const numericValue = safeParseNumber(value);
43+
const numericCapacity = safeParseNumber(capacity);
44+
45+
// Handle edge cases: negative values, zero capacity
46+
if (numericValue < 0) {
47+
return <div className={className}>{i18n('alert_no-data')}</div>;
48+
}
49+
50+
if (numericCapacity <= 0 && capacity !== undefined) {
51+
return <div className={className}>{i18n('alert_no-data')}</div>;
52+
}
53+
54+
// Calculate percentage for uikit Progress with proper bounds checking
55+
const rawPercentage = Math.floor((numericValue / numericCapacity) * MAX_PERCENTAGE);
56+
const fillWidth = Math.max(MIN_PERCENTAGE, rawPercentage);
57+
const clampedFillWidth = Math.min(fillWidth, MAX_PERCENTAGE);
58+
59+
// Get formatted display text - match original ProgressViewer exactly
60+
const [valueText, capacityText] = React.useMemo(() => {
61+
if (formatValues) {
62+
return formatValues(Number(value), Number(capacity));
63+
}
64+
return [value, capacity];
65+
}, [formatValues, value, capacity]);
66+
67+
// For storage variant, we always use the Figma green color regardless of colorizeProgress
68+
// This matches the original ProgressViewer behavior for storage size
69+
70+
// Memoize display text to avoid unnecessary recalculations
71+
const displayText = React.useMemo(() => {
72+
if (!isNumeric(numericCapacity) || numericCapacity <= 0) {
73+
return String(valueText);
74+
}
75+
return i18n('value_of_capacity', {value: valueText, capacity: capacityText});
76+
}, [valueText, capacityText, numericCapacity]);
77+
78+
// Validate width prop
79+
const validatedWidth = Math.max(0, width);
80+
81+
// For storage variant, use Flex layout similar to current ProgressViewer
82+
if (size === 'storage') {
83+
return (
84+
<Flex alignItems="center" gap="2" className={className}>
85+
<div className={b('storage-progress')} style={{width: `${validatedWidth}px`}}>
86+
<Progress
87+
value={clampedFillWidth}
88+
theme="success"
89+
size={PROGRESS_SIZES.STORAGE}
90+
/>
91+
</div>
92+
<Text variant="body-1" color="secondary">
93+
{displayText}
94+
</Text>
95+
</Flex>
96+
);
97+
}
98+
99+
// Default layout (though we're only using storage variant for now)
100+
return (
101+
<div className={className}>
102+
<Progress value={clampedFillWidth} text={displayText} size={PROGRESS_SIZES.DEFAULT} />
103+
</div>
104+
);
105+
}

src/containers/Tenant/Diagnostics/TenantOverview/TenantStorage/TenantStorage.tsx

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ import {Tab, TabList, TabProvider} from '@gravity-ui/uikit';
44

55
import {InfoViewer} from '../../../../../components/InfoViewer/InfoViewer';
66
import {LabelWithPopover} from '../../../../../components/LabelWithPopover';
7-
import {ProgressViewer} from '../../../../../components/ProgressViewer/ProgressViewer';
87
import {TENANT_STORAGE_TABS_IDS} from '../../../../../store/reducers/tenant/constants';
98
import {cn} from '../../../../../utils/cn';
109
import {formatStorageValues} from '../../../../../utils/dataFormatters/dataFormatters';
1110
import {TenantDashboard} from '../TenantDashboard/TenantDashboard';
1211
import i18n from '../i18n';
1312

13+
import {ProgressWrapper} from './ProgressWrapper';
1414
import {TopGroups} from './TopGroups';
1515
import {TopTables} from './TopTables';
1616
import {storageDashboardConfig} from './storageDashboardConfig';
@@ -62,11 +62,10 @@ export function TenantStorage({tenantName, metrics}: TenantStorageProps) {
6262
/>
6363
),
6464
value: (
65-
<ProgressViewer
65+
<ProgressWrapper
6666
value={tabletStorageUsed}
6767
capacity={tabletStorageLimit}
6868
formatValues={formatStorageValues}
69-
colorizeProgress={true}
7069
size="storage"
7170
/>
7271
),
@@ -79,11 +78,10 @@ export function TenantStorage({tenantName, metrics}: TenantStorageProps) {
7978
/>
8079
),
8180
value: (
82-
<ProgressViewer
81+
<ProgressWrapper
8382
value={blobStorageUsed}
8483
capacity={blobStorageLimit}
8584
formatValues={formatStorageValues}
86-
colorizeProgress={true}
8785
size="storage"
8886
/>
8987
),
@@ -93,11 +91,7 @@ export function TenantStorage({tenantName, metrics}: TenantStorageProps) {
9391
return (
9492
<React.Fragment>
9593
<TenantDashboard database={tenantName} charts={storageDashboardConfig} />
96-
<InfoViewer
97-
variant="storage"
98-
title={i18n('storage.storage-details-title')}
99-
info={info}
100-
/>
94+
<InfoViewer variant="small" title={i18n('storage.storage-details-title')} info={info} />
10195

10296
<div className={tenantStorageCn('tabs-container')}>
10397
<TabProvider value={storageTab}>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Progress wrapper constants following project patterns
2+
export const DEFAULT_PROGRESS_WIDTH = 400;
3+
export const PROGRESS_HEIGHT = 10;
4+
export const MAX_PERCENTAGE = 100;
5+
export const MIN_PERCENTAGE = 0;
6+
7+
// Progress size mappings for uikit Progress component
8+
export const PROGRESS_SIZES = {
9+
STORAGE: 'xs',
10+
DEFAULT: 'm',
11+
} as const;
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"alert_no-data": "No data",
3+
"value_of_capacity": "{{value}} of {{capacity}}"
4+
}

0 commit comments

Comments
 (0)