diff --git a/app/react/App/styles/globals.css b/app/react/App/styles/globals.css index dc9f825e6f..1d2b1906e4 100644 --- a/app/react/App/styles/globals.css +++ b/app/react/App/styles/globals.css @@ -1704,10 +1704,6 @@ input[type="range"]::-ms-fill-lower { grid-column: span 2 / span 2; } -.float-start { - float: inline-start; -} - .float-right { float: right; } diff --git a/app/react/V2/Components/UI/TableV2/DnDComponents.tsx b/app/react/V2/Components/UI/TableV2/DnDComponents.tsx index bcab8459d7..d50cc6408d 100644 --- a/app/react/V2/Components/UI/TableV2/DnDComponents.tsx +++ b/app/react/V2/Components/UI/TableV2/DnDComponents.tsx @@ -4,7 +4,7 @@ import React, { CSSProperties } from 'react'; import { useSortable } from '@dnd-kit/sortable'; import { CSS } from '@dnd-kit/utilities'; import { flexRender, Row } from '@tanstack/react-table'; -import { t, Translate } from 'app/I18N'; +import { Translate } from 'app/I18N'; import { RowWithId } from './Table'; const RowDragHandleCell = >({ row }: { row: Row }) => { @@ -14,7 +14,6 @@ const RowDragHandleCell = >({ row }: { row: Row }) => const canExpand = row.originalSubRows; const expanded = row.getIsExpanded(); - const parentRow = row.getParentRow(); if (canExpand && expanded && isDragging) { row.toggleExpanded(); @@ -22,13 +21,14 @@ const RowDragHandleCell = >({ row }: { row: Row }) => return ( ); }; const DraggableRow = >({ row }: { row: Row }) => { - const isParent = row.getCanExpand() || row.originalSubRows; const expanded = row.getIsExpanded(); const isEmpty = row.originalSubRows?.length === 0; @@ -84,7 +84,7 @@ const DraggableRow = >({ row }: { row: Row }) => { })} - {isParent && isEmpty && expanded && ( + {isEmpty && expanded && ( dropzone diff --git a/app/react/V2/Components/UI/TableV2/GroupComponents.tsx b/app/react/V2/Components/UI/TableV2/GroupComponents.tsx index 0b27802d2c..b2817a6692 100644 --- a/app/react/V2/Components/UI/TableV2/GroupComponents.tsx +++ b/app/react/V2/Components/UI/TableV2/GroupComponents.tsx @@ -19,8 +19,8 @@ const GroupCell = >({ row }: { row: Row }) => { color="indigo" className="bg-indigo-100 rounded-md border-none drop-shadow-none" > - {`${t('System', 'Open group', null, false)} ${`${row.index + 1}`}`} Group + Open group ) : null; }; diff --git a/app/react/V2/Components/UI/TableV2/Table.tsx b/app/react/V2/Components/UI/TableV2/Table.tsx index b0630d61ba..b350bcc769 100644 --- a/app/react/V2/Components/UI/TableV2/Table.tsx +++ b/app/react/V2/Components/UI/TableV2/Table.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useMemo, useRef, useState } from 'react'; +import React, { useEffect, useMemo, useState } from 'react'; import { useReactTable, getCoreRowModel, @@ -7,6 +7,7 @@ import { getExpandedRowModel, SortingState, getSortedRowModel, + RowSelectionState, } from '@tanstack/react-table'; import { DragEndEvent, @@ -17,14 +18,12 @@ import { useSensors, DndContext, closestCenter, - UniqueIdentifier, } from '@dnd-kit/core'; import { restrictToVerticalAxis } from '@dnd-kit/modifiers'; import { SortableContext, verticalListSortingStrategy } from '@dnd-kit/sortable'; -import { cloneDeep } from 'lodash'; import { DraggableRow, RowDragHandleCell, DnDHeader } from './DnDComponents'; import { IndeterminateCheckboxHeader, IndeterminateCheckboxRow } from './RowSelectComponents'; -import { dndSortHandler, getRowIds, sortHandler } from './helpers'; +import { dndSortHandler, getRowIds } from './helpers'; import { SortingChevrons } from './SortingChevrons'; import { GroupCell, GroupHeader } from './GroupComponents'; @@ -36,10 +35,19 @@ type RowWithId = { type TableProps> = { columns: ColumnDef[]; data: T[]; - setData?: React.Dispatch>; - selectionState?: [state: {}, setter: React.Dispatch>]; + onChange?: ({ + rows, + selectedRows, + sortingState, + }: { + rows: T[]; + selectedRows: RowSelectionState; + sortingState: SortingState; + }) => void; enableDnd?: boolean; + enableSelections?: boolean; defaultSorting?: SortingState; + manualSorting?: boolean; header?: React.ReactNode; footer?: React.ReactNode; className?: string; @@ -48,24 +56,20 @@ type TableProps> = { const Table = >({ columns, data, - setData, - selectionState, + onChange, enableDnd, + enableSelections, defaultSorting, + manualSorting, header, footer, className, }: TableProps) => { - const rowIds = useMemo(() => getRowIds(data), [data]); - const [rowSelection, setRowSelection] = selectionState || [null, null]; + const [dataState, setDataState] = useState(data); + const [rowSelection, setRowSelection] = useState({}); const [sortingState, setSortingState] = useState(defaultSorting || []); - const originalState = useRef([]); - const originalRowIds = useRef<{ id: UniqueIdentifier; parentId?: string }[]>([]); - const disableSortingEffect = useRef(false); - - if (!originalState.current) originalState.current = cloneDeep(data); - if (!originalRowIds.current) originalRowIds.current = [...rowIds]; + const rowIds = useMemo(() => getRowIds(dataState), [dataState]); const memoizedColumns = useMemo[]>(() => { const tableColumns = [...columns]; const hasGroups = data.find(item => item.subRows); @@ -79,7 +83,7 @@ const Table = >({ }); } - if (rowSelection) { + if (enableSelections) { tableColumns.unshift({ id: 'select', header: IndeterminateCheckboxHeader, @@ -98,10 +102,10 @@ const Table = >({ } return tableColumns; - }, [columns, rowSelection, enableDnd]); + }, [columns, data, enableSelections, enableDnd]); const table = useReactTable({ - data, + data: dataState, columns: memoizedColumns, state: { sorting: sortingState, @@ -111,49 +115,45 @@ const Table = >({ getSortedRowModel: getSortedRowModel(), getExpandedRowModel: getExpandedRowModel(), onSortingChange: setSortingState, + manualSorting, getRowId: row => row.rowId, getSubRows: row => row.subRows || undefined, ...(setRowSelection && { enableRowSelection: true, onRowSelectionChange: setRowSelection }), }); useEffect(() => { - originalState.current = cloneDeep(data); - originalRowIds.current = [...rowIds]; - if (setRowSelection) { - setRowSelection({}); - } + setDataState(data); + }, [data]); + + useEffect(() => { + setRowSelection({}); }, [rowIds.length]); useEffect(() => { - if (disableSortingEffect.current) { - disableSortingEffect.current = false; - } else if (setData) { + if (onChange) { + let updatedData = dataState; if (sortingState.length) { - const { rows } = table.getSortedRowModel(); - setData(sortHandler(rows)); - } else { - setData(originalState.current); + updatedData = table.getSortedRowModel().rows.map(row => row.original); } + onChange({ rows: updatedData, selectedRows: rowSelection, sortingState }); } - }, [sortingState]); + }, [dataState, onChange, rowSelection, sortingState, table]); const handleDragEnd = (event: DragEndEvent) => { const { active, over } = event; if (active && over && active.id !== over.id) { - if (setData) { - setData(() => { - let tableRows = data; - if (sortingState.length) { - table.resetSorting(); - tableRows = table.getSortedRowModel().rows.map(row => row.original); - return dndSortHandler(tableRows, rowIds, active.id, over.id); - } - return dndSortHandler(tableRows, rowIds, active.id, over.id); - }); - } + setDataState(() => { + let tableRows = dataState; + if (sortingState.length) { + table.resetSorting(); + tableRows = table.getSortedRowModel().rows.map(row => row.original); + } + return dndSortHandler(tableRows, rowIds, active.id, over.id); + }); } }; + const sensors = useSensors( useSensor(MouseSensor, {}), useSensor(TouchSensor, {}), @@ -166,9 +166,6 @@ const Table = >({ modifiers={[restrictToVerticalAxis]} onDragEnd={handleDragEnd} sensors={sensors} - onDragStart={() => { - disableSortingEffect.current = true; - }} >
diff --git a/app/react/V2/Components/UI/TableV2/helpers.ts b/app/react/V2/Components/UI/TableV2/helpers.ts index 79dee4b77f..18ceec030e 100644 --- a/app/react/V2/Components/UI/TableV2/helpers.ts +++ b/app/react/V2/Components/UI/TableV2/helpers.ts @@ -1,6 +1,5 @@ import { UniqueIdentifier } from '@dnd-kit/core'; import { cloneDeep } from 'lodash'; -import { Row } from '@tanstack/react-table'; import { RowWithId, TableProps } from './Table'; const getRowIds = >(data: TableProps['data']) => { @@ -75,13 +74,4 @@ const dndSortHandler = >( return state; }; -const sortHandler = >(rows: Row[]) => - rows.map(row => { - const { original, subRows } = row; - if (subRows.length) { - original.subRows = subRows.map(subRow => subRow.original); - } - return original; - }); - -export { getRowIds, dndSortHandler, sortHandler }; +export { getRowIds, dndSortHandler }; diff --git a/app/react/V2/Components/UI/specs/Table.cy.tsx b/app/react/V2/Components/UI/specs/Table.cy.tsx index 9dd05ebf83..5e46f77946 100644 --- a/app/react/V2/Components/UI/specs/Table.cy.tsx +++ b/app/react/V2/Components/UI/specs/Table.cy.tsx @@ -27,7 +27,7 @@ describe('Table', () => { }); it('Should return a table with the columns and row specified', () => { - Basic.args.checkboxes = false; + Basic.args.enableSelections = false; Basic.args.enableDnd = false; mount(); const toStrings = (cells: JQuery) => map(cells, 'textContent'); @@ -64,11 +64,12 @@ describe('Table', () => { }); it('Should be sortable by title', () => { - Basic.args.checkboxes = false; + Basic.args.enableSelections = false; Basic.args.enableDnd = false; mount(); cy.get('th').contains('Title').click(); + cy.contains('button', 'Save changes').click(); checkRowContent(1, ['Entity 1', data[1].description, '1']); checkRowContent(2, ['Entity 2', data[0].description, '2']); @@ -92,7 +93,7 @@ describe('Table', () => { }); it('should keep selections when sorting', () => { - Basic.args.checkboxes = true; + Basic.args.enableSelections = true; Basic.args.enableDnd = false; mount(); @@ -103,6 +104,7 @@ describe('Table', () => { // eslint-disable-next-line cypress/unsafe-to-chain-command cy.get('th').contains('Title').click().click(); + cy.contains('button', 'Save changes').click(); cy.get('[data-testid="selected-items"]').within(() => { cy.contains('Entity 2'); @@ -112,10 +114,12 @@ describe('Table', () => { it('should sort items in groups', () => { mount(); - cy.contains('Open group 1').click(); + cy.contains('tr', 'Group 1').within(() => { + cy.contains('button', 'Open group').click(); + }); checkRowContent(1, [ - 'Drag row 1', + 'Drag row', 'Select', 'Group', 'Group 1', @@ -123,7 +127,7 @@ describe('Table', () => { '10', ]); checkRowContent(2, [ - 'Drag row 1-1', + 'Drag row', 'Select', '', 'Sub 1-1', @@ -131,7 +135,7 @@ describe('Table', () => { '5', ]); checkRowContent(3, [ - 'Drag row 1-2', + 'Drag row', 'Select', '', 'Sub 1-2', @@ -139,10 +143,11 @@ describe('Table', () => { '7', ]); + // eslint-disable-next-line cypress/unsafe-to-chain-command cy.get('th').contains('Title').click().click(); checkRowContent(6, [ - 'Drag row 6', + 'Drag row', 'Select', 'Group', 'Group 1', @@ -150,7 +155,7 @@ describe('Table', () => { '10', ]); checkRowContent(7, [ - 'Drag row 6-1', + 'Drag row', 'Select', '', 'Sub 1-2', @@ -158,7 +163,7 @@ describe('Table', () => { '7', ]); checkRowContent(8, [ - 'Drag row 6-2', + 'Drag row', 'Select', '', 'Sub 1-1', @@ -187,7 +192,7 @@ describe('Table', () => { }); it('Should sort the rows with the sorting state specified', () => { - Basic.args.checkboxes = false; + Basic.args.enableSelections = false; Basic.args.enableDnd = false; Basic.args.defaultSorting = [{ id: 'created', desc: false }]; mount(); @@ -199,19 +204,29 @@ describe('Table', () => { it('should reset sorting state when using dnd after sorting', () => { Basic.args.defaultSorting = undefined; - Basic.args.checkboxes = false; + Basic.args.enableSelections = false; Basic.args.enableDnd = true; - mount(); - cy.contains('Open group 1').click(); + + cy.contains('tr', 'Group 1').within(() => { + cy.contains('button', 'Open group').click(); + }); // eslint-disable-next-line cypress/unsafe-to-chain-command cy.get('th').contains('Title').click().click(); + cy.contains('Sorted by title'); + + cy.realDragAndDrop( + cy.get('button[aria-roledescription="sortable"]').eq(6), + cy.get('button[aria-roledescription="sortable"]').eq(2) + ); + + cy.contains('No sorting'); }); }); describe('Selections', () => { beforeEach(() => { - Basic.args.checkboxes = true; + Basic.args.enableSelections = true; Basic.args.enableDnd = true; mount(); cy.contains('Select all').click(); @@ -219,9 +234,10 @@ describe('Table', () => { cy.get('input[type="checkbox"]').eq(0).uncheck(); cy.get('input[type="checkbox"]').eq(2).uncheck(); }); + cy.contains('button', 'Save changes').click(); }); - it('should select and uselect some items', () => { + it('should check the current selections', () => { cy.get('[data-testid="selected-items"]').within(() => { cy.contains('Entity 1'); cy.contains('Entity 2').should('not.exist'); @@ -233,6 +249,7 @@ describe('Table', () => { it('should reset selections when data changes', () => { cy.contains('button', 'Add new item').click(); + cy.contains('button', 'Save changes').click(); cy.get('[data-testid="selected-items"] > div').should('be.empty'); }); }); @@ -247,29 +264,26 @@ describe('Table', () => { }); it('should sort rows by dragging', () => { - cy.contains('button', 'Drag row 2').drag('button:contains("Drag row 1")', { - target: { x: 5, y: 0 }, - force: true, - }); + cy.realDragAndDrop( + cy.get('button[aria-roledescription="sortable"]').eq(1), + cy.get('button[aria-roledescription="sortable"]').eq(0) + ); - cy.get('[data-testid="sorted-items"]').within(() => { - cy.contains('Entity 1 Entity 2 Entity 4 Entity 3 Entity 5'); - }); + cy.realDragAndDrop( + cy.get('button[aria-roledescription="sortable"]').eq(3), + cy.get('button[aria-roledescription="sortable"]').eq(2) + ); - cy.contains('button', 'Drag row 3').drag('button:contains("Drag row 4")', { - target: { x: 5, y: 0 }, - force: true, - }); + checkRowContent(1, ['Drag row', 'Select', 'Entity 1', data[1].description, '1']); + checkRowContent(2, ['Drag row', 'Select', 'Entity 2', data[0].description, '2']); + checkRowContent(3, ['Drag row', 'Select', 'Entity 3', data[3].description, '3']); + checkRowContent(4, ['Drag row', 'Select', 'Entity 4', data[2].description, '4']); + checkRowContent(5, ['Drag row', 'Select', 'Entity 5', data[4].description, '5']); + cy.contains('button', 'Save changes').click(); cy.get('[data-testid="sorted-items"]').within(() => { cy.contains('Entity 1 Entity 2 Entity 3 Entity 4 Entity 5'); }); - - checkRowContent(1, ['Drag row 1', 'Select', 'Entity 1', data[1].description, '1']); - checkRowContent(2, ['Drag row 2', 'Select', 'Entity 2', data[0].description, '2']); - checkRowContent(3, ['Drag row 3', 'Select', 'Entity 3', data[3].description, '3']); - checkRowContent(4, ['Drag row 4', 'Select', 'Entity 4', data[2].description, '4']); - checkRowContent(5, ['Drag row 5', 'Select', 'Entity 5', data[4].description, '5']); }); it('should keep selections while dragging', () => { @@ -278,36 +292,31 @@ describe('Table', () => { cy.get('input[type="checkbox"]').eq(2).check(); }); - cy.contains('button', 'Drag row 2').drag('button:contains("Drag row 1")', { - target: { x: 5, y: 0 }, - force: true, - }); + cy.realDragAndDrop( + cy.get('button[aria-roledescription="sortable"]').eq(1), + cy.get('button[aria-roledescription="sortable"]').eq(0) + ); - cy.contains('button', 'Drag row 3').drag('button:contains("Drag row 4")', { - target: { x: 5, y: 0 }, - force: true, - }); + cy.contains('button', 'Save changes').click(); cy.get('[data-testid="selected-items"]').within(() => { cy.contains('Entity 1').should('not.exist'); cy.contains('Entity 2'); - cy.contains('Entity 3').should('not.exist'); cy.contains('Entity 4'); + cy.contains('Entity 3').should('not.exist'); cy.contains('Entity 5').should('not.exist'); }); - }); - - it('should add an item to an empty group', () => {}); - it('should empty a group by dragging all items out of it', () => {}); - - it('should not loose selections when dragging into a dropzone', () => {}); + cy.get('[data-testid="sorted-items"]').within(() => { + cy.contains('Entity 1 Entity 2 Entity 4 Entity 3 Entity 5'); + }); + }); }); describe('Nested data', () => { beforeEach(() => { Nested.args.enableDnd = true; - Nested.args.checkboxes = true; + Nested.args.enableSelections = true; mount(); }); @@ -316,7 +325,7 @@ describe('Table', () => { cy.contains('Group 1 Group 2 Group 3 Group 4 Item 1 Item 2'); }); checkRowContent(1, [ - 'Drag row 1', + 'Drag row', 'Select', 'Group', 'Group 1', @@ -324,7 +333,7 @@ describe('Table', () => { '10', ]); checkRowContent(2, [ - 'Drag row 2', + 'Drag row', 'Select', 'Group', 'Group 2', @@ -332,7 +341,7 @@ describe('Table', () => { '20', ]); checkRowContent(3, [ - 'Drag row 3', + 'Drag row', 'Select', 'Group', 'Group 3', @@ -340,7 +349,7 @@ describe('Table', () => { '30', ]); checkRowContent(4, [ - 'Drag row 4', + 'Drag row', 'Select', 'Group', 'Group 4', @@ -348,7 +357,7 @@ describe('Table', () => { '40', ]); checkRowContent(5, [ - 'Drag row 5', + 'Drag row', 'Select', undefined, 'Item 1', @@ -356,7 +365,7 @@ describe('Table', () => { '50', ]); checkRowContent(6, [ - 'Drag row 6', + 'Drag row', 'Select', undefined, 'Item 2', @@ -367,9 +376,15 @@ describe('Table', () => { it('should expand groups and check for accessibility', () => { cy.get('tbody').within(() => { - cy.contains('Open group 1').click(); - cy.contains('Open group 2').click(); - cy.contains('Open group 3').click(); + cy.contains('tr', 'Group 1').within(() => { + cy.contains('button', 'Open group').click(); + }); + cy.contains('tr', 'Group 2').within(() => { + cy.contains('button', 'Open group').click(); + }); + cy.contains('tr', 'Group 3').within(() => { + cy.contains('button', 'Open group').click(); + }); cy.contains('td', 'Sub 1-1'); cy.contains('td', 'Sub 1-2'); cy.contains('td', 'Sub 2-1'); @@ -383,29 +398,33 @@ describe('Table', () => { it('should sort children element with dnd', () => { cy.get('tbody').within(() => { - cy.contains('Open group 1').click(); - cy.contains('Open group 3').click(); + cy.contains('tr', 'Group 1').within(() => { + cy.contains('Open group').click(); + }); + cy.contains('tr', 'Group 3').within(() => { + cy.contains('Open group').click(); + }); cy.contains('td', 'Sub 1-1'); cy.contains('td', 'Sub 1-2'); cy.contains('td', 'Sub 3-1'); cy.contains('td', 'Sub 3-2'); }); - cy.contains('button', 'Drag row 3-1').drag('button:contains("Drag row 1-1")', { - target: { x: 5, y: 0 }, - force: true, - }); + cy.realDragAndDrop( + cy.get('button[aria-roledescription="sortable"]').eq(5), + cy.get('button[aria-roledescription="sortable"]').eq(1) + ); checkRowContent(1, [ - 'Drag row 1', + 'Drag row', 'Select', - 'Open group 1', + 'Open group', 'Group 1', dataWithNested[0].description, '10', ]); checkRowContent(2, [ - 'Drag row 1-1', + 'Drag row', 'Select', undefined, 'Sub 3-1', @@ -413,11 +432,108 @@ describe('Table', () => { '12', ]); + cy.contains('button', 'Save changes').click(); + cy.get('[data-testid="sorted-subrows"] > .flex > :nth-child(1)').contains( '|Group 1 - Sub 3-1|' ); }); + it('should add an item to an empty group', () => { + cy.contains('tr', 'Group 4').within(() => { + cy.contains('button', 'Open group').click(); + }); + cy.contains('tr', 'Group 3').within(() => { + cy.contains('button', 'Open group').click(); + }); + + cy.realDragAndDrop( + cy.get('button[aria-roledescription="sortable"]').eq(3), + cy.get('td').contains('dropzone') + ); + + checkRowContent(5, [ + 'Drag row', + 'Select', + 'Open group', + 'Group 4', + dataWithNested[3].description, + '40', + ]); + checkRowContent(6, [ + 'Drag row', + 'Select', + undefined, + 'Sub 3-1', + dataWithNested[2].subRows[0].description, + '12', + ]); + }); + + it('should empty a group by dragging all items out of it', () => { + cy.contains('tr', 'Group 1').within(() => { + cy.contains('button', 'Open group').click(); + }); + + cy.contains('tr', 'dropzone').should('not.exist'); + + cy.realDragAndDrop( + cy.get('button[aria-roledescription="sortable"]').eq(1), + cy.get('button[aria-roledescription="sortable"]').eq(0) + ); + cy.realDragAndDrop( + cy.get('button[aria-roledescription="sortable"]').eq(2), + cy.get('button[aria-roledescription="sortable"]').eq(0) + ); + + cy.contains('tr', 'dropzone').should('exist'); + + cy.realDragAndDrop( + cy.get('button[aria-roledescription="sortable"]').eq(7), + cy.get('td').contains('dropzone') + ); + + checkRowContent(3, [ + 'Drag row', + 'Select', + 'Open group', + 'Group 1', + dataWithNested[0].description, + '10', + ]); + checkRowContent(4, [ + 'Drag row', + 'Select', + undefined, + 'Item 2', + dataWithNested[5].description, + '60', + ]); + + cy.contains('tr', 'dropzone').should('not.exist'); + }); + + it('should not loose selections when dragging into a dropzone', () => { + cy.contains('tr', 'Group 4').within(() => { + cy.contains('button', 'Open group').click(); + }); + + cy.contains('tr', 'Item 2').within(() => { + cy.get('input[type="checkbox"]').check(); + }); + + cy.realDragAndDrop( + cy.get('button[aria-roledescription="sortable"]').eq(5), + cy.get('td').contains('dropzone') + ); + + cy.contains('button', 'Save changes').click(); + + cy.get('[data-testid="selected-items"]').within(() => { + cy.contains('Item 2'); + }); + }); + // xit('should sort an expanded row by the header', () => { // mount(); // cy.contains('children').click(); diff --git a/app/react/stories/TableV2.stories.tsx b/app/react/stories/TableV2.stories.tsx index 7b4aedca13..b963a7efc5 100644 --- a/app/react/stories/TableV2.stories.tsx +++ b/app/react/stories/TableV2.stories.tsx @@ -1,18 +1,18 @@ -import React, { useState } from 'react'; +import React, { useRef, useState } from 'react'; import { Meta, StoryObj } from '@storybook/react'; import { createColumnHelper, SortingState } from '@tanstack/react-table'; import { Provider } from 'react-redux'; -import uniqueID from 'shared/uniqueID'; import { Button, NewTable, NewTableProps } from 'V2/Components/UI'; import { LEGACY_createStore as createStore } from 'V2/shared/testingHelpers'; import { BasicData, DataWithGroups, basicData, dataWithGroups } from './table/fixtures'; type StoryProps = { + columns: NewTableProps['columns']; tableData: any[]; - checkboxes: boolean; enableDnd: boolean; + enableSelections: boolean; defaultSorting: SortingState; - columns: NewTableProps['columns']; + manualSorting: boolean; }; const basicColumnHelper = createColumnHelper(); @@ -35,28 +35,39 @@ const nestedColumns = [ ]; const StoryComponent = ({ - tableData, columns, + tableData, enableDnd, - checkboxes, + enableSelections, defaultSorting, + manualSorting, }: StoryProps) => { const [dataState, setDataState] = useState(tableData); const [selected, setSelected] = useState({}); + const [sorting, setSorting] = useState([]); + const currentDataState = useRef(tableData); + const currentSelections = useRef({}); + const [itemCounter, setItemCounter] = useState(1); return (
{ + currentDataState.current = rows; + currentSelections.current = selectedRows; + setSorting(sortingState); + }} enableDnd={enableDnd} + enableSelections={enableSelections} + manualSorting={manualSorting} header={ -
-

Table heading

+
+

Table heading

+

{sorting.length ? `Sorted by ${sorting[0].id}` : 'No sorting'}

} footer={

My table footer

} @@ -65,28 +76,28 @@ const StoryComponent = ({ - + +

@@ -155,8 +175,9 @@ const Primary: Story = { tableData={args.tableData} columns={args.columns} enableDnd={args.enableDnd} - checkboxes={args.checkboxes} + enableSelections={args.enableSelections} defaultSorting={args.defaultSorting} + manualSorting={args.manualSorting} /> ), @@ -168,8 +189,9 @@ const Basic = { tableData: basicData, columns: basicColumns, enableDnd: true, - checkboxes: true, + enableSelections: true, defaultSorting: undefined, + manualSorting: undefined, }, }; @@ -179,8 +201,9 @@ const Nested = { tableData: dataWithGroups, columns: nestedColumns, enableDnd: true, - checkboxes: true, + enableSelections: true, defaultSorting: undefined, + manualSorting: undefined, }, }; diff --git a/cypress/cypress.d.ts b/cypress/cypress.d.ts index a7b97886ee..05ad829cea 100644 --- a/cypress/cypress.d.ts +++ b/cypress/cypress.d.ts @@ -25,6 +25,7 @@ declare global { } ): Chainable; checkAccessibility(components: React.ReactNode[]); + realDragAndDrop(subject: Chainable, target: Chainable): void; // setCursor(subject: string, options?: Partial): Chainable; // setCursorBefore(subject: string, options?: Partial): Chainable; // setCursorAfter(subject: string, options?: Partial): Chainable; diff --git a/cypress/support/commands.js b/cypress/support/commands.js index c8247e76a5..ceeb03f167 100644 --- a/cypress/support/commands.js +++ b/cypress/support/commands.js @@ -187,4 +187,12 @@ Cypress.Commands.add('blankState', () => { }); }); +Cypress.Commands.add('realDragAndDrop', (subject, target) => { + subject + .realMouseDown({ button: 'left', position: 'center' }) + .realMouseMove(0, 10, { position: 'center' }) + .wait(100); + target.realMouseMove(0, 10, { position: 'center' }).realMouseUp().wait(100); +}); + export {};