From 8bdf75912dac7dbde624896b1eb671d5e48f6b0e Mon Sep 17 00:00:00 2001 From: ArturAbdullin Date: Fri, 19 Apr 2024 17:00:30 +0300 Subject: [PATCH 1/3] feat(WithTableSettings): add the reset action --- .../Table/__stories__/Table.stories.tsx | 32 ++++++++++++-- .../TableColumnSetup/TableColumnSetup.tsx | 29 +++++++++++- .../TableColumnSetup/i18n/en.json | 5 ++- .../TableColumnSetup/i18n/ru.json | 5 ++- .../withTableSettings/withTableSettings.tsx | 44 ++++++++++++++++++- 5 files changed, 105 insertions(+), 10 deletions(-) diff --git a/src/components/Table/__stories__/Table.stories.tsx b/src/components/Table/__stories__/Table.stories.tsx index 94265433e1..ad28fc8e58 100644 --- a/src/components/Table/__stories__/Table.stories.tsx +++ b/src/components/Table/__stories__/Table.stories.tsx @@ -3,6 +3,7 @@ import React from 'react'; import {Pencil} from '@gravity-ui/icons'; import {action} from '@storybook/addon-actions'; import type {Meta, StoryFn} from '@storybook/react'; +import {isEqual} from 'lodash'; import _cloneDeep from 'lodash/cloneDeep'; import type {TableAction, TableSettingsData} from '..'; @@ -199,11 +200,10 @@ const WithTableSelectionTemplate: StoryFn> = (args) => { }; export const HOCWithTableSelection = WithTableSelectionTemplate.bind({}); +const DEFAULT_SETTINGS = columns.map((x) => ({id: x.id, isSelected: true})); // --------------------------------- const WithTableSettingsTemplate: StoryFn> = (args, context) => { - const [settings, setSettings] = React.useState(() => - columns.map((x) => ({id: x.id, isSelected: true})), - ); + const [settings, setSettings] = React.useState(DEFAULT_SETTINGS); const updateSettings = React.useCallback( async (updatedSettings: TableSettingsData) => setSettings(updatedSettings), @@ -251,6 +251,32 @@ HOCWithTableSettingsFactory.parameters = { disableStrictMode: true, }; +const WithTableSettingsWithResetTemplate: StoryFn> = (args) => { + const [settings, setSettings] = React.useState(DEFAULT_SETTINGS); + + const updateSettings = React.useCallback( + async (updatedSettings: TableSettingsData) => setSettings(updatedSettings), + [], + ); + + return ( + + ); +}; + +export const HOCWithTableSettingsWithReset = WithTableSettingsWithResetTemplate.bind({}); +HOCWithTableSettingsWithReset.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 WithTableSettingsCustomActionsTemplate: StoryFn> = (args) => { const settings = React.useMemo(() => { const newSettings: TableSettingsData = columns.map((x) => ({ diff --git a/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx b/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx index 08c170f7be..4f01d1ffa2 100644 --- a/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx +++ b/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx @@ -20,6 +20,7 @@ import type { TreeSelectRenderContainer, TreeSelectRenderItem, } from '../../../../TreeSelect/types'; +import {Flex} from '../../../../layout/Flex/Flex'; import type {ListItemCommonProps, ListItemViewProps} from '../../../../useList'; import {ListContainerView, ListItemView} from '../../../../useList'; import {block} from '../../../../utils/cn'; @@ -265,6 +266,9 @@ export interface TableColumnSetupProps { renderControls?: RenderControls; className?: string; + + defaultItems?: TableColumnSetupItem[]; + showResetButton?: boolean | ((currentItems: TableColumnSetupItem[]) => boolean); } export const TableColumnSetup = (props: TableColumnSetupProps) => { @@ -277,6 +281,8 @@ export const TableColumnSetup = (props: TableColumnSetupProps) => { sortable, renderControls, className, + defaultItems = propsItems, + showResetButton: propsShowResetButton, } = props; const [open, setOpen] = React.useState(false); @@ -309,10 +315,31 @@ export const TableColumnSetup = (props: TableColumnSetupProps) => { } }; + const showResetButton = + typeof propsShowResetButton === 'function' + ? propsShowResetButton(items) + : propsShowResetButton; + const dndRenderContainer = useDndRenderContainer({ onDragEnd, renderControls: () => - renderControls ? renderControls({DefaultApplyButton, onApply}) : , + renderControls ? ( + renderControls({DefaultApplyButton, onApply}) + ) : ( + + {showResetButton && ( + + )} + + + ), }); const dndRenderItem = useDndRenderItem(sortable); diff --git a/src/components/Table/hoc/withTableSettings/TableColumnSetup/i18n/en.json b/src/components/Table/hoc/withTableSettings/TableColumnSetup/i18n/en.json index 7cfe4b8cb7..2ff8659b5f 100644 --- a/src/components/Table/hoc/withTableSettings/TableColumnSetup/i18n/en.json +++ b/src/components/Table/hoc/withTableSettings/TableColumnSetup/i18n/en.json @@ -1,4 +1,5 @@ { - "button_switcher": "Columns", - "button_apply": "Apply" + "button_apply": "Apply", + "button_reset": "Reset", + "button_switcher": "Columns" } diff --git a/src/components/Table/hoc/withTableSettings/TableColumnSetup/i18n/ru.json b/src/components/Table/hoc/withTableSettings/TableColumnSetup/i18n/ru.json index e216dd735f..8b2daea582 100644 --- a/src/components/Table/hoc/withTableSettings/TableColumnSetup/i18n/ru.json +++ b/src/components/Table/hoc/withTableSettings/TableColumnSetup/i18n/ru.json @@ -1,4 +1,5 @@ { - "button_switcher": "Колонки", - "button_apply": "Применить" + "button_apply": "Применить", + "button_reset": "Сбросить", + "button_switcher": "Колонки" } diff --git a/src/components/Table/hoc/withTableSettings/withTableSettings.tsx b/src/components/Table/hoc/withTableSettings/withTableSettings.tsx index 4af72b02ac..68871c0adf 100644 --- a/src/components/Table/hoc/withTableSettings/withTableSettings.tsx +++ b/src/components/Table/hoc/withTableSettings/withTableSettings.tsx @@ -2,6 +2,7 @@ import React from 'react'; import {Gear} from '@gravity-ui/icons'; import _get from 'lodash/get'; +import _isEqual from 'lodash/isEqual'; import _isString from 'lodash/isString'; import _last from 'lodash/last'; @@ -111,7 +112,7 @@ export interface WithTableSettingsOptions { sortable?: boolean; } -export interface WithTableSettingsProps { +interface WithTableSettingsBaseProps { /** * @deprecated Use factory notation: "withTableSettings({width: })(Table)" */ @@ -126,6 +127,25 @@ export interface WithTableSettingsProps { renderControls?: RenderControls; } +interface WithDefaultSettings { + /** Settings to which you can reset the current settings. */ + defaultSettings: TableSettingsData; + /** + * Display a reset button that resets the current settings changes. + * + * If the `defaultSettings` prop is set then the settings reset to the `defaultSettings`. + */ + showResetButton: boolean; +} + +interface WithoutDefaultSettings { + defaultSettings?: never; + showResetButton?: boolean; +} + +export type WithTableSettingsProps = WithTableSettingsBaseProps & + (WithDefaultSettings | WithoutDefaultSettings); + const b = block('table'); const POPUP_PLACEMENT: PopperPlacement = ['bottom-end', 'bottom', 'top-end', 'top', 'auto']; @@ -157,8 +177,18 @@ export function withTableSettings( columns, settingsPopupWidth, renderControls, + defaultSettings, + showResetButton, ...restTableProps }: TableProps & WithTableSettingsProps & E) { + const defaultActualItems = React.useMemo(() => { + if (!defaultSettings) { + return undefined; + } + + return getActualItems(columns, defaultSettings); + }, [columns, defaultSettings]); + const enhancedColumns = React.useMemo(() => { const actualItems = getActualItems(columns, settings || []); @@ -182,11 +212,21 @@ export function withTableSettings( )} renderControls={renderControls} + defaultItems={defaultActualItems} + showResetButton={showResetButton} /> ); }); - }, [columns, settings, updateSettings, settingsPopupWidth, renderControls]); + }, [ + columns, + settings, + settingsPopupWidth, + updateSettings, + renderControls, + defaultActualItems, + showResetButton, + ]); return ( From d31ad8df89762ef87114135dba5207901418e618 Mon Sep 17 00:00:00 2001 From: ArturAbdullin Date: Fri, 19 Apr 2024 17:03:42 +0300 Subject: [PATCH 2/3] refactor(Table.stories): change the lodash function import form --- src/components/Table/__stories__/Table.stories.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/Table/__stories__/Table.stories.tsx b/src/components/Table/__stories__/Table.stories.tsx index ad28fc8e58..3c9f55d86e 100644 --- a/src/components/Table/__stories__/Table.stories.tsx +++ b/src/components/Table/__stories__/Table.stories.tsx @@ -3,8 +3,8 @@ import React from 'react'; import {Pencil} from '@gravity-ui/icons'; import {action} from '@storybook/addon-actions'; import type {Meta, StoryFn} from '@storybook/react'; -import {isEqual} from 'lodash'; import _cloneDeep from 'lodash/cloneDeep'; +import _isEqual from 'lodash/isEqual'; import type {TableAction, TableSettingsData} from '..'; import {Icon} from '../../Icon'; @@ -265,7 +265,7 @@ const WithTableSettingsWithResetTemplate: StoryFn> = (args) settings={settings} updateSettings={updateSettings} defaultSettings={DEFAULT_SETTINGS} - showResetButton={!isEqual(DEFAULT_SETTINGS, settings)} + showResetButton={!_isEqual(DEFAULT_SETTINGS, settings)} /> ); }; From 61c8c549d05216868f70e125d5a1e5763e236e51 Mon Sep 17 00:00:00 2001 From: ArturAbdullin Date: Thu, 25 Apr 2024 19:03:26 +0300 Subject: [PATCH 3/3] refactor(Table.stories): remove redundant useCallback --- .../Table/__stories__/Table.stories.tsx | 20 +++---------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/src/components/Table/__stories__/Table.stories.tsx b/src/components/Table/__stories__/Table.stories.tsx index 3c9f55d86e..13062ec13f 100644 --- a/src/components/Table/__stories__/Table.stories.tsx +++ b/src/components/Table/__stories__/Table.stories.tsx @@ -205,21 +205,12 @@ const DEFAULT_SETTINGS = columns.map((x) => ({id: x.id, isSelected: true})); const WithTableSettingsTemplate: StoryFn> = (args, context) => { const [settings, setSettings] = React.useState(DEFAULT_SETTINGS); - const updateSettings = React.useCallback( - async (updatedSettings: TableSettingsData) => setSettings(updatedSettings), - [], - ); - if (context.parameters.isFactory) { return ( - + ); } else { - return ; + return ; } }; export const HOCWithTableSettings = WithTableSettingsTemplate.bind({}); @@ -254,16 +245,11 @@ HOCWithTableSettingsFactory.parameters = { const WithTableSettingsWithResetTemplate: StoryFn> = (args) => { const [settings, setSettings] = React.useState(DEFAULT_SETTINGS); - const updateSettings = React.useCallback( - async (updatedSettings: TableSettingsData) => setSettings(updatedSettings), - [], - ); - return (