@@ -15,23 +15,18 @@ import {
1515 getCoreRowModel ,
1616 getPaginationRowModel ,
1717 getSortedRowModel ,
18- type PaginationState ,
19- type SortingState ,
20- type Updater ,
2118 useReactTable ,
2219} from '@tanstack/react-table' ;
2320import { AlertTriangle } from 'lucide-react' ;
24- import { parseAsBoolean , parseAsInteger , parseAsString , useQueryState } from 'nuqs' ;
2521import type { FC } from 'react' ;
2622
2723import '../../../utils/array-extensions' ;
2824
29- import { useQueryStateWithCallback } from '../../../hooks/use-query-state-with-callback ' ;
25+ import { useUrlTableState } from '../../../hooks/use-url-table-state ' ;
3026import { useApiStoreHook } from '../../../state/backend-api' ;
3127import type { Partition , Topic } from '../../../state/rest-interfaces' ;
3228import { uiSettings } from '../../../state/ui' ;
3329import { DefaultSkeleton , numberToThousandsString } from '../../../utils/tsx-utils' ;
34- import { DEFAULT_TABLE_PAGE_SIZE } from '../../constants' ;
3530import { BrokerList } from '../../misc/broker-list' ;
3631import { Alert , AlertDescription } from '../../redpanda-ui/components/alert' ;
3732import { Badge } from '../../redpanda-ui/components/badge' ;
@@ -45,40 +40,13 @@ export const TopicPartitions: FC<TopicPartitionsProps> = ({ topic }) => {
4540 const partitions = useApiStoreHook ( ( s ) => s . topicPartitions . get ( topic . topicName ) ) ;
4641 const clusterHealth = useApiStoreHook ( ( s ) => s . clusterHealth ) ;
4742
48- const [ pageIndex , setPageIndex ] = useQueryState ( 'partitionPage' , parseAsInteger . withDefault ( 0 ) ) ;
49-
50- const [ pageSize , setPageSize ] = useQueryStateWithCallback < number > (
51- {
52- onUpdate : ( val ) => {
53- uiSettings . topicPartitionsList . pageSize = val ;
54- } ,
55- getDefaultValue : ( ) => uiSettings . topicPartitionsList . pageSize ,
56- } ,
57- 'partitionPageSize' ,
58- parseAsInteger . withDefault ( DEFAULT_TABLE_PAGE_SIZE )
59- ) ;
60-
61- const [ sortId , setSortId ] = useQueryStateWithCallback < string > (
62- {
63- onUpdate : ( val ) => {
64- uiSettings . topicPartitionsList . sortId = val ;
65- } ,
66- getDefaultValue : ( ) => uiSettings . topicPartitionsList . sortId ,
67- } ,
68- 'partitionSortId' ,
69- parseAsString . withDefault ( '' )
70- ) ;
71-
72- const [ sortDesc , setSortDesc ] = useQueryStateWithCallback < boolean > (
73- {
74- onUpdate : ( val ) => {
75- uiSettings . topicPartitionsList . sortDesc = val ;
76- } ,
77- getDefaultValue : ( ) => uiSettings . topicPartitionsList . sortDesc ,
78- } ,
79- 'partitionSortDesc' ,
80- parseAsBoolean . withDefault ( false )
81- ) ;
43+ // Kept above the early returns so the hook order stays stable; clamping no-ops until partitions load.
44+ const { sorting, pagination, onSortingChange, onPaginationChange } = useUrlTableState ( {
45+ keyPrefix : 'partition' ,
46+ settings : uiSettings . topicPartitionsList ,
47+ rowCount : Array . isArray ( partitions ) ? partitions . length : 0 ,
48+ enabled : Array . isArray ( partitions ) ,
49+ } ) ;
8250
8351 if ( partitions === undefined ) {
8452 return DefaultSkeleton ;
@@ -95,27 +63,6 @@ export const TopicPartitions: FC<TopicPartitionsProps> = ({ topic }) => {
9563 ( { topicName } ) => topicName === topic . topicName
9664 ) ?. partitionIds ;
9765
98- const sorting : SortingState = sortId ? [ { id : sortId , desc : sortDesc } ] : [ ] ;
99- const pagination : PaginationState = { pageIndex, pageSize } ;
100-
101- const handleSortingChange = ( updater : Updater < SortingState > ) => {
102- const next = typeof updater === 'function' ? updater ( sorting ) : updater ;
103- if ( next . length > 0 ) {
104- setSortId ( next [ 0 ] . id ) ;
105- setSortDesc ( next [ 0 ] . desc ) ;
106- } else {
107- setSortId ( '' ) ;
108- setSortDesc ( false ) ;
109- }
110- void setPageIndex ( 0 ) ;
111- } ;
112-
113- const handlePaginationChange = ( updater : Updater < PaginationState > ) => {
114- const next = typeof updater === 'function' ? updater ( pagination ) : updater ;
115- void setPageIndex ( next . pageIndex ) ;
116- setPageSize ( next . pageSize ) ;
117- } ;
118-
11966 const columns : ColumnDef < Partition > [ ] = [
12067 {
12168 accessorKey : 'id' ,
@@ -160,8 +107,8 @@ export const TopicPartitions: FC<TopicPartitionsProps> = ({ topic }) => {
160107 data : partitions ,
161108 columns,
162109 state : { sorting, pagination } ,
163- onSortingChange : handleSortingChange ,
164- onPaginationChange : handlePaginationChange ,
110+ onSortingChange,
111+ onPaginationChange,
165112 getCoreRowModel : getCoreRowModel ( ) ,
166113 getSortedRowModel : getSortedRowModel ( ) ,
167114 getPaginationRowModel : getPaginationRowModel ( ) ,
@@ -218,7 +165,7 @@ const PartitionError: FC<{ partition: Partition }> = ({ partition }) => {
218165 return (
219166 < Popover >
220167 < PopoverTrigger asChild >
221- < button className = "inline-flex" type = "button" >
168+ < button aria-label = "Show partition error details" className = "inline-flex" type = "button" >
222169 < AlertTriangle className = "h-5 w-5 text-orange-500" />
223170 </ button >
224171 </ PopoverTrigger >
0 commit comments