From 76a98c80753576bc4e52f11f8287c9448b876434 Mon Sep 17 00:00:00 2001 From: EgorIlyakhin Date: Wed, 30 Sep 2026 12:20:24 +0300 Subject: [PATCH 1/4] feat(TableSettings): reset to initial settings --- README-ru.md | 5 + README.md | 4 + .../TableSettings/TableSettings.test.tsx | 91 +++++++++++++++++++ .../TableSettings/TableSettings.tsx | 18 +++- src/components/TableSettings/i18n/en.json | 1 + src/components/TableSettings/i18n/ru.json | 1 + 6 files changed, 115 insertions(+), 5 deletions(-) create mode 100644 src/components/TableSettings/TableSettings.test.tsx diff --git a/README-ru.md b/README-ru.md index faf6fb5..2be941a 100644 --- a/README-ru.md +++ b/README-ru.md @@ -726,6 +726,11 @@ const ResizingDemo = () => { ### Настройки столбцов +Кнопка «Сбросить» в настройках восстанавливает видимость и порядок столбцов из +`initialState` таблицы. Изменения применяются после нажатия «Применить». Если +`initialState` не задан, все столбцы становятся видимыми и возвращаются к порядку из +определения. + ```tsx const columns: ColumnDef[] = [ // ...other columns diff --git a/README.md b/README.md index 9783129..2a93ccd 100644 --- a/README.md +++ b/README.md @@ -724,6 +724,10 @@ const ResizingDemo = () => { #### Column settings +The settings popup's Reset button restores column visibility and order from the table's +`initialState`. Reset changes the popup draft; press Apply to save it. Without an +`initialState`, Reset shows all columns in their definition order. + ```tsx const columns: ColumnDef[] = [ // ...other columns diff --git a/src/components/TableSettings/TableSettings.test.tsx b/src/components/TableSettings/TableSettings.test.tsx new file mode 100644 index 0000000..5066db2 --- /dev/null +++ b/src/components/TableSettings/TableSettings.test.tsx @@ -0,0 +1,91 @@ +import * as React from 'react'; + +import {ThemeProvider} from '@gravity-ui/uikit'; +import type {VisibilityState} from '@tanstack/react-table'; +import {fireEvent, render, screen} from '@testing-library/react'; + +import {useTable} from '../../hooks/useTable'; +import type {ColumnDef} from '../../types/base'; + +import {TableSettings} from './TableSettings'; + +const columns: ColumnDef<{first: string; second: string}>[] = [ + {id: 'first', accessorKey: 'first', header: 'First'}, + {id: 'second', accessorKey: 'second', header: 'Second'}, +]; + +const SettingsTest = ({withInitialState = true}: {withInitialState?: boolean}) => { + const [columnVisibility, setColumnVisibility] = React.useState({first: false}); + const [columnOrder, setColumnOrder] = React.useState(['second', 'first']); + const table = useTable({ + columns, + data: [], + ...(withInitialState && { + initialState: { + columnVisibility: {second: false}, + columnOrder: ['first', 'second'], + }, + }), + state: {columnVisibility, columnOrder}, + onColumnVisibilityChange: setColumnVisibility, + onColumnOrderChange: setColumnOrder, + }); + + return ( + + + {JSON.stringify(columnVisibility)} + {JSON.stringify(columnOrder)} + + ); +}; + +describe('TableSettings reset', () => { + it('restores initial settings only after Apply', () => { + render( + + + , + ); + fireEvent.click(screen.getAllByRole('button')[0]); + + fireEvent.click(screen.getByRole('button', {name: 'Reset'})); + expect(screen.getByTestId('visibility')).toHaveTextContent('{"first":false}'); + expect(screen.getByTestId('order')).toHaveTextContent('["second","first"]'); + + fireEvent.click(screen.getByRole('button', {name: 'Apply'})); + expect(screen.getByTestId('visibility')).toHaveTextContent('{"second":false}'); + expect(screen.getByTestId('order')).toHaveTextContent('["first","second"]'); + }); + + it('discards a reset when the popup is closed without applying', () => { + render( + + + , + ); + const settingsButton = screen.getAllByRole('button')[0]; + fireEvent.click(settingsButton); + fireEvent.click(screen.getByRole('button', {name: 'Reset'})); + fireEvent.click(settingsButton); + fireEvent.click(settingsButton); + fireEvent.click(screen.getByRole('button', {name: 'Apply'})); + + expect(screen.getByTestId('visibility')).toHaveTextContent('{"first":false}'); + expect(screen.getByTestId('order')).toHaveTextContent('["second","first"]'); + }); + + it('shows all columns in definition order when initial state is omitted', () => { + render( + + + , + ); + fireEvent.click(screen.getAllByRole('button')[0]); + fireEvent.click(screen.getByRole('button', {name: 'Reset'})); + fireEvent.click(screen.getByRole('button', {name: 'Apply'})); + + expect(screen.getByTestId('visibility')).toHaveTextContent('{}'); + expect(screen.getByTestId('order')).toHaveTextContent('["first","second"]'); + }); +}); diff --git a/src/components/TableSettings/TableSettings.tsx b/src/components/TableSettings/TableSettings.tsx index ed0677a..267e272 100644 --- a/src/components/TableSettings/TableSettings.tsx +++ b/src/components/TableSettings/TableSettings.tsx @@ -159,6 +159,11 @@ export const TableSettings = ({ setSearch(''); }; + const resetToInitial = () => { + setVisibilityState(table.initialState.columnVisibility ?? {}); + setOrderState(getInitialOrderItems(filteredColumns, table.initialState.columnOrder ?? [])); + }; + const cancelEditing = () => { setOpen(false); resetSettings(); @@ -247,13 +252,16 @@ export const TableSettings = ({ )} - {!emptyResult && ( -
- + -
- )} + + - - - + + + + - - + {!emptyResult && ( + + + + + )}