Skip to content

Commit 7477f0e

Browse files
committed
feat: redesign Storage section
1 parent c170578 commit 7477f0e

File tree

17 files changed

+194
-22
lines changed

17 files changed

+194
-22
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: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
@use '../../styles/mixins.scss';
2+
13
.info-viewer {
24
--ydb-info-viewer-font-size: var(--g-text-body-2-font-size);
35
--ydb-info-viewer-line-height: var(--g-text-body-2-line-height);
@@ -28,6 +30,10 @@
2830

2931
max-width: 100%;
3032
padding-top: 4px;
33+
34+
&:first-child {
35+
padding-top: 0;
36+
}
3137
}
3238

3339
&__label {
@@ -88,4 +94,18 @@
8894
}
8995
}
9096
}
97+
98+
&_variant_storage {
99+
.info-viewer__title {
100+
margin: 0 0 var(--g-spacing-3);
101+
102+
color: var(--g-color-text-primary);
103+
@include mixins.subheader-1-typography();
104+
}
105+
106+
.info-viewer__label {
107+
color: var(--g-color-text-secondary);
108+
@include mixins.body-1-typography();
109+
}
110+
}
91111
}

src/components/InfoViewer/InfoViewer.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export interface InfoViewerProps {
1616
info?: InfoViewerItem[];
1717
dots?: boolean;
1818
size?: 's';
19+
variant?: 'default' | 'storage';
1920
className?: string;
2021
multilineLabels?: boolean;
2122
renderEmptyState?: (props?: Pick<InfoViewerProps, 'title' | 'size'>) => React.ReactNode;
@@ -28,6 +29,7 @@ export const InfoViewer = ({
2829
info,
2930
dots = true,
3031
size,
32+
variant = 'default',
3133
className,
3234
multilineLabels,
3335
renderEmptyState,
@@ -37,7 +39,7 @@ export const InfoViewer = ({
3739
}
3840

3941
return (
40-
<div className={b({size}, className)}>
42+
<div className={b({size, variant}, className)}>
4143
{title && <div className={b('title')}>{title}</div>}
4244
{info && info.length > 0 ? (
4345
<div className={b('items')}>

src/components/ProgressViewer/ProgressViewer.scss

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,4 +109,31 @@
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+
}
112139
}

src/components/ProgressViewer/ProgressViewer.tsx

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
1-
import {useTheme} from '@gravity-ui/uikit';
1+
import {Flex, Text, 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+
810
import './ProgressViewer.scss';
911

1012
const b = cn('progress-viewer');
1113

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

1416
export type FormatProgressViewerValues = (
1517
value?: number,
@@ -107,7 +109,29 @@ export function ProgressViewer({
107109
return valueText;
108110
};
109111

112+
const isStorageVariant = size === 'storage';
113+
110114
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+
111135
return (
112136
<div className={b({size, theme, status}, className)}>
113137
<div className={b('line')} style={lineStyle}></div>
@@ -116,5 +140,5 @@ export function ProgressViewer({
116140
);
117141
}
118142

119-
return <div className={`${b({size})} ${className} error`}>no data</div>;
143+
return <div className={`${b({size})} ${className || ''} error`}>{i18n('no-data')}</div>;
120144
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"value_of_capacity": "{{value}} of {{capacity}}",
3+
"no-data": "no data"
4+
}
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-progress-viewer';
6+
7+
export default registerKeysets(COMPONENT, {en});

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
.ydb-tenant-dashboard {
22
width: var(--diagnostics-section-table-width);
3-
margin-bottom: var(--diagnostics-section-margin);
3+
margin-bottom: var(--g-spacing-4);
44

55
&__charts {
66
display: flex;
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
.tenant-storage {
2+
&__tabs-container {
3+
margin-top: var(--g-spacing-3);
4+
}
5+
6+
&__tab-content {
7+
margin-top: var(--g-spacing-3);
8+
}
9+
}

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

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,29 @@
11
import React from 'react';
22

3+
import {Tab, TabList, TabProvider} from '@gravity-ui/uikit';
4+
35
import {InfoViewer} from '../../../../../components/InfoViewer/InfoViewer';
46
import {LabelWithPopover} from '../../../../../components/LabelWithPopover';
57
import {ProgressViewer} from '../../../../../components/ProgressViewer/ProgressViewer';
8+
import {TENANT_STORAGE_TABS_IDS} from '../../../../../store/reducers/tenant/constants';
9+
import {cn} from '../../../../../utils/cn';
610
import {formatStorageValues} from '../../../../../utils/dataFormatters/dataFormatters';
711
import {TenantDashboard} from '../TenantDashboard/TenantDashboard';
812
import i18n from '../i18n';
9-
import {b} from '../utils';
1013

1114
import {TopGroups} from './TopGroups';
1215
import {TopTables} from './TopTables';
1316
import {storageDashboardConfig} from './storageDashboardConfig';
17+
import {useTenantStorageQueryParams} from './useTenantStorageQueryParams';
18+
19+
import './TenantStorage.scss';
1420

15-
import '../TenantOverview.scss';
21+
const tenantStorageCn = cn('tenant-storage');
22+
23+
const storageTabs = [
24+
{id: TENANT_STORAGE_TABS_IDS.tables, title: i18n('title_top-tables-by-size')},
25+
{id: TENANT_STORAGE_TABS_IDS.groups, title: i18n('title_top-groups-by-usage')},
26+
];
1627

1728
export interface TenantStorageMetrics {
1829
blobStorageUsed?: number;
@@ -27,8 +38,21 @@ interface TenantStorageProps {
2738
}
2839

2940
export function TenantStorage({tenantName, metrics}: TenantStorageProps) {
41+
const {storageTab, handleStorageTabChange} = useTenantStorageQueryParams();
42+
3043
const {blobStorageUsed, tabletStorageUsed, blobStorageLimit, tabletStorageLimit} = metrics;
3144

45+
const renderTabContent = () => {
46+
switch (storageTab) {
47+
case TENANT_STORAGE_TABS_IDS.tables:
48+
return <TopTables database={tenantName} />;
49+
case TENANT_STORAGE_TABS_IDS.groups:
50+
return <TopGroups tenant={tenantName} />;
51+
default:
52+
return null;
53+
}
54+
};
55+
3256
const info = [
3357
{
3458
label: (
@@ -43,6 +67,7 @@ export function TenantStorage({tenantName, metrics}: TenantStorageProps) {
4367
capacity={tabletStorageLimit}
4468
formatValues={formatStorageValues}
4569
colorizeProgress={true}
70+
size="storage"
4671
/>
4772
),
4873
},
@@ -59,6 +84,7 @@ export function TenantStorage({tenantName, metrics}: TenantStorageProps) {
5984
capacity={blobStorageLimit}
6085
formatValues={formatStorageValues}
6186
colorizeProgress={true}
87+
size="storage"
6288
/>
6389
),
6490
},
@@ -67,9 +93,27 @@ export function TenantStorage({tenantName, metrics}: TenantStorageProps) {
6793
return (
6894
<React.Fragment>
6995
<TenantDashboard database={tenantName} charts={storageDashboardConfig} />
70-
<InfoViewer className={b('storage-info')} title="Storage details" info={info} />
71-
<TopTables database={tenantName} />
72-
<TopGroups tenant={tenantName} />
96+
<InfoViewer
97+
variant="storage"
98+
title={i18n('storage.storage-details-title')}
99+
info={info}
100+
/>
101+
102+
<div className={tenantStorageCn('tabs-container')}>
103+
<TabProvider value={storageTab}>
104+
<TabList size="m">
105+
{storageTabs.map(({id, title}) => {
106+
return (
107+
<Tab key={id} value={id} onClick={() => handleStorageTabChange(id)}>
108+
{title}
109+
</Tab>
110+
);
111+
})}
112+
</TabList>
113+
</TabProvider>
114+
115+
<div className={tenantStorageCn('tab-content')}>{renderTabContent()}</div>
116+
</div>
73117
</React.Fragment>
74118
);
75119
}

0 commit comments

Comments
 (0)