diff --git a/packages/kbn-unified-data-table/src/components/data_table_columns.tsx b/packages/kbn-unified-data-table/src/components/data_table_columns.tsx
index 4ef0636093f8d..13059f2881711 100644
--- a/packages/kbn-unified-data-table/src/components/data_table_columns.tsx
+++ b/packages/kbn-unified-data-table/src/components/data_table_columns.tsx
@@ -182,7 +182,13 @@ function buildEuiGridColumn({
cellActions = columnCellActions;
} else {
cellActions = dataViewField
- ? buildCellActions(dataViewField, toastNotifications, valueToStringConverter, onFilter)
+ ? buildCellActions(
+ dataViewField,
+ isPlainRecord,
+ toastNotifications,
+ valueToStringConverter,
+ onFilter
+ )
: [];
if (columnCellActions?.length && cellActionsHandling === 'append') {
diff --git a/packages/kbn-unified-data-table/src/components/default_cell_actions.test.tsx b/packages/kbn-unified-data-table/src/components/default_cell_actions.test.tsx
index 628d3b5a29697..d097a2becd035 100644
--- a/packages/kbn-unified-data-table/src/components/default_cell_actions.test.tsx
+++ b/packages/kbn-unified-data-table/src/components/default_cell_actions.test.tsx
@@ -45,6 +45,7 @@ describe('Default cell actions ', function () {
it('should not show cell actions for unfilterable fields', async () => {
const cellActions = buildCellActions(
{ name: 'foo', filterable: false } as DataViewField,
+ false,
servicesMock.toastNotifications,
dataTableContextMock.valueToStringConverter
);
@@ -61,6 +62,7 @@ describe('Default cell actions ', function () {
it('should show filter actions for filterable fields', async () => {
const cellActions = buildCellActions(
{ name: 'foo', filterable: true } as DataViewField,
+ false,
servicesMock.toastNotifications,
dataTableContextMock.valueToStringConverter,
jest.fn()
@@ -71,6 +73,7 @@ describe('Default cell actions ', function () {
it('should show Copy action for _source field', async () => {
const cellActions = buildCellActions(
{ name: '_source', type: '_source', filterable: false } as DataViewField,
+ false,
servicesMock.toastNotifications,
dataTableContextMock.valueToStringConverter
);
@@ -87,65 +90,97 @@ describe('Default cell actions ', function () {
const component = mountWithIntl(
}
- rowIndex={1}
- colIndex={1}
- columnId="extension"
- isExpanded={false}
+ cellActionProps={{
+ Component: (props: any) => ,
+ rowIndex: 1,
+ colIndex: 1,
+ columnId: 'extension',
+ isExpanded: false,
+ }}
+ field={{ name: 'extension', filterable: true } as DataViewField}
+ isPlainRecord={false}
/>
);
const button = findTestSubject(component, 'filterForButton');
await button.simulate('click');
- expect(dataTableContextMock.onFilter).toHaveBeenCalledWith({}, 'jpg', '+');
+ expect(dataTableContextMock.onFilter).toHaveBeenCalledWith(
+ { name: 'extension', filterable: true },
+ 'jpg',
+ '+'
+ );
});
it('triggers filter function when FilterInBtn is clicked for a non-provided value', async () => {
const component = mountWithIntl(
}
- rowIndex={0}
- colIndex={1}
- columnId="extension"
- isExpanded={false}
+ cellActionProps={{
+ Component: (props: any) => ,
+ rowIndex: 0,
+ colIndex: 1,
+ columnId: 'extension',
+ isExpanded: false,
+ }}
+ field={{ name: 'extension', filterable: true } as DataViewField}
+ isPlainRecord={false}
/>
);
const button = findTestSubject(component, 'filterForButton');
await button.simulate('click');
- expect(dataTableContextMock.onFilter).toHaveBeenCalledWith({}, undefined, '+');
+ expect(dataTableContextMock.onFilter).toHaveBeenCalledWith(
+ { name: 'extension', filterable: true },
+ undefined,
+ '+'
+ );
});
it('triggers filter function when FilterInBtn is clicked for an empty string value', async () => {
const component = mountWithIntl(
}
- rowIndex={4}
- colIndex={1}
- columnId="message"
- isExpanded={false}
+ cellActionProps={{
+ Component: (props: any) => ,
+ rowIndex: 4,
+ colIndex: 1,
+ columnId: 'message',
+ isExpanded: false,
+ }}
+ field={{ name: 'message', filterable: true } as DataViewField}
+ isPlainRecord={false}
/>
);
const button = findTestSubject(component, 'filterForButton');
await button.simulate('click');
- expect(dataTableContextMock.onFilter).toHaveBeenCalledWith({}, '', '+');
+ expect(dataTableContextMock.onFilter).toHaveBeenCalledWith(
+ { name: 'message', filterable: true },
+ '',
+ '+'
+ );
});
it('triggers filter function when FilterOutBtn is clicked', async () => {
const component = mountWithIntl(
}
- rowIndex={1}
- colIndex={1}
- columnId="extension"
- isExpanded={false}
+ cellActionProps={{
+ Component: (props: any) => ,
+ rowIndex: 1,
+ colIndex: 1,
+ columnId: 'extension',
+ isExpanded: false,
+ }}
+ field={{ name: 'extension', filterable: true } as DataViewField}
+ isPlainRecord={false}
/>
);
const button = findTestSubject(component, 'filterOutButton');
await button.simulate('click');
- expect(dataTableContextMock.onFilter).toHaveBeenCalledWith({}, 'jpg', '-');
+ expect(dataTableContextMock.onFilter).toHaveBeenCalledWith(
+ { name: 'extension', filterable: true },
+ 'jpg',
+ '-'
+ );
});
it('triggers clipboard copy when CopyBtn is clicked', async () => {
const component = mountWithIntl(
diff --git a/packages/kbn-unified-data-table/src/components/default_cell_actions.tsx b/packages/kbn-unified-data-table/src/components/default_cell_actions.tsx
index 620151c9d9701..ce7b354fc8dc1 100644
--- a/packages/kbn-unified-data-table/src/components/default_cell_actions.tsx
+++ b/packages/kbn-unified-data-table/src/components/default_cell_actions.tsx
@@ -32,11 +32,25 @@ function onFilterCell(
}
}
-export const FilterInBtn = (
- { Component, rowIndex, columnId }: EuiDataGridColumnCellActionProps,
- field: DataViewField
-) => {
+const esqlMultivalueFilteringDisabled = i18n.translate(
+ 'unifiedDataTable.grid.esqlMultivalueFilteringDisabled',
+ {
+ defaultMessage: 'Multivalue filtering is not supported in ES|QL',
+ }
+);
+
+export const FilterInBtn = ({
+ cellActionProps: { Component, rowIndex, columnId },
+ field,
+ isPlainRecord,
+}: {
+ cellActionProps: EuiDataGridColumnCellActionProps;
+ field: DataViewField;
+ isPlainRecord: boolean | undefined;
+}) => {
const context = useContext(UnifiedDataTableContext);
+ const filteringDisabled =
+ isPlainRecord && Array.isArray(context.rows[rowIndex]?.flattened[columnId]);
const buttonTitle = i18n.translate('unifiedDataTable.grid.filterForAria', {
defaultMessage: 'Filter for this {value}',
values: { value: columnId },
@@ -49,7 +63,8 @@ export const FilterInBtn = (
}}
iconType="plusInCircle"
aria-label={buttonTitle}
- title={buttonTitle}
+ title={filteringDisabled ? esqlMultivalueFilteringDisabled : buttonTitle}
+ disabled={filteringDisabled}
data-test-subj="filterForButton"
>
{i18n.translate('unifiedDataTable.grid.filterFor', {
@@ -59,11 +74,18 @@ export const FilterInBtn = (
);
};
-export const FilterOutBtn = (
- { Component, rowIndex, columnId }: EuiDataGridColumnCellActionProps,
- field: DataViewField
-) => {
+export const FilterOutBtn = ({
+ cellActionProps: { Component, rowIndex, columnId },
+ field,
+ isPlainRecord,
+}: {
+ cellActionProps: EuiDataGridColumnCellActionProps;
+ field: DataViewField;
+ isPlainRecord: boolean | undefined;
+}) => {
const context = useContext(UnifiedDataTableContext);
+ const filteringDisabled =
+ isPlainRecord && Array.isArray(context.rows[rowIndex]?.flattened[columnId]);
const buttonTitle = i18n.translate('unifiedDataTable.grid.filterOutAria', {
defaultMessage: 'Filter out this {value}',
values: { value: columnId },
@@ -76,7 +98,8 @@ export const FilterOutBtn = (
}}
iconType="minusInCircle"
aria-label={buttonTitle}
- title={buttonTitle}
+ title={filteringDisabled ? esqlMultivalueFilteringDisabled : buttonTitle}
+ disabled={filteringDisabled}
data-test-subj="filterOutButton"
>
{i18n.translate('unifiedDataTable.grid.filterOut', {
@@ -120,6 +143,7 @@ export function buildCopyValueButton(
export function buildCellActions(
field: DataViewField,
+ isPlainRecord: boolean | undefined,
toastNotifications: ToastsStart,
valueToStringConverter: ValueToStringConverter,
onFilter?: DocViewFilterFn
@@ -127,16 +151,18 @@ export function buildCellActions(
return [
...(onFilter && field.filterable
? [
- ({ Component, rowIndex, columnId }: EuiDataGridColumnCellActionProps) =>
- FilterInBtn(
- { Component, rowIndex, columnId } as EuiDataGridColumnCellActionProps,
- field
- ),
- ({ Component, rowIndex, columnId }: EuiDataGridColumnCellActionProps) =>
- FilterOutBtn(
- { Component, rowIndex, columnId } as EuiDataGridColumnCellActionProps,
- field
- ),
+ (cellActionProps: EuiDataGridColumnCellActionProps) =>
+ FilterInBtn({
+ cellActionProps,
+ field,
+ isPlainRecord,
+ }),
+ (cellActionProps: EuiDataGridColumnCellActionProps) =>
+ FilterOutBtn({
+ cellActionProps,
+ field,
+ isPlainRecord,
+ }),
]
: []),
({ Component, rowIndex, columnId }: EuiDataGridColumnCellActionProps) =>