@@ -4,6 +4,9 @@ import {NoSearchResults} from '@gravity-ui/illustrations';
4
4
import { skipToken } from '@reduxjs/toolkit/query' ;
5
5
import { isNil } from 'lodash' ;
6
6
7
+ import { DrawerWrapper } from '../../../../components/Drawer' ;
8
+ import EnableFullscreenButton from '../../../../components/EnableFullscreenButton/EnableFullscreenButton' ;
9
+ import Fullscreen from '../../../../components/Fullscreen/Fullscreen' ;
7
10
import type { RenderControls } from '../../../../components/PaginatedTable' ;
8
11
import {
9
12
DEFAULT_TABLE_ROW_HEIGHT ,
@@ -19,6 +22,7 @@ import {safeParseNumber} from '../../../../utils/utils';
19
22
import { EmptyFilter } from '../../../Storage/EmptyFilter/EmptyFilter' ;
20
23
21
24
import { TopicDataControls } from './TopicDataControls/TopicDataControls' ;
25
+ import { TopicMessageDetails } from './TopicMessageDetails/TopicMessageDetails' ;
22
26
import {
23
27
DEFAULT_TOPIC_DATA_COLUMNS ,
24
28
REQUIRED_TOPIC_DATA_COLUMNS ,
@@ -43,6 +47,8 @@ interface TopicDataProps {
43
47
parentRef : React . RefObject < HTMLElement > ;
44
48
}
45
49
50
+ const columns = getAllColumns ( ) ;
51
+
46
52
export function TopicData ( { parentRef, path, database} : TopicDataProps ) {
47
53
const [ autoRefreshInterval ] = useAutoRefreshInterval ( ) ;
48
54
const [ startOffset , setStartOffset ] = React . useState < number > ( ) ;
@@ -61,9 +67,11 @@ export function TopicData({parentRef, path, database}: TopicDataProps) {
61
67
selectedOffset,
62
68
startTimestamp,
63
69
topicDataFilter,
70
+ activeOffset,
64
71
handleSelectedOffsetChange,
65
72
handleStartTimestampChange,
66
73
handleSelectedPartitionChange,
74
+ handleActiveOffsetChange,
67
75
} = useTopicDataQueryParams ( ) ;
68
76
69
77
React . useEffect ( ( ) => {
@@ -114,12 +122,15 @@ export function TopicData({parentRef, path, database}: TopicDataProps) {
114
122
115
123
React . useEffect ( ( ) => {
116
124
if ( partitions && partitions . length && isNil ( selectedPartition ) ) {
117
- handleSelectedPartitionChange ( partitions [ 0 ] . partitionId ) ;
125
+ const firstPartitionId = partitions [ 0 ] . partitionId ;
126
+ handleSelectedPartitionChange (
127
+ isNil ( firstPartitionId ) ? undefined : String ( firstPartitionId ) ,
128
+ ) ;
118
129
}
119
130
} , [ partitions , selectedPartition , handleSelectedPartitionChange ] ) ;
120
131
121
132
const { columnsToShow, columnsToSelect, setColumns} = useSelectedColumns (
122
- getAllColumns ( ) ,
133
+ columns ,
123
134
TOPIC_DATA_SELECTED_COLUMNS_LS_KEY ,
124
135
TOPIC_DATA_COLUMNS_TITLES ,
125
136
DEFAULT_TOPIC_DATA_COLUMNS ,
@@ -172,19 +183,28 @@ export function TopicData({parentRef, path, database}: TopicDataProps) {
172
183
[ baseOffset , parentRef ] ,
173
184
) ;
174
185
186
+ //this variable is used to scroll to active offset the very first time on open page
187
+ const initialActiveOffset = React . useMemo ( ( ) => activeOffset , [ ] ) ;
188
+
175
189
React . useEffect ( ( ) => {
176
190
if ( isFetching ) {
177
191
return ;
178
192
}
179
- const messages = currentData ?. Messages ;
180
- if ( messages ?. length ) {
181
- const messageOffset = safeParseNumber ( messages [ 0 ] . Offset ) ;
182
- //scroll when table is already rendered and calculated it's state
183
- setTimeout ( ( ) => {
184
- scrollToOffset ( messageOffset ) ;
185
- } , 0 ) ;
193
+
194
+ let currentOffset : number | undefined ;
195
+
196
+ if ( isNil ( initialActiveOffset ) ) {
197
+ const messages = currentData ?. Messages ;
198
+ if ( messages ?. length ) {
199
+ currentOffset = safeParseNumber ( messages [ 0 ] . Offset ) ;
200
+ }
201
+ } else {
202
+ currentOffset = safeParseNumber ( initialActiveOffset ) ;
203
+ }
204
+ if ( ! isNil ( currentOffset ) ) {
205
+ scrollToOffset ( currentOffset ) ;
186
206
}
187
- } , [ currentData , isFetching , scrollToOffset ] ) ;
207
+ } , [ currentData , isFetching , scrollToOffset , initialActiveOffset ] ) ;
188
208
189
209
const renderControls : RenderControls = ( ) => {
190
210
return (
@@ -222,29 +242,66 @@ export function TopicData({parentRef, path, database}: TopicDataProps) {
222
242
[ baseOffset ] ,
223
243
) ;
224
244
245
+ const closeDrawer = React . useCallback ( ( ) => {
246
+ handleActiveOffsetChange ( undefined ) ;
247
+ } , [ handleActiveOffsetChange ] ) ;
248
+
249
+ const renderDrawerContent = React . useCallback ( ( ) => {
250
+ return (
251
+ < Fullscreen >
252
+ < TopicMessageDetails database = { database } path = { path } />
253
+ </ Fullscreen >
254
+ ) ;
255
+ } , [ database , path ] ) ;
256
+
225
257
return (
226
258
! isNil ( baseOffset ) &&
227
259
! 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
- />
260
+ < DrawerWrapper
261
+ isDrawerVisible = { ! isNil ( activeOffset ) }
262
+ onCloseDrawer = { closeDrawer }
263
+ renderDrawerContent = { renderDrawerContent }
264
+ drawerId = "topic-data-details"
265
+ storageKey = "topic-data-details-drawer-width"
266
+ detectClickOutside
267
+ isPercentageWidth
268
+ drawerControls = { [
269
+ { type : 'copyLink' , link : window . location . href } ,
270
+ {
271
+ type : 'custom' ,
272
+ node : < EnableFullscreenButton disabled = { Boolean ( error ) } view = "flat" /> ,
273
+ key : 'fullscreen' ,
274
+ } ,
275
+ { type : 'close' } ,
276
+ ] }
277
+ title = { i18n ( 'label_message' ) }
278
+ headerClassName = { b ( 'drawer-header' ) }
279
+ >
280
+ < ResizeablePaginatedTable
281
+ columnsWidthLSKey = { TOPIC_DATA_COLUMNS_WIDTH_LS_KEY }
282
+ parentRef = { parentRef }
283
+ columns = { columnsToShow }
284
+ fetchData = { getTopicData }
285
+ initialEntitiesCount = { baseEndOffset - baseOffset }
286
+ limit = { TOPIC_DATA_FETCH_LIMIT }
287
+ renderControls = { renderControls }
288
+ renderErrorMessage = { renderPaginatedTableErrorMessage }
289
+ renderEmptyDataMessage = { renderEmptyDataMessage }
290
+ filters = { tableFilters }
291
+ tableName = "topicData"
292
+ rowHeight = { DEFAULT_TABLE_ROW_HEIGHT }
293
+ keepCache = { false }
294
+ getRowClassName = { ( row ) => {
295
+ return b ( 'row' , {
296
+ active : Boolean (
297
+ String ( row . Offset ) === selectedOffset ||
298
+ String ( row . Offset ) === activeOffset ,
299
+ ) ,
300
+ removed : row . removed ,
301
+ } ) ;
302
+ } }
303
+ />
304
+ </ DrawerWrapper >
248
305
)
249
306
) ;
250
307
}
0 commit comments