From a24a923616184344abac7d576a87185490423d8e Mon Sep 17 00:00:00 2001 From: Costantino Perciante Date: Wed, 13 Jul 2016 14:11:15 +0000 Subject: [PATCH] Improved info icons git-svn-id: http://svn.d4science-ii.research-infrastructures.eu/gcube/trunk/portlets/widgets/ckan-metadata-publisher-widget@130315 82a268e6-3cf1-43bd-a215-b396298e98cf --- .classpath | 1 + .settings/org.eclipse.wst.common.component | 3 + .../client/ui/CreateDatasetForm.java | 302 ++++++++++++++++-- .../client/ui/CreateDatasetForm.ui.xml | 153 ++++++--- .../client/ui/MetaDataFieldSkeleton.java | 74 ++++- .../client/ui/MetaDataFieldSkeleton.ui.xml | 16 +- .../client/ui/utils/GcubeDialogExtended.java | 68 ++++ .../client/ui/utils/InfoIconsLabels.java | 54 ++++ .../public/CKanMetadataPublisher.css | 5 + .../server/CKANPublisherServicesImpl.java | 22 +- .../shared/DatasetMetadataBean.java | 47 ++- .../shared/LicensesBean.java | 29 +- 12 files changed, 649 insertions(+), 125 deletions(-) create mode 100644 src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/utils/GcubeDialogExtended.java create mode 100644 src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/utils/InfoIconsLabels.java diff --git a/.classpath b/.classpath index 57c104b..3e9559a 100644 --- a/.classpath +++ b/.classpath @@ -20,6 +20,7 @@ + diff --git a/.settings/org.eclipse.wst.common.component b/.settings/org.eclipse.wst.common.component index 0190c48..8820ed0 100644 --- a/.settings/org.eclipse.wst.common.component +++ b/.settings/org.eclipse.wst.common.component @@ -5,6 +5,9 @@ + + uses + diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/CreateDatasetForm.java b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/CreateDatasetForm.java index 616df38..bd939ea 100644 --- a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/CreateDatasetForm.java +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/CreateDatasetForm.java @@ -13,6 +13,8 @@ import org.gcube.portlets.widgets.ckandatapublisherwidget.client.CKanPublisherSe import org.gcube.portlets.widgets.ckandatapublisherwidget.client.CKanPublisherServiceAsync; import org.gcube.portlets.widgets.ckandatapublisherwidget.client.events.DeleteCustomFieldEvent; import org.gcube.portlets.widgets.ckandatapublisherwidget.client.events.DeleteCustomFieldEventHandler; +import org.gcube.portlets.widgets.ckandatapublisherwidget.client.ui.utils.GcubeDialogExtended; +import org.gcube.portlets.widgets.ckandatapublisherwidget.client.ui.utils.InfoIconsLabels; import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.DatasetMetadataBean; import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.LicensesBean; import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.MetaDataProfileBean; @@ -23,8 +25,10 @@ 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.ListBox; import com.github.gwtbootstrap.client.ui.Paragraph; +import com.github.gwtbootstrap.client.ui.Popover; import com.github.gwtbootstrap.client.ui.Tab; import com.github.gwtbootstrap.client.ui.TabPanel; import com.github.gwtbootstrap.client.ui.TextArea; @@ -34,6 +38,8 @@ import com.github.gwtbootstrap.client.ui.constants.AlertType; import com.github.gwtbootstrap.client.ui.constants.ButtonType; import com.github.gwtbootstrap.client.ui.resources.Bootstrap.Tabs; import com.google.gwt.core.client.GWT; +import com.google.gwt.dom.client.Element; +import com.google.gwt.dom.client.Style.Cursor; import com.google.gwt.dom.client.Style.Display; import com.google.gwt.event.dom.client.ChangeEvent; import com.google.gwt.event.dom.client.ChangeHandler; @@ -45,12 +51,18 @@ 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.DOM; +import com.google.gwt.user.client.EventListener; import com.google.gwt.user.client.Timer; import com.google.gwt.user.client.Window; 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.FlowPanel; +import com.google.gwt.user.client.ui.FocusPanel; +import com.google.gwt.user.client.ui.HTML; import com.google.gwt.user.client.ui.HTMLPanel; +import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.SimplePanel; import com.google.gwt.user.client.ui.VerticalPanel; import com.google.gwt.user.client.ui.Widget; @@ -109,6 +121,34 @@ public class CreateDatasetForm extends Composite{ @UiField SimplePanel workspaceResourcesContainer; @UiField Button continueThirdStep; @UiField Button goBackButtonFirstStep; + @UiField Anchor licenseUrlAnchor; + @UiField Paragraph unavailableUrl; + + // info panels + @UiField Icon infoIconTags; + @UiField FocusPanel focusPanelTags; + @UiField Popover popoverTags; + @UiField Icon infoIconVisibility; + @UiField FocusPanel focusPanelVisibility; + @UiField Popover popoverVisibility; + @UiField Icon infoIconAuthor; + @UiField FocusPanel focusPanelAuthor; + @UiField Popover popoverAuthor; + @UiField Icon infoIconMaintainerEmail; + @UiField FocusPanel focusPanelMaintainerEmail; + @UiField Popover popoverMaintainerEmail; + @UiField Icon infoIconAuthorEmail; + @UiField FocusPanel focusPanelAuthorEmail; + @UiField Popover popoverAuthorEmail; + @UiField Icon infoIconProfiles; + @UiField FocusPanel focusPanelProfiles; + @UiField Popover popoverProfiles; + @UiField Icon infoIconMaintainer; + @UiField FocusPanel focusPanelMaintainer; + @UiField Popover popoverMaintainer; + @UiField Icon infoIconCustomFields; + @UiField FocusPanel focusPanelCustomFields; + @UiField Popover popoverCustomFields; // tab panel private TabPanel tabPanel; @@ -155,6 +195,9 @@ public class CreateDatasetForm extends Composite{ // bind on events bind(); + // prepare info icons + prepareInfoIcons(); + // set info block setAlertBlock("Retrieving information, please wait...", AlertType.INFO, true); @@ -175,9 +218,9 @@ public class CreateDatasetForm extends Composite{ // fill the form versionTextbox.setText(String.valueOf(bean.getVersion())); - authorTextbox.setText(bean.getAuthor()); + authorTextbox.setText(bean.getAuthorSurname() + " " + bean.getAuthorName()); authorEmailTextbox.setText(bean.getAuthorEmail()); - maintainerTextbox.setText(bean.getMaintainer()); + maintainerTextbox.setText(bean.getAuthorSurname() + " " + bean.getAuthorName()); maintainerEmailTextbox.setText(bean.getMaintainerEmail()); prepareMetadataList(receivedBean); @@ -195,23 +238,23 @@ public class CreateDatasetForm extends Composite{ @Override public void onSuccess(LicensesBean lBean) { - if(lBean != null && !lBean.getLicenses().isEmpty()){ + if(lBean != null && !lBean.getLicenseTitles().isEmpty()){ licenseBean = lBean; // sort the list - List listOfNames = licenseBean.getLicenses(); + List listOfNames = new ArrayList(); + Collections.copy(listOfNames, licenseBean.getLicenseTitles()); Collections.sort(listOfNames); - // fill the listbox for(int i = 0; i < listOfNames.size(); i++){ licenseListbox.addItem(listOfNames.get(i)); - if(listOfNames.get(i).equals("Creative Commons Attribution")) - licenseListbox.setItemSelected(i, true); - } + // set the url of the license, if any + showLicenseUrl(); + // everything went ok setAlertBlock("", AlertType.ERROR, false); continueButton.setEnabled(true); @@ -247,6 +290,93 @@ public class CreateDatasetForm extends Composite{ } + /** + * Prepare the info icons of all core metadata info + */ + private void prepareInfoIcons() { + + // tags + preparePopupPanelAndPopover( + InfoIconsLabels.TAGS_INFO_ID_POPUP, + InfoIconsLabels.TAGS_INFO_TEXT, + InfoIconsLabels.TAGS_INFO_CAPTION, + infoIconTags, + popoverTags, + focusPanelTags + ); + + // visibility + preparePopupPanelAndPopover( + InfoIconsLabels.VISIBILITY_INFO_ID_POPUP, + InfoIconsLabels.VISIBILITY_INFO_TEXT, + InfoIconsLabels.VISIBILITY_INFO_CAPTION, + infoIconVisibility, + popoverVisibility, + focusPanelVisibility + ); + + // author + preparePopupPanelAndPopover( + InfoIconsLabels.AUTHOR_INFO_ID_POPUP, + InfoIconsLabels.AUTHOR_INFO_TEXT, + InfoIconsLabels.AUTHOR_INFO_CAPTION, + infoIconAuthor, + popoverAuthor, + focusPanelAuthor + ); + + // author's email + preparePopupPanelAndPopover( + InfoIconsLabels.AUTHOR_EMAIL_INFO_ID_POPUP, + InfoIconsLabels.AUTHOR_EMAIL_INFO_TEXT, + InfoIconsLabels.AUTHOR_EMAIL_INFO_CAPTION, + infoIconAuthorEmail, + popoverAuthorEmail, + focusPanelAuthorEmail + ); + + // maintainer + preparePopupPanelAndPopover( + InfoIconsLabels.MAINTAINER_INFO_ID_POPUP, + InfoIconsLabels.MAINTAINER_INFO_TEXT, + InfoIconsLabels.MAINTAINER_INFO_CAPTION, + infoIconMaintainer, + popoverMaintainer, + focusPanelMaintainer + ); + + // maintainer's email + preparePopupPanelAndPopover( + InfoIconsLabels.MAINTAINER_EMAIL_INFO_ID_POPUP, + InfoIconsLabels.MAINTAINER_EMAIL_INFO_TEXT, + InfoIconsLabels.MAINTAINER_EMAIL_INFO_CAPTION, + infoIconMaintainerEmail, + popoverMaintainerEmail, + focusPanelMaintainerEmail + ); + + // profiles + preparePopupPanelAndPopover( + InfoIconsLabels.PROFILES_INFO_ID_POPUP, + InfoIconsLabels.PROFILES_INFO_TEXT, + InfoIconsLabels.PROFILES_INFO_CAPTION, + infoIconProfiles, + popoverProfiles, + focusPanelProfiles + ); + + // custom fields + preparePopupPanelAndPopover( + InfoIconsLabels.CUSTOM_FIELDS_INFO_ID_POPUP, + InfoIconsLabels.CUSTOM_FIELDS_INFO_TEXT, + InfoIconsLabels.CUSTOM_FIELDS_INFO_CAPTION, + infoIconCustomFields, + popoverCustomFields, + focusPanelCustomFields + ); + + } + /** * Invoked when the workspace is used. * @param idFolderWorkspace @@ -285,9 +415,9 @@ public class CreateDatasetForm extends Composite{ titleTextBox.setText(bean.getTitle()); descriptionTextarea.setText(bean.getDescription()); versionTextbox.setText(String.valueOf(bean.getVersion())); - authorTextbox.setText(bean.getAuthor()); + authorTextbox.setText(bean.getAuthorSurname() + " " + bean.getAuthorName()); authorEmailTextbox.setText(bean.getAuthorEmail()); - maintainerTextbox.setText(bean.getMaintainer()); + maintainerTextbox.setText(bean.getAuthorSurname() + " " + bean.getAuthorName()); maintainerEmailTextbox.setText(bean.getMaintainerEmail()); prepareMetadataList(receivedBean); @@ -344,23 +474,23 @@ public class CreateDatasetForm extends Composite{ @Override public void onSuccess(LicensesBean lBean) { - if(lBean != null && !lBean.getLicenses().isEmpty()){ + if(lBean != null && !lBean.getLicenseTitles().isEmpty()){ licenseBean = lBean; // sort the list - List listOfNames = licenseBean.getLicenses(); + List listOfNames = new ArrayList(); + Collections.copy(listOfNames, licenseBean.getLicenseTitles()); Collections.sort(listOfNames); - // fill the listbox for(int i = 0; i < listOfNames.size(); i++){ licenseListbox.addItem(listOfNames.get(i)); - if(listOfNames.get(i).equals("Creative Commons Attribution")) - licenseListbox.setItemSelected(i, true); - } + // set the url of the license, if any + showLicenseUrl(); + // everything went ok setAlertBlock("", AlertType.ERROR, false); continueButton.setEnabled(true); @@ -562,9 +692,14 @@ public class CreateDatasetForm extends Composite{ @UiHandler("createButton") void createDatasetEvent(ClickEvent e){ - boolean profileDataValid = areProfileDataValid(); + String errorMessage = areProfileDataValid(); - if(profileDataValid){ + if(errorMessage != null){ + + alertOnCreate("Please check the inserted values and the mandatory fields [" + errorMessage +"]", AlertType.ERROR); + + } + else{ String title = titleTextBox.getValue(); String description = descriptionTextarea.getText(); @@ -578,7 +713,7 @@ public class CreateDatasetForm extends Composite{ String chosenOrganization = organizationsListbox.getSelectedItemText(); // fill the bean - receivedBean.setAuthor(author); + receivedBean.setAuthorFullName(author); receivedBean.setAuthorEmail(authorEmail); receivedBean.setDescription(description); receivedBean.setLicense(selectedLicense); @@ -715,10 +850,6 @@ public class CreateDatasetForm extends Composite{ } }); - }else{ - - alertOnCreate("Please check the inserted values and the mandatory fields", AlertType.ERROR); - } } @@ -726,15 +857,15 @@ public class CreateDatasetForm extends Composite{ * Test if profile data are valid * @return */ - private boolean areProfileDataValid() { + private String areProfileDataValid() { for (MetaDataFieldSkeleton field : listOfMetadataFields) { if(!field.isFieldValueValid()) - return false; + return field.getFieldName() + " is not valid"; } - return true; + return null; } /** @@ -815,13 +946,6 @@ public class CreateDatasetForm extends Composite{ } - // name reg expression - String regexName = "^[a-zA-Z\\s]+"; - if(!validateByRegExpression(maintainerTextbox.getText(), regexName)){ - errorMessage = "Not valid maintainer name"; - return errorMessage; - } - // email reg expression String regexMail = "\\b[\\w.%-]+@[-.\\w]+\\.[A-Za-z]{2,4}\\b"; if(!validateByRegExpression(maintainerEmailTextbox.getText(), regexMail)){ @@ -965,6 +1089,40 @@ public class CreateDatasetForm extends Composite{ } + @UiHandler("licenseListbox") + void onSelectedLicenseChange(ChangeEvent c){ + + showLicenseUrl(); + } + + /** + * The body of the onSelectedLicenseChange + */ + private void showLicenseUrl(){ + + List titles = licenseBean.getLicenseTitles(); + String selectedLicense = licenseListbox.getSelectedItemText(); + GWT.log("Selected license is " + selectedLicense); + for (int i = 0; i < titles.size(); i++) { + if(selectedLicense.equals(titles.get(i))){ + + if(licenseBean.getLicenseUrls().get(i).isEmpty()) + break; + + GWT.log("URL is " + licenseBean.getLicenseUrls().get(i)); + + licenseUrlAnchor.setText(licenseBean.getLicenseUrls().get(i)); + licenseUrlAnchor.setHref(licenseBean.getLicenseUrls().get(i)); + licenseUrlAnchor.setVisible(true); + unavailableUrl.setVisible(false); + return; + } + } + licenseUrlAnchor.setVisible(false); + unavailableUrl.setVisible(true); + + } + /** * Add the tag as an element */ @@ -1052,4 +1210,82 @@ public class CreateDatasetForm extends Composite{ tagsPanel.clear(); } + + /** + * Prepare the popover and the gcube popup panel for information. + * @param text + * @param captionText + * @param iconElement + * @param popover + * @param focusPanel + */ + private void preparePopupPanelAndPopover( + final String popupId, + final String text, + final String captionText, + Icon iconElement, + Popover popover, + FocusPanel focusPanel){ + + // prepare the popover + popover.setText(new HTML("

" + text +"

").getHTML()); + popover.setHeading(new HTML("" + captionText +"").getHTML()); + + // set icon cursor + iconElement.getElement().getStyle().setCursor(Cursor.HELP); + + // prepare the gcube dialog + focusPanel.addClickHandler(new ClickHandler() { + + @Override + public void onClick(ClickEvent event) { + + // Retrieve elemnt that should have this id + GcubeDialogExtended popup = null; + try{ + Element element = DOM.getElementById(popupId); + popup = (GcubeDialogExtended) Widget.asWidgetOrNull(getWidget(element)); + }catch(Exception e){ + GWT.log("ERROR"); + } + + // if it doesn't exist, create it + if(popup == null){ + + popup = new GcubeDialogExtended(captionText, text); + popup.getElement().setId(popupId); + popup.setModal(false); + + } + + // then center and show + popup.center(); + popup.show(); + + } + }); + + } + + /** + * Check if an element of such type is actually a widget + * @param element + * @return + */ + public static IsWidget getWidget(Element element) { + EventListener listener = DOM + .getEventListener(element); + // No listener attached to the element, so no widget exist for this + // element + if (listener == null) { + GWT.log("Widget is NULL"); + return null; + } + if (listener instanceof Widget) { + // GWT uses the widget as event listener + GWT.log("Widget is " + listener); + return (Widget) listener; + } + return null; + } } diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/CreateDatasetForm.ui.xml b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/CreateDatasetForm.ui.xml index 0652c38..95f0de2 100644 --- a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/CreateDatasetForm.ui.xml +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/CreateDatasetForm.ui.xml @@ -62,7 +62,7 @@ + width="95%" b:id="title" title="Product title" ui:field="titleTextBox" /> @@ -72,7 +72,7 @@ @@ -84,16 +84,15 @@ Tags: - - - - Tags are meaningful information that can be associated to the - product and by means of them - it can be retrieved. A tag cannot - contain white spaces and can contain only alphanumeric - characters. - It must be at least of two characters. + + + + + + @@ -108,48 +107,61 @@ License: + width="91%" ui:field="licenseListbox"> - - - License definitions and additional information can be found at - opendefinition.org - - Visibility: + Selected + License Url: + + + Unavailable + + + + + + + Visibility: - Private + width="91%" ui:field="visibilityListbox"> + Restricted Public - - - Private products can only be accessed by certain users, while - public products can be accessed by anyone. + + + + + + - Publish in: + Publish in: + width="96%" title="Publish in this organization" ui:field="organizationsListbox"> - + Version: + width="90%" title="Product version" ui:field="versionTextbox" /> @@ -159,8 +171,17 @@ Author: - + + + + + + + + @@ -170,8 +191,17 @@ Author Email: - + + + + + + + + @@ -181,7 +211,16 @@ + width="90%" b:id="maintainer" title="Product maintainer" + ui:field="maintainerTextbox" /> + + + + + + + @@ -191,7 +230,16 @@ + width="90%" b:id="emailMaintaner" title="Product author" + ui:field="maintainerEmailTextbox" /> + + + + + + + @@ -200,9 +248,18 @@ Profile: + width="91%" title="The product profile format to be used" + ui:field="metadataProfilesFormatListbox"> none + + + + + + + @@ -219,9 +276,13 @@ checked="true" ui:field="addResourcesCheckBox"> Add folder content as resources - - - Automatically add folder content as resources of the product + + + + + + @@ -267,7 +328,6 @@ - Insert Product Profile Information @@ -289,14 +349,13 @@ - - - Custom fields are customable metadata that will be added to the - product. - You have to choose a unique key for the field and a value - for this. You - can remove them at any time until you create the - product. + + + + + + diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/MetaDataFieldSkeleton.java b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/MetaDataFieldSkeleton.java index 2bd2f61..516d5a0 100644 --- a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/MetaDataFieldSkeleton.java +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/MetaDataFieldSkeleton.java @@ -2,22 +2,32 @@ package org.gcube.portlets.widgets.ckandatapublisherwidget.client.ui; import java.util.List; +import org.gcube.portlets.widgets.ckandatapublisherwidget.client.ui.utils.GcubeDialogExtended; import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.MetadataFieldWrapper; import com.github.gwtbootstrap.client.ui.CheckBox; import com.github.gwtbootstrap.client.ui.ControlLabel; import com.github.gwtbootstrap.client.ui.Controls; +import com.github.gwtbootstrap.client.ui.Icon; import com.github.gwtbootstrap.client.ui.ListBox; +import com.github.gwtbootstrap.client.ui.Popover; import com.github.gwtbootstrap.client.ui.TextBox; import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.SpanElement; +import com.google.gwt.dom.client.Style.Cursor; import com.google.gwt.dom.client.Style.Display; +import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.event.logical.shared.ResizeEvent; +import com.google.gwt.event.logical.shared.ResizeHandler; 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.Window; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.FlowPanel; -import com.google.gwt.user.client.ui.InlineLabel; +import com.google.gwt.user.client.ui.FocusPanel; +import com.google.gwt.user.client.ui.HTML; import com.google.gwt.user.client.ui.SimplePanel; import com.google.gwt.user.client.ui.Widget; @@ -34,9 +44,11 @@ public class MetaDataFieldSkeleton extends Composite{ @UiField SpanElement name; @UiField SimplePanel elementPanel; @UiField FlowPanel noteFieldContainer; - @UiField InlineLabel noteField; + @UiField Popover noteFieldPopover; @UiField ControlLabel controlLabel; @UiField Controls controls; + @UiField Icon infoIcon; + @UiField FocusPanel focusPanelIconContainer; // the element that holds the value (it could be a checkbox, textbox or listbox) private Widget holder; @@ -44,12 +56,15 @@ public class MetaDataFieldSkeleton extends Composite{ // the field this object represents private MetadataFieldWrapper field; + // the dialog box for this metadata + private GcubeDialogExtended dialog; + public MetaDataFieldSkeleton(MetadataFieldWrapper field) { initWidget(uiBinder.createAndBindUi(this)); // prepare information this.field = field; - + // add custom css properties controls.addStyleName("form-controls-custom"); controlLabel.addStyleName("form-control-label-custom"); @@ -108,21 +123,54 @@ public class MetaDataFieldSkeleton extends Composite{ elementPanel.add(holder); } - } - + // set holder width - holder.setWidth("90%"); + if(holder.getClass().equals(ListBox.class)) + holder.setWidth("96%"); + else + holder.setWidth("95%"); - // set the notes, if any + // set the notes, if any, and the popover if(field.getNote() != null && !field.getNote().isEmpty()){ - noteField.setText(field.getNote()); + noteFieldPopover.setText(new HTML("

" + field.getNote() +"

").getHTML()); + noteFieldPopover.setHeading(new HTML("" + field.getFieldName() +"").getHTML()); + infoIcon.getElement().getStyle().setCursor(Cursor.HELP); + noteFieldPopover.setHtml(true); noteFieldContainer.setVisible(true); - }else{ - noteFieldContainer.setVisible(false); } + + // add a resize handler to center the dialog box if it's not null + Window.addResizeHandler(new ResizeHandler() { + + @Override + public void onResize(ResizeEvent event) { + + if(dialog != null) + dialog.center(); + + } + }); + + } + + @UiHandler("focusPanelIconContainer") + void onInfoIconClick(ClickEvent c){ + + if(dialog == null){ + + // create the dialog box + dialog = new GcubeDialogExtended(field.getFieldName(), field.getNote()); + + // set as non modal + dialog.setModal(false); + } + + // else just show and center + dialog.center(); + dialog.show(); } /** @@ -130,8 +178,10 @@ public class MetaDataFieldSkeleton extends Composite{ * @return */ public boolean isFieldValueValid() { - + String validator = field.getValidator(); + + GWT.log("Validator is " + validator); // if validator is not present and it is not a textbox if((validator == null || validator.isEmpty()) && !(holder.getClass().equals(TextBox.class) && field.getMandatory())) @@ -145,7 +195,7 @@ public class MetaDataFieldSkeleton extends Composite{ value = ((ListBox)holder).getSelectedItemText(); else if(holder.getClass().equals(TextBox.class)){ value = ((TextBox)holder).getText(); - + // if there is not a validator... if(validator == null){ if(value.isEmpty() && field.getMandatory()) diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/MetaDataFieldSkeleton.ui.xml b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/MetaDataFieldSkeleton.ui.xml index 91f27ce..ab471ad 100644 --- a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/MetaDataFieldSkeleton.ui.xml +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/MetaDataFieldSkeleton.ui.xml @@ -6,7 +6,7 @@ .note-container { display: inline-block; float: right; - width: 20%; + width: 5%; color: #aaaaaa; } @@ -21,21 +21,25 @@ display: inline-block; } - + * - + + width="95%"> - - + + + + + diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/utils/GcubeDialogExtended.java b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/utils/GcubeDialogExtended.java new file mode 100644 index 0000000..e810f75 --- /dev/null +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/utils/GcubeDialogExtended.java @@ -0,0 +1,68 @@ +package org.gcube.portlets.widgets.ckandatapublisherwidget.client.ui.utils; + +import org.gcube.portlets.user.gcubewidgets.client.popup.GCubeDialog; + +import com.github.gwtbootstrap.client.ui.Paragraph; +import com.google.gwt.dom.client.Element; +import com.google.gwt.dom.client.EventTarget; +import com.google.gwt.dom.client.Style.Cursor; +import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.event.dom.client.ClickHandler; +import com.google.gwt.user.client.ui.Anchor; +import com.google.gwt.user.client.ui.FlexTable; +import com.google.gwt.user.client.ui.HTML; +import com.google.gwt.user.client.ui.HasHorizontalAlignment; + +/** + * Extended version of the GcubeDialog with close symbol on the caption + * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) + */ +public class GcubeDialogExtended extends GCubeDialog { + + public GcubeDialogExtended(String captionText, String text){ + + // add custom style + addStyleName("metadata-popup-panel"); + + // create an anchor to close the dialogbox + final Anchor closeAnchor = new Anchor("x"); + closeAnchor.setTitle("Close"); + + // create a panel that will be put into the caption + FlexTable captionLayoutTable = new FlexTable(); + captionLayoutTable.setText(0, 0, captionText); + captionLayoutTable.setWidget(0, 3, closeAnchor); + captionLayoutTable.getCellFormatter().setHorizontalAlignment(0, 3, + HasHorizontalAlignment.ALIGN_RIGHT); + captionLayoutTable.setWidth("100%"); + + HTML caption = (HTML) getCaption(); + caption.getElement().getStyle().setCursor(Cursor.MOVE); + caption.getElement().appendChild(captionLayoutTable.getElement()); + caption.addClickHandler(new ClickHandler() { + @Override + public void onClick(ClickEvent event) { + // get the event + EventTarget target = event.getNativeEvent().getEventTarget(); + Element targetElement = (Element) target.cast(); + + // fire the event to the anchor + if (targetElement == closeAnchor.getElement()) { + closeAnchor.fireEvent(event); + } + } + }); + closeAnchor.addClickHandler(new ClickHandler() { + + @Override + public void onClick(ClickEvent event) { + + hide(); + + } + }); + + // set the text + add(new Paragraph(text)); + } +} diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/utils/InfoIconsLabels.java b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/utils/InfoIconsLabels.java new file mode 100644 index 0000000..11f35d1 --- /dev/null +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/utils/InfoIconsLabels.java @@ -0,0 +1,54 @@ +package org.gcube.portlets.widgets.ckandatapublisherwidget.client.ui.utils; + +/** + * Labels and texts for core ckan information + * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) + */ +public class InfoIconsLabels { + + // TAGS + public static final String TAGS_INFO_ID_POPUP = "tags-popup-panel-info"; + public static final String TAGS_INFO_CAPTION = "Tags"; + public static final String TAGS_INFO_TEXT = "Tags are meaningful information that can be associated to the product and by means of them it can be retrieved. A tag cannot contain white spaces and can contain only alphanumeric characters. It must be at least of two characters."; + + // VISIBILITY + public static final String VISIBILITY_INFO_ID_POPUP = "visibility-popup-panel-info"; + public static final String VISIBILITY_INFO_CAPTION = "Visibility"; + public static final String VISIBILITY_INFO_TEXT = "Restricted products can only be accessed by certain users, while Public products can be accessed by anyone."; + + // AUTHOR + public static final String AUTHOR_INFO_ID_POPUP = "author-popup-panel-info"; + public static final String AUTHOR_INFO_CAPTION = "Author's fullname"; + public static final String AUTHOR_INFO_TEXT = "The author of this product. Example: Joe Bloggs."; + + // AUTHOR EMAIL + public static final String AUTHOR_EMAIL_INFO_ID_POPUP = "author-email-popup-panel-info"; + public static final String AUTHOR_EMAIL_INFO_CAPTION = "Author's email"; + public static final String AUTHOR_EMAIL_INFO_TEXT = "The author's email. Example: joe.bloggs@catalogue.com"; + + // MAINTAINER + public static final String MAINTAINER_INFO_ID_POPUP = "maintainer-popup-panel-info"; + public static final String MAINTAINER_INFO_CAPTION = "Maintainer"; + public static final String MAINTAINER_INFO_TEXT = "The maintainer of this product (a person or an organization). Examples: Joe Bloggs, D4Science"; + + // MAINTAINER EMAIL + public static final String MAINTAINER_EMAIL_INFO_ID_POPUP = "maintainer-email-popup-panel-info"; + public static final String MAINTAINER_EMAIL_INFO_CAPTION = "Maintainer's email"; + public static final String MAINTAINER_EMAIL_INFO_TEXT = "The maintainer's email. Example: joe.bloggs@catalogue.com"; + + // PROFILES + public static final String PROFILES_INFO_ID_POPUP = "product-profiles-popup-panel-info"; + public static final String PROFILES_INFO_CAPTION = "Product Profiles"; + public static final String PROFILES_INFO_TEXT = "Select a profile, different from none, for your product among the ones available"; + + // RESOURCES + public static final String RESOURCES_INFO_ID_POPUP = "resouces-popup-panel-info"; + public static final String RESOURCES_INFO_CAPTION = "Product Resources"; + public static final String RESOURCES_INFO_TEXT = "Automatically add folder content as resources of the product"; + + // CUSTOM FIELDS + public static final String CUSTOM_FIELDS_INFO_ID_POPUP = "custom-fields-popup-panel-info"; + public static final String CUSTOM_FIELDS_INFO_CAPTION = "Product Custom Fields"; + public static final String CUSTOM_FIELDS_INFO_TEXT = "Custom fields are customable metadata that will be added to the product. You have to choose a unique key for the field and a value for this. You can remove them at any time until you create theproduct."; + +} diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/public/CKanMetadataPublisher.css b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/public/CKanMetadataPublisher.css index 064d968..dd86212 100644 --- a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/public/CKanMetadataPublisher.css +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/public/CKanMetadataPublisher.css @@ -30,4 +30,9 @@ .form-control-label-custom { width: 16% !important; +} + +/** for the popup panels **/ +.metadata-popup-panel { + max-width: 30%; } \ No newline at end of file diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/CKANPublisherServicesImpl.java b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/CKANPublisherServicesImpl.java index a97bdc5..31df96d 100644 --- a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/CKANPublisherServicesImpl.java +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/CKANPublisherServicesImpl.java @@ -44,6 +44,8 @@ import org.slf4j.LoggerFactory; import com.google.gwt.user.server.rpc.RemoteServiceServlet; import com.liferay.portal.service.UserLocalServiceUtil; +import eu.trentorise.opendata.jackan.model.CkanLicense; + /** * Server side of the data publisher. * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) @@ -332,8 +334,16 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C logger.debug("List of licenses was into session"); } else{ - List titlesLicenses = getCkanUtilsObj().getLicenseTitles(); - licensesBean = new LicensesBean(titlesLicenses); + List titlesLicenses = getCkanUtilsObj().getLicenses(); + List titles = new ArrayList(); + List urls = new ArrayList(); + for (CkanLicense license : titlesLicenses) { + titles.add(license.getTitle()); + + String url = (license.getUrl() != null && !license.getUrl().isEmpty()) ? license.getUrl() : ""; + urls.add(url); + } + licensesBean = new LicensesBean(titles, urls); httpSession.setAttribute(keyPerScope, licensesBean); logger.debug("List of licenses has been saved into session"); } @@ -373,7 +383,8 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C bean.setId(folderId); bean.setOwnerIdentifier(owner); bean.setVersion(1); - bean.setAuthor(userOwner.getFullname()); + bean.setAuthorName(userOwner.getFirstName()); + bean.setAuthorSurname(userOwner.getLastName()); bean.setAuthorEmail(userOwner.getEmail()); bean.setMaintainer(userOwner.getFullname()); bean.setMaintainerEmail(userOwner.getEmail()); @@ -427,7 +438,8 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C bean.setVersion(1); String onlyAlphanumeric = "test-creation-blablabla".replaceAll("[^A-Za-z0-9]", ""); bean.setTitle(onlyAlphanumeric + Calendar.getInstance().getTimeInMillis()); - bean.setAuthor("Costantino Perciante"); + bean.setAuthorName("Costantino"); + bean.setAuthorSurname("Perciante"); bean.setAuthorEmail("costantino.perciante@isti.cnr.it"); bean.setMaintainer("Costantino Perciante"); bean.setMaintainerEmail("costantino.perciante@isti.cnr.it"); @@ -515,7 +527,7 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C String title = toCreate.getTitle(); String organizationNameOrId = toCreate.getSelectedOrganization(); - String author = toCreate.getAuthor(); + String author = toCreate.getAuthorFullName(); String authorMail = toCreate.getAuthorEmail(); String maintainer = toCreate.getMaintainer(); String maintainerMail = toCreate.getMaintainerEmail(); diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/shared/DatasetMetadataBean.java b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/shared/DatasetMetadataBean.java index 2ea95d7..06a942f 100644 --- a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/shared/DatasetMetadataBean.java +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/shared/DatasetMetadataBean.java @@ -36,7 +36,9 @@ public class DatasetMetadataBean implements Serializable { private boolean visibility; // Private (false) or Public(true) private String source; // url of the folder in the workspace private long version; // version 1, 2 ... - private String author; // folder's owner fullname + private String authorName; // author name + private String authorSurname; // author surname + private String authorFullName; private String authorEmail; // folder's email owner private String maintainer; private String maintainerEmail; @@ -74,7 +76,7 @@ public class DatasetMetadataBean implements Serializable { public DatasetMetadataBean(String id, String title, String description, Map customFields, List tags, String license, boolean visibility, String source, long version, - String author, String authorEmail, String maintainer, + String authorName, String authorSurname, String authorEmail, String maintainer, String maintainerEmail, String ownerIdentifier, List organizationList, String selectedOrganization, List resources, @@ -89,7 +91,8 @@ public class DatasetMetadataBean implements Serializable { this.visibility = visibility; this.source = source; this.version = version; - this.author = author; + this.authorName = authorName; + this.authorSurname = authorSurname; this.authorEmail = authorEmail; this.maintainer = maintainer; this.maintainerEmail = maintainerEmail; @@ -188,12 +191,20 @@ public class DatasetMetadataBean implements Serializable { this.version = version; } - public String getAuthor() { - return author; + public String getAuthorName() { + return authorName; } - public void setAuthor(String author) { - this.author = author; + public void setAuthorName(String authorName) { + this.authorName = authorName; + } + + public String getAuthorSurname() { + return authorSurname; + } + + public void setAuthorSurname(String authorSurname) { + this.authorSurname = authorSurname; } public String getAuthorEmail() { @@ -243,6 +254,14 @@ public class DatasetMetadataBean implements Serializable { public void setResources(List resources) { this.resources = resources; } + + public String getAuthorFullName() { + return authorFullName; + } + + public void setAuthorFullName(String authorFullName) { + this.authorFullName = authorFullName; + } @Override public String toString() { @@ -250,12 +269,14 @@ public class DatasetMetadataBean implements Serializable { + ", description=" + description + ", customFields=" + customFields + ", tags=" + tags + ", license=" + license + ", visibility=" + visibility + ", source=" + source - + ", version=" + version + ", author=" + author - + ", authorEmail=" + authorEmail + ", maintainer=" + maintainer - + ", maintainerEmail=" + maintainerEmail + ", ownerIdentifier=" - + ownerIdentifier + ", organizationList=" + organizationList + + ", version=" + version + ", authorName=" + authorName + + ", authorSurname=" + authorSurname + ", authorFullName=" + + authorFullName + ", authorEmail=" + authorEmail + + ", maintainer=" + maintainer + ", maintainerEmail=" + + maintainerEmail + ", ownerIdentifier=" + ownerIdentifier + + ", organizationList=" + organizationList + ", selectedOrganization=" + selectedOrganization - + ", resources=" + resources + ", metadataList=" + metadataList + "]"; + + ", resources=" + resources + ", metadataList=" + metadataList + + "]"; } - } diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/shared/LicensesBean.java b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/shared/LicensesBean.java index 738892f..1880f9f 100644 --- a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/shared/LicensesBean.java +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/shared/LicensesBean.java @@ -10,8 +10,9 @@ import java.util.List; @SuppressWarnings("serial") public class LicensesBean implements Serializable{ - List licenses; - + private List licenseTitles; + private List licenseUrls; + public LicensesBean() { super(); } @@ -19,21 +20,31 @@ public class LicensesBean implements Serializable{ /** * @param licenses */ - public LicensesBean(List licenses) { + public LicensesBean(List licenseTitles, List licenseUrls) { super(); - this.licenses = licenses; + this.licenseTitles = licenseTitles; + this.licenseUrls = licenseUrls; } - public List getLicenses() { - return licenses; + public List getLicenseTitles() { + return licenseTitles; } - public void setLicenses(List licenses) { - this.licenses = licenses; + public void setLicenseTitles(List licenseTitles) { + this.licenseTitles = licenseTitles; + } + + public List getLicenseUrls() { + return licenseUrls; + } + + public void setLicenseUrls(List licenseUrls) { + this.licenseUrls = licenseUrls; } @Override public String toString() { - return "LicensesBean [licenses=" + licenses + "]"; + return "LicensesBean [licenseTitles=" + licenseTitles + + ", licenseUrls=" + licenseUrls + "]"; } }