From 88cb3bd473070ff383c11e0b8ee591249c0c32f5 Mon Sep 17 00:00:00 2001 From: Paola De Bartolo Date: Fri, 14 Jan 2022 16:25:49 -0300 Subject: [PATCH] feat: upgrade so component works with vaadin 22 Close #11 --- enhanced-grid-flow-demo/pom.xml | 6 +- enhanced-grid-flow/pom.xml | 6 +- .../enhancedgrid/EnhancedGrid.java | 8 +- .../enhancedtreegrid/EnhancedTreeGrid.java | 226 ++++++++++++++++-- .../GridSorterFilterComponentRenderer.java | 2 +- .../src/custom-grid-flow-selection-column.js | 97 ++++---- .../frontend/src/enhanced-grid-sorter.js | 60 ++--- pom.xml | 6 +- 8 files changed, 307 insertions(+), 104 deletions(-) diff --git a/enhanced-grid-flow-demo/pom.xml b/enhanced-grid-flow-demo/pom.xml index 6bca45d..07ba96f 100644 --- a/enhanced-grid-flow-demo/pom.xml +++ b/enhanced-grid-flow-demo/pom.xml @@ -6,7 +6,7 @@ com.vaadin.componentfactory enhanced-grid-flow-demo - 0.9.1 + 2.0.0 Enhanced Grid Demo war @@ -18,7 +18,7 @@ - 14.4.4 + 22.0.2 1.8 1.8 UTF-8 @@ -106,7 +106,7 @@ com.vaadin.componentfactory enhanced-grid-flow - 0.9.1 + ${project.version} diff --git a/enhanced-grid-flow/pom.xml b/enhanced-grid-flow/pom.xml index e699107..dc0e8d3 100644 --- a/enhanced-grid-flow/pom.xml +++ b/enhanced-grid-flow/pom.xml @@ -6,7 +6,7 @@ com.vaadin.componentfactory enhanced-grid-flow - 0.9.1 + 2.0.0 jar Enhanced Grid @@ -19,7 +19,7 @@ - 14.4.4 + 22.0.2 1.8 1.8 UTF-8 @@ -104,7 +104,7 @@ com.vaadin.componentfactory popup - 2.2.4 + 3.0.0 diff --git a/enhanced-grid-flow/src/main/java/com/vaadin/componentfactory/enhancedgrid/EnhancedGrid.java b/enhanced-grid-flow/src/main/java/com/vaadin/componentfactory/enhancedgrid/EnhancedGrid.java index c795107..1a21832 100644 --- a/enhanced-grid-flow/src/main/java/com/vaadin/componentfactory/enhancedgrid/EnhancedGrid.java +++ b/enhanced-grid-flow/src/main/java/com/vaadin/componentfactory/enhancedgrid/EnhancedGrid.java @@ -175,7 +175,7 @@ protected > B dataCommunicatorBuilder) { super(pageSize, updateQueueBuilder, dataCommunicatorBuilder); } - + /** * Define if an item can be selected. * @@ -193,14 +193,14 @@ public SerializablePredicate getSelectionPredicate() { public void setSelectionPredicate(SerializablePredicate selectionPredicate) { this.selectionPredicate = selectionPredicate; if (generateSelectionGenerator != null) { - removeDataGenerator(generateSelectionGenerator); + generateSelectionGenerator.destroyAllData(); } generateSelectionGenerator = this::generateSelectionAccess; addDataGenerator(generateSelectionGenerator); - + super.setClassNameGenerator(item -> selectionDisabled.apply(item).concat(" ").concat(defaultClassNameGenerator.apply(item))); } - + @Override public void setClassNameGenerator(SerializableFunction classNameGenerator) { defaultClassNameGenerator = classNameGenerator; diff --git a/enhanced-grid-flow/src/main/java/com/vaadin/componentfactory/enhancedtreegrid/EnhancedTreeGrid.java b/enhanced-grid-flow/src/main/java/com/vaadin/componentfactory/enhancedtreegrid/EnhancedTreeGrid.java index 1c985d3..b711588 100644 --- a/enhanced-grid-flow/src/main/java/com/vaadin/componentfactory/enhancedtreegrid/EnhancedTreeGrid.java +++ b/enhanced-grid-flow/src/main/java/com/vaadin/componentfactory/enhancedtreegrid/EnhancedTreeGrid.java @@ -41,22 +41,29 @@ import com.vaadin.flow.component.grid.Grid; import com.vaadin.flow.component.grid.GridArrayUpdater; import com.vaadin.flow.component.grid.GridArrayUpdater.UpdateQueueData; +import com.vaadin.flow.component.grid.dataview.GridDataView; +import com.vaadin.flow.component.grid.dataview.GridLazyDataView; +import com.vaadin.flow.component.grid.dataview.GridListDataView; import com.vaadin.flow.component.treegrid.CollapseEvent; import com.vaadin.flow.component.treegrid.ExpandEvent; import com.vaadin.flow.component.treegrid.HierarchyColumnComponentRenderer; import com.vaadin.flow.component.treegrid.TreeGrid; import com.vaadin.flow.component.treegrid.TreeGridArrayUpdater; import com.vaadin.flow.data.binder.PropertyDefinition; +import com.vaadin.flow.data.provider.BackEndDataProvider; +import com.vaadin.flow.data.provider.CallbackDataProvider; import com.vaadin.flow.data.provider.CompositeDataGenerator; import com.vaadin.flow.data.provider.DataChangeEvent; import com.vaadin.flow.data.provider.DataCommunicator; import com.vaadin.flow.data.provider.DataProvider; +import com.vaadin.flow.data.provider.ListDataProvider; import com.vaadin.flow.data.provider.hierarchy.HasHierarchicalDataProvider; import com.vaadin.flow.data.provider.hierarchy.HierarchicalArrayUpdater.HierarchicalUpdate; import com.vaadin.flow.data.provider.hierarchy.HierarchicalConfigurableFilterDataProvider; import com.vaadin.flow.data.provider.hierarchy.HierarchicalDataCommunicator; import com.vaadin.flow.data.provider.hierarchy.HierarchicalDataProvider; import com.vaadin.flow.data.provider.hierarchy.HierarchicalQuery; +import com.vaadin.flow.data.provider.hierarchy.TreeData; import com.vaadin.flow.data.provider.hierarchy.TreeDataProvider; import com.vaadin.flow.data.renderer.ComponentRenderer; import com.vaadin.flow.data.renderer.Renderer; @@ -286,24 +293,190 @@ public Registration addCollapseListener( } @Override - public void setDataProvider(DataProvider dataProvider) { - if (!(dataProvider instanceof HierarchicalDataProvider)) { - throw new IllegalArgumentException( - "TreeGrid only accepts hierarchical data providers. " - + "An example of interface to be used: HierarchicalDataProvider"); - } - if (dataProviderRegistration != null) { - dataProviderRegistration.remove(); - } - dataProviderRegistration = dataProvider.addDataProviderListener(e -> { - if (!(e instanceof DataChangeEvent.DataRefreshEvent)) { - // refreshAll was called - getElement().callJsFunction("$connector.reset"); - } - }); - super.setDataProvider(dataProvider); - } - + public void setDataProvider(DataProvider dataProvider) { + if (dataProvider instanceof HierarchicalDataProvider) { + this.setDataProvider((HierarchicalDataProvider) dataProvider); + } else { + throw new IllegalArgumentException( + "TreeGrid only accepts hierarchical data providers. " + + "An example of interface to be used: HierarchicalDataProvider"); + } + } + + @Override + public void setDataProvider( + HierarchicalDataProvider hierarchicalDataProvider) { + if (dataProviderRegistration != null) { + dataProviderRegistration.remove(); + } + dataProviderRegistration = hierarchicalDataProvider + .addDataProviderListener(e -> { + if (!(e instanceof DataChangeEvent.DataRefreshEvent)) { + // refreshAll was called + getElement().executeJs( + "$0.$connector && $0.$connector.reset()", + getElement()); + } + }); + super.setDataProvider(hierarchicalDataProvider); + } + + /** + * Tree grid does not support data views. Use + * {@link #setDataProvider(HierarchicalDataProvider)} instead. This method + * is inherited from Grid and it will throw an + * {@link UnsupportedOperationException}. + * + * @param dataProvider + * the data provider + * @return the data view + * @deprecated use {@link #setDataProvider(HierarchicalDataProvider)}, + * {@link #setItems(Collection, ValueProvider)}, + * {@link #setItems(Stream, ValueProvider)} or + * {@link #setTreeData(TreeData)} instead. + */ + @Deprecated + @Override + public GridLazyDataView setItems( + BackEndDataProvider dataProvider) { + throw new UnsupportedOperationException( + "TreeGrid only accepts hierarchical data providers. " + + "Use another setDataProvider/setItems method instead with hierarchical data." + + "An example of interface to be used: HierarchicalDataProvider"); + } + + /** + * Tree grid supports only hierarchical data so use another method instead. + * This method is inherited from Grid and it will throw an + * {@link UnsupportedOperationException}. + * + * @param fetchCallback + * the fetch callback + * @return the data view + * @deprecated use {@link #setDataProvider(HierarchicalDataProvider)}, + * {@link #setItems(Collection, ValueProvider)}, + * {@link #setItems(Stream, ValueProvider)} or + * {@link #setTreeData(TreeData)} instead. + */ + @Deprecated + @Override + public GridLazyDataView setItems( + CallbackDataProvider.FetchCallback fetchCallback) { + throw new UnsupportedOperationException( + "TreeGrid only accepts hierarchical data providers. " + + "Use another setDataProvider/setItems method instead with hierarchical data." + + "An example of interface to be used: HierarchicalDataProvider"); + } + + /** + * Tree grid supports only hierarchical data providers so use another method + * instead. This method is inherited from Grid and it will throw an + * {@link UnsupportedOperationException}. + * + * @param dataProvider + * the data provider + * @return the data view + * @deprecated use {@link #setDataProvider(HierarchicalDataProvider)}, + * {@link #setItems(Collection, ValueProvider)}, + * {@link #setItems(Stream, ValueProvider)} or + * {@link #setTreeData(TreeData)} instead. + */ + @Deprecated + @Override + public GridListDataView setItems(ListDataProvider dataProvider) { + throw new UnsupportedOperationException( + "TreeGrid only accepts hierarchical data providers. " + + "Use another setDataProvider/setItems method instead with hierarchical data." + + "An example of interface to be used: HierarchicalDataProvider"); + } + + /** + * Tree grid supports only hierarchical data so use another method instead. + * This method is inherited from Grid and it will throw an + * {@link UnsupportedOperationException}. + * + * @param items + * the items to display, not {@code null} + * @return the data view + * @deprecated use {@link #setDataProvider(HierarchicalDataProvider)}, + * {@link #setItems(Collection, ValueProvider)}, + * {@link #setItems(Stream, ValueProvider)} or + * {@link #setTreeData(TreeData)} instead. + */ + @Deprecated + @Override + public GridListDataView setItems(T... items) { + throw new UnsupportedOperationException( + "TreeGrid only accepts hierarchical data providers. " + + "Use another setDataProvider/setItems method instead with hierarchical data." + + "An example of interface to be used: HierarchicalDataProvider"); + } + + /** + * Tree grid supports only hierarchical data, so use another method instead. + * This method is inherited from Grid and it will throw an + * {@link UnsupportedOperationException}. + * + * @param items + * the items to display, not {@code null} + * @return the data view + * @deprecated use {@link #setDataProvider(HierarchicalDataProvider)}, + * {@link #setItems(Collection, ValueProvider)}, + * {@link #setItems(Stream, ValueProvider)} or + * {@link #setTreeData(TreeData)} instead. + */ + @Deprecated + @Override + public GridListDataView setItems(Collection items) { + throw new UnsupportedOperationException( + "TreeGrid only accepts hierarchical data providers. " + + "Use another setDataProvider/setItems method instead with hierarchical data." + + "An example of interface to be used: HierarchicalDataProvider"); + } + + /** + * Tree grid does not support list data view, this will throw an + * {@link UnsupportedOperationException}. + * + * @return exception is thrown + * @deprecated not supported + */ + @Deprecated + @Override + public GridListDataView getListDataView() { + throw new UnsupportedOperationException( + "TreeGrid does not support list data view."); + } + + /** + * Tree grid does not support list data view, this will throw an + * {@link UnsupportedOperationException}. + * + * @return exception is thrown + * @deprecated not supported + */ + @Deprecated + @Override + public GridLazyDataView getLazyDataView() { + throw new UnsupportedOperationException( + "TreeGrid does not support lazy data view."); + } + + /** + * Tree grid does not support list data view, this will throw an + * {@link UnsupportedOperationException}. + * + * @return exception is thrown + * @deprecated not supported + */ + @Deprecated + @Override + public GridDataView getGenericDataView() { + throw new UnsupportedOperationException( + "TreeGrid does not support generic data view."); + } + + /** * Adds a new Hierarchy column to this {@link Grid} with a value provider. * The value is converted to String when sent to the client by using @@ -779,6 +952,22 @@ public HierarchicalDataProvider> getDataProvider() { return (HierarchicalDataProvider>) super.getDataProvider(); } + /** + * The effective index of an item depends on the complete hierarchy of the + * tree. {@link TreeGrid} uses lazy loading for performance reasons and does + * not know about the complete hierarchy. Without the knowledge of the + * complete hierarchy, {@link TreeGrid} can’t reliably calculate an exact + * scroll position. This uncertainty makes this method unreliable and so + * should be avoided. + * + * @param rowIndex + * zero based index of the item to scroll to in the current view. + */ + @Override + public void scrollToIndex(int rowIndex) { + super.scrollToIndex(rowIndex); + } + @Override protected void applyFilterPredicate(SerializablePredicate finalPredicate) { DataProvider dataProvider = getDataProvider(); @@ -788,4 +977,5 @@ protected void applyFilterPredicate(SerializablePredicate finalPredicate) { ((HierarchicalConfigurableFilterDataProvider)dataProvider).setFilter(new Filter(finalPredicate)); } } + } diff --git a/enhanced-grid-flow/src/main/java/com/vaadin/flow/component/grid/GridSorterFilterComponentRenderer.java b/enhanced-grid-flow/src/main/java/com/vaadin/flow/component/grid/GridSorterFilterComponentRenderer.java index e02f560..7a545eb 100644 --- a/enhanced-grid-flow/src/main/java/com/vaadin/flow/component/grid/GridSorterFilterComponentRenderer.java +++ b/enhanced-grid-flow/src/main/java/com/vaadin/flow/component/grid/GridSorterFilterComponentRenderer.java @@ -25,9 +25,9 @@ import com.vaadin.componentfactory.enhancedgrid.EnhancedColumn; import com.vaadin.flow.component.Component; import com.vaadin.flow.component.UI; -import com.vaadin.flow.data.provider.ComponentDataGenerator; import com.vaadin.flow.data.provider.DataGenerator; import com.vaadin.flow.data.provider.DataKeyMapper; +import com.vaadin.flow.data.renderer.ComponentDataGenerator; import com.vaadin.flow.data.renderer.ComponentRenderer; import com.vaadin.flow.data.renderer.Rendering; import com.vaadin.flow.dom.Element; diff --git a/enhanced-grid-flow/src/main/resources/META-INF/resources/frontend/src/custom-grid-flow-selection-column.js b/enhanced-grid-flow/src/main/resources/META-INF/resources/frontend/src/custom-grid-flow-selection-column.js index f6e2368..35ac28a 100644 --- a/enhanced-grid-flow/src/main/resources/META-INF/resources/frontend/src/custom-grid-flow-selection-column.js +++ b/enhanced-grid-flow/src/main/resources/META-INF/resources/frontend/src/custom-grid-flow-selection-column.js @@ -17,24 +17,12 @@ * limitations under the License. * #L% */ -import '@vaadin/vaadin-grid/vaadin-grid-column.js'; -import { html } from '@polymer/polymer/lib/utils/html-tag.js'; -import { GridColumnElement } from '@vaadin/vaadin-grid/src/vaadin-grid-column.js'; -{ - class CustomGridFlowSelectionColumnElement extends GridColumnElement { - static get template() { - return html` - - -`; - } +import '@vaadin/grid/vaadin-grid-column.js'; +import { GridColumn } from '@vaadin/grid/src/vaadin-grid-column.js'; +{ + class CustomGridFlowSelectionColumn extends GridColumn { + static get is() { return 'custom-grid-flow-selection-column'; } @@ -84,13 +72,11 @@ import { GridColumnElement } from '@vaadin/vaadin-grid/src/vaadin-grid-column.js this._boundOnSelectEvent = this._onSelectEvent.bind(this); this._boundOnDeselectEvent = this._onDeselectEvent.bind(this); } - - _prepareHeaderTemplate() { - return this._prepareTemplatizer(this.$.defaultHeaderTemplate); - } - - _prepareBodyTemplate() { - return this._prepareTemplatizer(this.$.defaultBodyTemplate); + + static get observers() { + return [ + '_onHeaderRendererOrBindingChanged(_headerRenderer, _headerCell, path, header, selectAll, selectAllHidden)' + ]; } /** @private */ @@ -108,34 +94,60 @@ import { GridColumnElement } from '@vaadin/vaadin-grid/src/vaadin-grid-column.js if (this._grid) { this._grid.removeEventListener('select', this._boundOnSelectEvent); this._grid.removeEventListener('deselect', this._boundOnDeselectEvent); + } + } - const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent); - if (isSafari && window.ShadyDOM && this.parentElement) { - // Detach might have been caused by order change. - // Shady on safari doesn't restore isAttached so we'll need to do it manually. - const parent = this.parentElement; - const nextSibling = this.nextElementSibling; - parent.removeChild(this); - if (nextSibling) { - parent.insertBefore(this, nextSibling); - } else { - parent.appendChild(this); - } - } + /** + * Renders the Select All checkbox to the header cell. + * + * @override + */ + _defaultHeaderRenderer(root, _column) { + let checkbox = root.firstElementChild; + if (!checkbox) { + checkbox = document.createElement('vaadin-checkbox'); + checkbox.id = 'selectAllCheckbox'; + checkbox.setAttribute('aria-label', 'Select All'); + checkbox.classList.add('vaadin-grid-select-all-checkbox'); + checkbox.addEventListener('click', this._onSelectAllClick.bind(this)); + root.appendChild(checkbox); } + + const checked = this.selectAll; + checkbox.hidden = this.selectAllHidden; + checkbox.checked = checked; + } + + /** + * Renders the Select Row checkbox to the body cell. + * + * @override + */ + _defaultRenderer(root, _column, { item, selected }) { + let checkbox = root.firstElementChild; + if (!checkbox) { + checkbox = document.createElement('vaadin-checkbox'); + checkbox.setAttribute('aria-label', 'Select Row'); + checkbox.addEventListener('click', this._onSelectClick.bind(this)); + root.appendChild(checkbox); + } + + checkbox.__item = item; + checkbox.checked = selected; + checkbox.disabled = item.selectionDisabled; } _onSelectClick(e) { if (!e.model.item.selectionDisabled) { - e.target.checked ? this._grid.$connector.doDeselection([e.model.item], true) : this._grid.$connector.doSelection([e.model.item], true); - e.target.checked = !e.target.checked; + e.currentTarget.checked ? this._grid.$connector.doDeselection([e.model.item], true) : this._grid.$connector.doSelection([e.model.item], true); + e.currentTarget.checked = !e.currentTarget.checked; } } _onSelectAllClick(e) { e.preventDefault(); if (this._grid.hasAttribute('disabled')) { - e.target.checked = !e.target.checked; + e.currentTarget.checked = !e.currentTarget.checked; return; } this.selectAll ? this.$server.deselectAll() : this.$server.selectAll(); @@ -151,7 +163,8 @@ import { GridColumnElement } from '@vaadin/vaadin-grid/src/vaadin-grid-column.js } } - customElements.define(CustomGridFlowSelectionColumnElement.is, CustomGridFlowSelectionColumnElement); + customElements.define(CustomGridFlowSelectionColumn.is, CustomGridFlowSelectionColumn); - Vaadin.CustomGridFlowSelectionColumnElement = CustomGridFlowSelectionColumnElement; + Vaadin.CustomGridFlowSelectionColumn = CustomGridFlowSelectionColumn; + } diff --git a/enhanced-grid-flow/src/main/resources/META-INF/resources/frontend/src/enhanced-grid-sorter.js b/enhanced-grid-flow/src/main/resources/META-INF/resources/frontend/src/enhanced-grid-sorter.js index 56a9e21..7e088f7 100644 --- a/enhanced-grid-flow/src/main/resources/META-INF/resources/frontend/src/enhanced-grid-sorter.js +++ b/enhanced-grid-flow/src/main/resources/META-INF/resources/frontend/src/enhanced-grid-sorter.js @@ -22,38 +22,38 @@ * `` is a helper element for the `` that extends `` * adding support to display a button for filtering */ -import { PolymerElement, html } from '@polymer/polymer/polymer-element.js'; -import { GridSorterElement } from '@vaadin/vaadin-grid/vaadin-grid-sorter.js'; +import { html } from '@polymer/polymer/polymer-element.js'; +import { GridSorter } from '@vaadin/grid/vaadin-grid-sorter.js'; -class EnhancedGridSorterElement extends GridSorterElement { +class EnhancedGridSorter extends GridSorter { static get template() { return html` @@ -61,7 +61,7 @@ class EnhancedGridSorterElement extends GridSorterElement { - + `; } @@ -88,7 +88,7 @@ class EnhancedGridSorterElement extends GridSorterElement { /** @private */ _onFilterClick(e) { e.stopPropagation(); - this.dispatchEvent(new CustomEvent('filter-clicked', { bubbles: true, composed: true, detail: { id: e.target.path } })); + this.dispatchEvent(new CustomEvent('filter-clicked', { bubbles: true, composed: true, detail: { id: e.target.parentElement.path } })); } _onClick(e) { @@ -131,6 +131,6 @@ class EnhancedGridSorterElement extends GridSorterElement { } -customElements.define(EnhancedGridSorterElement.is, EnhancedGridSorterElement); +customElements.define(EnhancedGridSorter.is, EnhancedGridSorter); -export { EnhancedGridSorterElement }; +export { EnhancedGridSorter }; diff --git a/pom.xml b/pom.xml index 5fe63b5..11166c0 100755 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ com.vaadin.componentfactory enhanced-grid-flow-root - 0.9.1 + 2.0.0 pom enhanced-grid-flow @@ -13,12 +13,12 @@ enhanced-grid-flow - 14.4.4 + 22.0.2 1.8 1.8 UTF-8 UTF-8 - 0.9.1 + 2.0.0 2020