1- import { useEffect } from "react" ;
1+ import { useEffect , useState , useRef } from "react" ;
22import { useAtomValue , useSetAtom } from "jotai" ;
3- import { useParams } from "react-router-dom" ;
3+ import { useParams , useSearchParams } from "react-router-dom" ;
44import { Notification , Icon } from "@canonical/react-components" ;
55
66import { useSerialLogs } from "../../hooks" ;
@@ -15,7 +15,23 @@ import type { SerialLogResponse, ApiResponse } from "../../types/shared";
1515
1616function SerialLog ( ) : React . JSX . Element {
1717 const { id, modelId } = useParams ( ) ;
18+ const [ searchParams , setSearchParams ] = useSearchParams ( ) ;
1819 const brandId = useAtomValue ( brandIdState ) ;
20+ const [ currentCursor , setCurrentCursor ] = useState < string | null > ( null ) ;
21+ const [ nextCursor , setNextCursor ] = useState < string | null > ( null ) ;
22+ const cursorHistory = useRef < Array < string | null > > ( [ ] ) ;
23+
24+ const pageSizeParam = searchParams . get ( "page-size" ) ;
25+ const parsedPageSize = pageSizeParam ? parseInt ( pageSizeParam ) : NaN ;
26+ const startTime = searchParams . get ( "start-time" ) ;
27+ const endTime = searchParams . get ( "end-time" ) ;
28+ const pageSize = Number . isInteger ( parsedPageSize ) ? parsedPageSize : 25 ;
29+ const params = {
30+ pageSize : pageSize ,
31+ page : currentCursor ,
32+ ...( startTime && endTime && { interval : { startTime, endTime } } ) ,
33+ } ;
34+
1935 const {
2036 isLoading,
2137 isError,
@@ -24,17 +40,44 @@ function SerialLog(): React.JSX.Element {
2440 } : UseQueryResult < ApiResponse < SerialLogResponse > , Error > = useSerialLogs (
2541 brandId ,
2642 modelId ,
43+ params ,
2744 ) ;
2845 const setSerialLogs = useSetAtom ( serialLogsListState ) ;
2946 const brandStore = useAtomValue ( brandStoreState ( id ) ) ;
3047
48+ const handlePageForward = ( ) => {
49+ cursorHistory . current . push ( currentCursor ) ;
50+ setCurrentCursor ( nextCursor ) ;
51+ } ;
52+
53+ const handlePageBack = ( ) => {
54+ const lastCursor = cursorHistory . current . pop ( ) ;
55+ setCurrentCursor ( lastCursor || null ) ;
56+ } ;
57+
58+ const handlePageSizeChange = ( newPageSize : number ) => {
59+ // Need to reset current page when changing page size
60+ // because otherwise the cursor history gets out of sync
61+ setCurrentCursor ( null ) ;
62+ cursorHistory . current = [ ] ;
63+ setSearchParams ( ( params ) => {
64+ params . set ( "page-size" , newPageSize . toString ( ) ) ;
65+ return params ;
66+ } ) ;
67+ } ;
68+
3169 brandStore
3270 ? setPageTitle ( `Serial logs in ${ brandStore . name } ` )
3371 : setPageTitle ( "Serial logs" ) ;
3472
3573 useEffect ( ( ) => {
36- if ( ! isLoading && ! isError && data ) {
74+ if ( isLoading && isError ) {
75+ return ;
76+ }
77+
78+ if ( data ) {
3779 setSerialLogs ( data . data ?. items || [ ] ) ;
80+ setNextCursor ( data . data ?. [ "next-cursor" ] || null ) ;
3881 }
3982 } , [ isLoading , isError , data ] ) ;
4083
@@ -57,7 +100,16 @@ function SerialLog(): React.JSX.Element {
57100 </ Notification >
58101 ) : (
59102 < div className = "u-flex-column u-flex-grow" >
60- < SerialLogTable />
103+ < SerialLogTable
104+ handlePageForward = { handlePageForward }
105+ handlePageBack = { handlePageBack }
106+ handlePageSizeChange = { handlePageSizeChange }
107+ forwardDisabled = { ! nextCursor }
108+ backDisabled = {
109+ cursorHistory . current . length < 1 || currentCursor === null
110+ }
111+ pageSize = { pageSize }
112+ />
61113 </ div >
62114 ) }
63115 </ div >
0 commit comments