package org.sigmah.client.ui.view.importation; /* * #%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.store.ListStore; import com.extjs.gxt.ui.client.widget.grid.CheckBoxSelectionModel; import com.extjs.gxt.ui.client.widget.grid.ColumnConfig; import com.extjs.gxt.ui.client.widget.grid.ColumnData; import com.extjs.gxt.ui.client.widget.grid.ColumnModel; import com.extjs.gxt.ui.client.widget.grid.Grid; import com.extjs.gxt.ui.client.widget.grid.GridCellRenderer; import com.extjs.gxt.ui.client.widget.grid.GridSelectionModel; import java.io.Serializable; import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Map; import org.sigmah.client.i18n.I18N; import org.sigmah.client.ui.widget.HasGrid; import org.sigmah.client.ui.widget.button.Button; import org.sigmah.client.ui.widget.form.Forms; import org.sigmah.client.ui.widget.layout.Layouts; import org.sigmah.client.ui.widget.popup.PopupWidget; import org.sigmah.shared.dto.ElementExtractedValue; import org.sigmah.shared.dto.ImportDetails; import org.sigmah.shared.dto.ProjectDTO; import org.sigmah.shared.dto.base.EntityDTO; import org.sigmah.shared.dto.element.BudgetElementDTO; import org.sigmah.shared.dto.element.BudgetSubFieldDTO; import org.sigmah.shared.dto.element.FlexibleElementDTO; import org.sigmah.shared.dto.element.QuestionChoiceElementDTO; import org.sigmah.shared.dto.element.QuestionElementDTO; import org.sigmah.shared.dto.element.TextAreaElementDTO; import org.sigmah.shared.dto.element.TripletsListElementDTO; import org.sigmah.shared.dto.orgunit.OrgUnitDTO; import org.sigmah.shared.dto.referential.BudgetSubFieldType; import org.sigmah.shared.dto.referential.DefaultFlexibleElementType; import org.sigmah.shared.dto.referential.ElementExtractedValueStatus; import org.sigmah.shared.util.ValueResultUtils; /** * Displays the changes that will be applied on a project/orgunit after an * import. * * @author Guerline Jean-Baptiste (gjbaptiste@ideia.fr) * @author Raphaƫl Calabro (rcalabro@ideia.fr) v2.0 */ public class ElementExtractedValuePopup extends PopupWidget implements HasGrid<ElementExtractedValue> { private static final String FIELD_LABEL = "fieldLabel"; private static final String OLD_VALUE = "oldValue"; private static final String NEW_VALUE = "newValue"; private Grid<ElementExtractedValue> grid; private Button confirmButton; private ImportDetails parentModel; private EntityDTO<?> entity; public ElementExtractedValuePopup() { super(true, Layouts.fitLayout()); setWidth("900px"); setHeight("500px"); } public void initialize() { // Building the grid. final CheckBoxSelectionModel<ElementExtractedValue> selectionModel = new CheckBoxSelectionModel<ElementExtractedValue>(); final ColumnModel columnModel = createColumnModel(selectionModel); grid = createGrid(columnModel, selectionModel); grid.addPlugin(selectionModel); // Creating the OK button. confirmButton = Forms.button(I18N.CONSTANTS.ok()); // Preparing the popup. setContent(grid); addButton(confirmButton); } @Override public Grid<ElementExtractedValue> getGrid() { return grid; } @Override public ListStore<ElementExtractedValue> getStore() { return grid.getStore(); } public GridSelectionModel<ElementExtractedValue> getSelectionModel() { return grid.getSelectionModel(); } public Button getConfirmButton() { return confirmButton; } @Override public void setGridEventHandler(GridEventHandler<ElementExtractedValue> handler) { } public ImportDetails getParentModel() { return parentModel; } public void setParentModel(ImportDetails parentModel) { this.parentModel = parentModel; } /** * Retrieves the current entity. * * @return */ public EntityDTO<?> getEntity() { return entity; } /** * Changes the current entity displayed in this popup and updates the title. * * @param entity Entity to use. */ public void setEntity(EntityDTO<?> entity) { this.entity = entity; updateTitle(); } /** * Retrieves the current selection. * * @return List of {@link ElementExtractedValue} selected by the user. */ public List<ElementExtractedValue> getSelection() { return grid.getSelectionModel().getSelectedItems(); } // -- // Utility methods. // -- /** * Modify this popup header with information from the current entity. */ private void updateTitle() { final String information; if(entity instanceof OrgUnitDTO) { final OrgUnitDTO orgUnit = (OrgUnitDTO)entity; information = orgUnit.getFullName() + " (" + orgUnit.getName() + ')'; } else if(entity instanceof ProjectDTO) { final ProjectDTO project = (ProjectDTO)entity; information = project.getFullName() + " (" + project.getName() + ')'; } else { throw new IllegalArgumentException("Type not supported: " + entity); } setTitle(I18N.MESSAGES.importConfirmationDetailsHeading(information)); } /** * Creates the grid of this popup. * * @param columnModel * @param selectionModel * @return */ private Grid<ElementExtractedValue> createGrid(final ColumnModel columnModel, final GridSelectionModel<ElementExtractedValue> selectionModel) { final Grid<ElementExtractedValue> grid = new Grid<ElementExtractedValue>(new ListStore<ElementExtractedValue>(), columnModel); grid.setSelectionModel(selectionModel); grid.getView().setForceFit(true); return grid; } /** * Creates the column model. * * @param selectionModel * @return */ private ColumnModel createColumnModel(CheckBoxSelectionModel<ElementExtractedValue> selectionModel) { // Checkbox column (to select changes to apply). final ColumnConfig checkboxColumnConfig = selectionModel.getColumn(); // Field label column. final ColumnConfig fieldLabelColumnConfig = new ColumnConfig(FIELD_LABEL, I18N.CONSTANTS.adminFlexible(), 100); fieldLabelColumnConfig.setRenderer(new GridCellRenderer<ElementExtractedValue>() { @Override public Object render(final ElementExtractedValue model, String property, ColumnData config, int rowIndex, int colIndex, ListStore<ElementExtractedValue> store, Grid<ElementExtractedValue> grid) { return formatLabel(model); } }); // Old value column. final ColumnConfig oldValueColumnConfig = new ColumnConfig(OLD_VALUE, I18N.CONSTANTS.adminImportOldValue(), 70); oldValueColumnConfig.setRenderer(new GridCellRenderer<ElementExtractedValue>() { @Override public Object render(final ElementExtractedValue model, String property, ColumnData config, int rowIndex, int colIndex, ListStore<ElementExtractedValue> store, Grid<ElementExtractedValue> grid) { if (model.getStatus() == ElementExtractedValueStatus.VALID_VALUE) { return formatValue(model.getElement(), model.getOldValue(), model.getNewBudgetValues(), model.getOldBudgetValues()); } return null; } }); // New value column. final ColumnConfig newValueColumnConfig = new ColumnConfig(NEW_VALUE, I18N.CONSTANTS.adminImportNewValue(), 70); newValueColumnConfig.setRenderer(new GridCellRenderer<ElementExtractedValue>() { @Override public Object render(final ElementExtractedValue model, String property, ColumnData config, int rowIndex, int colIndex, ListStore<ElementExtractedValue> store, Grid<ElementExtractedValue> grid) { if (model.getStatus() == ElementExtractedValueStatus.VALID_VALUE) { return formatValue(model.getElement(), model.getNewValue(), model.getNewBudgetValues(), model.getNewBudgetValues()); } else { return ElementExtractedValueStatus.getMessage(model.getStatus()); } } }); // Creating the column model. final ArrayList<ColumnConfig> columnConfigs = new ArrayList<ColumnConfig>(); columnConfigs.add(checkboxColumnConfig); columnConfigs.add(fieldLabelColumnConfig); columnConfigs.add(oldValueColumnConfig); columnConfigs.add(newValueColumnConfig); return new ColumnModel(columnConfigs); } /** * Return a formatted version of the label of the given element. * * @param model ExtractedValue containing a FlexibleElementDTO. * @return Its label, formatted. */ private String formatLabel(ElementExtractedValue model) { final String elementLabel; if (model.getElement() instanceof BudgetElementDTO) { final BudgetElementDTO budgetElement = (BudgetElementDTO) model.getElement(); final StringBuilder fieldNameBuilder = new StringBuilder(); for (BudgetSubFieldDTO subField : budgetElement.getBudgetSubFields()) { if (model.getNewBudgetValues().containsKey(subField.getId())) { if (subField.getType() != null) { fieldNameBuilder.append(BudgetSubFieldType.getName(subField.getType())); } else { fieldNameBuilder.append(subField.getLabel()); } fieldNameBuilder.append("; "); } } if(fieldNameBuilder.length() == 0) { fieldNameBuilder.append(DefaultFlexibleElementType.getName(DefaultFlexibleElementType.BUDGET)); } elementLabel = fieldNameBuilder.toString(); } else { elementLabel = model.getElement().getFormattedLabel(); } return elementLabel; } /** * Return a formatted version of the value of the given element. * * @param element Element containing the value. * @param value Simple value. * @param budgetHaystack Map of budget values where to search. * @param budgetValues Map of buget values to use. * @return Its value, formatted. */ private <V extends Serializable> String formatValue(FlexibleElementDTO element, Serializable value, Map<Integer, Serializable> budgetHaystack, Map<Integer, V> budgetValues) { final String elementValue; if(value instanceof String) { return element.toHTML((String)value); } // TODO: Modify the code to return values as String (instead of Serializable) and allow the use of element.toHTML(...). if (element instanceof BudgetElementDTO && !budgetValues.isEmpty()) { // -- // Budget element. // -- final BudgetElementDTO budgetElement = (BudgetElementDTO) element; final StringBuilder valueBuilder = new StringBuilder(); for (BudgetSubFieldDTO subField : budgetElement.getBudgetSubFields()) { if (budgetHaystack.containsKey(subField.getId())) { final V subFieldValue = budgetValues.get(subField.getId()); if (subFieldValue != null) { valueBuilder.append(subFieldValue); } else { valueBuilder.append("0.0"); } valueBuilder.append("; "); } } elementValue = valueBuilder.toString(); } else if(value != null) { if(element instanceof QuestionElementDTO && isQuestionElementValueValid((QuestionElementDTO)element, value)) { // -- // Question element. // -- final QuestionElementDTO questionElement = (QuestionElementDTO) element; final List<Integer> choices; if(questionElement.getMultiple() != null && questionElement.getMultiple()) { choices = ValueResultUtils.splitValuesAsInteger(value.toString()); } else { choices = Collections.singletonList((Integer)value); } final StringBuilder valueBuilder = new StringBuilder(); if (choices != null && !choices.isEmpty()) { for (QuestionChoiceElementDTO questionChoice : questionElement.getChoices()) { if(choices.contains(questionChoice.getId())){ if(questionChoice.getCategoryElement() != null) { valueBuilder.append(questionChoice.getCategoryElement().getLabel()); } else { valueBuilder.append(questionChoice.getLabel()); } valueBuilder.append("; "); } } } elementValue = valueBuilder.toString(); } else if(element instanceof TripletsListElementDTO && value instanceof String[]) { // -- // Triplet list value. // -- final String[] tripletValues = (String[]) value; elementValue = new StringBuilder() .append(I18N.CONSTANTS.flexibleElementTripletsListCode()).append(" : ") .append(tripletValues[0]).append(" - ") .append(I18N.CONSTANTS.flexibleElementTripletsListName()).append(" : ") .append(tripletValues[1]).append(" - ") .append(I18N.CONSTANTS.flexibleElementTripletsListPeriod()).append(" : ") .append(tripletValues[2]) .toString(); } else if(element instanceof TextAreaElementDTO && Character.valueOf('D').equals(((TextAreaElementDTO)element).getType()) && value instanceof Date) { // -- // Date type text area element. // -- final Date dateValue = (Date) value; elementValue = dateValue.toString(); } else { // -- // Basic value. // -- elementValue = value.toString(); } } else { // -- // No value. // -- elementValue = null; } return elementValue; } /** * Verify the type of the value for the given <code>questionElement</code>. * * @param questionElement * @param value * @return */ private boolean isQuestionElementValueValid(QuestionElementDTO questionElement, Serializable value) { return (questionElement.getMultiple() != null && questionElement.getMultiple() && value instanceof String) || ((questionElement.getMultiple() == null || !questionElement.getMultiple()) && value instanceof Integer); } }