-
-
Notifications
You must be signed in to change notification settings - Fork 72
Issue 591 - Row and column selection with multiple tables #594
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -33,7 +33,7 @@ function deleteRow(idx: number, data: Data, selectedRows: number[]) { | |
| return newProps; | ||
| } | ||
|
|
||
| function rowSelectCell(idx: number, rowSelectable: Selection, selectedRows: number[], setProps: SetProps, data: Data) { | ||
| function rowSelectCell(id: string, idx: number, rowSelectable: Selection, selectedRows: number[], setProps: SetProps, data: Data) { | ||
| return (<td | ||
| key='select' | ||
| className='dash-select-cell' | ||
|
|
@@ -42,7 +42,7 @@ function rowSelectCell(idx: number, rowSelectable: Selection, selectedRows: numb | |
| <input | ||
| type={rowSelectable === 'single' ? 'radio' : 'checkbox'} | ||
| style={{ verticalAlign: 'middle' }} | ||
| name='row-select' | ||
| name={`row-select-${id}`} | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use the table's id to make the group unique |
||
| checked={R.includes(idx, selectedRows)} | ||
| onChange={() => { | ||
| const newSelectedRows = rowSelectable === 'single' ? | ||
|
|
@@ -73,6 +73,7 @@ function rowDeleteCell(doDelete: () => any) { | |
| } | ||
|
|
||
| const getter = ( | ||
| id: string, | ||
| data: Data, | ||
| viewportData: Data, | ||
| viewportIndices: Indices, | ||
|
|
@@ -83,7 +84,7 @@ const getter = ( | |
| ): JSX.Element[][] => R.addIndex<Datum, JSX.Element[]>(R.map)( | ||
| (_, rowIndex) => [ | ||
| ...(rowDeletable ? [rowDeleteCell(() => setProps(deleteRow(viewportIndices[rowIndex], data, selectedRows)))] : []), | ||
| ...(rowSelectable ? [rowSelectCell(viewportIndices[rowIndex], rowSelectable, selectedRows, setProps, data)] : []) | ||
| ...(rowSelectable ? [rowSelectCell(id, viewportIndices[rowIndex], rowSelectable, selectedRows, setProps, data)] : []) | ||
| ], | ||
| viewportData | ||
| ); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -150,6 +150,7 @@ function getSortingIcon(columnId: ColumnId, sortBy: SortBy) { | |
| } | ||
|
|
||
| function getter( | ||
| id: string, | ||
| visibleColumns: Columns, | ||
| columns: Columns, | ||
| hiddenColumns: string[] | undefined, | ||
|
|
@@ -230,7 +231,7 @@ function getter( | |
| column_selectable === 'single', | ||
| !allSelected | ||
| )} | ||
| name='column-header--select' | ||
| name={`column-select-${id}`} | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use the table's id to make the group unique |
||
| type={column_selectable === 'single' ? | ||
| 'radio' : | ||
| 'checkbox' | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -19,104 +19,200 @@ const getSelector = (state: State) => { | |
| } | ||
| }; | ||
|
|
||
| export default class DashTable { | ||
| static getCell(row: number, column: number, editable: State = State.Ready) { | ||
| return cy.get(`#table ${getSelector(editable)} tbody tr td.column-${column}`).eq(row); | ||
| export class DashTableHelper { | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Generalize the helper to work for multiple tables - Leaving the static implementation below for existing tests |
||
| constructor(private readonly id) { | ||
|
|
||
| } | ||
|
|
||
| public getCell(row: number, column: number, editable: State = State.Ready) { | ||
| return cy.get(`#${this.id} ${getSelector(editable)} tbody tr td.column-${column}`).eq(row); | ||
| } | ||
|
|
||
| static getCellById(row: number, column: string, editable: State = State.Ready) { | ||
| return cy.get(`#table ${getSelector(editable)} tbody tr td[data-dash-column="${column}"]`).eq(row); | ||
| public getCellById(row: number, column: string, editable: State = State.Ready) { | ||
| return cy.get(`#${this.id} ${getSelector(editable)} tbody tr td[data-dash-column="${column}"]`).eq(row); | ||
| } | ||
|
|
||
| static getFilter(column: number, editable: State = State.Ready) { | ||
| return cy.get(`#table ${getSelector(editable)} tbody tr th.dash-filter.column-${column}`); | ||
| public getFilter(column: number, editable: State = State.Ready) { | ||
| return cy.get(`#${this.id} ${getSelector(editable)} tbody tr th.dash-filter.column-${column}`); | ||
| } | ||
|
|
||
| static getFilterById(column: string, editable: State = State.Ready) { | ||
| return cy.get(`#table ${getSelector(editable)} tbody tr th.dash-filter[data-dash-column="${column}"]`); | ||
| public getFilterById(column: string, editable: State = State.Ready) { | ||
| return cy.get(`#${this.id} ${getSelector(editable)} tbody tr th.dash-filter[data-dash-column="${column}"]`); | ||
| } | ||
|
|
||
| static getHeader(row: number, column: number, editable: State = State.Ready) { | ||
| return cy.get(`#table ${getSelector(editable)} tbody tr th.dash-header.column-${column}`).eq(row); | ||
| public getHeader(row: number, column: number, editable: State = State.Ready) { | ||
| return cy.get(`#${this.id} ${getSelector(editable)} tbody tr th.dash-header.column-${column}`).eq(row); | ||
| } | ||
|
|
||
| static getHeaderById(row: number, column: string, editable: State = State.Ready) { | ||
| return cy.get(`#table ${getSelector(editable)} tbody tr th.dash-header[data-dash-column="${column}"]`).eq(row); | ||
| public getHeaderById(row: number, column: string, editable: State = State.Ready) { | ||
| return cy.get(`#${this.id} ${getSelector(editable)} tbody tr th.dash-header[data-dash-column="${column}"]`).eq(row); | ||
| } | ||
|
|
||
| static focusCell(row: number, column: number) { | ||
| public focusCell(row: number, column: number) { | ||
| // somehow we need to scrollIntoView AFTER click, or it doesn't | ||
| // work right. Why? | ||
| return this.getCell(row, column).click().scrollIntoView(); | ||
| } | ||
|
|
||
| static focusCellById(row: number, column: string) { | ||
| public focusCellById(row: number, column: string) { | ||
| return this.getCellById(row, column).click().scrollIntoView(); | ||
| } | ||
|
|
||
| static clearColumnById(row: number, column: string, editable: State = State.Ready) { | ||
| return cy.get(`#table ${getSelector(editable)} tbody tr th.dash-header[data-dash-column="${column}"] .column-header--clear`).eq(row).click(); | ||
| public clearColumnById(row: number, column: string, editable: State = State.Ready) { | ||
| return cy.get(`#${this.id} ${getSelector(editable)} tbody tr th.dash-header[data-dash-column="${column}"] .column-header--clear`).eq(row).click(); | ||
| } | ||
|
|
||
| static deleteColumnById(row: number, column: string, editable: State = State.Ready) { | ||
| return cy.get(`#table ${getSelector(editable)} tbody tr th.dash-header[data-dash-column="${column}"] .column-header--delete`).eq(row).click(); | ||
| public deleteColumnById(row: number, column: string, editable: State = State.Ready) { | ||
| return cy.get(`#${this.id} ${getSelector(editable)} tbody tr th.dash-header[data-dash-column="${column}"] .column-header--delete`).eq(row).click(); | ||
| } | ||
|
|
||
| static hideColumnById(row: number, column: string, editable: State = State.Ready) { | ||
| return cy.get(`#table ${getSelector(editable)} tbody tr th.dash-header[data-dash-column="${column}"] .column-header--hide`).eq(row).click(); | ||
| public hideColumnById(row: number, column: string, editable: State = State.Ready) { | ||
| return cy.get(`#${this.id} ${getSelector(editable)} tbody tr th.dash-header[data-dash-column="${column}"] .column-header--hide`).eq(row).click(); | ||
| } | ||
|
|
||
| static getSelectColumnById(row: number, column: string, editable: State = State.Ready) { | ||
| return cy.get(`#table ${getSelector(editable)} tbody tr th.dash-header[data-dash-column="${column}"] .column-header--select input`).eq(row); | ||
| public getSelectColumnById(row: number, column: string, editable: State = State.Ready) { | ||
| return cy.get(`#${this.id} ${getSelector(editable)} tbody tr th.dash-header[data-dash-column="${column}"] .column-header--select input`).eq(row); | ||
| } | ||
|
|
||
| static selectColumnById(row: number, column: string) { | ||
| return DashTable.getSelectColumnById(row, column).click(); | ||
| public selectColumnById(row: number, column: string) { | ||
| return this.getSelectColumnById(row, column).click(); | ||
| } | ||
|
|
||
| static getDelete(row: number, editable: State = State.Ready) { | ||
| return cy.get(`#table ${getSelector(editable)} tbody tr td.dash-delete-cell`).eq(row); | ||
| public getDelete(row: number, editable: State = State.Ready) { | ||
| return cy.get(`#${this.id} ${getSelector(editable)} tbody tr td.dash-delete-cell`).eq(row); | ||
| } | ||
|
|
||
| static getSelect(row: number, editable: State = State.Ready) { | ||
| return cy.get(`#table ${getSelector(editable)} tbody tr td.dash-select-cell`).eq(row); | ||
| public getSelect(row: number, editable: State = State.Ready) { | ||
| return cy.get(`#${this.id} ${getSelector(editable)} tbody tr td.dash-select-cell`).eq(row); | ||
| } | ||
|
|
||
| static getActiveCell(editable: State = State.Ready) { | ||
| return cy.get(`#table ${getSelector(editable)} tbody td.focused`); | ||
| public getActiveCell(editable: State = State.Ready) { | ||
| return cy.get(`#${this.id} ${getSelector(editable)} tbody td.focused`); | ||
| } | ||
|
|
||
| static getSelectedCells(editable: State = State.Ready) { | ||
| return cy.get(`#table ${getSelector(editable)} tbody td.cell--selected`); | ||
| public getSelectedCells(editable: State = State.Ready) { | ||
| return cy.get(`#${this.id} ${getSelector(editable)} tbody td.cell--selected`); | ||
| } | ||
|
|
||
| static scrollToTop() { | ||
| public scrollToTop() { | ||
| cy.get(`.cell.cell-1-1.dash-fixed-content`).invoke(`outerHeight`).then(height => { | ||
| cy.scrollTo(0, -height); | ||
| }); | ||
| } | ||
|
|
||
| static scrollToBottom() { | ||
| public scrollToBottom() { | ||
| cy.get(`.cell.cell-1-1.dash-fixed-content`).invoke(`outerHeight`).then(height => { | ||
| cy.scrollTo(0, height); | ||
| }); | ||
| } | ||
|
|
||
| static getCellInLastRowOfColumn(column: number) { | ||
| public getCellInLastRowOfColumn(column: number) { | ||
| const cellInLastRow = cy.get(`td.dash-cell.column-${column}`).last().then(elem => { | ||
| const lastRow = elem ? elem.attr(`data-dash-row`) : undefined; | ||
| return lastRow ? cy.get(`td.dash-cell.column-${column}[data-dash-row="${lastRow}"`) : undefined; | ||
| }); | ||
| return cellInLastRow; | ||
| } | ||
|
|
||
| static getCellFromDataDash(row: number, column: number) { | ||
| public getCellFromDataDash(row: number, column: number) { | ||
| return cy.get(`td.column-${column}[data-dash-row="${row}"]`); | ||
| } | ||
|
|
||
| static toggleScroll(toggled: boolean) { | ||
| public toggleScroll(toggled: boolean) { | ||
| cy.get('.row-1').then($el => { | ||
| $el[0].style.overflow = toggled ? '' : 'unset'; | ||
| }); | ||
| } | ||
| } | ||
|
|
||
| export default class DashTable { | ||
| private static __helper = new DashTableHelper('table'); | ||
|
||
|
|
||
| static getCell(_row: number, _column: number, _editable: State = State.Ready) { | ||
| return this.__helper.getCell.apply(this.__helper, Array.from(arguments) as any); | ||
| } | ||
|
|
||
| static getCellById(_row: number, _column: string, _editable: State = State.Ready) { | ||
| return this.__helper.getCellById.apply(this.__helper, Array.from(arguments) as any); | ||
| } | ||
|
|
||
| static getFilter(_column: number, _editable: State = State.Ready) { | ||
| return this.__helper.getFilter.apply(this.__helper, Array.from(arguments) as any); | ||
| } | ||
|
|
||
| static getFilterById(_column: string, _editable: State = State.Ready) { | ||
| return this.__helper.getFilterById.apply(this.__helper, Array.from(arguments) as any); | ||
| } | ||
|
|
||
| static getHeader(_row: number, _column: number, _editable: State = State.Ready) { | ||
| return this.__helper.getHeader.apply(this.__helper, Array.from(arguments) as any); | ||
| } | ||
|
|
||
| static getHeaderById(_row: number, _column: string, _editable: State = State.Ready) { | ||
| return this.__helper.getHeaderById.apply(this.__helper, Array.from(arguments) as any); | ||
| } | ||
|
|
||
| static focusCell(_row: number, _column: number) { | ||
| return this.__helper.focusCell.apply(this.__helper, Array.from(arguments) as any); | ||
| } | ||
|
|
||
| static focusCellById(_row: number, _column: string) { | ||
| return this.__helper.focusCellById.apply(this.__helper, Array.from(arguments) as any); | ||
| } | ||
|
|
||
| static clearColumnById(_row: number, _column: string, _editable: State = State.Ready) { | ||
| return this.__helper.clearColumnById.apply(this.__helper, Array.from(arguments) as any); | ||
| } | ||
|
|
||
| static deleteColumnById(_row: number, _column: string, _editable: State = State.Ready) { | ||
| return this.__helper.deleteColumnById.apply(this.__helper, Array.from(arguments) as any); | ||
| } | ||
|
|
||
| static hideColumnById(_row: number, _column: string, _editable: State = State.Ready) { | ||
| return this.__helper.hideColumnById.apply(this.__helper, Array.from(arguments) as any); | ||
| } | ||
|
|
||
| static getSelectColumnById(_row: number, _column: string, _editable: State = State.Ready) { | ||
| return this.__helper.getSelectColumnById.apply(this.__helper, Array.from(arguments) as any); | ||
| } | ||
|
|
||
| static selectColumnById(_row: number, _column: string) { | ||
| return this.__helper.selectColumnById.apply(this.__helper, Array.from(arguments) as any); | ||
| } | ||
|
|
||
| static getDelete(_row: number, _editable: State = State.Ready) { | ||
| return this.__helper.getDelete.apply(this.__helper, Array.from(arguments) as any); | ||
| } | ||
|
|
||
| static getSelect(_row: number, _editable: State = State.Ready) { | ||
| return this.__helper.getSelect.apply(this.__helper, Array.from(arguments) as any); | ||
| } | ||
|
|
||
| static getActiveCell(_editable: State = State.Ready) { | ||
| return this.__helper.getActiveCell.apply(this.__helper, Array.from(arguments) as any); | ||
| } | ||
|
|
||
| static getSelectedCells(_editable: State = State.Ready) { | ||
| return this.__helper.getSelectedCells.apply(this.__helper, Array.from(arguments) as any); | ||
| } | ||
|
|
||
| static scrollToTop() { | ||
| return this.__helper.scrollToTop.apply(this.__helper, Array.from(arguments) as any); | ||
| } | ||
|
|
||
| static scrollToBottom() { | ||
| return this.__helper.scrollToBottom.apply(this.__helper, Array.from(arguments) as any); | ||
| } | ||
|
|
||
| static getCellInLastRowOfColumn(_column: number) { | ||
| return this.__helper.getCellInLastRowOfColumn.apply(this.__helper, Array.from(arguments) as any); | ||
| } | ||
|
|
||
| static getCellFromDataDash(_row: number, _column: number) { | ||
| return this.__helper.getCellFromDataDash.apply(this.__helper, Array.from(arguments) as any); | ||
| } | ||
|
|
||
| static toggleScroll(_toggled: boolean) { | ||
| return this.__helper.toggleScroll.apply(this.__helper, Array.from(arguments) as any); | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change the 2 tables test behavior so that
idonly if the 1st one has one