Skip to content

Commit a614a8c

Browse files
fix(TopicStats): use prepared stats, update fields
1 parent 14ac58a commit a614a8c

File tree

13 files changed

+79
-84
lines changed

13 files changed

+79
-84
lines changed

src/components/InfoViewer/InfoViewer.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import cn from 'bem-cn-lite';
44
import './InfoViewer.scss';
55

66
export interface InfoViewerItem {
7-
label: string;
7+
label: ReactNode;
88
value: ReactNode;
99
}
1010

@@ -39,7 +39,7 @@ const InfoViewer = ({
3939
{info && info.length > 0 ? (
4040
<div className={b('items')}>
4141
{info.map((data, infoIndex) => (
42-
<div className={b('row')} key={data.label + infoIndex}>
42+
<div className={b('row')} key={infoIndex}>
4343
<div className={b('label')}>
4444
<div className={b('label-text', {multiline: multilineLabels})}>
4545
{data.label}
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
export * from './common';
22
export * from './schema';
3-
export * from './topicStats';
43
export * from './pqGroup';
54
export * from './cdcStream';
65
export * from './table';

src/components/InfoViewer/formatters/topicStats.tsx

-29
This file was deleted.

src/components/LabelWithPopover/LabelWithPopover.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ import {HelpPopover} from '@gravity-ui/uikit';
44

55
interface LabelWithPopoverProps {
66
text: string;
7-
content: ReactNode;
7+
popoverContent: ReactNode;
88
className?: string;
99
}
1010

11-
export const LabelWithPopover = ({text, content, className}: LabelWithPopoverProps) => (
11+
export const LabelWithPopover = ({text, popoverContent, className}: LabelWithPopoverProps) => (
1212
<div className={className}>
1313
{text}
14-
<HelpPopover content={content} />
14+
<HelpPopover content={popoverContent} />
1515
</div>
1616
);

src/components/LagPopover/index.ts

-1
This file was deleted.

src/components/LagPopover/LagPopover.scss src/components/LagPopoverContent/LagPopoverContent.scss

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
.ydb-lag-popover {
2-
div:nth-child(1) {
1+
.ydb-lag-popover-content {
2+
&__text {
33
margin-bottom: 10px;
44
}
55

src/components/LagPopover/LagPopover.tsx src/components/LagPopoverContent/LagPopoverContent.tsx

+5-5
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,18 @@ import block from 'bem-cn-lite';
22

33
import {ReadLagImage, WriteLagImage} from '../LagImages';
44

5-
import './LagPopover.scss';
5+
import './LagPopoverContent.scss';
66

7-
const b = block('ydb-lag-popover');
7+
const b = block('ydb-lag-popover-content');
88

9-
interface LagPopoverProps {
9+
interface LagPopoverContentProps {
1010
text: string;
1111
type: 'read' | 'write';
1212
}
1313

14-
export const LagPopover = ({text, type}: LagPopoverProps) => (
14+
export const LagPopoverContent = ({text, type}: LagPopoverContentProps) => (
1515
<div className={b({type})}>
16-
<div>{text}</div>
16+
<div className={b('text')}>{text}</div>
1717
<div>{type === 'read' ? <ReadLagImage /> : <WriteLagImage />}</div>
1818
</div>
1919
);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './LagPopoverContent';

src/containers/Tenant/Diagnostics/Consumers/Headers/Headers.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import block from 'bem-cn-lite';
22

33
import {LabelWithPopover} from '../../../../../components/LabelWithPopover';
4-
import {LagPopover} from '../../../../../components/LagPopover';
4+
import {LagPopoverContent} from '../../../../../components/LagPopoverContent';
55

66
import {CONSUMERS_COLUMNS_IDS, CONSUMERS_COLUMNS_TITILES} from '../utils/constants';
77

@@ -15,6 +15,6 @@ export const ReadLagsHeader = () => (
1515
<LabelWithPopover
1616
className={b('lags')}
1717
text={CONSUMERS_COLUMNS_TITILES[CONSUMERS_COLUMNS_IDS.READ_LAGS]}
18-
content={<LagPopover text={i18n('lagsPopover.readLags')} type="read" />}
18+
popoverContent={<LagPopoverContent text={i18n('lagsPopover.readLags')} type="read" />}
1919
/>
2020
);

src/containers/Tenant/Diagnostics/Overview/TopicStats/TopicStats.tsx

+51-32
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,81 @@
11
import cn from 'bem-cn-lite';
2-
import {isEmpty} from 'lodash/fp';
32

4-
import type {DescribeTopicResult} from '../../../../../types/api/topic';
3+
import type {IPreparedTopicStats} from '../../../../../types/store/topic';
54

65
import {Loader} from '../../../../../components/Loader';
7-
import {InfoViewerItem, formatObject, InfoViewer} from '../../../../../components/InfoViewer';
8-
9-
import {formatTopicStats} from '../../../../../components/InfoViewer/formatters';
6+
import {InfoViewerItem, InfoViewer} from '../../../../../components/InfoViewer';
7+
import {SpeedMultiMeter} from '../../../../../components/SpeedMultiMeter';
8+
import {LabelWithPopover} from '../../../../../components/LabelWithPopover';
9+
import {LagPopoverContent} from '../../../../../components/LagPopoverContent';
10+
import {ResponseError} from '../../../../../components/Errors/ResponseError';
1011

1112
import {useTypedSelector} from '../../../../../utils/hooks';
12-
import {convertBytesObjectToSpeed} from '../../../../../utils/bytesParsers';
13-
import {formatBps} from '../../../../../utils';
13+
import {formatDurationToShortTimeFormat} from '../../../../../utils/timeParsers';
14+
import {formatBps, formatBytes} from '../../../../../utils';
15+
16+
import {selectPreparedTopicStats} from '../../../../../store/reducers/topic';
1417

1518
import i18n from './i18n';
1619

1720
import './TopicStats.scss';
1821

1922
const b = cn('ydb-overview-topic-stats');
2023

21-
const prepareTopicInfo = (data: DescribeTopicResult): Array<InfoViewerItem> => {
24+
const prepareTopicInfo = (data: IPreparedTopicStats): Array<InfoViewerItem> => {
2225
return [
23-
...formatObject(formatTopicStats, {
24-
...data.topic_stats,
25-
}),
26+
{label: 'Store size', value: formatBytes(data.storeSize)},
27+
{
28+
label: (
29+
<LabelWithPopover
30+
text={'Write idle time'}
31+
popoverContent={
32+
<LagPopoverContent text={i18n('writeIdleTimePopover')} type="write" />
33+
}
34+
/>
35+
),
36+
value: formatDurationToShortTimeFormat(data.partitionsIdleTime),
37+
},
38+
{
39+
label: (
40+
<LabelWithPopover
41+
text={'Write lag'}
42+
popoverContent={
43+
<LagPopoverContent text={i18n('writeLagPopover')} type="write" />
44+
}
45+
/>
46+
),
47+
value: formatDurationToShortTimeFormat(data.partitionsWriteLag),
48+
},
49+
{
50+
label: 'Average write speed',
51+
value: <SpeedMultiMeter data={data.writeSpeed} withValue={false} />,
52+
},
2653
];
2754
};
2855

29-
const prepareBytesWrittenInfo = (data: DescribeTopicResult): Array<InfoViewerItem> => {
30-
const preparedBytes = convertBytesObjectToSpeed(data?.topic_stats?.bytes_written);
56+
const prepareBytesWrittenInfo = (data: IPreparedTopicStats): Array<InfoViewerItem> => {
57+
const writeSpeed = data.writeSpeed;
3158

3259
return [
3360
{
3461
label: 'per minute',
35-
value: formatBps(preparedBytes.perMinute),
62+
value: formatBps(writeSpeed.perMinute),
3663
},
3764
{
3865
label: 'per hour',
39-
value: formatBps(preparedBytes.perHour),
66+
value: formatBps(writeSpeed.perHour),
4067
},
4168
{
4269
label: 'per day',
43-
value: formatBps(preparedBytes.perDay),
70+
value: formatBps(writeSpeed.perDay),
4471
},
4572
];
4673
};
4774

4875
export const TopicStats = () => {
49-
const {data, error, loading, wasLoaded} = useTypedSelector((state) => state.topic);
76+
const {error, loading, wasLoaded} = useTypedSelector((state) => state.topic);
77+
78+
const data = useTypedSelector(selectPreparedTopicStats);
5079

5180
if (loading && !wasLoaded) {
5281
return (
@@ -56,24 +85,14 @@ export const TopicStats = () => {
5685
);
5786
}
5887

59-
// There are several backed versions with different behaviour
60-
// Possible returns on older versions:
61-
// 1. Error when trying to access endpoint
62-
// 2. No data
63-
// 3. HTML page of Internal Viewer with an error
64-
// 4. Data with no topic stats
65-
// 5. Topic Stats as an empty object
66-
if (
67-
error ||
68-
!data ||
69-
typeof data !== 'object' ||
70-
!data.topic_stats ||
71-
isEmpty(data.topic_stats)
72-
) {
88+
// If there is at least some empty data object
89+
// we initialize its fields with zero values
90+
// so no data at all is considered to be error as well
91+
if (error || !data) {
7392
return (
7493
<div className={b()}>
7594
<div className={b('title')}>Stats</div>
76-
<div className="error">{i18n('notSupportedVersion')}</div>
95+
<ResponseError error={error} />
7796
</div>
7897
);
7998
}
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
{
2-
"notSupportedVersion": "Topic stats are not supported in the current cluster version. Update cluster version to see topic stats"
2+
"writeLagPopover": "Write lag, maximum among all topic partitions",
3+
"writeIdleTimePopover": "Write idle time, maximum among all topic partitions"
34
}
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
{
2-
"notSupportedVersion": "Статистика топиков не поддерживается в текущей версии. Обновите кластер до более новой версии, чтобы увидеть статистику топиков"
2+
"writeLagPopover": "Лаг записи, максимальное значение среди всех партиций топика",
3+
"writeIdleTimePopover": "Время без записи, максимальное значение среди всех партиций топика"
34
}

src/containers/Tenant/Diagnostics/Partitions/Headers/Headers.tsx

+9-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import block from 'bem-cn-lite';
22

33
import {LabelWithPopover} from '../../../../../components/LabelWithPopover';
4-
import {LagPopover} from '../../../../../components/LagPopover';
4+
import {LagPopoverContent} from '../../../../../components/LagPopoverContent';
55

66
import {PARTITIONS_COLUMNS_IDS, PARTITIONS_COLUMNS_TITILES} from '../utils/constants';
77

@@ -29,30 +29,34 @@ export const WriteLagsHeader = () => (
2929
<LabelWithPopover
3030
className={b('lags')}
3131
text={PARTITIONS_COLUMNS_TITILES[PARTITIONS_COLUMNS_IDS.READ_LAGS]}
32-
content={<LagPopover text={i18n('lagsPopover.readLags')} type="read" />}
32+
popoverContent={<LagPopoverContent text={i18n('lagsPopover.readLags')} type="read" />}
3333
/>
3434
);
3535

3636
export const ReadLagsHeader = () => (
3737
<LabelWithPopover
3838
className={b('lags')}
3939
text={PARTITIONS_COLUMNS_TITILES[PARTITIONS_COLUMNS_IDS.WRITE_LAGS]}
40-
content={<LagPopover text={i18n('lagsPopover.writeLags')} type="write" />}
40+
popoverContent={<LagPopoverContent text={i18n('lagsPopover.writeLags')} type="write" />}
4141
/>
4242
);
4343

4444
export const UnreadMessagesHeader = () => (
4545
<LabelWithPopover
4646
className={b('messages')}
4747
text={PARTITIONS_COLUMNS_TITILES[PARTITIONS_COLUMNS_IDS.UNREAD_MESSAGES]}
48-
content={<div className={b('messages-popover-content')}>{i18n('headers.unread')}</div>}
48+
popoverContent={
49+
<div className={b('messages-popover-content')}>{i18n('headers.unread')}</div>
50+
}
4951
/>
5052
);
5153

5254
export const UncommitedMessagesHeader = () => (
5355
<LabelWithPopover
5456
className={b('messages')}
5557
text={PARTITIONS_COLUMNS_TITILES[PARTITIONS_COLUMNS_IDS.UNCOMMITED_MESSAGES]}
56-
content={<div className={b('messages-popover-content')}>{i18n('headers.uncommited')}</div>}
58+
popoverContent={
59+
<div className={b('messages-popover-content')}>{i18n('headers.uncommited')}</div>
60+
}
5761
/>
5862
);

0 commit comments

Comments
 (0)