package org.gcube.datacatalogue.grsf_manage_widget.client.view; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.gcube.datacatalogue.common.enums.Status; import org.gcube.datacatalogue.grsf_manage_widget.client.GRSFManageWidgetService; import org.gcube.datacatalogue.grsf_manage_widget.client.GRSFManageWidgetServiceAsync; import org.gcube.datacatalogue.grsf_manage_widget.client.events.HideManagementPanelEvent; import org.gcube.datacatalogue.grsf_manage_widget.client.view.subwidgets.ConnectToWidget; import org.gcube.datacatalogue.grsf_manage_widget.client.view.subwidgets.SimilarGRSFRecordWidget; import org.gcube.datacatalogue.grsf_manage_widget.client.view.subwidgets.SourceWidget; import org.gcube.datacatalogue.grsf_manage_widget.client.view.subwidgets.SuggestMerges; import org.gcube.datacatalogue.grsf_manage_widget.shared.ManageProductBean; import org.gcube.datacatalogue.grsf_manage_widget.shared.SimilarGRSFRecord; import org.gcube.datacatalogue.grsf_manage_widget.shared.SourceRecord; import org.gcube.datacatalogue.grsf_manage_widget.shared.ex.NoGRSFRecordException; import com.github.gwtbootstrap.client.ui.AlertBlock; import com.github.gwtbootstrap.client.ui.Button; import com.github.gwtbootstrap.client.ui.CheckBox; import com.github.gwtbootstrap.client.ui.ControlGroup; import com.github.gwtbootstrap.client.ui.Form; import com.github.gwtbootstrap.client.ui.Icon; import com.github.gwtbootstrap.client.ui.Image; import com.github.gwtbootstrap.client.ui.ListBox; import com.github.gwtbootstrap.client.ui.Modal; import com.github.gwtbootstrap.client.ui.TextArea; import com.github.gwtbootstrap.client.ui.TextBox; import com.github.gwtbootstrap.client.ui.constants.AlertType; import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.SelectElement; import com.google.gwt.dom.client.Style.Unit; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.shared.HandlerManager; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.uibinder.client.UiHandler; import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.HTML; import com.google.gwt.user.client.ui.VerticalPanel; import com.google.gwt.user.client.ui.Widget; /** * Management widget main panel. * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) */ public class ManageProductWidget extends Composite{ private static GRSFManageWidgetServiceAsync service = GWT.create(GRSFManageWidgetService.class); private static ManageProductWidgetUiBinder uiBinder = GWT .create(ManageProductWidgetUiBinder.class); interface ManageProductWidgetUiBinder extends UiBinder { } @UiField VerticalPanel container; @UiField Modal manageProductModal; @UiField AlertBlock infoBlock; @UiField TextArea shortNameTextBox; @UiField TextBox productGrsfType; @UiField CheckBox traceabilityFlag; @UiField TextArea GRSFNameTexBox; @UiField TextArea semanticIdentifierTextBox; @UiField VerticalPanel panelForSourceItems; @UiField ControlGroup similarGRSFRecordGroup; @UiField VerticalPanel panelForSimilarGRSFRecords; @UiField VerticalPanel panelForFurtherMerges; @UiField VerticalPanel panelForConnectOtherRecords; @UiField TextBox currentStatus; @UiField ListBox listBoxStatus; @UiField TextArea annotationArea; @UiField Button cancelButton; @UiField Button confirmButton; @UiField Icon loaderIcon; @UiField ControlGroup listBoxStatusGroup; @UiField ControlGroup annotationAreaGroup; @UiField ControlGroup productGrsfTypeGroup; @UiField Form formUpdate; @UiField Image loadingImage; public static final String LOADING_IMAGE_URL = GWT.getModuleBaseURL() + "../images/loader.gif"; // messages used here and there private final static String STATUS_UPDATE_SUCCESS = "The record has been correctly updated. Thanks for your collaboration!"; private final static String STATUS_UPDATE_ERROR = "Sorry, there was a problem while trying to update the status of this record"; protected static final String ERROR_ON_RETRIEVING_BEAN = "It seems there was a problem while contacting the service..."; protected static final String NO_GRSF_RECORD_BEAN = "This record is not a GRSF record, thus it cannot be managed"; protected static final String NO_ADMIN_ROLE = "Sorry but it seems you do not have the rights to manage records." + " You are suggested to contact the VRE Manager if something is wrong with this."; // event bus shared with the portlet private HandlerManager eventBus = null; // the objects to be managed private ManageProductBean bean; private final static List STATUS = new ArrayList(Arrays.asList(Status.values())); // similar records and to connect widgets references private SimilarGRSFRecordWidget similarRecordPanel; private SuggestMerges suggestedMergesPanel; private ConnectToWidget connectWidget; /** * Build a ManageProduct widget for the product with the specified id. * @param productIdentifier * @param eventBus */ public ManageProductWidget(String productIdentifier, HandlerManager eventBus) { initWidget(uiBinder.createAndBindUi(this)); this.eventBus = eventBus; GWT.log("item identifier is " + productIdentifier); if(productIdentifier == null || productIdentifier.isEmpty()) return; // start loader service loadingImage.setUrl(LOADING_IMAGE_URL); loadingImage.setVisible(true); formUpdate.setVisible(false); // show modal manageProductModal.addStyleName("management-metadata-modal-style"); manageProductModal.getElement().getStyle().setWidth(60, Unit.PCT); manageProductModal.show(); // async request to fetch the product retrieveProductBean(productIdentifier); } /** * Actually builds the widget... asks for details about the record * @param productIdentifier */ private void retrieveProductBean(final String productIdentifier) { // check if it is an administrator service.isAdminUser(new AsyncCallback() { @Override public void onSuccess(Boolean result) { if(!result){ showInfo(NO_ADMIN_ROLE, AlertType.ERROR); // hide the form and disable the send button formUpdate.setVisible(false); confirmButton.setEnabled(false); loadingImage.setVisible(false); // ask to hide management panel if(eventBus != null){ eventBus.fireEvent(new HideManagementPanelEvent()); GWT.log("Hide management panel event sent"); } }else{ service.getProductBeanById(productIdentifier, new AsyncCallback() { @Override public void onSuccess(ManageProductBean resBean) { if(resBean == null){ showInfo(ERROR_ON_RETRIEVING_BEAN, AlertType.ERROR); formUpdate.setVisible(false); confirmButton.setEnabled(false); }else{ bean = resBean; infoBlock.setVisible(false); // top: more or less fixed information GRSFNameTexBox.setText(bean.getGrsfName()); shortNameTextBox.setText(bean.getShortName()); semanticIdentifierTextBox.setText(bean.getSemanticIdentifier()); productGrsfType.setText(bean.getGrsfType()); currentStatus.setText(bean.getCurrentStatus().toString()); traceabilityFlag.setValue(bean.isTraceabilityFlag()); traceabilityFlag.setText("Traceability"); traceabilityFlag.setTitle("Current value for this flag in the Knowledge Base is " + bean.isTraceabilityFlag()); // manage sources List availableSources = bean.getSources(); panelForSourceItems.add(new SourceWidget(availableSources)); // manage similar GRSF records, if any if(bean.getSimilarGrsfRecords() != null && !bean.getSimilarGrsfRecords().isEmpty()){ List availableGRSFSimilarRecords = bean.getSimilarGrsfRecords(); similarRecordPanel = new SimilarGRSFRecordWidget(availableGRSFSimilarRecords); panelForSimilarGRSFRecords.add(similarRecordPanel); }else similarGRSFRecordGroup.setVisible(false); // further suggested merges suggestedMergesPanel = new SuggestMerges(service); panelForFurtherMerges.add(suggestedMergesPanel); // prepare "connect" panel connectWidget = new ConnectToWidget(bean, service); panelForConnectOtherRecords.add(connectWidget); // check for new status box List statusToShow = new ArrayList(STATUS); statusToShow.remove(bean.getCurrentStatus()); statusToShow.remove(Status.To_be_Merged); // it cannot be set by a user // if the record isn't approved, then remove also archived if(!bean.getCurrentStatus().equals(Status.Approved)) statusToShow.remove(Status.Archived); listBoxStatus.addItem("Select a new status"); listBoxStatus.getElement().cast().getOptions().getItem(0).setDisabled(true); for (Status availableStatus : statusToShow) { listBoxStatus.addItem(availableStatus.toString()); } listBoxStatus.setSelectedIndex(0); formUpdate.setVisible(true); } loadingImage.setVisible(false); } @Override public void onFailure(Throwable caught) { if(caught instanceof NoGRSFRecordException) showInfo(NO_GRSF_RECORD_BEAN, AlertType.WARNING); else showInfo("Error is " + caught, AlertType.ERROR); // hide the form and disable the send button formUpdate.setVisible(false); confirmButton.setEnabled(false); loadingImage.setVisible(false); } }); } } @Override public void onFailure(Throwable caught) { showInfo(NO_ADMIN_ROLE, AlertType.ERROR); // hide the form and disable the send button formUpdate.setVisible(false); confirmButton.setEnabled(false); loadingImage.setVisible(false); } }); } @UiHandler("confirmButton") void onSaveButton(ClickEvent ce){ // if the status has not be changed ... if(listBoxStatus.getSelectedIndex() <= 0) bean.setNewStatus(bean.getCurrentStatus()); else bean.setNewStatus(Status.fromString(listBoxStatus.getSelectedItemText())); manageProductModal.setCloseVisible(false); cancelButton.setEnabled(false); confirmButton.setEnabled(false); loaderIcon.setVisible(true); // get short name bean.setShortNameUpdated(shortNameTextBox.getText()); // evaluate the connections and the actions on them bean.setConnections(connectWidget.getConnectList()); // update similar records and to connect if(similarRecordPanel != null) bean.setSimilarGrsfRecords(similarRecordPanel.getSimilarRecords()); bean.getSimilarGrsfRecords().addAll(suggestedMergesPanel.getSimilarRecords()); // set new values bean.setAnnotation(new HTML(annotationArea.getText().trim()).getText()); // traceability flag bean.setTraceabilityFlag(traceabilityFlag.getValue()); service.notifyProductUpdate(bean, new AsyncCallback() { @Override public void onSuccess(String result) { if(result == null){ showInfo(STATUS_UPDATE_SUCCESS, AlertType.SUCCESS); confirmButton.removeFromParent(); formUpdate.setVisible(false); }else{ showInfo(STATUS_UPDATE_ERROR + "(" + result + ")", AlertType.ERROR); confirmButton.setEnabled(true); } manageProductModal.setCloseVisible(true); cancelButton.setEnabled(true); loaderIcon.setVisible(false); } @Override public void onFailure(Throwable caught) { manageProductModal.setCloseVisible(true); cancelButton.setEnabled(true); confirmButton.setEnabled(true); loaderIcon.setVisible(false); showInfo(STATUS_UPDATE_ERROR + ": " + caught.getMessage(), AlertType.ERROR); } }); } @UiHandler("cancelButton") void onCancelButton(ClickEvent ce){ manageProductModal.hide(); } /** * Show information * @param statusUpdateError */ protected void showInfo(String statusUpdateError, AlertType type) { infoBlock.setText(statusUpdateError); infoBlock.setType(type); infoBlock.setVisible(true); } }