All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.ocs.dynamo.ui.component.ServiceBasedDetailsEditGrid Maven / Gradle / Ivy

/*
   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 com.ocs.dynamo.ui.component;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.function.Function;

import com.ocs.dynamo.constants.DynamoConstants;
import com.ocs.dynamo.dao.FetchJoinInformation;
import com.ocs.dynamo.domain.AbstractEntity;
import com.ocs.dynamo.domain.model.AttributeModel;
import com.ocs.dynamo.domain.model.EntityModel;
import com.ocs.dynamo.exception.OCSRuntimeException;
import com.ocs.dynamo.filter.EqualsPredicate;
import com.ocs.dynamo.service.BaseService;
import com.ocs.dynamo.ui.CanAssignEntity;
import com.ocs.dynamo.ui.composite.dialog.EntityPopupDialog;
import com.ocs.dynamo.ui.composite.layout.FormOptions;
import com.ocs.dynamo.ui.provider.IdBasedDataProvider;
import com.ocs.dynamo.ui.utils.VaadinUtils;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.grid.GridSortOrder;
import com.vaadin.flow.component.grid.contextmenu.GridContextMenu;
import com.vaadin.flow.data.provider.DataProvider;
import com.vaadin.flow.data.provider.SortOrder;
import com.vaadin.flow.function.SerializablePredicate;

import lombok.Getter;
import lombok.Setter;

/**
 * A grid component that is meant for use inside an edit form. It manages a
 * lazily loaded 1-to-N or N-to-N detail collection
 * 
 * @author Bas Rutten
 *
 * @param   the type of the primary key of the entities
 * @param    the type of the entities
 * @param  the type of the ID of the parent attribute
 * @param    the type of the parent attribute
 */
public class ServiceBasedDetailsEditGrid, ID2 extends Serializable, U extends AbstractEntity>
		extends BaseDetailsEditGrid implements CanAssignEntity {

	private static final long serialVersionUID = -1203245694503350276L;

	/**
	 * The joins to use when exporting (needed when using export mode FULL)
	 */
	@Getter
	@Setter
	private FetchJoinInformation[] exportJoins;

	/**
	 * The search filter to apply
	 */
	private SerializablePredicate filter;

	/**
	 * The code that is carried out to create the filter that is used to limit the
	 * results that show up in the grid
	 */
	@Getter
	@Setter
	private Function> filterCreator;

	/**
	 * The currently selected entity in the edit form that this component is part of
	 */
	private U parent;

	private IdBasedDataProvider provider;

	/**
	 * Constructor
	 * 
	 * @param service        the service for retrieving data from the database
	 * @param entityModel    the entity model
	 * @param attributeModel the attribute model
	 * @param viewMode       whether the component is in view mode
	 * @param formOptions    the form options that govern how the component behaves
	 * @param joins          the joins to apply when fetching data
	 */
	public ServiceBasedDetailsEditGrid(BaseService service, EntityModel entityModel,
			AttributeModel attributeModel, boolean viewMode, FormOptions formOptions, FetchJoinInformation... joins) {
		super(service, entityModel, attributeModel, viewMode, true, formOptions);
		this.provider = new IdBasedDataProvider<>(service, entityModel, joins);
		provider.setAfterCountCompleted(count -> updateCaption(count));

		setOnAdd(() -> {
			if (this.parent.getId() != null) {
				showPopup(null);
			} else {
				// cannot add a new entity if the parent entity has not been saved yet
				VaadinUtils.showErrorNotification(
						getMessageService().getMessage("ocs.save.entity.first", VaadinUtils.getLocale()));
			}
		});
		setOnEdit(this::showPopup);

		build();

	}

	protected void addDownloadMenu() {
		if (getFormOptions().isExportAllowed() && getExportDelegate() != null) {
			GridContextMenu contextMenu = getGrid().addContextMenu();
			Button downloadButton = new Button(getMessageService().getMessage("ocs.download", VaadinUtils.getLocale()));
			downloadButton.addClickListener(event -> {
				List> orders = new ArrayList<>();
				List> so = getGrid().getSortOrder();
				for (GridSortOrder gso : so) {
					orders.add(new SortOrder<>(gso.getSorted().getKey(), gso.getDirection()));
				}
				applyFilter();
				EntityModel em = getExportEntityModel() != null ? getExportEntityModel() : getEntityModel();
				getExportDelegate().export(em, getFormOptions().getExportMode(), filter, orders,
						getExportJoins() != null ? getExportJoins() : null);
			});
			contextMenu.add(downloadButton);
		}
	}

	/**
	 * Applies the search filter to the data provider
	 */
	@Override
	protected void applyFilter() {
		filter = (filterCreator == null || parent == null) ? null : filterCreator.apply(parent);

		// for a new entity without ID you can't filter yet
		if (parent != null && parent.getId() == null) {
			filter = new EqualsPredicate<>(DynamoConstants.ID, -1);
		}
		getGrid().getDataCommunicator().setDataProvider(provider, filter);
	}

	@Override
	public void assignEntity(U u) {
		this.parent = u;
		build();

		if (getGrid() != null) {
			getGrid().deselectAll();
			applyFilter();
		}

		// hide add button for new entity
		getAddButton().setVisible(!isViewMode() && getFormOptions().isShowAddButton()
				&& !getFormOptions().isDetailsGridSearchMode() && this.parent.getId() != null);
	}

	@Override
	protected U generateModelValue() {
		return parent;
	}

	@Override
	protected DataProvider> getDataProvider() {
		return provider;
	}

	public int getItemCount() {
		return provider.getSize();
	}

	@Override
	public U getValue() {
		return parent;
	}

	@Override
	protected void handleDialogSelection(Collection selected) {
		if (getLinkEntity() == null) {
			throw new OCSRuntimeException("No linkEntity specified. Please use the setLinkEntity method");
		}
		selected.forEach(t -> getLinkEntity().accept(t));
	}

	@Override
	protected void setPresentationValue(U value) {
		this.parent = value;
		if (getGrid() != null) {
			getGrid().deselectAll();
			applyFilter();
			getGrid().deselectAll();
		}
	}

	/**
	 * Shows a pop-up for editing/creating the specified entity
	 * 
	 * @param entity the entity - this is empty in case a new entity is being
	 *               created
	 */
	private void showPopup(T entity) {
		EntityPopupDialog dialog = new EntityPopupDialog<>(getService(), entity, getEntityModel(),
				getFieldFilters(), new FormOptions(), getComponentContext(), getDetailJoins());
		dialog.setAfterEditDone((cancel, newEntity, ent) -> provider.refreshAll());
		dialog.setCreateEntity(getCreateEntity());
		dialog.buildAndOpen();
	}

	@Override
	protected boolean showDetailsPanelInEditMode() {
		return true;
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy