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

[7.x] [Lens] Hide column in table (#88680) #90286

Merged
merged 1 commit into from
Feb 5, 2021
Merged
Show file tree
Hide file tree
Changes from all 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

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 @@ -10,7 +10,7 @@ import { i18n } from '@kbn/i18n';
import { EuiDataGridColumn, EuiDataGridColumnCellActionProps } from '@elastic/eui';
import type { Datatable, DatatableColumnMeta } from 'src/plugins/expressions';
import type { FormatFactory } from '../../types';
import type { DatatableColumns } from './types';
import { ColumnConfig } from './table_basic';

export const createGridColumns = (
bucketColumns: string[],
Expand All @@ -23,10 +23,11 @@ export const createGridColumns = (
negate?: boolean
) => void,
isReadOnly: boolean,
columnConfig: DatatableColumns & { type: 'lens_datatable_columns' },
columnConfig: ColumnConfig,
visibleColumns: string[],
formatFactory: FormatFactory,
onColumnResize: (eventData: { columnId: string; width: number | undefined }) => void
onColumnResize: (eventData: { columnId: string; width: number | undefined }) => void,
onColumnHide: (eventData: { columnId: string }) => void
) => {
const columnsReverseLookup = table.columns.reduce<
Record<string, { name: string; index: number; meta?: DatatableColumnMeta }>
Expand Down Expand Up @@ -134,8 +135,9 @@ export const createGridColumns = (
]
: undefined;

const initialWidth = columnConfig.columnWidth?.find(({ columnId }) => columnId === field)
?.width;
const column = columnConfig.columns.find(({ columnId }) => columnId === field);
const initialWidth = column?.width;
const isHidden = column?.hidden;

const columnDefinition: EuiDataGridColumn = {
id: field,
Expand Down Expand Up @@ -174,6 +176,17 @@ export const createGridColumns = (
'data-test-subj': 'lensDatatableResetWidth',
isDisabled: initialWidth == null,
},
{
color: 'text',
size: 'xs',
onClick: () => onColumnHide({ columnId: field }),
iconType: 'eyeClosed',
label: i18n.translate('xpack.lens.table.hide.hideLabel', {
defaultMessage: 'Hide',
}),
'data-test-subj': 'lensDatatableHide',
isDisabled: !isHidden && visibleColumns.length <= 1,
},
],
},
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@

export const LENS_EDIT_SORT_ACTION = 'sort';
export const LENS_EDIT_RESIZE_ACTION = 'resize';
export const LENS_TOGGLE_ACTION = 'toggle';
Original file line number Diff line number Diff line change
@@ -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; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import React from 'react';
import { i18n } from '@kbn/i18n';
import { EuiSwitch, EuiFormRow } from '@elastic/eui';
import { VisualizationDimensionEditorProps } from '../../types';
import { DatatableVisualizationState } from '../visualization';

export function TableDimensionEditor(
props: VisualizationDimensionEditorProps<DatatableVisualizationState>
) {
const { state, setState, accessor } = props;
const column = state.columns.find((c) => c.columnId === accessor);

const visibleColumnsCount = state.columns.filter((c) => !c.hidden).length;

if (!column) {
return null;
}

return (
<EuiFormRow
label={i18n.translate('xpack.lens.table.columnVisibilityLabel', {
defaultMessage: 'Column hidden in table',
})}
display="columnCompressedSwitch"
>
<EuiSwitch
compressed
label={i18n.translate('xpack.lens.table.columnVisibilityLabel', {
defaultMessage: 'Column hidden in table',
})}
showLabel={false}
data-test-subj="lns-table-column-hidden"
checked={Boolean(column?.hidden)}
disabled={!column.hidden && visibleColumnsCount <= 1}
onChange={() => {
const newState = {
...state,
columns: state.columns.map((currentColumn) => {
if (currentColumn.columnId === accessor) {
return {
...currentColumn,
hidden: !column.hidden,
};
} else {
return currentColumn;
}
}),
};
setState(newState);
}}
/>
</EuiFormRow>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,19 @@ import {
createGridFilterHandler,
createGridResizeHandler,
createGridSortingConfig,
createGridHideHandler,
} from './table_actions';
import { DatatableColumns, LensGridDirection } from './types';
import { LensGridDirection } from './types';
import { ColumnConfig } from './table_basic';

function getDefaultConfig(): DatatableColumns & {
type: 'lens_datatable_columns';
} {
function getDefaultConfig(): ColumnConfig {
return {
columnIds: [],
sortBy: '',
sortDirection: 'none',
type: 'lens_datatable_columns',
columns: [
{ columnId: 'a', type: 'lens_datatable_column' },
{ columnId: 'b', type: 'lens_datatable_column' },
],
sortingColumnId: '',
sortingDirection: 'none',
};
}

Expand Down Expand Up @@ -207,24 +209,28 @@ describe('Table actions', () => {

expect(setColumnConfig).toHaveBeenCalledWith({
...columnConfig,
columnWidth: [{ columnId: 'a', width: 100, type: 'lens_datatable_column_width' }],
columns: [
{ columnId: 'a', width: 100, type: 'lens_datatable_column' },
{
columnId: 'b',
type: 'lens_datatable_column',
},
],
});

expect(onEditAction).toHaveBeenCalledWith({ action: 'resize', columnId: 'a', width: 100 });
});

it('should pull out the table custom width from the local state when passing undefined', () => {
const columnConfig = getDefaultConfig();
columnConfig.columnWidth = [
{ columnId: 'a', width: 100, type: 'lens_datatable_column_width' },
];
columnConfig.columns = [{ columnId: 'a', width: 100, type: 'lens_datatable_column' }];

const resizer = createGridResizeHandler(columnConfig, setColumnConfig, onEditAction);
resizer({ columnId: 'a', width: undefined });

expect(setColumnConfig).toHaveBeenCalledWith({
...columnConfig,
columnWidth: [],
columns: [{ columnId: 'a', width: undefined, type: 'lens_datatable_column' }],
});

expect(onEditAction).toHaveBeenCalledWith({
Expand All @@ -234,4 +240,23 @@ describe('Table actions', () => {
});
});
});
describe('Column hiding', () => {
const setColumnConfig = jest.fn();

it('should allow to hide column', () => {
const columnConfig = getDefaultConfig();
const hiding = createGridHideHandler(columnConfig, setColumnConfig, onEditAction);
hiding({ columnId: 'a' });

expect(setColumnConfig).toHaveBeenCalledWith({
...columnConfig,
columns: [
{ columnId: 'a', hidden: true, type: 'lens_datatable_column' },
{ columnId: 'b', type: 'lens_datatable_column' },
],
});

expect(onEditAction).toHaveBeenCalledWith({ action: 'toggle', columnId: 'a' });
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -9,43 +9,30 @@ import type { EuiDataGridSorting } from '@elastic/eui';
import type { Datatable } from 'src/plugins/expressions';
import type { LensFilterEvent } from '../../types';
import type {
DatatableColumns,
LensGridDirection,
LensResizeAction,
LensSortAction,
LensToggleAction,
} from './types';
import { ColumnConfig } from './table_basic';

import { desanitizeFilterContext } from '../../utils';

export const createGridResizeHandler = (
columnConfig: DatatableColumns & {
type: 'lens_datatable_columns';
},
setColumnConfig: React.Dispatch<
React.SetStateAction<
DatatableColumns & {
type: 'lens_datatable_columns';
}
>
>,
columnConfig: ColumnConfig,
setColumnConfig: React.Dispatch<React.SetStateAction<ColumnConfig>>,
onEditAction: (data: LensResizeAction['data']) => void
) => (eventData: { columnId: string; width: number | undefined }) => {
// directly set the local state of the component to make sure the visualization re-renders immediately,
// re-layouting and taking up all of the available space.
setColumnConfig({
...columnConfig,
columnWidth: [
...(columnConfig.columnWidth || []).filter(({ columnId }) => columnId !== eventData.columnId),
...(eventData.width !== undefined
? [
{
columnId: eventData.columnId,
width: eventData.width,
type: 'lens_datatable_column_width' as const,
},
]
: []),
],
columns: columnConfig.columns.map((column) => {
if (column.columnId === eventData.columnId) {
return { ...column, width: eventData.width };
}
return column;
}),
});
return onEditAction({
action: 'resize',
Expand All @@ -54,6 +41,27 @@ export const createGridResizeHandler = (
});
};

export const createGridHideHandler = (
columnConfig: ColumnConfig,
setColumnConfig: React.Dispatch<React.SetStateAction<ColumnConfig>>,
onEditAction: (data: LensToggleAction['data']) => void
) => (eventData: { columnId: string }) => {
// directly set the local state of the component to make sure the visualization re-renders immediately
setColumnConfig({
...columnConfig,
columns: columnConfig.columns.map((column) => {
if (column.columnId === eventData.columnId) {
return { ...column, hidden: true };
}
return column;
}),
});
return onEditAction({
action: 'toggle',
columnId: eventData.columnId,
});
};

export const createGridFilterHandler = (
tableRef: React.MutableRefObject<Datatable>,
onClickValue: (data: LensFilterEvent['data']) => void
Expand Down Expand Up @@ -85,7 +93,7 @@ export const createGridFilterHandler = (
};

export const createGridSortingConfig = (
sortBy: string,
sortBy: string | undefined,
sortDirection: LensGridDirection,
onEditAction: (data: LensSortAction['data']) => void
): EuiDataGridSorting => ({
Expand Down
Loading