@@ -9,6 +9,10 @@ import {
99} from 'redux/reducers/topicMessages/selectors' ;
1010import TopicMessagesContext from 'components/contexts/TopicMessagesContext' ;
1111import { useAppSelector } from 'lib/hooks/redux' ;
12+ import { Button } from 'components/common/Button/Button' ;
13+ import { useSearchParams } from 'react-router-dom' ;
14+ import { MESSAGES_PER_PAGE } from 'lib/constants' ;
15+ import * as S from 'components/common/NewTable/Table.styled' ;
1216
1317import PreviewModal from './PreviewModal' ;
1418import Message , { PreviewFilter } from './Message' ;
@@ -19,75 +23,123 @@ const MessagesTable: React.FC = () => {
1923 const [ keyFilters , setKeyFilters ] = useState < PreviewFilter [ ] > ( [ ] ) ;
2024 const [ contentFilters , setContentFilters ] = useState < PreviewFilter [ ] > ( [ ] ) ;
2125
26+ const [ searchParams , setSearchParams ] = useSearchParams ( ) ;
27+ const page = searchParams . get ( 'page' ) ;
2228 const { isLive } = useContext ( TopicMessagesContext ) ;
2329
2430 const messages = useAppSelector ( getTopicMessges ) ;
2531 const isFetching = useAppSelector ( getIsTopicMessagesFetching ) ;
32+
33+ const isTailing = isLive && isFetching ;
34+
35+ // Pagination is disabled in live mode, also we don't want to show the button
36+ // if we are fetching the messages or if we are at the end of the topic
37+ const isPaginationDisabled = isTailing || isFetching ;
38+
39+ const isNextPageButtonDisabled =
40+ isPaginationDisabled || messages . length < Number ( MESSAGES_PER_PAGE ) ;
41+ const isPrevPageButtonDisabled =
42+ isPaginationDisabled || ! Number ( searchParams . get ( 'page' ) ) ;
43+
44+ const handleNextPage = ( ) => {
45+ searchParams . set ( 'page' , String ( Number ( page || 0 ) + 1 ) ) ;
46+ setSearchParams ( searchParams ) ;
47+ } ;
48+
49+ const handlePrevPage = ( ) => {
50+ searchParams . set ( 'page' , String ( Number ( page || 0 ) - 1 ) ) ;
51+ setSearchParams ( searchParams ) ;
52+ } ;
53+
2654 return (
27- < Table isFullwidth >
28- < thead >
29- < tr >
30- < TableHeaderCell > </ TableHeaderCell >
31- < TableHeaderCell title = "Offset" />
32- < TableHeaderCell title = "Partition" />
33- < TableHeaderCell title = "Timestamp" />
34- < TableHeaderCell
35- title = "Key"
36- previewText = { `Preview ${
37- keyFilters . length ? `(${ keyFilters . length } selected)` : ''
38- } `}
39- onPreview = { ( ) => setPreviewFor ( 'key' ) }
40- />
41- < TableHeaderCell
42- title = "Value"
43- previewText = { `Preview ${
44- contentFilters . length ? `(${ contentFilters . length } selected)` : ''
45- } `}
46- onPreview = { ( ) => setPreviewFor ( 'content' ) }
47- />
48- < TableHeaderCell > </ TableHeaderCell >
55+ < >
56+ < Table isFullwidth >
57+ < thead >
58+ < tr >
59+ < TableHeaderCell > </ TableHeaderCell >
60+ < TableHeaderCell title = "Offset" />
61+ < TableHeaderCell title = "Partition" />
62+ < TableHeaderCell title = "Timestamp" />
63+ < TableHeaderCell
64+ title = "Key"
65+ previewText = { `Preview ${
66+ keyFilters . length ? `(${ keyFilters . length } selected)` : ''
67+ } `}
68+ onPreview = { ( ) => setPreviewFor ( 'key' ) }
69+ />
70+ < TableHeaderCell
71+ title = "Value"
72+ previewText = { `Preview ${
73+ contentFilters . length
74+ ? `(${ contentFilters . length } selected)`
75+ : ''
76+ } `}
77+ onPreview = { ( ) => setPreviewFor ( 'content' ) }
78+ />
79+ < TableHeaderCell > </ TableHeaderCell >
4980
50- { previewFor !== null && (
51- < PreviewModal
52- values = { previewFor === 'key' ? keyFilters : contentFilters }
53- toggleIsOpen = { ( ) => setPreviewFor ( null ) }
54- setFilters = { ( payload : PreviewFilter [ ] ) =>
55- previewFor === 'key'
56- ? setKeyFilters ( payload )
57- : setContentFilters ( payload )
58- }
81+ { previewFor !== null && (
82+ < PreviewModal
83+ values = { previewFor === 'key' ? keyFilters : contentFilters }
84+ toggleIsOpen = { ( ) => setPreviewFor ( null ) }
85+ setFilters = { ( payload : PreviewFilter [ ] ) =>
86+ previewFor === 'key'
87+ ? setKeyFilters ( payload )
88+ : setContentFilters ( payload )
89+ }
90+ />
91+ ) }
92+ </ tr >
93+ </ thead >
94+ < tbody >
95+ { messages . map ( ( message : TopicMessage ) => (
96+ < Message
97+ key = { [
98+ message . offset ,
99+ message . timestamp ,
100+ message . key ,
101+ message . partition ,
102+ ] . join ( '-' ) }
103+ message = { message }
104+ keyFilters = { keyFilters }
105+ contentFilters = { contentFilters }
59106 />
107+ ) ) }
108+ { isFetching && isLive && ! messages . length && (
109+ < tr >
110+ < td colSpan = { 10 } >
111+ < PageLoader />
112+ </ td >
113+ </ tr >
60114 ) }
61- </ tr >
62- </ thead >
63- < tbody >
64- { messages . map ( ( message : TopicMessage ) => (
65- < Message
66- key = { [
67- message . offset ,
68- message . timestamp ,
69- message . key ,
70- message . partition ,
71- ] . join ( '-' ) }
72- message = { message }
73- keyFilters = { keyFilters }
74- contentFilters = { contentFilters }
75- />
76- ) ) }
77- { isFetching && isLive && ! messages . length && (
78- < tr >
79- < td colSpan = { 10 } >
80- < PageLoader />
81- </ td >
82- </ tr >
83- ) }
84- { messages . length === 0 && ! isFetching && (
85- < tr >
86- < td colSpan = { 10 } > No messages found</ td >
87- </ tr >
88- ) }
89- </ tbody >
90- </ Table >
115+ { messages . length === 0 && ! isFetching && (
116+ < tr >
117+ < td colSpan = { 10 } > No messages found</ td >
118+ </ tr >
119+ ) }
120+ </ tbody >
121+ </ Table >
122+ < S . Pagination >
123+ < S . Pages >
124+ < Button
125+ buttonType = "secondary"
126+ buttonSize = "L"
127+ disabled = { isPrevPageButtonDisabled }
128+ onClick = { handlePrevPage }
129+ >
130+ ← Back
131+ </ Button >
132+ < Button
133+ buttonType = "secondary"
134+ buttonSize = "L"
135+ disabled = { isNextPageButtonDisabled }
136+ onClick = { handleNextPage }
137+ >
138+ Next →
139+ </ Button >
140+ </ S . Pages >
141+ </ S . Pagination >
142+ </ >
91143 ) ;
92144} ;
93145
0 commit comments