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

io.imunity.upman.front.views.members.MenuItemFactory Maven / Gradle / Ivy

There is a newer version: 4.0.2
Show newest version
/*
 * Copyright (c) 2018 Bixbit - Krzysztof Benedyczak. All rights reserved.
 * See LICENCE.txt file for licensing information.
 */

package io.imunity.upman.front.views.members;

import com.vaadin.flow.component.ClickEvent;
import com.vaadin.flow.component.ComponentEventListener;
import com.vaadin.flow.component.UI;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.combobox.ComboBox;
import com.vaadin.flow.component.dialog.Dialog;
import com.vaadin.flow.component.html.Div;
import com.vaadin.flow.component.html.Span;
import com.vaadin.flow.component.orderedlayout.FlexComponent;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.radiobutton.RadioButtonGroup;
import com.vaadin.flow.component.radiobutton.RadioGroupVariant;
import com.vaadin.flow.router.Location;
import com.vaadin.flow.router.NavigationTrigger;
import com.vaadin.flow.router.Route;
import io.imunity.upman.front.model.Group;
import io.imunity.upman.front.model.GroupTreeNode;
import io.imunity.upman.front.model.ProjectGroup;
import io.imunity.vaadin.elements.BaseDialog;
import io.imunity.vaadin.elements.MenuButton;
import io.imunity.vaadin.elements.SubmitButton;
import io.imunity.vaadin.elements.CssClassNames;
import pl.edu.icm.unity.base.message.MessageSource;
import pl.edu.icm.unity.engine.api.authn.InvocationContext;
import pl.edu.icm.unity.engine.api.project.GroupAuthorizationRole;

import java.util.List;
import java.util.Set;
import java.util.function.Supplier;

import static com.vaadin.flow.component.icon.VaadinIcon.*;
import static java.util.stream.Collectors.toList;
import static pl.edu.icm.unity.engine.api.project.GroupAuthorizationRole.*;

class MenuItemFactory
{
	private final GroupMembersService groupMembersController;
	private final MessageSource msg;
	private final Div content;
	private final Runnable viewReloader;

	MenuItemFactory(MessageSource msg, GroupMembersService groupMembersController, Div content, Runnable reloader)
	{
		this.groupMembersController = groupMembersController;
		this.msg = msg;
		this.content = content;
		this.viewReloader = reloader;
	}

	MenuItem createRemoveFromProjectItem(Supplier projectGetter,
	                                     Supplier> modelsGetter, Supplier roleGetter)
	{
		MenuButton menuButton = new MenuButton(msg.getMessage("GroupMembersComponent.removeFromProjectAction"), BAN);
		return new MenuItem(menuButton, event -> removeFromProject(projectGetter.get(), roleGetter.get(), modelsGetter.get()));
	}

	MenuItem createRemoveFromGroupItem(Supplier projectGetter, Supplier groupGetter,
	                                   Supplier> modelsGetter, Supplier roleGetter)
	{
		MenuButton menuButton = new MenuButton(msg.getMessage("GroupMembersComponent.removeFromGroupAction"), FILE_REMOVE);
		return new MenuItem(menuButton, event -> removeFromGroup(projectGetter.get(), groupGetter.get(), roleGetter.get(), modelsGetter.get()));
	}

	MenuItem createAddToGroupItem(Supplier projectGetter, Supplier> groupGetter, Supplier> modelsGetter)
	{
		MenuButton menuButton = new MenuButton(msg.getMessage("GroupMembersComponent.addToGroupAction"), PLUS_CIRCLE_O);
		return new MenuItem(menuButton, event -> createAddToGroupDialog(projectGetter.get(), modelsGetter.get(), groupGetter.get()).open());
	}

	MenuItem createSetProjectRoleItem(Supplier projectGetter, Supplier groupGetter, Supplier> modelsGetter,
	                                  Supplier roleGetter)
	{
		MenuButton menuButton = new MenuButton(msg.getMessage("GroupMembersComponent.setProjectRoleAction"), STAR_O);
		return new MenuItem(menuButton, event -> createSetProjectRoleDialog(projectGetter.get(), groupGetter.get(), modelsGetter.get(), roleGetter.get()).open());
	}

	MenuItem createSetSubProjectRoleItem(Supplier projectGetter, Supplier groupGetter, Supplier> modelsGetter,
	                                     Supplier roleGetter)
	{
		MenuButton menuButton = new MenuButton(msg.getMessage("GroupMembersComponent.setSubProjectRoleAction"), STAR_O);
		return new MenuItem(menuButton, event -> createSetSubProjectRoleDialog(projectGetter.get(), groupGetter.get(), modelsGetter.get(), roleGetter.get()).open());
	}

	private void removeFromGroup(ProjectGroup projectGroup, Group group, GroupAuthorizationRole role, Set models)
	{
		if(projectGroup.path.equals(group.path))
		{
			removeFromProject(projectGroup, role, models);
			return;
		}
		if(isCurrentUserSelected(models))
		{
			String message = msg.getMessage("GroupMembersComponent.confirmSelfRemoveFromProject", projectGroup.displayedName);
			createSelfRemoveDialog(
				message, () ->
					{
						groupMembersController.removeFromGroup(projectGroup, group, models);
						viewReloader.run();
					}
			).open();
		}
		else
		{
			groupMembersController.removeFromGroup(projectGroup, group, models);
			viewReloader.run();
		}
	}

	private void removeFromProject(ProjectGroup projectGroup, GroupAuthorizationRole role, Set models)
	{
		if(isCurrentUserSelected(models))
		{
			String message = msg.getMessage("GroupMembersComponent.confirmSelfRemoveFromProject", projectGroup.displayedName);
			createSelfRemoveDialog(
					message, () ->
					{
						groupMembersController.removeFromProject(projectGroup, models);
						if(role.equals(projectsAdmin))
							reloadMainLayout();
						else
							viewReloader.run();
					}
			).open();
		}
		else
		{
			groupMembersController.removeFromProject(projectGroup, models);
			viewReloader.run();
		}
	}

	private boolean isCurrentUserSelected(Set models)
	{
		long entityId = InvocationContext.getCurrent().getLoginSession().getEntityId();
		return models.stream().map(member -> member.entityId).anyMatch(memberId -> memberId.equals(entityId));
	}

	private void reloadMainLayout()
	{
		UI ui = UI.getCurrent();
		String location = MembersView.class.getAnnotation(Route.class).value();
		ui.getInternals().getRouter().navigate(ui, new Location(location), NavigationTrigger.PROGRAMMATIC);
	}

	private Dialog createSelfRemoveDialog(String txt, Runnable job)
	{
		Dialog dialog = createBaseDialog(msg.getMessage("Confirmation"));
		dialog.addClassName(CssClassNames.DIALOG_CONFIRM.getName());
		dialog.add(new VerticalLayout(new Span(txt)));

		Button saveButton = new SubmitButton(msg::getMessage);
		saveButton.addClickListener(e ->
		{
			job.run();
			dialog.close();
		});
		dialog.getFooter().add(saveButton);

		return dialog;
	}

	private Dialog createAddToGroupDialog(ProjectGroup projectGroup, Set members, List groups)
	{
		Dialog dialog = createBaseDialog(msg.getMessage("AddToGroupDialog.caption"));

		ComboBox groupComboBox = new GroupComboBox(msg);
		groupComboBox.focus();
		groupComboBox.setLabel(msg.getMessage("AddToGroupDialog.info"));
		groupComboBox.setItems(groups);
		if(groups.iterator().hasNext())
			groupComboBox.setValue(groups.iterator().next());
		groupComboBox.getStyle().set("width", "24em");

		HorizontalLayout dialogLayout = new HorizontalLayout();
		dialogLayout.setAlignItems(FlexComponent.Alignment.BASELINE);
		dialogLayout.add(new Span(msg.getMessage("AddToGroupDialog.selectGroup")), groupComboBox);
		dialog.add(dialogLayout);

		Button saveButton = createAddToGroupButton(projectGroup, dialog, groupComboBox, members);
		dialog.getFooter().add(saveButton);

		return dialog;
	}

	private Dialog createSetProjectRoleDialog(ProjectGroup projectGroup, Group group, Set items, GroupAuthorizationRole role)
	{
		Dialog dialog = createBaseDialog(msg.getMessage("RoleSelectionDialog.projectCaption"));

		RadioButtonGroup radioGroup = createRoleRadioButtonGroup(role, items);
		Span label = new Span(msg.getMessage("RoleSelectionDialog.projectRole"));

		HorizontalLayout dialogLayout = new HorizontalLayout();
		dialogLayout.add(label, radioGroup);
		dialogLayout.setAlignItems(FlexComponent.Alignment.CENTER);
		dialog.add(dialogLayout);

		Button saveButton = createSetProjectRoleButton(projectGroup, group, dialog, radioGroup, items);
		dialog.getFooter().add(saveButton);

		return dialog;
	}

	private RadioButtonGroup createRoleRadioButtonGroup(GroupAuthorizationRole role, Set items)
	{
		RadioButtonGroup radioGroup = new RadioButtonGroup<>();
		radioGroup.addThemeVariants(RadioGroupVariant.LUMO_VERTICAL);

		List roles;
		if(role.equals(manager))
			roles = List.of(manager, regular);
		else
			roles = List.of(projectsAdmin, manager, regular);

		radioGroup.setItems(roles);
		radioGroup.setItemLabelGenerator(r-> msg.getMessage("Role." + r.toString().toLowerCase()));
		if(items.size() == 1)
			radioGroup.setValue(GroupAuthorizationRole.valueOf(items.iterator().next().role.getKey()));
		return radioGroup;
	}

	private Dialog createSetSubProjectRoleDialog(ProjectGroup projectGroup, Group group, Set items, GroupAuthorizationRole role)
	{
		Dialog dialog = createBaseDialog(msg.getMessage("RoleSelectionDialog.subprojectCaption"));

		RadioButtonGroup radioGroup = createRoleRadioButtonGroup(role, items);
		Span label = new Span(msg.getMessage("RoleSelectionDialog.subprojectRole"));

		HorizontalLayout dialogLayout = new HorizontalLayout();
		dialogLayout.add(label, radioGroup);
		dialogLayout.setAlignItems(FlexComponent.Alignment.CENTER);
		dialog.add(dialogLayout);

		Button saveButton = createSetSubProjectRoleButton(projectGroup, group, dialog, radioGroup, items);
		dialog.getFooter().add(saveButton);

		return dialog;
	}

	private Dialog createBaseDialog(String header)
	{
		return new BaseDialog(header, msg.getMessage("Cancel"), content);
	}

	private Button createSetSubProjectRoleButton(ProjectGroup projectGroup, Group group, Dialog dialog, RadioButtonGroup radioGroup, Set items)
	{
		Button button = new SubmitButton(msg::getMessage);
		button.addClickListener(event ->
		{
			groupMembersController.updateRole(projectGroup, group, radioGroup.getValue(), items);
			viewReloader.run();
			dialog.close();
		});
		return button;
	}

	private Button createSetProjectRoleButton(ProjectGroup projectGroup, Group group, Dialog dialog, RadioButtonGroup radioGroup, Set items)
	{
		Button button = new SubmitButton(msg::getMessage);
		button.addClickListener(event ->
		{
			GroupAuthorizationRole role = radioGroup.getValue();
			if(role.equals(regular) && isCurrentUserSelected(items))
			{
				dialog.close();
				createSelfRemoveDialog(
						msg.getMessage("GroupMembersComponent.confirmSelfRevokeManagerPrivileges", projectGroup.displayedName),
						() ->
						{
							groupMembersController.updateRole(projectGroup, group, role, items);
							viewReloader.run();
						}
				).open();
				return;
			}
			groupMembersController.updateRole(projectGroup, group, role, items);
			viewReloader.run();
			dialog.close();
		});
		return button;
	}

	private Button createAddToGroupButton(ProjectGroup projectGroup, Dialog dialog, ComboBox comboBox, Set members)
	{
		Button button = new SubmitButton(msg::getMessage);
		button.addClickListener(event ->
		{
			GroupTreeNode value = comboBox.getValue();
			List parents = value.getNodeWithAllOffspring();
			parents.add(value);

			groupMembersController.addToGroup(projectGroup, parents.stream().map(node -> node.group).collect(toList()), members);
			dialog.close();
		});
		return button;
	}

	static class MenuItem
	{
		MenuButton component;
		ComponentEventListener> clickListener;

		private MenuItem(MenuButton component, ComponentEventListener> clickListener)
		{
			this.component = component;
			this.clickListener = clickListener;
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy