@vaadin/grid 24.2.0-dev.f254716fe → 24.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +11 -11
- package/src/vaadin-grid-column-group.js +3 -1
- package/src/vaadin-grid-column.js +6 -3
- package/src/vaadin-grid-data-provider-mixin.d.ts +25 -0
- package/src/vaadin-grid-data-provider-mixin.js +252 -79
- package/src/vaadin-grid-dynamic-columns-mixin.js +1 -1
- package/src/vaadin-grid-filter-column.js +5 -1
- package/src/vaadin-grid-filter.js +3 -1
- package/src/vaadin-grid-keyboard-navigation-mixin.js +38 -5
- package/src/vaadin-grid-mixin.d.ts +218 -0
- package/src/vaadin-grid-mixin.js +1025 -0
- package/src/vaadin-grid-selection-column-base-mixin.d.ts +6 -0
- package/src/vaadin-grid-selection-column-base-mixin.js +151 -0
- package/src/vaadin-grid-selection-column.js +4 -1
- package/src/vaadin-grid-sort-column.js +5 -1
- package/src/vaadin-grid-sorter.js +3 -1
- package/src/vaadin-grid-tree-column.js +6 -2
- package/src/vaadin-grid-tree-toggle.js +3 -1
- package/src/vaadin-grid.d.ts +5 -190
- package/src/vaadin-grid.js +7 -1018
- package/web-types.json +2311 -0
- package/web-types.lit.json +1007 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vaadin/grid",
|
|
3
|
-
"version": "24.2.0
|
|
3
|
+
"version": "24.2.0",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -46,18 +46,18 @@
|
|
|
46
46
|
"dependencies": {
|
|
47
47
|
"@open-wc/dedupe-mixin": "^1.3.0",
|
|
48
48
|
"@polymer/polymer": "^3.0.0",
|
|
49
|
-
"@vaadin/a11y-base": "24.2.0
|
|
50
|
-
"@vaadin/checkbox": "24.2.0
|
|
51
|
-
"@vaadin/component-base": "24.2.0
|
|
52
|
-
"@vaadin/lit-renderer": "24.2.0
|
|
53
|
-
"@vaadin/text-field": "24.2.0
|
|
54
|
-
"@vaadin/vaadin-lumo-styles": "24.2.0
|
|
55
|
-
"@vaadin/vaadin-material-styles": "24.2.0
|
|
56
|
-
"@vaadin/vaadin-themable-mixin": "24.2.0
|
|
49
|
+
"@vaadin/a11y-base": "~24.2.0",
|
|
50
|
+
"@vaadin/checkbox": "~24.2.0",
|
|
51
|
+
"@vaadin/component-base": "~24.2.0",
|
|
52
|
+
"@vaadin/lit-renderer": "~24.2.0",
|
|
53
|
+
"@vaadin/text-field": "~24.2.0",
|
|
54
|
+
"@vaadin/vaadin-lumo-styles": "~24.2.0",
|
|
55
|
+
"@vaadin/vaadin-material-styles": "~24.2.0",
|
|
56
|
+
"@vaadin/vaadin-themable-mixin": "~24.2.0"
|
|
57
57
|
},
|
|
58
58
|
"devDependencies": {
|
|
59
59
|
"@esm-bundle/chai": "^4.3.4",
|
|
60
|
-
"@vaadin/testing-helpers": "^0.
|
|
60
|
+
"@vaadin/testing-helpers": "^0.5.0",
|
|
61
61
|
"lit": "^2.0.0",
|
|
62
62
|
"sinon": "^13.0.2"
|
|
63
63
|
},
|
|
@@ -65,5 +65,5 @@
|
|
|
65
65
|
"web-types.json",
|
|
66
66
|
"web-types.lit.json"
|
|
67
67
|
],
|
|
68
|
-
"gitHead": "
|
|
68
|
+
"gitHead": "8b9e860d53fc0132d05d3e8701eeded2dca74eba"
|
|
69
69
|
}
|
|
@@ -7,6 +7,7 @@ import { FlattenedNodesObserver } from '@polymer/polymer/lib/utils/flattened-nod
|
|
|
7
7
|
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
|
8
8
|
import { animationFrame } from '@vaadin/component-base/src/async.js';
|
|
9
9
|
import { Debouncer } from '@vaadin/component-base/src/debounce.js';
|
|
10
|
+
import { defineCustomElement } from '@vaadin/component-base/src/define.js';
|
|
10
11
|
import { ColumnBaseMixin } from './vaadin-grid-column.js';
|
|
11
12
|
import { updateColumnOrders } from './vaadin-grid-helpers.js';
|
|
12
13
|
|
|
@@ -39,6 +40,7 @@ import { updateColumnOrders } from './vaadin-grid-helpers.js';
|
|
|
39
40
|
* column2.renderer = (root, column, model) => { ... };
|
|
40
41
|
* ```
|
|
41
42
|
*
|
|
43
|
+
* @customElement
|
|
42
44
|
* @extends HTMLElement
|
|
43
45
|
* @mixes ColumnBaseMixin
|
|
44
46
|
*/
|
|
@@ -396,6 +398,6 @@ class GridColumnGroup extends ColumnBaseMixin(PolymerElement) {
|
|
|
396
398
|
}
|
|
397
399
|
}
|
|
398
400
|
|
|
399
|
-
|
|
401
|
+
defineCustomElement(GridColumnGroup);
|
|
400
402
|
|
|
401
403
|
export { GridColumnGroup };
|
|
@@ -6,7 +6,9 @@
|
|
|
6
6
|
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
|
7
7
|
import { animationFrame } from '@vaadin/component-base/src/async.js';
|
|
8
8
|
import { Debouncer } from '@vaadin/component-base/src/debounce.js';
|
|
9
|
+
import { defineCustomElement } from '@vaadin/component-base/src/define.js';
|
|
9
10
|
import { DirMixin } from '@vaadin/component-base/src/dir-mixin.js';
|
|
11
|
+
import { get } from '@vaadin/component-base/src/path-utils.js';
|
|
10
12
|
import { processTemplates } from '@vaadin/component-base/src/templates.js';
|
|
11
13
|
import { updateCellState } from './vaadin-grid-helpers.js';
|
|
12
14
|
|
|
@@ -487,7 +489,7 @@ export const ColumnBaseMixin = (superClass) =>
|
|
|
487
489
|
|
|
488
490
|
/** @private */
|
|
489
491
|
_textAlignChanged(textAlign) {
|
|
490
|
-
if (textAlign === undefined) {
|
|
492
|
+
if (textAlign === undefined || this._grid === undefined) {
|
|
491
493
|
return;
|
|
492
494
|
}
|
|
493
495
|
if (['start', 'end', 'center'].indexOf(textAlign) === -1) {
|
|
@@ -713,7 +715,7 @@ export const ColumnBaseMixin = (superClass) =>
|
|
|
713
715
|
return;
|
|
714
716
|
}
|
|
715
717
|
|
|
716
|
-
this.__setTextContent(root,
|
|
718
|
+
this.__setTextContent(root, get(this.path, item));
|
|
717
719
|
}
|
|
718
720
|
|
|
719
721
|
/**
|
|
@@ -783,6 +785,7 @@ export const ColumnBaseMixin = (superClass) =>
|
|
|
783
785
|
* See [`<vaadin-grid>`](#/elements/vaadin-grid) documentation for instructions on how
|
|
784
786
|
* to configure the `<vaadin-grid-column>`.
|
|
785
787
|
*
|
|
788
|
+
* @customElement
|
|
786
789
|
* @extends HTMLElement
|
|
787
790
|
* @mixes ColumnBaseMixin
|
|
788
791
|
*/
|
|
@@ -894,6 +897,6 @@ class GridColumn extends ColumnBaseMixin(DirMixin(PolymerElement)) {
|
|
|
894
897
|
}
|
|
895
898
|
}
|
|
896
899
|
|
|
897
|
-
|
|
900
|
+
defineCustomElement(GridColumn);
|
|
898
901
|
|
|
899
902
|
export { GridColumn };
|
|
@@ -33,6 +33,31 @@ export type GridDataProvider<TItem> = (
|
|
|
33
33
|
callback: GridDataProviderCallback<TItem>,
|
|
34
34
|
) => void;
|
|
35
35
|
|
|
36
|
+
export declare class ItemCache<TItem> {
|
|
37
|
+
grid: HTMLElement;
|
|
38
|
+
parentCache: ItemCache<TItem> | undefined;
|
|
39
|
+
parentItem: TItem | undefined;
|
|
40
|
+
itemCaches: object | null;
|
|
41
|
+
items: object | null;
|
|
42
|
+
effectiveSize: number;
|
|
43
|
+
size: number;
|
|
44
|
+
pendingRequests: object | null;
|
|
45
|
+
|
|
46
|
+
constructor(grid: HTMLElement, parentCache: ItemCache<TItem> | undefined, parentItem: TItem | undefined);
|
|
47
|
+
|
|
48
|
+
isLoading(): boolean;
|
|
49
|
+
|
|
50
|
+
getItemForIndex(index: number): TItem | undefined;
|
|
51
|
+
|
|
52
|
+
updateSize(): void;
|
|
53
|
+
|
|
54
|
+
ensureSubCacheForScaledIndex(scaledIndex: number): void;
|
|
55
|
+
|
|
56
|
+
getCacheAndIndex(index: number): { cache: ItemCache<TItem>; scaledIndex: number };
|
|
57
|
+
|
|
58
|
+
getFlatIndex(scaledIndex: number): number;
|
|
59
|
+
}
|
|
60
|
+
|
|
36
61
|
export declare function DataProviderMixin<TItem, T extends Constructor<HTMLElement>>(
|
|
37
62
|
base: T,
|
|
38
63
|
): Constructor<DataProviderMixinClass<TItem>> & T;
|
|
@@ -4,10 +4,116 @@
|
|
|
4
4
|
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
5
|
*/
|
|
6
6
|
import { timeOut } from '@vaadin/component-base/src/async.js';
|
|
7
|
-
import { DataProviderController } from '@vaadin/component-base/src/data-provider-controller.js';
|
|
8
7
|
import { Debouncer } from '@vaadin/component-base/src/debounce.js';
|
|
8
|
+
import { get } from '@vaadin/component-base/src/path-utils.js';
|
|
9
9
|
import { getBodyRowCells, updateCellsPart, updateState } from './vaadin-grid-helpers.js';
|
|
10
10
|
|
|
11
|
+
/**
|
|
12
|
+
* @private
|
|
13
|
+
*/
|
|
14
|
+
export const ItemCache = class ItemCache {
|
|
15
|
+
/**
|
|
16
|
+
* @param {!HTMLElement} grid
|
|
17
|
+
* @param {!ItemCache | undefined} parentCache
|
|
18
|
+
* @param {!GridItem | undefined} parentItem
|
|
19
|
+
*/
|
|
20
|
+
constructor(grid, parentCache, parentItem) {
|
|
21
|
+
/** @type {!HTMLElement} */
|
|
22
|
+
this.grid = grid;
|
|
23
|
+
/** @type {!ItemCache | undefined} */
|
|
24
|
+
this.parentCache = parentCache;
|
|
25
|
+
/** @type {!GridItem | undefined} */
|
|
26
|
+
this.parentItem = parentItem;
|
|
27
|
+
/** @type {object} */
|
|
28
|
+
this.itemCaches = {};
|
|
29
|
+
/** @type {object[]} */
|
|
30
|
+
this.items = [];
|
|
31
|
+
/** @type {number} */
|
|
32
|
+
this.effectiveSize = 0;
|
|
33
|
+
/** @type {number} */
|
|
34
|
+
this.size = 0;
|
|
35
|
+
/** @type {object} */
|
|
36
|
+
this.pendingRequests = {};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* @return {boolean}
|
|
41
|
+
*/
|
|
42
|
+
isLoading() {
|
|
43
|
+
return Boolean(
|
|
44
|
+
Object.keys(this.pendingRequests).length ||
|
|
45
|
+
Object.keys(this.itemCaches).filter((index) => {
|
|
46
|
+
return this.itemCaches[index].isLoading();
|
|
47
|
+
})[0],
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* @param {number} index
|
|
53
|
+
* @return {!GridItem | undefined}
|
|
54
|
+
*/
|
|
55
|
+
getItemForIndex(index) {
|
|
56
|
+
const { cache, scaledIndex } = this.getCacheAndIndex(index);
|
|
57
|
+
return cache.items[scaledIndex];
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
updateSize() {
|
|
61
|
+
this.effectiveSize =
|
|
62
|
+
!this.parentItem || this.grid._isExpanded(this.parentItem)
|
|
63
|
+
? this.size +
|
|
64
|
+
Object.keys(this.itemCaches).reduce((prev, curr) => {
|
|
65
|
+
const subCache = this.itemCaches[curr];
|
|
66
|
+
subCache.updateSize();
|
|
67
|
+
return prev + subCache.effectiveSize;
|
|
68
|
+
}, 0)
|
|
69
|
+
: 0;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* @param {number} scaledIndex
|
|
74
|
+
*/
|
|
75
|
+
ensureSubCacheForScaledIndex(scaledIndex) {
|
|
76
|
+
if (!this.itemCaches[scaledIndex]) {
|
|
77
|
+
const subCache = new ItemCache(this.grid, this, this.items[scaledIndex]);
|
|
78
|
+
this.itemCaches[scaledIndex] = subCache;
|
|
79
|
+
this.grid._loadPage(0, subCache);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* @param {number} index
|
|
85
|
+
* @return {{cache: !ItemCache, scaledIndex: number}}
|
|
86
|
+
*/
|
|
87
|
+
getCacheAndIndex(index) {
|
|
88
|
+
let thisLevelIndex = index;
|
|
89
|
+
for (const [index, subCache] of Object.entries(this.itemCaches)) {
|
|
90
|
+
const numberIndex = Number(index);
|
|
91
|
+
if (thisLevelIndex <= numberIndex) {
|
|
92
|
+
return { cache: this, scaledIndex: thisLevelIndex };
|
|
93
|
+
} else if (thisLevelIndex <= numberIndex + subCache.effectiveSize) {
|
|
94
|
+
return subCache.getCacheAndIndex(thisLevelIndex - numberIndex - 1);
|
|
95
|
+
}
|
|
96
|
+
thisLevelIndex -= subCache.effectiveSize;
|
|
97
|
+
}
|
|
98
|
+
return { cache: this, scaledIndex: thisLevelIndex };
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Gets the scaled index as flattened index on this cache level.
|
|
103
|
+
* In practice, this means that the effective size of any expanded
|
|
104
|
+
* subcaches preceding the index are added to the value.
|
|
105
|
+
* @param {number} scaledIndex
|
|
106
|
+
* @return {number} The flat index on this cache level.
|
|
107
|
+
*/
|
|
108
|
+
getFlatIndex(scaledIndex) {
|
|
109
|
+
const clampedIndex = Math.max(0, Math.min(this.size - 1, scaledIndex));
|
|
110
|
+
|
|
111
|
+
return Object.entries(this.itemCaches).reduce((prev, [index, subCache]) => {
|
|
112
|
+
return clampedIndex > Number(index) ? prev + subCache.effectiveSize : prev;
|
|
113
|
+
}, clampedIndex);
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
|
|
11
117
|
/**
|
|
12
118
|
* @polymerMixin
|
|
13
119
|
*/
|
|
@@ -75,6 +181,18 @@ export const DataProviderMixin = (superClass) =>
|
|
|
75
181
|
reflectToAttribute: true,
|
|
76
182
|
},
|
|
77
183
|
|
|
184
|
+
/**
|
|
185
|
+
* @type {!ItemCache}
|
|
186
|
+
* @protected
|
|
187
|
+
*/
|
|
188
|
+
_cache: {
|
|
189
|
+
type: Object,
|
|
190
|
+
value() {
|
|
191
|
+
const cache = new ItemCache(this);
|
|
192
|
+
return cache;
|
|
193
|
+
},
|
|
194
|
+
},
|
|
195
|
+
|
|
78
196
|
/**
|
|
79
197
|
* @protected
|
|
80
198
|
*/
|
|
@@ -126,32 +244,12 @@ export const DataProviderMixin = (superClass) =>
|
|
|
126
244
|
return ['_sizeChanged(size)', '_expandedItemsChanged(expandedItems.*)'];
|
|
127
245
|
}
|
|
128
246
|
|
|
129
|
-
constructor() {
|
|
130
|
-
super();
|
|
131
|
-
|
|
132
|
-
/** @type {DataProviderController} */
|
|
133
|
-
this._dataProviderController = new DataProviderController(this, {
|
|
134
|
-
size: this.size,
|
|
135
|
-
pageSize: this.pageSize,
|
|
136
|
-
isExpanded: this._isExpanded.bind(this),
|
|
137
|
-
dataProvider: this.dataProvider ? this.dataProvider.bind(this) : null,
|
|
138
|
-
dataProviderParams: () => {
|
|
139
|
-
return {
|
|
140
|
-
sortOrders: this._mapSorters(),
|
|
141
|
-
filters: this._mapFilters(),
|
|
142
|
-
};
|
|
143
|
-
},
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
this._dataProviderController.addEventListener('page-requested', this._onDataProviderPageRequested.bind(this));
|
|
147
|
-
this._dataProviderController.addEventListener('page-received', this._onDataProviderPageReceived.bind(this));
|
|
148
|
-
this._dataProviderController.addEventListener('page-loaded', this._onDataProviderPageLoaded.bind(this));
|
|
149
|
-
}
|
|
150
|
-
|
|
151
247
|
/** @private */
|
|
152
248
|
_sizeChanged(size) {
|
|
153
|
-
this.
|
|
154
|
-
this.
|
|
249
|
+
const delta = size - this._cache.size;
|
|
250
|
+
this._cache.size += delta;
|
|
251
|
+
this._cache.effectiveSize += delta;
|
|
252
|
+
this._effectiveSize = this._cache.effectiveSize;
|
|
155
253
|
}
|
|
156
254
|
|
|
157
255
|
/** @private */
|
|
@@ -174,17 +272,17 @@ export const DataProviderMixin = (superClass) =>
|
|
|
174
272
|
}
|
|
175
273
|
|
|
176
274
|
el.index = index;
|
|
177
|
-
|
|
178
|
-
const
|
|
275
|
+
const { cache, scaledIndex } = this._cache.getCacheAndIndex(index);
|
|
276
|
+
const item = cache.items[scaledIndex];
|
|
179
277
|
if (item) {
|
|
180
278
|
this.__updateLoading(el, false);
|
|
181
279
|
this._updateItem(el, item);
|
|
182
280
|
if (this._isExpanded(item)) {
|
|
183
|
-
|
|
281
|
+
cache.ensureSubCacheForScaledIndex(scaledIndex);
|
|
184
282
|
}
|
|
185
283
|
} else {
|
|
186
284
|
this.__updateLoading(el, true);
|
|
187
|
-
this.
|
|
285
|
+
this._loadPage(this._getPageForIndex(scaledIndex), cache);
|
|
188
286
|
}
|
|
189
287
|
}
|
|
190
288
|
|
|
@@ -210,7 +308,7 @@ export const DataProviderMixin = (superClass) =>
|
|
|
210
308
|
* @return {!GridItem | !unknown}
|
|
211
309
|
*/
|
|
212
310
|
getItemId(item) {
|
|
213
|
-
return this.itemIdPath ?
|
|
311
|
+
return this.itemIdPath ? get(this.itemIdPath, item) : item;
|
|
214
312
|
}
|
|
215
313
|
|
|
216
314
|
/**
|
|
@@ -224,8 +322,8 @@ export const DataProviderMixin = (superClass) =>
|
|
|
224
322
|
|
|
225
323
|
/** @private */
|
|
226
324
|
_expandedItemsChanged() {
|
|
227
|
-
this.
|
|
228
|
-
this._effectiveSize = this.
|
|
325
|
+
this._cache.updateSize();
|
|
326
|
+
this._effectiveSize = this._cache.effectiveSize;
|
|
229
327
|
this.__updateVisibleRows();
|
|
230
328
|
}
|
|
231
329
|
|
|
@@ -265,68 +363,122 @@ export const DataProviderMixin = (superClass) =>
|
|
|
265
363
|
* @return {number}
|
|
266
364
|
* @protected
|
|
267
365
|
*/
|
|
268
|
-
_getIndexLevel(index
|
|
269
|
-
|
|
366
|
+
_getIndexLevel(index) {
|
|
367
|
+
let { cache } = this._cache.getCacheAndIndex(index);
|
|
368
|
+
let level = 0;
|
|
369
|
+
while (cache.parentCache) {
|
|
370
|
+
cache = cache.parentCache;
|
|
371
|
+
level += 1;
|
|
372
|
+
}
|
|
270
373
|
return level;
|
|
271
374
|
}
|
|
272
375
|
|
|
273
|
-
/**
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
376
|
+
/**
|
|
377
|
+
* @param {number} page
|
|
378
|
+
* @param {ItemCache} cache
|
|
379
|
+
* @protected
|
|
380
|
+
*/
|
|
381
|
+
_loadPage(page, cache) {
|
|
382
|
+
// Make sure same page isn't requested multiple times.
|
|
383
|
+
if (!cache.pendingRequests[page] && this.dataProvider) {
|
|
384
|
+
this._setLoading(true);
|
|
385
|
+
cache.pendingRequests[page] = true;
|
|
386
|
+
const params = {
|
|
387
|
+
page,
|
|
388
|
+
pageSize: this.pageSize,
|
|
389
|
+
sortOrders: this._mapSorters(),
|
|
390
|
+
filters: this._mapFilters(),
|
|
391
|
+
parentItem: cache.parentItem,
|
|
392
|
+
};
|
|
393
|
+
|
|
394
|
+
this.dataProvider(params, (items, size) => {
|
|
395
|
+
if (size !== undefined) {
|
|
396
|
+
cache.size = size;
|
|
397
|
+
} else if (params.parentItem) {
|
|
398
|
+
cache.size = items.length;
|
|
399
|
+
}
|
|
282
400
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
401
|
+
// Populate the cache with new items
|
|
402
|
+
items.forEach((item, itemsIndex) => {
|
|
403
|
+
const itemIndex = page * this.pageSize + itemsIndex;
|
|
404
|
+
cache.items[itemIndex] = item;
|
|
405
|
+
});
|
|
406
|
+
|
|
407
|
+
// With the new items added, update the cache size and the grid's effective size
|
|
408
|
+
this._cache.updateSize();
|
|
409
|
+
this._effectiveSize = this._cache.effectiveSize;
|
|
410
|
+
|
|
411
|
+
// After updating the cache, check if some of the expanded items should have sub-caches loaded
|
|
412
|
+
this._getRenderedRows().forEach((row) => {
|
|
413
|
+
const { cache, scaledIndex } = this._cache.getCacheAndIndex(row.index);
|
|
414
|
+
const item = cache.items[scaledIndex];
|
|
415
|
+
if (item && this._isExpanded(item)) {
|
|
416
|
+
cache.ensureSubCacheForScaledIndex(scaledIndex);
|
|
417
|
+
}
|
|
418
|
+
});
|
|
419
|
+
|
|
420
|
+
this._hasData = true;
|
|
421
|
+
|
|
422
|
+
// Remove the pending request
|
|
423
|
+
delete cache.pendingRequests[page];
|
|
424
|
+
|
|
425
|
+
// Schedule a debouncer to update the visible rows
|
|
426
|
+
this._debouncerApplyCachedData = Debouncer.debounce(this._debouncerApplyCachedData, timeOut.after(0), () => {
|
|
427
|
+
this._setLoading(false);
|
|
428
|
+
|
|
429
|
+
this._getRenderedRows().forEach((row) => {
|
|
430
|
+
const cachedItem = this._cache.getItemForIndex(row.index);
|
|
431
|
+
if (cachedItem) {
|
|
432
|
+
this._getItem(row.index, row);
|
|
433
|
+
}
|
|
434
|
+
});
|
|
435
|
+
|
|
436
|
+
this.__scrollToPendingIndexes();
|
|
437
|
+
this.__dispatchPendingBodyCellFocus();
|
|
438
|
+
});
|
|
439
|
+
|
|
440
|
+
// If the grid is not loading anything, flush the debouncer immediately
|
|
441
|
+
if (!this._cache.isLoading()) {
|
|
442
|
+
this._debouncerApplyCachedData.flush();
|
|
443
|
+
}
|
|
287
444
|
|
|
288
|
-
|
|
445
|
+
// Notify that new data has been received
|
|
446
|
+
this._onDataProviderPageLoaded();
|
|
447
|
+
});
|
|
448
|
+
}
|
|
289
449
|
}
|
|
290
450
|
|
|
291
451
|
/** @protected */
|
|
292
|
-
_onDataProviderPageLoaded() {
|
|
293
|
-
// Schedule a debouncer to update the visible rows
|
|
294
|
-
this._debouncerApplyCachedData = Debouncer.debounce(this._debouncerApplyCachedData, timeOut.after(0), () => {
|
|
295
|
-
this._setLoading(false);
|
|
296
|
-
|
|
297
|
-
this._getRenderedRows().forEach((row) => {
|
|
298
|
-
const { item } = this._dataProviderController.getFlatIndexInfo(row.index);
|
|
299
|
-
if (item) {
|
|
300
|
-
this._getItem(row.index, row);
|
|
301
|
-
}
|
|
302
|
-
});
|
|
303
|
-
|
|
304
|
-
this.__scrollToPendingIndexes();
|
|
305
|
-
});
|
|
452
|
+
_onDataProviderPageLoaded() {}
|
|
306
453
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
454
|
+
/**
|
|
455
|
+
* @param {number} index
|
|
456
|
+
* @return {number}
|
|
457
|
+
* @private
|
|
458
|
+
*/
|
|
459
|
+
_getPageForIndex(index) {
|
|
460
|
+
return Math.floor(index / this.pageSize);
|
|
311
461
|
}
|
|
312
462
|
|
|
313
463
|
/**
|
|
314
464
|
* Clears the cached pages and reloads data from dataprovider when needed.
|
|
315
465
|
*/
|
|
316
466
|
clearCache() {
|
|
317
|
-
this.
|
|
467
|
+
this._cache = new ItemCache(this);
|
|
468
|
+
this._cache.size = this.size || 0;
|
|
469
|
+
this._cache.updateSize();
|
|
318
470
|
this._hasData = false;
|
|
319
471
|
this.__updateVisibleRows();
|
|
320
|
-
|
|
472
|
+
|
|
473
|
+
if (!this._effectiveSize) {
|
|
474
|
+
this._loadPage(0, this._cache);
|
|
475
|
+
}
|
|
321
476
|
}
|
|
322
477
|
|
|
323
478
|
/** @private */
|
|
324
479
|
_pageSizeChanged(pageSize, oldPageSize) {
|
|
325
|
-
this._dataProviderController.setPageSize(pageSize);
|
|
326
480
|
if (oldPageSize !== undefined && pageSize !== oldPageSize) {
|
|
327
|
-
this.
|
|
328
|
-
this.__updateVisibleRows();
|
|
329
|
-
this._ensureFirstPageLoaded();
|
|
481
|
+
this.clearCache();
|
|
330
482
|
}
|
|
331
483
|
}
|
|
332
484
|
|
|
@@ -344,11 +496,8 @@ export const DataProviderMixin = (superClass) =>
|
|
|
344
496
|
|
|
345
497
|
/** @private */
|
|
346
498
|
_dataProviderChanged(dataProvider, oldDataProvider) {
|
|
347
|
-
this._dataProviderController.setDataProvider(dataProvider ? dataProvider.bind(this) : null);
|
|
348
|
-
|
|
349
499
|
if (oldDataProvider !== undefined) {
|
|
350
|
-
this.
|
|
351
|
-
this.__updateVisibleRows();
|
|
500
|
+
this.clearCache();
|
|
352
501
|
}
|
|
353
502
|
|
|
354
503
|
this._ensureFirstPageLoaded();
|
|
@@ -365,7 +514,7 @@ export const DataProviderMixin = (superClass) =>
|
|
|
365
514
|
if (!this._hasData) {
|
|
366
515
|
// Load data before adding rows to make sure they have content when
|
|
367
516
|
// rendered for the first time.
|
|
368
|
-
this.
|
|
517
|
+
this._loadPage(0, this._cache);
|
|
369
518
|
}
|
|
370
519
|
}
|
|
371
520
|
|
|
@@ -415,15 +564,39 @@ export const DataProviderMixin = (superClass) =>
|
|
|
415
564
|
// ending up in a loading state. Try scrolling to the index until the target
|
|
416
565
|
// index stabilizes.
|
|
417
566
|
let targetIndex;
|
|
418
|
-
while (targetIndex !== (targetIndex = this.
|
|
567
|
+
while (targetIndex !== (targetIndex = this.__getGlobalFlatIndex(indexes))) {
|
|
419
568
|
this._scrollToFlatIndex(targetIndex);
|
|
420
569
|
}
|
|
421
570
|
|
|
422
|
-
if (this.
|
|
571
|
+
if (this._cache.isLoading() || !this.clientHeight) {
|
|
423
572
|
this.__pendingScrollToIndexes = indexes;
|
|
424
573
|
}
|
|
425
574
|
}
|
|
426
575
|
|
|
576
|
+
/**
|
|
577
|
+
* Recursively returns the globally flat index of the item the given indexes point to.
|
|
578
|
+
* Each index in the array points to a sub-item of the previous index.
|
|
579
|
+
* Using `Infinity` as an index will point to the last item on the level.
|
|
580
|
+
*
|
|
581
|
+
* @param {!Array<number>} indexes
|
|
582
|
+
* @param {!ItemCache} cache
|
|
583
|
+
* @param {number} flatIndex
|
|
584
|
+
* @return {number}
|
|
585
|
+
* @private
|
|
586
|
+
*/
|
|
587
|
+
__getGlobalFlatIndex([levelIndex, ...subIndexes], cache = this._cache, flatIndex = 0) {
|
|
588
|
+
if (levelIndex === Infinity) {
|
|
589
|
+
// Treat Infinity as the last index on the level
|
|
590
|
+
levelIndex = cache.size - 1;
|
|
591
|
+
}
|
|
592
|
+
const flatIndexOnLevel = cache.getFlatIndex(levelIndex);
|
|
593
|
+
const subCache = cache.itemCaches[levelIndex];
|
|
594
|
+
if (subCache && subCache.effectiveSize && subIndexes.length) {
|
|
595
|
+
return this.__getGlobalFlatIndex(subIndexes, subCache, flatIndex + flatIndexOnLevel + 1);
|
|
596
|
+
}
|
|
597
|
+
return flatIndex + flatIndexOnLevel;
|
|
598
|
+
}
|
|
599
|
+
|
|
427
600
|
/** @private */
|
|
428
601
|
__scrollToPendingIndexes() {
|
|
429
602
|
if (this.__pendingScrollToIndexes && this.$.items.children.length) {
|
|
@@ -112,7 +112,7 @@ export const DynamicColumnsMixin = (superClass) =>
|
|
|
112
112
|
if (hasColumnElements(info.addedNodes) || hasColumnElements(info.removedNodes)) {
|
|
113
113
|
const allRemovedCells = info.removedNodes.flatMap((c) => c._allCells);
|
|
114
114
|
const filterNotConnected = (element) =>
|
|
115
|
-
allRemovedCells.filter((cell) => cell._content.contains(element)).length;
|
|
115
|
+
allRemovedCells.filter((cell) => cell && cell._content.contains(element)).length;
|
|
116
116
|
|
|
117
117
|
this.__removeSorters(this._sorters.filter(filterNotConnected));
|
|
118
118
|
this.__removeFilters(this._filters.filter(filterNotConnected));
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
5
|
*/
|
|
6
6
|
import './vaadin-grid-filter.js';
|
|
7
|
+
import { defineCustomElement } from '@vaadin/component-base/src/define.js';
|
|
7
8
|
import { GridColumn } from './vaadin-grid-column.js';
|
|
8
9
|
|
|
9
10
|
/**
|
|
@@ -18,6 +19,9 @@ import { GridColumn } from './vaadin-grid-column.js';
|
|
|
18
19
|
* <vaadin-grid-column>
|
|
19
20
|
* ...
|
|
20
21
|
* ```
|
|
22
|
+
*
|
|
23
|
+
* @customElement
|
|
24
|
+
* @extends GridColumn
|
|
21
25
|
*/
|
|
22
26
|
class GridFilterColumn extends GridColumn {
|
|
23
27
|
static get is() {
|
|
@@ -114,6 +118,6 @@ class GridFilterColumn extends GridColumn {
|
|
|
114
118
|
}
|
|
115
119
|
}
|
|
116
120
|
|
|
117
|
-
|
|
121
|
+
defineCustomElement(GridFilterColumn);
|
|
118
122
|
|
|
119
123
|
export { GridFilterColumn };
|
|
@@ -8,6 +8,7 @@ import { html, PolymerElement } from '@polymer/polymer/polymer-element.js';
|
|
|
8
8
|
import { timeOut } from '@vaadin/component-base/src/async.js';
|
|
9
9
|
import { ControllerMixin } from '@vaadin/component-base/src/controller-mixin.js';
|
|
10
10
|
import { Debouncer } from '@vaadin/component-base/src/debounce.js';
|
|
11
|
+
import { defineCustomElement } from '@vaadin/component-base/src/define.js';
|
|
11
12
|
import { SlotController } from '@vaadin/component-base/src/slot-controller.js';
|
|
12
13
|
|
|
13
14
|
/**
|
|
@@ -35,6 +36,7 @@ import { SlotController } from '@vaadin/component-base/src/slot-controller.js';
|
|
|
35
36
|
*
|
|
36
37
|
* @fires {CustomEvent} value-changed - Fired when the `value` property changes.
|
|
37
38
|
*
|
|
39
|
+
* @customElement
|
|
38
40
|
* @extends HTMLElement
|
|
39
41
|
*/
|
|
40
42
|
class GridFilter extends ControllerMixin(PolymerElement) {
|
|
@@ -125,6 +127,6 @@ class GridFilter extends ControllerMixin(PolymerElement) {
|
|
|
125
127
|
}
|
|
126
128
|
}
|
|
127
129
|
|
|
128
|
-
|
|
130
|
+
defineCustomElement(GridFilter);
|
|
129
131
|
|
|
130
132
|
export { GridFilter };
|