Skip to content

Commit 90ead6e

Browse files
committed
fix: review
1 parent 0be62cc commit 90ead6e

File tree

17 files changed

+225
-110
lines changed

17 files changed

+225
-110
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import type {TextInputProps} from '@gravity-ui/uikit';
2+
import {TextInput} from '@gravity-ui/uikit';
3+
4+
import {useDebouncedValue} from '../../utils/hooks/useDebouncedValue';
5+
6+
interface DebouncedInputProps extends TextInputProps {
7+
debounce?: number;
8+
}
9+
10+
export const DebouncedInput = ({
11+
onUpdate,
12+
value = '',
13+
debounce = 200,
14+
...rest
15+
}: DebouncedInputProps) => {
16+
const [currentValue, handleUpdate] = useDebouncedValue<string>({value, onUpdate, debounce});
17+
18+
return <TextInput value={currentValue} onUpdate={handleUpdate} {...rest} />;
19+
};

src/components/PaginatedTable/PaginatedTable.tsx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ export interface PaginatedTableProps<T, F> {
3636
renderEmptyDataMessage?: RenderEmptyDataMessage;
3737
renderErrorMessage?: RenderErrorMessage;
3838
containerClassName?: string;
39-
startOffset?: number;
4039
}
4140

4241
export const PaginatedTable = <T, F>({
@@ -55,7 +54,6 @@ export const PaginatedTable = <T, F>({
5554
renderErrorMessage,
5655
renderEmptyDataMessage,
5756
containerClassName,
58-
startOffset = 0,
5957
}: PaginatedTableProps<T, F>) => {
6058
const initialTotal = initialEntitiesCount || 0;
6159
const initialFound = initialEntitiesCount || 1;
@@ -125,7 +123,6 @@ export const PaginatedTable = <T, F>({
125123
renderEmptyDataMessage={renderEmptyDataMessage}
126124
onDataFetched={handleDataFetched}
127125
isActive={isActive}
128-
startOffset={startOffset}
129126
/>
130127
));
131128
};

src/components/PaginatedTable/TableChunk.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ interface TableChunkProps<T, F> {
3030
sortParams?: SortParams;
3131
isActive: boolean;
3232
tableName: string;
33-
startOffset: number;
3433

3534
fetchData: FetchData<T, F>;
3635
getRowClassName?: GetRowClassName<T>;
@@ -54,7 +53,6 @@ export const TableChunk = typedMemo(function TableChunk<T, F>({
5453
renderErrorMessage,
5554
renderEmptyDataMessage,
5655
onDataFetched,
57-
startOffset,
5856
isActive,
5957
}: TableChunkProps<T, F>) {
6058
const [isTimeoutActive, setIsTimeoutActive] = React.useState(true);
@@ -63,7 +61,7 @@ export const TableChunk = typedMemo(function TableChunk<T, F>({
6361
const columnsIds = columns.map((column) => column.name);
6462

6563
const queryParams = {
66-
offset: startOffset + id * chunkSize,
64+
offset: id * chunkSize,
6765
limit: chunkSize,
6866
fetchData: fetchData as FetchData<T, unknown>,
6967
filters,

src/components/PaginatedTable/useScrollBasedChunks.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ export const useScrollBasedChunks = ({
9292
return React.useMemo(() => {
9393
// boolean array that represents active chunks
9494
const activeChunks = Array(chunksCount).fill(false);
95-
for (let i = startChunk; i <= Math.min(endChunk, chunksCount); i++) {
95+
for (let i = startChunk; i <= endChunk; i++) {
9696
activeChunks[i] = true;
9797
}
9898
return activeChunks;

src/components/Search/Search.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React from 'react';
22

33
import {cn} from '../../utils/cn';
4-
import {DebouncedInput} from '../DebouncedInput/DebouncedInput';
4+
import {DebouncedInput} from '../DebouncedInput/DebouncedTextInput';
55

66
import './Search.scss';
77

src/containers/Tenant/Diagnostics/Diagnostics.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,14 @@ function Diagnostics(props: DiagnosticsProps) {
143143
return <Partitions path={path} database={tenantName} />;
144144
}
145145
case TENANT_DIAGNOSTICS_TABS_IDS.topicData: {
146-
return <TopicData path={path} database={tenantName} parentRef={containerRef} />;
146+
return (
147+
<TopicData
148+
key={path}
149+
path={path}
150+
database={tenantName}
151+
parentRef={containerRef}
152+
/>
153+
);
147154
}
148155
case TENANT_DIAGNOSTICS_TABS_IDS.configs: {
149156
return <Configs database={tenantName} />;

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,7 @@
1212
&__date-picker {
1313
min-width: 265px;
1414
}
15+
&__offsets-count {
16+
border-radius: unset;
17+
}
1518
}

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

Lines changed: 66 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ import {skipToken} from '@reduxjs/toolkit/query';
55
import {isNil} from 'lodash';
66

77
import type {RenderControls} from '../../../../components/PaginatedTable';
8-
import {ResizeablePaginatedTable} from '../../../../components/PaginatedTable';
8+
import {
9+
DEFAULT_TABLE_ROW_HEIGHT,
10+
ResizeablePaginatedTable,
11+
} from '../../../../components/PaginatedTable';
912
import {partitionsApi} from '../../../../store/reducers/partitions/partitions';
1013
import {topicApi} from '../../../../store/reducers/topic';
1114
import type {TopicDataRequest, TopicMessageMetadataItem} from '../../../../types/api/topic';
@@ -28,6 +31,7 @@ import {useTopicDataQueryParams} from './useTopicDataQueryParams';
2831
import {
2932
TOPIC_DATA_COLUMNS_TITLES,
3033
TOPIC_DATA_COLUMNS_WIDTH_LS_KEY,
34+
TOPIC_DATA_FETCH_LIMIT,
3135
TOPIC_DATA_SELECTED_COLUMNS_LS_KEY,
3236
} from './utils/constants';
3337

@@ -41,12 +45,19 @@ interface TopicDataProps {
4145

4246
export function TopicData({parentRef, path, database}: TopicDataProps) {
4347
const [autoRefreshInterval] = useAutoRefreshInterval();
44-
const [startOffset, setStartOffset] = React.useState(0);
45-
const [endOffset, setEndOffset] = React.useState(0);
48+
const [startOffset, setStartOffset] = React.useState<number>();
49+
const [endOffset, setEndOffset] = React.useState<number>();
4650
const [fullValue, setFullValue] = React.useState<
4751
string | TopicMessageMetadataItem[] | undefined
4852
>(undefined);
4953
const [controlsKey, setControlsKey] = React.useState(0);
54+
const [emptyData, setEmptyData] = React.useState(false);
55+
56+
const [baseOffset, setBaseOffset] = React.useState<number>(0);
57+
const [baseEndOffset, setBaseEndOffset] = React.useState<number>(0);
58+
59+
const startRef = React.useRef<number>();
60+
startRef.current = startOffset;
5061

5162
const {
5263
selectedPartition,
@@ -58,6 +69,14 @@ export function TopicData({parentRef, path, database}: TopicDataProps) {
5869
handleSelectedPartitionChange,
5970
} = useTopicDataQueryParams();
6071

72+
React.useEffect(() => {
73+
return () => {
74+
handleSelectedPartitionChange(undefined);
75+
handleSelectedOffsetChange(undefined);
76+
handleStartTimestampChange(undefined);
77+
};
78+
}, [handleSelectedPartitionChange, handleSelectedOffsetChange, handleStartTimestampChange]);
79+
6180
const queryParams = React.useMemo(() => {
6281
if (isNil(selectedPartition)) {
6382
return skipToken;
@@ -66,12 +85,12 @@ export function TopicData({parentRef, path, database}: TopicDataProps) {
6685
if (startTimestamp) {
6786
params.read_timestamp = startTimestamp;
6887
} else {
69-
params.offset = selectedOffset ?? 0;
88+
params.offset = safeParseNumber(selectedOffset);
7089
}
7190
return params;
7291
}, [selectedPartition, selectedOffset, startTimestamp, database, path]);
7392

74-
const {currentData, isFetching} = topicApi.useGetTopicDataQuery(queryParams);
93+
const {currentData, error, isFetching} = topicApi.useGetTopicDataQuery(queryParams);
7594

7695
const {
7796
data: partitions,
@@ -86,26 +105,21 @@ export function TopicData({parentRef, path, database}: TopicDataProps) {
86105
const selectedPartitionData = partitions?.find(
87106
({partitionId}) => partitionId === selectedPartition,
88107
);
89-
90108
if (selectedPartitionData) {
91-
setStartOffset(safeParseNumber(selectedPartitionData.startOffset));
92-
setEndOffset(safeParseNumber(selectedPartitionData.endOffset));
109+
if (!baseOffset) {
110+
setBaseOffset(safeParseNumber(selectedPartitionData.startOffset));
111+
}
112+
if (!baseEndOffset) {
113+
setBaseEndOffset(safeParseNumber(selectedPartitionData.endOffset));
114+
}
93115
}
94-
}, [selectedPartition, partitions]);
116+
}, [selectedPartition, partitions, baseOffset, baseEndOffset, startOffset, endOffset]);
95117

96118
React.useEffect(() => {
97119
if (partitions && partitions.length && isNil(selectedPartition)) {
98120
handleSelectedPartitionChange(partitions[0].partitionId);
99-
handleSelectedOffsetChange(undefined);
100-
handleStartTimestampChange(undefined);
101121
}
102-
}, [
103-
partitions,
104-
selectedPartition,
105-
handleSelectedPartitionChange,
106-
handleSelectedOffsetChange,
107-
handleStartTimestampChange,
108-
]);
122+
}, [partitions, selectedPartition, handleSelectedPartitionChange]);
109123

110124
const {columnsToShow, columnsToSelect, setColumns} = useSelectedColumns(
111125
getAllColumns(setFullValue),
@@ -115,27 +129,42 @@ export function TopicData({parentRef, path, database}: TopicDataProps) {
115129
REQUIRED_TOPIC_DATA_COLUMNS,
116130
);
117131

118-
const emptyData = React.useMemo(() => !currentData?.Messages?.length, [currentData]);
132+
React.useEffect(() => {
133+
//values should be recalculated only when data is fetched
134+
if (isFetching || (!currentData && !error)) {
135+
return;
136+
}
137+
if (currentData?.Messages?.length || (!currentData && !error)) {
138+
setEmptyData(false);
139+
} else if (!(currentData && currentData.Messages?.length) || error) {
140+
setEmptyData(true);
141+
}
142+
if (currentData) {
143+
setStartOffset(safeParseNumber(currentData.StartOffset));
144+
setEndOffset(safeParseNumber(currentData.EndOffset));
145+
}
146+
}, [isFetching, currentData, error]);
119147

120-
const tableFilters = React.useMemo(() => {
121-
return {
148+
const tableFilters = React.useMemo(
149+
() => ({
122150
path,
123151
database,
124152
partition: selectedPartition ?? '',
125153
isEmpty: emptyData,
126-
};
127-
}, [path, database, selectedPartition, emptyData]);
154+
}),
155+
[path, database, selectedPartition, emptyData],
156+
);
128157

129158
const scrollToOffset = React.useCallback(
130159
(newOffset: number) => {
131-
const scrollTop = (newOffset - (startOffset ?? 0)) * 41;
160+
const scrollTop = (newOffset - (baseOffset ?? 0)) * DEFAULT_TABLE_ROW_HEIGHT;
132161
const normalizedScrollTop = Math.max(0, scrollTop);
133162
parentRef.current?.scrollTo({
134163
top: normalizedScrollTop,
135164
behavior: 'instant',
136165
});
137166
},
138-
[startOffset, parentRef],
167+
[baseOffset, parentRef],
139168
);
140169

141170
React.useEffect(() => {
@@ -153,20 +182,16 @@ export function TopicData({parentRef, path, database}: TopicDataProps) {
153182
}, [currentData, isFetching, scrollToOffset]);
154183

155184
const scrollToStartOffset = React.useCallback(() => {
156-
parentRef.current?.scrollTo({
157-
top: 0,
158-
behavior: 'smooth',
159-
});
160-
}, [parentRef]);
185+
if (startOffset) {
186+
scrollToOffset(startOffset);
187+
}
188+
}, [startOffset, scrollToOffset]);
161189

162190
const scrollToEndOffset = React.useCallback(() => {
163-
if (parentRef.current) {
164-
parentRef.current.scrollTo({
165-
top: parentRef.current.scrollHeight - parentRef.current.clientHeight,
166-
behavior: 'smooth',
167-
});
191+
if (endOffset) {
192+
scrollToOffset(endOffset);
168193
}
169-
}, [parentRef]);
194+
}, [endOffset, scrollToOffset]);
170195

171196
const renderControls: RenderControls = () => {
172197
return (
@@ -210,8 +235,8 @@ export function TopicData({parentRef, path, database}: TopicDataProps) {
210235
};
211236

212237
const getTopicData = React.useMemo(
213-
() => generateTopicDataGetter({setEndOffset, setStartOffset}),
214-
[],
238+
() => generateTopicDataGetter({setEndOffset, setStartOffset, baseOffset}),
239+
[baseOffset],
215240
);
216241

217242
return (
@@ -222,14 +247,14 @@ export function TopicData({parentRef, path, database}: TopicDataProps) {
222247
parentRef={parentRef}
223248
columns={columnsToShow}
224249
fetchData={getTopicData}
225-
initialEntitiesCount={endOffset - startOffset}
226-
limit={50}
227-
startOffset={startOffset}
250+
initialEntitiesCount={baseEndOffset - baseOffset}
251+
limit={TOPIC_DATA_FETCH_LIMIT}
228252
renderControls={renderControls}
229253
renderErrorMessage={renderPaginatedTableErrorMessage}
230254
renderEmptyDataMessage={renderEmptyDataMessage}
231255
filters={tableFilters}
232256
tableName="topicData"
257+
rowHeight={DEFAULT_TABLE_ROW_HEIGHT}
233258
/>
234259
</React.Fragment>
235260
);

0 commit comments

Comments
 (0)