Skip to content

Commit 11508f1

Browse files
committed
fix: paginated container and extra pixels
1 parent fa227a5 commit 11508f1

File tree

15 files changed

+310
-245
lines changed

15 files changed

+310
-245
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import React from 'react';
2+
3+
import {TableWithControlsLayout} from '../TableWithControlsLayout/TableWithControlsLayout';
4+
import type {TableProps} from '../TableWithControlsLayout/TableWithControlsLayout';
5+
6+
import {PaginatedTableProvider} from './PaginatedTableContext';
7+
import type {PaginatedTableState} from './types';
8+
9+
export interface PaginatedTableWithLayoutProps {
10+
controls: React.ReactNode;
11+
table: React.ReactNode;
12+
tableProps?: TableProps;
13+
error?: React.ReactNode;
14+
initialState?: Partial<PaginatedTableState>;
15+
fullHeight?: boolean;
16+
}
17+
18+
export const PaginatedTableWithLayout = ({
19+
controls,
20+
table,
21+
tableProps,
22+
error,
23+
initialState,
24+
fullHeight = true,
25+
}: PaginatedTableWithLayoutProps) => (
26+
<PaginatedTableProvider initialState={initialState}>
27+
<TableWithControlsLayout fullHeight={fullHeight}>
28+
<TableWithControlsLayout.Controls>{controls}</TableWithControlsLayout.Controls>
29+
{error}
30+
<TableWithControlsLayout.Table {...(tableProps || {})}>
31+
{table}
32+
</TableWithControlsLayout.Table>
33+
</TableWithControlsLayout>
34+
</PaginatedTableProvider>
35+
);

src/components/TableWithControlsLayout/TableWithControlsLayout.scss

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
11
@use '../../styles/mixins.scss';
22

33
.ydb-table-with-controls-layout {
4-
--data-table-sticky-top-offset: 62px;
4+
// Height of visible area above table for min-height calculation (e.g., tabs)
5+
--data-table-min-height-offset: 62px;
6+
// Total height of all fixed elements above table for sticky header positioning
7+
--data-table-sticky-header-offset: 62px;
58

69
display: inline-block;
710

811
box-sizing: border-box;
912
min-width: 100%;
1013

1114
&_fullHeight {
12-
min-height: calc(100vh - var(--data-table-sticky-top-offset));
15+
min-height: calc(100vh - var(--data-table-min-height-offset));
1316
}
1417

1518
&__controls-wrapper {
@@ -34,18 +37,14 @@
3437
&__table {
3538
position: relative;
3639
z-index: 2;
37-
38-
&_fullHeight {
39-
min-height: calc(100vh - var(--data-table-sticky-top-offset));
40-
}
4140
}
4241

4342
.ydb-paginated-table__head {
44-
top: var(--data-table-sticky-top-offset, 62px);
43+
top: var(--data-table-sticky-header-offset, 62px);
4544
}
4645

4746
.data-table__sticky_moving {
4847
// Place table head right after controls
49-
top: var(--data-table-sticky-top-offset, 62px) !important;
48+
top: var(--data-table-sticky-header-offset, 62px) !important;
5049
}
5150
}

src/components/TableWithControlsLayout/TableWithControlsLayout.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@ import './TableWithControlsLayout.scss';
1010
const b = cn('ydb-table-with-controls-layout');
1111

1212
interface TableWithControlsLayoutItemProps {
13-
children: React.ReactNode;
13+
children?: React.ReactNode;
1414
className?: string;
1515
fullHeight?: boolean;
1616
}
1717

18-
interface TableProps extends TableWithControlsLayoutItemProps {
18+
export interface TableProps extends TableWithControlsLayoutItemProps {
1919
loading?: boolean;
2020
scrollContainerRef?: React.RefObject<HTMLElement>;
2121
scrollDependencies?: any[];
@@ -44,7 +44,6 @@ TableWithControlsLayout.Table = function Table({
4444
children,
4545
loading,
4646
className,
47-
fullHeight,
4847
scrollContainerRef,
4948
scrollDependencies = [],
5049
}: TableProps) {
@@ -63,7 +62,7 @@ TableWithControlsLayout.Table = function Table({
6362
}
6463

6564
return (
66-
<div ref={tableContainerRef} className={b('table', {fullHeight}, className)}>
65+
<div ref={tableContainerRef} className={b('table', className)}>
6766
{children}
6867
</div>
6968
);

src/components/TableWithControlsLayout/useTableScroll.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@ export const useTableScroll = ({
1616
// Try to get the variable from parent elements
1717
if (tableContainerRef?.current) {
1818
const computedStyle = window.getComputedStyle(tableContainerRef.current);
19+
// Read the sticky header offset variable for correct scroll positioning
1920
const stickyTopOffset = computedStyle.getPropertyValue(
20-
'--data-table-sticky-top-offset',
21+
'--data-table-sticky-header-offset',
2122
);
2223

2324
return stickyTopOffset ? parseInt(stickyTopOffset, 10) : 0;
@@ -37,7 +38,7 @@ export const useTableScroll = ({
3738
const scrollContainerRect = scrollContainerRef.current.getBoundingClientRect();
3839
const scrollTop =
3940
tableRect.top - scrollContainerRect.top + scrollContainerRef.current.scrollTop;
40-
if (tableRect.top < scrollContainerRect.top) {
41+
if (tableRect.top - stickyTopOffset < scrollContainerRect.top) {
4142
// Adjust scroll position to account for sticky offset
4243
scrollContainerRef.current.scrollTo(0, scrollTop - stickyTopOffset);
4344
}

src/containers/Cluster/Cluster.scss

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@
6363
}
6464

6565
.ydb-table-with-controls-layout {
66-
--data-table-sticky-top-offset: 102px;
66+
// Height of visible tabs area above table for min-height calculation
67+
--data-table-min-height-offset: 62px;
68+
// Total height of all fixed elements above table for sticky header positioning
69+
--data-table-sticky-header-offset: 102px;
6770
}
6871
}

src/containers/Cluster/Cluster.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,14 +159,21 @@ export function Cluster({
159159
getLocationObjectFromHref(getClusterPath(clusterTabsIds.tablets)).pathname
160160
}
161161
>
162-
<TabletsTable loading={infoLoading} tablets={clusterTablets} />
162+
<TabletsTable
163+
loading={infoLoading}
164+
tablets={clusterTablets}
165+
scrollContainerRef={container}
166+
/>
163167
</Route>
164168
<Route
165169
path={
166170
getLocationObjectFromHref(getClusterPath(clusterTabsIds.tenants)).pathname
167171
}
168172
>
169-
<Tenants additionalTenantsProps={additionalTenantsProps} />
173+
<Tenants
174+
scrollContainerRef={container}
175+
additionalTenantsProps={additionalTenantsProps}
176+
/>
170177
</Route>
171178
<Route
172179
path={getLocationObjectFromHref(getClusterPath(clusterTabsIds.nodes)).pathname}

src/containers/Node/Node.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,14 @@ function NodePageContent({
234234
);
235235
}
236236
case 'tablets': {
237-
return <Tablets nodeId={nodeId} database={tenantName} onlyActive />;
237+
return (
238+
<Tablets
239+
scrollContainerRef={parentContainer}
240+
nodeId={nodeId}
241+
database={tenantName}
242+
onlyActive
243+
/>
244+
);
238245
}
239246

240247
case 'structure': {

src/containers/Nodes/Nodes.tsx

Lines changed: 50 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,8 @@ import type {TableColumnSetupItem} from '@gravity-ui/uikit';
55
import {ResponseError} from '../../components/Errors/ResponseError';
66
import {LoaderWrapper} from '../../components/LoaderWrapper/LoaderWrapper';
77
import type {Column} from '../../components/PaginatedTable';
8-
import {
9-
PaginatedTableProvider,
10-
usePaginatedTableState,
11-
} from '../../components/PaginatedTable/PaginatedTableContext';
12-
import {TableWithControlsLayout} from '../../components/TableWithControlsLayout/TableWithControlsLayout';
8+
import {usePaginatedTableState} from '../../components/PaginatedTable/PaginatedTableContext';
9+
import {PaginatedTableWithLayout} from '../../components/PaginatedTable/PaginatedTableWithLayout';
1310
import {
1411
NODES_COLUMNS_TITLES,
1512
isMonitoringUserNodesColumn,
@@ -179,34 +176,34 @@ function NodesComponent({
179176
);
180177

181178
return (
182-
<PaginatedTableProvider>
183-
<TableWithControlsLayout fullHeight>
184-
<TableWithControlsLayout.Controls>
185-
<NodesControlsWithTableState
186-
withGroupBySelect={viewerNodesHandlerHasGrouping}
187-
groupByParams={groupByParams}
188-
withPeerRoleFilter={withPeerRoleFilter}
189-
columnsToSelect={columnsToSelect}
190-
handleSelectedColumnsUpdate={setColumns}
191-
/>
192-
</TableWithControlsLayout.Controls>
193-
<TableWithControlsLayout.Table
179+
<PaginatedTableWithLayout
180+
controls={
181+
<NodesControlsWithTableState
182+
withGroupBySelect={viewerNodesHandlerHasGrouping}
183+
groupByParams={groupByParams}
184+
withPeerRoleFilter={withPeerRoleFilter}
185+
columnsToSelect={columnsToSelect}
186+
handleSelectedColumnsUpdate={setColumns}
187+
/>
188+
}
189+
table={
190+
<NodesTable
191+
path={path}
192+
database={database}
193+
searchValue={searchValue}
194+
problemFilter={problemFilter}
195+
uptimeFilter={uptimeFilter}
196+
peerRoleFilter={peerRoleFilter}
197+
columns={columnsToShow}
194198
scrollContainerRef={scrollContainerRef}
195-
scrollDependencies={[searchValue, problemFilter, uptimeFilter, peerRoleFilter]}
196-
>
197-
<NodesTable
198-
path={path}
199-
database={database}
200-
searchValue={searchValue}
201-
problemFilter={problemFilter}
202-
uptimeFilter={uptimeFilter}
203-
peerRoleFilter={peerRoleFilter}
204-
columns={columnsToShow}
205-
scrollContainerRef={scrollContainerRef}
206-
/>
207-
</TableWithControlsLayout.Table>
208-
</TableWithControlsLayout>
209-
</PaginatedTableProvider>
199+
/>
200+
}
201+
tableProps={{
202+
scrollContainerRef,
203+
scrollDependencies: [searchValue, problemFilter, uptimeFilter, peerRoleFilter],
204+
}}
205+
fullHeight
206+
/>
210207
);
211208
}
212209

@@ -377,27 +374,26 @@ function GroupedNodesComponent({
377374
};
378375

379376
return (
380-
<PaginatedTableProvider initialState={initialState}>
381-
<TableWithControlsLayout>
382-
<TableWithControlsLayout.Controls>
383-
<NodesControlsWithTableState
384-
withGroupBySelect={true}
385-
groupByParams={groupByParams}
386-
withPeerRoleFilter={withPeerRoleFilter}
387-
columnsToSelect={columnsToSelect}
388-
handleSelectedColumnsUpdate={setColumns}
389-
/>
390-
</TableWithControlsLayout.Controls>
391-
{error ? <ResponseError error={error} /> : null}
392-
<TableWithControlsLayout.Table
393-
scrollContainerRef={scrollContainerRef}
394-
scrollDependencies={[searchValue, groupByParam]}
395-
loading={isLoading}
396-
className={b('groups-wrapper')}
397-
>
398-
{renderGroups()}
399-
</TableWithControlsLayout.Table>
400-
</TableWithControlsLayout>
401-
</PaginatedTableProvider>
377+
<PaginatedTableWithLayout
378+
initialState={initialState}
379+
controls={
380+
<NodesControlsWithTableState
381+
withGroupBySelect={true}
382+
groupByParams={groupByParams}
383+
withPeerRoleFilter={withPeerRoleFilter}
384+
columnsToSelect={columnsToSelect}
385+
handleSelectedColumnsUpdate={setColumns}
386+
/>
387+
}
388+
error={error ? <ResponseError error={error} /> : null}
389+
table={renderGroups()}
390+
tableProps={{
391+
scrollContainerRef,
392+
scrollDependencies: [searchValue, groupByParam],
393+
loading: isLoading,
394+
className: b('groups-wrapper'),
395+
}}
396+
fullHeight
397+
/>
402398
);
403399
}

0 commit comments

Comments
 (0)