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

feat(withTableSettings): add a reset action #1526

Merged
merged 7 commits into from
Apr 26, 2024
40 changes: 26 additions & 14 deletions src/components/Table/__stories__/Table.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {Pencil} from '@gravity-ui/icons';
import {action} from '@storybook/addon-actions';
import type {Meta, StoryFn} from '@storybook/react';
import _cloneDeep from 'lodash/cloneDeep';
import _isEqual from 'lodash/isEqual';

import type {TableAction, TableSettingsData} from '..';
import {Icon} from '../../Icon';
Expand Down Expand Up @@ -199,27 +200,17 @@ const WithTableSelectionTemplate: StoryFn<TableProps<DataItem>> = (args) => {
};
export const HOCWithTableSelection = WithTableSelectionTemplate.bind({});

const DEFAULT_SETTINGS = columns.map((x) => ({id: x.id, isSelected: true}));
// ---------------------------------
const WithTableSettingsTemplate: StoryFn<TableProps<DataItem>> = (args, context) => {
const [settings, setSettings] = React.useState<TableSettingsData>(() =>
columns.map((x) => ({id: x.id, isSelected: true})),
);

const updateSettings = React.useCallback(
async (updatedSettings: TableSettingsData) => setSettings(updatedSettings),
[],
);
const [settings, setSettings] = React.useState<TableSettingsData>(DEFAULT_SETTINGS);

if (context.parameters.isFactory) {
return (
<TableWithSettingsFactory
{...args}
settings={settings}
updateSettings={updateSettings}
/>
<TableWithSettingsFactory {...args} settings={settings} updateSettings={setSettings} />
);
} else {
return <TableWithSettings {...args} settings={settings} updateSettings={updateSettings} />;
return <TableWithSettings {...args} settings={settings} updateSettings={setSettings} />;
}
};
export const HOCWithTableSettings = WithTableSettingsTemplate.bind({});
Expand Down Expand Up @@ -251,6 +242,27 @@ HOCWithTableSettingsFactory.parameters = {
disableStrictMode: true,
};

const WithTableSettingsWithResetTemplate: StoryFn<TableProps<DataItem>> = (args) => {
const [settings, setSettings] = React.useState<TableSettingsData>(DEFAULT_SETTINGS);

return (
<TableWithSettings
{...args}
settings={settings}
updateSettings={setSettings}
defaultSettings={DEFAULT_SETTINGS}
showResetButton={!_isEqual(DEFAULT_SETTINGS, settings)}
/>
);
};

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<TableProps<DataItem>> = (args) => {
const settings = React.useMemo(() => {
const newSettings: TableSettingsData = columns.map((x) => ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -265,6 +266,9 @@ export interface TableColumnSetupProps {
renderControls?: RenderControls;

className?: string;

defaultItems?: TableColumnSetupItem[];
showResetButton?: boolean | ((currentItems: TableColumnSetupItem[]) => boolean);
}

export const TableColumnSetup = (props: TableColumnSetupProps) => {
Expand All @@ -277,6 +281,8 @@ export const TableColumnSetup = (props: TableColumnSetupProps) => {
sortable,
renderControls,
className,
defaultItems = propsItems,
showResetButton: propsShowResetButton,
} = props;

const [open, setOpen] = React.useState(false);
Expand Down Expand Up @@ -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}) : <DefaultApplyButton />,
renderControls ? (
renderControls({DefaultApplyButton, onApply})
) : (
<Flex gapRow={1} direction="column" className={controlsCn}>
{showResetButton && (
<Button
onClick={() => {
setItems(defaultItems);
}}
width="max"
>
{i18n('button_reset')}
</Button>
)}
<DefaultApplyButton />
</Flex>
),
});

const dndRenderItem = useDndRenderItem(sortable);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"button_switcher": "Columns",
"button_apply": "Apply"
"button_apply": "Apply",
"button_reset": "Reset",
"button_switcher": "Columns"
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"button_switcher": "Колонки",
"button_apply": "Применить"
"button_apply": "Применить",
"button_reset": "Сбросить",
"button_switcher": "Колонки"
}
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down Expand Up @@ -111,7 +112,7 @@ export interface WithTableSettingsOptions {
sortable?: boolean;
}

export interface WithTableSettingsProps {
interface WithTableSettingsBaseProps {
/**
* @deprecated Use factory notation: "withTableSettings({width: <value>})(Table)"
*/
Expand All @@ -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'];
Expand Down Expand Up @@ -157,8 +177,18 @@ export function withTableSettings<I extends TableDataItem, E extends {} = {}>(
columns,
settingsPopupWidth,
renderControls,
defaultSettings,
showResetButton,
...restTableProps
}: TableProps<I> & 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 || []);

Expand All @@ -182,11 +212,21 @@ export function withTableSettings<I extends TableDataItem, E extends {} = {}>(
</Button>
)}
renderControls={renderControls}
defaultItems={defaultActualItems}
showResetButton={showResetButton}
/>
</div>
);
});
}, [columns, settings, updateSettings, settingsPopupWidth, renderControls]);
}, [
columns,
settings,
settingsPopupWidth,
updateSettings,
renderControls,
defaultActualItems,
showResetButton,
]);

return (
<React.Fragment>
Expand Down
Loading