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

Allow DataGrid's columns popover to optionally not allow hiding and/or reordering #2993

Merged
Show file tree
Hide file tree
Changes from 1 commit
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
5 changes: 5 additions & 0 deletions src-docs/src/views/datagrid/datagrid.js
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,11 @@ export default () => {
return (
<EuiDataGrid
aria-label="Data grid demo"
toolbarVisibility={{
showColumnSelector: {
allowHide: false,
},
}}
columns={columns}
columnVisibility={{ visibleColumns, setVisibleColumns }}
trailingControlColumns={trailingControlColumns}
Expand Down
8 changes: 4 additions & 4 deletions src/components/datagrid/__snapshots__/data_grid.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ Array [
<span
class="euiButtonEmpty__text"
>
Hide fields
Columns
</span>
</span>
</button>
Expand Down Expand Up @@ -718,7 +718,7 @@ Array [
<span
class="euiButtonEmpty__text"
>
Hide fields
Columns
</span>
</span>
</button>
Expand Down Expand Up @@ -1435,7 +1435,7 @@ Array [
<span
class="euiButtonEmpty__text"
>
Hide fields
Columns
</span>
</span>
</button>
Expand Down Expand Up @@ -1956,7 +1956,7 @@ Array [
<span
class="euiButtonEmpty__text"
>
Hide fields
Columns
</span>
</span>
</button>
Expand Down
161 changes: 97 additions & 64 deletions src/components/datagrid/column_selector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import classNames from 'classnames';
import {
EuiDataGridColumn,
EuiDataGridColumnVisibility,
EuiDataGridToolBarVisibilityColumnSelectorOptions,
EuiDataGridToolBarVisibilityOptions,
} from './data_grid_types';
import { EuiPopover, EuiPopoverFooter, EuiPopoverTitle } from '../popover';
import { EuiI18n } from '../i18n';
Expand All @@ -26,10 +28,30 @@ import { DropResult } from 'react-beautiful-dnd';
import { EuiIcon } from '../icon';
import { useDependentState } from '../../services';

const getShowColumnSelectorValue = (
showColumnSelector: EuiDataGridToolBarVisibilityOptions['showColumnSelector'],
valueName: keyof EuiDataGridToolBarVisibilityColumnSelectorOptions
) => {
if (showColumnSelector === false) return false;
if (showColumnSelector == null) return true;
if (showColumnSelector === true) return true;
return showColumnSelector[valueName] !== false;
};

export const useColumnSelector = (
availableColumns: EuiDataGridColumn[],
columnVisibility: EuiDataGridColumnVisibility
columnVisibility: EuiDataGridColumnVisibility,
showColumnSelector: EuiDataGridToolBarVisibilityOptions['showColumnSelector']
): [ReactElement, EuiDataGridColumn[]] => {
const allowColumnHiding = getShowColumnSelectorValue(
showColumnSelector,
'allowHide'
);
const allowColumnReorder = getShowColumnSelectorValue(
showColumnSelector,
'allowReorder'
);

const [sortedColumns, setSortedColumns] = useDependentState(
() => availableColumns.map(({ id }) => id),
[availableColumns]
Expand Down Expand Up @@ -69,7 +91,7 @@ export const useColumnSelector = (
const filteredColumns = sortedColumns.filter(
id => id.toLowerCase().indexOf(columnSearchText.toLowerCase()) !== -1
);
const isDragEnabled = columnSearchText.length === 0; // only allow drag-and-drop when not filtering columns
const isDragEnabled = allowColumnReorder && columnSearchText.length === 0; // only allow drag-and-drop when not filtering columns

const columnSelector = (
<EuiPopover
Expand All @@ -86,7 +108,7 @@ export const useColumnSelector = (
'euiColumnSelector.button',
'euiColumnSelector.buttonActive',
]}
defaults={['Hide fields', 'fields hidden']}>
defaults={['Columns', 'columns hidden']}>
snide marked this conversation as resolved.
Show resolved Hide resolved
{([button, buttonActive]: ReactChild[]) => (
<EuiButtonEmpty
size="xs"
Expand All @@ -103,26 +125,28 @@ export const useColumnSelector = (
</EuiI18n>
}>
<div>
<EuiPopoverTitle>
<EuiI18n
tokens={[
'euiColumnSelector.search',
'euiColumnSelector.searchcolumns',
]}
defaults={['Search', 'Search columns']}>
{([search, searchcolumns]: string[]) => (
<EuiFieldText
compressed
placeholder={search}
aria-label={searchcolumns}
value={columnSearchText}
onChange={(e: ChangeEvent<HTMLInputElement>) =>
setColumnSearchText(e.currentTarget.value)
}
/>
)}
</EuiI18n>
</EuiPopoverTitle>
{allowColumnHiding && (
<EuiPopoverTitle>
<EuiI18n
tokens={[
'euiColumnSelector.search',
'euiColumnSelector.searchcolumns',
]}
defaults={['Search', 'Search columns']}>
{([search, searchcolumns]: string[]) => (
<EuiFieldText
compressed
placeholder={search}
aria-label={searchcolumns}
value={columnSearchText}
onChange={(e: ChangeEvent<HTMLInputElement>) =>
setColumnSearchText(e.currentTarget.value)
}
/>
)}
</EuiI18n>
</EuiPopoverTitle>
)}
<EuiDragDropContext onDragEnd={onDragEnd}>
<EuiDroppable
droppableId="columnOrder"
Expand All @@ -141,27 +165,31 @@ export const useColumnSelector = (
'euiDataGridColumnSelector__item-isDragging'}`}>
<EuiFlexGroup gutterSize="m" alignItems="center">
<EuiFlexItem>
<EuiSwitch
name={id}
label={id}
checked={visibleColumnIds.has(id)}
compressed
className="euiSwitch--mini"
onChange={event => {
const {
target: { checked },
} = event;
const nextVisibleColumns = sortedColumns.filter(
columnId =>
checked
? visibleColumnIds.has(columnId) ||
id === columnId
: visibleColumnIds.has(columnId) &&
id !== columnId
);
setVisibleColumns(nextVisibleColumns);
}}
/>
{allowColumnHiding ? (
<EuiSwitch
name={id}
label={id}
checked={visibleColumnIds.has(id)}
compressed
className="euiSwitch--mini"
onChange={event => {
const {
target: { checked },
} = event;
const nextVisibleColumns = sortedColumns.filter(
columnId =>
checked
? visibleColumnIds.has(columnId) ||
id === columnId
: visibleColumnIds.has(columnId) &&
id !== columnId
);
setVisibleColumns(nextVisibleColumns);
}}
/>
) : (
id
)}
</EuiFlexItem>
{isDragEnabled && (
<EuiFlexItem grow={false}>
Expand All @@ -177,26 +205,31 @@ export const useColumnSelector = (
</EuiDroppable>
</EuiDragDropContext>
</div>
<EuiPopoverFooter>
<EuiFlexGroup gutterSize="s" justifyContent="spaceBetween">
<EuiFlexItem>
<EuiButtonEmpty
size="xs"
flush="left"
onClick={() => setVisibleColumns(sortedColumns)}>
<EuiI18n token="euiColumnSelector.selectAll" default="Show all" />
</EuiButtonEmpty>
</EuiFlexItem>
<EuiFlexItem>
<EuiButtonEmpty
size="xs"
flush="right"
onClick={() => setVisibleColumns([])}>
<EuiI18n token="euiColumnSelector.hideAll" default="Hide all" />
</EuiButtonEmpty>
</EuiFlexItem>
</EuiFlexGroup>
</EuiPopoverFooter>
{allowColumnHiding && (
<EuiPopoverFooter>
<EuiFlexGroup gutterSize="s" justifyContent="spaceBetween">
<EuiFlexItem>
<EuiButtonEmpty
size="xs"
flush="left"
onClick={() => setVisibleColumns(sortedColumns)}>
<EuiI18n
token="euiColumnSelector.selectAll"
default="Show all"
/>
</EuiButtonEmpty>
</EuiFlexItem>
<EuiFlexItem>
<EuiButtonEmpty
size="xs"
flush="right"
onClick={() => setVisibleColumns([])}>
<EuiI18n token="euiColumnSelector.hideAll" default="Hide all" />
</EuiButtonEmpty>
</EuiFlexItem>
</EuiFlexGroup>
</EuiPopoverFooter>
)}
</EuiPopover>
);

Expand Down
53 changes: 27 additions & 26 deletions src/components/datagrid/data_grid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,31 @@ const useFocus = (
return [focusProps, focusedCell, setFocusedCell];
};

// Typeguards to see if toolbarVisibility has a certain boolean property assigned
// If not, just set it to true and assume it's OK to show
function objectHasKey<O extends Record<string, any>, ObjectKey extends keyof O>(
object: O,
key: ObjectKey
): object is Required<O> {
return object.hasOwnProperty(key);
}
function checkOrDefaultToolBarDiplayOptions<
OptionKey extends keyof EuiDataGridToolBarVisibilityOptions
>(
arg: EuiDataGridProps['toolbarVisibility'],
option: OptionKey
): Required<EuiDataGridToolBarVisibilityOptions>[OptionKey] {
if (arg === undefined) {
return true;
} else if (typeof arg === 'boolean') {
return arg as boolean;
} else if (objectHasKey(arg, option)) {
return arg[option];
} else {
return true;
}
}

export const EuiDataGrid: FunctionComponent<EuiDataGridProps> = props => {
const [isFullScreen, setIsFullScreen] = useState(false);
const [hasRoomForGridControls, setHasRoomForGridControls] = useState(true);
Expand Down Expand Up @@ -605,7 +630,8 @@ export const EuiDataGrid: FunctionComponent<EuiDataGridProps> = props => {

const [columnSelector, orderedVisibleColumns] = useColumnSelector(
columns,
columnVisibility
columnVisibility,
checkOrDefaultToolBarDiplayOptions(toolbarVisibility, 'showColumnSelector')
);
const columnSorting = useColumnSorting(
orderedVisibleColumns,
Expand Down Expand Up @@ -653,31 +679,6 @@ export const EuiDataGrid: FunctionComponent<EuiDataGridProps> = props => {
// By default the toolbar appears
const showToolbar = !!toolbarVisibility;

// Typeguards to see if toolbarVisibility has a certain boolean property assigned
// If not, just set it to true and assume it's OK to show
function objectHasKey<
O extends Record<string, any>,
ObjectKey extends keyof O
>(object: O, key: ObjectKey): object is Required<O> {
return object.hasOwnProperty(key);
}
function checkOrDefaultToolBarDiplayOptions<
OptionKey extends keyof EuiDataGridToolBarVisibilityOptions
>(
arg: EuiDataGridProps['toolbarVisibility'],
option: OptionKey
): Required<EuiDataGridToolBarVisibilityOptions>[OptionKey] {
if (arg === undefined) {
return true;
} else if (typeof arg === 'boolean') {
return arg as boolean;
} else if (objectHasKey(arg, option)) {
return arg[option];
} else {
return true;
}
}

// These grid controls will only show when there is room. Check the resize observer callback
// They can also be optionally turned off individually by using toolbarVisibility
const gridControls = (
Expand Down
9 changes: 8 additions & 1 deletion src/components/datagrid/data_grid_types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,18 @@ export interface EuiDataGridStyle {
cellPadding?: EuiDataGridStyleCellPaddings;
}

export interface EuiDataGridToolBarVisibilityColumnSelectorOptions {
allowHide?: boolean;
allowReorder?: boolean;
}

export interface EuiDataGridToolBarVisibilityOptions {
/**
* Allows the ability for the user to hide fields and sort columns
*/
showColumnSelector?: boolean;
showColumnSelector?:
| boolean
| EuiDataGridToolBarVisibilityColumnSelectorOptions;
/**
* Allows the ability for the user to set the grid density. If on, this merges against what is provided in #EuiDataGridStyle
*/
Expand Down