Skip to content

Commit 189aa30

Browse files
fix(Versions): replace radio with sections
1 parent 75a950b commit 189aa30

File tree

4 files changed

+106
-175
lines changed

4 files changed

+106
-175
lines changed

src/containers/Versions/NodesTreeTitle/NodesTreeTitle.tsx

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
import React from 'react';
22

3-
import {ChevronDown, ChevronUp, Database} from '@gravity-ui/icons';
4-
import {ClipboardButton, Flex, Icon, Text} from '@gravity-ui/uikit';
3+
import {ArrowRight, ChevronDown, ChevronUp, Database} from '@gravity-ui/icons';
4+
import {Button, ClipboardButton, Flex, Icon, Text} from '@gravity-ui/uikit';
55

6+
import {InternalLink} from '../../../components/InternalLink';
67
import {VersionsBar} from '../../../components/VersionsBar/VersionsBar';
78
import {cn} from '../../../utils/cn';
89
import type {PreparedNodeSystemState} from '../../../utils/nodes';
910
import type {PreparedVersion} from '../../../utils/versions/types';
11+
import {getTenantPath} from '../../Tenant/TenantPages';
1012
import i18n from '../i18n';
1113
import type {GroupedNodesItem} from '../types';
1214

@@ -59,6 +61,31 @@ export const NodesTreeTitle = ({
5961
}
6062
}, [items, nodes]);
6163

64+
const renderNodesCount = () => {
65+
if (isDatabase) {
66+
return (
67+
<InternalLink
68+
to={getTenantPath({
69+
database: title,
70+
diagnosticsTab: 'nodes',
71+
})}
72+
tabIndex={0}
73+
>
74+
<Button size="s">
75+
{i18n('nodes-count', {count: nodesAmount})}
76+
<Icon data={ArrowRight} />
77+
</Button>
78+
</InternalLink>
79+
);
80+
}
81+
82+
return (
83+
<Text variant="body-2" color="hint">
84+
{i18n('nodes-count', {count: nodesAmount})}
85+
</Text>
86+
);
87+
};
88+
6289
return (
6390
<div className={b('overview')} onClick={handleClick}>
6491
<Flex gap={2} alignItems={'center'}>
@@ -77,12 +104,10 @@ export const NodesTreeTitle = ({
77104
/>
78105
</React.Fragment>
79106
) : null}
80-
<Text variant="body-2" color="hint">
81-
{i18n('nodes-count', {count: nodesAmount})}
82-
</Text>
107+
{renderNodesCount()}
83108
</Flex>
84109
<Flex alignItems={'center'} gap={4}>
85-
{preparedVersions ? (
110+
{isDatabase && preparedVersions ? (
86111
<div className={b('version-progress')}>
87112
<VersionsBar preparedVersions={preparedVersions} withTitles={false} />
88113
</div>

src/containers/Versions/Versions.scss

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,7 @@
99
font-size: var(--ydb-info-viewer-font-size);
1010
line-height: var(--ydb-info-viewer-line-height);
1111

12-
&__controls {
13-
margin-bottom: var(--g-spacing-3);
14-
}
1512
&__overall {
1613
margin-top: var(--g-spacing-4);
17-
margin-bottom: var(--g-spacing-6);
1814
}
1915
}
Lines changed: 75 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React from 'react';
22

33
import {ChevronsCollapseVertical, ChevronsExpandVertical} from '@gravity-ui/icons';
4-
import {Button, Flex, Icon, SegmentedRadioGroup, Select, Text} from '@gravity-ui/uikit';
4+
import {Button, Flex, Icon, Select, Text} from '@gravity-ui/uikit';
55
import {StringParam, useQueryParams} from 'use-query-params';
66
import {z} from 'zod';
77

@@ -15,10 +15,9 @@ import {useAutoRefreshInterval} from '../../utils/hooks';
1515
import type {PreparedVersion, VersionsDataMap} from '../../utils/versions/types';
1616

1717
import {GroupedNodesTree} from './GroupedNodesTree/GroupedNodesTree';
18-
import type {NodeType} from './constants';
19-
import {NODE_TYPES, NODE_TYPES_TITLE} from './constants';
2018
import {getGroupedStorageNodes, getGroupedTenantNodes, getOtherNodes} from './groupNodes';
2119
import i18n from './i18n';
20+
import type {GroupedNodesItem} from './types';
2221
import {GroupByValue} from './types';
2322
import {useGetPreparedVersions, useVersionsDataMap} from './utils';
2423

@@ -62,20 +61,15 @@ interface VersionsProps {
6261
versionsDataMap?: VersionsDataMap;
6362
}
6463

65-
const nodeTypeSchema = z.nativeEnum(NODE_TYPES).catch(NODE_TYPES.storage);
6664
const groupByValueSchema = z.nativeEnum(GroupByValue).catch(GroupByValue.VERSION);
6765

6866
function Versions({preparedVersions, nodes, versionsDataMap}: VersionsProps) {
69-
const [{nodeType: rawNodeType, groupBy: rawGroupByValue}, setQueryParams] = useQueryParams({
70-
nodeType: StringParam,
67+
const [{groupBy: rawGroupByValue}, setQueryParams] = useQueryParams({
7168
groupBy: StringParam,
7269
});
7370

74-
const nodeType = nodeTypeSchema.parse(rawNodeType);
7571
const groupByValue = groupByValueSchema.parse(rawGroupByValue);
7672

77-
const [expanded, setExpanded] = React.useState(false);
78-
7973
const tenantNodes = React.useMemo(() => {
8074
return getGroupedTenantNodes(nodes, versionsDataMap, groupByValue);
8175
}, [groupByValue, nodes, versionsDataMap]);
@@ -89,167 +83,100 @@ function Versions({preparedVersions, nodes, versionsDataMap}: VersionsProps) {
8983
const handleGroupByValueChange = (value: string) => {
9084
setQueryParams({groupBy: value as GroupByValue}, 'replaceIn');
9185
};
92-
const handleNodeTypeChange = (value: string) => {
93-
setQueryParams({nodeType: value as NodeType}, 'replaceIn');
94-
};
9586

96-
const renderExpandButton = () => {
87+
const renderGroupControl = () => {
88+
const options = [
89+
{value: GroupByValue.TENANT, content: i18n('title_database')},
90+
{value: GroupByValue.VERSION, content: i18n('title_version')},
91+
];
9792
return (
98-
<Button onClick={() => setExpanded((value) => !value)}>
99-
<Icon data={expanded ? ChevronsCollapseVertical : ChevronsExpandVertical} />
100-
{expanded ? i18n('action_collapse') : i18n('action_expand')}
101-
</Button>
93+
<Select
94+
label={i18n('group-by')}
95+
value={[groupByValue]}
96+
options={options}
97+
onUpdate={(values) => handleGroupByValueChange(values[0])}
98+
width={200}
99+
size="m"
100+
/>
102101
);
103102
};
104103

105-
const renderNodeTypeRadio = () => {
106-
const options = [
107-
<SegmentedRadioGroup.Option value={NODE_TYPES.storage}>
108-
{NODE_TYPES_TITLE.storage}
109-
</SegmentedRadioGroup.Option>,
110-
<SegmentedRadioGroup.Option value={NODE_TYPES.database}>
111-
{NODE_TYPES_TITLE.database}
112-
</SegmentedRadioGroup.Option>,
113-
];
104+
return (
105+
<Flex className={b()} direction={'column'} gap={6}>
106+
<Flex gap={3} direction={'column'} className={b('overall')}>
107+
<Text variant="subheader-3">{i18n('title_overall')}</Text>
108+
<VersionsBar preparedVersions={preparedVersions} size="m" />
109+
</Flex>
114110

115-
if (otherNodes?.length) {
116-
options.push(
117-
<SegmentedRadioGroup.Option value={NODE_TYPES.other}>
118-
{NODE_TYPES_TITLE.other}
119-
</SegmentedRadioGroup.Option>,
120-
);
121-
}
111+
<VersionsSection sectionTitle={i18n('title_storage-nodes')} nodes={storageNodes} />
112+
<VersionsSection
113+
sectionTitle={i18n('title_database-nodes')}
114+
nodes={tenantNodes}
115+
renderControls={renderGroupControl}
116+
/>
117+
<VersionsSection sectionTitle={i18n('title_other-nodes')} nodes={otherNodes} />
118+
</Flex>
119+
);
120+
}
122121

123-
return (
124-
<SegmentedRadioGroup value={nodeType} onUpdate={handleNodeTypeChange}>
125-
{options}
126-
</SegmentedRadioGroup>
127-
);
128-
};
122+
function VersionsSection({
123+
sectionTitle,
124+
renderControls,
125+
nodes,
126+
}: {
127+
sectionTitle: string;
128+
renderControls?: () => React.ReactNode;
129+
nodes?: GroupedNodesItem[];
130+
}) {
131+
const [expanded, setExpanded] = React.useState(false);
129132

130-
const renderGroupControl = () => {
131-
if (nodeType === NODE_TYPES.database) {
132-
const options = [
133-
{value: GroupByValue.TENANT, content: i18n('title_database')},
134-
{value: GroupByValue.VERSION, content: i18n('title_version')},
135-
];
136-
return (
137-
<Select
138-
label={i18n('group-by')}
139-
value={[groupByValue]}
140-
options={options}
141-
onUpdate={(values) => handleGroupByValueChange(values[0])}
142-
width={200}
143-
size="m"
144-
/>
145-
);
146-
}
133+
if (!nodes?.length) {
147134
return null;
148-
};
149-
const renderControls = () => {
135+
}
136+
137+
const renderExpandButton = () => {
150138
return (
151-
<Flex gap={3} className={b('controls')}>
152-
{renderNodeTypeRadio()}
153-
{renderGroupControl()}
154-
{renderExpandButton()}
155-
</Flex>
139+
<Button onClick={() => setExpanded((value) => !value)}>
140+
<Icon data={expanded ? ChevronsCollapseVertical : ChevronsExpandVertical} />
141+
{expanded ? i18n('action_collapse') : i18n('action_expand')}
142+
</Button>
156143
);
157144
};
158145

159-
const renderStorageNodes = () => {
160-
if (storageNodes?.length) {
161-
return storageNodes.map(({title, nodes: itemNodes, items, versionColor}) => (
146+
const renderNodes = () => {
147+
return nodes.map(
148+
({
149+
title,
150+
isDatabase,
151+
nodes: itemNodes,
152+
items,
153+
versionColor,
154+
preparedVersions: nodesVersions,
155+
}) => (
162156
<GroupedNodesTree
163-
key={`storage-nodes-${title}`}
157+
key={title}
164158
title={title}
159+
isDatabase={isDatabase}
165160
nodes={itemNodes}
166161
items={items}
167-
expanded={expanded}
168162
versionColor={versionColor}
163+
expanded={expanded}
164+
preparedVersions={nodesVersions}
169165
/>
170-
));
171-
}
172-
return null;
173-
};
174-
const renderDatabaseNodes = () => {
175-
if (tenantNodes?.length) {
176-
return tenantNodes.map(
177-
({
178-
title,
179-
isDatabase,
180-
nodes: itemNodes,
181-
items,
182-
versionColor,
183-
preparedVersions: nodesVersions,
184-
}) => (
185-
<GroupedNodesTree
186-
key={`tenant-nodes-${title}`}
187-
title={title}
188-
isDatabase={isDatabase}
189-
nodes={itemNodes}
190-
items={items}
191-
expanded={expanded}
192-
versionColor={versionColor}
193-
preparedVersions={nodesVersions}
194-
/>
195-
),
196-
);
197-
}
198-
return null;
199-
};
200-
201-
const renderOtherNodes = () => {
202-
if (otherNodes?.length) {
203-
return otherNodes.map(
204-
({
205-
title,
206-
nodes: itemNodes,
207-
items,
208-
versionColor,
209-
preparedVersions: nodesVersions,
210-
}) => (
211-
<GroupedNodesTree
212-
key={`other-nodes-${title}`}
213-
title={title}
214-
nodes={itemNodes}
215-
items={items}
216-
versionColor={versionColor}
217-
expanded={expanded}
218-
preparedVersions={nodesVersions}
219-
/>
220-
),
221-
);
222-
}
223-
return null;
224-
};
225-
226-
const renderContent = () => {
227-
switch (nodeType) {
228-
case NODE_TYPES.storage:
229-
return renderStorageNodes();
230-
case NODE_TYPES.database:
231-
return renderDatabaseNodes();
232-
case NODE_TYPES.other:
233-
return renderOtherNodes();
234-
default:
235-
return null;
236-
}
166+
),
167+
);
237168
};
238169

239-
const overallContent = (
240-
<Flex gap={3} direction={'column'} className={b('overall')}>
241-
<Text variant="subheader-3">{i18n('title_overall')}</Text>
242-
<VersionsBar preparedVersions={preparedVersions} size="m" />
243-
</Flex>
244-
);
245-
246170
return (
247-
<div className={b()}>
248-
{overallContent}
249-
{renderControls()}
250-
<Flex direction={'column'} gap={3}>
251-
{renderContent()}
171+
<Flex gap={3} direction={'column'}>
172+
<Flex justifyContent={'space-between'}>
173+
<Flex gap={3}>
174+
<Text variant="subheader-3">{sectionTitle}</Text>
175+
{renderControls?.()}
176+
</Flex>
177+
{renderExpandButton()}
252178
</Flex>
253-
</div>
179+
{renderNodes()}
180+
</Flex>
254181
);
255182
}

src/containers/Versions/constants.ts

Lines changed: 0 additions & 17 deletions
This file was deleted.

0 commit comments

Comments
 (0)