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

io.imunity.furms.ui.components.administrators.UserContextMenuFactory Maven / Gradle / Ivy

There is a newer version: 4.3.1
Show newest version
/*
 * Copyright (c) 2020 Bixbit s.c. All rights reserved.
 * See LICENSE file for licensing information.
 */

package io.imunity.furms.ui.components.administrators;

import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.UI;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.html.Div;
import io.imunity.furms.domain.invitations.InvitationId;
import io.imunity.furms.domain.users.PersistentId;
import io.imunity.furms.ui.components.FurmsDialog;
import io.imunity.furms.ui.components.GridActionMenu;
import io.imunity.furms.ui.components.MenuButton;
import io.imunity.furms.ui.views.landing.LandingPageView;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;

import static com.vaadin.flow.component.button.ButtonVariant.LUMO_TERTIARY;
import static com.vaadin.flow.component.icon.VaadinIcon.MINUS_CIRCLE;
import static com.vaadin.flow.component.icon.VaadinIcon.PAPERPLANE;
import static com.vaadin.flow.component.icon.VaadinIcon.TRASH;
import static io.imunity.furms.ui.utils.NotificationUtils.showErrorNotification;
import static io.imunity.furms.ui.utils.VaadinExceptionHandler.getResultOrException;
import static io.imunity.furms.ui.utils.VaadinExceptionHandler.handleExceptions;
import static io.imunity.furms.ui.utils.VaadinTranslator.getTranslation;

public class UserContextMenuFactory {
	private final Consumer removeUserAction;
	private final Optional> postRemoveUserAction;
	private final Consumer resendInvitationAction;
	private final Consumer removeInvitationAction;
	private final PersistentId currentUserId;
	private final boolean redirectOnCurrentUserRemoval;
	private final boolean allowRemovalOfLastUser;

	private final String confirmRemovalMessageKey;
	private final String confirmSelfRemovalMessageKey;
	private final String removalNotAllowedMessageKey;

	private final List> customContextMenuItems;

	UserContextMenuFactory(Consumer removeUserAction,
	                       Optional> postRemoveUserAction,
	                       PersistentId currentUserId,
	                       boolean redirectOnCurrentUserRemoval,
	                       boolean allowRemovalOfLastUser,
	                       String confirmRemovalMessageKey,
	                       String confirmSelfRemovalMessageKey,
	                       String removalNotAllowedMessageKey,
	                       List> customContextMenuItems,
	                       Consumer resendInvitationAction,
	                       Consumer removeInvitationAction) {
		this.removeUserAction = removeUserAction;
		this.postRemoveUserAction = postRemoveUserAction;
		this.currentUserId = currentUserId;
		this.redirectOnCurrentUserRemoval = redirectOnCurrentUserRemoval;
		this.allowRemovalOfLastUser = allowRemovalOfLastUser;
		this.confirmRemovalMessageKey = confirmRemovalMessageKey == null
			? "component.administrators.remove.confirm"
			: confirmRemovalMessageKey;
		this.confirmSelfRemovalMessageKey = confirmSelfRemovalMessageKey == null
			? "component.administrators.remove.yourself.confirm"
			: confirmSelfRemovalMessageKey;
		this.removalNotAllowedMessageKey = removalNotAllowedMessageKey == null
			? "component.administrators.error.validation.remove"
			: removalNotAllowedMessageKey;
		this.customContextMenuItems = customContextMenuItems;
		this.resendInvitationAction = resendInvitationAction;
		this.removeInvitationAction = removeInvitationAction;
	}

	private void doRemoveYourself(Runnable gridReloader, Supplier gridSizeLoader){
		FurmsDialog furmsDialog = new FurmsDialog(getTranslation(confirmSelfRemovalMessageKey));
		furmsDialog.addConfirmButtonClickListener(event -> {
			if (allowRemoval(gridSizeLoader)) {
				getResultOrException(() -> {
					removeUserAction.accept(currentUserId);
					postRemoveUserAction.ifPresent(action -> action.accept(currentUserId));
				})
						.getException()
						.ifPresentOrElse(
								e -> showErrorNotification(getTranslation(e.getMessage())),
								() -> refreshUserRoles(gridReloader));
			} else {
				showErrorNotification(getTranslation(removalNotAllowedMessageKey));
			}
		});
		furmsDialog.open();
	}

	private void doRemoveItemAction(UserGridItem removedItem, Runnable gridReloader, Supplier gridSizeLoader) {
		FurmsDialog furmsDialog = new FurmsDialog(getTranslation(confirmRemovalMessageKey,
			getFullName(removedItem)));
		furmsDialog.addConfirmButtonClickListener(event -> {
			if (allowRemoval(gridSizeLoader)) {
				final PersistentId persistentId = removedItem.getId().orElse(null);
				handleExceptions(() -> {
					removeUserAction.accept(persistentId);
					postRemoveUserAction.ifPresent(action -> action.accept(currentUserId));

				});
				gridReloader.run();
			} else {
				showErrorNotification(getTranslation(removalNotAllowedMessageKey));
			}
		});
		furmsDialog.open();
	}

	private void refreshUserRoles(Runnable gridReloader) {
		if(redirectOnCurrentUserRemoval)
			UI.getCurrent().navigate(LandingPageView.class);
		else
			gridReloader.run();
	}

	private boolean allowRemoval(Supplier gridSizeLoader) {
		return allowRemovalOfLastUser || gridSizeLoader.get() > 1;
	}

	public Component get(UserGridItem gridItem, Runnable gridReloader, Supplier gridSizeLoader){
		GridActionMenu contextMenu = new GridActionMenu();

		if(removeUserAction != null && gridItem.getStatus().equals(UserUIStatus.ENABLED)) {
			Button button = new Button(getTranslation("component.administrators.context.menu.remove"),
				MINUS_CIRCLE.create());
			button.addThemeVariants(LUMO_TERTIARY);
			contextMenu.addItem(button, event -> {
				if (gridItem.getId().isPresent()
					&& gridItem.getId().get().equals(currentUserId))
					doRemoveYourself(gridReloader, gridSizeLoader);
				else
					doRemoveItemAction(gridItem, gridReloader, gridSizeLoader);
			});
		}
		if(resendInvitationAction != null && gridItem.getStatus().equals(UserUIStatus.AWAITS_APPROVAL)){
			Button button = new Button(getTranslation("component.administrators.context.menu.resend.invitation"),
				PAPERPLANE.create());
			button.addThemeVariants(LUMO_TERTIARY);
			contextMenu.addItem(button, event -> resendInvitationAction.accept(gridItem.getInvitationId().get()));
		}
		if(removeInvitationAction != null && gridItem.getStatus().equals(UserUIStatus.AWAITS_APPROVAL)){
			Button button = new Button(getTranslation("component.administrators.context.menu.remove.invitation"),
				TRASH.create());
			button.addThemeVariants(LUMO_TERTIARY);
			contextMenu.addItem(button, event -> removeInvitationAction.accept(gridItem.getInvitationId().get()));
		}
		customContextMenuItems.stream()
			.filter(item -> item.confirmer.test(gridItem))
			.forEach(item ->
			contextMenu.addItem(item.buttonProvider.apply(gridItem), event -> item.menuButtonHandler.accept(gridItem))
		);
		if(contextMenu.getChildren().count() == 0)
			return new Div();
		return contextMenu.getTarget();
	}

	private static String getFullName(UserGridItem c) {
		return c.getFirstName()
			.map(value -> value + " ").orElse("")
			+ c.getLastName().orElse("");
	}

	public static Builder builder() {
		return new Builder();
	}

	public static final class Builder {
		private Consumer removeUserAction;
		private Consumer postRemoveUserAction;
		private PersistentId currentUserId;
		private boolean redirectOnCurrentUserRemoval = false;
		private boolean allowRemovalOfLastUser = false;
		private String confirmRemovalMessageKey;
		private String confirmSelfRemovalMessageKey;
		private String removalNotAllowedMessageKey;
		private final List> customContextMenuItems = new ArrayList<>();
		private Consumer resendInvitationAction;
		private Consumer removeInvitationAction;

		private Builder() {
		}

		public Builder withRemoveUserAction(Consumer removeUserAction) {
			this.removeUserAction = removeUserAction;
			return this;
		}

		public Builder withPostRemoveUserAction(Consumer postRemoveUserAction) {
			if (this.removeUserAction == null) {
				throw new IllegalArgumentException("Post Remove Action required Remove User Action declared");
			}
			this.postRemoveUserAction = postRemoveUserAction;
			return this;
		}

		public Builder withCurrentUserId(PersistentId currentUserId) {
			this.currentUserId = currentUserId;
			return this;
		}

		public Builder redirectOnCurrentUserRemoval() {
			this.redirectOnCurrentUserRemoval = true;
			return this;
		}

		public Builder allowRemovalOfLastUser() {
			this.allowRemovalOfLastUser = true;
			return this;
		}

		public Builder withConfirmRemovalMessageKey(String key) {
			this.confirmRemovalMessageKey = key;
			return this;
		}

		public Builder withConfirmSelfRemovalMessageKey(String key) {
			this.confirmSelfRemovalMessageKey = key;
			return this;
		}

		@SuppressWarnings({"unchecked", "rawtypes"})
		public  Builder addCustomContextMenuItem(Function buttonProvider, Consumer action) {
			this.customContextMenuItems.add(new CustomContextMenuItem(buttonProvider, action, x -> true));
			return this;
		}

		@SuppressWarnings({"unchecked", "rawtypes"})
		public  Builder addCustomContextMenuItem(Function buttonProvider, Consumer action, Predicate predicate) {
			this.customContextMenuItems.add(new CustomContextMenuItem(buttonProvider, action, predicate));
			return this;
		}

		public Builder withRemoveInvitationAction(Consumer removeInvitationAction) {
			this.removeInvitationAction = removeInvitationAction;
			return this;
		}

		public Builder withResendInvitationAction(Consumer resendInvitationAction) {
			this.resendInvitationAction = resendInvitationAction;
			return this;
		}

		public Builder withRemovalNotAllowedMessageKey(String key) {
			this.removalNotAllowedMessageKey = key;
			return this;
		}

		public UserContextMenuFactory build() {
			return new UserContextMenuFactory(removeUserAction, Optional.ofNullable(postRemoveUserAction),
				currentUserId,
				redirectOnCurrentUserRemoval, allowRemovalOfLastUser, confirmRemovalMessageKey,
				confirmSelfRemovalMessageKey, removalNotAllowedMessageKey, customContextMenuItems,
				resendInvitationAction, removeInvitationAction);
		}
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy