Skip to content

Commit

Permalink
Upgrade EUI to v95.10.1 (#192026)
Browse files Browse the repository at this point in the history
`v95.9.0`⏩`v95.10.1`

> [!note]
> **EuiDataGrid**'s header cells have received a major UX change in
order to support interactive children within header content. Column
header actions now must be hovered and then clicked directly, or opened
with the Enter key, as opposed to being able to click the entire header
cell to see the actions popover.

_[Questions? Please see our Kibana upgrade
FAQ.](https://github.com/elastic/eui/blob/main/wiki/eui-team-processes/upgrading-kibana.md#faq-for-kibana-teams)_

---

## [`v95.10.0`](https://github.com/elastic/eui/releases/v95.10.0)

- Updated `EuiDataGrid` to support interactive header cell content
([#7898](elastic/eui#7898))
- Updated `EuiSearchBar`'s `field_value_selection` filter type with a
new `autoSortOptions` config, allowing consumers to configure whether or
not selected options are automatically sorted to the top of the filter
list ([#7958](elastic/eui#7958))
- Updated `getDefaultEuiMarkdownPlugins` to support the following new
default plugin configurations:
([#7985](elastic/eui#7985))
- `parsingConfig.linkValidator`, which allows configuring
`allowRelative` and `allowProtocols`
  - `parsingConfig.emoji`, which allows configuring emoticon parsing
- `processingConfig.linkProps`, which allows configuring rendered links
with any props that `EuiLink` accepts
- See our **Markdown plugins** documentation for example
`EuiMarkdownFormat` and `EuiMarkdownEditor` usage
- Updated `EuiDatePicker` to support `append` and `prepend` nodes in its
form control layout ([#7987](elastic/eui#7987))

**Bug fixes**

- Fixed border rendering bug with inline `EuiDatePicker`s with
`shadow={false}` ([#7987](elastic/eui#7987))
- Fixed `EuiSuperSelect`'s placeholder text color to match other form
controls ([#7995](elastic/eui#7995))

**Accessibility**

- Improved the keyboard navigation and screen reader output for
`EuiDataGrid` header cells
([#7898](elastic/eui#7898))

## [`v95.10.1`](https://github.com/elastic/eui/releases/v95.10.1)

**Bug fixes**

- Fixed a visual bug in compact density `EuiDataGrid`s, where the header
cell height would increase when the actions button became visible
([#7999](elastic/eui#7999))

---------

Co-authored-by: Lene Gadewoll <lene.gadewoll@elastic.co>
  • Loading branch information
cee-chen and mgadewoll authored Sep 10, 2024
1 parent 71b43af commit 20566d0
Show file tree
Hide file tree
Showing 22 changed files with 123 additions and 122 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@
"@elastic/ecs": "^8.11.1",
"@elastic/elasticsearch": "^8.15.0",
"@elastic/ems-client": "8.5.3",
"@elastic/eui": "95.9.0",
"@elastic/eui": "95.10.1",
"@elastic/filesaver": "1.1.2",
"@elastic/node-crypto": "1.2.1",
"@elastic/numeral": "^2.5.1",
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -542,16 +542,25 @@ export const getEuiContextMapping = (): EuiTokensObject => {
'core.euiDataGridCell.focusTrapEnterPrompt',
{ defaultMessage: "Press the Enter key to interact with this cell's contents." }
),
'euiDataGridCell.focusTrapExitPrompt': i18n.translate(
'core.euiDataGridCell.focusTrapExitPrompt',
{ defaultMessage: 'Exited cell content.' }
),
'euiDataGridCellActions.expandButtonTitle': i18n.translate(
'core.euiDataGridCellActions.expandButtonTitle',
{
defaultMessage: 'Click or hit enter to interact with cell content',
}
),
'euiDataGridHeaderCell.headerActions': i18n.translate(
'core.euiDataGridHeaderCell.headerActions',
'euiDataGridHeaderCell.actionsButtonAriaLabel': ({ title }: EuiValues) =>
i18n.translate('core.euiDataGridHeaderCell.actionsButtonAriaLabel', {
defaultMessage: '{title}. Click to view column header actions.',
values: { title },
}),
'euiDataGridHeaderCell.actionsEnterKeyInstructions': i18n.translate(
'core.euiDataGridHeaderCell.actionsEnterKeyInstructions',
{
defaultMessage: 'Click to view column header actions',
defaultMessage: "Press the Enter key to view this column's actions",
}
),
'euiDataGridHeaderCell.sortedByAscendingSingle': i18n.translate(
Expand Down
55 changes: 31 additions & 24 deletions packages/kbn-unified-data-table/src/components/data_table.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
EuiDataGridCellValueElementProps,
EuiDataGridCustomBodyProps,
} from '@elastic/eui';
import { waitForEuiPopoverOpen } from '@elastic/eui/lib/test/rtl';
import { Storage } from '@kbn/kibana-utils-plugin/public';
import { act } from 'react-dom/test-utils';
import { findTestSubject } from '@elastic/eui/lib/test';
Expand Down Expand Up @@ -385,7 +386,7 @@ describe('UnifiedDataTable', () => {
expect(
screen.queryByTestId('dataGridHeaderCellActionGroup-message')
).not.toBeInTheDocument();
await userEvent.click(screen.getByRole('button', { name: 'message' }));
await userEvent.click(screen.getByTestId('dataGridHeaderCellActionButton-message'));
expect(screen.getByTestId('dataGridHeaderCellActionGroup-message')).toBeInTheDocument();
expect(screen.getByTestId('gridEditFieldButton')).toBeInTheDocument();
},
Expand All @@ -399,7 +400,7 @@ describe('UnifiedDataTable', () => {
expect(
screen.queryByTestId('dataGridHeaderCellActionGroup-message')
).not.toBeInTheDocument();
await userEvent.click(screen.getByRole('button', { name: 'message' }));
await userEvent.click(screen.getByTestId('dataGridHeaderCellActionButton-message'));
expect(screen.getByTestId('dataGridHeaderCellActionGroup-message')).toBeInTheDocument();
expect(screen.queryByTestId('gridEditFieldButton')).not.toBeInTheDocument();
},
Expand Down Expand Up @@ -458,7 +459,8 @@ describe('UnifiedDataTable', () => {
});

describe('sorting', () => {
const getButton = (name: string) => screen.getByRole('button', { name });
const getColumnActions = (name: string) =>
screen.getByTestId(`dataGridHeaderCellActionButton-${name}`);
const getCellValuesByColumn = () => {
const columns = screen
.getAllByRole('columnheader')
Expand Down Expand Up @@ -497,12 +499,11 @@ describe('UnifiedDataTable', () => {
'message_8',
'message_9',
]);
await userEvent.click(getButton('message'));
await userEvent.click(getColumnActions('message'));
await waitForEuiPopoverOpen();
// Column sort button incorrectly renders as "Sort " instead
// of "Sort Z-A" in Jest tests, so we need to find it by index
await userEvent.click(screen.getAllByRole('button', { name: /Sort/ })[2], {
pointerEventsCheck: 0,
});
await userEvent.click(screen.getAllByRole('button', { name: /Sort/ })[2]);
await waitFor(() => {
values = getCellValuesByColumn();
expect(values.message).toEqual([
Expand Down Expand Up @@ -544,12 +545,11 @@ describe('UnifiedDataTable', () => {
'message_8',
'message_9',
]);
await userEvent.click(getButton('message'));
await userEvent.click(getColumnActions('message'));
await waitForEuiPopoverOpen();
// Column sort button incorrectly renders as "Sort " instead
// of "Sort Z-A" in Jest tests, so we need to find it by index
await userEvent.click(screen.getAllByRole('button', { name: /Sort/ })[2], {
pointerEventsCheck: 0,
});
await userEvent.click(screen.getAllByRole('button', { name: /Sort/ })[2]);
await waitFor(() => {
values = getCellValuesByColumn();
expect(values.message).toEqual([
Expand Down Expand Up @@ -1100,9 +1100,8 @@ describe('UnifiedDataTable', () => {
await selectDocument(esHitsMock[0]);
await selectDocument(esHitsMock[1]);
await openSelectedRowsMenu();
await userEvent.click(await screen.findByTestId('unifiedDataTableCompareSelectedDocuments'), {
pointerEventsCheck: 0,
});
await waitForEuiPopoverOpen();
await userEvent.click(await screen.findByTestId('unifiedDataTableCompareSelectedDocuments'));
await screen.findByText('Comparing 2 documents');
// EuiDataGrid makes state updates after calling requestAnimationFrame, which can lead
// to "Can't perform a React state update on an unmounted component." warnings in tests,
Expand Down Expand Up @@ -1259,7 +1258,15 @@ describe('UnifiedDataTable', () => {
const EUI_DEFAULT_COLUMN_WIDTH = '100px';
const getColumnHeader = (name: string) => screen.getByRole('columnheader', { name });
const queryColumnHeader = (name: string) => screen.queryByRole('columnheader', { name });
const getButton = (name: string) => screen.getByRole('button', { name });
const openColumnActions = async (name: string) => {
const actionsButton = screen.getByTestId(`dataGridHeaderCellActionButton-${name}`);
await userEvent.click(actionsButton);
await waitForEuiPopoverOpen();
};
const clickColumnAction = async (name: string) => {
const action = screen.getByRole('button', { name });
await userEvent.click(action);
};
const queryButton = (name: string) => screen.queryByRole('button', { name });

it(
Expand All @@ -1277,8 +1284,8 @@ describe('UnifiedDataTable', () => {
expect(getColumnHeader('message')).toHaveStyle({ width: EUI_DEFAULT_COLUMN_WIDTH });
expect(getColumnHeader('extension')).toHaveStyle({ width: '50px' });
expect(getColumnHeader('bytes')).toHaveStyle({ width: '50px' });
await userEvent.click(getButton('message'));
await userEvent.click(getButton('Remove column'), { pointerEventsCheck: 0 });
await openColumnActions('message');
await clickColumnAction('Remove column');
await waitFor(() => {
expect(queryColumnHeader('message')).not.toBeInTheDocument();
});
Expand All @@ -1302,8 +1309,8 @@ describe('UnifiedDataTable', () => {
expect(getColumnHeader('message')).toHaveStyle({ width: EUI_DEFAULT_COLUMN_WIDTH });
expect(getColumnHeader('extension')).toHaveStyle({ width: EUI_DEFAULT_COLUMN_WIDTH });
expect(getColumnHeader('bytes')).toHaveStyle({ width: '50px' });
await userEvent.click(getButton('message'));
await userEvent.click(getButton('Remove column'), { pointerEventsCheck: 0 });
await openColumnActions('message');
await clickColumnAction('Remove column');
await waitFor(() => {
expect(queryColumnHeader('message')).not.toBeInTheDocument();
});
Expand All @@ -1326,21 +1333,21 @@ describe('UnifiedDataTable', () => {
},
});
expect(getColumnHeader('@timestamp')).toHaveStyle({ width: '50px' });
await userEvent.click(getButton('@timestamp'));
await userEvent.click(getButton('Reset width'), { pointerEventsCheck: 0 });
await openColumnActions('@timestamp');
await clickColumnAction('Reset width');
await waitFor(() => {
expect(getColumnHeader('@timestamp')).toHaveStyle({
width: `${defaultTimeColumnWidth}px`,
});
});
expect(getColumnHeader('message')).toHaveStyle({ width: EUI_DEFAULT_COLUMN_WIDTH });
await userEvent.click(getButton('message'));
await openColumnActions('message');
expect(queryButton('Reset width')).not.toBeInTheDocument();
await waitFor(() => {
expect(getColumnHeader('extension')).toHaveStyle({ width: '50px' });
});
await userEvent.click(getButton('extension'));
await userEvent.click(getButton('Reset width'), { pointerEventsCheck: 0 });
await openColumnActions('extension');
await clickColumnAction('Reset width');
await waitFor(() => {
expect(getColumnHeader('extension')).toHaveStyle({ width: EUI_DEFAULT_COLUMN_WIDTH });
});
Expand Down
2 changes: 1 addition & 1 deletion src/dev/license_checker/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ export const LICENSE_OVERRIDES = {
'jsts@1.6.2': ['Eclipse Distribution License - v 1.0'], // cf. https://github.com/bjornharrtell/jsts
'@mapbox/jsonlint-lines-primitives@2.0.2': ['MIT'], // license in readme https://github.com/tmcw/jsonlint
'@elastic/ems-client@8.5.3': ['Elastic License 2.0'],
'@elastic/eui@95.9.0': ['Elastic License 2.0 OR AGPL-3.0-only OR SSPL-1.0'],
'@elastic/eui@95.10.1': ['Elastic License 2.0 OR AGPL-3.0-only OR SSPL-1.0'],
'language-subtag-registry@0.3.21': ['CC-BY-4.0'], // retired ODC‑By license https://github.com/mattcg/language-subtag-registry
'buffers@0.1.1': ['MIT'], // license in importing module https://www.npmjs.com/package/binary
'@bufbuild/protobuf@1.2.1': ['Apache-2.0'], // license (Apache-2.0 AND BSD-3-Clause)
Expand Down
2 changes: 1 addition & 1 deletion test/accessibility/apps/discover.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
});

it('a11y test for data-grid actions on columns', async () => {
await testSubjects.click('dataGridHeaderCellActionButton-Carrier');
await dataGrid.openColMenuByField('Carrier');
await a11y.testAppSnapshot();
});

Expand Down
10 changes: 5 additions & 5 deletions test/functional/apps/context/_discover_navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await kibanaServer.uiSettings.replace({});
});

it('should open the context view with the same columns', async () => {
const columnNames = await dataGrid.getHeaderFields();
expect(columnNames).to.eql(['@timestamp', ...TEST_COLUMN_NAMES]);
});

it('should open the context view with the selected document as anchor and allows selecting next anchor', async () => {
/**
* Helper function to get the first timestamp of the document table
Expand Down Expand Up @@ -95,11 +100,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
});
});

it('should open the context view with the same columns', async () => {
const columnNames = await dataGrid.getHeaderFields();
expect(columnNames).to.eql(['@timestamp', ...TEST_COLUMN_NAMES]);
});

it('should open the context view with the filters disabled', async () => {
let disabledFilterCounter = 0;
for (const [columnName, value] of TEST_FILTER_COLUMN_NAMES) {
Expand Down
10 changes: 5 additions & 5 deletions test/functional/apps/context/classic/_discover_navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await kibanaServer.uiSettings.replace({});
});

it('should open the context view with the same columns', async () => {
const columnNames = await docTable.getHeaderFields();
expect(columnNames).to.eql(['@timestamp', ...TEST_COLUMN_NAMES]);
});

it('should open the context view with the selected document as anchor and allows selecting next anchor', async () => {
/**
* Helper function to get the first timestamp of the document table
Expand Down Expand Up @@ -93,11 +98,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
});
});

it('should open the context view with the same columns', async () => {
const columnNames = await docTable.getHeaderFields();
expect(columnNames).to.eql(['@timestamp', ...TEST_COLUMN_NAMES]);
});

it('should open the context view with the filters disabled', async () => {
let disabledFilterCounter = 0;
for (const [_, value, columnId] of TEST_FILTER_COLUMN_NAMES) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await timePicker.resetDefaultAbsoluteRangeViaUiSettings();
});

it('should open the context view with the same columns', async () => {
const columnNames = await dataGrid.getHeaderFields();
expect(columnNames).to.eql(['@timestamp', ...TEST_COLUMN_NAMES]);
});

it('should open the context view with the selected document as anchor', async () => {
// check the anchor timestamp in the context view
await retry.waitFor('selected document timestamp matches anchor timestamp ', async () => {
Expand All @@ -82,11 +87,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
});
});

it('should open the context view with the same columns', async () => {
const columnNames = await dataGrid.getHeaderFields();
expect(columnNames).to.eql(['@timestamp', ...TEST_COLUMN_NAMES]);
});

it('should open the context view with the filters disabled', async () => {
let disabledFilterCounter = 0;
for (const [_, value, columnId] of TEST_FILTER_COLUMN_NAMES) {
Expand Down
35 changes: 12 additions & 23 deletions test/functional/apps/management/data_views/_scripted_fields.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
const retry = getService('retry');
const testSubjects = getService('testSubjects');
const filterBar = getService('filterBar');
const find = getService('find');
const dataGrid = getService('dataGrid');
const PageObjects = getPageObjects([
'common',
Expand All @@ -60,16 +59,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.common.unsetTime();
});

/**
* @param field field name to sort
* @param optionIndex index of the option to choose in dropdown
*/
const clickSort = async (field: string, optionIndex: number) => {
await testSubjects.click(`dataGridHeaderCell-${field}`);
const optionButtons = await find.allByCssSelector('.euiListGroupItem__button');
await optionButtons[optionIndex].click();
};

it('should not allow saving of invalid scripts', async function () {
await PageObjects.settings.navigateTo();
await PageObjects.settings.clickKibanaIndexPatterns();
Expand Down Expand Up @@ -170,25 +159,25 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {

// add a test to sort numeric scripted field
it('should sort scripted field value in Discover', async function () {
await clickSort(scriptedPainlessFieldName, 1);
await dataGrid.clickColumnActionAt(scriptedPainlessFieldName, 1);
await PageObjects.common.sleep(500);

// after the first click on the scripted field, it becomes secondary sort after time.
// click on the timestamp twice to make it be the secondary sort key.
await clickSort('@timestamp', 1);
await clickSort('@timestamp', 0);
await dataGrid.clickColumnActionAt('@timestamp', 1);
await dataGrid.clickColumnActionAt('@timestamp', 0);

await PageObjects.header.waitUntilLoadingHasFinished();
await retry.try(async function () {
const rowData = (await dataGrid.getRowsText())[0];
expect(rowData).to.be('Sep 17, 2015 @ 10:53:14.181-1');
});

await clickSort(scriptedPainlessFieldName, 2);
await dataGrid.clickColumnActionAt(scriptedPainlessFieldName, 2);
// after the first click on the scripted field, it becomes primary sort after time.
// click on the scripted field twice then, makes it be the secondary sort key.
await clickSort(scriptedPainlessFieldName, 2);
await clickSort(scriptedPainlessFieldName, 2);
await dataGrid.clickColumnActionAt(scriptedPainlessFieldName, 2);
await dataGrid.clickColumnActionAt(scriptedPainlessFieldName, 2);

await PageObjects.header.waitUntilLoadingHasFinished();
await retry.try(async function () {
Expand Down Expand Up @@ -275,25 +264,25 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {

// add a test to sort string scripted field
it('should sort scripted field value in Discover', async function () {
await clickSort(scriptedPainlessFieldName2, 1);
await dataGrid.clickColumnActionAt(scriptedPainlessFieldName2, 1);
// await testSubjects.click(`docTableHeaderFieldSort_${scriptedPainlessFieldName2}`);
await PageObjects.common.sleep(500);

// after the first click on the scripted field, it becomes secondary sort after time.
// click on the timestamp twice to make it be the secondary sort key.
await clickSort('@timestamp', 1);
await clickSort('@timestamp', 0);
await dataGrid.clickColumnActionAt('@timestamp', 1);
await dataGrid.clickColumnActionAt('@timestamp', 0);
await PageObjects.header.waitUntilLoadingHasFinished();
await retry.try(async function () {
const rowData = (await dataGrid.getRowsText())[0];
expect(rowData).to.be('Sep 17, 2015 @ 09:48:40.594bad');
});

await clickSort(scriptedPainlessFieldName2, 2);
await dataGrid.clickColumnActionAt(scriptedPainlessFieldName2, 2);
// after the first click on the scripted field, it becomes primary sort after time.
// click on the scripted field twice then, makes it be the secondary sort key.
await clickSort(scriptedPainlessFieldName2, 2);
await clickSort(scriptedPainlessFieldName2, 2);
await dataGrid.clickColumnActionAt(scriptedPainlessFieldName2, 2);
await dataGrid.clickColumnActionAt(scriptedPainlessFieldName2, 2);

await PageObjects.header.waitUntilLoadingHasFinished();
await retry.try(async function () {
Expand Down
Loading

0 comments on commit 20566d0

Please sign in to comment.