package org.sigmah.client.ui.widget.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.event.logical.shared.ValueChangeEvent; import com.google.gwt.event.logical.shared.ValueChangeHandler; import com.google.gwt.user.client.ui.Image; import com.google.gwt.user.client.ui.Label; import com.extjs.gxt.ui.client.Style; import com.extjs.gxt.ui.client.event.ButtonEvent; import com.extjs.gxt.ui.client.event.ComponentEvent; 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.event.WidgetListener; import com.extjs.gxt.ui.client.store.ListStore; import com.extjs.gxt.ui.client.widget.Component; import com.extjs.gxt.ui.client.widget.LayoutContainer; import com.extjs.gxt.ui.client.widget.Window; import com.extjs.gxt.ui.client.widget.form.CheckBox; 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.layout.CardLayout; import com.extjs.gxt.ui.client.widget.layout.FitLayout; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.sigmah.client.i18n.I18N; 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.shared.command.result.ContactDuplicatedProperty; import org.sigmah.shared.dto.ContactDTO; import org.sigmah.shared.dto.element.event.ValueEvent; import org.sigmah.shared.dto.element.event.ValueHandler; public class DedupeContactDialog extends Window { private final boolean createContact; private Grid<ContactDTO> possibleDuplicatesGrid; private Grid<ContactDuplicatedProperty> duplicatedPropertiesGrid; private Button firstStepMainButton; private Button secondStepMainButton; private Button cancelSecondStepButton; private LayoutContainer secondStepContainer; private CardLayout cardLayout; private List<ContactDuplicatedProperty> selectedProperties = new ArrayList<ContactDuplicatedProperty>(); private ContactDTO selectedContact; private SecondStepHandler secondStepHandler; public DedupeContactDialog(boolean createContact) { super(); this.createContact = createContact; initComponent(); } private void initComponent() { this.setPlain(true); this.setModal(true); this.setBlinkModal(true); this.setLayout(new FitLayout()); this.setSize(650, 300); this.setHeadingHtml(I18N.CONSTANTS.dedupeContactWindowTitle()); possibleDuplicatesGrid = generatePossibleDuplicatesGrid(); firstStepMainButton = generateFirstStepMainButton(); LayoutContainer firstStepButtonsContainer = Layouts.border(); firstStepButtonsContainer.add(firstStepMainButton, Layouts.borderLayoutData(Style.LayoutRegion.EAST)); LayoutContainer firstStepContainer = Layouts.border(); firstStepContainer.setScrollMode(Style.Scroll.AUTOY); firstStepContainer.add(generateMessageLabel(), Layouts.borderLayoutData(Style.LayoutRegion.NORTH, 50f, Layouts.Margin.HALF_TOP, Layouts.Margin.HALF_RIGHT, Layouts.Margin.HALF_BOTTOM, Layouts.Margin.HALF_LEFT)); firstStepContainer.add(possibleDuplicatesGrid, Layouts.borderLayoutData(Style.LayoutRegion.CENTER, Layouts.Margin.HALF_TOP, Layouts.Margin.HALF_BOTTOM)); firstStepContainer.add(firstStepButtonsContainer, Layouts.borderLayoutData(Style.LayoutRegion.SOUTH, 20f, Layouts.Margin.HALF_TOP, Layouts.Margin.HALF_RIGHT, Layouts.Margin.BOTTOM, Layouts.Margin.DOUBLE_LEFT)); duplicatedPropertiesGrid = generateDuplicatedPropertiesGrid(); secondStepMainButton = generateSecondStepMainButton(); LayoutContainer secondStepButtonsContainer = Layouts.border(); secondStepButtonsContainer.add(secondStepMainButton, Layouts.borderLayoutData(Style.LayoutRegion.EAST)); cancelSecondStepButton = generateCancelSecondStepButton(); secondStepButtonsContainer.add(cancelSecondStepButton, Layouts.borderLayoutData(Style.LayoutRegion.WEST)); secondStepContainer = Layouts.border(); secondStepContainer.setScrollMode(Style.Scroll.AUTOY); secondStepContainer.add(duplicatedPropertiesGrid, Layouts.borderLayoutData(Style.LayoutRegion.CENTER, Layouts.Margin.HALF_TOP, Layouts.Margin.HALF_BOTTOM)); secondStepContainer.add(secondStepButtonsContainer, Layouts.borderLayoutData(Style.LayoutRegion.SOUTH, 20f, Layouts.Margin.HALF_TOP, Layouts.Margin.HALF_RIGHT, Layouts.Margin.BOTTOM, Layouts.Margin.DOUBLE_LEFT)); cardLayout = new CardLayout(); LayoutContainer mainContainer = new LayoutContainer(cardLayout); mainContainer.add(firstStepContainer); mainContainer.add(secondStepContainer); cardLayout.setActiveItem(firstStepContainer); add(mainContainer); } private Label generateMessageLabel() { if (createContact) { return new Label(I18N.CONSTANTS.dedupeContactCreateMessage()); } return new Label(I18N.CONSTANTS.dedupeContactUpdateMessage()); } private Button generateFirstStepMainButton() { Button button; if (createContact) { button = new Button(I18N.CONSTANTS.dedupeContactCreateNewButton()); } else { button = new Button(I18N.CONSTANTS.dedupeContactUpdateIndependently()); } return button; } private Button generateSecondStepMainButton() { Button button = new Button(I18N.CONSTANTS.dedupeContactUpdateButton()); button.addSelectionListener(new SelectionListener<ButtonEvent>() { @Override public void componentSelected(ButtonEvent ce) { secondStepHandler.handleDedupeContact(selectedContact.getId(), selectedProperties); } }); return button; } private Button generateCancelSecondStepButton() { Button button = new Button(I18N.CONSTANTS.cancel()); button.addSelectionListener(new SelectionListener<ButtonEvent>() { @Override public void componentSelected(ButtonEvent ce) { secondStepHandler.handleCancel(); } }); return button; } private Grid<ContactDTO> generatePossibleDuplicatesGrid() { ColumnConfig nameColumn = new ColumnConfig(ContactDTO.FULLNAME, I18N.CONSTANTS.fullName(), 250); ColumnConfig emailColumn = new ColumnConfig(ContactDTO.EMAIL, I18N.CONSTANTS.email(), 250); ColumnConfig actionsColumn = new ColumnConfig(); actionsColumn.setWidth(100); actionsColumn.setRenderer(new GridCellRenderer<ContactDTO>() { @Override public Object render(final ContactDTO contact, String property, ColumnData config, int rowIndex, int colIndex, ListStore store, Grid grid) { Button button = Forms.button(I18N.CONSTANTS.dedupeContactUpdateButton()); button.addSelectionListener(new SelectionListener<ButtonEvent>() { @Override public void componentSelected(ButtonEvent ce) { cardLayout.setActiveItem(secondStepContainer); secondStepHandler.initialize(contact.getId(), duplicatedPropertiesGrid.getStore()); selectedContact = contact; } }); return button; } }); ColumnModel columnModel = new ColumnModel(Arrays.asList(nameColumn, emailColumn, actionsColumn)); return new Grid<ContactDTO>(new ListStore<ContactDTO>(), columnModel); } private Grid<ContactDuplicatedProperty> generateDuplicatedPropertiesGrid() { ColumnConfig selectColumn = new ColumnConfig(); selectColumn.setWidth(20); selectColumn.setRenderer(new GridCellRenderer<ContactDuplicatedProperty>() { @Override public Object render(final ContactDuplicatedProperty contactDuplicatedProperty, String property, ColumnData config, int rowIndex, int colIndex, ListStore store, Grid grid) { final CheckBox checkbox = Forms.checkbox(null); checkbox.addHandler(new ValueChangeHandler<Boolean>() { @Override public void onValueChange(ValueChangeEvent<Boolean> event) { if (event.getValue()) { selectedProperties.add(contactDuplicatedProperty); } else { selectedProperties.remove(contactDuplicatedProperty); } } }, ValueChangeEvent.getType()); checkbox.addListener(Events.OnClick, new Listener<FieldEvent>() { @Override public void handleEvent(FieldEvent event) { if (checkbox.getValue()) { selectedProperties.add(contactDuplicatedProperty); } else { selectedProperties.remove(contactDuplicatedProperty); } } }); return checkbox; } }); ColumnConfig propertyNameColumn = new ColumnConfig(ContactDuplicatedProperty.PROPERTY_LABEL, I18N.CONSTANTS.dedupeContactPropertyNameHeader(), 150); ColumnConfig oldValueColumn = new ColumnConfig(); oldValueColumn.setHeaderText(I18N.CONSTANTS.dedupeContactOldValue()); oldValueColumn.setWidth(200); oldValueColumn.setRenderer(new GridCellRenderer<ContactDuplicatedProperty>() { @Override public Object render(ContactDuplicatedProperty contactDuplicatedProperty, String property, ColumnData config, int rowIndex, int colIndex, ListStore store, Grid grid) { return renderProperty(contactDuplicatedProperty.getValueType(), contactDuplicatedProperty.getFormattedOldValue(), contactDuplicatedProperty.getSerializedOldValue()); } }); ColumnConfig newValueColumn = new ColumnConfig(); newValueColumn.setHeaderText(I18N.CONSTANTS.dedupeContactNewValue()); newValueColumn.setWidth(200); newValueColumn.setRenderer(new GridCellRenderer<ContactDuplicatedProperty>() { @Override public Object render(ContactDuplicatedProperty contactDuplicatedProperty, String property, ColumnData config, int rowIndex, int colIndex, ListStore store, Grid grid) { return renderProperty(contactDuplicatedProperty.getValueType(), contactDuplicatedProperty.getFormattedNewValue(), contactDuplicatedProperty.getSerializedNewValue()); } }); ColumnModel columnModel = new ColumnModel(Arrays.asList(selectColumn, propertyNameColumn, oldValueColumn, newValueColumn)); return new Grid<ContactDuplicatedProperty>(new ListStore<ContactDuplicatedProperty>(), columnModel); } public Grid<ContactDTO> getPossibleDuplicatesGrid() { return possibleDuplicatesGrid; } public Grid<ContactDuplicatedProperty> getDuplicatedPropertiesGrid() { return duplicatedPropertiesGrid; } public Button getFirstStepMainButton() { return firstStepMainButton; } public Button getSecondStepMainButton() { return secondStepMainButton; } public void setSecondStepHandler(SecondStepHandler secondStepHandler) { this.secondStepHandler = secondStepHandler; } private Object renderProperty(ContactDuplicatedProperty.ValueType valueType, String formattedValue, String serializedValue) { if (serializedValue == null) { return ""; } switch (valueType) { case STRING: return formattedValue; case IMAGE: Image image = new Image(); secondStepHandler.downloadImage(serializedValue, image); image.getElement().getStyle().setHeight(50, com.google.gwt.dom.client.Style.Unit.PX); return image; default: throw new IllegalStateException("Unknown ValueType : " + valueType); } } public interface SecondStepHandler { void initialize(Integer contactId, ListStore<ContactDuplicatedProperty> propertiesStore); void downloadImage(String id, Image image); void handleDedupeContact(Integer targetedContactId, List<ContactDuplicatedProperty> selectedProperties); void handleCancel(); } }