most of the updates of the #10928 have been implemented

git-svn-id: http://svn.research-infrastructures.eu/public/d4science/gcube/trunk/portlets/widgets/grsf-manage-widget@164601 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
Costantino Perciante 2018-02-27 16:13:41 +00:00
parent a34fd17b74
commit 12d22bfa9b
13 changed files with 304 additions and 387 deletions

View File

@ -12,7 +12,7 @@
<groupId>org.gcube.portlets.widgets</groupId>
<artifactId>grsf-manage-widget</artifactId>
<version>1.3.1-SNAPSHOT</version>
<version>1.3.2-SNAPSHOT</version>
<name>gCube GRSF Manage widget</name>
<scm>

View File

@ -21,7 +21,7 @@ public interface GRSFManageWidgetService extends RemoteService {
* @return ManageProductBean
* @throws Exception
*/
ManageProductBean getProductBeanById(String identifier) throws Exception;
ManageProductBean getProductBeanById(String identifier, boolean isRequestForRevertingMerge) throws Exception;
/**
* Notify product update

View File

@ -18,6 +18,7 @@ public interface GRSFManageWidgetServiceAsync {
AsyncCallback<Void> callback);
void getProductBeanById(String identifier,
boolean isRequestForRevertingMerge,
AsyncCallback<ManageProductBean> callback);
void isAdminUser(AsyncCallback<Boolean> callback);

View File

@ -2,6 +2,7 @@ package org.gcube.datacatalogue.grsf_manage_widget.client.view;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@ -22,6 +23,7 @@ import org.gcube.datacatalogue.grsf_manage_widget.client.view.subwidgets.Suggest
import org.gcube.datacatalogue.grsf_manage_widget.shared.ConnectedBean;
import org.gcube.datacatalogue.grsf_manage_widget.shared.HashTagsOnUpdate;
import org.gcube.datacatalogue.grsf_manage_widget.shared.ManageProductBean;
import org.gcube.datacatalogue.grsf_manage_widget.shared.RevertableOperationInfo;
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;
@ -39,6 +41,7 @@ import com.github.gwtbootstrap.client.ui.TextArea;
import com.github.gwtbootstrap.client.ui.TextBox;
import com.github.gwtbootstrap.client.ui.constants.AlertType;
import com.github.gwtbootstrap.client.ui.constants.ButtonType;
import com.github.gwtbootstrap.client.ui.constants.ControlGroupType;
import com.github.gwtbootstrap.client.ui.event.HiddenEvent;
import com.github.gwtbootstrap.client.ui.event.HiddenHandler;
import com.google.gwt.core.client.GWT;
@ -50,6 +53,7 @@ import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
@ -92,7 +96,7 @@ public class ManageProductWidget extends Composite{
@UiField
CheckBox traceabilityFlag;
@UiField
CheckBox sdgFlag;
@ -108,6 +112,12 @@ public class ManageProductWidget extends Composite{
@UiField
ControlGroup similarGRSFRecordGroup;
@UiField
ControlGroup suggestFurtherMerges;
@UiField
ControlGroup connectToOtherRecordsGroup;
@UiField
VerticalPanel panelForSimilarGRSFRecords;
@ -147,9 +157,24 @@ public class ManageProductWidget extends Composite{
@UiField
Form formUpdate;
@UiField
VerticalPanel moreInfoAboutOperation;
@UiField
Image loadingImage;
@UiField
TextArea requestAuthor;
// @UiField
// TextArea requestTypeBox;
@UiField
TextArea requestRecordUUID;
@UiField
TextArea requestTimestamp;
public static final String LOADING_IMAGE_URL = GWT.getModuleBaseURL() + "../images/loader.gif";
// messages used here and there
@ -165,29 +190,32 @@ public class ManageProductWidget extends Composite{
// the objects to be managed
private ManageProductBean bean;
private RevertableOperationInfo revertableOperation = null;
private final static List<Status> STATUS = new ArrayList<Status>(Arrays.asList(Status.values()));
// similar records and to connect widgets references
private SimilarGRSFRecordWidget similarRecordPanel;
private SuggestMerges suggestedMergesPanel;
private ConnectToWidget connectWidget;
private boolean updateSucceeded = false;
private boolean isRevertingMerge = false;
/**
* Build a ManageProduct widget for the product with the specified id.
* @param productIdentifier
* Build a ManageProduct widget for the product with the specified id or with a given revert merge url.
* @param productIdentifierOrUrl
* @param eventBus
*/
public ManageProductWidget(String productIdentifier, HandlerManager eventBus) {
public ManageProductWidget(String productIdentifierOrUrl, HandlerManager eventBus) {
initWidget(uiBinder.createAndBindUi(this));
this.eventBus = eventBus;
GWT.log("item identifier is " + productIdentifier);
if(productIdentifier == null || productIdentifier.isEmpty())
if(productIdentifierOrUrl == null || productIdentifierOrUrl.isEmpty())
return;
// check if we are going to perform a revert merge operation
if(productIdentifierOrUrl.startsWith("http"))
isRevertingMerge = true;
// start loader service
loadingImage.setUrl(LOADING_IMAGE_URL);
loadingImage.setVisible(true);
@ -196,6 +224,7 @@ public class ManageProductWidget extends Composite{
// show modal
manageProductModal.addStyleName("management-metadata-modal-style");
manageProductModal.addStyleName("modal-top-custom");
((Element)manageProductModal.getElement().getChildNodes().getItem(1)).addClassName("modal-body-custom");
manageProductModal.show();
@ -210,7 +239,10 @@ public class ManageProductWidget extends Composite{
});
// async request to fetch the product
retrieveProductBean(productIdentifier);
if(!isRevertingMerge)
retrieveProductBean(productIdentifierOrUrl);
else
validateRevertUrlBefore(productIdentifierOrUrl);
listenEvents(this.eventBus);
}
@ -229,12 +261,55 @@ public class ManageProductWidget extends Composite{
});
}
/**
* Validate the parameters of the url and ask the editor/reviewer what he/she wants to do.
* @param encryptedUrlOperation
*/
private void validateRevertUrlBefore(String encryptedUrlOperation) {
confirmButton.setEnabled(false);
service.validateRevertOperation(encryptedUrlOperation, new AsyncCallback<RevertableOperationInfo>() {
@Override
public void onSuccess(RevertableOperationInfo result) {
loadingImage.setVisible(false);
if(result != null){
revertableOperation = result;
String dateString = DateTimeFormat.getFormat("MM/dd/yyyy HH:mm:ss (z)").format(new Date(revertableOperation.getTimestamp()));
requestAuthor.setText(revertableOperation.getFullNameOriginalAdmin() + "(" + revertableOperation.getUserNameOriginalAdmin() + ")");
// requestTypeBox.setText(revertableOperation.getOperation().toString().toUpperCase());
requestRecordUUID.setText(revertableOperation.getUuid());
requestTimestamp.setText(dateString);
moreInfoAboutOperation.setVisible(true);
// proceed by fetching the other details
retrieveProductBean(revertableOperation.getUuid());
}else{
showInfo("Unable to evaluate the url for this operation. ", AlertType.ERROR);
formUpdate.setVisible(false);
loadingImage.setVisible(false);
}
}
@Override
public void onFailure(Throwable caught) {
showInfo("Unable to perform this operation. " + (caught != null ? "Error was " + caught : ""), AlertType.ERROR);
formUpdate.setVisible(false);
loadingImage.setVisible(false);
}
});
}
/**
* Actually builds the widget... asks for details about the record
* @param productIdentifier
* @param productIdentifierOrUrl
*/
private void retrieveProductBean(final String productIdentifier) {
private void retrieveProductBean(final String productIdentifierOrUrl) {
// check if it is an administrator
service.isAdminUser(new AsyncCallback<Boolean>() {
@ -257,7 +332,7 @@ public class ManageProductWidget extends Composite{
GWT.log("Hide management panel event sent");
}
}else{
service.getProductBeanById(productIdentifier, new AsyncCallback<ManageProductBean>() {
service.getProductBeanById(productIdentifierOrUrl, isRevertingMerge, new AsyncCallback<ManageProductBean>() {
@Override
public void onSuccess(ManageProductBean resBean) {
@ -282,17 +357,17 @@ public class ManageProductWidget extends Composite{
});
semanticIdentifierTextBox.setText(bean.getSemanticIdentifier());
// update product type listbox.. get the available types for the record under management
List<String> types = getTypesForRecord(bean.getDomain());
productGrsfTypeListbox.addItem(bean.getCurrentGrsfType(), bean.getCurrentGrsfType());
types.remove(bean.getCurrentGrsfType());
for (String type : types) {
productGrsfTypeListbox.addItem(type, type);
}
//select the current
productGrsfTypeListbox.setSelectedValue(bean.getCurrentGrsfType());
productGrsfTypeListbox.setSelectedValue(bean.getCurrentGrsfType());
productGrsfTypeListbox.addChangeHandler(new ChangeHandler() {
@ -302,7 +377,7 @@ public class ManageProductWidget extends Composite{
}
});
currentStatus.setText(bean.getCurrentStatus().toString());
// traceability flag
traceabilityFlag.setValue(bean.isTraceabilityFlag());
traceabilityFlag.setText("Traceability");
@ -314,7 +389,7 @@ public class ManageProductWidget extends Composite{
eventBus.fireEvent(new EnableConfirmButtonEvent());
}
});
// sdg flag
sdgFlag.setValue(bean.isSdgFlag());
sdgFlag.setText("Sustainable Development Goals");
@ -326,7 +401,7 @@ public class ManageProductWidget extends Composite{
eventBus.fireEvent(new EnableConfirmButtonEvent());
}
});
// manage sources
List<SourceRecord> availableSources = bean.getSources();
panelForSourceItems.add(new SourceWidget(availableSources));
@ -350,14 +425,36 @@ public class ManageProductWidget extends Composite{
// check for new status box
List<Status> statusToShow = new ArrayList<Status>(STATUS);
statusToShow.remove(bean.getCurrentStatus());
// remove to be merged, since it cannot be set by a user
statusToShow.remove(Status.To_be_Merged);
// if the record isn't approved, then remove also archived
if(!bean.getCurrentStatus().equals(Status.Approved))
statusToShow.remove(Status.Archived);
// if we are going to revert an operation
if(isRevertingMerge){
statusToShow.clear();
statusToShow.add(Status.Reject_Merge);
// all other stuff must be frozen, since the only allowed operation is to reject the merge
shortNameTextBox.setEnabled(false);
productGrsfTypeListbox.setEnabled(false);
sdgFlag.setEnabled(false);
traceabilityFlag.setEnabled(false);
// freeze other panels
connectWidget.freezeWidget();
similarRecordPanel.freezeWidget();
suggestedMergesPanel.freezeWidget();
}else{
// remove to be merged, since it cannot be set by a user
statusToShow.remove(Status.To_be_Merged);
// remove reject merge
statusToShow.remove(Status.Reject_Merge);
// 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().<SelectElement>cast().getOptions().getItem(0).setDisabled(true);
for (Status availableStatus : statusToShow) {
@ -423,14 +520,80 @@ public class ManageProductWidget extends Composite{
@UiHandler("confirmButton")
void onSaveButton(ClickEvent ce){
String report = "";
Set<String> hashtags = new HashSet<>();
annotationAreaGroup.setType(ControlGroupType.NONE);
annotationArea.setPlaceholder("");
listBoxStatusGroup.setType(ControlGroupType.NONE);
if(isRevertingMerge && listBoxStatus.getSelectedIndex() <= 0){
listBoxStatusGroup.setType(ControlGroupType.ERROR);
return;
}
// in case we are rejecting the record or the merge, the annotation is mandatory
Status selectedStatus = Status.fromString(listBoxStatus.getSelectedItemText());
if(selectedStatus.equals(Status.Reject_Merge) || selectedStatus.equals(Status.Rejected)){
if(annotationArea.getText() == null || annotationArea.getText().isEmpty()){
annotationArea.setPlaceholder("In case of reject operations you must specify this field");
annotationAreaGroup.setType(ControlGroupType.ERROR);
return;
}
}
manageProductModal.setCloseVisible(false);
cancelButton.setEnabled(false);
confirmButton.setEnabled(false);
loaderIcon.setVisible(true);
if(isRevertingMerge)
revertMergeOperation();
else
performRecordUpdate();
}
/**
* Perform a revert merge operation
*/
private void revertMergeOperation(){
service.performRevertOperation(revertableOperation, new AsyncCallback<Boolean>() {
@Override
public void onSuccess(Boolean result) {
confirmButton.setEnabled(true);
loaderIcon.setVisible(false);
if(!result){
showInfo("Unable to perform this operation. ", AlertType.ERROR);
}
else{
infoBlock.setVisible(true);
infoBlock.setType(AlertType.SUCCESS);
infoBlock.setText("The request has been processed successfully!");
confirmButton.removeFromParent();
cancelButton.setText("Ok");
cancelButton.setType(ButtonType.INFO);
cancelButton.setEnabled(true);
}
}
@Override
public void onFailure(Throwable caught) {
showInfo("Unable to perform this operation. " + (caught != null ? "Error was " + caught : ""), AlertType.ERROR);
confirmButton.setEnabled(true);
loadingImage.setVisible(false);
}
});
}
/**
* Perform an update for this record
*/
private void performRecordUpdate(){
String report = "";
Set<String> hashtags = new HashSet<>();
// get short name
bean.setShortNameUpdated(shortNameTextBox.getText());
@ -438,7 +601,7 @@ public class ManageProductWidget extends Composite{
report += "\n- The GRSF Short Name has been changed to '" + bean.getShortNameUpdated() + "' from '" + bean.getShortName() + "';";
hashtags.add(HashTagsOnUpdate.SHORTNAME_UPDATED.getString());
}
// status
bean.setNewGrsfType(productGrsfTypeListbox.getSelectedItemText());
if(bean.getNewGrsfType().equalsIgnoreCase(bean.getCurrentGrsfType())){
@ -465,7 +628,7 @@ public class ManageProductWidget extends Composite{
}else
report += "\n\t - keep this suggestion " + cb.getKnowledgeBaseId() + ";";
}
if(addConnectionHashtag)
hashtags.add(HashTagsOnUpdate.CONNECT.getString());
}
@ -493,7 +656,7 @@ public class ManageProductWidget extends Composite{
hashtags.add(HashTagsOnUpdate.MERGE.getString());
}
}
// set new values
bean.setAnnotation(new HTML(annotationArea.getText().trim()).getText());
@ -510,10 +673,10 @@ public class ManageProductWidget extends Composite{
else
hashtags.add(HashTagsOnUpdate.TRACEABILITY_FLAG_UNSET.getString());
}
// update the traceability flag
bean.setTraceabilityFlag(traceabilityNewValue);
// sdg flag
Boolean sdgNewValue = sdgFlag.getValue();
boolean currentSdgFlag = bean.isSdgFlag();
@ -524,10 +687,10 @@ public class ManageProductWidget extends Composite{
else
hashtags.add(HashTagsOnUpdate.SDG_FLAG_UNSET.getString());
}
// update the traceability flag
bean.setSdgFlag(sdgNewValue);
// force the new status in the listbox
if(bean.isMergesInvolved()){
bean.setNewStatus(Status.To_be_Merged);
@ -577,7 +740,6 @@ public class ManageProductWidget extends Composite{
showInfo(STATUS_UPDATE_ERROR + ": " + caught.getMessage(), AlertType.ERROR);
}
});
}
@UiHandler("cancelButton")
@ -597,7 +759,7 @@ public class ManageProductWidget extends Composite{
infoBlock.setType(type);
infoBlock.setVisible(true);
}
/**
* Retrieve the list of types for stocks and fisheries, given the domain
* @param domain

View File

@ -25,8 +25,8 @@
</b:ControlLabel>
<b:Controls>
<b:TextArea alternateSize="LARGE" placeholder="GRSF Name"
visibleLines="2" readOnly="true" width="97%" b:id="grsfname"
title="GRSF Name" ui:field="GRSFNameTexBox" />
enabled="false" visibleLines="2" width="97%"
b:id="grsfname" title="GRSF Name" ui:field="GRSFNameTexBox" />
</b:Controls>
</b:ControlGroup>
@ -37,7 +37,7 @@
</b:ControlLabel>
<b:Controls>
<b:TextArea alternateSize="LARGE" placeholder="GRSF Short Name"
visibleLines="2" readOnly="false" width="97%" b:id="shortname"
visibleLines="2" width="97%" b:id="shortname"
title="GRSF Short Name" ui:field="shortNameTextBox" />
</b:Controls>
</b:ControlGroup>
@ -48,8 +48,9 @@
</b:ControlLabel>
<b:Controls>
<b:TextArea alternateSize="LARGE" placeholder="GRSF Semantic Identifier"
visibleLines="2" readOnly="true" width="97%" b:id="semanticidentifier"
title="GRSF Semantic Identifier" ui:field="semanticIdentifierTextBox" />
enabled="false" visibleLines="2" width="97%"
b:id="semanticidentifier" title="GRSF Semantic Identifier"
ui:field="semanticIdentifierTextBox" />
</b:Controls>
</b:ControlGroup>
@ -70,8 +71,8 @@
</b:ControlLabel>
<b:Controls>
<b:TextBox b:id="currentStatus" alternateSize="LARGE"
readOnly="true" width="97%" title="The current status of this record"
ui:field="currentStatus">
enabled="false" width="97%"
title="The current status of this record" ui:field="currentStatus">
</b:TextBox>
</b:Controls>
</b:ControlGroup>
@ -135,8 +136,7 @@
<b>SDG Flag:</b>
</b:ControlLabel>
<b:Controls>
<b:CheckBox b:id="sdgflag" title="SDG Flag"
ui:field="sdgFlag"></b:CheckBox>
<b:CheckBox b:id="sdgflag" title="SDG Flag" ui:field="sdgFlag"></b:CheckBox>
</b:Controls>
</b:ControlGroup>
@ -150,6 +150,56 @@
</b:Controls>
</b:ControlGroup>
<g:VerticalPanel ui:field="moreInfoAboutOperation"
visible="false" width="100%">
<!-- <b:ControlGroup ui:field="originalRequest"> -->
<!-- <b:ControlLabel for="requestType" title="Request Type"> -->
<!-- <b>Request Type was:</b> -->
<!-- </b:ControlLabel> -->
<!-- <b:Controls> -->
<!-- <b:TextArea alternateSize="LARGE" placeholder="Request Type" -->
<!-- visibleLines="2" readOnly="true" width="97%" b:id="requestType" -->
<!-- title="Request Type" ui:field="requestTypeBox" /> -->
<!-- </b:Controls> -->
<!-- </b:ControlGroup> -->
<b:ControlGroup ui:field="originalAuthor">
<b:ControlLabel for="requestPerformedBy" title="Request was performed by">
<b>Request was originally performed by:</b>
</b:ControlLabel>
<b:Controls>
<b:TextArea alternateSize="LARGE" placeholder="Request author"
visibleLines="2" width="97%" b:id="requestPerformedBy" enabled="false"
title="Request was performed by" ui:field="requestAuthor" />
</b:Controls>
</b:ControlGroup>
<b:ControlGroup ui:field="originalRecordUUID">
<b:ControlLabel for="requestPerformedOnRecord"
title="Request was performed on Record">
<b>Request was performed on Record:</b>
</b:ControlLabel>
<b:Controls>
<b:TextArea alternateSize="LARGE"
placeholder="Request performed on record" visibleLines="2"
width="97%" b:id="requestPerformedOnRecord" enabled="false"
title="Request was performed on Record" ui:field="requestRecordUUID" />
</b:Controls>
</b:ControlGroup>
<b:ControlGroup ui:field="originalOperationDate">
<b:ControlLabel for="requestTimestamp" title="Request timestamp">
<b>Request was performed at:</b>
</b:ControlLabel>
<b:Controls>
<b:TextArea alternateSize="LARGE" placeholder="Request timestamp"
visibleLines="2" enabled="false" width="97%" b:id="requestTimestamp"
title="Request timestamp" ui:field="requestTimestamp" />
</b:Controls>
</b:ControlGroup>
</g:VerticalPanel>
<b:ControlGroup ui:field="annotationAreaGroup">
<b:ControlLabel for="annotation"
title="An annotation message to send along the update">
@ -161,6 +211,7 @@
title="An annotation message to send along the update" ui:field="annotationArea"></b:TextArea>
</b:Controls>
</b:ControlGroup>
</b:Form>
<!-- Alert blocks for info/errors -->

View File

@ -1,199 +0,0 @@
package org.gcube.datacatalogue.grsf_manage_widget.client.view;
import java.util.Date;
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.shared.RevertableOperationInfo;
import com.github.gwtbootstrap.client.ui.AlertBlock;
import com.github.gwtbootstrap.client.ui.Button;
import com.github.gwtbootstrap.client.ui.Icon;
import com.github.gwtbootstrap.client.ui.Image;
import com.github.gwtbootstrap.client.ui.Modal;
import com.github.gwtbootstrap.client.ui.TextArea;
import com.github.gwtbootstrap.client.ui.constants.AlertType;
import com.github.gwtbootstrap.client.ui.constants.ButtonType;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Style.FontWeight;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.i18n.client.DateTimeFormat;
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.Anchor;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
public class ManageRevertOperationWidget extends Composite {
private static ManageRevertOperationWidgetUiBinder uiBinder = GWT
.create(ManageRevertOperationWidgetUiBinder.class);
interface ManageRevertOperationWidgetUiBinder extends
UiBinder<Widget, ManageRevertOperationWidget> {
}
public ManageRevertOperationWidget() {
initWidget(uiBinder.createAndBindUi(this));
}
@UiField
VerticalPanel moreInfoAboutOperation;
@UiField
Modal revertOperationModal;
@UiField
Icon loaderIcon;
@UiField
Image loadingImage;
@UiField
AlertBlock infoBlock;
@UiField
Button revertButton;
@UiField
Button cancelButton;
@UiField
TextArea requestAuthor;
@UiField
TextArea requestTypeBox;
@UiField
TextArea requestRecordUUID;
@UiField
TextArea requestTimestamp;
private static GRSFManageWidgetServiceAsync service = GWT.create(GRSFManageWidgetService.class);
public static final String LOADING_IMAGE_URL = GWT.getModuleBaseURL() + "../images/loader.gif";
private RevertableOperationInfo revertableOperation = null;
public ManageRevertOperationWidget(String encryptedUrlOperation) {
initWidget(uiBinder.createAndBindUi(this));
GWT.log("Encrypted url is " + encryptedUrlOperation);
if(encryptedUrlOperation == null || encryptedUrlOperation.isEmpty())
return;
// start loader service
loadingImage.setUrl(LOADING_IMAGE_URL);
loadingImage.setVisible(true);
// show modal
revertOperationModal.addStyleName("management-metadata-modal-style");
// revertOperationModal.getElement().getStyle().setWidth(60, Unit.PCT);
revertOperationModal.show();
loaderIcon.getElement().getStyle().setMarginRight(10, Unit.PX);
moreInfoAboutOperation.getElement().getStyle().setMarginBottom(50, Unit.PX);
// async request to fetch the product
loadModalContent(encryptedUrlOperation);
}
/**
* Validate the parameters of the url and ask the editor/reviewer what he/she wants to do.
* @param encryptedUrlOperation
*/
private void loadModalContent(String encryptedUrlOperation) {
revertButton.setEnabled(false);
service.validateRevertOperation(encryptedUrlOperation, new AsyncCallback<RevertableOperationInfo>() {
@Override
public void onSuccess(RevertableOperationInfo result) {
loadingImage.setVisible(false);
if(result != null){
revertableOperation = result;
String dateString = DateTimeFormat.getFormat("MM/dd/yyyy HH:mm:ss").format(new Date(revertableOperation.getTimestamp()));
requestAuthor.setText(revertableOperation.getFullNameOriginalAdmin() + "(" + revertableOperation.getUserNameOriginalAdmin() + ")");
requestTypeBox.setText(revertableOperation.getOperation().toString().toUpperCase());
requestRecordUUID.setText(revertableOperation.getUuid());
requestTimestamp.setText(dateString);
Anchor viewRecord = new Anchor();
viewRecord.setText("View Record");
viewRecord.getElement().getStyle().setFontWeight(FontWeight.BOLD);
viewRecord.setHref(revertableOperation.getRecordUrl());
viewRecord.setTarget("_blank");
moreInfoAboutOperation.add(viewRecord);
moreInfoAboutOperation.setVisible(true);
revertButton.setEnabled(true);
}else
displayError(null);
}
@Override
public void onFailure(Throwable caught) {
loadingImage.setVisible(false);
displayError(caught);
}
});
}
@UiHandler("revertButton")
void onSaveButton(ClickEvent ce){
loaderIcon.setVisible(true);
revertButton.setEnabled(false);
cancelButton.setEnabled(false);
service.performRevertOperation(revertableOperation, new AsyncCallback<Boolean>() {
@Override
public void onSuccess(Boolean result) {
revertButton.setEnabled(true);
loaderIcon.setVisible(false);
if(!result)
displayError(null);
else{
infoBlock.setVisible(true);
infoBlock.setType(AlertType.SUCCESS);
infoBlock.setText("The request has been processed successfully!");
revertButton.removeFromParent();
cancelButton.setText("Ok");
cancelButton.setType(ButtonType.INFO);
cancelButton.setEnabled(true);
}
}
@Override
public void onFailure(Throwable caught) {
displayError(caught);
}
});
}
@UiHandler("cancelButton")
void onCancelButton(ClickEvent ce){
revertOperationModal.hide();
}
protected void displayError(Throwable caught) {
infoBlock.setVisible(true);
infoBlock.setType(AlertType.ERROR);
infoBlock.setText("Unable to perform this operation. " + (caught != null ? "Error was " + caught : ""));
}
}

View File

@ -1,87 +0,0 @@
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:g="urn:import:com.google.gwt.user.client.ui" xmlns:b="urn:import:com.github.gwtbootstrap.client.ui">
<ui:style>
.loader-image {
display: block;
margin: auto auto;
}
</ui:style>
<g:HTMLPanel>
<b:Modal ui:field="revertOperationModal" title="Revert Operation"
backdrop="STATIC" keyboard="true" animation="true" closeVisible="true">
<g:VerticalPanel width="100%" ui:field="container">
<!-- Loader image at the beginning -->
<b:Image ui:field="loadingImage" styleName="{style.loader-image}"
visible="true"></b:Image>
<g:VerticalPanel ui:field="moreInfoAboutOperation"
visible="false" width="100%">
<b:Form type="VERTICAL" visible="true" ui:field="formUpdate"
width="100%">
<b:ControlGroup ui:field="originalRequest">
<b:ControlLabel for="requestType" title="Request Type">
<b>Request Type:</b>
</b:ControlLabel>
<b:Controls>
<b:TextArea alternateSize="LARGE" placeholder="Request Type"
visibleLines="2" readOnly="true" width="97%" b:id="requestType"
title="Request Type" ui:field="requestTypeBox" />
</b:Controls>
</b:ControlGroup>
<b:ControlGroup ui:field="originalAuthor">
<b:ControlLabel for="requestPerformedBy" title="Request was performed by">
<b>Request was performed by:</b>
</b:ControlLabel>
<b:Controls>
<b:TextArea alternateSize="LARGE" placeholder="Request author"
visibleLines="2" readOnly="true" width="97%" b:id="requestPerformedBy"
title="Request was performed by" ui:field="requestAuthor" />
</b:Controls>
</b:ControlGroup>
<b:ControlGroup ui:field="originalRecordUUID">
<b:ControlLabel for="requestPerformedOnRecord"
title="Request was performed on Record">
<b>Request was performed on Record:</b>
</b:ControlLabel>
<b:Controls>
<b:TextArea alternateSize="LARGE"
placeholder="Request performed on record" visibleLines="2"
readOnly="true" width="97%" b:id="requestPerformedOnRecord"
title="Request was performed on Record" ui:field="requestRecordUUID" />
</b:Controls>
</b:ControlGroup>
<b:ControlGroup ui:field="originalOperationDate">
<b:ControlLabel for="requestTimestamp" title="Request timestamp">
<b>Request was performed at:</b>
</b:ControlLabel>
<b:Controls>
<b:TextArea alternateSize="LARGE" placeholder="Request timestamp"
visibleLines="2" readOnly="true" width="97%" b:id="requestTimestamp"
title="Request timestamp" ui:field="requestTimestamp" />
</b:Controls>
</b:ControlGroup>
</b:Form>
</g:VerticalPanel>
<!-- Alert blocks for info/errors -->
<b:AlertBlock type="INFO" close="false" animation="true"
visible="false" ui:field="infoBlock"></b:AlertBlock>
</g:VerticalPanel>
<b:ModalFooter>
<b:Icon type="GEAR" spin="true" ui:field="loaderIcon"
visible="false" />
<b:Button ui:field="cancelButton">Cancel</b:Button>
<b:Button icon="FILE" type="PRIMARY" ui:field="revertButton">Revert</b:Button>
</b:ModalFooter>
</b:Modal>
</g:HTMLPanel>
</ui:UiBinder>

View File

@ -58,7 +58,7 @@ public class ConnectToWidget extends Composite{
private List<ConnectedBean> currentlyConnected; // they can be "unconnected" or "removed"
private List<ConnectedBean> suggestedByKnowledgeBase; // they can be "connected"
private GRSFManageWidgetServiceAsync service;
private static List<CheckBox> buttonsOrCheckboxesToFreeze = new ArrayList<CheckBox>();
private HandlerManager eventBus;
public ConnectToWidget(final ManageProductBean bean, GRSFManageWidgetServiceAsync service, final HandlerManager eventBus) {
@ -161,6 +161,8 @@ public class ConnectToWidget extends Composite{
}
});
rightPanel.add(removeExtra);
// append buttons and checkboxes that could be frozen
buttonsOrCheckboxesToFreeze.add(removeExtra);
}
final CheckBox connect = new CheckBox("Connect");
@ -179,6 +181,10 @@ public class ConnectToWidget extends Composite{
hp.add(rightPanel);
hp.getElement().getStyle().setPadding(10, Unit.PX);
hp.getElement().getStyle().setMarginBottom(10, Unit.PX);
// append buttons and checkboxes that could be frozen
buttonsOrCheckboxesToFreeze.add(connect);
return hp;
}
@ -364,5 +370,15 @@ public class ConnectToWidget extends Composite{
else
tooltip.hide();
}
public void freezeWidget(){
suggestRecord.setEnabled(false);
// freeze the checkboxes
for (CheckBox cb : buttonsOrCheckboxesToFreeze) {
cb.setEnabled(false);
}
}
}

View File

@ -1,37 +0,0 @@
package org.gcube.datacatalogue.grsf_manage_widget.client.view.subwidgets;
import com.github.gwtbootstrap.client.ui.ControlLabel;
import com.github.gwtbootstrap.client.ui.TextBox;
import com.google.gwt.core.client.GWT;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Widget;
/**
* A dynamic ControlGroup to add to a form
* @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
*/
public class FormEntryModel extends Composite{
private static FormEntryModelUiBinder uiBinder = GWT
.create(FormEntryModelUiBinder.class);
interface FormEntryModelUiBinder extends UiBinder<Widget, FormEntryModel> {
}
@UiField
ControlLabel labelEntry;
@UiField
TextBox entryValue;
public FormEntryModel(String label, String value) {
initWidget(uiBinder.createAndBindUi(this));
labelEntry.add(new HTML("<b> " + label.substring(0, 1).toUpperCase() + label.substring(1) + ":</b>"));
entryValue.setText(value);
}
}

View File

@ -27,7 +27,7 @@ import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
public class SimilarGRSFRecordWidget extends Composite {
private static SimilarGRSFRecordWidgetUiBinder uiBinder = GWT
.create(SimilarGRSFRecordWidgetUiBinder.class);
@ -42,6 +42,7 @@ public class SimilarGRSFRecordWidget extends Composite {
Button viewMore;
private List<SimilarGRSFRecord> availableGRSFSimilarRecords;
private static List<CheckBox> buttonsOrCheckboxesToFreeze = new ArrayList<CheckBox>();
private List<Widget> toHide = new ArrayList<Widget>();
private static final int THRESHOLD_SET_HIDDEN = 5;
private static final String SEE_MORE = "See More";
@ -133,7 +134,7 @@ public class SimilarGRSFRecordWidget extends Composite {
Paragraph identifier = new Paragraph("UUID: " +
similarGRSFRecord.getKnowledgeBaseId());
leftPanel.add(identifier);
Paragraph semanticIdentifier = new Paragraph("Semantic Identifier: " +
similarGRSFRecord.getSemanticIdentifier());
leftPanel.add(semanticIdentifier);
@ -174,6 +175,7 @@ public class SimilarGRSFRecordWidget extends Composite {
rightPanel.getElement().getStyle().setFloat(Float.RIGHT);
rightPanel.add(mergeSuggested);
buttonsOrCheckboxesToFreeze.add(mergeSuggested);
hp.add(leftPanel);
hp.add(rightPanel);
hp.getElement().getStyle().setPadding(10, Unit.PX);
@ -190,4 +192,13 @@ public class SimilarGRSFRecordWidget extends Composite {
return availableGRSFSimilarRecords;
}
public void freezeWidget() {
// freeze the checkboxes
for (CheckBox cb : buttonsOrCheckboxesToFreeze) {
cb.setEnabled(false);
}
}
}

View File

@ -267,4 +267,10 @@ public class SuggestMerges extends Composite {
else
tooltip.hide();
}
public void freezeWidget(){
addSimilarRecord.setEnabled(false);
}
}

View File

@ -74,15 +74,12 @@ public class GRSFNotificationService extends RemoteServiceServlet implements GRS
}
@Override
public ManageProductBean getProductBeanById(String productIdentifier) throws Exception {
public ManageProductBean getProductBeanById(String productIdentifier, boolean requestForRevertingMerge) throws Exception {
ManageProductBean toReturn = null;
// check into user's session first
HttpSession httpSession = getThreadLocalRequest().getSession();
String sessionProductKey = ScopeProvider.instance.get() + productIdentifier;
if(httpSession.getAttribute(sessionProductKey) != null)
return (ManageProductBean) httpSession.getAttribute(sessionProductKey);
// testing case...
if(!Utils.isIntoPortal()){
@ -222,6 +219,10 @@ public class GRSFNotificationService extends RemoteServiceServlet implements GRS
String catalogueIdentifier = record.getId();
String description = record.getNotes();
Status status = Status.fromString(extrasWithoutNamespaces.get(Constants.STATUS_OF_THE_GRSF_RECORD_CUSTOM_KEY).get(0));
if(status.equals(Status.To_be_Merged) && !requestForRevertingMerge)
throw new Exception("Records under merging activities cannot be managed without explicit authorisation!");
String uuidKB = extrasWithoutNamespaces.get(Constants.UUID_KB_CUSTOM_KEY).get(0);
String grsfDomain = extrasWithoutNamespaces.get(Constants.DOMAIN_CUSTOM_KEY).get(0);
String semanticId = extrasWithoutNamespaces.get(Constants.GRSF_SEMANTIC_IDENTIFIER_CUSTOM_KEY).get(0);
@ -243,10 +244,6 @@ public class GRSFNotificationService extends RemoteServiceServlet implements GRS
logger.warn("Unable to fetch sdg flag. Setting it to false", e);
}
// TODO, remove
if(status.equals(Status.To_be_Merged) || status.equals(Status.Rejected))
throw new Exception("Records under merging activity or rejected cannot be managed!");
// Get similar GRSF records, if any (each of which should have name, description, url and id(i.e semantic identifier))
List<String> similarGrsfRecordsAsStrings = extrasWithoutNamespaces.containsKey(Constants.SIMILAR_GRSF_RECORDS_CUSTOM_KEY) ? extrasWithoutNamespaces.get(Constants.SIMILAR_GRSF_RECORDS_CUSTOM_KEY): null;
@ -314,10 +311,6 @@ public class GRSFNotificationService extends RemoteServiceServlet implements GRS
}
}
// save it into session
if(toReturn != null)
httpSession.setAttribute(sessionProductKey, toReturn);
logger.debug("Returning item bean " + toReturn);
return toReturn;
}

View File

@ -81,7 +81,7 @@ public class GRSFUpdaterServiceClient {
}
return toReturn;
}
/**
* Send updates to the knowledge base
* @param httpClient
@ -147,7 +147,7 @@ public class GRSFUpdaterServiceClient {
logger.info("Update request looks like " + obj.toJSONString());
logger.info("Sending request to " + serviceUrl + Constants.SERVICE_POST_UPDATER_METHOD);
HttpPost request = new HttpPost(serviceUrl + Constants.SERVICE_POST_UPDATER_METHOD);
request.setHeader("Accept", "application/json");
request.setHeader("Content-type", "application/json");