Skip to content

Commit 2d4d2fb

Browse files
committed
refactor: change to logic to minimize changes to existing tests
1 parent e52b20c commit 2d4d2fb

10 files changed

+112
-37
lines changed

packages/vaadin-crud/src/vaadin-crud-grid.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ class CrudGridElement extends IncludedMixin(GridElement) {
5454

5555
/** @private */
5656
__onItemsChange(items) {
57-
if ((!this.dataProvider || this.dataProvider.__arrayDataProvider) && !this.include && items && items[0]) {
57+
if ((!this.dataProvider || this.dataProvider == this._arrayDataProvider) && !this.include && items && items[0]) {
5858
this._configure(items[0]);
5959
}
6060
}
@@ -91,7 +91,7 @@ class CrudGridElement extends IncludedMixin(GridElement) {
9191
* @private
9292
*/
9393
_dataProviderChanged(dataProvider, oldDataProvider) {
94-
if (dataProvider.__arrayDataProvider) {
94+
if (this._arrayDataProvider == dataProvider) {
9595
super._dataProviderChanged(dataProvider, oldDataProvider);
9696
} else if (this.__dataProviderWrapper != dataProvider) {
9797
this.innerHTML = '';

packages/vaadin-grid/src/arrayDataProvider.js

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ function filter(items, filters) {
106106
}
107107

108108
export const createArrayDataProvider = (allItems) => {
109-
const arrayDataProvider = (params, callback) => {
109+
return (params, callback) => {
110110
let items = allItems || [];
111111
if (params.filters && checkPaths(params.filters, 'filtering', items)) {
112112
items = filter(items, params.filters);
@@ -116,14 +116,10 @@ export const createArrayDataProvider = (allItems) => {
116116
items = multiSort(items, params.sortOrders);
117117
}
118118

119-
const start = params.page * params.pageSize;
120-
const end = start + params.pageSize;
119+
const count = Math.min(items.length, params.pageSize);
120+
const start = params.page * count;
121+
const end = start + count;
121122
const slice = items.slice(start, end);
122123
callback(slice, items.length);
123124
};
124-
125-
// Mark the data provider as an array data provider
126-
// (needed by the selection column which has logic depending on it)
127-
arrayDataProvider.__arrayDataProvider = true;
128-
return arrayDataProvider;
129125
};

packages/vaadin-grid/src/vaadin-grid-a11y-mixin.js

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
export const A11yMixin = (superClass) =>
1111
class A11yMixin extends superClass {
1212
static get observers() {
13-
return ['_a11yUpdateGridSize(_effectiveSize, _columnTree, _columnTree.*)'];
13+
return ['_a11yUpdateGridSize(size, _columnTree, _columnTree.*)'];
1414
}
1515

1616
/** @private */
@@ -26,15 +26,15 @@ export const A11yMixin = (superClass) =>
2626
}
2727

2828
/** @private */
29-
_a11yUpdateGridSize(effectiveSize, _columnTree) {
30-
if (effectiveSize === undefined || _columnTree === undefined) {
29+
_a11yUpdateGridSize(size, _columnTree) {
30+
if (size === undefined || _columnTree === undefined) {
3131
return;
3232
}
3333

3434
const bodyColumns = _columnTree[_columnTree.length - 1];
3535
this.$.table.setAttribute(
3636
'aria-rowcount',
37-
effectiveSize + this._a11yGetHeaderRowCount(_columnTree) + this._a11yGetFooterRowCount(_columnTree)
37+
size + this._a11yGetHeaderRowCount(_columnTree) + this._a11yGetFooterRowCount(_columnTree)
3838
);
3939
this.$.table.setAttribute('aria-colcount', (bodyColumns && bodyColumns.length) || 0);
4040

@@ -52,10 +52,7 @@ export const A11yMixin = (superClass) =>
5252
/** @protected */
5353
_a11yUpdateFooterRows() {
5454
Array.from(this.$.footer.children).forEach((footerRow, index) =>
55-
footerRow.setAttribute(
56-
'aria-rowindex',
57-
this._a11yGetHeaderRowCount(this._columnTree) + this._effectiveSize + index + 1
58-
)
55+
footerRow.setAttribute('aria-rowindex', this._a11yGetHeaderRowCount(this._columnTree) + this.size + index + 1)
5956
);
6057
}
6158

packages/vaadin-grid/src/vaadin-grid-array-data-provider-mixin.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ declare interface ArrayDataProviderMixin<TItem> {
1212
* instances.
1313
*/
1414
items: TItem[] | null | undefined;
15+
16+
_arrayDataProvider(opts: GridDataProviderParams<TItem> | null, cb: GridDataProviderCallback<TItem> | null): void;
1517
}
1618

1719
export { ArrayDataProviderMixin, ArrayDataProviderMixinConstructor };

packages/vaadin-grid/src/vaadin-grid-array-data-provider-mixin.js

Lines changed: 46 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,54 @@ export const ArrayDataProviderMixin = (superClass) =>
2323
}
2424

2525
static get observers() {
26-
return ['__itemsChanged(items)'];
26+
return ['__dataProviderOrItemsChanged(dataProvider, items, isAttached, items.*, _filters, _sorters)'];
2727
}
2828

29-
/** @private */
30-
__itemsChanged(items) {
31-
if (Array.isArray(items)) {
32-
this.dataProvider = createArrayDataProvider(items, {});
33-
} else if (items === null) {
34-
this.dataProvider = null;
29+
__setArrayDataProvider(items) {
30+
const arrayDataProvider = createArrayDataProvider(this.items, {});
31+
arrayDataProvider.__items = items;
32+
this.setProperties({
33+
_arrayDataProvider: arrayDataProvider,
34+
size: items.length,
35+
dataProvider: arrayDataProvider
36+
});
37+
}
38+
39+
__unsetArrayDataProvider() {
40+
this.setProperties({
41+
_arrayDataProvider: undefined,
42+
items: undefined // TODO: selection column just checks for grid.items in some logic. Add a test which adds items and then a custom dp.
43+
});
44+
}
45+
46+
__dataProviderOrItemsChanged(dataProvider, items, isAttached) {
47+
if (!isAttached) {
48+
return;
49+
}
50+
51+
if (this._arrayDataProvider) {
52+
// Has an items array data provider beforehand
53+
54+
if (dataProvider !== this._arrayDataProvider) {
55+
// A custom data provider was set externally
56+
this.__unsetArrayDataProvider();
57+
} else if (!items) {
58+
// The items array was unset
59+
this.__unsetArrayDataProvider();
60+
this.dataProvider = undefined;
61+
this.size = 0;
62+
this.clearCache();
63+
} else if (this._arrayDataProvider.__items === items) {
64+
// The items array was modified
65+
this.clearCache();
66+
this.size = this._effectiveSize;
67+
} else {
68+
// The items array was replaced
69+
this.__setArrayDataProvider(items);
70+
}
71+
} else if (items) {
72+
// There was no array data provider before items was set
73+
this.__setArrayDataProvider(items);
3574
}
3675
}
3776
};

packages/vaadin-grid/src/vaadin-grid-data-provider-mixin.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,14 @@ export const DataProviderMixin = (superClass) =>
203203
type: Object,
204204
notify: true,
205205
value: () => []
206+
},
207+
208+
/**
209+
* @private
210+
*/
211+
__expandedKeys: {
212+
type: Object,
213+
value: () => new Set()
206214
}
207215
};
208216
}

packages/vaadin-grid/src/vaadin-grid-filter-mixin.js

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,6 @@ export const FilterMixin = (superClass) =>
2121
};
2222
}
2323

24-
static get observers() {
25-
return ['__applyFilters(isAttached)'];
26-
}
27-
2824
/** @protected */
2925
ready() {
3026
super.ready();
@@ -62,7 +58,6 @@ export const FilterMixin = (superClass) =>
6258
__applyFilters() {
6359
if (this.dataProvider && this.isAttached) {
6460
this.clearCache();
65-
this._ensureFirstPageLoaded();
6661
}
6762
}
6863

packages/vaadin-grid/src/vaadin-grid-selection-column.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -270,13 +270,13 @@ class GridSelectionColumnElement extends GridColumnElement {
270270
}
271271

272272
/** @private */
273-
_onDataProviderChanged() {
273+
__onDataProviderChanged() {
274274
this.__selectAllHidden = !this.__gridUsesArrayDataProvider();
275275
}
276276

277277
/**
278-
* Assuming the grid uses an array data provider, fetches all the filtered items
279-
* from it and invokes the callback with the resulting array.
278+
* Assuming the grid uses an items array data provider, fetches all the filtered items
279+
* from the data provider and invokes the callback with the resulting array.
280280
*
281281
* @private
282282
**/
@@ -296,7 +296,7 @@ class GridSelectionColumnElement extends GridColumnElement {
296296
* @private
297297
**/
298298
__gridUsesArrayDataProvider() {
299-
return this._grid.dataProvider && this._grid.dataProvider.__arrayDataProvider;
299+
return this._grid._arrayDataProvider;
300300
}
301301
}
302302

packages/vaadin-grid/src/vaadin-grid.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,7 @@ class GridElement extends ElementMixin(
526526
const cellCoordinates = this.__getBodyCellCoordinates(cell);
527527

528528
virtualizer.size = effectiveSize;
529+
virtualizer.flush();
529530

530531
// If the focused cell's parent row got hidden by the size change, focus the corresponding new cell
531532
cellCoordinates && cell.parentElement.hidden && this.__focusBodyCell(cellCoordinates);

packages/vaadin-grid/test/array-data-provider.test.js

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { expect } from '@esm-bundle/chai';
22
import sinon from 'sinon';
33
import { click, fixtureSync, nextFrame } from '@vaadin/testing-helpers';
4-
import { flushGrid, getCellContent, getRows, getRowCells } from './helpers.js';
4+
import { flushGrid, getCellContent, getRows, getRowCells, getBodyCellContent } from './helpers.js';
55
import '../vaadin-grid.js';
66
import '../vaadin-grid-filter.js';
77
import '../vaadin-grid-sorter.js';
@@ -85,10 +85,10 @@ describe('array data provider', () => {
8585
expect(grid.dataProvider).to.equal(grid._arrayDataProvider);
8686
});
8787

88-
it('should not override custom data provider', () => {
88+
it('should override custom data provider', () => {
8989
const ds = (grid.dataProvider = () => {});
9090
grid.items = [1, 2, 3];
91-
expect(grid.dataProvider).to.equal(ds);
91+
expect(grid.dataProvider).not.to.equal(ds);
9292
});
9393

9494
it('should handle new array of same length', () => {
@@ -249,3 +249,40 @@ describe('invalid paths', () => {
249249
});
250250
});
251251
});
252+
253+
describe('items with a custom data provider', () => {
254+
let grid;
255+
const dataProvider = (params, callback) => callback([{ value: 'foo' }], 1);
256+
const items = [{ value: 'bar' }];
257+
258+
beforeEach(() => {
259+
grid = fixtureSync(`
260+
<vaadin-grid>
261+
<vaadin-grid-column path="value"></vaadin-grid-column>
262+
</vaadin-grid>
263+
`);
264+
});
265+
266+
it('use the items array', () => {
267+
grid.dataProvider = dataProvider;
268+
grid.items = items;
269+
flushGrid(grid);
270+
expect(getBodyCellContent(grid, 0, 0).textContent).to.equal('bar');
271+
expect(grid.dataProvider).not.to.equal(dataProvider);
272+
});
273+
274+
it('should use the data provider', () => {
275+
grid.items = items;
276+
grid.dataProvider = dataProvider;
277+
flushGrid(grid);
278+
expect(getBodyCellContent(grid, 0, 0).textContent).to.equal('foo');
279+
expect(grid.items).to.be.undefined;
280+
});
281+
282+
it('should unset the data provider', () => {
283+
grid.items = items;
284+
grid.items = null;
285+
flushGrid(grid);
286+
expect(grid.dataProvider).to.be.undefined;
287+
});
288+
});

0 commit comments

Comments
 (0)