package org.sigmah.client.ui.presenter.contact; /* * #%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.google.gwt.core.client.Scheduler; import com.google.gwt.i18n.client.DateTimeFormat; import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.ui.Widget; import com.google.inject.ImplementedBy; import com.google.inject.Inject; import com.extjs.gxt.ui.client.event.ComponentEvent; import com.extjs.gxt.ui.client.event.Listener; import com.extjs.gxt.ui.client.widget.Component; import java.util.Arrays; import java.util.Comparator; import java.util.List; import java.util.TreeSet; import org.sigmah.client.dispatch.monitor.LoadingMask; import org.sigmah.client.inject.Injector; import org.sigmah.client.page.Page; import org.sigmah.client.page.PageRequest; import org.sigmah.client.page.RequestParameter; import org.sigmah.client.ui.presenter.base.AbstractPagePresenter; import org.sigmah.client.ui.presenter.base.Presenter; import org.sigmah.client.ui.view.base.ViewInterface; import org.sigmah.client.ui.view.contact.ContactView; import org.sigmah.client.ui.zone.Zone; import org.sigmah.client.util.ImageProvider; import org.sigmah.shared.command.GetContact; import org.sigmah.shared.dto.ContactDTO; import org.sigmah.shared.dto.ContactModelDTO; import org.sigmah.shared.dto.element.DefaultContactFlexibleElementDTO; import org.sigmah.shared.dto.layout.LayoutConstraintDTO; import org.sigmah.shared.dto.layout.LayoutGroupDTO; import org.sigmah.shared.dto.orgunit.OrgUnitDTO; import org.sigmah.shared.dto.referential.ContactModelType; import com.allen_sauer.gwt.log.client.Log; public class ContactPresenter extends AbstractPagePresenter<ContactPresenter.View> { @ImplementedBy(ContactView.class) public interface View extends ViewInterface { Component getMainComponent(); void setAvatarUrl(String url); void setDefaultAvatar(ContactModelType type); void prepareContainers(); void addLabel(String label); void addNameLabel(String name); void addOrganizationLabel(String organization); void addLabel(String label, String style); void setHeaderText(String header); void addTab(final String tabTitle, final Widget tabView); void selectFirstTab(); } interface ContactSubPresenter<E extends ViewInterface> extends Presenter<E> { String getTabHeader(); void refresh(ContactDTO contactDTO); boolean hasValueChanged(); } private final List<? extends ContactSubPresenter> tabPresenters; private final ImageProvider imageProvider; private ContactDTO contactDTO; @Inject public ContactPresenter(View view, Injector injector, ContactDetailsPresenter contactDetailsPresenter, ContactRelationshipsPresenter contactRelationshipsPresenter, ContactHistoryPresenter contactHistoryPresenter, ImageProvider imageProvider) { super(view, injector); this.imageProvider = imageProvider; this.tabPresenters = Arrays.asList(contactDetailsPresenter, contactRelationshipsPresenter, contactHistoryPresenter); } @Override public void onBind() { for (ContactSubPresenter tabPresenter : tabPresenters) { tabPresenter.initialize(); view.addTab(tabPresenter.getTabHeader(), tabPresenter.getView().asWidget()); } } @Override public Page getPage() { return Page.CONTACT_DASHBOARD; } @Override public void onPageRequest(PageRequest request) { Integer contactId = request.getParameterInteger(RequestParameter.ID); loadContact(contactId, request); } private void loadContact(final Integer contactId, final PageRequest pageRequest) { if (contactDTO != null && contactDTO.getId().equals(contactId)) { // Already loaded onContactLoaded(pageRequest); return; } dispatch.execute(new GetContact(contactId, ContactDTO.Mode.ALL), new AsyncCallback<ContactDTO>() { @Override public void onFailure(Throwable caught) { Log.error("Error while requesting a contact.", caught); } @Override public void onSuccess(final ContactDTO contactDTO) { ContactPresenter.this.contactDTO = contactDTO; onContactLoaded(pageRequest); } }, new LoadingMask(view.getMainComponent())); } private void onContactLoaded(PageRequest request) { // Updates the tab title. eventBus.updateZoneRequest(Zone.MENU_BANNER.requestWith(RequestParameter.REQUEST, request).addData(RequestParameter.HEADER, contactDTO.getFullName())); view.setHeaderText(contactDTO.getFullName()); // By calling following refresh methods without deferring, all card labels will be placed at the same position. // Its mainly due to the fact that GXT overuse absolute positioning and calculate once at runtime the position of // each element. As the view is not ready if the user is going back to the Contact tab, GXT cannot calculate the // right position. Scheduler.get().scheduleDeferred(new Scheduler.ScheduledCommand() { @Override public void execute() { refreshCard(); refreshTabs(); } }); } private void refreshCard() { final ContactModelDTO contactModelDTO = contactDTO.getContactModel(); view.prepareContainers(); TreeSet<LayoutConstraintDTO> constraints = new TreeSet<LayoutConstraintDTO>(new Comparator<LayoutConstraintDTO>() { @Override public int compare(LayoutConstraintDTO constraint1, LayoutConstraintDTO constraint2) { if (constraint1.getSortOrder() == constraint2.getSortOrder()) { return constraint1.getFlexibleElementDTO().getId().compareTo(constraint2.getFlexibleElementDTO().getId()); } return constraint1.getSortOrder() - constraint2.getSortOrder(); } }); for (LayoutGroupDTO layoutGroup : contactModelDTO.getCard().getLayout().getGroups()) { for (LayoutConstraintDTO constraint : layoutGroup.getConstraints()) { constraints.add(constraint); } } boolean hasPhoto = false; for (LayoutConstraintDTO constraint : constraints) { DefaultContactFlexibleElementDTO flexibleElementDTO = (DefaultContactFlexibleElementDTO) constraint.getFlexibleElementDTO(); if (!flexibleElementDTO.getType().isVisibleForType(contactModelDTO.getType())) { continue; } switch (flexibleElementDTO.getType()) { case PHOTO: if (contactDTO.getPhoto() == null) { break; } hasPhoto = true; imageProvider.provideDataUrl(contactDTO.getPhoto(), new AsyncCallback<String>() { @Override public void onFailure(Throwable caught) { view.setDefaultAvatar(contactModelDTO.getType()); } @Override public void onSuccess(String dataUrl) { view.setAvatarUrl(dataUrl); } }); break; case COUNTRY: if (contactDTO.getCountry() == null) { break; } view.addLabel(contactDTO.getCountry().getName()); break; case CREATION_DATE: if (contactDTO.getDateCreated() == null) { break; } String date = DateTimeFormat.getFormat(DateTimeFormat.PredefinedFormat.DATE_TIME_MEDIUM).format(contactDTO.getDateCreated()); view.addLabel(date); break; case DIRECT_MEMBERSHIP: if (contactDTO.getParent() == null) { break; } view.addLabel(contactDTO.getParent().getName()); break; case EMAIL_ADDRESS: view.addLabel(contactDTO.getEmail()); break; case FAMILY_NAME: view.addNameLabel(contactDTO.getName()); break; case FIRST_NAME: view.addNameLabel(contactDTO.getFirstname()); break; case LOGIN: view.addLabel(contactDTO.getLogin()); break; case MAIN_ORG_UNIT: if (contactDTO.getMainOrgUnit() == null) { break; } view.addLabel(contactDTO.getMainOrgUnit().getName()); break; case ORGANIZATION_NAME: view.addNameLabel(contactDTO.getName()); break; case PHONE_NUMBER: view.addLabel(contactDTO.getPhoneNumber()); break; case POSTAL_ADDRESS: view.addLabel(contactDTO.getPostalAddress()); break; case SECONDARY_ORG_UNITS: for (OrgUnitDTO secondaryOrgUnit : contactDTO.getSecondaryOrgUnits()) { view.addLabel(secondaryOrgUnit.getName()); } break; case TOP_MEMBERSHIP: if (contactDTO.getRoot() == null) { break; } view.addOrganizationLabel(contactDTO.getRoot().getName()); break; default: throw new IllegalStateException("Unknown DefaultContactFlexibleElementType : " + flexibleElementDTO.getType()); } } if (!hasPhoto) { view.setDefaultAvatar(contactModelDTO.getType()); } } private void refreshTabs() { view.selectFirstTab(); for (ContactSubPresenter tabPresenter : tabPresenters) { tabPresenter.refresh(contactDTO); } } @Override public boolean hasValueChanged() { for (ContactSubPresenter tabPresenter : tabPresenters) { if (tabPresenter.hasValueChanged()) return true; } return false; } }