Skip to content

Commit d7ef54b

Browse files
authored
fix(AnalyticalTable): return correct values in onRowSelect for filtered rows (#4902)
1 parent 799a935 commit d7ef54b

File tree

3 files changed

+149
-19
lines changed

3 files changed

+149
-19
lines changed

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

Lines changed: 112 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -366,21 +366,43 @@ describe('AnalyticalTable', () => {
366366
cy.findByTestId('payloadHelper').should('have.text', '4{"0":true,"1":true,"0.2":true,"0.2.0":true}');
367367
});
368368

369-
it('programmatic and user selection', () => {
370-
const data = generateMoreData(20);
369+
it('programmatic and user selection + filtering', () => {
370+
const data = [
371+
...generateMoreData(20),
372+
{
373+
name: `Name-7`,
374+
age: 22,
375+
friend: {
376+
name: `FriendName-X`,
377+
age: 22 + 10
378+
}
379+
}
380+
];
371381
const TestComp = ({ onRowSelect }: PropTypes) => {
372382
const [selectedRowIds, setSelectedRowIds] = useState({});
373383
const [selectedFlatRows, setSelectedFlatRows] = useState([]);
374384
const [selectedRowIdsCb, setSelectedRowIdsCb] = useState({});
385+
const [allRowsSelected, setAllRowsSelected] = useState(false);
386+
const [globalFilterVal, setGlobalFilterVal] = useState('');
375387
return (
376388
<>
377389
<Button onClick={() => setSelectedRowIds({ 2: true, 3: false })}>Set selected rows</Button>
390+
<input
391+
data-testid="input"
392+
value={globalFilterVal}
393+
onInput={(e) => {
394+
setGlobalFilterVal(e.target.value);
395+
}}
396+
/>
378397
<AnalyticalTable
398+
filterable
379399
data={data}
380400
columns={columns}
401+
globalFilterValue={globalFilterVal}
381402
onRowSelect={(e) => {
382403
setSelectedFlatRows(e.detail.selectedFlatRows.map((item) => item.id));
383404
setSelectedRowIdsCb(e.detail.selectedRowIds);
405+
setAllRowsSelected(e.detail.allRowsSelected);
384406
onRowSelect(e);
385407
}}
386408
selectionMode={AnalyticalTableSelectionMode.MultiSelect}
@@ -392,6 +414,10 @@ describe('AnalyticalTable', () => {
392414
<p>
393415
"e.detail.selectedRowIds:"<span data-testid="payloadRowsById">{JSON.stringify(selectedRowIdsCb)}</span>
394416
</p>
417+
<p>
418+
"e.detail.allRowsSelected:"
419+
<span data-testid="payloadAllRowsSelected">{`${allRowsSelected}`}</span>
420+
</p>
395421
</>
396422
);
397423
};
@@ -404,13 +430,97 @@ describe('AnalyticalTable', () => {
404430
cy.findByText('Name-5').click();
405431
cy.findByTestId('payload').should('have.text', '["0","1"]');
406432
cy.findByTestId('payloadRowsById').should('have.text', '{"0":true,"1":true}');
433+
cy.findByTestId('payloadAllRowsSelected').should('have.text', 'false');
407434
cy.get('@onRowSelectSpy').should('have.callCount', 4);
408435

409436
cy.findByText('Set selected rows').click();
410437
cy.get('@onRowSelectSpy').should('have.callCount', 4);
411438
cy.findByText('Name-1').click();
439+
cy.get('@onRowSelectSpy').should('have.callCount', 5);
412440
cy.findByTestId('payload').should('have.text', '["1","2"]');
413441
cy.findByTestId('payloadRowsById').should('have.text', '{"1":true,"2":true,"3":false}');
442+
cy.findByTestId('payloadAllRowsSelected').should('have.text', 'false');
443+
444+
cy.get('[data-row-index="0"][data-column-index="0"]').click();
445+
cy.get('@onRowSelectSpy').should('have.callCount', 6);
446+
cy.findByTestId('payload').should(
447+
'have.text',
448+
'["0","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20"]'
449+
);
450+
cy.findByTestId('payloadRowsById').should(
451+
'have.text',
452+
'{"0":true,"1":true,"2":true,"3":true,"4":true,"5":true,"6":true,"7":true,"8":true,"9":true,"10":true,"11":true,"12":true,"13":true,"14":true,"15":true,"16":true,"17":true,"18":true,"19":true,"20":true}'
453+
);
454+
cy.findByTestId('payloadAllRowsSelected').should('have.text', 'true');
455+
456+
cy.get('[data-row-index="0"][data-column-index="0"]').click();
457+
458+
cy.findByText('Name-0').click();
459+
cy.findByText('Name-1').click();
460+
cy.findByText('Name-5').click();
461+
cy.findByText('Name').click();
462+
cy.get('[ui5-li-custom]').shadow().get('[ui5-input]').typeIntoUi5Input('7{enter}');
463+
cy.findByTestId('payload').should('have.text', '["0","1","5"]');
464+
cy.findByTestId('payloadRowsById').should('have.text', '{"0":true,"1":true,"5":true}');
465+
cy.findByTestId('payloadAllRowsSelected').should('have.text', 'false');
466+
467+
cy.get('[data-row-index="0"][data-column-index="0"]').click();
468+
cy.get('@onRowSelectSpy').should('have.callCount', 11);
469+
cy.findByTestId('payload').should('have.text', '["0","1","5","7","17","20"]');
470+
cy.findByTestId('payloadRowsById').should('have.text', '{"0":true,"1":true,"5":true,"7":true,"17":true,"20":true}');
471+
cy.findByTestId('payloadAllRowsSelected').should('have.text', 'false');
472+
473+
cy.findByText('Name').click();
474+
cy.get('[ui5-li-custom]').shadow().get('[ui5-input]').typeIntoUi5Input('{selectall}{backspace}{enter}');
475+
cy.get('[data-row-index="0"][data-column-index="0"]').click();
476+
cy.findByText('Name-17').click({ force: true });
477+
cy.findByText('Name').click();
478+
cy.get('[ui5-li-custom]').shadow().get('[ui5-input]').typeIntoUi5Input('7{enter}');
479+
cy.findByTestId('payload').should(
480+
'have.text',
481+
'["0","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","18","19","20"]'
482+
);
483+
cy.findByTestId('payloadRowsById').should(
484+
'have.text',
485+
'{"0":true,"1":true,"2":true,"3":true,"4":true,"5":true,"6":true,"7":true,"8":true,"9":true,"10":true,"11":true,"12":true,"13":true,"14":true,"15":true,"16":true,"18":true,"19":true,"20":true}'
486+
);
487+
cy.findByTestId('payloadAllRowsSelected').should('have.text', 'false');
488+
cy.findByText('Name-17').click();
489+
cy.findByTestId('payload').should(
490+
'have.text',
491+
'["0","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20"]'
492+
);
493+
cy.findByTestId('payloadRowsById').should(
494+
'have.text',
495+
'{"0":true,"1":true,"2":true,"3":true,"4":true,"5":true,"6":true,"7":true,"8":true,"9":true,"10":true,"11":true,"12":true,"13":true,"14":true,"15":true,"16":true,"17":true,"18":true,"19":true,"20":true}'
496+
);
497+
cy.findByTestId('payloadAllRowsSelected').should('have.text', 'true');
498+
499+
cy.findByText('Name').click();
500+
cy.get('[ui5-li-custom]').shadow().get('[ui5-input]').typeIntoUi5Input('{selectall}{backspace}{enter}');
501+
502+
cy.findByText('Name-17').click({ force: true });
503+
cy.findByTestId('input').type('7{enter}');
504+
cy.findByTestId('payload').should(
505+
'have.text',
506+
'["0","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","18","19","20"]'
507+
);
508+
cy.findByTestId('payloadRowsById').should(
509+
'have.text',
510+
'{"0":true,"1":true,"2":true,"3":true,"4":true,"5":true,"6":true,"7":true,"8":true,"9":true,"10":true,"11":true,"12":true,"13":true,"14":true,"15":true,"16":true,"18":true,"19":true,"20":true}'
511+
);
512+
cy.findByTestId('payloadAllRowsSelected').should('have.text', 'false');
513+
cy.findByText('Name-17').click();
514+
cy.findByTestId('payload').should(
515+
'have.text',
516+
'["0","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20"]'
517+
);
518+
cy.findByTestId('payloadRowsById').should(
519+
'have.text',
520+
'{"0":true,"1":true,"2":true,"3":true,"4":true,"5":true,"6":true,"7":true,"8":true,"9":true,"10":true,"11":true,"12":true,"13":true,"14":true,"15":true,"16":true,"17":true,"18":true,"19":true,"20":true}'
521+
);
522+
cy.findByTestId('payloadAllRowsSelected').should('have.text', 'true');
523+
cy.get('@onRowSelectSpy').should('have.callCount', 16);
414524
});
415525

416526
it('row & header height', () => {

packages/main/src/components/AnalyticalTable/hooks/useRowSelectionColumn.tsx

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,9 @@ const headerProps = (props, { instance }) => {
6262
webComponentsReactProperties: { onRowSelect, selectionMode },
6363
toggleAllRowsSelected,
6464
isAllRowsSelected,
65-
rowsById
65+
rowsById,
66+
dispatch,
67+
state: { filters, globalFilter }
6668
} = instance;
6769
const style = { ...props.style, cursor: 'pointer', display: 'flex', justifyContent: 'center' };
6870
if (
@@ -71,15 +73,20 @@ const headerProps = (props, { instance }) => {
7173
) {
7274
const onClick = (e) => {
7375
toggleAllRowsSelected(!isAllRowsSelected);
76+
const isFiltered = filters?.length > 0 || !!globalFilter;
7477
if (typeof onRowSelect === 'function') {
75-
onRowSelect(
76-
// cannot use instance.selectedFlatRows here as it only returns all rows on the first level
77-
enrichEventWithDetails(e, {
78-
allRowsSelected: !isAllRowsSelected,
79-
selectedFlatRows: !isAllRowsSelected ? flatRows : [],
80-
selectedRowIds: !isAllRowsSelected ? getNextSelectedRowIds(rowsById) : {}
81-
})
82-
);
78+
if (isFiltered) {
79+
dispatch({ type: 'SELECT_ROW_CB', payload: { event: e, row: undefined, selectAll: true, fired: true } });
80+
} else {
81+
onRowSelect(
82+
// cannot use instance.selectedFlatRows here as it only returns all rows on the first level
83+
enrichEventWithDetails(e, {
84+
allRowsSelected: !isAllRowsSelected,
85+
selectedFlatRows: !isAllRowsSelected ? flatRows : [],
86+
selectedRowIds: !isAllRowsSelected ? getNextSelectedRowIds(rowsById) : {}
87+
})
88+
);
89+
}
8390
}
8491
};
8592

packages/main/src/components/AnalyticalTable/hooks/useSelectionChangeCallback.ts

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,28 @@ import { AnalyticalTableSelectionMode } from '../../../enums/index.js';
44

55
export const useSelectionChangeCallback = (hooks) => {
66
hooks.useControlledState.push((state, { instance }) => {
7-
const { selectedRowPayload, selectedRowIds } = state;
8-
const { rowsById, preFilteredRowsById, webComponentsReactProperties, dispatch, filters } = instance;
7+
const { selectedRowPayload, selectedRowIds, filters, globalFilter } = state;
8+
const { rowsById, preFilteredRowsById, webComponentsReactProperties, dispatch } = instance;
9+
const isFiltered = filters?.length > 0 || !!globalFilter;
10+
911
// eslint-disable-next-line react-hooks/rules-of-hooks
1012
useEffect(() => {
1113
if (selectedRowPayload?.fired) {
12-
const { event: e, row: selRow } = selectedRowPayload;
14+
const { event: e, row: selRow, selectAll } = selectedRowPayload;
1315
const row = rowsById[selRow?.id];
1416

15-
if (row) {
17+
if (row || selectAll) {
1618
const payload = {
1719
row: row,
18-
isSelected: row.isSelected,
19-
selectedFlatRows: row.isSelected ? [row] : [],
20+
isSelected: row?.isSelected,
21+
selectedFlatRows: row?.isSelected ? [row] : [],
2022
allRowsSelected: false,
2123
selectedRowIds
2224
};
2325

2426
if (webComponentsReactProperties.selectionMode === AnalyticalTableSelectionMode.MultiSelect) {
2527
// when selecting a row on a filtered table, `preFilteredRowsById` has to be used, otherwise filtered out rows are undefined
26-
const tempRowsById = filters?.length > 0 ? preFilteredRowsById : rowsById;
28+
const tempRowsById = isFiltered ? preFilteredRowsById : rowsById;
2729
const selectedRowIdsArrayMapped = Object.keys(selectedRowIds).reduce((acc, key) => {
2830
if (selectedRowIds[key]) {
2931
acc.push(tempRowsById[key]);
@@ -35,12 +37,23 @@ export const useSelectionChangeCallback = (hooks) => {
3537
if (selectedRowIdsArrayMapped.length === Object.keys(tempRowsById).length) {
3638
payload.allRowsSelected = true;
3739
}
40+
if (selectAll) {
41+
dispatch({ type: 'SELECT_ROW_CB', payload: { event: e, row, selectAll: false, fired: false } });
42+
webComponentsReactProperties?.onRowSelect(
43+
enrichEventWithDetails(e, {
44+
selectedFlatRows: payload.selectedFlatRows,
45+
allRowsSelected: payload.allRowsSelected,
46+
selectedRowIds: payload.selectedRowIds
47+
})
48+
);
49+
return;
50+
}
3851
}
3952
dispatch({ type: 'SELECT_ROW_CB', payload: { event: e, row, fired: false } });
4053
webComponentsReactProperties?.onRowSelect(enrichEventWithDetails(e, payload));
4154
}
4255
}
43-
}, [selectedRowPayload?.fired, rowsById, webComponentsReactProperties.selectionMode, selectedRowIds]);
56+
}, [selectedRowPayload?.fired, rowsById, webComponentsReactProperties.selectionMode, selectedRowIds, isFiltered]);
4457

4558
return state;
4659
});

0 commit comments

Comments
 (0)