diff --git a/packages/dash-table/CHANGELOG.md b/packages/dash-table/CHANGELOG.md index 7d0a0d27dc..e80cf74f0b 100644 --- a/packages/dash-table/CHANGELOG.md +++ b/packages/dash-table/CHANGELOG.md @@ -26,9 +26,9 @@ This project adheres to [Semantic Versioning](http://semver.org/). - Additionally clearing the column will reset the filter for the affected column(s) [#318](https://github.com/plotly/dash-table/issues/318) -- Headers are included when copying from the table to different -tabs and elsewhere. They are ignored when copying from the table onto itself and -between two tables within the same tab. +- Headers are included when copying from the table to different +tabs and elsewhere. They are ignored when copying from the table onto itself and +between two tables within the same tab. ### Changed [#497](https://github.com/plotly/dash-table/pull/497) @@ -36,6 +36,9 @@ between two tables within the same tab. reset the filter for the affected column(s) ### Fixed +[#524](https://github.com/plotly/dash-table/issues/524) +- Fixed readonly dropdown cells content (display label, not value) + [#259](https://github.com/plotly/dash-table/issues/259) - Fixed columns `sticky` on Safari diff --git a/packages/dash-table/demo/AppMode.ts b/packages/dash-table/demo/AppMode.ts index 788823a74f..0dd4715aa2 100644 --- a/packages/dash-table/demo/AppMode.ts +++ b/packages/dash-table/demo/AppMode.ts @@ -56,7 +56,14 @@ function getBaseTableProps(mock: IDataMock) { bbb: { clearable: true, options: ['Humid', 'Wet', 'Snowy', 'Tropical Beaches'].map(i => ({ - label: i, + label: `label: ${i}`, + value: i + })) + }, + 'bbb-readonly': { + clearable: true, + options: ['Humid', 'Wet', 'Snowy', 'Tropical Beaches'].map(i => ({ + label: `label: ${i}`, value: i })) } diff --git a/packages/dash-table/demo/data.ts b/packages/dash-table/demo/data.ts index 0b3df6de5a..42f2f13d34 100644 --- a/packages/dash-table/demo/data.ts +++ b/packages/dash-table/demo/data.ts @@ -68,6 +68,7 @@ export const generateMockData = (rows: number) => unpackIntoColumnsAndData([ id: 'bbb-readonly', name: ['', 'Weather', 'Climate-RO'], type: ColumnType.Text, + presentation: 'dropdown', editable: false, data: gendata( i => ['Humid', 'Wet', 'Snowy', 'Tropical Beaches'][i % 4], @@ -86,6 +87,7 @@ export const generateMockData = (rows: number) => unpackIntoColumnsAndData([ id: 'aaa-readonly', name: ['', 'Weather', 'Temperature-RO'], type: ColumnType.Numeric, + presentation: 'dropdown', editable: false, data: gendata(i => i + 1, rows) } diff --git a/packages/dash-table/src/dash-table/derived/cell/contents.tsx b/packages/dash-table/src/dash-table/derived/cell/contents.tsx index 3539546f2c..c521017342 100644 --- a/packages/dash-table/src/dash-table/derived/cell/contents.tsx +++ b/packages/dash-table/src/dash-table/derived/cell/contents.tsx @@ -26,6 +26,7 @@ const mapRow = R.addIndex(R.map); enum CellType { Dropdown, + DropdownLabel, Input, Label } @@ -40,7 +41,7 @@ function getCellType( case Presentation.Input: return (!active || !editable) ? CellType.Label : CellType.Input; case Presentation.Dropdown: - return (!dropdown || !editable) ? CellType.Label : CellType.Dropdown; + return (!dropdown || !editable) ? CellType.DropdownLabel : CellType.Dropdown; default: return (!active || !editable) ? CellType.Label : CellType.Input; } @@ -124,7 +125,9 @@ class Contents { 'dash-cell-value' ].join(' '); - switch (getCellType(active, column.editable, dropdown && dropdown.options, column.presentation)) { + const cellType = getCellType(active, column.editable, dropdown && dropdown.options, column.presentation); + + switch (cellType) { case CellType.Dropdown: return (); + case CellType.DropdownLabel: case CellType.Label: default: + const resolvedValue = cellType === CellType.DropdownLabel ? + this.resolveDropdownLabel(dropdown, datum[column.id]) : + formatters[columnIndex](datum[column.id]); + return (); } } + + private resolveDropdownLabel(dropdown: IDropdown | undefined, value: any) { + const dropdownValue = dropdown && dropdown.options && dropdown.options.find(option => option.value === value); + + return dropdownValue ? dropdownValue.label : value; + } } diff --git a/packages/dash-table/tests/cypress/tests/standalone/filtering_test.ts b/packages/dash-table/tests/cypress/tests/standalone/filtering_test.ts index a6bbb60537..490303d569 100644 --- a/packages/dash-table/tests/cypress/tests/standalone/filtering_test.ts +++ b/packages/dash-table/tests/cypress/tests/standalone/filtering_test.ts @@ -101,7 +101,7 @@ describe('filter', () => { DashTable.getFilterById('ccc').click(); DashTable.getFilterById('bbb').within(() => cy.get('input').should('have.value', 'Tr')); - DashTable.getCellById(0, 'bbb-readonly').within(() => cy.get('.dash-cell-value').should('have.html', 'Tropical Beaches')); + DashTable.getCellById(0, 'bbb-readonly').within(() => cy.get('.dash-cell-value').should('have.html', 'label: Tropical Beaches')); }); it('filters `Numeric` columns with `equal` without operator', () => { diff --git a/packages/dash-table/tests/cypress/tests/standalone/readonly_sorting_test.ts b/packages/dash-table/tests/cypress/tests/standalone/readonly_sorting_test.ts index 716905e9a6..65e7241e35 100644 --- a/packages/dash-table/tests/cypress/tests/standalone/readonly_sorting_test.ts +++ b/packages/dash-table/tests/cypress/tests/standalone/readonly_sorting_test.ts @@ -10,15 +10,25 @@ Object.values([AppMode.ReadOnly]).forEach(mode => { }); it('can sort', () => { - DashTable.getCell(0, 6).within(() => cy.get('.dash-cell-value').should('have.html', 'Wet')); - DashTable.getCell(1, 6).within(() => cy.get('.dash-cell-value').should('have.html', 'Snowy')); - DashTable.getCell(2, 6).within(() => cy.get('.dash-cell-value').should('have.html', 'Tropical Beaches')); - DashTable.getCell(3, 6).within(() => cy.get('.dash-cell-value').should('have.html', 'Humid')); + DashTable.getCell(0, 6).within(() => cy.get('.dash-cell-value').should('have.html', 'label: Wet')); + DashTable.getCell(1, 6).within(() => cy.get('.dash-cell-value').should('have.html', 'label: Snowy')); + DashTable.getCell(2, 6).within(() => cy.get('.dash-cell-value').should('have.html', 'label: Tropical Beaches')); + DashTable.getCell(3, 6).within(() => cy.get('.dash-cell-value').should('have.html', 'label: Humid')); + + DashTable.getCell(0, 7).within(() => cy.get('.dash-cell-value').should('have.html', 'label: Wet')); + DashTable.getCell(1, 7).within(() => cy.get('.dash-cell-value').should('have.html', 'label: Snowy')); + DashTable.getCell(2, 7).within(() => cy.get('.dash-cell-value').should('have.html', 'label: Tropical Beaches')); + DashTable.getCell(3, 7).within(() => cy.get('.dash-cell-value').should('have.html', 'label: Humid')); cy.get('tr th.column-6 .sort').last().click(); - DashTable.getCell(0, 6).within(() => cy.get('.dash-cell-value').should('have.html', 'Humid')); - DashTable.getCell(1, 6).within(() => cy.get('.dash-cell-value').should('have.html', 'Humid')); - DashTable.getCell(2, 6).within(() => cy.get('.dash-cell-value').should('have.html', 'Humid')); - DashTable.getCell(3, 6).within(() => cy.get('.dash-cell-value').should('have.html', 'Humid')); + DashTable.getCell(0, 6).within(() => cy.get('.dash-cell-value').should('have.html', 'label: Humid')); + DashTable.getCell(1, 6).within(() => cy.get('.dash-cell-value').should('have.html', 'label: Humid')); + DashTable.getCell(2, 6).within(() => cy.get('.dash-cell-value').should('have.html', 'label: Humid')); + DashTable.getCell(3, 6).within(() => cy.get('.dash-cell-value').should('have.html', 'label: Humid')); + + DashTable.getCell(0, 7).within(() => cy.get('.dash-cell-value').should('have.html', 'label: Humid')); + DashTable.getCell(1, 7).within(() => cy.get('.dash-cell-value').should('have.html', 'label: Humid')); + DashTable.getCell(2, 7).within(() => cy.get('.dash-cell-value').should('have.html', 'label: Humid')); + DashTable.getCell(3, 7).within(() => cy.get('.dash-cell-value').should('have.html', 'label: Humid')); }); }); }); \ No newline at end of file diff --git a/packages/dash-table/tests/cypress/tests/standalone/readwrite_sorting_test.ts b/packages/dash-table/tests/cypress/tests/standalone/readwrite_sorting_test.ts index ce53b99d14..3a21e18cc1 100644 --- a/packages/dash-table/tests/cypress/tests/standalone/readwrite_sorting_test.ts +++ b/packages/dash-table/tests/cypress/tests/standalone/readwrite_sorting_test.ts @@ -10,15 +10,25 @@ Object.values(ReadWriteModes).forEach(mode => { }); it('can sort', () => { - DashTable.getCell(0, 6).within(() => cy.get('.Select-value-label').should('have.html', 'Wet')); - DashTable.getCell(1, 6).within(() => cy.get('.Select-value-label').should('have.html', 'Snowy')); - DashTable.getCell(2, 6).within(() => cy.get('.Select-value-label').should('have.html', 'Tropical Beaches')); - DashTable.getCell(3, 6).within(() => cy.get('.Select-value-label').should('have.html', 'Humid')); + DashTable.getCell(0, 6).within(() => cy.get('.Select-value-label').should('have.html', 'label: Wet')); + DashTable.getCell(1, 6).within(() => cy.get('.Select-value-label').should('have.html', 'label: Snowy')); + DashTable.getCell(2, 6).within(() => cy.get('.Select-value-label').should('have.html', 'label: Tropical Beaches')); + DashTable.getCell(3, 6).within(() => cy.get('.Select-value-label').should('have.html', 'label: Humid')); + + DashTable.getCell(0, 7).within(() => cy.get('.dash-cell-value').should('have.html', 'label: Wet')); + DashTable.getCell(1, 7).within(() => cy.get('.dash-cell-value').should('have.html', 'label: Snowy')); + DashTable.getCell(2, 7).within(() => cy.get('.dash-cell-value').should('have.html', 'label: Tropical Beaches')); + DashTable.getCell(3, 7).within(() => cy.get('.dash-cell-value').should('have.html', 'label: Humid')); cy.get('tr th.column-6 .sort').last().click(); - DashTable.getCell(0, 6).within(() => cy.get('.Select-value-label').should('have.html', 'Humid')); - DashTable.getCell(1, 6).within(() => cy.get('.Select-value-label').should('have.html', 'Humid')); - DashTable.getCell(2, 6).within(() => cy.get('.Select-value-label').should('have.html', 'Humid')); - DashTable.getCell(3, 6).within(() => cy.get('.Select-value-label').should('have.html', 'Humid')); + DashTable.getCell(0, 6).within(() => cy.get('.Select-value-label').should('have.html', 'label: Humid')); + DashTable.getCell(1, 6).within(() => cy.get('.Select-value-label').should('have.html', 'label: Humid')); + DashTable.getCell(2, 6).within(() => cy.get('.Select-value-label').should('have.html', 'label: Humid')); + DashTable.getCell(3, 6).within(() => cy.get('.Select-value-label').should('have.html', 'label: Humid')); + + DashTable.getCell(0, 7).within(() => cy.get('.dash-cell-value').should('have.html', 'label: Humid')); + DashTable.getCell(1, 7).within(() => cy.get('.dash-cell-value').should('have.html', 'label: Humid')); + DashTable.getCell(2, 7).within(() => cy.get('.dash-cell-value').should('have.html', 'label: Humid')); + DashTable.getCell(3, 7).within(() => cy.get('.dash-cell-value').should('have.html', 'label: Humid')); }); }); }); \ No newline at end of file diff --git a/packages/dash-table/tests/visual/percy-storybook/Dropdown.percy.tsx b/packages/dash-table/tests/visual/percy-storybook/Dropdown.percy.tsx index a5d7864d7c..7569b4ae33 100644 --- a/packages/dash-table/tests/visual/percy-storybook/Dropdown.percy.tsx +++ b/packages/dash-table/tests/visual/percy-storybook/Dropdown.percy.tsx @@ -30,6 +30,48 @@ const columns2 = R.map( ); storiesOf('DashTable/Dropdown', module) + .add('readonly dropdown shows label', () => ({ label: `label: ${i}`, value: i }), + ['Sunny', 'Snowy', 'Rainy'] + ) + }, + city: { + options: R.map( + i => ({ label: `label: ${i}`, value: i }), + ['NYC', 'Montreal', 'Miami'] + ) + } + }} + />) + .add('editable dropdown shows label', () => ({ label: `label: ${i}`, value: i }), + ['Sunny', 'Snowy', 'Rainy'] + ) + }, + city: { + options: R.map( + i => ({ label: `label: ${i}`, value: i }), + ['NYC', 'Montreal', 'Miami'] + ) + } + }} + />) .add('dropdown by column', () => (