From 4ad5eed2af0a5a471b32bb013ad5c94ca23be54f Mon Sep 17 00:00:00 2001 From: Aman Mahajan Date: Mon, 20 Apr 2020 13:59:59 -0500 Subject: [PATCH 01/10] Initial implementation for column reordering --- package.json | 2 + src/DataGrid.tsx | 5 - src/HeaderCell.test.tsx | 18 ---- src/HeaderCell.tsx | 14 --- src/HeaderRow.test.tsx | 8 +- src/HeaderRow.tsx | 4 - src/common/types.ts | 4 +- stories/demos/CellNavigation.tsx | 2 +- stories/demos/ColumnsReordering.tsx | 162 ++++++++++++++++++++++++++++ stories/index.tsx | 4 +- 10 files changed, 171 insertions(+), 52 deletions(-) create mode 100644 stories/demos/ColumnsReordering.tsx diff --git a/package.json b/package.json index f11f6de10d..581dcb20cd 100644 --- a/package.json +++ b/package.json @@ -77,6 +77,8 @@ "mini-css-extract-plugin": "^0.9.0", "react": "^16.13.1", "react-contextmenu": "^2.13.0", + "react-dnd": "^10.0.2", + "react-dnd-html5-backend": "^10.0.2", "react-dom": "^16.13.1", "react-select": "^3.1.0", "react-virtualized": "^9.21.2", diff --git a/src/DataGrid.tsx b/src/DataGrid.tsx index 30cfb81107..521f591f26 100644 --- a/src/DataGrid.tsx +++ b/src/DataGrid.tsx @@ -114,8 +114,6 @@ export interface DataGridProps { rowRenderer?: React.ComponentType>; rowGroupRenderer?: React.ComponentType; emptyRowsView?: React.ComponentType<{}>; - /** Component used to render a draggable header cell */ - draggableHeaderCell?: React.ComponentType<{ column: CalculatedColumn; onHeaderDrop: () => void }>; /** * Event props @@ -126,7 +124,6 @@ export interface DataGridProps { onScroll?: (scrollPosition: ScrollPosition) => void; /** Called when a column is resized */ onColumnResize?: (idx: number, width: number) => void; - onHeaderDrop?: () => void; onRowExpandToggle?: (event: RowExpandToggleEvent) => void; /** Function called whenever selected cell is changed */ onSelectedCellChange?: (position: Position) => void; @@ -427,8 +424,6 @@ function DataGrid({ columns={viewportColumns} onColumnResize={handleColumnResize} lastFrozenColumnIndex={lastFrozenColumnIndex} - draggableHeaderCell={props.draggableHeaderCell} - onHeaderDrop={props.onHeaderDrop} allRowsSelected={selectedRows?.size === rows.length} onSelectedRowsChange={onSelectedRowsChange} sortColumn={props.sortColumn} diff --git a/src/HeaderCell.test.tsx b/src/HeaderCell.test.tsx index 64aa98801a..00fafb3cfc 100644 --- a/src/HeaderCell.test.tsx +++ b/src/HeaderCell.test.tsx @@ -10,10 +10,6 @@ interface Row { } describe('HeaderCell', () => { - function DraggableHeaderCell() { - return
; - } - function setup(overrideProps = {}, columnProps = {}) { const props: HeaderCellProps = { column: { @@ -27,8 +23,6 @@ describe('HeaderCell', () => { }, lastFrozenColumnIndex: -1, onResize: jest.fn(), - onHeaderDrop() { }, - draggableHeaderCell: DraggableHeaderCell, allRowsSelected: false, onAllRowsSelectionChange() {}, ...overrideProps @@ -53,16 +47,4 @@ describe('HeaderCell', () => { expect(props.onResize).toHaveBeenCalledWith(props.column, 200); }); }); - - describe('Render draggableHeaderCell', () => { - it('should not render DraggableHeaderCell when draggable is false', () => { - const { wrapper } = setup({}, { draggable: false }); - expect(wrapper.find(DraggableHeaderCell)).toHaveLength(0); - }); - - it('should not render DraggableHeaderCell when draggable is true', () => { - const { wrapper } = setup({}, { draggable: true }); - expect(wrapper.find(DraggableHeaderCell)).toHaveLength(1); - }); - }); }); diff --git a/src/HeaderCell.tsx b/src/HeaderCell.tsx index 1540a8652d..433856d5de 100644 --- a/src/HeaderCell.tsx +++ b/src/HeaderCell.tsx @@ -10,9 +10,7 @@ type SharedHeaderRowProps = Pick, | 'sortColumn' | 'sortDirection' | 'onSort' - | 'onHeaderDrop' | 'allRowsSelected' - | 'draggableHeaderCell' >; export interface HeaderCellProps extends SharedHeaderRowProps { @@ -78,17 +76,5 @@ export default function HeaderCell({ ); } - const DraggableHeaderCell = props.draggableHeaderCell; - if (column.draggable && DraggableHeaderCell) { - return ( - - {cell} - - ); - } - return cell; } diff --git a/src/HeaderRow.test.tsx b/src/HeaderRow.test.tsx index bdb8e9a021..1c9e9811fc 100644 --- a/src/HeaderRow.test.tsx +++ b/src/HeaderRow.test.tsx @@ -14,9 +14,7 @@ describe('HeaderRow', () => { onColumnResize() { }, onSort: jest.fn(), sortDirection: 'NONE', - allRowsSelected: false, - onHeaderDrop() { }, - draggableHeaderCell: () =>
+ allRowsSelected: false }; const setup = (testProps?: Partial>) => { @@ -77,9 +75,7 @@ describe('HeaderRow', () => { lastFrozenColumnIndex: 1, onSort: jest.fn(), allRowsSelected: false, - onColumnResize: jest.fn(), - onHeaderDrop() { }, - draggableHeaderCell: () =>
+ onColumnResize: jest.fn() }; it('passes classname property', () => { diff --git a/src/HeaderRow.tsx b/src/HeaderRow.tsx index 9764684e54..925486876e 100644 --- a/src/HeaderRow.tsx +++ b/src/HeaderRow.tsx @@ -6,9 +6,7 @@ import { assertIsValidKey } from './utils'; import { DataGridProps } from './DataGrid'; type SharedDataGridProps = Pick, - | 'draggableHeaderCell' | 'rows' - | 'onHeaderDrop' | 'onSelectedRowsChange' | 'sortColumn' | 'sortDirection' @@ -53,10 +51,8 @@ function HeaderRow({ column={column} lastFrozenColumnIndex={props.lastFrozenColumnIndex} onResize={props.onColumnResize} - onHeaderDrop={props.onHeaderDrop} allRowsSelected={props.allRowsSelected} onAllRowsSelectionChange={handleAllRowsSelectionChange} - draggableHeaderCell={props.draggableHeaderCell} onSort={props.onSort} sortColumn={props.sortColumn} sortDirection={props.sortDirection} diff --git a/src/common/types.ts b/src/common/types.ts index 2aeb2a61a6..49fe8de758 100644 --- a/src/common/types.ts +++ b/src/common/types.ts @@ -25,8 +25,6 @@ export interface Column { summaryFormatter?: React.ComponentType>; /** Enables cell editing. If set and no editor property specified, then a textinput will be used as the cell editor */ editable?: boolean | ((row: TRow) => boolean); - /** Enable dragging of a column */ - draggable?: boolean; /** Determines whether column is frozen or not */ frozen?: boolean; /** Enable resizing of a column */ @@ -115,7 +113,7 @@ export interface EditorProps { onOverrideKeyDown: (e: KeyboardEvent) => void; } -export interface HeaderRendererProps { +export interface HeaderRendererProps { column: CalculatedColumn; allRowsSelected: boolean; onAllRowsSelectionChange: (checked: boolean) => void; diff --git a/stories/demos/CellNavigation.tsx b/stories/demos/CellNavigation.tsx index 49a859ca83..89bbc07008 100644 --- a/stories/demos/CellNavigation.tsx +++ b/stories/demos/CellNavigation.tsx @@ -66,7 +66,7 @@ function createRows(): Row[] { return rows; } -export default function ScrollToRow() { +export default function CellNavigation() { const [rows] = useState(createRows); const [cellNavigatioMode, setCellNavigationMode] = useState(CellNavigationMode.CHANGE_ROW); diff --git a/stories/demos/ColumnsReordering.tsx b/stories/demos/ColumnsReordering.tsx new file mode 100644 index 0000000000..16ae2f96cb --- /dev/null +++ b/stories/demos/ColumnsReordering.tsx @@ -0,0 +1,162 @@ +import React, { useState } from 'react'; +import { DndProvider, useDrag, useDrop, DragObjectWithType } from 'react-dnd'; +import Backend from 'react-dnd-html5-backend'; + +import DataGrid, { Column, HeaderRendererProps } from '../../src'; + +function wrapRefs(...refs: React.Ref[]) { + return (handle: T | null) => { + for (const ref of refs) { + if (typeof ref === 'function') { + ref(handle); + } else if (ref !== null) { + // https://github.com/DefinitelyTyped/DefinitelyTyped/issues/31065 + (ref as React.MutableRefObject).current = handle; + } + } + }; +} + +interface Row { + id: number; + task: string; + complete: number; + priority: string; + issueType: string; + startDate: string; + completeDate: string; +} + +interface ColumnDragObject extends DragObjectWithType { + key: string; +} + +function DraggableHeaderRenderer({ onColumnsReorder, ...props }: HeaderRendererProps & { onColumnsReorder: (sourceKey: string, targetKey: string) => void }) { + const [{ isDragging }, drag] = useDrag({ + item: { key: props.column.key, type: 'COLUMN_DRAG' }, + collect: monitor => ({ + isDragging: !!monitor.isDragging() + }) + }); + + const [{ isOver }, drop] = useDrop({ + accept: 'COLUMN_DRAG', + drop({ key, type }: ColumnDragObject) { + if (type === 'COLUMN_DRAG') { + onColumnsReorder(key, props.column.key); + } + }, + collect: monitor => ({ + isOver: !!monitor.isOver(), + canDrop: !!monitor.canDrop() + }) + }); + + return ( +
+ {props.column.name} +
+ ); +} + +function getRandomDate(start: Date, end: Date) { + return new Date(start.getTime() + Math.random() * (end.getTime() - start.getTime())).toLocaleDateString(); +} + +function createRows(): Row[] { + const rows = []; + for (let i = 1; i < 500; i++) { + rows.push({ + id: i, + task: `Task ${i}`, + complete: Math.min(100, Math.round(Math.random() * 110)), + priority: ['Critical', 'High', 'Medium', 'Low'][Math.floor((Math.random() * 3) + 1)], + issueType: ['Bug', 'Improvement', 'Epic', 'Story'][Math.floor((Math.random() * 3) + 1)], + startDate: getRandomDate(new Date(2015, 3, 1), new Date()), + completeDate: getRandomDate(new Date(), new Date(2016, 0, 1)) + }); + } + + return rows; +} + +export default function ColumnsReordering() { + const [rows] = useState(createRows); + const [columns, setColumns] = useState[]>(() => [ + { + key: 'id', + name: 'ID', + width: 80 + }, + { + key: 'task', + name: 'Title', + resizable: true, + headerRenderer: HeaderRenderer + }, + { + key: 'priority', + name: 'Priority', + resizable: true, + headerRenderer: HeaderRenderer + }, + { + key: 'issueType', + name: 'Issue Type', + resizable: true, + headerRenderer: HeaderRenderer + }, + { + key: 'complete', + name: '% Complete', + resizable: true, + headerRenderer: HeaderRenderer + }, + { + key: 'startDate', + name: 'Start Date', + resizable: true, + headerRenderer: HeaderRenderer + }, + { + key: 'completeDate', + name: 'Expected Complete', + width: 200, + resizable: true, + headerRenderer: HeaderRenderer + } + ]); + + function HeaderRenderer(props: HeaderRendererProps) { + return ; + } + + function onColumnsReorder(sourceKey: string, targetKey: string) { + const sourceColumn = columns.find(c => c.key === sourceKey)!; + const targetColumn = columns.find(c => c.key === targetKey)!; + + const reorderedColumns = columns.map(c => { + if (c === sourceColumn) return targetColumn; + if (c === targetColumn) return sourceColumn; + return c; + }); + + setColumns(reorderedColumns); + } + + return ( + + + + ); +} diff --git a/stories/index.tsx b/stories/index.tsx index 53a55abda5..a4659649f4 100644 --- a/stories/index.tsx +++ b/stories/index.tsx @@ -14,6 +14,7 @@ import ContextMenu from './demos/ContextMenu'; import ScrollToRow from './demos/ScrollToRow'; import CellNavigation from './demos/CellNavigation'; import HeaderFilters from './demos/HeaderFilters'; +import ColumnsReordering from './demos/ColumnsReordering'; storiesOf('Demos', module) .add('Common Features', () => ) @@ -25,4 +26,5 @@ storiesOf('Demos', module) .add('Context Menu', () => ) .add('Scroll To Row', () => ) .add('Cell Navigation', () => ) - .add('Header Filters', () => ); + .add('Header Filters', () => ) + .add('Columns Reordering', () => ); From ca7cf30cdd3afbcd4203b3c4da308a301199efa9 Mon Sep 17 00:00:00 2001 From: Aman Mahajan Date: Mon, 20 Apr 2020 14:06:06 -0500 Subject: [PATCH 02/10] Add DraggableHeaderRenderer component --- stories/demos/ColumnsReordering.tsx | 78 +------------------ .../DraggableHeaderRenderer.tsx | 57 ++++++++++++++ .../demos/components/HeaderRenderers/index.ts | 1 + 3 files changed, 61 insertions(+), 75 deletions(-) create mode 100644 stories/demos/components/HeaderRenderers/DraggableHeaderRenderer.tsx create mode 100644 stories/demos/components/HeaderRenderers/index.ts diff --git a/stories/demos/ColumnsReordering.tsx b/stories/demos/ColumnsReordering.tsx index 16ae2f96cb..e07719f63f 100644 --- a/stories/demos/ColumnsReordering.tsx +++ b/stories/demos/ColumnsReordering.tsx @@ -1,73 +1,16 @@ import React, { useState } from 'react'; -import { DndProvider, useDrag, useDrop, DragObjectWithType } from 'react-dnd'; +import { DndProvider } from 'react-dnd'; import Backend from 'react-dnd-html5-backend'; +import { DraggableHeaderRenderer } from './components/HeaderRenderers'; import DataGrid, { Column, HeaderRendererProps } from '../../src'; -function wrapRefs(...refs: React.Ref[]) { - return (handle: T | null) => { - for (const ref of refs) { - if (typeof ref === 'function') { - ref(handle); - } else if (ref !== null) { - // https://github.com/DefinitelyTyped/DefinitelyTyped/issues/31065 - (ref as React.MutableRefObject).current = handle; - } - } - }; -} - interface Row { id: number; task: string; complete: number; priority: string; issueType: string; - startDate: string; - completeDate: string; -} - -interface ColumnDragObject extends DragObjectWithType { - key: string; -} - -function DraggableHeaderRenderer({ onColumnsReorder, ...props }: HeaderRendererProps & { onColumnsReorder: (sourceKey: string, targetKey: string) => void }) { - const [{ isDragging }, drag] = useDrag({ - item: { key: props.column.key, type: 'COLUMN_DRAG' }, - collect: monitor => ({ - isDragging: !!monitor.isDragging() - }) - }); - - const [{ isOver }, drop] = useDrop({ - accept: 'COLUMN_DRAG', - drop({ key, type }: ColumnDragObject) { - if (type === 'COLUMN_DRAG') { - onColumnsReorder(key, props.column.key); - } - }, - collect: monitor => ({ - isOver: !!monitor.isOver(), - canDrop: !!monitor.canDrop() - }) - }); - - return ( -
- {props.column.name} -
- ); -} - -function getRandomDate(start: Date, end: Date) { - return new Date(start.getTime() + Math.random() * (end.getTime() - start.getTime())).toLocaleDateString(); } function createRows(): Row[] { @@ -78,9 +21,7 @@ function createRows(): Row[] { task: `Task ${i}`, complete: Math.min(100, Math.round(Math.random() * 110)), priority: ['Critical', 'High', 'Medium', 'Low'][Math.floor((Math.random() * 3) + 1)], - issueType: ['Bug', 'Improvement', 'Epic', 'Story'][Math.floor((Math.random() * 3) + 1)], - startDate: getRandomDate(new Date(2015, 3, 1), new Date()), - completeDate: getRandomDate(new Date(), new Date(2016, 0, 1)) + issueType: ['Bug', 'Improvement', 'Epic', 'Story'][Math.floor((Math.random() * 3) + 1)] }); } @@ -118,19 +59,6 @@ export default function ColumnsReordering() { name: '% Complete', resizable: true, headerRenderer: HeaderRenderer - }, - { - key: 'startDate', - name: 'Start Date', - resizable: true, - headerRenderer: HeaderRenderer - }, - { - key: 'completeDate', - name: 'Expected Complete', - width: 200, - resizable: true, - headerRenderer: HeaderRenderer } ]); diff --git a/stories/demos/components/HeaderRenderers/DraggableHeaderRenderer.tsx b/stories/demos/components/HeaderRenderers/DraggableHeaderRenderer.tsx new file mode 100644 index 0000000000..5b04c67435 --- /dev/null +++ b/stories/demos/components/HeaderRenderers/DraggableHeaderRenderer.tsx @@ -0,0 +1,57 @@ +import React from 'react'; +import { useDrag, useDrop, DragObjectWithType } from 'react-dnd'; + +import { HeaderRendererProps } from '../../../../src'; + + +interface ColumnDragObject extends DragObjectWithType { + key: string; +} + +function wrapRefs(...refs: React.Ref[]) { + return (handle: T | null) => { + for (const ref of refs) { + if (typeof ref === 'function') { + ref(handle); + } else if (ref !== null) { + // https://github.com/DefinitelyTyped/DefinitelyTyped/issues/31065 + (ref as React.MutableRefObject).current = handle; + } + } + }; +} + +export function DraggableHeaderRenderer({ onColumnsReorder, ...props }: HeaderRendererProps & { onColumnsReorder: (sourceKey: string, targetKey: string) => void }) { + const [{ isDragging }, drag] = useDrag({ + item: { key: props.column.key, type: 'COLUMN_DRAG' }, + collect: monitor => ({ + isDragging: !!monitor.isDragging() + }) + }); + + const [{ isOver }, drop] = useDrop({ + accept: 'COLUMN_DRAG', + drop({ key, type }: ColumnDragObject) { + if (type === 'COLUMN_DRAG') { + onColumnsReorder(key, props.column.key); + } + }, + collect: monitor => ({ + isOver: !!monitor.isOver(), + canDrop: !!monitor.canDrop() + }) + }); + + return ( +
+ {props.column.name} +
+ ); +} diff --git a/stories/demos/components/HeaderRenderers/index.ts b/stories/demos/components/HeaderRenderers/index.ts new file mode 100644 index 0000000000..4f84e87b49 --- /dev/null +++ b/stories/demos/components/HeaderRenderers/index.ts @@ -0,0 +1 @@ +export * from './DraggableHeaderRenderer'; From de55fa7575eb512455909e956b1d4acc9736a00d Mon Sep 17 00:00:00 2001 From: Aman Mahajan Date: Mon, 20 Apr 2020 14:13:02 -0500 Subject: [PATCH 03/10] Add sorting --- stories/demos/ColumnsReordering.tsx | 42 +++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/stories/demos/ColumnsReordering.tsx b/stories/demos/ColumnsReordering.tsx index e07719f63f..dc6c441f55 100644 --- a/stories/demos/ColumnsReordering.tsx +++ b/stories/demos/ColumnsReordering.tsx @@ -1,9 +1,9 @@ -import React, { useState } from 'react'; +import React, { useState, useCallback, useMemo } from 'react'; import { DndProvider } from 'react-dnd'; import Backend from 'react-dnd-html5-backend'; import { DraggableHeaderRenderer } from './components/HeaderRenderers'; -import DataGrid, { Column, HeaderRendererProps } from '../../src'; +import DataGrid, { Column, HeaderRendererProps, SortDirection } from '../../src'; interface Row { id: number; @@ -40,33 +40,58 @@ export default function ColumnsReordering() { key: 'task', name: 'Title', resizable: true, + sortable: true, headerRenderer: HeaderRenderer }, { key: 'priority', name: 'Priority', resizable: true, + sortable: true, headerRenderer: HeaderRenderer }, { key: 'issueType', name: 'Issue Type', resizable: true, + sortable: true, headerRenderer: HeaderRenderer }, { key: 'complete', name: '% Complete', resizable: true, + sortable: true, headerRenderer: HeaderRenderer } ]); + const [[sortColumn, sortDirection], setSort] = useState<[string, SortDirection]>(['task', 'NONE']); + + const sortedRows: readonly Row[] = useMemo(() => { + if (sortDirection === 'NONE') return rows; + + let sortedRows: Row[] = [...rows]; + + switch (sortColumn) { + case 'task': + case 'priority': + case 'issueType': + sortedRows = sortedRows.sort((a, b) => a[sortColumn].localeCompare(b[sortColumn])); + break; + case 'complete': + sortedRows = sortedRows.sort((a, b) => a[sortColumn] - b[sortColumn]); + break; + default: + } + + return sortDirection === 'DESC' ? sortedRows.reverse() : sortedRows; + }, [rows, sortDirection, sortColumn]); function HeaderRenderer(props: HeaderRendererProps) { - return ; + return ; } - function onColumnsReorder(sourceKey: string, targetKey: string) { + function handleColumnsReorder(sourceKey: string, targetKey: string) { const sourceColumn = columns.find(c => c.key === sourceKey)!; const targetColumn = columns.find(c => c.key === targetKey)!; @@ -79,11 +104,18 @@ export default function ColumnsReordering() { setColumns(reorderedColumns); } + const handleSort = useCallback((columnKey: string, direction: SortDirection) => { + setSort([columnKey, direction]); + }, []); + return ( ); From 4ec57ec4f9efdbb3f449e0a8633e330631333195 Mon Sep 17 00:00:00 2001 From: Aman Mahajan Date: Mon, 20 Apr 2020 14:29:30 -0500 Subject: [PATCH 04/10] Fix dragging logic --- stories/demos/ColumnsReordering.tsx | 75 ++++++++++++++++------------- 1 file changed, 41 insertions(+), 34 deletions(-) diff --git a/stories/demos/ColumnsReordering.tsx b/stories/demos/ColumnsReordering.tsx index dc6c441f55..b083130f5a 100644 --- a/stories/demos/ColumnsReordering.tsx +++ b/stories/demos/ColumnsReordering.tsx @@ -28,9 +28,8 @@ function createRows(): Row[] { return rows; } -export default function ColumnsReordering() { - const [rows] = useState(createRows); - const [columns, setColumns] = useState[]>(() => [ +function createColumns(): Column[] { + return [ { key: 'id', name: 'ID', @@ -40,33 +39,62 @@ export default function ColumnsReordering() { key: 'task', name: 'Title', resizable: true, - sortable: true, - headerRenderer: HeaderRenderer + sortable: true }, { key: 'priority', name: 'Priority', resizable: true, - sortable: true, - headerRenderer: HeaderRenderer + sortable: true }, { key: 'issueType', name: 'Issue Type', resizable: true, - sortable: true, - headerRenderer: HeaderRenderer + sortable: true }, { key: 'complete', name: '% Complete', resizable: true, - sortable: true, - headerRenderer: HeaderRenderer + sortable: true } - ]); + ]; +} + +export default function ColumnsReordering() { + const [rows] = useState(createRows); + const [columns, setColumns] = useState(createColumns); const [[sortColumn, sortDirection], setSort] = useState<[string, SortDirection]>(['task', 'NONE']); + const handleSort = useCallback((columnKey: string, direction: SortDirection) => { + setSort([columnKey, direction]); + }, []); + + const draggableColumns = useMemo(() => { + function HeaderRenderer(props: HeaderRendererProps) { + return ; + } + + function handleColumnsReorder(sourceKey: string, targetKey: string) { + const sourceColumn = columns.find(c => c.key === sourceKey)!; + const targetColumn = columns.find(c => c.key === targetKey)!; + + const reorderedColumns = columns.map(c => { + if (c === sourceColumn) return targetColumn; + if (c === targetColumn) return sourceColumn; + return c; + }); + + setColumns(reorderedColumns); + } + + return columns.map(c => { + if (c.key === 'id') return c; + return { ...c, headerRenderer: HeaderRenderer }; + }); + }, [columns]); + const sortedRows: readonly Row[] = useMemo(() => { if (sortDirection === 'NONE') return rows; @@ -87,31 +115,10 @@ export default function ColumnsReordering() { return sortDirection === 'DESC' ? sortedRows.reverse() : sortedRows; }, [rows, sortDirection, sortColumn]); - function HeaderRenderer(props: HeaderRendererProps) { - return ; - } - - function handleColumnsReorder(sourceKey: string, targetKey: string) { - const sourceColumn = columns.find(c => c.key === sourceKey)!; - const targetColumn = columns.find(c => c.key === targetKey)!; - - const reorderedColumns = columns.map(c => { - if (c === sourceColumn) return targetColumn; - if (c === targetColumn) return sourceColumn; - return c; - }); - - setColumns(reorderedColumns); - } - - const handleSort = useCallback((columnKey: string, direction: SortDirection) => { - setSort([columnKey, direction]); - }, []); - return ( Date: Mon, 20 Apr 2020 15:00:21 -0500 Subject: [PATCH 05/10] Update changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 84ef82b468..ec912a3cd1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,6 +36,9 @@ - ⚠️ `onGridKeyDown` - ⚠️ `onGridKeyUp` - ⚠️ `onRowDoubleClick` + - ⚠️ `onHeaderDrop` + - ⚠️ `draggableHeaderCell` + - Check [#2006](https://github.com/adazzle/react-data-grid/pull/2006) on how to migrate - ⚠️ `rowsContainer` - ⚠️ Subrow props: `getSubRowDetails`, `onCellExpand`, `onDeleteSubRow`, and `onAddSubRow` - Check [#1853](https://github.com/adazzle/react-data-grid/pull/1853) on how to migrate @@ -56,6 +59,7 @@ - Check [#1845](https://github.com/adazzle/react-data-grid/pull/1845) on how to migrate - ⚠️ `column.getRowMetaData` - ⚠️ `column.filterable` + - ⚠️ `column.draggable` - ⚠️ `cellRangeSelection.{onStart,onUpdate,onEnd}` - ⚠️ `fromRowId`, `toRowId`, and `fromRowData` from `onRowsUpdate` argument - ⚠️ Stopped exporting `HeaderCell` From 6f5a0e45d1d1e1ff0a08e0cfaafbb6ec13a6146e Mon Sep 17 00:00:00 2001 From: Aman Mahajan Date: Mon, 20 Apr 2020 15:06:14 -0500 Subject: [PATCH 06/10] Cleanup types Co-Authored-By: Nicolas Stepien <567105+nstepien@users.noreply.github.com> --- stories/demos/ColumnsReordering.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stories/demos/ColumnsReordering.tsx b/stories/demos/ColumnsReordering.tsx index b083130f5a..e8453e48e0 100644 --- a/stories/demos/ColumnsReordering.tsx +++ b/stories/demos/ColumnsReordering.tsx @@ -95,7 +95,7 @@ export default function ColumnsReordering() { }); }, [columns]); - const sortedRows: readonly Row[] = useMemo(() => { + const sortedRows = useMemo((): readonly Row[] => { if (sortDirection === 'NONE') return rows; let sortedRows: Row[] = [...rows]; From 9efa51f0ef59f22a401ccb164c86e5f8ca097339 Mon Sep 17 00:00:00 2001 From: Aman Mahajan Date: Mon, 20 Apr 2020 15:06:26 -0500 Subject: [PATCH 07/10] Fix PR number Co-Authored-By: Nicolas Stepien <567105+nstepien@users.noreply.github.com> --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ec912a3cd1..e372036484 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,7 +38,7 @@ - ⚠️ `onRowDoubleClick` - ⚠️ `onHeaderDrop` - ⚠️ `draggableHeaderCell` - - Check [#2006](https://github.com/adazzle/react-data-grid/pull/2006) on how to migrate + - Check [#2007](https://github.com/adazzle/react-data-grid/pull/2007) on how to migrate - ⚠️ `rowsContainer` - ⚠️ Subrow props: `getSubRowDetails`, `onCellExpand`, `onDeleteSubRow`, and `onAddSubRow` - Check [#1853](https://github.com/adazzle/react-data-grid/pull/1853) on how to migrate From a7b3b3ce23d2dc35347a47289ef309e1a9c964ad Mon Sep 17 00:00:00 2001 From: Aman Mahajan Date: Mon, 20 Apr 2020 15:11:10 -0500 Subject: [PATCH 08/10] Address comments --- stories/demos/ColumnsReordering.tsx | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/stories/demos/ColumnsReordering.tsx b/stories/demos/ColumnsReordering.tsx index e8453e48e0..33938884d2 100644 --- a/stories/demos/ColumnsReordering.tsx +++ b/stories/demos/ColumnsReordering.tsx @@ -77,14 +77,16 @@ export default function ColumnsReordering() { } function handleColumnsReorder(sourceKey: string, targetKey: string) { - const sourceColumn = columns.find(c => c.key === sourceKey)!; - const targetColumn = columns.find(c => c.key === targetKey)!; - - const reorderedColumns = columns.map(c => { - if (c === sourceColumn) return targetColumn; - if (c === targetColumn) return sourceColumn; - return c; - }); + const sourceColumnIndex = columns.findIndex(c => c.key === sourceKey)!; + const targetColumnIndex = columns.findIndex(c => c.key === targetKey)!; + + const reorderedColumns = [...columns]; + + reorderedColumns.splice( + targetColumnIndex, + 0, + reorderedColumns.splice(sourceColumnIndex, 1)[0] + ); setColumns(reorderedColumns); } From c3c88f33f89df03c9bd5a535cc5fda4783db3556 Mon Sep 17 00:00:00 2001 From: Aman Mahajan Date: Mon, 20 Apr 2020 15:12:27 -0500 Subject: [PATCH 09/10] Remove extra space --- stories/demos/ColumnsReordering.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/stories/demos/ColumnsReordering.tsx b/stories/demos/ColumnsReordering.tsx index 33938884d2..d1ec792db8 100644 --- a/stories/demos/ColumnsReordering.tsx +++ b/stories/demos/ColumnsReordering.tsx @@ -79,7 +79,6 @@ export default function ColumnsReordering() { function handleColumnsReorder(sourceKey: string, targetKey: string) { const sourceColumnIndex = columns.findIndex(c => c.key === sourceKey)!; const targetColumnIndex = columns.findIndex(c => c.key === targetKey)!; - const reorderedColumns = [...columns]; reorderedColumns.splice( From 962ab8e98c38f92be44d8eec59479d6f9a7f56f8 Mon Sep 17 00:00:00 2001 From: Aman Mahajan Date: Mon, 20 Apr 2020 15:14:48 -0500 Subject: [PATCH 10/10] Remove unnecessary ! Co-Authored-By: Nicolas Stepien <567105+nstepien@users.noreply.github.com> --- stories/demos/ColumnsReordering.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stories/demos/ColumnsReordering.tsx b/stories/demos/ColumnsReordering.tsx index d1ec792db8..782ab71c0e 100644 --- a/stories/demos/ColumnsReordering.tsx +++ b/stories/demos/ColumnsReordering.tsx @@ -77,8 +77,8 @@ export default function ColumnsReordering() { } function handleColumnsReorder(sourceKey: string, targetKey: string) { - const sourceColumnIndex = columns.findIndex(c => c.key === sourceKey)!; - const targetColumnIndex = columns.findIndex(c => c.key === targetKey)!; + const sourceColumnIndex = columns.findIndex(c => c.key === sourceKey); + const targetColumnIndex = columns.findIndex(c => c.key === targetKey); const reorderedColumns = [...columns]; reorderedColumns.splice(