Skip to content

Commit fc05ab6

Browse files
committed
fix(AnalyticalTable): offer limited support for infiniteScroll combined with a grouped table (#6431)
Using `infiniteScroll` with a grouped table can result in an odd user experience. For example, when rows are lazy-loaded via scrolling, new rows might only be added to existing groups. This won't change the scroll container's height, potentially forcing the user to scroll down again to load more rows. Therefore (and as we don't have a concept for this behavior) __it's not recommended using a grouped table in combination with `infiniteScroll`__!
1 parent 28675d0 commit fc05ab6

File tree

3 files changed

+19
-5
lines changed

3 files changed

+19
-5
lines changed

packages/main/src/components/AnalyticalTable/TableBody/VirtualTableBodyContainer.tsx

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { enrichEventWithDetails } from '@ui5/webcomponents-react-base';
22
import type { MutableRefObject } from 'react';
33
import { useCallback, useEffect, useRef, useState } from 'react';
4-
import type { AnalyticalTablePropTypes } from '../types/index.js';
4+
import type { AnalyticalTablePropTypes, TableInstance } from '../types/index.js';
55

66
interface VirtualTableBodyContainerProps {
77
tableBodyHeight: number;
@@ -12,13 +12,14 @@ interface VirtualTableBodyContainerProps {
1212
infiniteScroll?: AnalyticalTablePropTypes['infiniteScroll'];
1313
infiniteScrollThreshold?: AnalyticalTablePropTypes['infiniteScrollThreshold'];
1414
onLoadMore: AnalyticalTablePropTypes['onLoadMore'];
15-
rows: Record<string, any>[];
15+
rows: TableInstance['rows'];
1616
internalRowHeight: number;
1717
handleExternalScroll: AnalyticalTablePropTypes['onTableScroll'];
1818
visibleRows: number;
1919
popInRowHeight: number;
2020
rowCollapsedFlag?: boolean;
2121
dispatch: (e: { type: string; payload?: any }) => void;
22+
isGrouped: boolean;
2223
}
2324

2425
export const VirtualTableBodyContainer = (props: VirtualTableBodyContainerProps) => {
@@ -37,6 +38,7 @@ export const VirtualTableBodyContainer = (props: VirtualTableBodyContainerProps)
3738
visibleRows,
3839
popInRowHeight,
3940
rowCollapsedFlag,
41+
isGrouped,
4042
dispatch
4143
} = props;
4244
const [isMounted, setIsMounted] = useState(false);
@@ -75,13 +77,19 @@ export const VirtualTableBodyContainer = (props: VirtualTableBodyContainerProps)
7577
handleExternalScroll(enrichEventWithDetails(event, { rows, rowElements: event.target.children[0].children }));
7678
const scrollOffset = event.target.scrollTop;
7779
const isScrollingDown = lastScrollTop.current < scrollOffset;
78-
if (isScrollingDown && infiniteScroll) {
80+
const target = event.target;
81+
const scrolledToBottom = target.scrollHeight - target.scrollTop === target.clientHeight;
82+
// For a grouped table, it is possible that no new groups (rows) are added since new rows are added to existing groups.
83+
// Because of this, the table should trigger the `onLoadMore` event every time a user scrolls to the bottom.
84+
const applyGroupingLogic = scrolledToBottom && isGrouped;
85+
86+
if ((isScrollingDown || applyGroupingLogic) && infiniteScroll) {
7987
lastScrollTop.current = scrollOffset;
8088
const currentLastRow =
8189
Math.floor(scrollOffset / popInRowHeight) +
8290
(popInRowHeight === internalRowHeight ? visibleRows : Math.floor(tableBodyHeight / popInRowHeight));
83-
if (rows.length - currentLastRow < infiniteScrollThreshold) {
84-
if (!firedInfiniteLoadEvents.current.has(rows.length)) {
91+
if (rows.length - currentLastRow < infiniteScrollThreshold || applyGroupingLogic) {
92+
if (!firedInfiniteLoadEvents.current.has(rows.length) || applyGroupingLogic) {
8593
onLoadMore(event);
8694
}
8795
firedInfiniteLoadEvents.current.add(rows.length);

packages/main/src/components/AnalyticalTable/index.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,7 @@ const AnalyticalTable = forwardRef<AnalyticalTableDomRef, AnalyticalTablePropTyp
287287

288288
const tableState: AnalyticalTableState = tableInstanceRef.current.state;
289289
const { triggerScroll } = tableState;
290+
const isGrouped = !!tableState.groupBy.length;
290291

291292
const noDataTextI18n = i18nBundle.getText(LIST_NO_DATA);
292293
const noDataTextFiltered = i18nBundle.getText(NO_DATA_FILTERED);
@@ -796,6 +797,7 @@ const AnalyticalTable = forwardRef<AnalyticalTableDomRef, AnalyticalTablePropTyp
796797
rows={rows}
797798
handleExternalScroll={handleBodyScroll}
798799
visibleRows={internalVisibleRowCount}
800+
isGrouped={isGrouped}
799801
>
800802
<VirtualTableBody
801803
scrollContainerRef={scrollContainerRef}

packages/main/src/components/AnalyticalTable/types/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,8 @@ export interface AnalyticalTablePropTypes extends Omit<CommonProps, 'title'> {
490490
* Defines whether columns are groupable.
491491
*
492492
* __Note:__ This prop has no effect when `isTreeTable` is true or `renderRowSubComponent` is set.
493+
*
494+
* __Note:__ It is not recommended to use grouping in combination with `infiniteScroll` as there is no concept for this configuration.
493495
*/
494496
groupable?: boolean;
495497
/**
@@ -546,6 +548,8 @@ export interface AnalyticalTablePropTypes extends Omit<CommonProps, 'title'> {
546548
columnOrder?: string[];
547549
/**
548550
* Defines whether infinite scroll is active.
551+
*
552+
* __Note:__ It is not recommended to use this prop in combination with a grouped table, as there is no concept for this configuration.
549553
*/
550554
infiniteScroll?: boolean;
551555
/**

0 commit comments

Comments
 (0)