Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[EuiDataGrid] Fix column actions not working for draggable datagrid inside modals #8135

Merged
merged 6 commits into from
Nov 14, 2024
Merged
Show file tree
Hide file tree
Changes from 5 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
4 changes: 4 additions & 0 deletions packages/eui/changelogs/upcoming/8135.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
**Bug fixes**

- Fixed an `EuiDataGrid` bug where column actions where not clickable when `EuiDataGrid` with `columnVisibility.canDragAndDropColumns` was used inside a modal

Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ import {
EuiAvatar,
EuiToolTip,
EuiButtonIcon,
EuiModal,
EuiModalBody,
EuiButton,
} from '../../../../../src/components';

const CustomHeaderCell = ({ title }) => (
Expand Down Expand Up @@ -67,21 +70,33 @@ for (let i = 1; i < 5; i++) {
}

export default () => {
const [isOpen, setOpen] = useState(false);
const [visibleColumns, setVisibleColumns] = useState(
columns.map(({ id }) => id)
);

return (
<EuiDataGrid
aria-label="DataGrid demonstrating column reordering on drag"
columns={columns}
columnVisibility={{
visibleColumns: visibleColumns,
setVisibleColumns: setVisibleColumns,
canDragAndDropColumns: true,
}}
rowCount={data.length}
renderCellValue={({ rowIndex, columnId }) => data[rowIndex][columnId]}
/>
<>
<EuiButton onClick={() => setOpen(!isOpen)}>Toggle modal</EuiButton>
{isOpen && (
<EuiModal onClose={() => setOpen(false)}>
<EuiModalBody>
<EuiDataGrid
aria-label="DataGrid demonstrating column reordering on drag"
columns={columns}
columnVisibility={{
visibleColumns: visibleColumns,
setVisibleColumns: setVisibleColumns,
canDragAndDropColumns: true,
}}
rowCount={data.length}
renderCellValue={({ rowIndex, columnId }) =>
data[rowIndex][columnId]
}
/>
</EuiModalBody>
</EuiModal>
)}
</>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

import React, { useState } from 'react';
import { EuiDataGrid, EuiDataGridProps } from '../../index';
import { EuiModal, EuiModalBody } from '../../../modal';

describe('draggable columns', () => {
const columns = [
Expand Down Expand Up @@ -284,4 +285,40 @@ describe('draggable columns', () => {
cy.get('[data-popover-open]').should('not.exist');
});
});

describe('inside a modal', () => {
it('should execute column actions on click', () => {
cy.realMount(
<EuiModal onClose={() => {}}>
<EuiModalBody>
<StatefulDataGrid />
</EuiModalBody>
</EuiModal>
);

cy.get('[data-test-subj=dataGridHeaderCell-a]').realHover();
cy.wait(50); // wait until actions button transition is progressed enough for the button to be clickable
cy.get('[data-test-subj=dataGridHeaderCellActionButton-a]').realClick();
cy.get('[data-popover-open]').should('have.focus');

cy.get(
'.euiListGroupItem:last-child .euiListGroupItem__button'
).realClick();

cy.get('[data-test-subj=dataGridHeaderCell-a]').should(
'have.attr',
'data-gridcell-column-index',
'1'
);
cy.get('[data-test-subj=dataGridHeaderCell-b]').should(
'have.attr',
'data-gridcell-column-index',
'0'
);

cy.get('[data-test-subj=euiDataGridHeaderColumnActions]').should(
'not.exist'
);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -132,16 +132,23 @@ export const DraggableColumn: FunctionComponent<{
const { setFocusedCell } = useContext(DataGridFocusContext);
const handleOnMouseDown: MouseEventHandler = useCallback(
(e) => {
const openFocusTrap = document.querySelector(
const openFocusTraps = document.querySelectorAll(
'[data-focus-lock-disabled="false"]'
);
if (
!!openFocusTrap && // If a focus trap is open somewhere on the page
!openFocusTrap.contains(e.target as Node) && // & the focus trap doesn't belong to this header
e.target !== actionsPopoverToggle // & we're not closing the actions popover toggle
) {
const validOpenFocusTraps = [...openFocusTraps].filter(
(focusTrap) => !focusTrap.contains(e.currentTarget as Node) // remove containing focus traps (e.g. modals or flyouts)
);

const shouldDispatchEvent = validOpenFocusTraps.some(
(focusTrap) =>
!!focusTrap && // If there is a focus trap open
!focusTrap.contains(e.target as Node) && // & if it doesn't contain the target
e.target !== actionsPopoverToggle // & we're not closing the actions popover toggle
);

if (shouldDispatchEvent) {
// Trick the focus trap lib into registering an outside click -
// the drag/drop lib otherwise otherwise prevents the event 💀
// the drag/drop lib otherwise prevents the event 💀
document.dispatchEvent(new MouseEvent('mousedown'));
}
setTimeout(() => {
Expand Down
Loading