From 3b1785cc3b050a96f8f4616cde8060cf56d61e0f Mon Sep 17 00:00:00 2001 From: GermanVor Date: Thu, 4 Apr 2024 12:51:58 +0200 Subject: [PATCH 01/15] chore: remove TableColumnSetupItem from export --- src/components/Table/hoc/index.ts | 1 - .../TableColumnSetup/TableColumnSetup.tsx | 7 ++++++- .../Table/hoc/withTableSettings/withTableSettings.tsx | 7 +------ 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/components/Table/hoc/index.ts b/src/components/Table/hoc/index.ts index c280d72514..adaa8132c7 100644 --- a/src/components/Table/hoc/index.ts +++ b/src/components/Table/hoc/index.ts @@ -20,6 +20,5 @@ export {withTableSettings} from './withTableSettings/withTableSettings'; export type { WithTableSettingsProps, TableSettingsData, - TableColumnSetupItem, } from './withTableSettings/withTableSettings'; export * from './withTableSettings/TableColumnSetup/TableColumnSetup'; diff --git a/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx b/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx index a4309e2ec2..e9b1eeaaa7 100644 --- a/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx +++ b/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx @@ -22,7 +22,7 @@ import type { import type {ListItemViewProps} from '../../../../useList'; import {ListContainerView, ListItemView} from '../../../../useList'; import {block} from '../../../../utils/cn'; -import type {TableColumnSetupItem, TableSetting} from '../withTableSettings'; +import type {TableSetting} from '../withTableSettings'; import i18n from './i18n'; @@ -186,6 +186,11 @@ const useDndRenderItem = (sortable: boolean | undefined) => { return renderDndItem; }; +export type TableColumnSetupItem = TableSetting & { + title: React.ReactNode; + isRequired?: boolean; +}; + type Item = TableColumnSetupItem & ListItemViewProps & { id: string; diff --git a/src/components/Table/hoc/withTableSettings/withTableSettings.tsx b/src/components/Table/hoc/withTableSettings/withTableSettings.tsx index 5dde42b076..afdbdcdcc9 100644 --- a/src/components/Table/hoc/withTableSettings/withTableSettings.tsx +++ b/src/components/Table/hoc/withTableSettings/withTableSettings.tsx @@ -16,7 +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 type {RenderControls, TableColumnSetupItem} from './TableColumnSetup/TableColumnSetup'; import i18n from './i18n'; import './withTableSettings.scss'; @@ -28,11 +28,6 @@ export type TableSetting = { export type TableSettingsData = TableSetting[]; -export type TableColumnSetupItem = TableSetting & { - title: React.ReactNode; - isRequired?: boolean; -}; - export function filterColumns( columns: TableColumnConfig[], settings: TableSettingsData, From 4aec3d3a1adeedeea339b5f7808394f658f24a82 Mon Sep 17 00:00:00 2001 From: GermanVor Date: Fri, 5 Apr 2024 18:46:22 +0200 Subject: [PATCH 02/15] feat: new tableColumnSetup with old ableColumnSetupProps --- src/components/Table/hoc/index.ts | 1 - .../TableColumnSetup/TableColumnSetup.scss | 2 +- .../TableColumnSetup/TableColumnSetup.tsx | 16 ++- .../TableColumnSetup/TableColumnSetup.scss | 10 ++ .../TableColumnSetup/TableColumnSetup.tsx | 124 ++++++++++++++++++ src/components/TableColumnSetup/i18n/en.json | 3 + src/components/TableColumnSetup/i18n/index.ts | 8 ++ src/components/TableColumnSetup/i18n/ru.json | 3 + src/components/TableColumnSetup/index.ts | 1 + 9 files changed, 161 insertions(+), 7 deletions(-) create mode 100644 src/components/TableColumnSetup/TableColumnSetup.scss create mode 100644 src/components/TableColumnSetup/TableColumnSetup.tsx create mode 100644 src/components/TableColumnSetup/i18n/en.json create mode 100644 src/components/TableColumnSetup/i18n/index.ts create mode 100644 src/components/TableColumnSetup/i18n/ru.json create mode 100644 src/components/TableColumnSetup/index.ts diff --git a/src/components/Table/hoc/index.ts b/src/components/Table/hoc/index.ts index adaa8132c7..767a609842 100644 --- a/src/components/Table/hoc/index.ts +++ b/src/components/Table/hoc/index.ts @@ -21,4 +21,3 @@ export type { WithTableSettingsProps, TableSettingsData, } from './withTableSettings/withTableSettings'; -export * from './withTableSettings/TableColumnSetup/TableColumnSetup'; diff --git a/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.scss b/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.scss index a9a535280c..003c2f5d69 100644 --- a/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.scss +++ b/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.scss @@ -1,6 +1,6 @@ @use '../../../../variables'; -$block: '.#{variables.$ns}table-column-setup'; +$block: '.#{variables.$ns}inner-table-column-setup'; #{$block} { &__controls { diff --git a/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx b/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx index e9b1eeaaa7..2667858317 100644 --- a/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx +++ b/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx @@ -32,11 +32,14 @@ function identity(value: T): T { return value; } -const b = block('table-column-setup'); -const tableColumnSetupCn = b(null); +const b = block('inner-table-column-setup'); const controlsCn = b('controls'); -const reorderArray = (list: T[], startIndex: number, endIndex: number): T[] => { +const reorderArray = ( + list: T[], + startIndex: number, + endIndex: number, +): T[] => { const result = [...list]; const [removed] = result.splice(startIndex, 1); result.splice(endIndex, 0, removed); @@ -46,7 +49,7 @@ const reorderArray = (list: T[], startIndex: number, endIndex const prepareDndItems = (tableColumnItems: TableColumnSetupItem[]) => { return tableColumnItems.map((tableColumnItem) => { - const hasSelectionIcon = tableColumnItem.isRequired === false; + const hasSelectionIcon = !tableColumnItem.isRequired; return { ...tableColumnItem, @@ -219,6 +222,8 @@ export interface TableColumnSetupProps { * @deprecated */ renderControls?: RenderControls; + + className?: string; } export const TableColumnSetup = (props: TableColumnSetupProps) => { @@ -230,6 +235,7 @@ export const TableColumnSetup = (props: TableColumnSetupProps) => { onUpdate: propsOnUpdate, sortable, renderControls, + className, } = props; const [open, setOpen] = React.useState(false); @@ -307,7 +313,7 @@ export const TableColumnSetup = (props: TableColumnSetupProps) => { return ( ; + onClick: React.MouseEventHandler; +} + +export interface TableColumnSetupProps { + // for Button + disabled?: boolean; + /** + * @deprecated Use renderSwitcher instead + */ + switcher?: React.ReactElement | undefined; + renderSwitcher?: (props: SwitcherProps) => React.ReactElement | undefined; + + items: Item[]; + sortable?: boolean; + + onUpdate: (updated: Item[]) => void; + popupWidth?: number | 'fit' | undefined; + popupPlacement?: PopperPlacement; + getItemTitle?: (item: Item) => TableColumnSetupItem['title']; + showStatus?: boolean; + className?: string; +} + +export const TableColumnSetup = (props: TableColumnSetupProps) => { + const { + switcher, + renderSwitcher: renderSwitcherProps, + disabled, + popupWidth, + popupPlacement, + className, + items: propsItems, + sortable = true, + showStatus, + onUpdate: propsOnUpdate, + } = props; + + const renderStatus = () => { + if (!showStatus) { + return null; + } + + const selected = propsItems.reduce((acc, cur) => (cur.selected ? acc + 1 : acc), 0); + const all = propsItems.length; + const status = `${selected}/${all}`; + + return {status}; + }; + + const renderSwitcher = (switcherProps: SwitcherProps) => { + return ( + renderSwitcherProps?.(switcherProps) || + switcher || ( + + ) + ); + }; + + const items = propsItems.map(({id, title, required, selected}) => ({ + id, + title, + isRequired: required, + isSelected: selected, + })); + + const onUpdate = (newSettings: TableSetting[]) => { + propsOnUpdate( + newSettings.map(({id, isSelected}) => { + const prevItem = propsItems.find((item) => item.id === id); + + return { + id, + selected: isSelected, + title: prevItem?.title, + required: prevItem?.required, + }; + }), + ); + }; + + return ( + + ); +}; diff --git a/src/components/TableColumnSetup/i18n/en.json b/src/components/TableColumnSetup/i18n/en.json new file mode 100644 index 0000000000..933351927b --- /dev/null +++ b/src/components/TableColumnSetup/i18n/en.json @@ -0,0 +1,3 @@ +{ + "button_switcher": "Columns" +} diff --git a/src/components/TableColumnSetup/i18n/index.ts b/src/components/TableColumnSetup/i18n/index.ts new file mode 100644 index 0000000000..820c28b081 --- /dev/null +++ b/src/components/TableColumnSetup/i18n/index.ts @@ -0,0 +1,8 @@ +import {addComponentKeysets} from '../../utils/addComponentKeysets'; + +import en from './en.json'; +import ru from './ru.json'; + +const COMPONENT = 'TableColumnSetup'; + +export default addComponentKeysets({en, ru}, COMPONENT); diff --git a/src/components/TableColumnSetup/i18n/ru.json b/src/components/TableColumnSetup/i18n/ru.json new file mode 100644 index 0000000000..05ed5176f6 --- /dev/null +++ b/src/components/TableColumnSetup/i18n/ru.json @@ -0,0 +1,3 @@ +{ + "button_switcher": "Колонки" +} diff --git a/src/components/TableColumnSetup/index.ts b/src/components/TableColumnSetup/index.ts new file mode 100644 index 0000000000..482ccb159b --- /dev/null +++ b/src/components/TableColumnSetup/index.ts @@ -0,0 +1 @@ +export * from './TableColumnSetup'; From d677d5a4297ceceadaf4f3938ea3ccf5e6abf035 Mon Sep 17 00:00:00 2001 From: GermanVor Date: Sat, 6 Apr 2024 02:59:24 +0200 Subject: [PATCH 03/15] feat: add sticky support for withTableSettings --- .../TableColumnSetup/TableColumnSetup.tsx | 121 ++++++++++++++---- .../withTableSettings/withTableSettings.tsx | 1 + 2 files changed, 97 insertions(+), 25 deletions(-) diff --git a/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx b/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx index 2667858317..f3155e99b2 100644 --- a/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx +++ b/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx @@ -3,11 +3,14 @@ import React from 'react'; import {Gear, Grip, Lock} from '@gravity-ui/icons'; import {DragDropContext, Draggable, Droppable} from 'react-beautiful-dnd'; import type { + DraggableChildrenFn, DraggableProvided, DraggableStateSnapshot, OnDragEndResponder, } from 'react-beautiful-dnd'; +import type {TableColumnConfig} from 'src/components/Table/Table'; + import {useUniqId} from '../../../../../hooks'; import type {PopperPlacement} from '../../../../../hooks/private'; import {createOnKeyDownHandler} from '../../../../../hooks/useActionHandlers/useActionHandlers'; @@ -19,7 +22,7 @@ import type { TreeSelectRenderContainer, TreeSelectRenderItem, } from '../../../../TreeSelect/types'; -import type {ListItemViewProps} from '../../../../useList'; +import type {ListItemType, ListItemViewProps} from '../../../../useList'; import {ListContainerView, ListItemView} from '../../../../useList'; import {block} from '../../../../utils/cn'; import type {TableSetting} from '../withTableSettings'; @@ -52,7 +55,11 @@ const prepareDndItems = (tableColumnItems: TableColumnSetupItem[]) => { const hasSelectionIcon = !tableColumnItem.isRequired; return { - ...tableColumnItem, + id: tableColumnItem.id, + title: tableColumnItem.title, + isRequired: tableColumnItem.isRequired, + isSelected: tableColumnItem.isSelected, + sticky: tableColumnItem.sticky, startSlot: tableColumnItem.isRequired ? : undefined, hasSelectionIcon, selected: hasSelectionIcon ? tableColumnItem.isSelected : undefined, @@ -60,6 +67,48 @@ const prepareDndItems = (tableColumnItems: TableColumnSetupItem[]) => { }); }; +const prepareStikyState = (items: ListItemType[], visibleFlattenIds: string[]) => { + let lastStickyLeftIdx = 0; + for (; lastStickyLeftIdx !== visibleFlattenIds.length; lastStickyLeftIdx++) { + const visibleFlattenId = visibleFlattenIds[lastStickyLeftIdx]; + const item = items.find((item) => item.id === visibleFlattenId) as Item | undefined; + + if (item?.sticky !== 'left' && item?.sticky !== 'start') { + break; + } + } + + let firstStickyRightIdx = visibleFlattenIds.length; + for (; firstStickyRightIdx !== 0; firstStickyRightIdx--) { + const visibleFlattenId = visibleFlattenIds[firstStickyRightIdx - 1]; + const item = items.find((item) => item.id === visibleFlattenId) as Item | undefined; + + if (item?.sticky !== 'right' && item?.sticky !== 'end') { + break; + } + } + + const stickyLeftItemIdList: string[] = []; + for (let i = 0; i < lastStickyLeftIdx; i++) { + const visibleFlattenId = visibleFlattenIds[i]; + stickyLeftItemIdList.push(visibleFlattenId); + } + + const sortableItemIdList: string[] = []; + for (let i = lastStickyLeftIdx; i < firstStickyRightIdx; i++) { + const visibleFlattenId = visibleFlattenIds[i]; + sortableItemIdList.push(visibleFlattenId); + } + + const stickyRightItemIdList: string[] = []; + for (let i = firstStickyRightIdx; i < visibleFlattenIds.length; i++) { + const visibleFlattenId = visibleFlattenIds[i]; + stickyRightItemIdList.push(visibleFlattenId); + } + + return {stickyLeftItemIdList, sortableItemIdList, stickyRightItemIdList}; +}; + const prepareValue = (tableColumnItems: TableColumnSetupItem[]) => { const selectedIds: string[] = []; @@ -73,10 +122,13 @@ const prepareValue = (tableColumnItems: TableColumnSetupItem[]) => { }; interface RenderContainerProps { - provided: DraggableProvided; - snapshot: DraggableStateSnapshot; + isDragDisabled?: boolean; + provided?: DraggableProvided; + snapshot?: DraggableStateSnapshot; } +const RENDER_DRAG_DISABLED_CONTAINER_PROPS: RenderContainerProps = {isDragDisabled: true}; + interface SwitcherProps { onKeyDown: React.KeyboardEventHandler; onClick: React.MouseEventHandler; @@ -92,47 +144,61 @@ const useDndRenderContainer = ({onDragEnd, renderControls}: UseDndRenderContaine const dndRenderContainer: TreeSelectRenderContainer = ({ renderItem, visibleFlattenIds, - items: _items, + items, containerRef, id, className, }) => { - const visibleFlattenItemList = visibleFlattenIds.map((visibleFlattenId, idx) => - renderItem(visibleFlattenId, idx), + const renderDndActiveItem: DraggableChildrenFn = (provided, snapshot, rubric) => { + const renderContainerProps: RenderContainerProps = { + provided, + snapshot, + }; + + return renderItem( + visibleFlattenIds[rubric.source.index], + rubric.source.index, + renderContainerProps, + ); + }; + + const {stickyLeftItemIdList, sortableItemIdList, stickyRightItemIdList} = prepareStikyState( + items, + visibleFlattenIds, ); + const stickyLeftItemList = stickyLeftItemIdList.map((visibleFlattenId, idx) => { + return renderItem(visibleFlattenId, idx, RENDER_DRAG_DISABLED_CONTAINER_PROPS); + }); + + const sortableItemList = sortableItemIdList.map((visibleFlattenId, idx) => { + return renderItem(visibleFlattenId, idx + stickyLeftItemIdList.length); + }); + + const stickyRightItemList = stickyRightItemIdList.map((visibleFlattenId, idx) => { + return renderItem(visibleFlattenId, idx, RENDER_DRAG_DISABLED_CONTAINER_PROPS); + }); + return ( + {stickyLeftItemList} - { - const renderContainerProps: RenderContainerProps = { - provided, - snapshot, - }; - - return renderItem( - visibleFlattenIds[rubric.source.index], - rubric.source.index, - renderContainerProps, - ); - }} - > + {(droppableProvided) => { return (
- {visibleFlattenItemList} + {sortableItemList} {droppableProvided.placeholder}
); }}
+ {stickyRightItemList}
{renderControls()}
@@ -149,7 +215,7 @@ const useDndRenderItem = (sortable: boolean | undefined) => { index, renderContainerProps, }) => { - const isDragDisabled = sortable === false; + const isDragDisabled = sortable === false || renderContainerProps?.isDragDisabled === true; const endSlot = data.endSlot ?? (isDragDisabled ? undefined : ); @@ -160,6 +226,10 @@ const useDndRenderItem = (sortable: boolean | undefined) => { endSlot, }; + if (isDragDisabled) { + return ; + } + const renderItem = (provided: DraggableProvided, snapshot: DraggableStateSnapshot) => ( { /> ); - if (renderContainerProps) { + if (renderContainerProps?.provided && renderContainerProps.snapshot) { return renderItem(renderContainerProps.provided, renderContainerProps.snapshot); } @@ -192,6 +262,7 @@ const useDndRenderItem = (sortable: boolean | undefined) => { export type TableColumnSetupItem = TableSetting & { title: React.ReactNode; isRequired?: boolean; + sticky?: TableColumnConfig['sticky']; }; type Item = TableColumnSetupItem & diff --git a/src/components/Table/hoc/withTableSettings/withTableSettings.tsx b/src/components/Table/hoc/withTableSettings/withTableSettings.tsx index afdbdcdcc9..4af72b02ac 100644 --- a/src/components/Table/hoc/withTableSettings/withTableSettings.tsx +++ b/src/components/Table/hoc/withTableSettings/withTableSettings.tsx @@ -74,6 +74,7 @@ const getTableColumnSetupItem = ( isSelected: isProtected ? true : isSelected, isRequired: isProtected, title: column ? getColumnStringTitle(column) : id, + sticky: column?.sticky, }; }; From 458d8121c3f588fbd5f81aaf189a2c15a6d7d975 Mon Sep 17 00:00:00 2001 From: GermanVor Date: Sat, 6 Apr 2024 03:06:38 +0200 Subject: [PATCH 04/15] chore: new tableColumnSetup with old ableColumnSetupProps --- src/components/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/index.ts b/src/components/index.ts index f1da847a03..8a59a62982 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -42,6 +42,7 @@ export * from './Slider'; export * from './Spin'; export * from './Switch'; export * from './Table'; +export * from './TableColumnSetup'; export * from './Tabs'; export * from './Text'; export * from './Toaster'; From 3a68f6c3d090fc06706d845d5bf39ed8234296d2 Mon Sep 17 00:00:00 2001 From: GermanVor Date: Sat, 6 Apr 2024 03:14:09 +0200 Subject: [PATCH 05/15] chore: absolute import path --- .../withTableSettings/TableColumnSetup/TableColumnSetup.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx b/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx index f3155e99b2..2fe2dee6f9 100644 --- a/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx +++ b/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx @@ -9,8 +9,6 @@ import type { OnDragEndResponder, } from 'react-beautiful-dnd'; -import type {TableColumnConfig} from 'src/components/Table/Table'; - import {useUniqId} from '../../../../../hooks'; import type {PopperPlacement} from '../../../../../hooks/private'; import {createOnKeyDownHandler} from '../../../../../hooks/useActionHandlers/useActionHandlers'; @@ -25,6 +23,7 @@ import type { import type {ListItemType, ListItemViewProps} from '../../../../useList'; import {ListContainerView, ListItemView} from '../../../../useList'; import {block} from '../../../../utils/cn'; +import type {TableColumnConfig} from '../../../Table'; import type {TableSetting} from '../withTableSettings'; import i18n from './i18n'; From 7685c371e4a6fc2cc5254175b33577cea6bec78c Mon Sep 17 00:00:00 2001 From: GermanVor Date: Sat, 6 Apr 2024 03:47:23 +0200 Subject: [PATCH 06/15] chore: fix test --- src/components/Table/__tests__/Table.withTableSettings.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Table/__tests__/Table.withTableSettings.test.tsx b/src/components/Table/__tests__/Table.withTableSettings.test.tsx index 1e0f453d9e..25a35b2e68 100644 --- a/src/components/Table/__tests__/Table.withTableSettings.test.tsx +++ b/src/components/Table/__tests__/Table.withTableSettings.test.tsx @@ -288,7 +288,7 @@ describe('withTableSettings', () => { 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'})); + await userEvent.click(screen.getByRole('button', {name: 'button_apply'})); expect(updateSettings).toHaveBeenCalledWith([ { From 5c2df0933c42d5e5a34c001f4e3d8e05ed9e9a3b Mon Sep 17 00:00:00 2001 From: GermanVor Date: Sat, 6 Apr 2024 17:49:32 +0200 Subject: [PATCH 07/15] chore: itemsById instead items.find --- .../TableColumnSetup/TableColumnSetup.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx b/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx index 2fe2dee6f9..dbaf46db9f 100644 --- a/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx +++ b/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx @@ -20,7 +20,7 @@ import type { TreeSelectRenderContainer, TreeSelectRenderItem, } from '../../../../TreeSelect/types'; -import type {ListItemType, ListItemViewProps} from '../../../../useList'; +import type {ListItemViewProps} from '../../../../useList'; import {ListContainerView, ListItemView} from '../../../../useList'; import {block} from '../../../../utils/cn'; import type {TableColumnConfig} from '../../../Table'; @@ -66,11 +66,11 @@ const prepareDndItems = (tableColumnItems: TableColumnSetupItem[]) => { }); }; -const prepareStikyState = (items: ListItemType[], visibleFlattenIds: string[]) => { +const prepareStikyState = (itemsById: Record, visibleFlattenIds: string[]) => { let lastStickyLeftIdx = 0; for (; lastStickyLeftIdx !== visibleFlattenIds.length; lastStickyLeftIdx++) { const visibleFlattenId = visibleFlattenIds[lastStickyLeftIdx]; - const item = items.find((item) => item.id === visibleFlattenId) as Item | undefined; + const item = itemsById[visibleFlattenId]; if (item?.sticky !== 'left' && item?.sticky !== 'start') { break; @@ -80,7 +80,7 @@ const prepareStikyState = (items: ListItemType[], visibleFlattenIds: strin let firstStickyRightIdx = visibleFlattenIds.length; for (; firstStickyRightIdx !== 0; firstStickyRightIdx--) { const visibleFlattenId = visibleFlattenIds[firstStickyRightIdx - 1]; - const item = items.find((item) => item.id === visibleFlattenId) as Item | undefined; + const item = itemsById[visibleFlattenId]; if (item?.sticky !== 'right' && item?.sticky !== 'end') { break; @@ -143,7 +143,7 @@ const useDndRenderContainer = ({onDragEnd, renderControls}: UseDndRenderContaine const dndRenderContainer: TreeSelectRenderContainer = ({ renderItem, visibleFlattenIds, - items, + itemsById, containerRef, id, className, @@ -162,7 +162,7 @@ const useDndRenderContainer = ({onDragEnd, renderControls}: UseDndRenderContaine }; const {stickyLeftItemIdList, sortableItemIdList, stickyRightItemIdList} = prepareStikyState( - items, + itemsById, visibleFlattenIds, ); From 3e0caca9a531afab41d511b7d005cc5e77c59938 Mon Sep 17 00:00:00 2001 From: GermanVor Date: Sat, 6 Apr 2024 23:55:37 +0200 Subject: [PATCH 08/15] chore: unknown --- .../withTableSettings/TableColumnSetup/TableColumnSetup.tsx | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx b/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx index dbaf46db9f..4dc4e21768 100644 --- a/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx +++ b/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx @@ -37,11 +37,7 @@ function identity(value: T): T { const b = block('inner-table-column-setup'); const controlsCn = b('controls'); -const reorderArray = ( - list: T[], - startIndex: number, - endIndex: number, -): T[] => { +const reorderArray = (list: T[], startIndex: number, endIndex: number): T[] => { const result = [...list]; const [removed] = result.splice(startIndex, 1); result.splice(endIndex, 0, removed); From 260152ea2ccd8bd9327da7622e61d2f85000e799 Mon Sep 17 00:00:00 2001 From: GermanVor Date: Sun, 7 Apr 2024 00:04:04 +0200 Subject: [PATCH 09/15] chore: obsolete words --- .../TableColumnSetup/TableColumnSetup.tsx | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx b/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx index 4dc4e21768..e63a34caf7 100644 --- a/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx +++ b/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx @@ -63,9 +63,9 @@ const prepareDndItems = (tableColumnItems: TableColumnSetupItem[]) => { }; const prepareStikyState = (itemsById: Record, visibleFlattenIds: string[]) => { - let lastStickyLeftIdx = 0; - for (; lastStickyLeftIdx !== visibleFlattenIds.length; lastStickyLeftIdx++) { - const visibleFlattenId = visibleFlattenIds[lastStickyLeftIdx]; + let lastStickyStartIdx = 0; + for (; lastStickyStartIdx !== visibleFlattenIds.length; lastStickyStartIdx++) { + const visibleFlattenId = visibleFlattenIds[lastStickyStartIdx]; const item = itemsById[visibleFlattenId]; if (item?.sticky !== 'left' && item?.sticky !== 'start') { @@ -73,9 +73,9 @@ const prepareStikyState = (itemsById: Record, visibleFlattenIds: s } } - let firstStickyRightIdx = visibleFlattenIds.length; - for (; firstStickyRightIdx !== 0; firstStickyRightIdx--) { - const visibleFlattenId = visibleFlattenIds[firstStickyRightIdx - 1]; + let firstStickyEndIdx = visibleFlattenIds.length; + for (; firstStickyEndIdx !== 0; firstStickyEndIdx--) { + const visibleFlattenId = visibleFlattenIds[firstStickyEndIdx - 1]; const item = itemsById[visibleFlattenId]; if (item?.sticky !== 'right' && item?.sticky !== 'end') { @@ -83,25 +83,25 @@ const prepareStikyState = (itemsById: Record, visibleFlattenIds: s } } - const stickyLeftItemIdList: string[] = []; - for (let i = 0; i < lastStickyLeftIdx; i++) { + const stickyStartItemIdList: string[] = []; + for (let i = 0; i < lastStickyStartIdx; i++) { const visibleFlattenId = visibleFlattenIds[i]; - stickyLeftItemIdList.push(visibleFlattenId); + stickyStartItemIdList.push(visibleFlattenId); } const sortableItemIdList: string[] = []; - for (let i = lastStickyLeftIdx; i < firstStickyRightIdx; i++) { + for (let i = lastStickyStartIdx; i < firstStickyEndIdx; i++) { const visibleFlattenId = visibleFlattenIds[i]; sortableItemIdList.push(visibleFlattenId); } - const stickyRightItemIdList: string[] = []; - for (let i = firstStickyRightIdx; i < visibleFlattenIds.length; i++) { + const stickyEndItemIdList: string[] = []; + for (let i = firstStickyEndIdx; i < visibleFlattenIds.length; i++) { const visibleFlattenId = visibleFlattenIds[i]; - stickyRightItemIdList.push(visibleFlattenId); + stickyEndItemIdList.push(visibleFlattenId); } - return {stickyLeftItemIdList, sortableItemIdList, stickyRightItemIdList}; + return {stickyStartItemIdList, sortableItemIdList, stickyEndItemIdList}; }; const prepareValue = (tableColumnItems: TableColumnSetupItem[]) => { @@ -157,27 +157,27 @@ const useDndRenderContainer = ({onDragEnd, renderControls}: UseDndRenderContaine ); }; - const {stickyLeftItemIdList, sortableItemIdList, stickyRightItemIdList} = prepareStikyState( + const {stickyStartItemIdList, sortableItemIdList, stickyEndItemIdList} = prepareStikyState( itemsById, visibleFlattenIds, ); - const stickyLeftItemList = stickyLeftItemIdList.map((visibleFlattenId, idx) => { + const stickyStartItemList = stickyStartItemIdList.map((visibleFlattenId, idx) => { return renderItem(visibleFlattenId, idx, RENDER_DRAG_DISABLED_CONTAINER_PROPS); }); const sortableItemList = sortableItemIdList.map((visibleFlattenId, idx) => { - return renderItem(visibleFlattenId, idx + stickyLeftItemIdList.length); + return renderItem(visibleFlattenId, idx + stickyStartItemIdList.length); }); - const stickyRightItemList = stickyRightItemIdList.map((visibleFlattenId, idx) => { + const stickyEndItemList = stickyEndItemIdList.map((visibleFlattenId, idx) => { return renderItem(visibleFlattenId, idx, RENDER_DRAG_DISABLED_CONTAINER_PROPS); }); return ( - {stickyLeftItemList} + {stickyStartItemList} {(droppableProvided) => { @@ -193,7 +193,7 @@ const useDndRenderContainer = ({onDragEnd, renderControls}: UseDndRenderContaine }} - {stickyRightItemList} + {stickyEndItemList}
{renderControls()}
From 2c189689e5fa4d3bce9a269091da8ee1dc1d6cba Mon Sep 17 00:00:00 2001 From: GermanVor Date: Sun, 7 Apr 2024 00:12:32 +0200 Subject: [PATCH 10/15] chore: remove fors --- .../TableColumnSetup/TableColumnSetup.tsx | 24 ++++--------------- 1 file changed, 5 insertions(+), 19 deletions(-) diff --git a/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx b/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx index e63a34caf7..bc9dc2c502 100644 --- a/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx +++ b/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx @@ -83,25 +83,11 @@ const prepareStikyState = (itemsById: Record, visibleFlattenIds: s } } - const stickyStartItemIdList: string[] = []; - for (let i = 0; i < lastStickyStartIdx; i++) { - const visibleFlattenId = visibleFlattenIds[i]; - stickyStartItemIdList.push(visibleFlattenId); - } - - const sortableItemIdList: string[] = []; - for (let i = lastStickyStartIdx; i < firstStickyEndIdx; i++) { - const visibleFlattenId = visibleFlattenIds[i]; - sortableItemIdList.push(visibleFlattenId); - } - - const stickyEndItemIdList: string[] = []; - for (let i = firstStickyEndIdx; i < visibleFlattenIds.length; i++) { - const visibleFlattenId = visibleFlattenIds[i]; - stickyEndItemIdList.push(visibleFlattenId); - } - - return {stickyStartItemIdList, sortableItemIdList, stickyEndItemIdList}; + return { + stickyStartItemIdList: visibleFlattenIds.slice(0, lastStickyStartIdx), + sortableItemIdList: visibleFlattenIds.slice(lastStickyStartIdx, firstStickyEndIdx), + stickyEndItemIdList: visibleFlattenIds.slice(firstStickyEndIdx), + }; }; const prepareValue = (tableColumnItems: TableColumnSetupItem[]) => { From ace54b3b7d87cb5833bbe739f5515672e9b76399 Mon Sep 17 00:00:00 2001 From: GermanVor Date: Sun, 7 Apr 2024 00:29:12 +0200 Subject: [PATCH 11/15] chore: add sticky for old TableColumnSetup --- .../TableColumnSetup/TableColumnSetup.tsx | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/components/TableColumnSetup/TableColumnSetup.tsx b/src/components/TableColumnSetup/TableColumnSetup.tsx index f424fd2080..cca38e2fd3 100644 --- a/src/components/TableColumnSetup/TableColumnSetup.tsx +++ b/src/components/TableColumnSetup/TableColumnSetup.tsx @@ -5,7 +5,9 @@ import {Gear} from '@gravity-ui/icons'; import type {PopperPlacement} from '../../hooks/private'; import {Button} from '../Button'; import {Icon} from '../Icon'; -import {TableColumnSetup as TableColumnSetupComponent} from '../Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup'; +import type {TableColumnConfig} from '../Table/Table'; +import type {TableColumnSetupItem as NewTableColumnSetupItem} from '../Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup'; +import {TableColumnSetup as NewTableColumnSetup} from '../Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup'; import type {TableSetting} from '../Table/hoc/withTableSettings/withTableSettings'; import {block} from '../utils/cn'; @@ -20,6 +22,7 @@ export interface TableColumnSetupItem { title: React.ReactNode; selected?: boolean; required?: boolean; + sticky?: TableColumnConfig['sticky']; } type Item = TableColumnSetupItem; @@ -88,12 +91,15 @@ export const TableColumnSetup = (props: TableColumnSetupProps) => { ); }; - const items = propsItems.map(({id, title, required, selected}) => ({ - id, - title, - isRequired: required, - isSelected: selected, - })); + const items = propsItems.map( + ({id, title, required, selected, sticky}) => ({ + id, + title, + isRequired: required, + isSelected: selected, + sticky, + }), + ); const onUpdate = (newSettings: TableSetting[]) => { propsOnUpdate( @@ -111,7 +117,7 @@ export const TableColumnSetup = (props: TableColumnSetupProps) => { }; return ( - Date: Mon, 8 Apr 2024 10:10:28 +0200 Subject: [PATCH 12/15] chore: remove isDragDisabled from Item --- .../hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx b/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx index bc9dc2c502..c0f2ed1d8c 100644 --- a/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx +++ b/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx @@ -249,7 +249,6 @@ export type TableColumnSetupItem = TableSetting & { type Item = TableColumnSetupItem & ListItemViewProps & { id: string; - isDragDisabled?: boolean; }; export type RenderControls = (params: { From be995eb333b3fe6131bd17de02f51ef2d6570436 Mon Sep 17 00:00:00 2001 From: GermanVor Date: Mon, 8 Apr 2024 10:54:09 +0200 Subject: [PATCH 13/15] chore: remove warnings --- .../TableColumnSetup/TableColumnSetup.tsx | 29 ++++++++++++++----- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx b/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx index c0f2ed1d8c..3e4f3fb941 100644 --- a/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx +++ b/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx @@ -30,10 +30,6 @@ import i18n from './i18n'; import './TableColumnSetup.scss'; -function identity(value: T): T { - return value; -} - const b = block('inner-table-column-setup'); const controlsCn = b('controls'); @@ -157,7 +153,11 @@ const useDndRenderContainer = ({onDragEnd, renderControls}: UseDndRenderContaine }); const stickyEndItemList = stickyEndItemIdList.map((visibleFlattenId, idx) => { - return renderItem(visibleFlattenId, idx, RENDER_DRAG_DISABLED_CONTAINER_PROPS); + return renderItem( + visibleFlattenId, + idx + sortableItemList.length, + RENDER_DRAG_DISABLED_CONTAINER_PROPS, + ); }); return ( @@ -201,9 +201,11 @@ const useDndRenderItem = (sortable: boolean | undefined) => { const endSlot = data.endSlot ?? (isDragDisabled ? undefined : ); - const commonProps = { + const {isRequired: _isRequired, isSelected: _isSelected, ...itemViewPropsFromData} = data; + + const commonProps: ListItemViewProps = { ...props, - ...data, + ...itemViewPropsFromData, endSlot, }; @@ -218,6 +220,7 @@ const useDndRenderItem = (sortable: boolean | undefined) => { {...provided.dragHandleProps} ref={provided.innerRef} dragging={snapshot.isDragging} + key={commonProps.id} /> ); @@ -251,6 +254,16 @@ type Item = TableColumnSetupItem & id: string; }; +const mapItemDataToProps = (item: Item) => { + return { + id: item.id, + title: item.title, + startSlot: item.isRequired ? : undefined, + hasSelectionIcon: !item.isRequired, + selected: item.selected, + }; +}; + export type RenderControls = (params: { DefaultApplyButton: React.ComponentType; /** @@ -365,7 +378,7 @@ export const TableColumnSetup = (props: TableColumnSetupProps) => { return ( Date: Mon, 8 Apr 2024 13:00:12 +0200 Subject: [PATCH 14/15] chore: remove prepareDndItems --- .../TableColumnSetup/TableColumnSetup.tsx | 70 ++++++------------- 1 file changed, 22 insertions(+), 48 deletions(-) diff --git a/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx b/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx index 3e4f3fb941..2f82359f96 100644 --- a/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx +++ b/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx @@ -20,7 +20,7 @@ import type { TreeSelectRenderContainer, TreeSelectRenderItem, } from '../../../../TreeSelect/types'; -import type {ListItemViewProps} from '../../../../useList'; +import type {ListItemCommonProps, ListItemViewProps} from '../../../../useList'; import {ListContainerView, ListItemView} from '../../../../useList'; import {block} from '../../../../utils/cn'; import type {TableColumnConfig} from '../../../Table'; @@ -41,24 +41,10 @@ const reorderArray = (list: T[], startIndex: number, endIndex return result; }; -const prepareDndItems = (tableColumnItems: TableColumnSetupItem[]) => { - return tableColumnItems.map((tableColumnItem) => { - const hasSelectionIcon = !tableColumnItem.isRequired; - - return { - id: tableColumnItem.id, - title: tableColumnItem.title, - isRequired: tableColumnItem.isRequired, - isSelected: tableColumnItem.isSelected, - sticky: tableColumnItem.sticky, - startSlot: tableColumnItem.isRequired ? : undefined, - hasSelectionIcon, - selected: hasSelectionIcon ? tableColumnItem.isSelected : undefined, - }; - }); -}; - -const prepareStikyState = (itemsById: Record, visibleFlattenIds: string[]) => { +const prepareStikyState = ( + itemsById: Record, + visibleFlattenIds: string[], +) => { let lastStickyStartIdx = 0; for (; lastStickyStartIdx !== visibleFlattenIds.length; lastStickyStartIdx++) { const visibleFlattenId = visibleFlattenIds[lastStickyStartIdx]; @@ -118,7 +104,7 @@ interface UseDndRenderContainerParams { const useDndRenderContainer = ({onDragEnd, renderControls}: UseDndRenderContainerParams) => { const uniqId = useUniqId(); - const dndRenderContainer: TreeSelectRenderContainer = ({ + const dndRenderContainer: TreeSelectRenderContainer = ({ renderItem, visibleFlattenIds, itemsById, @@ -155,7 +141,7 @@ const useDndRenderContainer = ({onDragEnd, renderControls}: UseDndRenderContaine const stickyEndItemList = stickyEndItemIdList.map((visibleFlattenId, idx) => { return renderItem( visibleFlattenId, - idx + sortableItemList.length, + stickyStartItemList.length + sortableItemList.length + idx, RENDER_DRAG_DISABLED_CONTAINER_PROPS, ); }); @@ -190,27 +176,28 @@ const useDndRenderContainer = ({onDragEnd, renderControls}: UseDndRenderContaine }; const useDndRenderItem = (sortable: boolean | undefined) => { - const renderDndItem: TreeSelectRenderItem = ({ - data, + const renderDndItem: TreeSelectRenderItem = ({ + data: item, props, index, renderContainerProps, }) => { const isDragDisabled = sortable === false || renderContainerProps?.isDragDisabled === true; - - const endSlot = - data.endSlot ?? (isDragDisabled ? undefined : ); - - const {isRequired: _isRequired, isSelected: _isSelected, ...itemViewPropsFromData} = data; + const endSlot = isDragDisabled ? undefined : ; + const hasSelectionIcon = !item.isRequired; + const startSlot = item.isRequired ? : undefined; + const selected = item.isRequired ? false : props.selected; const commonProps: ListItemViewProps = { ...props, - ...itemViewPropsFromData, + selected, + startSlot, + hasSelectionIcon, endSlot, }; if (isDragDisabled) { - return ; + return ; } const renderItem = (provided: DraggableProvided, snapshot: DraggableStateSnapshot) => ( @@ -220,7 +207,6 @@ const useDndRenderItem = (sortable: boolean | undefined) => { {...provided.dragHandleProps} ref={provided.innerRef} dragging={snapshot.isDragging} - key={commonProps.id} /> ); @@ -230,9 +216,9 @@ const useDndRenderItem = (sortable: boolean | undefined) => { return ( {renderItem} @@ -249,18 +235,9 @@ export type TableColumnSetupItem = TableSetting & { sticky?: TableColumnConfig['sticky']; }; -type Item = TableColumnSetupItem & - ListItemViewProps & { - id: string; - }; - -const mapItemDataToProps = (item: Item) => { +const mapItemDataToProps = (item: TableColumnSetupItem): ListItemCommonProps => { return { - id: item.id, title: item.title, - startSlot: item.isRequired ? : undefined, - hasSelectionIcon: !item.isRequired, - selected: item.selected, }; }; @@ -370,10 +347,7 @@ export const TableColumnSetup = (props: TableColumnSetupProps) => { }); }; - const [value, dndItems] = React.useMemo( - () => [prepareValue(items), prepareDndItems(items)] as const, - [items], - ); + const value = React.useMemo(() => prepareValue(items), [items]); return ( { size="l" open={open} value={value} - items={dndItems} + items={items} onUpdate={onUpdate} popupWidth={popupWidth} onOpenChange={onOpenChange} From 79d33de373c7243a52456037e6c3b4c557884821 Mon Sep 17 00:00:00 2001 From: GermanVor Date: Mon, 8 Apr 2024 16:26:03 +0200 Subject: [PATCH 15/15] chore: prepareStickyState --- .../withTableSettings/TableColumnSetup/TableColumnSetup.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx b/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx index 2f82359f96..4965d10b6f 100644 --- a/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx +++ b/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx @@ -41,7 +41,7 @@ const reorderArray = (list: T[], startIndex: number, endIndex return result; }; -const prepareStikyState = ( +const prepareStickyState = ( itemsById: Record, visibleFlattenIds: string[], ) => { @@ -125,7 +125,7 @@ const useDndRenderContainer = ({onDragEnd, renderControls}: UseDndRenderContaine ); }; - const {stickyStartItemIdList, sortableItemIdList, stickyEndItemIdList} = prepareStikyState( + const {stickyStartItemIdList, sortableItemIdList, stickyEndItemIdList} = prepareStickyState( itemsById, visibleFlattenIds, );