Skip to content

Commit 57c3d42

Browse files
committed
fix: review
1 parent a46fa9d commit 57c3d42

File tree

11 files changed

+136
-143
lines changed

11 files changed

+136
-143
lines changed

src/containers/Tenant/Diagnostics/TopicData/TopicData.scss

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,17 @@
1212
&__date-picker {
1313
min-width: 265px;
1414
}
15-
&__offsets-count {
16-
border-radius: unset;
15+
&__column-setup {
16+
margin-left: auto;
17+
}
18+
19+
&__row {
20+
&_active {
21+
background-color: var(--g-color-base-selection);
22+
23+
&:hover {
24+
background: var(--g-color-base-selection-hover) !important;
25+
}
26+
}
1727
}
1828
}

src/containers/Tenant/Diagnostics/TopicData/TopicData.tsx

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,13 @@ import {
1111
} from '../../../../components/PaginatedTable';
1212
import {partitionsApi} from '../../../../store/reducers/partitions/partitions';
1313
import {topicApi} from '../../../../store/reducers/topic';
14-
import type {TopicDataRequest, TopicMessageMetadataItem} from '../../../../types/api/topic';
14+
import type {TopicDataRequest} from '../../../../types/api/topic';
1515
import {useAutoRefreshInterval} from '../../../../utils/hooks';
1616
import {useSelectedColumns} from '../../../../utils/hooks/useSelectedColumns';
1717
import {renderPaginatedTableErrorMessage} from '../../../../utils/renderPaginatedTableErrorMessage';
1818
import {safeParseNumber} from '../../../../utils/utils';
1919
import {EmptyFilter} from '../../../Storage/EmptyFilter/EmptyFilter';
2020

21-
import {FullValue} from './FullValue';
2221
import {TopicDataControls} from './TopicDataControls/TopicDataControls';
2322
import {
2423
DEFAULT_TOPIC_DATA_COLUMNS,
@@ -33,6 +32,7 @@ import {
3332
TOPIC_DATA_COLUMNS_WIDTH_LS_KEY,
3433
TOPIC_DATA_FETCH_LIMIT,
3534
TOPIC_DATA_SELECTED_COLUMNS_LS_KEY,
35+
b,
3636
} from './utils/constants';
3737

3838
import './TopicData.scss';
@@ -47,9 +47,6 @@ export function TopicData({parentRef, path, database}: TopicDataProps) {
4747
const [autoRefreshInterval] = useAutoRefreshInterval();
4848
const [startOffset, setStartOffset] = React.useState<number>();
4949
const [endOffset, setEndOffset] = React.useState<number>();
50-
const [fullValue, setFullValue] = React.useState<
51-
string | TopicMessageMetadataItem[] | undefined
52-
>(undefined);
5350
const [controlsKey, setControlsKey] = React.useState(0);
5451
const [emptyData, setEmptyData] = React.useState(false);
5552

@@ -122,7 +119,7 @@ export function TopicData({parentRef, path, database}: TopicDataProps) {
122119
}, [partitions, selectedPartition, handleSelectedPartitionChange]);
123120

124121
const {columnsToShow, columnsToSelect, setColumns} = useSelectedColumns(
125-
getAllColumns(setFullValue),
122+
getAllColumns(),
126123
TOPIC_DATA_SELECTED_COLUMNS_LS_KEY,
127124
TOPIC_DATA_COLUMNS_TITLES,
128125
DEFAULT_TOPIC_DATA_COLUMNS,
@@ -226,25 +223,28 @@ export function TopicData({parentRef, path, database}: TopicDataProps) {
226223
);
227224

228225
return (
229-
<React.Fragment>
230-
<FullValue value={fullValue} onClose={() => setFullValue(undefined)} />
231-
{!isNil(baseOffset) && !isNil(baseEndOffset) && (
232-
<ResizeablePaginatedTable
233-
columnsWidthLSKey={TOPIC_DATA_COLUMNS_WIDTH_LS_KEY}
234-
parentRef={parentRef}
235-
columns={columnsToShow}
236-
fetchData={getTopicData}
237-
initialEntitiesCount={baseEndOffset - baseOffset}
238-
limit={TOPIC_DATA_FETCH_LIMIT}
239-
renderControls={renderControls}
240-
renderErrorMessage={renderPaginatedTableErrorMessage}
241-
renderEmptyDataMessage={renderEmptyDataMessage}
242-
filters={tableFilters}
243-
tableName="topicData"
244-
rowHeight={DEFAULT_TABLE_ROW_HEIGHT}
245-
keepCache={false}
246-
/>
247-
)}
248-
</React.Fragment>
226+
!isNil(baseOffset) &&
227+
!isNil(baseEndOffset) && (
228+
<ResizeablePaginatedTable
229+
columnsWidthLSKey={TOPIC_DATA_COLUMNS_WIDTH_LS_KEY}
230+
parentRef={parentRef}
231+
columns={columnsToShow}
232+
fetchData={getTopicData}
233+
initialEntitiesCount={baseEndOffset - baseOffset}
234+
limit={TOPIC_DATA_FETCH_LIMIT}
235+
renderControls={renderControls}
236+
renderErrorMessage={renderPaginatedTableErrorMessage}
237+
renderEmptyDataMessage={renderEmptyDataMessage}
238+
filters={tableFilters}
239+
tableName="topicData"
240+
rowHeight={DEFAULT_TABLE_ROW_HEIGHT}
241+
keepCache={false}
242+
getRowClassName={(row) => {
243+
return b('row', {
244+
active: Boolean(selectedOffset && String(row.Offset) === selectedOffset),
245+
});
246+
}}
247+
/>
248+
)
249249
);
250250
}

src/containers/Tenant/Diagnostics/TopicData/TopicDataControls/TopicDataControls.tsx

Lines changed: 9 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,20 @@ import React from 'react';
33
import type {Value} from '@gravity-ui/date-components';
44
import {RelativeDatePicker} from '@gravity-ui/date-components';
55
import {dateTimeParse} from '@gravity-ui/date-utils';
6-
import {ArrowDownToLine, ArrowUpToLine, CircleChevronDownFill} from '@gravity-ui/icons';
6+
import {CircleChevronDownFill} from '@gravity-ui/icons';
77
import type {TableColumnSetupItem} from '@gravity-ui/uikit';
88
import {
99
ActionTooltip,
1010
Button,
11-
Flex,
1211
Icon,
1312
RadioButton,
1413
Select,
1514
TableColumnSetup,
15+
Text,
1616
} from '@gravity-ui/uikit';
1717
import {isNil} from 'lodash';
1818

1919
import {DebouncedInput} from '../../../../../components/DebouncedInput/DebouncedTextInput';
20-
import {EntitiesCount} from '../../../../../components/EntitiesCount';
2120
import type {PreparedPartitionData} from '../../../../../store/reducers/partitions/types';
2221
import {formatNumber} from '../../../../../utils/dataFormatters/dataFormatters';
2322
import {prepareErrorMessage} from '../../../../../utils/prepareErrorMessage';
@@ -77,18 +76,6 @@ export function TopicDataControls({
7776
],
7877
);
7978

80-
const scrollToStartOffset = React.useCallback(() => {
81-
if (startOffset) {
82-
scrollToOffset(startOffset);
83-
}
84-
}, [startOffset, scrollToOffset]);
85-
86-
const scrollToEndOffset = React.useCallback(() => {
87-
if (endOffset) {
88-
scrollToOffset(endOffset);
89-
}
90-
}, [endOffset, scrollToOffset]);
91-
9279
return (
9380
<React.Fragment>
9481
<Select
@@ -105,42 +92,20 @@ export function TopicDataControls({
10592
loading={partitionsLoading}
10693
/>
10794
<TopicDataStartControls scrollToOffset={scrollToOffset} />
95+
96+
{!isNil(startOffset) && !isNil(endOffset) && (
97+
<Text color="secondary" whiteSpace="nowrap">
98+
{formatNumber(startOffset)}{formatNumber(endOffset - 1)}
99+
</Text>
100+
)}
108101
<TableColumnSetup
102+
className={b('column-setup')}
109103
popupWidth={242}
110104
items={columnsToSelect}
111105
showStatus
112106
onUpdate={handleSelectedColumnsUpdate}
113107
sortable={false}
114108
/>
115-
{!isNil(startOffset) && !isNil(endOffset) && (
116-
<Flex gap={0.5}>
117-
<ActionTooltip title={i18n('action_scroll-up')}>
118-
<Button
119-
onClick={scrollToStartOffset}
120-
view="flat-info"
121-
selected
122-
pin="round-brick"
123-
>
124-
<Icon size={14} data={ArrowUpToLine} />
125-
</Button>
126-
</ActionTooltip>
127-
<EntitiesCount
128-
label={i18n('label_offset')}
129-
current={`${formatNumber(startOffset)}${formatNumber(endOffset - 1)}`}
130-
className={b('offsets-count')}
131-
/>
132-
<ActionTooltip title={i18n('action_scroll-down')}>
133-
<Button
134-
onClick={scrollToEndOffset}
135-
view="flat-info"
136-
selected
137-
pin="brick-round"
138-
>
139-
<Icon size={14} data={ArrowDownToLine} />
140-
</Button>
141-
</ActionTooltip>
142-
</Flex>
143-
)}
144109
</React.Fragment>
145110
);
146111
}

src/containers/Tenant/Diagnostics/TopicData/__test__/getData.test.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,11 @@ describe('prepareResponse', () => {
3636
expect(result.messages.length).toBe(8); // 5 removed + 3 actual
3737

3838
// Check removed messages
39-
expect(result.messages[0]).toEqual({Offset: '<removed> 100'});
40-
expect(result.messages[1]).toEqual({Offset: '<removed> 101'});
41-
expect(result.messages[2]).toEqual({Offset: '<removed> 102'});
42-
expect(result.messages[3]).toEqual({Offset: '<removed> 103'});
43-
expect(result.messages[4]).toEqual({Offset: '<removed> 104'});
39+
expect(result.messages[0]).toEqual({Offset: '100', removed: true});
40+
expect(result.messages[1]).toEqual({Offset: '101', removed: true});
41+
expect(result.messages[2]).toEqual({Offset: '102', removed: true});
42+
expect(result.messages[3]).toEqual({Offset: '103', removed: true});
43+
expect(result.messages[4]).toEqual({Offset: '104', removed: true});
4444

4545
// Check actual messages
4646
expect(result.messages[5]).toEqual({Offset: '105'});
@@ -64,7 +64,7 @@ describe('prepareResponse', () => {
6464

6565
// All messages should be "removed" placeholders since there are more than the limit
6666
for (let i = 0; i < TOPIC_DATA_FETCH_LIMIT; i++) {
67-
expect(result.messages[i]).toEqual({Offset: `<removed> ${100 + i}`});
67+
expect(result.messages[i]).toEqual({Offset: `${100 + i}`, removed: true});
6868
}
6969
});
7070

src/containers/Tenant/Diagnostics/TopicData/columns/Columns.scss

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,12 @@
1111

1212
color: var(--g-color-text-info);
1313
}
14+
&__offset_removed {
15+
text-decoration: line-through;
16+
}
17+
18+
&__message_invalid,
19+
&__truncated {
20+
font-style: italic;
21+
}
1422
}

src/containers/Tenant/Diagnostics/TopicData/columns/columns.tsx

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

33
import DataTable from '@gravity-ui/react-data-table';
4+
import {Text} from '@gravity-ui/uikit';
45
import {isNil} from 'lodash';
56

67
import {EntityStatus} from '../../../../../components/EntityStatus/EntityStatus';
78
import {MultilineTableHeader} from '../../../../../components/MultilineTableHeader/MultilineTableHeader';
89
import type {Column} from '../../../../../components/PaginatedTable';
9-
import type {TopicMessage, TopicMessageMetadataItem} from '../../../../../types/api/topic';
10+
import {TOPIC_MESSAGE_SIZE_LIMIT} from '../../../../../store/reducers/topic';
11+
import type {TopicMessageEnhanced} from '../../../../../types/api/topic';
1012
import {cn} from '../../../../../utils/cn';
1113
import {EMPTY_DATA_PLACEHOLDER} from '../../../../../utils/constants';
1214
import {formatBytes, formatTimestamp} from '../../../../../utils/dataFormatters/dataFormatters';
@@ -21,13 +23,24 @@ import './Columns.scss';
2123

2224
const b = cn('ydb-diagnostics-topic-data-columns');
2325

24-
export function getAllColumns(setFullValue: (value: string | TopicMessageMetadataItem[]) => void) {
25-
const columns: Column<TopicMessage>[] = [
26+
export function getAllColumns() {
27+
const columns: Column<TopicMessageEnhanced>[] = [
2628
{
2729
name: TOPIC_DATA_COLUMNS_IDS.OFFSET,
2830
header: TOPIC_DATA_COLUMNS_TITLES[TOPIC_DATA_COLUMNS_IDS.OFFSET],
2931
align: DataTable.LEFT,
30-
render: ({row}) => valueOrPlaceholder(row.Offset),
32+
render: ({row}) => {
33+
const {Offset, removed} = row;
34+
return (
35+
<Text
36+
className={b('offset', {removed})}
37+
variant="body-2"
38+
color={removed ? 'secondary' : 'primary'}
39+
>
40+
{valueOrPlaceholder(Offset)}
41+
</Text>
42+
);
43+
},
3144
width: 100,
3245
},
3346
{
@@ -78,27 +91,43 @@ export function getAllColumns(setFullValue: (value: string | TopicMessageMetadat
7891
const prepared = MessageMetadata.map(
7992
({Key = '', Value = ''}) => `${Key}: ${Value}`,
8093
);
81-
const isTruncated = prepared.length > 0;
82-
return (
83-
<span
84-
className={b('message', {clickable: isTruncated})}
85-
onClick={isTruncated ? () => setFullValue(MessageMetadata) : undefined}
86-
>
87-
{prepared.join(', ')}
88-
</span>
89-
);
94+
return prepared.join(', ');
9095
},
9196
width: 200,
9297
},
9398
{
9499
name: TOPIC_DATA_COLUMNS_IDS.MESSAGE,
95100
header: TOPIC_DATA_COLUMNS_TITLES[TOPIC_DATA_COLUMNS_IDS.MESSAGE],
96101
align: DataTable.LEFT,
97-
render: ({row: {Message: message}}) => {
98-
if (isNil(message)) {
102+
render: ({row: {Message, OriginalSize}}) => {
103+
if (isNil(Message)) {
99104
return EMPTY_DATA_PLACEHOLDER;
100105
}
101-
return <Message setFullValue={setFullValue} message={message} />;
106+
let encryptedMessage;
107+
let invalid = false;
108+
try {
109+
encryptedMessage = atob(Message);
110+
} catch {
111+
encryptedMessage = i18n('description_failed-decode');
112+
invalid = true;
113+
}
114+
115+
const truncated = safeParseNumber(OriginalSize) > TOPIC_MESSAGE_SIZE_LIMIT;
116+
return (
117+
<Text
118+
variant="body-2"
119+
color={invalid ? 'secondary' : 'primary'}
120+
className={b('message', {invalid})}
121+
>
122+
{encryptedMessage}
123+
{truncated && (
124+
<Text color="secondary" className={b('truncated')}>
125+
{' '}
126+
{i18n('description_truncated')}
127+
</Text>
128+
)}
129+
</Text>
130+
);
102131
},
103132
width: 500,
104133
},
@@ -179,40 +208,9 @@ function TopicDataTimestamp({timestamp}: TopicDataTimestampProps) {
179208
);
180209
}
181210

182-
function valueOrPlaceholder(value: string | undefined, placeholder = EMPTY_DATA_PLACEHOLDER) {
211+
function valueOrPlaceholder(
212+
value: string | number | undefined,
213+
placeholder = EMPTY_DATA_PLACEHOLDER,
214+
) {
183215
return isNil(value) ? placeholder : value;
184216
}
185-
186-
interface MessageProps {
187-
setFullValue: (value: string) => void;
188-
message: string;
189-
}
190-
191-
function Message({setFullValue, message}: MessageProps) {
192-
const longMessage = message.length > 200;
193-
194-
let encryptedMessage: string | undefined;
195-
196-
if (!longMessage) {
197-
try {
198-
encryptedMessage = atob(message);
199-
} catch {}
200-
}
201-
202-
const handleClick = () => {
203-
try {
204-
if (!encryptedMessage) {
205-
encryptedMessage = atob(message);
206-
}
207-
setFullValue(encryptedMessage);
208-
} catch {}
209-
};
210-
return (
211-
<span
212-
className={b('message', {clickable: longMessage})}
213-
onClick={longMessage ? handleClick : undefined}
214-
>
215-
{encryptedMessage ?? i18n('action_show-message')}
216-
</span>
217-
);
218-
}

0 commit comments

Comments
 (0)