package org.sigmah.client.ui.presenter.project.indicator; /* * #%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.event.ButtonEvent; import com.extjs.gxt.ui.client.event.Events; import com.extjs.gxt.ui.client.event.FieldEvent; import com.extjs.gxt.ui.client.event.Listener; import com.extjs.gxt.ui.client.event.SelectionListener; import com.extjs.gxt.ui.client.store.ListStore; import com.extjs.gxt.ui.client.widget.form.ComboBox; import com.extjs.gxt.ui.client.widget.form.Field; import com.extjs.gxt.ui.client.widget.form.Radio; import com.extjs.gxt.ui.client.widget.form.RadioGroup; import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.inject.ImplementedBy; import com.google.inject.Inject; import com.google.inject.Singleton; import java.util.List; import org.sigmah.client.dispatch.CommandResultHandler; import org.sigmah.client.event.UpdateEvent; 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.page.RequestParameter; import org.sigmah.client.ui.notif.N10N; import org.sigmah.client.ui.presenter.base.AbstractPagePresenter; import org.sigmah.client.ui.presenter.base.HasForm; import org.sigmah.client.ui.view.base.ViewPopupInterface; import org.sigmah.client.ui.view.pivot.LayoutComposer; import org.sigmah.client.ui.view.pivot.table.PivotGridPanel; import org.sigmah.client.ui.view.project.indicator.EditIndicatorView; import org.sigmah.client.ui.widget.button.Button; import org.sigmah.client.ui.widget.form.DatasourceField; import org.sigmah.client.ui.widget.form.FormPanel; import org.sigmah.client.util.GWTDates; import org.sigmah.shared.command.BatchCommand; import org.sigmah.shared.command.CreateEntity; import org.sigmah.shared.command.GenerateElement; import org.sigmah.shared.command.GetIndicators; import org.sigmah.shared.command.GetProject; import org.sigmah.shared.command.UpdateEntity; import org.sigmah.shared.command.result.CreateResult; import org.sigmah.shared.command.result.IndicatorListResult; import org.sigmah.shared.command.result.ListResult; import org.sigmah.shared.command.result.Result; import org.sigmah.shared.dto.IndicatorDTO; import org.sigmah.shared.dto.IndicatorGroup; import org.sigmah.shared.dto.ProjectDTO; import org.sigmah.shared.dto.pivot.content.PivotContent; import org.sigmah.shared.dto.pivot.model.PivotTableElement; /** * Indicator presenter which manages the {@link EditIndicatorView}. * * @author Raphaƫl Calabro (rcalabro@ideia.fr) */ @Singleton public class EditIndicatorPresenter extends AbstractPagePresenter<EditIndicatorPresenter.View> implements HasForm { /** * Description of the view managed by this presenter. */ @ImplementedBy(EditIndicatorView.class) public static interface View extends ViewPopupInterface { FormPanel getForm(); // Fields. Field<String> getCodeField(); Field<String> getNameField(); ComboBox<IndicatorGroup> getIndicatorGroupField(); RadioGroup getTypeField(); Radio getTypeQuantitativeRadio(); Radio getTypeQualitativeTypeRadio(); Field<Object> getLabelsField(); RadioGroup getAggregationField(); Radio getAggregationSumRadio(); Radio getAggregationAverageTypeRadio(); Field<String> getUnitsField(); Field<Number> getObjectiveField(); Field<String> getVerificationField(); Field<String> getDescriptionField(); DatasourceField getDatasourceField(); PivotGridPanel getPivotGridPanel(); Button getSaveButton(); Button getCancelButton(); void loadIndicator(Integer projectId, IndicatorDTO indicator); void setDataEntryVisible(boolean visible); } private Integer projectId; private Integer indicatorId; private String category; private AsyncCallback<IndicatorDTO> callback; /** * Presenters's initialization. * * @param view * Presenter's view interface. * @param injector * Injected client injector. */ @Inject protected EditIndicatorPresenter(final EditIndicatorPresenter.View view, final Injector injector) { super(view, injector); } /** * {@inheritDoc} */ @Override public Page getPage() { return Page.INDICATOR_EDIT; } /** * {@inheritDoc} */ @Override public FormPanel[] getForms() { return new FormPanel[] { view.getForm() }; } /** * {@inheritDoc} */ @Override public void onBind() { view.getSaveButton().addSelectionListener(new SelectionListener<ButtonEvent>() { @Override public void componentSelected(ButtonEvent ce) { onSaveAction(); } }); view.getCancelButton().addSelectionListener(new SelectionListener<ButtonEvent>() { @Override public void componentSelected(ButtonEvent ce) { hideView(); } }); view.getTypeField().addListener(Events.Change, new Listener<FieldEvent>() { @Override public void handleEvent(FieldEvent be) { updateFormLayout(); } }); } /** * {@inheritDoc} */ @Override public void onPageRequest(PageRequest request) { this.projectId = request.getParameterInteger(RequestParameter.ID); this.category = request.getParameter(RequestParameter.CATEGORY); this.callback = request.getData(RequestParameter.REQUEST); final IndicatorDTO indicatorDTO = request.getData(RequestParameter.MODEL); if(indicatorDTO != null) { // Edit mode. // Sets the page title. setPageTitle(indicatorDTO.getName()); // Saving the current indicator identifer this.indicatorId = indicatorDTO.getId(); // Update category if present if(indicatorDTO.getCategory() != null) { this.category = indicatorDTO.getCategory(); } view.setDataEntryVisible(true); loadPivot(); } else { // Create mode. setPageTitle(I18N.CONSTANTS.newIndicator()); this.indicatorId = null; view.setDataEntryVisible(false); } // Load groups loadIndicatorGroups(projectId, indicatorDTO); // Display the current indicator view.loadIndicator(projectId, indicatorDTO); updateFormLayout(); } /** * Callback executed on save button action. */ private void onSaveAction() { // -- // Forms validation. // -- if (!isValid()) { // Form(s) validation failed. N10N.warn(I18N.CONSTANTS.form_validation_ko()); return; } // -- // Save or update the indicator. // -- if(indicatorId == null) { // Save. dispatch.execute(new CreateEntity(getIndicator()), new CommandResultHandler<CreateResult>() { @Override protected void onCommandSuccess(CreateResult result) { // Send an event to refresh the grid. fireUpdateEvent((Integer)result.getEntity().getId()); // Hides view and displays notification. hideView(); } }, view.getSaveButton()); } else { // Update. final IndicatorDTO indicatorDTO = getIndicator(); final BatchCommand updateCommand = new BatchCommand(new UpdateEntity(indicatorDTO, indicatorDTO.getProperties())); updateCommand.addAll(view.getPivotGridPanel().composeSaveCommand()); dispatch.execute(updateCommand, new CommandResultHandler<ListResult<Result>>() { @Override protected void onCommandSuccess(ListResult<Result> result) { // Send an event to refresh the grid. fireUpdateEvent(indicatorId); // Hides view and displays notification. hideView(); } }); } } /** * Validates only the visible fields of the form. * * @return <code>true</code> if all visible fields are valids, <code>false</code> otherwise. */ private boolean isValid() { boolean valid = true; for (Field<?> field : view.getForm().getFields()) { if (field.isVisible() && !field.isValid(true)) { valid = false; } } return valid; } /** * Fires the update event to notify registered presenter(s). */ private void fireUpdateEvent(int indicatorId) { final IndicatorDTO indicator = getIndicator(); indicator.setId(indicatorId); eventBus.fireEvent(new UpdateEvent(UpdateEvent.INDICATOR_UPDATED, indicatorId, indicator.getProperties())); if(callback != null) { callback.onSuccess(indicator); } } /** * Load the indicator groups of the given project. * @param projectId Project identifier. */ private void loadIndicatorGroups(Integer projectId, final IndicatorDTO indicatorDTO) { final ListStore<IndicatorGroup> store = view.getIndicatorGroupField().getStore(); store.removeAll(); dispatch.execute(new GetIndicators(projectId), new CommandResultHandler<IndicatorListResult>() { @Override protected void onCommandSuccess(IndicatorListResult result) { store.add(result.getGroups()); if(indicatorDTO != null && indicatorDTO.getGroupId() != null) { final Integer groupId = indicatorDTO.getGroupId(); for(final IndicatorGroup indicatorGroup : result.getGroups()) { if(groupId.equals(indicatorGroup.getId())) { view.getIndicatorGroupField().setValue(indicatorGroup); return; } } } } }); } private IndicatorDTO getIndicator() { final IndicatorDTO indicatorDTO = new IndicatorDTO(); indicatorDTO.setId(indicatorId); indicatorDTO.setDatabaseId(projectId); indicatorDTO.setCategory(category); indicatorDTO.setCode(view.getCodeField().getValue()); indicatorDTO.setName(view.getNameField().getValue()); indicatorDTO.setGroupId(view.getIndicatorGroupField().getValue() != null ? view.getIndicatorGroupField().getValue().getId() : null); indicatorDTO.setAggregation(getAggregationValue()); indicatorDTO.setLabels((List<String>) view.getLabelsField().getValue()); indicatorDTO.setUnits(view.getUnitsField().getValue()); indicatorDTO.setObjective(view.getObjectiveField().getValue() != null ? view.getObjectiveField().getValue().doubleValue() : null); indicatorDTO.setSourceOfVerification(view.getVerificationField().getValue()); indicatorDTO.setDescription(view.getDescriptionField().getValue()); indicatorDTO.set(IndicatorDTO.DATA_SOURCE_IDS, view.getDatasourceField().getValue()); indicatorDTO.setDirectDataEntryEnabled(view.getDatasourceField().getDirectBox().getValue() != null ? view.getDatasourceField().getDirectBox().getValue() : false); return indicatorDTO; } private int getAggregationValue() { if(view.getTypeField().getValue() == view.getTypeQualitativeTypeRadio()) { return IndicatorDTO.AGGREGATE_MULTINOMIAL; } else if(view.getAggregationField().getValue() == view.getAggregationAverageTypeRadio()) { return IndicatorDTO.AGGREGATE_AVG; } else { return IndicatorDTO.AGGREGATE_SUM; } } private void updateFormLayout() { final boolean qualitative = view.getTypeField().getValue() == view.getTypeQualitativeTypeRadio(); view.getLabelsField().setVisible(qualitative); view.getUnitsField().setVisible(!qualitative); view.getAggregationField().setVisible(!qualitative); view.getObjectiveField().setVisible(!qualitative); } private void loadPivot() { view.getPivotGridPanel().clear(); dispatch.execute(new GetProject(projectId), new CommandResultHandler<ProjectDTO>() { @Override protected void onCommandSuccess(ProjectDTO project) { LayoutComposer composer = new LayoutComposer(new GWTDates(), project); final PivotTableElement pivot = composer.fixIndicator(indicatorId); dispatch.execute(new GenerateElement<PivotContent>(pivot), new CommandResultHandler<PivotContent>() { @Override protected void onCommandSuccess(PivotContent content) { pivot.setContent(content); view.getPivotGridPanel().setValue(pivot); } }, view.getPivotGridPanel()); } }, view.getPivotGridPanel()); } }