diff --git a/addon/components/yeti-table/component.js b/addon/components/yeti-table/component.js index 41105c8b..f60ced01 100644 --- a/addon/components/yeti-table/component.js +++ b/addon/components/yeti-table/component.js @@ -206,6 +206,18 @@ class YetiTable extends DidChangeAttrsComponent { */ sortSequence = this.get('config').sortSequence || ['asc', 'desc']; + /** + * Use `@disableObserveData` to prevent yeti from observing changes to the underlying data and resorting or + * refiltering. Useful when doing inline editing in a table. + * + * Defaults to false + * + * This is an initial render only value. Changing it after the table has been rendered will not be respected. + * + * @type {boolean} + */ + ignoreDataChanges = false; + @className @reads('mergedTheme.table') themeClass; @@ -339,7 +351,7 @@ class YetiTable extends DidChangeAttrsComponent { if (!this.isDestroyed) { this.set('isLoading', false); } - // re-throw the non-cancelation error + // re-throw the non-cancellation error throw e; } }); @@ -358,16 +370,23 @@ class YetiTable extends DidChangeAttrsComponent { didInsertElement() { super.didInsertElement(...arguments); - // Only include columns with a prop - // truncate prop names to the first period - // get a unique list - let columns = this.get('columns') - .filter(column => column.get('prop')) - .map(column => column.get('prop').split('.')[0]) - .filter((v, i, a) => a.indexOf(v) === i); + let depKeys = '[]'; + if (this.get('ignoreDataChanges') === false) { + // Only include columns with a prop + // truncate prop names to the first period + // get a unique list + let columns = this.get('columns') + .filter(column => column.get('prop')) + .map(column => column.get('prop').split('.')[0]) + .filter((v, i, a) => a.indexOf(v) === i); + + if (columns.length > 0) { + depKeys = `@each.{${columns.join(',')}}`; + } + } let filteredDataDeps = [ - `resolvedData.@each.{${columns.join(',')}}`, + `resolvedData.${depKeys}`, 'columns.@each.{prop,filterFunction,filter,filterUsing,filterable}', 'filter', 'filterUsing', @@ -386,7 +405,7 @@ class YetiTable extends DidChangeAttrsComponent { })); let sortedDataDeps = [ - `filteredData.@each.{${columns.join(',')}}`, + `filteredData.${depKeys}`, 'columns.@each.{prop,sort,sortable}', 'sortFunction', 'compareFunction' diff --git a/tests/dummy/app/pods/docs/filtering/template.md b/tests/dummy/app/pods/docs/filtering/template.md index 3633960d..b5c96ddb 100644 --- a/tests/dummy/app/pods/docs/filtering/template.md +++ b/tests/dummy/app/pods/docs/filtering/template.md @@ -9,6 +9,8 @@ This allows you to update that argument as you wish, either using an input eleme Using the `@filter` argument on the `` component itself will apply a *global* filter to the rows. This means that Yeti Table will only show rows in which any of its columns match that text. +If you update an object's property, the tables filtered rows will be updated accordingly. This behaviour cant be turned off with `@ignoreDataChanges={{true}}` + {{#docs-demo as |demo|}} {{#demo.example name="filtering-simple.hbs"}}
diff --git a/tests/dummy/app/pods/docs/sorting/template.md b/tests/dummy/app/pods/docs/sorting/template.md index a98b4bd1..92ec36d4 100644 --- a/tests/dummy/app/pods/docs/sorting/template.md +++ b/tests/dummy/app/pods/docs/sorting/template.md @@ -39,7 +39,9 @@ In the following example we disabled sorting on the second column. If you need to specify a sort order, you can use the `@sort` argument on the column definitions, with a string of `asc` or `desc`. -Note that updating the `@sort` argument will also update the sorting of the table. Also, if you update an object's property which the table is sorted on, the table sorting will update accordingly. +Note that updating the `@sort` argument will also update the sorting of the table. + +If you update an object's property which the table is sorted on, the table sorting will update accordingly. This behaviour cant be turned off with `@ignoreDataChanges={{true}}` {{#docs-demo as |demo|}} {{#demo.example name="sorting-sort-property.hbs"}} diff --git a/tests/integration/components/yeti-table/filtering-test.js b/tests/integration/components/yeti-table/filtering-test.js index 9502b75e..2228d33c 100644 --- a/tests/integration/components/yeti-table/filtering-test.js +++ b/tests/integration/components/yeti-table/filtering-test.js @@ -232,6 +232,41 @@ module('Integration | Component | yeti-table (filtering)', function(hooks) { assert.dom('tbody tr:nth-child(1) td:nth-child(1)').hasText('Tom'); }); + test('changing a filtered property updates table is ignored correctly', async function(assert) { + await render(hbs` + + + + + First name + + + Last name + + + Points + + + + + + + `); + + assert.dom('tbody tr').exists({ count: 2 }); + assert.dom('tbody tr:nth-child(1) td:nth-child(1)').hasText('Tom'); + assert.dom('tbody tr:nth-child(2) td:nth-child(1)').hasText('Tom'); + + run(() => { + set(this.data.objectAt(3), 'firstName', '123'); + }); + await settled(); + + assert.dom('tbody tr').exists({ count: 2 }); + assert.dom('tbody tr:nth-child(1) td:nth-child(1)').hasText('123'); + assert.dom('tbody tr:nth-child(2) td:nth-child(1)').hasText('Tom'); + }); + test('custom filter function', async function(assert) { this.filter = (row, filter) => { let [prop, text] = filter.split(':'); diff --git a/tests/integration/components/yeti-table/sorting-test.js b/tests/integration/components/yeti-table/sorting-test.js index 51b6a3e6..c43678a6 100644 --- a/tests/integration/components/yeti-table/sorting-test.js +++ b/tests/integration/components/yeti-table/sorting-test.js @@ -536,6 +536,45 @@ module('Integration | Component | yeti-table (sorting)', function(hooks) { assert.dom('tbody tr:nth-child(5) td:nth-child(1)').hasText('Tom'); }); + test('changing a sorted property updates sorting is ignored correctly', async function(assert) { + await render(hbs` + + + + + First name + + + Last name + + + Points + + + + + + + `); + + assert.dom('tbody tr:nth-child(1) td:nth-child(1)').hasText('José'); + assert.dom('tbody tr:nth-child(2) td:nth-child(1)').hasText('Maria'); + assert.dom('tbody tr:nth-child(3) td:nth-child(1)').hasText('Miguel'); + assert.dom('tbody tr:nth-child(4) td:nth-child(1)').hasText('Tom'); + assert.dom('tbody tr:nth-child(5) td:nth-child(1)').hasText('Tom'); + + run(() => { + set(this.data.objectAt(3), 'firstName', '123'); + }); + await settled(); + + assert.dom('tbody tr:nth-child(1) td:nth-child(1)').hasText('José'); + assert.dom('tbody tr:nth-child(2) td:nth-child(1)').hasText('Maria'); + assert.dom('tbody tr:nth-child(3) td:nth-child(1)').hasText('Miguel'); + assert.dom('tbody tr:nth-child(4) td:nth-child(1)').hasText('123'); + assert.dom('tbody tr:nth-child(5) td:nth-child(1)').hasText('Tom'); + }); + test('using multiple properties on sort works', async function(assert) { await render(hbs`