Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ actions.toggleGroupBy = 'toggleGroupBy';
*
* This is a fork of react-table's `useGroupBy` with the following changes:
* - Aggregate grouped columns that define an `aggregate` above their own grouping level, instead of copying the first leaf value
* - Derive `canGroupBy` from `disableGroupBy` only (no self-seed), so runtime `groupable` toggling works — like `useSortBy`/`useFilters`
*/
export const useGroupBy: PluginHook = (hooks: ReactTableHooks) => {
hooks.getGroupByToggleProps = [defaultGetGroupByToggleProps];
Expand Down Expand Up @@ -154,12 +155,11 @@ function useInstance(instance: TableInstance) {

column.canGroupBy = accessor
? getFirstDefined(
column.canGroupBy,
columnDisableGroupBy === true ? false : undefined,
disableGroupBy === true ? false : undefined,
true,
)
: getFirstDefined(column.canGroupBy, defaultColumnGroupBy, defaultCanGroupBy, false);
: getFirstDefined(defaultColumnGroupBy, defaultCanGroupBy, false);

if (column.canGroupBy) {
column.toggleGroupBy = () => instance.toggleGroupBy(column.id);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useMemo } from 'react';
import { useMemo, useState } from 'react';
import type { AnalyticalTableColumnDefinition } from '../index.js';
import { AnalyticalTable } from '../index.js';

Expand Down Expand Up @@ -88,3 +88,32 @@ export const GroupingAggregationHarness = () => {
/>
);
};

const toggleData = [
{ name: 'Alpha', status: 'active' },
{ name: 'Bravo', status: 'active' },
{ name: 'Charlie', status: 'inactive' },
{ name: 'Delta', status: 'active' },
{ name: 'Echo', status: 'inactive' },
];

// Toggling `groupable` at runtime must flip `column.canGroupBy` so the Group/Ungroup affordance
// appears and disappears accordingly.
export const GroupableRuntimeToggleHarness = ({ initialGroupable = false }: { initialGroupable?: boolean }) => {
const [groupable, setGroupable] = useState(initialGroupable);
const columns = useMemo<AnalyticalTableColumnDefinition[]>(
() => [
{ Header: 'Name', accessor: 'name', width: 200 },
{ Header: 'Status', accessor: 'status', width: 200 },
],
[],
);
return (
<>
<button data-testid="toggle-groupable" onClick={() => setGroupable((prev) => !prev)}>
toggle
</button>
<AnalyticalTable data={toggleData} columns={columns} groupable={groupable} visibleRows={10} />
</>
);
};
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import type { Page } from '@playwright/test';
import { expect, test } from '../../../../../../playwright/fixtures/gallery-fixtures.js';
import type { GroupingAggregationHarness } from './AnalyticalTableGrouping.gallery.js';
import type { GroupableRuntimeToggleHarness, GroupingAggregationHarness } from './AnalyticalTableGrouping.gallery.js';

const STORY = 'AnalyticalTableGrouping/GroupingAggregationHarness';
const TOGGLE_STORY = 'AnalyticalTableGrouping/GroupableRuntimeToggleHarness';

const listItem = (page: Page, text: string) => page.locator(`[ui5-li][text="${text}"]`);
const popover = (page: Page) => page.locator('[data-component-name="ATHeaderPopover"]');
const openHeaderPopover = (page: Page, text: string) => page.getByText(text, { exact: true }).click();

test.describe('AnalyticalTable', () => {
test('grouped column is aggregated on ancestor group rows', async ({ mount, page }) => {
Expand All @@ -21,4 +27,25 @@ test.describe('AnalyticalTable', () => {
await expect(enUs).toHaveAttribute('data-agg-status', 'finished');
await expect(enUs).toHaveText('all finished');
});

test('runtime groupable toggle', async ({ mount, page }) => {
await mount<typeof GroupableRuntimeToggleHarness>(TOGGLE_STORY, { initialGroupable: false });

// Grouping is the only header option, so while disabled the header has no popover at all.
await openHeaderPopover(page, 'Status');
await expect(popover(page)).toHaveCount(0);

// Enable at runtime → the popover with the Group item appears, and grouping applies.
await page.getByTestId('toggle-groupable').click();
await openHeaderPopover(page, 'Status');
await expect(listItem(page, 'Group')).toBeVisible();
await listItem(page, 'Group').click();
await expect(page.getByText('active (3)', { exact: true })).toBeVisible();
await expect(page.getByText('inactive (2)', { exact: true })).toBeVisible();

// Disable at runtime → with no other option left, the header popover is gone again.
await page.getByTestId('toggle-groupable').click();
await openHeaderPopover(page, 'Status');
await expect(popover(page)).toHaveCount(0);
});
});
Loading