package org.sigmah.client.ui.presenter.project; /* * #%L * Sigmah * %% * Copyright (C) 2010 - 2016 URD * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program. If not, see * <http://www.gnu.org/licenses/gpl-3.0.html>. * #L% */ import com.extjs.gxt.ui.client.data.ModelData; import com.extjs.gxt.ui.client.event.ButtonEvent; import com.extjs.gxt.ui.client.event.SelectionListener; import com.extjs.gxt.ui.client.store.ListStore; import com.extjs.gxt.ui.client.widget.LayoutContainer; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.user.client.ui.Image; import com.google.inject.ImplementedBy; import com.google.inject.Inject; import com.google.inject.Singleton; import java.util.HashSet; import java.util.List; import java.util.Set; import org.sigmah.client.dispatch.CommandResultHandler; import org.sigmah.client.dispatch.monitor.LoadingMask; import org.sigmah.client.i18n.I18N; import org.sigmah.client.inject.Injector; import org.sigmah.client.page.Page; import org.sigmah.client.page.PageRequest; import org.sigmah.client.ui.notif.N10N; import org.sigmah.client.ui.view.project.ProjectTeamMembersView; import org.sigmah.client.ui.widget.button.Button; import org.sigmah.shared.command.GetProfiles; import org.sigmah.shared.command.GetProjectTeamMembers; import org.sigmah.shared.command.GetUsersByOrgUnit; import org.sigmah.shared.command.UpdateProjectTeamMembers; import org.sigmah.shared.command.result.ListResult; import org.sigmah.shared.command.result.TeamMembersResult; import org.sigmah.shared.dto.TeamMemberDTO; import org.sigmah.shared.dto.UserDTO; import org.sigmah.shared.dto.profile.ProfileDTO; import org.sigmah.shared.dto.referential.GlobalPermissionEnum; import org.sigmah.shared.util.ProfileUtils; /** * Project's details presenter which manages the {@link ProjectTeamMembersView}. * * @author Aurélien PONÇON (aurelien.poncon@gmail.com) */ @Singleton public class ProjectTeamMembersPresenter extends AbstractProjectPresenter<ProjectTeamMembersPresenter.View> { /** * Description of the view managed by this presenter. */ @ImplementedBy(ProjectTeamMembersView.class) public interface View extends AbstractProjectPresenter.View { LayoutContainer getMainPanel(); Button getAddTeamMemberButton(); Button getAddTeamMemberByProfileButton(); ListStore<ModelData> getTeamMembersStore(); void setRemoveTeamMemberButtonCreationHandler(RemoveTeamMemberButtonCreationHandler removeTeamMemberButtonCreationHandler); void buildAddTeamMemberDialog(AddTeamMemberHandler handler, List<UserDTO> availableUsers); void buildAddTeamMembersByProfileDialog(SelectTeamMembersByProfileHandler handler, List<ProfileDTO> profiles); } public interface RemoveTeamMemberButtonCreationHandler { void onCreateRemoveUserButton(Image imageButton, UserDTO userDTO); void onCreateRemoveProfileButton(Image imageButton, ProfileDTO userDTO); } public interface AddTeamMemberHandler { void onAddTeamMember(UserDTO userDTO); } public interface SelectTeamMembersByProfileHandler { void onSelectTeamMemberByProfile(ProfileDTO profileDTO); } /** * Presenters's initialization. * * @param view * Presenter's view interface. * @param injector * Injected client injector. */ @Inject public ProjectTeamMembersPresenter(final View view, final Injector injector) { super(view, injector); } /** * {@inheritDoc} */ @Override public Page getPage() { return Page.PROJECT_TEAM_MEMBERS; } /** * {@inheritDoc} */ @Override public void onPageRequest(final PageRequest request) { load(); } /** * {@inheritDoc} */ @Override public boolean hasValueChanged() { return false; } // --------------------------------------------------------------------------------------------------------------- // // UTILITY METHODS. // // --------------------------------------------------------------------------------------------------------------- /** * Loads the presenter with the given project {@code team members}. */ private void load() { view.getTeamMembersStore().removeAll(); dispatch.execute(new GetProjectTeamMembers(getProject().getId()), new CommandResultHandler<TeamMembersResult>() { @Override protected void onCommandSuccess(TeamMembersResult result) { fillTeamMembersStore(result); } }, null, new LoadingMask(view.getMainPanel())); } @Override public void onBind() { super.onBind(); view.setRemoveTeamMemberButtonCreationHandler(new RemoveTeamMemberButtonCreationHandler() { @Override public void onCreateRemoveUserButton(Image imageButton, final UserDTO userDTO) { if (!isEditable()) { imageButton.setVisible(false); return; } imageButton.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent clickEvent) { view.getTeamMembersStore().remove(userDTO); save(); } }); } @Override public void onCreateRemoveProfileButton(Image imageButton, final ProfileDTO profileDTO) { if (!isEditable()) { imageButton.setVisible(false); return; } imageButton.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent clickEvent) { view.getTeamMembersStore().remove(profileDTO); save(); } }); } }); addButtonHandlers(); } private void addButtonHandlers() { if (!isEditable()) { view.getAddTeamMemberButton().setEnabled(false); view.getAddTeamMemberByProfileButton().setEnabled(false); return; } view.getAddTeamMemberButton().addSelectionListener(new SelectionListener<ButtonEvent>() { @Override public void componentSelected(ButtonEvent ce) { Set<Integer> alreadySelectedUserIds = new HashSet<Integer>(); for (ModelData modelData : view.getTeamMembersStore().findModels(TeamMemberDTO.TYPE, TeamMemberDTO.TeamMemberType.TEAM_MEMBER)) { alreadySelectedUserIds.add((Integer) modelData.get(TeamMemberDTO.ID)); } dispatch.execute( new GetUsersByOrgUnit(getProject().getOrgUnitId(), alreadySelectedUserIds), new CommandResultHandler<ListResult<UserDTO>>() { @Override protected void onCommandSuccess(ListResult<UserDTO> results) { view.buildAddTeamMemberDialog(new AddTeamMemberHandler() { @Override public void onAddTeamMember(UserDTO userDTO) { userDTO.set(TeamMemberDTO.TYPE, TeamMemberDTO.TeamMemberType.TEAM_MEMBER); userDTO.set(TeamMemberDTO.ORDER, 3); view.getTeamMembersStore().add(userDTO); save(); } }, results.getData()); } }, view.getAddTeamMemberButton(), new LoadingMask(view.getMainPanel()) ); } }); view.getAddTeamMemberByProfileButton().addSelectionListener(new SelectionListener<ButtonEvent>() { @Override public void componentSelected(ButtonEvent event) { dispatch.execute( new GetProfiles(ProfileDTO.Mode.BASE), new CommandResultHandler<ListResult<ProfileDTO>>() { @Override protected void onCommandSuccess(ListResult<ProfileDTO> result) { view.buildAddTeamMembersByProfileDialog(new SelectTeamMembersByProfileHandler() { @Override public void onSelectTeamMemberByProfile(ProfileDTO profileDTO) { profileDTO.set(TeamMemberDTO.TYPE, TeamMemberDTO.TeamMemberType.TEAM_MEMBER_PROFILE); profileDTO.set(TeamMemberDTO.ORDER, 2); view.getTeamMembersStore().add(profileDTO); save(); } }, result.getData()); } }, view.getAddTeamMemberByProfileButton(), new LoadingMask(view.getMainPanel()) ); } }); } private void save() { List<UserDTO> teamMembers = (List<UserDTO>) (List) view.getTeamMembersStore().findModels(TeamMemberDTO.TYPE, TeamMemberDTO.TeamMemberType.TEAM_MEMBER); List<ProfileDTO> teamMemberProfiles = (List<ProfileDTO>) (List)view.getTeamMembersStore().findModels(TeamMemberDTO.TYPE, TeamMemberDTO.TeamMemberType.TEAM_MEMBER_PROFILE); dispatch.execute( new UpdateProjectTeamMembers(getProject().getId(), teamMembers, teamMemberProfiles), new CommandResultHandler<TeamMembersResult>() { @Override public void onCommandFailure(final Throwable caught) { N10N.error(I18N.CONSTANTS.save(), I18N.CONSTANTS.saveError()); } @Override protected void onCommandSuccess(TeamMembersResult result) { N10N.infoNotif(I18N.CONSTANTS.infoConfirmation(), I18N.CONSTANTS.saveConfirm()); fillTeamMembersStore(result); } }, view.getAddTeamMemberButton(), new LoadingMask(view.getMainPanel()) ); } private void fillTeamMembersStore(TeamMembersResult result) { UserDTO projectManager = result.getProjectManager(); // ProjectManager can be null if the current user doesn't have sufficient UserPermission if (projectManager != null) { // As the ListStore doesn't support duplicated IDs, let's modify the ID of the manager projectManager.set(TeamMemberDTO.ID, Integer.MAX_VALUE); projectManager.set(TeamMemberDTO.TYPE, TeamMemberDTO.TeamMemberType.MANAGER); projectManager.set(TeamMemberDTO.ORDER, 1); } List<ProfileDTO> teamMemberProfiles = result.getTeamMemberProfiles(); for (ProfileDTO profileDTO : teamMemberProfiles) { profileDTO.set(TeamMemberDTO.TYPE, TeamMemberDTO.TeamMemberType.TEAM_MEMBER_PROFILE); profileDTO.set(TeamMemberDTO.ORDER, 2); } List<UserDTO> teamMembers = result.getTeamMembers(); for (UserDTO userDTO : teamMembers) { userDTO.set(TeamMemberDTO.TYPE, TeamMemberDTO.TeamMemberType.TEAM_MEMBER); userDTO.set(TeamMemberDTO.ORDER, 3); } view.getTeamMembersStore().removeAll(); if (projectManager != null) { view.getTeamMembersStore().add(projectManager); } view.getTeamMembersStore().add(teamMemberProfiles); view.getTeamMembersStore().add(teamMembers); } private boolean isEditable() { return ProfileUtils.isGranted(auth(), GlobalPermissionEnum.EDIT_PROJECT) && ProfileUtils.isGranted(auth(), GlobalPermissionEnum.EDIT_PROJECT_TEAM_MEMBERS); } }