package.src.vaadin-grid-dynamic-columns-mixin.js Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of grid Show documentation
Show all versions of grid Show documentation
A free, flexible and high-quality Web Component for showing large amounts of tabular data
/**
* @license
* Copyright (c) 2016 - 2023 Vaadin Ltd.
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
*/
import { microTask, timeOut } from '@vaadin/component-base/src/async.js';
import { Debouncer } from '@vaadin/component-base/src/debounce.js';
import { ColumnObserver, updateCellState } from './vaadin-grid-helpers.js';
function arrayEquals(arr1, arr2) {
if (!arr1 || !arr2 || arr1.length !== arr2.length) {
return false;
}
for (let i = 0, l = arr1.length; i < l; i++) {
// Check if we have nested arrays
if (arr1[i] instanceof Array && arr2[i] instanceof Array) {
// Recurse into the nested arrays
if (!arrayEquals(arr1[i], arr2[i])) {
return false;
}
} else if (arr1[i] !== arr2[i]) {
return false;
}
}
return true;
}
/**
* @polymerMixin
*/
export const DynamicColumnsMixin = (superClass) =>
class DynamicColumnsMixin extends superClass {
static get properties() {
return {
/**
* @protected
*/
_columnTree: Object,
};
}
/** @protected */
ready() {
super.ready();
this._addNodeObserver();
}
/** @private */
_hasColumnGroups(columns) {
return columns.some((column) => column.localName === 'vaadin-grid-column-group');
}
/**
* @param {!GridColumnGroup} el
* @return {!Array}
* @protected
*/
_getChildColumns(el) {
return ColumnObserver.getColumns(el);
}
/** @private */
_flattenColumnGroups(columns) {
return columns
.map((col) => {
if (col.localName === 'vaadin-grid-column-group') {
return this._getChildColumns(col);
}
return [col];
})
.reduce((prev, curr) => {
return prev.concat(curr);
}, []);
}
/** @private */
_getColumnTree() {
const rootColumns = ColumnObserver.getColumns(this);
const columnTree = [rootColumns];
let c = rootColumns;
while (this._hasColumnGroups(c)) {
c = this._flattenColumnGroups(c);
columnTree.push(c);
}
return columnTree;
}
/** @protected */
_debounceUpdateColumnTree() {
this.__updateColumnTreeDebouncer = Debouncer.debounce(this.__updateColumnTreeDebouncer, microTask, () =>
this._updateColumnTree(),
);
}
/** @protected */
_updateColumnTree() {
const columnTree = this._getColumnTree();
if (!arrayEquals(columnTree, this._columnTree)) {
// Request a synchronoys update for each column
columnTree.forEach((columnArray) => {
columnArray.forEach((column) => {
if (column.performUpdate) {
column.performUpdate();
}
});
});
this._columnTree = columnTree;
}
}
/** @private */
_addNodeObserver() {
this._observer = new ColumnObserver(this, (_addedColumns, removedColumns) => {
const allRemovedCells = removedColumns.flatMap((c) => c._allCells);
const filterNotConnected = (element) =>
allRemovedCells.filter((cell) => cell && cell._content.contains(element)).length;
this.__removeSorters(this._sorters.filter(filterNotConnected));
this.__removeFilters(this._filters.filter(filterNotConnected));
this._debounceUpdateColumnTree();
this._debouncerCheckImports = Debouncer.debounce(
this._debouncerCheckImports,
timeOut.after(2000),
this._checkImports.bind(this),
);
this._ensureFirstPageLoaded();
});
}
/** @protected */
_checkImports() {
[
'vaadin-grid-column-group',
'vaadin-grid-filter',
'vaadin-grid-filter-column',
'vaadin-grid-tree-toggle',
'vaadin-grid-selection-column',
'vaadin-grid-sort-column',
'vaadin-grid-sorter',
].forEach((elementName) => {
const element = this.querySelector(elementName);
if (element && !customElements.get(elementName)) {
console.warn(`Make sure you have imported the required module for <${elementName}> element.`);
}
});
}
/** @protected */
_updateFirstAndLastColumn() {
Array.from(this.shadowRoot.querySelectorAll('tr')).forEach((row) => this._updateFirstAndLastColumnForRow(row));
}
/**
* @param {!HTMLElement} row
* @protected
*/
_updateFirstAndLastColumnForRow(row) {
Array.from(row.querySelectorAll('[part~="cell"]:not([part~="details-cell"])'))
.sort((a, b) => {
return a._column._order - b._column._order;
})
.forEach((cell, cellIndex, children) => {
updateCellState(cell, 'first-column', cellIndex === 0);
updateCellState(cell, 'last-column', cellIndex === children.length - 1);
});
}
/**
* @param {!Node} node
* @return {boolean}
* @protected
*/
_isColumnElement(node) {
return node.nodeType === Node.ELEMENT_NODE && /\bcolumn\b/u.test(node.localName);
}
};