All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
io.graphenee.vaadin.AbstractEntityListPanel Maven / Gradle / Ivy
Go to download
Set of useful Vaadin prebuilt components, views and UIs.
/*******************************************************************************
* Copyright (c) 2016, 2018 Farrukh Ijaz
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*******************************************************************************/
package io.graphenee.vaadin;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.function.Function;
import javax.annotation.PostConstruct;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.vaadin.dialogs.ConfirmDialog;
import org.vaadin.gridutil.cell.GridCellFilter;
import org.vaadin.viritin.button.DownloadButton;
import org.vaadin.viritin.button.MButton;
import org.vaadin.viritin.grid.MGrid;
import org.vaadin.viritin.label.MLabel;
import org.vaadin.viritin.layouts.MHorizontalLayout;
import org.vaadin.viritin.layouts.MPanel;
import org.vaadin.viritin.layouts.MVerticalLayout;
import org.vaadin.viritin.ui.MNotification;
import com.google.common.base.Strings;
import com.vaadin.addon.contextmenu.ContextMenu;
import com.vaadin.addon.contextmenu.GridContextMenu;
import com.vaadin.data.util.BeanItem;
import com.vaadin.data.util.BeanItemContainer;
import com.vaadin.event.ItemClickEvent;
import com.vaadin.event.SelectionEvent;
import com.vaadin.server.FontAwesome;
import com.vaadin.spring.annotation.SpringComponent;
import com.vaadin.ui.AbstractLayout;
import com.vaadin.ui.AbstractOrderedLayout;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Component;
import com.vaadin.ui.Grid.CellReference;
import com.vaadin.ui.Grid.CellStyleGenerator;
import com.vaadin.ui.Grid.Column;
import com.vaadin.ui.Grid.SelectionMode;
import com.vaadin.ui.UI;
import com.vaadin.ui.renderers.DateRenderer;
import com.vaadin.ui.themes.ValoTheme;
import io.graphenee.core.util.TRCalendarUtil;
import io.graphenee.gx.theme.graphenee.GrapheneeTheme;
import io.graphenee.vaadin.component.ExportDataSpreadSheetComponent;
import io.graphenee.vaadin.event.TRItemClickListener;
import io.graphenee.vaadin.renderer.BooleanRenderer;
import io.graphenee.vaadin.util.VaadinUtils;
public abstract class AbstractEntityListPanel extends MPanel {
private static final Logger L = LoggerFactory.getLogger(AbstractEntityListPanel.class);
private Class entityClass;
private boolean isBuilt;
private MGrid mainGrid;
private BeanItemContainer mainGridContainer;
private AbstractLayout toolbar;
private AbstractLayout secondaryToolbar;
private MButton addButton;
private MButton editButton;
private MButton deleteButton;
private MButton searchButton;
private GridCellFilter gridCellFilter;
private Object filter;
private Function onItemClick;
private Function, Boolean> onSelection;
private boolean isSelectionEnabled = true;
private AbstractEntityListPanelDelegate delegate = null;
private TRAbstractSearchForm searchForm = null;
private ExportDataSpreadSheetComponent exportDataSpreadSheetComponent;
private DownloadButton exportDataDownloadButton;
private MVerticalLayout rootLayout;
private boolean rootLayoutMargin = false;
public AbstractEntityListPanel(Class entityClass) {
this.entityClass = entityClass;
if (!isSpringComponent()) {
postConstruct();
}
}
protected boolean isSpringComponent() {
return this.getClass().getAnnotation(SpringComponent.class) != null;
}
@PostConstruct
private void postConstruct() {
postInitialize();
}
protected void postInitialize() {
}
public AbstractEntityListPanel build() {
if (!isBuilt) {
setSizeFull();
setStyleName(ValoTheme.PANEL_BORDERLESS);
setCaption(panelCaption());
mainGrid = buildMainGrid();
addButton = new MButton(FontAwesome.PLUS, localizedSingularValue("New"), event -> {
try {
onAddButtonClick(initializeEntity(entityClass.newInstance()));
} catch (Exception e) {
L.warn(e.getMessage(), e);
}
}).withStyleName(ValoTheme.BUTTON_PRIMARY);
editButton = new MButton(FontAwesome.EDIT, localizedSingularValue("Modify"), event -> {
Collection items = mainGrid.getSelectedRowsWithType();
if (items.size() == 1) {
T item = items.iterator().next();
preEdit(item);
openEditorForm(item);
}
});
editButton.setEnabled(false);
deleteButton = new MButton(FontAwesome.REMOVE, localizedSingularValue("Remove"), event -> {
Collection issues = mainGrid.getSelectedRowsWithType();
if (issues.size() > 0) {
if (shouldShowDeleteConfirmation()) {
ConfirmDialog.show(UI.getCurrent(), "Are you sure to remove selected records?", e -> {
if (e.isConfirmed()) {
for (Iterator itemIterator = issues.iterator(); itemIterator.hasNext();) {
T item = itemIterator.next();
try {
if (onDeleteEntity(item)) {
mainGridContainer.removeItem(item);
if (delegate != null) {
delegate.onDelete(item);
}
}
} catch (Exception e1) {
if (e1.getMessage().contains("ConstraintViolationException"))
MNotification.tray("Operation Denied", "Record is in use therefore cannot be removed.");
else
MNotification.tray("Operation Failed", e1.getMessage());
}
}
// refresh();
deselectAll();
mainGrid.refreshAllRows();
}
});
}
else {
for (Iterator itemIterator = issues.iterator(); itemIterator.hasNext();) {
T item = itemIterator.next();
if (onDeleteEntity(item)) {
mainGridContainer.removeItem(item);
}
}
// refresh();
deselectAll();
mainGrid.refreshAllRows();
}
}
});
deleteButton.withStyleName(ValoTheme.BUTTON_DANGER);
deleteButton.setEnabled(false);
searchButton = new MButton(FontAwesome.SEARCH, localizedSingularValue("Search"), event -> {
try {
searchForm.openInModalPopup();
} catch (Exception e) {
L.warn(e.getMessage(), e);
}
});
exportDataSpreadSheetComponent = new ExportDataSpreadSheetComponent();
exportDataSpreadSheetComponent.withColumnsCaptions(() -> {
return getGridHeaderCaptionList();
});
exportDataSpreadSheetComponent.withDataColumns(() -> {
List columnList = new ArrayList<>();
entityGrid().getColumns().forEach(column -> {
if (!column.isHidden()) {
columnList.add(column.getPropertyId().toString());
}
});
return columnList;
}).withDataItems(() -> {
Collection selectedRows = entityGrid().getSelectedRows();
if (selectedRows.size() > 0) {
return selectedRows;
}
return new ArrayList<>(mainGridContainer.getItemIds());
});
exportDataDownloadButton = exportDataSpreadSheetComponent.getDownloadButton();
exportDataDownloadButton.setVisible(shouldShowExportDataButton());
toolbar = buildToolbar();
if (toolbar.getComponentCount() == 0)
toolbar.setVisible(false);
secondaryToolbar = buildSecondaryToolbar();
if (secondaryToolbar.getComponentCount() == 0)
secondaryToolbar.setVisible(false);
rootLayout = new MVerticalLayout().withMargin(rootLayoutMargin);
rootLayout.setSizeFull();
rootLayout.addComponents(toolbar, secondaryToolbar, mainGrid);
rootLayout.setExpandRatio(mainGrid, 1);
setContent(rootLayout);
postBuild();
isBuilt = true;
}
return this;
}
private MGrid buildMainGrid() {
MGrid grid = new MGrid<>(entityClass);
mainGridContainer = new BeanItemContainer<>(entityClass);
grid.setContainerDataSource(mainGridContainer);
grid.setSizeFull();
String[] visibleProperties = visibleProperties();
if (visibleProperties != null) {
for (String propertyId : visibleProperties()) {
if (propertyId.contains(".")) {
mainGridContainer.addNestedContainerProperty(propertyId);
}
}
grid.withProperties(visibleProperties());
}
if (isGridCellFilterEnabled()) {
gridCellFilter = new GridCellFilter(grid);
if (visibleProperties != null) {
addCellFiltersForVisibleProperties(gridCellFilter, visibleProperties);
}
}
grid.getColumns().forEach(column -> {
column.setHidable(true);
applyRendererForColumn(column);
});
grid.setSelectionMode(isSelectionEnabled ? SelectionMode.MULTI : SelectionMode.NONE);
grid.addItemClickListener(new TRItemClickListener() {
@Override
public void onItemClick(ItemClickEvent event) {
if (event.getPropertyId() != null) {
BeanItem item = mainGridContainer.getItem(event.getItemId());
if (item != null) {
if (onItemClick != null) {
Boolean value = onItemClick.apply(item.getBean());
if (value != null && value == true) {
onGridItemClicked(item.getBean(), event.getPropertyId() != null ? event.getPropertyId().toString() : "");
}
} else {
onGridItemClicked(item.getBean(), event.getPropertyId() != null ? event.getPropertyId().toString() : "");
}
}
}
}
});
grid.addSelectionListener(event -> {
if (onSelection != null) {
Boolean value = onSelection.apply((Collection) event.getSelected());
if (value != null && value == true) {
onGridItemSelect(event);
}
} else {
onGridItemSelect(event);
}
});
grid.getColumns().forEach(column -> {
if (column.getPropertyId() != null) {
column.setHeaderCaption(localizedSingularValue(column.getHeaderCaption()));
}
});
grid.setCellStyleGenerator(new CellStyleGenerator() {
@Override
public String getStyle(CellReference cell) {
if (cell.getPropertyId() == null) {
return GrapheneeTheme.STYLE_V_ALIGN_CENTER;
}
String cellStyle = generateCellStyle(cell);
Alignment alignment = alignmentForProperty(cell.getPropertyId().toString());
if (Strings.isNullOrEmpty(cellStyle)) {
if (alignment.isLeft()) {
return GrapheneeTheme.STYLE_V_ALIGN_LEFT;
}
if (alignment.isRight()) {
return GrapheneeTheme.STYLE_V_ALIGN_RIGHT;
}
return GrapheneeTheme.STYLE_V_ALIGN_CENTER;
} else {
if (alignment.isLeft()) {
return GrapheneeTheme.STYLE_V_ALIGN_LEFT + " " + cellStyle;
}
if (alignment.isRight()) {
return GrapheneeTheme.STYLE_V_ALIGN_RIGHT + " " + cellStyle;
}
return GrapheneeTheme.STYLE_V_ALIGN_CENTER + " " + cellStyle;
}
}
});
GridContextMenu contextMenu = new GridContextMenu(grid);
contextMenu.addGridBodyContextMenuListener(event -> {
event.getContextMenu().removeItems();
addMenuItemsToContextMenu(contextMenu, (T) event.getItemId(), grid.getSelectedRowsWithType());
});
return grid;
}
protected void addMenuItemsToContextMenu(ContextMenu contextMenu, T item, Collection selectedItems) {
}
protected String generateCellStyle(CellReference cell) {
return null;
}
protected void applyRendererForColumn(Column column) {
if (column.getPropertyId() != null) {
if (column.getPropertyId().toString().matches("(is|should|has)[A-Z].*")) {
column.setMaximumWidth(150);
column.setRenderer(new BooleanRenderer(event -> {
if (event.getPropertyId() != null) {
onGridItemClicked((T) event.getItemId(), event.getPropertyId().toString());
} else {
onGridItemClicked((T) event.getItemId(), "");
}
}), BooleanRenderer.CHECK_BOX_CONVERTER);
} else if ((column.getPropertyId().toString().matches("(date|since)") || column.getPropertyId().toString().matches("(date|since)[A-Z].*")
|| column.getPropertyId().toString().matches(".*[a-z](Date|Since)"))) {
column.setRenderer(new DateRenderer(applyDateFormatForProperty(column.getPropertyId().toString())));
} else if ((column.getPropertyId().toString().equalsIgnoreCase("time") || column.getPropertyId().toString().matches("(time)[A-Z].*")
|| column.getPropertyId().toString().matches(".*[a-z](Time)"))) {
column.setRenderer(new DateRenderer(applyDateTimeFormatForProperty(column.getPropertyId().toString())));
}
}
}
protected DateFormat applyDateFormatForProperty(String propertyId) {
return TRCalendarUtil.dateFormatter;
}
protected DateFormat applyDateTimeFormatForProperty(String propertyId) {
return TRCalendarUtil.dateTimeFormatter;
}
protected Alignment alignmentForProperty(String propertyId) {
if (propertyId.matches("(is|should|has)[A-Z].*")) {
return Alignment.MIDDLE_LEFT;
}
if (propertyId.matches("(cost|price|sum|amount|percent)")) {
return Alignment.MIDDLE_RIGHT;
}
if (propertyId.matches("(cost|price|sum|amount|percent)[A-Z].*")) {
return Alignment.MIDDLE_RIGHT;
}
if (propertyId.matches(".*(Cost|Price|Sum|Amount|Percent)")) {
return Alignment.MIDDLE_RIGHT;
}
return Alignment.MIDDLE_LEFT;
}
protected void onGridItemSelect(SelectionEvent event) {
editButton.setEnabled(event.getSelected().size() == 1);
deleteButton.setEnabled(event.getSelected().size() > 0);
if (delegate != null) {
delegate.onGridItemSelect(event);
}
}
protected void addCellFiltersForVisibleProperties(GridCellFilter filter, String[] visibleProperties) {
for (String visibleProperty : visibleProperties) {
filter.setTextFilter(visibleProperty, true, false);
}
}
protected boolean isGridCellFilterEnabled() {
return false;
}
private AbstractLayout buildToolbar() {
MHorizontalLayout layout = new MHorizontalLayout().withStyleName("toolbar").withDefaultComponentAlignment(Alignment.BOTTOM_LEFT).withFullWidth().withMargin(false)
.withSpacing(true);
layout.add(addButton);
layout.add(editButton);
layout.add(deleteButton);
layout.add(searchButton);
searchButton.setVisible(false);
layout.add(exportDataDownloadButton);
addButtonsToToolbar(layout);
boolean addSpacer = true;
Iterator iter = layout.iterator();
while (iter.hasNext()) {
Component c = iter.next();
if (layout.getExpandRatio(c) > 0) {
addSpacer = false;
break;
}
}
if (addSpacer) {
MLabel spacerLabel = new MLabel().withStyleName(ValoTheme.LABEL_NO_MARGIN);
layout.addComponent(spacerLabel);
layout.setExpandRatio(spacerLabel, 1);
}
// localize...
localizeRecursively(layout);
VaadinUtils.applyStyleRecursively(layout, "small");
return layout;
}
private AbstractLayout buildSecondaryToolbar() {
MHorizontalLayout layout = new MHorizontalLayout().withStyleName("toolbar").withDefaultComponentAlignment(Alignment.BOTTOM_LEFT).withFullWidth().withMargin(false)
.withSpacing(true);
addButtonsToSecondaryToolbar(layout);
boolean addSpacer = true;
Iterator iter = layout.iterator();
layout.setVisible(layout.getComponentCount() > 0);
while (iter.hasNext()) {
Component c = iter.next();
if (layout.getExpandRatio(c) > 0) {
addSpacer = false;
break;
}
}
if (addSpacer) {
MLabel spacerLabel = new MLabel().withStyleName(ValoTheme.LABEL_NO_MARGIN);
layout.addComponent(spacerLabel);
layout.setExpandRatio(spacerLabel, 1);
}
// localize...
localizeRecursively(layout);
VaadinUtils.applyStyleRecursively(layout, "small");
return layout;
}
private List getGridHeaderCaptionList() {
List columnList = new ArrayList<>();
entityGrid().getColumns().forEach(column -> {
if (!column.isHidden()) {
columnList.add(column.getHeaderCaption());
}
});
return columnList;
}
protected DownloadButton getDownloadButton() {
if (exportDataSpreadSheetComponent != null) {
return exportDataSpreadSheetComponent.getDownloadButton();
}
return null;
}
protected boolean shouldShowExportDataButton() {
return false;
}
protected void preEdit(T item) {
}
protected void onAddButtonClick(T entity) {
preEdit(entity);
openEditorForm(entity);
}
protected boolean shouldShowDeleteConfirmation() {
return false;
}
private void openEditorForm(T item) {
if (editorForm() != null) {
// BeanItem beanItem = mainGridContainer.getItem(item);
// if (beanItem == null) {
// cachedForm().setEntity(entityClass, item);
// } else {
// cachedForm().setEntity(entityClass, beanItem.getBean());
// }
editorForm().setEntity(entityClass, item);
editorForm().setSavedHandler(entity -> {
try {
if (onSaveEntity(entity)) {
if (delegate != null) {
delegate.onSave(entity);
}
editorForm().closePopup();
// UI.getCurrent().access(() -> {
// if (!mainGridContainer.containsId(entity)) {
// mainGridContainer.addBean(entity);
// }
// mainGrid.clearSortOrder();
// UI.getCurrent().push();
// });
refresh();
}
} catch (Exception e) {
L.warn(e.getMessage(), e);
}
});
editorForm().openInModalPopup();
}
}
protected T initializeEntity(T item) {
return item;
}
protected abstract boolean onSaveEntity(T entity);
protected abstract boolean onDeleteEntity(T entity);
public AbstractEntityListPanel refresh() {
if (filter != null) {
return refresh(filter);
}
UI.getCurrent().access(() -> {
deselectAll();
List entities = fetchEntities();
mainGridContainer.removeAllItems();
if (entities != null) {
mainGridContainer.addAll(entities);
}
UI.getCurrent().push();
});
return this;
}
public AbstractEntityListPanel refresh(F filter) {
this.filter = filter;
UI.getCurrent().access(() -> {
deselectAll();
List entities = postFetch(fetchEntities(filter));
mainGridContainer.removeAllItems();
mainGridContainer.addAll(entities);
UI.getCurrent().push();
});
return this;
}
protected List postFetch(List fetchedEntities) {
return fetchedEntities;
}
protected abstract String panelCaption();
protected abstract List fetchEntities();
protected List fetchEntities(F filter) {
return fetchEntities();
}
protected abstract String[] visibleProperties();
protected abstract TRAbstractForm editorForm();
protected void postBuild() {
}
protected MGrid entityGrid() {
return mainGrid;
}
protected void setAddButtonVisibility(boolean visibility) {
if (addButton != null) {
addButton.setVisible(visibility);
}
}
protected void setEditButtonVisibility(boolean visibility) {
if (editButton != null) {
editButton.setVisible(visibility);
}
}
protected void setDeleteButtonVisibility(boolean visibility) {
if (deleteButton != null) {
deleteButton.setVisible(visibility);
}
}
protected void setAddButtonEnable(boolean isEnable) {
if (addButton != null) {
addButton.setEnabled(isEnable);
}
}
protected void setDeleteButtonEnable(boolean isEnable) {
if (deleteButton != null) {
deleteButton.setEnabled(isEnable);
}
}
protected void addButtonsToToolbar(AbstractOrderedLayout toolbar) {
}
protected void addButtonsToSecondaryToolbar(AbstractOrderedLayout toolbar) {
}
protected void onGridItemClicked(T item) {
preEdit(item);
openEditorForm(item);
}
protected void onGridItemClicked(T item, String propertyId) {
onGridItemClicked(item);
}
public > R withItemClick(Function onItemClick) {
this.onItemClick = onItemClick;
return (R) this;
}
public > R withSelection(Function, Boolean> onSelection) {
this.onSelection = onSelection;
return (R) this;
}
public AbstractEntityListPanel clearFilter() {
filter = null;
return this;
}
public AbstractEntityListPanel withToolbarVisibility(boolean visibility) {
toolbar.setVisible(visibility);
return this;
}
public AbstractEntityListPanel withSelectionEnabled(boolean isSelectionEnabled) {
this.isSelectionEnabled = isSelectionEnabled;
mainGrid.setSelectionMode(isSelectionEnabled ? SelectionMode.MULTI : SelectionMode.NONE);
return this;
}
public AbstractEntityListPanel withMargin(boolean margins) {
this.rootLayoutMargin = margins;
if (rootLayout != null)
rootLayout.setMargin(margins);
return this;
}
public AbstractEntityListPanel withDelegate(AbstractEntityListPanelDelegate delegate) {
setDelegate(delegate);
return this;
}
public void setDelegate(AbstractEntityListPanelDelegate delegate) {
this.delegate = delegate;
}
public AbstractEntityListPanel withSearchForm(TRAbstractSearchForm searchForm) {
setSearchForm(searchForm);
return this;
}
public void setSearchForm(TRAbstractSearchForm searchForm) {
this.searchForm = searchForm;
if (searchButton != null) {
searchButton.setVisible(searchForm != null);
}
}
public static interface AbstractEntityListPanelDelegate {
default void onGridItemSelect(SelectionEvent event) {
}
default void onSave(Object entity) {
}
default void onDelete(Object entity) {
}
}
protected String localizedSingularValue(String key) {
return VaadinUtils.localizedSingularValue(key);
}
protected String localizedPluralValue(String key) {
return VaadinUtils.localizedSingularValue(key);
}
protected void localizeRecursively(Component component) {
VaadinUtils.localizeRecursively(component);
}
protected String localizedSingularValue(Locale locale, String key) {
return VaadinUtils.localizedSingularValue(key);
}
protected String localizedPluralValue(Locale locale, String key) {
return VaadinUtils.localizedSingularValue(key);
}
protected void localizeRecursively(Locale locale, Component component) {
VaadinUtils.localizeRecursively(component);
}
public void deselectAll() {
try {
entityGrid().deselectAll();
} catch (Exception e) {
}
}
public void showToolbar() {
toolbar.setVisible(true);
}
public void hideToolbar() {
toolbar.setVisible(false);
}
public void showSecondaryToolbar() {
secondaryToolbar.setVisible(true);
}
public void hideSecondaryToolbar() {
secondaryToolbar.setVisible(false);
}
public void showMargin() {
rootLayoutMargin = true;
rootLayout.setMargin(true);
}
public void hideMargin() {
rootLayoutMargin = false;
rootLayout.setMargin(false);
}
public MButton getAddButton() {
return addButton;
}
public MButton getEditButton() {
return editButton;
}
public MButton getDeleteButton() {
return deleteButton;
}
}