Skip to content

Commit a103739

Browse files
committed
fix: table is not scrolled to top on sorting
1 parent 828724d commit a103739

File tree

7 files changed

+125
-58
lines changed

7 files changed

+125
-58
lines changed

src/components/PaginatedTable/PaginatedTableWithLayout.tsx

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,45 @@ import React from 'react';
33
import {TableWithControlsLayout} from '../TableWithControlsLayout/TableWithControlsLayout';
44
import type {TableProps} from '../TableWithControlsLayout/TableWithControlsLayout';
55

6-
import {PaginatedTableProvider} from './PaginatedTableContext';
6+
import {PaginatedTableProvider, usePaginatedTableState} from './PaginatedTableContext';
77
import type {PaginatedTableState} from './types';
88

99
export interface PaginatedTableWithLayoutProps {
10-
controls: React.ReactNode;
10+
controls?: React.ReactNode;
1111
table: React.ReactNode;
1212
tableProps?: TableProps;
1313
error?: React.ReactNode;
1414
initialState?: Partial<PaginatedTableState>;
1515
fullHeight?: boolean;
1616
}
1717

18+
// Internal component that has access to the paginated table context
19+
const TableWithAutoScrolling = ({
20+
table,
21+
tableProps,
22+
}: {
23+
table: React.ReactNode;
24+
tableProps?: TableProps;
25+
}) => {
26+
const {tableState} = usePaginatedTableState();
27+
const {sortParams} = tableState;
28+
29+
// Enhance tableProps to include sortParams in scrollDependencies
30+
const enhancedTableProps = React.useMemo(
31+
() => ({
32+
...tableProps,
33+
scrollDependencies: [...(tableProps?.scrollDependencies || []), sortParams],
34+
}),
35+
[tableProps, sortParams],
36+
);
37+
38+
return (
39+
<TableWithControlsLayout.Table {...enhancedTableProps}>
40+
{table}
41+
</TableWithControlsLayout.Table>
42+
);
43+
};
44+
1845
export const PaginatedTableWithLayout = ({
1946
controls,
2047
table,
@@ -25,11 +52,11 @@ export const PaginatedTableWithLayout = ({
2552
}: PaginatedTableWithLayoutProps) => (
2653
<PaginatedTableProvider initialState={initialState}>
2754
<TableWithControlsLayout fullHeight={fullHeight}>
28-
<TableWithControlsLayout.Controls>{controls}</TableWithControlsLayout.Controls>
55+
{controls ? (
56+
<TableWithControlsLayout.Controls>{controls}</TableWithControlsLayout.Controls>
57+
) : null}
2958
{error}
30-
<TableWithControlsLayout.Table {...(tableProps || {})}>
31-
{table}
32-
</TableWithControlsLayout.Table>
59+
<TableWithAutoScrolling table={table} tableProps={tableProps} />
3360
</TableWithControlsLayout>
3461
</PaginatedTableProvider>
3562
);

src/components/TableWithControlsLayout/TableWithControlsLayout.tsx

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,12 @@ interface TableWithControlsLayoutItemProps {
1818
fullHeight?: boolean;
1919
}
2020

21-
export interface TableProps extends TableWithControlsLayoutItemProps {
21+
export interface TableProps extends Omit<TableWithControlsLayoutItemProps, 'children'> {
2222
loading?: boolean;
2323
scrollContainerRef?: React.RefObject<HTMLElement>;
2424
scrollDependencies?: any[];
25+
onSort?: (params: any) => void;
26+
children?: React.ReactNode | ((props: {onSort: (params: any) => void}) => React.ReactNode);
2527
}
2628

2729
export const TableWithControlsLayout = ({
@@ -56,24 +58,34 @@ TableWithControlsLayout.Table = function Table({
5658
className,
5759
scrollContainerRef,
5860
scrollDependencies = [],
61+
onSort,
5962
}: TableProps) {
6063
// Create an internal ref for the table container
6164
const tableContainerRef = React.useRef<HTMLDivElement>(null);
6265

6366
// Use the internal ref for scrolling
64-
useTableScroll({
67+
const {handleTableScroll} = useTableScroll({
6568
tableContainerRef,
6669
scrollContainerRef,
6770
dependencies: scrollDependencies,
6871
});
6972

73+
// Create a wrapper function that triggers scroll on sort
74+
const handleSort = React.useCallback(
75+
(params: any) => {
76+
onSort?.(params); // Call original callback if provided
77+
handleTableScroll(); // Trigger scroll to top
78+
},
79+
[onSort, handleTableScroll],
80+
);
81+
7082
if (loading) {
7183
return <TableSkeleton className={b('loader')} />;
7284
}
7385

7486
return (
7587
<div ref={tableContainerRef} className={b('table', className)}>
76-
{children}
88+
{typeof children === 'function' ? children({onSort: handleSort}) : children}
7789
</div>
7890
);
7991
};

src/containers/Nodes/PaginatedNodes/GroupedNodesComponent.tsx

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -55,18 +55,26 @@ const NodeGroup = React.memo(function NodeGroup({
5555
expanded={isExpanded}
5656
onIsExpandedChange={onIsExpandedChange}
5757
>
58-
<NodesTable
59-
path={path}
60-
database={database}
61-
searchValue={searchValue}
62-
problemFilter={'All'}
63-
uptimeFilter={NodesUptimeFilterValues.All}
64-
peerRoleFilter={peerRoleFilter}
65-
filterGroup={name}
66-
filterGroupBy={groupByParam}
67-
initialEntitiesCount={count}
68-
columns={columns}
69-
scrollContainerRef={scrollContainerRef}
58+
<PaginatedTableWithLayout
59+
initialState={{sortParams: undefined}}
60+
table={
61+
<NodesTable
62+
path={path}
63+
database={database}
64+
searchValue={searchValue}
65+
problemFilter={'All'}
66+
uptimeFilter={NodesUptimeFilterValues.All}
67+
peerRoleFilter={peerRoleFilter}
68+
filterGroup={name}
69+
filterGroupBy={groupByParam}
70+
initialEntitiesCount={count}
71+
columns={columns}
72+
scrollContainerRef={scrollContainerRef}
73+
/>
74+
}
75+
tableProps={{
76+
scrollContainerRef: scrollContainerRef,
77+
}}
7078
/>
7179
</TableGroup>
7280
);

src/containers/Storage/PaginatedStorageGroups/GroupedStorageGroupsComponent.tsx

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -59,20 +59,28 @@ export const StorageGroupGroup = React.memo(function StorageGroupGroup({
5959
expanded={isExpanded}
6060
onIsExpandedChange={onIsExpandedChange}
6161
>
62-
<PaginatedStorageGroupsTable
63-
database={database}
64-
scrollContainerRef={scrollContainerRef}
65-
nodeId={nodeId}
66-
groupId={groupId}
67-
pDiskId={pDiskId}
68-
filterGroup={name}
69-
filterGroupBy={filterGroupBy}
70-
searchValue={searchValue}
71-
visibleEntities={'all'}
72-
onShowAll={handleShowAllGroups}
73-
renderErrorMessage={renderPaginatedTableErrorMessage}
74-
columns={columns}
75-
initialEntitiesCount={count}
62+
<PaginatedTableWithLayout
63+
initialState={{sortParams: undefined}}
64+
table={
65+
<PaginatedStorageGroupsTable
66+
database={database}
67+
scrollContainerRef={scrollContainerRef}
68+
nodeId={nodeId}
69+
groupId={groupId}
70+
pDiskId={pDiskId}
71+
filterGroup={name}
72+
filterGroupBy={filterGroupBy}
73+
searchValue={searchValue}
74+
visibleEntities={'all'}
75+
onShowAll={handleShowAllGroups}
76+
renderErrorMessage={renderPaginatedTableErrorMessage}
77+
columns={columns}
78+
initialEntitiesCount={count}
79+
/>
80+
}
81+
tableProps={{
82+
scrollContainerRef: scrollContainerRef,
83+
}}
7684
/>
7785
</TableGroup>
7886
);

src/containers/Storage/PaginatedStorageNodes/GroupedStorageNodesComponent.tsx

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -60,21 +60,29 @@ export const StorageNodeGroup = React.memo(function StorageNodeGroup({
6060
expanded={isExpanded}
6161
onIsExpandedChange={onIsExpandedChange}
6262
>
63-
<PaginatedStorageNodesTable
64-
database={database}
65-
scrollContainerRef={scrollContainerRef}
66-
nodeId={nodeId}
67-
groupId={groupId}
68-
filterGroup={name}
69-
filterGroupBy={filterGroupBy}
70-
searchValue={searchValue}
71-
visibleEntities={'all'}
72-
nodesUptimeFilter={NodesUptimeFilterValues.All}
73-
onShowAll={handleShowAllNodes}
74-
renderErrorMessage={renderPaginatedTableErrorMessage}
75-
columns={columns}
76-
initialEntitiesCount={count}
77-
onDataFetched={onDataFetched}
63+
<PaginatedTableWithLayout
64+
initialState={{sortParams: undefined}}
65+
table={
66+
<PaginatedStorageNodesTable
67+
database={database}
68+
scrollContainerRef={scrollContainerRef}
69+
nodeId={nodeId}
70+
groupId={groupId}
71+
filterGroup={name}
72+
filterGroupBy={filterGroupBy}
73+
searchValue={searchValue}
74+
visibleEntities={'all'}
75+
nodesUptimeFilter={NodesUptimeFilterValues.All}
76+
onShowAll={handleShowAllNodes}
77+
renderErrorMessage={renderPaginatedTableErrorMessage}
78+
columns={columns}
79+
initialEntitiesCount={count}
80+
onDataFetched={onDataFetched}
81+
/>
82+
}
83+
tableProps={{
84+
scrollContainerRef: scrollContainerRef,
85+
}}
7886
/>
7987
</TableGroup>
8088
);

src/containers/Tablets/TabletsTable.tsx

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -217,12 +217,15 @@ export function TabletsTable({
217217
scrollDependencies={[tabletsSearch]}
218218
loading={loading}
219219
>
220-
<ResizeableDataTable
221-
columns={columns}
222-
data={filteredTablets}
223-
settings={DEFAULT_TABLE_SETTINGS}
224-
emptyDataMessage={i18n('noTabletsData')}
225-
/>
220+
{({onSort}) => (
221+
<ResizeableDataTable
222+
columns={columns}
223+
data={filteredTablets}
224+
settings={DEFAULT_TABLE_SETTINGS}
225+
emptyDataMessage={i18n('noTabletsData')}
226+
onSort={onSort}
227+
/>
228+
)}
226229
</TableWithControlsLayout.Table>
227230
</TableWithControlsLayout>
228231
);

src/containers/Tenants/Tenants.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ export const Tenants = ({additionalTenantsProps, scrollContainerRef}: TenantsPro
128128
);
129129
};
130130

131-
const renderTable = () => {
131+
const renderTable = (onSort?: (params: any) => void) => {
132132
const columns: Column<PreparedTenant>[] = [
133133
{
134134
name: 'Name',
@@ -261,6 +261,7 @@ export const Tenants = ({additionalTenantsProps, scrollContainerRef}: TenantsPro
261261
columns={columns}
262262
settings={DEFAULT_TABLE_SETTINGS}
263263
emptyDataMessage="No such tenants"
264+
onSort={onSort}
264265
/>
265266
);
266267
};
@@ -277,7 +278,7 @@ export const Tenants = ({additionalTenantsProps, scrollContainerRef}: TenantsPro
277278
loading={loading}
278279
scrollDependencies={[searchValue, problemFilter]}
279280
>
280-
{currentData ? renderTable() : null}
281+
{({onSort}) => (currentData ? renderTable(onSort) : null)}
281282
</TableWithControlsLayout.Table>
282283
</TableWithControlsLayout>
283284
</div>

0 commit comments

Comments
 (0)