mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
[ES|QL] Enables the addition of columns from the doc viewer (#171083)
## Summary
From our user sessions we found out that many users on the ES|QL mode
they are adding columns to the Document view from the Document viewer
but the ES|QL mode is missing this functionality. This PR enables this
action. We haven't decided what we are going to do with filtering yet so
I disable all the filtering related actions.
<img width="1886" alt="image"
src="61f93e53
-c1e4-4581-bc89-41c8422ef4f3">
### Checklist
- [ ] [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
This commit is contained in:
parent
bf054059c8
commit
43d18438f5
8 changed files with 88 additions and 17 deletions
|
@ -36,6 +36,7 @@ export interface DocViewRenderProps {
|
|||
columnTypes?: Record<string, string>;
|
||||
query?: Query | AggregateQuery;
|
||||
textBasedHits?: DataTableRecord[];
|
||||
hideActionsColumn?: boolean;
|
||||
filter?: DocViewFilterFn;
|
||||
onAddColumn?: (columnName: string) => void;
|
||||
onRemoveColumn?: (columnName: string) => void;
|
||||
|
|
|
@ -119,7 +119,7 @@ export function Doc(props: DocProps) {
|
|||
|
||||
{reqState === ElasticRequestState.Found && hit !== null && dataView && (
|
||||
<div data-test-subj="doc-hit">
|
||||
<UnifiedDocViewer hit={hit} dataView={dataView} />
|
||||
<UnifiedDocViewer hit={hit} dataView={dataView} hideActionsColumn />
|
||||
</div>
|
||||
)}
|
||||
</EuiPageBody>
|
||||
|
|
|
@ -248,6 +248,7 @@ describe('DocViewTable at Discover Doc', () => {
|
|||
const props = {
|
||||
hit,
|
||||
dataView,
|
||||
hideActionsColumn: true,
|
||||
};
|
||||
const component = mountComponent(props);
|
||||
const foundLength = findTestSubject(component, 'addInclusiveFilterButton').length;
|
||||
|
|
|
@ -25,6 +25,7 @@ export const DocViewerLegacyTable = ({
|
|||
columns,
|
||||
hit,
|
||||
dataView,
|
||||
hideActionsColumn,
|
||||
filter,
|
||||
onAddColumn,
|
||||
onRemoveColumn,
|
||||
|
@ -34,8 +35,8 @@ export const DocViewerLegacyTable = ({
|
|||
|
||||
const mapping = useCallback((name: string) => dataView.fields.getByName(name), [dataView.fields]);
|
||||
const tableColumns = useMemo(() => {
|
||||
return filter ? [ACTIONS_COLUMN, ...MAIN_COLUMNS] : MAIN_COLUMNS;
|
||||
}, [filter]);
|
||||
return !hideActionsColumn ? [ACTIONS_COLUMN, ...MAIN_COLUMNS] : MAIN_COLUMNS;
|
||||
}, [hideActionsColumn]);
|
||||
const onToggleColumn = useCallback(
|
||||
(field: string) => {
|
||||
if (!onRemoveColumn || !onAddColumn || !columns) {
|
||||
|
|
|
@ -36,11 +36,11 @@ export const TableActions = ({
|
|||
return (
|
||||
<div className="kbnDocViewer__buttons">
|
||||
<DocViewTableRowBtnFilterAdd
|
||||
disabled={!fieldMapping || !fieldMapping.filterable || ignoredValue}
|
||||
disabled={!fieldMapping || !fieldMapping.filterable || ignoredValue || !onFilter}
|
||||
onClick={() => onFilter(fieldMapping, flattenedField, '+')}
|
||||
/>
|
||||
<DocViewTableRowBtnFilterRemove
|
||||
disabled={!fieldMapping || !fieldMapping.filterable || ignoredValue}
|
||||
disabled={!fieldMapping || !fieldMapping.filterable || ignoredValue || !onFilter}
|
||||
onClick={() => onFilter(fieldMapping, flattenedField, '-')}
|
||||
/>
|
||||
<DocViewTableRowBtnToggleColumn
|
||||
|
@ -49,7 +49,7 @@ export const TableActions = ({
|
|||
onClick={() => onToggleColumn(field)}
|
||||
/>
|
||||
<DocViewTableRowBtnFilterExists
|
||||
disabled={!fieldMapping || !fieldMapping.filterable}
|
||||
disabled={!fieldMapping || !fieldMapping.filterable || !onFilter}
|
||||
onClick={() => onFilter('_exists_', field, '+')}
|
||||
scripted={fieldMapping && fieldMapping.scripted}
|
||||
/>
|
||||
|
|
|
@ -109,6 +109,7 @@ export const DocViewerTable = ({
|
|||
columnTypes,
|
||||
hit,
|
||||
dataView,
|
||||
hideActionsColumn,
|
||||
filter,
|
||||
onAddColumn,
|
||||
onRemoveColumn,
|
||||
|
@ -118,7 +119,6 @@ export const DocViewerTable = ({
|
|||
const { fieldFormats, storage, uiSettings } = useUnifiedDocViewerServices();
|
||||
const showMultiFields = uiSettings.get(SHOW_MULTIFIELDS);
|
||||
const currentDataViewId = dataView.id!;
|
||||
const isSingleDocView = !filter;
|
||||
|
||||
const [searchText, setSearchText] = useState(getSearchText(storage));
|
||||
const [pinnedFields, setPinnedFields] = useState<string[]>(
|
||||
|
@ -283,7 +283,7 @@ export const DocViewerTable = ({
|
|||
);
|
||||
|
||||
const headers = [
|
||||
!isSingleDocView && (
|
||||
!hideActionsColumn && (
|
||||
<EuiTableHeaderCell
|
||||
key="header-cell-actions"
|
||||
align="left"
|
||||
|
@ -332,7 +332,7 @@ export const DocViewerTable = ({
|
|||
}: FieldRecord) => {
|
||||
return (
|
||||
<EuiTableRow key={field} className="kbnDocViewer__tableRow" isSelected={pinned}>
|
||||
{!isSingleDocView && (
|
||||
{!hideActionsColumn && (
|
||||
<EuiTableRowCell
|
||||
key={field + '-actions'}
|
||||
align={showActionsInsideTableCell ? 'left' : 'center'}
|
||||
|
@ -347,7 +347,7 @@ export const DocViewerTable = ({
|
|||
pinned={pinned}
|
||||
fieldMapping={fieldMapping}
|
||||
flattenedField={flattenedField}
|
||||
onFilter={onFilter!}
|
||||
onFilter={onFilter}
|
||||
onToggleColumn={onToggleColumn}
|
||||
ignoredValue={!!ignored}
|
||||
onTogglePinned={onTogglePinned}
|
||||
|
@ -392,7 +392,7 @@ export const DocViewerTable = ({
|
|||
}
|
||||
);
|
||||
},
|
||||
[onToggleColumn, onTogglePinned, isSingleDocView, showActionsInsideTableCell, searchText]
|
||||
[hideActionsColumn, showActionsInsideTableCell, onToggleColumn, onTogglePinned, searchText]
|
||||
);
|
||||
|
||||
const rowElements = [
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
import React from 'react';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { TableActions } from './table_cell_actions';
|
||||
import { DataViewField } from '@kbn/data-views-plugin/common';
|
||||
|
||||
describe('TableActions', () => {
|
||||
it('should render the panels correctly for undefined onFilter function', () => {
|
||||
render(
|
||||
<TableActions
|
||||
mode="inline"
|
||||
field="message"
|
||||
pinned={false}
|
||||
fieldMapping={undefined}
|
||||
flattenedField="message"
|
||||
onFilter={undefined}
|
||||
onToggleColumn={jest.fn()}
|
||||
ignoredValue={false}
|
||||
onTogglePinned={jest.fn()}
|
||||
/>
|
||||
);
|
||||
expect(screen.getByTestId('addFilterForValueButton-message')).toBeDisabled();
|
||||
expect(screen.getByTestId('addFilterOutValueButton-message')).toBeDisabled();
|
||||
expect(screen.getByTestId('addExistsFilterButton-message')).toBeDisabled();
|
||||
expect(screen.getByTestId('toggleColumnButton-message')).not.toBeDisabled();
|
||||
expect(screen.getByTestId('togglePinFilterButton-message')).not.toBeDisabled();
|
||||
});
|
||||
|
||||
it('should render the panels correctly for defined onFilter function', () => {
|
||||
render(
|
||||
<TableActions
|
||||
mode="inline"
|
||||
field="message"
|
||||
pinned={false}
|
||||
fieldMapping={
|
||||
{
|
||||
name: 'message',
|
||||
type: 'string',
|
||||
filterable: true,
|
||||
} as DataViewField
|
||||
}
|
||||
flattenedField="message"
|
||||
onFilter={jest.fn()}
|
||||
onToggleColumn={jest.fn()}
|
||||
ignoredValue={false}
|
||||
onTogglePinned={jest.fn()}
|
||||
/>
|
||||
);
|
||||
expect(screen.getByTestId('addFilterForValueButton-message')).not.toBeDisabled();
|
||||
expect(screen.getByTestId('addFilterOutValueButton-message')).not.toBeDisabled();
|
||||
expect(screen.getByTestId('addExistsFilterButton-message')).not.toBeDisabled();
|
||||
expect(screen.getByTestId('toggleColumnButton-message')).not.toBeDisabled();
|
||||
expect(screen.getByTestId('togglePinFilterButton-message')).not.toBeDisabled();
|
||||
});
|
||||
});
|
|
@ -25,7 +25,7 @@ interface TableActionsProps {
|
|||
pinned: boolean;
|
||||
flattenedField: unknown;
|
||||
fieldMapping?: DataViewField;
|
||||
onFilter: DocViewFilterFn;
|
||||
onFilter?: DocViewFilterFn;
|
||||
onToggleColumn: (field: string) => void;
|
||||
ignoredValue: boolean;
|
||||
onTogglePinned: (field: string) => void;
|
||||
|
@ -51,7 +51,8 @@ export const TableActions = ({
|
|||
});
|
||||
|
||||
// Filters pair
|
||||
const filtersPairDisabled = !fieldMapping || !fieldMapping.filterable || ignoredValue;
|
||||
const filtersPairDisabled =
|
||||
!fieldMapping || !fieldMapping.filterable || ignoredValue || !onFilter;
|
||||
const filterAddLabel = i18n.translate(
|
||||
'unifiedDocViewer.docViews.table.filterForValueButtonTooltip',
|
||||
{
|
||||
|
@ -88,7 +89,7 @@ export const TableActions = ({
|
|||
'unifiedDocViewer.docViews.table.filterForFieldPresentButtonAriaLabel',
|
||||
{ defaultMessage: 'Filter for field present' }
|
||||
);
|
||||
const filtersExistsDisabled = !fieldMapping || !fieldMapping.filterable;
|
||||
const filtersExistsDisabled = !fieldMapping || !fieldMapping.filterable || !onFilter;
|
||||
const filtersExistsToolTip =
|
||||
(filtersExistsDisabled &&
|
||||
(fieldMapping && fieldMapping.scripted
|
||||
|
@ -156,7 +157,9 @@ export const TableActions = ({
|
|||
icon: 'plusInCircle',
|
||||
disabled: filtersPairDisabled,
|
||||
'data-test-subj': `addFilterForValueButton-${field}`,
|
||||
onClick: onClickAction(onFilter.bind({}, fieldMapping, flattenedField, '+')),
|
||||
onClick: onFilter
|
||||
? onClickAction(onFilter.bind({}, fieldMapping, flattenedField, '+'))
|
||||
: undefined,
|
||||
},
|
||||
{
|
||||
name: filterOutLabel,
|
||||
|
@ -164,7 +167,10 @@ export const TableActions = ({
|
|||
toolTipContent: filtersPairToolTip,
|
||||
icon: 'minusInCircle',
|
||||
disabled: filtersPairDisabled,
|
||||
onClick: onClickAction(onFilter.bind({}, fieldMapping, flattenedField, '-')),
|
||||
'data-test-subj': `addFilterOutValueButton-${field}`,
|
||||
onClick: onFilter
|
||||
? onClickAction(onFilter.bind({}, fieldMapping, flattenedField, '-'))
|
||||
: undefined,
|
||||
},
|
||||
{
|
||||
name: filterExistsLabel,
|
||||
|
@ -173,7 +179,7 @@ export const TableActions = ({
|
|||
icon: 'filter',
|
||||
disabled: filtersExistsDisabled,
|
||||
'data-test-subj': `addExistsFilterButton-${field}`,
|
||||
onClick: onClickAction(onFilter.bind({}, '_exists_', field, '+')),
|
||||
onClick: onFilter ? onClickAction(onFilter.bind({}, '_exists_', field, '+')) : undefined,
|
||||
},
|
||||
{
|
||||
name: toggleColumnsLabel,
|
||||
|
@ -186,6 +192,7 @@ export const TableActions = ({
|
|||
name: pinnedLabel,
|
||||
'aria-label': pinnedAriaLabel,
|
||||
icon: pinnedIconType,
|
||||
'data-test-subj': `togglePinFilterButton-${field}`,
|
||||
onClick: onClickAction(togglePinned),
|
||||
},
|
||||
],
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue