From b3f0d789b131e9b5677e134eee668361ce50fcf6 Mon Sep 17 00:00:00 2001 From: Artur Abdullin <30603428+ArturAbdullin@users.noreply.github.com> Date: Tue, 20 Feb 2024 18:17:04 +0300 Subject: [PATCH] feat(withTableSettings): add the renderControls prop (#1357) --- src/components/Table/README.md | 42 ++- .../Table/__stories__/Table.stories.tsx | 22 ++ .../WithTableSettingsCustomActions.tsx | 88 +++++ .../WithTableSettingsCustomActions/index.ts | 1 + .../__tests__/Table.withTableSettings.test.ts | 246 ------------- .../Table.withTableSettings.test.tsx | 336 ++++++++++++++++++ .../TableColumnSetup/TableColumnSetup.scss | 2 +- .../TableColumnSetup/TableColumnSetup.tsx | 39 +- .../__tests__/withTableSettings.test.tsx | 54 --- .../withTableSettings/withTableSettings.tsx | 7 +- 10 files changed, 515 insertions(+), 322 deletions(-) create mode 100644 src/components/Table/__stories__/WithTableSettingsCustomActions/WithTableSettingsCustomActions.tsx create mode 100644 src/components/Table/__stories__/WithTableSettingsCustomActions/index.ts delete mode 100644 src/components/Table/__tests__/Table.withTableSettings.test.ts create mode 100644 src/components/Table/__tests__/Table.withTableSettings.test.tsx delete mode 100644 src/components/Table/hoc/withTableSettings/__tests__/withTableSettings.test.tsx diff --git a/src/components/Table/README.md b/src/components/Table/README.md index 981cb4bcc2..3b553f3f16 100644 --- a/src/components/Table/README.md +++ b/src/components/Table/README.md @@ -251,11 +251,12 @@ const MyTable1 = withTableSettings({sortable: false})(Table); ### Properties -| Name | Description | Type | -| :----------------- | :---------------------------- | :------------------------------------------: | -| settingsPopupWidth | TableColumnSetup pop-up width | `number` `fit` | -| settings | Current settings | `TableSettingsData` | -| updateSettings | Settings update handle | `(data: TableSettingsData) => Promise` | +| Name | Description | Type | +| :----------------- | :------------------------------ | :------------------------------------------: | +| settingsPopupWidth | TableColumnSetup pop-up width | `number` `fit` | +| settings | Current settings | `TableSettingsData` | +| updateSettings | Settings update handle | `(data: TableSettingsData) => Promise` | +| renderControls | Allows to render custom actions | `RenderControls` | ### TableSettingsData @@ -266,6 +267,15 @@ type TableSettingsData = Array<{ }>; ``` +### RenderControls + +```ts +type RenderControls = (params: { + DefaultApplyButton: React.ComponentType; + onApply: () => void; +}) => React.ReactNode; +``` + ### Example ```jsx @@ -277,12 +287,12 @@ const data = [ {id: 2, text: 'World'}, ]; const columns = [{id: 'id'}, {id: 'text'}]; +const initialSettings = [ + {id: 'id', isSelected: false}, + {id: 'text', isSelected: true}, +]; function SelectionTable() { - const initialSettings = [ - {id: 'id', isSelected: false}, - {id: 'text', isSelected: true}, - ]; const [settings, setSettings] = React.useState(initialSettings); return ( @@ -294,6 +304,20 @@ function SelectionTable() { setSettings(settings); return Promise.resolve(); }} + renderControls={({DefaultApplyButton, onApply}) => ( + + + + + )} /> ); } diff --git a/src/components/Table/__stories__/Table.stories.tsx b/src/components/Table/__stories__/Table.stories.tsx index 5a738432f6..98e03a89ee 100644 --- a/src/components/Table/__stories__/Table.stories.tsx +++ b/src/components/Table/__stories__/Table.stories.tsx @@ -11,6 +11,7 @@ import {TreeSelect} from '../../TreeSelect/TreeSelect'; import {Table} from '../Table'; import type {TableProps} from '../Table'; +import {WithTableSettingsCustomActionsShowcase} from './WithTableSettingsCustomActions'; import { TableWithAction, TableWithCopy, @@ -225,6 +226,27 @@ HOCWithTableSettingsFactory.parameters = { disableStrictMode: true, }; +const WithTableSettingsCustomActionsTemplate: StoryFn> = (args) => { + const settings = React.useMemo(() => { + const newSettings: TableSettingsData = columns.map((x) => ({ + id: x.id, + isSelected: true, + })); + newSettings[0].isSelected = false; + newSettings[2].isSelected = false; + + return newSettings; + }, []); + + return ; +}; +export const HOCWithTableSettingsCustomActions = WithTableSettingsCustomActionsTemplate.bind({}); +HOCWithTableSettingsCustomActions.parameters = { + // Strict mode ruins sortable list due to this react-beautiful-dnd issue + // https://github.com/atlassian/react-beautiful-dnd/issues/2350 + disableStrictMode: true, +}; + // --------------------------------- const columnsWithSorting = _cloneDeep(columns); columnsWithSorting[0].meta = {sort: true}; diff --git a/src/components/Table/__stories__/WithTableSettingsCustomActions/WithTableSettingsCustomActions.tsx b/src/components/Table/__stories__/WithTableSettingsCustomActions/WithTableSettingsCustomActions.tsx new file mode 100644 index 0000000000..59b73ee674 --- /dev/null +++ b/src/components/Table/__stories__/WithTableSettingsCustomActions/WithTableSettingsCustomActions.tsx @@ -0,0 +1,88 @@ +import React from 'react'; + +import {ArrowRotateLeft} from '@gravity-ui/icons'; +import _isEqual from 'lodash/isEqual'; + +import {Button} from '../../../Button'; +import type {ButtonProps} from '../../../Button'; +import {Icon} from '../../../Icon'; +import {Flex} from '../../../layout'; +import type {TableProps} from '../../Table'; +import type {TableSettingsData} from '../../hoc/withTableSettings/withTableSettings'; +import type {DataItem} from '../utils'; +import {TableWithSettings} from '../utils'; + +interface WithTableSettingsCustomActionsShowcaseProps extends TableProps { + defaultSettings: TableSettingsData; +} + +export const WithTableSettingsCustomActionsShowcase = ({ + defaultSettings, + ...restTableProps +}: WithTableSettingsCustomActionsShowcaseProps) => { + const [innerSettings, setInnerSettings] = React.useState(defaultSettings); + + const updateSettings = React.useCallback( + (updatedSettings: TableSettingsData) => setInnerSettings(updatedSettings), + [], + ); + + const showSelectAllButton = React.useMemo( + () => innerSettings.some(({isSelected}) => !isSelected), + [innerSettings], + ); + + const showResetButton = React.useMemo( + () => !_isEqual(innerSettings, defaultSettings), + [defaultSettings, innerSettings], + ); + + return ( + ( + + {showSelectAllButton && ( + { + onApply(); + setInnerSettings((prevState) => + prevState.map((setting) => ({ + ...setting, + isSelected: true, + })), + ); + }} + /> + )} + {showResetButton && ( + { + onApply(); + setInnerSettings(defaultSettings); + }} + /> + )} + + + )} + /> + ); +}; + +function SelectAllButton({onClick}: T) { + return ; +} + +function ResetButton({onClick}: T) { + return ( + + ); +} diff --git a/src/components/Table/__stories__/WithTableSettingsCustomActions/index.ts b/src/components/Table/__stories__/WithTableSettingsCustomActions/index.ts new file mode 100644 index 0000000000..6cf76a0baf --- /dev/null +++ b/src/components/Table/__stories__/WithTableSettingsCustomActions/index.ts @@ -0,0 +1 @@ +export {WithTableSettingsCustomActionsShowcase} from './WithTableSettingsCustomActions'; diff --git a/src/components/Table/__tests__/Table.withTableSettings.test.ts b/src/components/Table/__tests__/Table.withTableSettings.test.ts deleted file mode 100644 index 317fe74ad4..0000000000 --- a/src/components/Table/__tests__/Table.withTableSettings.test.ts +++ /dev/null @@ -1,246 +0,0 @@ -import type {TableColumnConfig} from '../Table'; -import {enhanceSystemColumn} from '../hoc/withTableActions/withTableActions'; -import {selectionColumnId} from '../hoc/withTableSelection/withTableSelection'; -import type {TableSettingsData} from '../hoc/withTableSettings/withTableSettings'; -import { - filterColumns, - getActualItems, - getColumnStringTitle, -} from '../hoc/withTableSettings/withTableSettings'; - -const columns: TableColumnConfig[] = [ - { - id: 'id', - }, - { - id: 'name', - }, - { - id: 'description', - meta: { - sort: true, - }, - }, -]; - -const columnsWithSystem: TableColumnConfig[] = enhanceSystemColumn( - [ - { - id: selectionColumnId, - name: 'selection', - }, - ...columns, - ], - (systemColumn) => { - systemColumn.template = () => 'template'; - return systemColumn; - }, -); - -function ids(items: Array<{id: string}>) { - return items.map(({id}) => id); -} - -describe('withTableSettings getColumnStringTitle', () => { - it('should use id if name is not defined', () => { - expect(getColumnStringTitle({id: 'name'})).toEqual('name'); - }); - - it('should use name if it is string', () => { - expect(getColumnStringTitle({id: 'name', name: 'First Name'})).toEqual('First Name'); - }); - - it('should use meta._originalName if it is a string', () => { - expect( - getColumnStringTitle({ - id: 'name', - meta: { - _originalName: 'Result', - }, - }), - ).toEqual('Result'); - }); -}); - -describe('withTableSettings getActualItems', () => { - it('should filter system columns', () => { - expect(getActualItems(columnsWithSystem, []).map((column) => column.id)).toEqual( - columns.map((column) => column.id), - ); - }); - - it('should return recently added columns', () => { - const settings: TableSettingsData = [ - { - id: 'id', - isSelected: true, - }, - { - id: 'name', - isSelected: false, - }, - { - id: 'description', - isSelected: true, - }, - ]; - const updatedColumns = [...columns, {id: 'os'}]; - const actualSettings = getActualItems(updatedColumns, settings).map((column) => column.id); - expect(actualSettings).toEqual(updatedColumns.map((column) => column.id)); - }); - - it('should respect selectedByDefault in recently added columns', () => { - const settings: TableSettingsData = [ - { - id: 'id', - isSelected: true, - }, - { - id: 'name', - isSelected: false, - }, - { - id: 'description', - isSelected: true, - }, - ]; - const updatedColumns = [ - ...columns, - { - id: 'os', - meta: { - selectedByDefault: true, - }, - }, - { - id: 'osx', - meta: { - selectedByDefault: false, - }, - }, - ]; - const osSettings = getActualItems(updatedColumns, settings).find(({id}) => id === 'os'); - const osxSettings = getActualItems(updatedColumns, settings).find(({id}) => id === 'osx'); - expect(osSettings).toBeDefined(); - expect(osxSettings).toBeDefined(); - // @ts-ignore - expect(osSettings.isSelected).toBe(true); - // @ts-ignore - expect(osxSettings.isSelected).toBe(false); - }); - - it('should return columns when no settings provided', () => { - expect(ids(getActualItems(columns, []))).toEqual(ids(columns)); - }); - - it('should ignore settings which is not exists in columns', () => { - const settings: TableSettingsData = [ - { - id: 'description', - isSelected: true, - }, - { - id: 'name', - isSelected: true, - }, - { - id: 'id', - isSelected: true, - }, - { - id: 'removed', - isSelected: true, - }, - ]; - expect(ids(getActualItems(columns, settings))).toEqual( - ids([settings[0], settings[1], settings[2]]), - ); - }); -}); - -describe('withTableSettings filterColumns', () => { - it('should return only selected columns from settings', () => { - const settings: TableSettingsData = [ - { - id: 'id', - isSelected: true, - }, - { - id: 'name', - isSelected: false, - }, - { - id: 'description', - isSelected: true, - }, - ]; - expect(filterColumns(columns, settings)).toEqual([columns[0], columns[2]]); - }); - - it('should use columns order from settings', () => { - const settings: TableSettingsData = [ - { - id: 'description', - isSelected: true, - }, - { - id: 'name', - isSelected: true, - }, - { - id: 'id', - isSelected: true, - }, - ]; - expect(filterColumns(columns, settings)).toEqual([columns[2], columns[1], columns[0]]); - }); - - it('should ignore system column for selection', () => { - const enhancedColumns = [ - { - id: '_selection', - name: 'for selection', - }, - ...columns, - ]; - const settings: TableSettingsData = [ - { - id: 'description', - isSelected: true, - }, - { - id: 'name', - isSelected: true, - }, - { - id: 'id', - isSelected: true, - }, - ]; - expect(filterColumns(enhancedColumns, settings)).toEqual([ - enhancedColumns[0], - enhancedColumns[3], - enhancedColumns[2], - enhancedColumns[1], - ]); - }); - - it('should not filter system columns when settings provided', () => { - expect( - filterColumns(columnsWithSystem, [ - { - id: 'id', - isSelected: true, - }, - { - id: 'name', - isSelected: false, - }, - { - id: 'description', - isSelected: false, - }, - ]), - ).toEqual([columnsWithSystem[0], columnsWithSystem[1], columnsWithSystem[4]]); - }); -}); diff --git a/src/components/Table/__tests__/Table.withTableSettings.test.tsx b/src/components/Table/__tests__/Table.withTableSettings.test.tsx new file mode 100644 index 0000000000..1e0f453d9e --- /dev/null +++ b/src/components/Table/__tests__/Table.withTableSettings.test.tsx @@ -0,0 +1,336 @@ +import React from 'react'; + +import userEvent from '@testing-library/user-event'; + +import {render, screen} from '../../../../test-utils/utils'; +import {Button} from '../../Button'; +import {Table} from '../Table'; +import type {TableColumnConfig, TableProps} from '../Table'; +import {enhanceSystemColumn} from '../hoc/withTableActions/withTableActions'; +import {selectionColumnId} from '../hoc/withTableSelection/withTableSelection'; +import type {TableSetting, TableSettingsData} from '../hoc/withTableSettings/withTableSettings'; +import { + filterColumns, + getActualItems, + getColumnStringTitle, + withTableSettings, +} from '../hoc/withTableSettings/withTableSettings'; + +interface SomeItem { + id: string; + name: string; + description: string; +} + +const columns: TableColumnConfig[] = [ + { + id: 'id', + }, + { + id: 'name', + }, + { + id: 'description', + meta: { + sort: true, + }, + }, +]; + +const columnsWithSystem: TableColumnConfig[] = enhanceSystemColumn( + [ + { + id: selectionColumnId, + name: 'selection', + }, + ...columns, + ], + (systemColumn) => { + systemColumn.template = () => 'template'; + return systemColumn; + }, +); + +const data: TableProps['data'] = [ + {id: 'id1', name: 'Mock data 1', description: 'Mock data 1 description'}, + {id: 'id2', name: 'Mock data 2', description: 'Mock data 2 description'}, +]; + +function ids(items: Array<{id: string}>) { + return items.map(({id}) => id); +} + +describe('withTableSettings', () => { + const TableWithSettings = withTableSettings(Table); + + describe('getColumnStringTitle', () => { + it('should use id if name is not defined', () => { + expect(getColumnStringTitle({id: 'name'})).toEqual('name'); + }); + + it('should use name if it is string', () => { + expect(getColumnStringTitle({id: 'name', name: 'First Name'})).toEqual('First Name'); + }); + + it('should use meta._originalName if it is a string', () => { + expect( + getColumnStringTitle({ + id: 'name', + meta: { + _originalName: 'Result', + }, + }), + ).toEqual('Result'); + }); + }); + + describe('getActualItems', () => { + it('should filter system columns', () => { + expect(getActualItems(columnsWithSystem, []).map((column) => column.id)).toEqual( + columns.map((column) => column.id), + ); + }); + + it('should return recently added columns', () => { + const settings: TableSettingsData = [ + { + id: 'id', + isSelected: true, + }, + { + id: 'name', + isSelected: false, + }, + { + id: 'description', + isSelected: true, + }, + ]; + const updatedColumns = [...columns, {id: 'os'}]; + const actualSettings = getActualItems(updatedColumns, settings).map( + (column) => column.id, + ); + expect(actualSettings).toEqual(updatedColumns.map((column) => column.id)); + }); + + it('should respect selectedByDefault in recently added columns', () => { + const settings: TableSettingsData = [ + { + id: 'id', + isSelected: true, + }, + { + id: 'name', + isSelected: false, + }, + { + id: 'description', + isSelected: true, + }, + ]; + const updatedColumns = [ + ...columns, + { + id: 'os', + meta: { + selectedByDefault: true, + }, + }, + { + id: 'osx', + meta: { + selectedByDefault: false, + }, + }, + ]; + const osSettings = getActualItems(updatedColumns, settings).find(({id}) => id === 'os'); + const osxSettings = getActualItems(updatedColumns, settings).find( + ({id}) => id === 'osx', + ); + expect(osSettings).toBeDefined(); + expect(osxSettings).toBeDefined(); + // @ts-ignore + expect(osSettings.isSelected).toBe(true); + // @ts-ignore + expect(osxSettings.isSelected).toBe(false); + }); + + it('should return columns when no settings provided', () => { + expect(ids(getActualItems(columns, []))).toEqual(ids(columns)); + }); + + it('should ignore settings which is not exists in columns', () => { + const settings: TableSettingsData = [ + { + id: 'description', + isSelected: true, + }, + { + id: 'name', + isSelected: true, + }, + { + id: 'id', + isSelected: true, + }, + { + id: 'removed', + isSelected: true, + }, + ]; + expect(ids(getActualItems(columns, settings))).toEqual( + ids([settings[0], settings[1], settings[2]]), + ); + }); + }); + + describe('filterColumns', () => { + it('should return only selected columns from settings', () => { + const settings: TableSettingsData = [ + { + id: 'id', + isSelected: true, + }, + { + id: 'name', + isSelected: false, + }, + { + id: 'description', + isSelected: true, + }, + ]; + expect(filterColumns(columns, settings)).toEqual([columns[0], columns[2]]); + }); + + it('should use columns order from settings', () => { + const settings: TableSettingsData = [ + { + id: 'description', + isSelected: true, + }, + { + id: 'name', + isSelected: true, + }, + { + id: 'id', + isSelected: true, + }, + ]; + expect(filterColumns(columns, settings)).toEqual([columns[2], columns[1], columns[0]]); + }); + + it('should ignore system column for selection', () => { + const enhancedColumns = [ + { + id: '_selection', + name: 'for selection', + }, + ...columns, + ]; + const settings: TableSettingsData = [ + { + id: 'description', + isSelected: true, + }, + { + id: 'name', + isSelected: true, + }, + { + id: 'id', + isSelected: true, + }, + ]; + expect(filterColumns(enhancedColumns, settings)).toEqual([ + enhancedColumns[0], + enhancedColumns[3], + enhancedColumns[2], + enhancedColumns[1], + ]); + }); + + it('should not filter system columns when settings provided', () => { + expect( + filterColumns(columnsWithSystem, [ + { + id: 'id', + isSelected: true, + }, + { + id: 'name', + isSelected: false, + }, + { + id: 'description', + isSelected: false, + }, + ]), + ).toEqual([columnsWithSystem[0], columnsWithSystem[1], columnsWithSystem[4]]); + }); + }); + + describe('updateSettings', () => { + const settings = columns.map((column) => ({id: column.id, isSelected: true})); + + it('should change table columns visibility', async () => { + const updateSettings = jest.fn(); + + render( + , + ); + + await userEvent.click(screen.getByRole('button', {name: 'Table settings'})); + await userEvent.click(await screen.findByRole('button', {name: 'description'})); + await userEvent.click(screen.getByRole('button', {name: 'Apply'})); + + expect(updateSettings).toHaveBeenCalledWith([ + { + id: 'id', + isSelected: true, + }, + { + id: 'name', + isSelected: true, + }, + { + id: 'description', + isSelected: false, + }, + ] as TableSetting[]); + }); + }); + + describe('renderControls', () => { + const settings = columns.map((column) => ({id: column.id, isSelected: true})); + + it('should have custom controls', async () => { + const updateSettings = jest.fn(); + + const customControlText = 'Custom controls'; + + render( + { + return ; + }} + />, + ); + + await userEvent.click(screen.getByRole('button', {name: 'Table settings'})); + const customControl = screen.getByText(customControlText); + + expect(customControl).toBeVisible(); + }); + }); +}); diff --git a/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.scss b/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.scss index 92c8fc42e9..11820473db 100644 --- a/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.scss +++ b/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.scss @@ -3,7 +3,7 @@ $block: '.#{variables.$ns}table-column-setup'; #{$block} { - &__apply { + &__controls { margin: var(--g-spacing-1) var(--g-spacing-1) 0; } diff --git a/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx b/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx index 408c47e621..4ad867e1cd 100644 --- a/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx +++ b/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx @@ -27,7 +27,7 @@ import './TableColumnSetup.scss'; const b = block('table-column-setup'); const tableColumnSetupCn = b(null); -const applyButtonCn = b('apply'); +const controlsCn = b('controls'); const requiredDndItemCn = b('required-item'); const reorderArray = (list: T[], startIndex: number, endIndex: number): T[] => { @@ -69,13 +69,11 @@ interface SwitcherProps { onClick: React.MouseEventHandler; } -const useDndRenderContainer = ({ - onApply, - onDragEnd, -}: { +interface UseDndRenderContainerParams { onDragEnd: OnDragEndResponder; - onApply: () => void; -}) => { + renderControls: () => React.ReactNode; +} +const useDndRenderContainer = ({onDragEnd, renderControls}: UseDndRenderContainerParams) => { const uniqId = useUniqId(); const dndRenderContainer: TreeSelectRenderContainer = ({ @@ -108,9 +106,7 @@ const useDndRenderContainer = ({ - +
{renderControls()}
); }; @@ -173,6 +169,14 @@ type Item = TableColumnSetupItem & isDragDisabled?: boolean; }; +export type RenderControls = (params: { + DefaultApplyButton: React.ComponentType; + /** + * Is used to apply new settings and close the popup + */ + onApply: () => void; +}) => React.ReactNode; + export interface TableColumnSetupProps { renderSwitcher?: (props: SwitcherProps) => React.JSX.Element; @@ -182,6 +186,8 @@ export interface TableColumnSetupProps { onUpdate: (newSettings: TableSetting[]) => void; popupWidth?: TreeSelectProps['popupWidth']; popupPlacement?: PopperPlacement; + + renderControls?: RenderControls; } export const TableColumnSetup = (props: TableColumnSetupProps) => { @@ -192,6 +198,7 @@ export const TableColumnSetup = (props: TableColumnSetupProps) => { items: propsItems, onUpdate: propsOnUpdate, sortable, + renderControls, } = props; const [open, setOpen] = React.useState(false); @@ -210,6 +217,12 @@ export const TableColumnSetup = (props: TableColumnSetupProps) => { setOpen(false); }; + const DefaultApplyButton = () => ( + + ); + const onDragEnd: OnDragEndResponder = ({destination, source}) => { if (destination?.index !== undefined && destination?.index !== source.index) { setItems((prevItems) => { @@ -218,7 +231,11 @@ export const TableColumnSetup = (props: TableColumnSetupProps) => { } }; - const dndRenderContainer = useDndRenderContainer({onApply, onDragEnd}); + const dndRenderContainer = useDndRenderContainer({ + onDragEnd, + renderControls: () => + renderControls ? renderControls({DefaultApplyButton, onApply}) : , + }); const dndRenderItem = useDndRenderItem(sortable); diff --git a/src/components/Table/hoc/withTableSettings/__tests__/withTableSettings.test.tsx b/src/components/Table/hoc/withTableSettings/__tests__/withTableSettings.test.tsx deleted file mode 100644 index bdeb24e8ba..0000000000 --- a/src/components/Table/hoc/withTableSettings/__tests__/withTableSettings.test.tsx +++ /dev/null @@ -1,54 +0,0 @@ -import React from 'react'; - -import userEvent from '@testing-library/user-event'; - -import {render, screen} from '../../../../../../test-utils/utils'; -import type {TableColumnConfig} from '../../../Table'; -import {Table} from '../../../Table'; -import type {TableSetting} from '../withTableSettings'; -import {withTableSettings} from '../withTableSettings'; - -const item = {name: 'John Doe', occupation: 'Worker'}; - -const TableWithSettings = withTableSettings(Table); - -const columns: TableColumnConfig[] = [ - { - id: 'name', - }, - { - id: 'occupation', - }, -]; - -const data = [item]; - -const settings = columns.map((column) => ({id: column.id, isSelected: true})); - -test('should change table columns', async () => { - const updateSettings = jest.fn(); - - render( - , - ); - - await userEvent.click(screen.getByRole('button', {name: 'Table settings'})); - await userEvent.click(await screen.findByRole('button', {name: 'occupation'})); - await userEvent.click(screen.getByRole('button', {name: 'Apply'})); - - expect(updateSettings).toHaveBeenCalledWith([ - { - id: 'name', - isSelected: true, - }, - { - id: 'occupation', - isSelected: false, - }, - ]); -}); diff --git a/src/components/Table/hoc/withTableSettings/withTableSettings.tsx b/src/components/Table/hoc/withTableSettings/withTableSettings.tsx index b46f4269f1..e9e85913d6 100644 --- a/src/components/Table/hoc/withTableSettings/withTableSettings.tsx +++ b/src/components/Table/hoc/withTableSettings/withTableSettings.tsx @@ -16,6 +16,7 @@ import {actionsColumnId, enhanceSystemColumn} from '../withTableActions/withTabl import {selectionColumnId} from '../withTableSelection/withTableSelection'; import {TableColumnSetup} from './TableColumnSetup/TableColumnSetup'; +import type {RenderControls} from './TableColumnSetup/TableColumnSetup'; import i18n from './i18n'; import './withTableSettings.scss'; @@ -122,6 +123,8 @@ export interface WithTableSettingsProps { settings: TableSettingsData; updateSettings: (data: TableSettingsData) => void; + + renderControls?: RenderControls; } const b = block('table'); @@ -154,6 +157,7 @@ export function withTableSettings( settings, columns, settingsPopupWidth, + renderControls, ...restTableProps }: TableProps & WithTableSettingsProps & E) { const enhancedColumns = React.useMemo(() => { @@ -178,11 +182,12 @@ export function withTableSettings( )} + renderControls={renderControls} /> ); }); - }, [columns, settings, updateSettings, settingsPopupWidth]); + }, [columns, settings, updateSettings, settingsPopupWidth, renderControls]); return (