Skip to content

Commit 187032b

Browse files
feat(Node): rework page (#1917)
1 parent e888fe3 commit 187032b

24 files changed

+404
-386
lines changed

src/components/BasicNodeViewer/BasicNodeViewer.scss

-35
This file was deleted.

src/components/BasicNodeViewer/BasicNodeViewer.tsx

-73
This file was deleted.

src/components/BasicNodeViewer/index.ts

-1
This file was deleted.

src/components/EntityPageTitle/EntityPageTitle.tsx

+8-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type {EFlag} from '../../types/api/enums';
1+
import {EFlag} from '../../types/api/enums';
22
import {cn} from '../../utils/cn';
33
import {StatusIcon} from '../StatusIcon/StatusIcon';
44

@@ -8,12 +8,17 @@ const b = cn('ydb-entity-page-title');
88

99
interface EntityPageTitleProps {
1010
entityName: React.ReactNode;
11-
status: EFlag;
11+
status?: EFlag;
1212
id: React.ReactNode;
1313
className?: string;
1414
}
1515

16-
export function EntityPageTitle({entityName, status, id, className}: EntityPageTitleProps) {
16+
export function EntityPageTitle({
17+
entityName,
18+
status = EFlag.Grey,
19+
id,
20+
className,
21+
}: EntityPageTitleProps) {
1722
return (
1823
<div className={b(null, className)}>
1924
<span className={b('prefix')}>{entityName}</span>

src/components/FullNodeViewer/FullNodeViewer.scss

+8-8
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,13 @@
33
.full-node-viewer {
44
@include mixins.body-2-typography();
55

6-
&__common-info {
6+
&__section {
77
display: flex;
88
flex-direction: column;
9-
justify-content: flex-start;
10-
align-items: stretch;
11-
}
129

13-
&__section {
14-
border-radius: 10px;
10+
width: max-content;
11+
min-width: 300px;
12+
max-width: 500px;
1513

1614
&_pools {
1715
display: grid;
@@ -26,8 +24,10 @@
2624
}
2725

2826
&__section-title {
29-
margin: 15px 0 10px;
27+
@include mixins.info-viewer-title();
28+
}
3029

31-
font-weight: 600;
30+
&__role {
31+
color: var(--g-color-text-secondary);
3232
}
3333
}
Original file line numberDiff line numberDiff line change
@@ -1,83 +1,123 @@
1+
import {Flex} from '@gravity-ui/uikit';
2+
13
import type {PreparedNode} from '../../store/reducers/node/types';
24
import {cn} from '../../utils/cn';
3-
import {LOAD_AVERAGE_TIME_INTERVALS} from '../../utils/constants';
5+
import {useNodeDeveloperUIHref} from '../../utils/hooks/useNodeDeveloperUIHref';
46
import {InfoViewer} from '../InfoViewer/InfoViewer';
57
import type {InfoViewerItem} from '../InfoViewer/InfoViewer';
8+
import {LinkWithIcon} from '../LinkWithIcon/LinkWithIcon';
69
import {PoolUsage} from '../PoolUsage/PoolUsage';
710
import {ProgressViewer} from '../ProgressViewer/ProgressViewer';
811
import {NodeUptime} from '../UptimeViewer/UptimeViewer';
912

13+
import i18n from './i18n';
14+
1015
import './FullNodeViewer.scss';
1116

1217
const b = cn('full-node-viewer');
1318

1419
interface FullNodeViewerProps {
15-
node: PreparedNode | undefined;
20+
node?: PreparedNode;
1621
className?: string;
1722
}
23+
const getLoadAverageIntervalTitle = (index: number) => {
24+
return [i18n('la-interval-1m'), i18n('la-interval-5m'), i18n('la-interval-15m')][index];
25+
};
1826

1927
export const FullNodeViewer = ({node, className}: FullNodeViewerProps) => {
20-
const endpointsInfo = node?.Endpoints?.map(({Name, Address}) => ({
21-
label: Name,
22-
value: Address,
23-
}));
28+
const developerUIHref = useNodeDeveloperUIHref(node);
2429

2530
const commonInfo: InfoViewerItem[] = [];
2631

27-
// Do not add DB field for static nodes (they have no Tenants)
2832
if (node?.Tenants?.length) {
29-
commonInfo.push({label: 'Database', value: node.Tenants[0]});
33+
commonInfo.push({label: i18n('database'), value: node.Tenants[0]});
3034
}
3135

3236
commonInfo.push(
33-
{label: 'Version', value: node?.Version},
37+
{label: i18n('version'), value: node?.Version},
3438
{
35-
label: 'Uptime',
39+
label: i18n('uptime'),
3640
value: <NodeUptime StartTime={node?.StartTime} DisconnectTime={node?.DisconnectTime} />,
3741
},
38-
{label: 'DC', value: node?.DataCenterDescription || node?.DC},
39-
{label: 'Rack', value: node?.Rack},
42+
{label: i18n('dc'), value: node?.DataCenterDescription || node?.DC},
4043
);
4144

45+
if (node?.Rack) {
46+
commonInfo.push({label: i18n('rack'), value: node?.Rack});
47+
}
48+
49+
if (developerUIHref) {
50+
commonInfo.push({
51+
label: i18n('links'),
52+
value: <LinkWithIcon url={developerUIHref} title={i18n('developer-ui')} />,
53+
});
54+
}
55+
56+
const endpointsInfo = node?.Endpoints?.map(({Name, Address}) => ({
57+
label: Name,
58+
value: Address,
59+
}));
60+
4261
const averageInfo = node?.LoadAveragePercents?.map((load, loadIndex) => ({
43-
label: LOAD_AVERAGE_TIME_INTERVALS[loadIndex],
62+
label: getLoadAverageIntervalTitle(loadIndex),
4463
value: (
4564
<ProgressViewer value={load} percents={true} colorizeProgress={true} capacity={100} />
4665
),
4766
}));
4867

68+
if (!node) {
69+
return <div className="error">{i18n('no-data')}</div>;
70+
}
71+
4972
return (
50-
<div className={`${b()} ${className}`}>
51-
{node ? (
52-
<div className={b('common-info')}>
73+
<div className={b(null, className)}>
74+
<Flex wrap gap={4}>
75+
<Flex direction="column" gap={2}>
76+
<InfoViewer
77+
title={i18n('title.common-info')}
78+
className={b('section')}
79+
info={commonInfo}
80+
/>
81+
82+
{endpointsInfo && endpointsInfo.length ? (
83+
<InfoViewer
84+
title={i18n('title.endpoints')}
85+
className={b('section')}
86+
info={endpointsInfo}
87+
/>
88+
) : null}
89+
</Flex>
90+
91+
<Flex direction="column" gap={2}>
5392
<div>
54-
<div className={b('section-title')}>Pools</div>
93+
<div className={b('section-title')}>{i18n('title.pools')}</div>
5594
<div className={b('section', {pools: true})}>
5695
{node?.PoolStats?.map((pool, poolIndex) => (
5796
<PoolUsage key={poolIndex} data={pool} />
5897
))}
5998
</div>
6099
</div>
61100

62-
{endpointsInfo && endpointsInfo.length && (
63-
<InfoViewer
64-
title="Endpoints"
65-
className={b('section')}
66-
info={endpointsInfo}
67-
/>
68-
)}
69-
70-
<InfoViewer title="Common info" className={b('section')} info={commonInfo} />
71-
72101
<InfoViewer
73-
title="Load average"
102+
title={i18n('title.load-average')}
74103
className={b('section', {average: true})}
75104
info={averageInfo}
76105
/>
77-
</div>
78-
) : (
79-
<div className="error">no data</div>
80-
)}
106+
</Flex>
107+
108+
{node.Roles && node.Roles.length ? (
109+
<Flex direction="column" gap={2}>
110+
<div className={b('section')}>
111+
<div className={b('section-title')}>{i18n('title.roles')}</div>
112+
{node?.Roles?.map((role) => (
113+
<div className={b('role')} key={role}>
114+
{role}
115+
</div>
116+
))}
117+
</div>
118+
</Flex>
119+
) : null}
120+
</Flex>
81121
</div>
82122
);
83123
};
+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"database": "Database",
3+
"uptime": "Uptime",
4+
"version": "Version",
5+
"dc": "DC",
6+
"rack": "Rack",
7+
"links": "Links",
8+
9+
"la-interval-1m": "1 min",
10+
"la-interval-5m": "5 min",
11+
"la-interval-15m": "15 min",
12+
13+
"developer-ui": "Developer UI",
14+
"no-data": "No data",
15+
16+
"title.common-info": "Common info",
17+
"title.endpoints": "Endpoints",
18+
"title.roles": "Roles",
19+
"title.pools": "Pools",
20+
"title.load-average": "Load average"
21+
}
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-node-info';
6+
7+
export default registerKeysets(COMPONENT, {en});

src/components/NodeHostWrapper/NodeHostWrapper.tsx

+7-3
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,13 @@ export const NodeHostWrapper = ({
5454
}
5555

5656
const nodePath = isNodeAvailable
57-
? getDefaultNodePath(node.NodeId, {
58-
database: database ?? node.TenantName,
59-
})
57+
? getDefaultNodePath(
58+
node.NodeId,
59+
{
60+
database: database ?? node.TenantName,
61+
},
62+
node.TenantName ? 'tablets' : 'storage',
63+
)
6064
: undefined;
6165

6266
return (

src/components/PageMeta/PageMeta.tsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,15 @@ interface PageMetaProps {
1414
loading?: boolean;
1515
}
1616

17+
const separator = '\u00a0\u00a0\u00B7\u00a0\u00a0';
18+
1719
export function PageMeta({items, loading}: PageMetaProps) {
1820
const renderContent = () => {
1921
if (loading) {
2022
return <Skeleton className={b('skeleton')} />;
2123
}
2224

23-
return items.filter((item) => Boolean(item)).join('\u00a0\u00a0\u00B7\u00a0\u00a0');
25+
return items.filter((item) => Boolean(item)).join(separator);
2426
};
2527

2628
return <div className={b('info')}>{renderContent()}</div>;

0 commit comments

Comments
 (0)