From e291e2600e35ae5a5fd374609c913ef2f14f6ca3 Mon Sep 17 00:00:00 2001 From: Davis McPhee Date: Fri, 27 Sep 2024 13:28:48 -0300 Subject: [PATCH] [Discover] [ES|QL] Disable ES|QL multivalue filtering in Unified Doc Viewer (#194232) ## Summary This PR disables ES|QL multivalue filtering in Unified Doc Viewer, similar to what we did for Unified Data Table in #193415: ![image](https://github.com/user-attachments/assets/f86c3ba9-05e9-4245-97f6-a8f9413950e9) Part of https://github.com/elastic/kibana/issues/193015. ### Checklist - [x] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md) - [ ] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [ ] [Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed - [x] Any UI touched in this PR is usable by keyboard only (learn more about [keyboard accessibility](https://webaim.org/techniques/keyboard/)) - [ ] Any UI touched in this PR does not create any new axe failures (run axe in browser: [FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/), [Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US)) - [ ] If a plugin configuration key changed, check if it needs to be allowlisted in the cloud and added to the [docker list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker) - [ ] This renders correctly on smaller devices using a responsive layout. (You can test this [in your browser](https://www.browserstack.com/guide/responsive-testing-on-local-server)) - [ ] This was checked for [cross-browser compatibility](https://www.elastic.co/support/matrix#matrix_browsers) ### For maintainers - [ ] This was checked for breaking API changes and was [labeled appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) (cherry picked from commit 6f01d6a2605e69737ddff0993fc07d8ab8deb43e) --- .../table_cell_actions.test.tsx.snap | 60 ++++++++-- .../components/doc_viewer_table/table.tsx | 8 +- .../table_cell_actions.test.tsx | 104 +++++++++++++++--- .../doc_viewer_table/table_cell_actions.tsx | 72 +++++++++--- 4 files changed, 197 insertions(+), 47 deletions(-) diff --git a/src/plugins/unified_doc_viewer/public/components/doc_viewer_table/__snapshots__/table_cell_actions.test.tsx.snap b/src/plugins/unified_doc_viewer/public/components/doc_viewer_table/__snapshots__/table_cell_actions.test.tsx.snap index a71babb2977d1..f39970e15f6fe 100644 --- a/src/plugins/unified_doc_viewer/public/components/doc_viewer_table/__snapshots__/table_cell_actions.test.tsx.snap +++ b/src/plugins/unified_doc_viewer/public/components/doc_viewer_table/__snapshots__/table_cell_actions.test.tsx.snap @@ -4,12 +4,20 @@ exports[`TableActions getFieldCellActions should render correctly for undefined Array [ , , getFieldCellActions({ rows, onFilter: filter, onToggleColumn }), - [rows, filter, onToggleColumn] + () => getFieldCellActions({ rows, isEsqlMode, onFilter: filter, onToggleColumn }), + [rows, isEsqlMode, filter, onToggleColumn] ); const fieldValueCellActions = useMemo( - () => getFieldValueCellActions({ rows, onFilter: filter }), - [rows, filter] + () => getFieldValueCellActions({ rows, isEsqlMode, onFilter: filter }), + [rows, isEsqlMode, filter] ); useWindowSize(); // trigger re-render on window resize to recalculate the grid container height diff --git a/src/plugins/unified_doc_viewer/public/components/doc_viewer_table/table_cell_actions.test.tsx b/src/plugins/unified_doc_viewer/public/components/doc_viewer_table/table_cell_actions.test.tsx index 9dd4305cd4b00..c29c7d6a4452f 100644 --- a/src/plugins/unified_doc_viewer/public/components/doc_viewer_table/table_cell_actions.test.tsx +++ b/src/plugins/unified_doc_viewer/public/components/doc_viewer_table/table_cell_actions.test.tsx @@ -11,26 +11,27 @@ import React from 'react'; import { getFieldCellActions, getFieldValueCellActions } from './table_cell_actions'; import { FieldRow } from './field_row'; import { buildDataTableRecord } from '@kbn/discover-utils'; -import { stubLogstashDataView as dataView } from '@kbn/data-views-plugin/common/data_view.stub'; import type { FieldFormatsStart } from '@kbn/field-formats-plugin/public'; +import { render, screen } from '@testing-library/react'; +import { dataViewMockWithTimeField } from '@kbn/discover-utils/src/__mocks__'; describe('TableActions', () => { - const rows: FieldRow[] = [ + const getRows = (fieldName = 'message', fieldValue: unknown = 'test'): FieldRow[] => [ new FieldRow({ - name: 'message', - flattenedValue: 'flattenedField', + name: fieldName, + flattenedValue: fieldValue, hit: buildDataTableRecord( { _ignored: [], _index: 'test', _id: '1', _source: { - message: 'test', + [fieldName]: fieldValue, }, }, - dataView + dataViewMockWithTimeField ), - dataView, + dataView: dataViewMockWithTimeField, fieldFormats: {} as FieldFormatsStart, isPinned: false, columnsMeta: undefined, @@ -49,23 +50,32 @@ describe('TableActions', () => { describe('getFieldCellActions', () => { it('should render correctly for undefined functions', () => { expect( - getFieldCellActions({ rows, onFilter: undefined, onToggleColumn: jest.fn() }).map((item) => - item(EuiCellParams) - ) + getFieldCellActions({ + rows: getRows(), + isEsqlMode: false, + onFilter: undefined, + onToggleColumn: jest.fn(), + }).map((item) => item(EuiCellParams)) ).toMatchSnapshot(); expect( - getFieldCellActions({ rows, onFilter: undefined, onToggleColumn: undefined }).map((item) => - item(EuiCellParams) - ) + getFieldCellActions({ + rows: getRows(), + isEsqlMode: false, + onFilter: undefined, + onToggleColumn: undefined, + }).map((item) => item(EuiCellParams)) ).toMatchSnapshot(); }); it('should render the panels correctly for defined onFilter function', () => { expect( - getFieldCellActions({ rows, onFilter: jest.fn(), onToggleColumn: jest.fn() }).map((item) => - item(EuiCellParams) - ) + getFieldCellActions({ + rows: getRows(), + isEsqlMode: false, + onFilter: jest.fn(), + onToggleColumn: jest.fn(), + }).map((item) => item(EuiCellParams)) ).toMatchSnapshot(); }); }); @@ -73,14 +83,72 @@ describe('TableActions', () => { describe('getFieldValueCellActions', () => { it('should render correctly for undefined functions', () => { expect( - getFieldValueCellActions({ rows, onFilter: undefined }).map((item) => item(EuiCellParams)) + getFieldValueCellActions({ rows: getRows(), isEsqlMode: false, onFilter: undefined }).map( + (item) => item(EuiCellParams) + ) ).toMatchSnapshot(); }); it('should render the panels correctly for defined onFilter function', () => { expect( - getFieldValueCellActions({ rows, onFilter: jest.fn() }).map((item) => item(EuiCellParams)) + getFieldValueCellActions({ rows: getRows(), isEsqlMode: false, onFilter: jest.fn() }).map( + (item) => item(EuiCellParams) + ) ).toMatchSnapshot(); }); + + it('should allow filtering in ES|QL mode', () => { + const actions = getFieldValueCellActions({ + rows: getRows('extension'), + isEsqlMode: true, + onFilter: jest.fn(), + }).map((Action, i) => ( + ( +
{JSON.stringify(props)}
+ )} + /> + )); + render(<>{actions}); + const filterForProps = JSON.parse( + screen.getByTestId('addFilterForValueButton-extension').innerHTML + ); + expect(filterForProps.disabled).toBe(false); + expect(filterForProps.title).toBe('Filter for value'); + const filterOutProps = JSON.parse( + screen.getByTestId('addFilterOutValueButton-extension').innerHTML + ); + expect(filterOutProps.disabled).toBe(false); + expect(filterOutProps.title).toBe('Filter out value'); + }); + + it('should not allow filtering in ES|QL mode for multivalue fields', () => { + const actions = getFieldValueCellActions({ + rows: getRows('extension', ['foo', 'bar']), + isEsqlMode: true, + onFilter: jest.fn(), + }).map((Action, i) => ( + ( +
{JSON.stringify(props)}
+ )} + /> + )); + render(<>{actions}); + const filterForProps = JSON.parse( + screen.getByTestId('addFilterForValueButton-extension').innerHTML + ); + expect(filterForProps.disabled).toBe(true); + expect(filterForProps.title).toBe('Multivalue filtering is not supported in ES|QL'); + const filterOutProps = JSON.parse( + screen.getByTestId('addFilterOutValueButton-extension').innerHTML + ); + expect(filterOutProps.disabled).toBe(true); + expect(filterOutProps.title).toBe('Multivalue filtering is not supported in ES|QL'); + }); }); }); diff --git a/src/plugins/unified_doc_viewer/public/components/doc_viewer_table/table_cell_actions.tsx b/src/plugins/unified_doc_viewer/public/components/doc_viewer_table/table_cell_actions.tsx index e9c5a70770ca5..8bbb0f31d4798 100644 --- a/src/plugins/unified_doc_viewer/public/components/doc_viewer_table/table_cell_actions.tsx +++ b/src/plugins/unified_doc_viewer/public/components/doc_viewer_table/table_cell_actions.tsx @@ -16,9 +16,10 @@ import { FieldRow } from './field_row'; interface TableActionsProps { Component: EuiDataGridColumnCellActionProps['Component']; row: FieldRow | undefined; // as we pass `rows[rowIndex]` it's safer to assume that `row` prop can be undefined + isEsqlMode: boolean | undefined; } -export function isFilterInOutPairDisabled( +function isFilterInOutPairDisabled( row: FieldRow | undefined, onFilter: DocViewFilterFn | undefined ): boolean { @@ -58,9 +59,17 @@ export function getFilterInOutPairDisabledWarning( : undefined; } -export const FilterIn: React.FC = ({ +const esqlMultivalueFilteringDisabled = i18n.translate( + 'unifiedDocViewer.docViews.table.esqlMultivalueFilteringDisabled', + { + defaultMessage: 'Multivalue filtering is not supported in ES|QL', + } +); + +const FilterIn: React.FC = ({ Component, row, + isEsqlMode, onFilter, }) => { if (!row) { @@ -81,12 +90,14 @@ export const FilterIn: React.FC onFilter(dataViewField, flattenedValue, '+')} > @@ -95,9 +106,10 @@ export const FilterIn: React.FC = ({ +const FilterOut: React.FC = ({ Component, row, + isEsqlMode, onFilter, }) => { if (!row) { @@ -118,12 +130,14 @@ export const FilterOut: React.FC onFilter(dataViewField, flattenedValue, '-')} > @@ -132,7 +146,7 @@ export const FilterOut: React.FC = ({ Component, row, onFilter }) => { +const FilterExist: React.FC = ({ + Component, + row, + onFilter, +}) => { if (!row) { return null; } @@ -198,7 +214,7 @@ export const FilterExist: React.FC< ); }; -export const ToggleColumn: React.FC< +const ToggleColumn: React.FC< TableActionsProps & { onToggleColumn: ((field: string) => void) | undefined; } @@ -236,10 +252,12 @@ export const ToggleColumn: React.FC< export function getFieldCellActions({ rows, + isEsqlMode, onFilter, onToggleColumn, }: { rows: FieldRow[]; + isEsqlMode: boolean | undefined; onFilter?: DocViewFilterFn; onToggleColumn: ((field: string) => void) | undefined; }) { @@ -247,7 +265,14 @@ export function getFieldCellActions({ ...(onFilter ? [ ({ Component, rowIndex }: EuiDataGridColumnCellActionProps) => { - return ; + return ( + + ); }, ] : []), @@ -258,6 +283,7 @@ export function getFieldCellActions({ ); @@ -269,18 +295,34 @@ export function getFieldCellActions({ export function getFieldValueCellActions({ rows, + isEsqlMode, onFilter, }: { rows: FieldRow[]; + isEsqlMode: boolean | undefined; onFilter?: DocViewFilterFn; }) { return onFilter ? [ ({ Component, rowIndex }: EuiDataGridColumnCellActionProps) => { - return ; + return ( + + ); }, ({ Component, rowIndex }: EuiDataGridColumnCellActionProps) => { - return ; + return ( + + ); }, ] : [];