geoportal-data-viewer-app/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/ui/cms/search/SearchFacilityUI.java

546 lines
16 KiB
Java

package org.gcube.portlets.user.geoportaldataviewer.client.ui.cms.search;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.gcube.application.geoportalcommon.shared.GeoportalItemReferences;
import org.gcube.application.geoportalcommon.shared.ResultSetPaginatedData;
import org.gcube.application.geoportalcommon.shared.SearchingFilter;
import org.gcube.application.geoportalcommon.shared.SearchingFilter.LOGICAL_OP;
import org.gcube.application.geoportalcommon.shared.SearchingFilter.ORDER;
import org.gcube.application.geoportalcommon.shared.WhereClause;
import org.gcube.application.geoportalcommon.shared.geoportal.DocumentDV;
import org.gcube.application.geoportalcommon.shared.geoportal.ResultDocumentDV;
import org.gcube.application.geoportalcommon.shared.geoportal.config.ItemFieldDV;
import org.gcube.portlets.user.geoportaldataviewer.client.GeoportalDataViewerServiceAsync;
import org.gcube.portlets.user.geoportaldataviewer.client.events.ClosedViewDetailsEvent;
import org.gcube.portlets.user.geoportaldataviewer.client.events.SearchPerformedEvent;
import org.gcube.portlets.user.geoportaldataviewer.client.events.ShowDetailsEvent;
import org.gcube.portlets.user.geoportaldataviewer.client.events.ShowDetailsEvent.EVENT_SOURCE;
import org.gcube.portlets.user.geoportaldataviewer.client.util.LoaderIcon;
import org.gcube.portlets.user.geoportaldataviewer.client.util.StringUtil;
import org.gcube.portlets.user.geoportaldataviewer.shared.ResultSetPaginatedDataIDs;
import com.github.gwtbootstrap.client.ui.Alert;
import com.github.gwtbootstrap.client.ui.Button;
import com.github.gwtbootstrap.client.ui.DropdownButton;
import com.github.gwtbootstrap.client.ui.ListBox;
import com.github.gwtbootstrap.client.ui.NavLink;
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.IconType;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ChangeEvent;
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.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
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.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Widget;
/**
* The Class SearchFacilityUI.
*
* @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it
*
* Dec 14, 2021
*/
public class SearchFacilityUI extends Composite {
private static final int SEARCHING_LIMIT_RESULTS_TO = 50;
private static SearchFacilityPanelUiBinder uiBinder = GWT.create(SearchFacilityPanelUiBinder.class);
protected static final int MIN_LENGHT_SERCHING_STRING = 3;
public static final String DEFAULT_DOCUMENT_PROJECTION_NAME = "_theDocument";
@UiField
ListBox listBoxSortBy;
@UiField
ListBox listBoxSearchFor;
@UiField
TextBox searchField;
@UiField
NavLink sortByToogle;
@UiField
Button resetSearch;
@UiField
HTMLPanel panelResults;
@UiField
HorizontalPanel toogleSortBy;
private List<ItemFieldDV> searchForFields;
private List<ItemFieldDV> sortByFields;
private SearchingFilter currentSortFilter;
private HandlerManager appManagerBus;
private static final String LABEL_FILTER_SEPARATOR = " - ";
protected static final int MAX_TEXT_DIMENSION = 100;
protected static final int MAX_COLUMNS_RESULTS = 3;
private ResultSetPaginatedData latestResult;
private DropdownButton searchFacilityButton;
private String profileID;
private List<ItemFieldDV> displayByFields;
/**
* The Interface SearchFacilityPanelUiBinder.
*
* @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it
*
* Dec 14, 2021
*/
interface SearchFacilityPanelUiBinder extends UiBinder<Widget, SearchFacilityUI> {
}
/**
* Instantiates a new search facility UI.
*
* @param profileID the profile ID
* @param appManagerBus the app manager bus
* @param sortByFields the sort by fields
* @param searchForFields the search for fields
* @param initialSortFilter the initial sort filter
*/
public SearchFacilityUI(String profileID, HandlerManager appManagerBus, List<ItemFieldDV> displayByFields,
List<ItemFieldDV> sortByFields, List<ItemFieldDV> searchForFields, SearchingFilter initialSortFilter) {
initWidget(uiBinder.createAndBindUi(this));
this.profileID = profileID;
this.displayByFields = displayByFields;
this.searchForFields = searchForFields;
this.currentSortFilter = initialSortFilter;
this.sortByFields = sortByFields;
this.appManagerBus = appManagerBus;
resetSearch.setType(ButtonType.LINK);
listBoxSortBy.setWidth("180px");
// listBoxSearchFor.setWidth("140px");
bindEvents();
}
/**
* To label filter.
*
* @param itemField the item field
* @param direction the direction
* @return the string
*/
private String toLabelFilter(ItemFieldDV itemField, ORDER direction) {
String labelFilter = itemField.getDisplayName() + LABEL_FILTER_SEPARATOR + direction.name();
return labelFilter;
}
/**
* Bind events.
*/
private void bindEvents() {
for (ItemFieldDV record_FIELD : sortByFields) {
if (record_FIELD.isSortable()) {
String labelASC = toLabelFilter(record_FIELD, ORDER.ASC);
String labelDESC = toLabelFilter(record_FIELD, ORDER.DESC);
listBoxSortBy.addItem(labelASC);
listBoxSortBy.addItem(labelDESC);
}
}
listBoxSortBy.addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event) {
if (latestResult != null && latestResult.getData().size() > 0) {
doSearchEvent();
}
}
});
for (ItemFieldDV record_FIELD : searchForFields) {
GWT.log("search for: " + record_FIELD);
if (record_FIELD.isSearchable()) {
listBoxSearchFor.addItem(record_FIELD.getDisplayName());
}
}
listBoxSearchFor.addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event) {
if (searchField.getText().length() >= MIN_LENGHT_SERCHING_STRING) {
doSearchEvent();
}
}
});
sortByToogle.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
if (toogleSortBy.isVisible())
toogleSortBy.setVisible(false);
else
toogleSortBy.setVisible(true);
}
});
searchField.addKeyPressHandler(new KeyPressHandler() {
@Override
public void onKeyPress(KeyPressEvent event) {
if (com.google.gwt.event.dom.client.KeyCodes.KEY_ENTER == event.getCharCode()) {
GWT.log(searchField.getText());
doSearchEvent();
}
}
});
resetSearch.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
resetCurrentSearch();
}
});
}
public void resetCurrentSearch() {
searchField.setText("");
resetSearch.setVisible(false);
panelResults.clear();
latestResult = null;
appManagerBus.fireEvent(new SearchPerformedEvent(profileID, null, true));
setSearchEnabled(false);
}
/**
* Sets the search enabled.
*
* @param bool the new search enabled
*/
private void setSearchEnabled(boolean bool) {
if (bool) {
searchFacilityButton.getElement().addClassName("highlight-button");
} else {
searchFacilityButton.getElement().removeClassName("highlight-button");
}
}
/**
* Search concessioni.
*/
private void searchProjects() {
SearchingFilter filter = getCurrentSortFilter();
panelResults.clear();
panelResults.add(new HTML("<hr>"));
panelResults.add(new LoaderIcon("Searching..."));
GeoportalDataViewerServiceAsync.Util.getInstance().getListProjects(profileID, 0, SEARCHING_LIMIT_RESULTS_TO,
filter, false, new AsyncCallback<ResultSetPaginatedDataIDs>() {
@Override
public void onFailure(Throwable caught) {
// showLoading(false);
// Window.alert(caught.getMessage());
panelResults.clear();
panelResults.add(new HTML("<hr>"));
Alert alert = new Alert("Error on searching. Please, refresh or change the search");
alert.setType(AlertType.ERROR);
alert.setClose(false);
panelResults.add(alert);
}
@Override
public void onSuccess(ResultSetPaginatedDataIDs result) {
appManagerBus
.fireEvent(new SearchPerformedEvent(profileID, result.getResultSetProjectIDs(), false));
setSearchEnabled(true);
latestResult = result;
panelResults.clear();
panelResults.add(new HTML("<hr>"));
if (result.getData().size() == 0) {
panelResults.add(new HTML("No result found"));
return;
}
int allItems = result.getResultSetProjectIDs().size();
int returnedItems = result.getData().size();
String message = "";
if (allItems > returnedItems) {
message = "Your query returns too many results (" + allItems
+ "). Please find below the top " + returnedItems + ".<br>";
} else if (returnedItems > 0) {
message = "Found " + returnedItems;
message += returnedItems > 0 ? " items" : " item";
message += ". ";
}
if (returnedItems > 0) {
message += "On the map you can see all the projects with a centroid matching the query";
}
HTML resultMessage = new HTML(message);
resultMessage.getElement().addClassName("search_result_msg");
panelResults.add(resultMessage);
FlexTable ft = new FlexTable();
ft.getElement().setClassName("table-results");
int i = 0;
// Table headers
for (ItemFieldDV itemField : displayByFields) {
if (i > MAX_COLUMNS_RESULTS) {
break;
}
i++;
String displayName = itemField.getDisplayName();
ft.setWidget(0, i, new HTML(displayName));
}
// From the Second row
i = 1;
for (DocumentDV documentDV : result.getData()) {
ResultDocumentDV resultDoc = (ResultDocumentDV) documentDV;
NavLink locateOnMap = new NavLink("Show");
locateOnMap.setTitle("Locate this project on Map and show details");
locateOnMap.setIcon(IconType.MAP_MARKER);
locateOnMap.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
GeoportalItemReferences gir = new GeoportalItemReferences(resultDoc.getProjectID(),
profileID);
// here
appManagerBus.fireEvent(new ClosedViewDetailsEvent());
appManagerBus.fireEvent(new ShowDetailsEvent(gir, null, true, true, EVENT_SOURCE.LOCATE_SEARCHED));
// appManagerBus.fireEvent(new ShowPopupOnCentroidEvent(profileID,
// resultDoc.getProjectID(), resultDoc.getSpatialReference()));
}
});
// First column
ft.setWidget(i, 0, locateOnMap);
int j = 0;
// Other columns
for (ItemFieldDV itemField : displayByFields) {
if (j > MAX_COLUMNS_RESULTS) {
break;
}
String firstJsonField = itemField.getJsonFields().get(0);
GWT.log("The json fields is: " + firstJsonField);
String key = firstJsonField.replace(DEFAULT_DOCUMENT_PROJECTION_NAME + ".", "");
Object value = documentDV.getDocumentAsMap().get(key);
String objectToRender = "";
String toTitle = "";
if (value == null) {
objectToRender = "N.A.";
toTitle = objectToRender;
} else if (value instanceof ArrayList) {
ArrayList<Object> arrayValues = (ArrayList<Object>) value;
String toReturn = "<ul>";
String toDisplayTitle = "";
for (Object arrayValue : arrayValues) {
toReturn += "<li>" + arrayValue + "</li>";
toDisplayTitle += arrayValue + "; ";
}
toReturn += "</ul>";
GWT.log("Array returning: " + key + " is instance of: " + value.getClass()
+ " to return: " + toReturn);
toTitle = toDisplayTitle;
objectToRender = StringUtil.ellipsize(toReturn, MAX_TEXT_DIMENSION);
} else {
String valueStr = value.toString();
toTitle = valueStr;
objectToRender = StringUtil.ellipsize(valueStr, MAX_TEXT_DIMENSION);
}
GWT.log("The key is: " + key + " objectToRender is: " + objectToRender);
HTML htmlValue = new HTML(objectToRender);
htmlValue.setTitle(toTitle);
ft.setWidget(i, ++j, htmlValue);
}
i++;
}
panelResults.add(ft);
}
});
}
/**
* To display authors.
*
* @param listValues the list values
* @return the string
*/
private String toDisplayList(List<Object> listValues) {
String toDisplay = "";
if (listValues == null)
return toDisplay;
for (Object author : listValues) {
toDisplay += author + "; ";
}
return toDisplay;
}
/**
* Do search event.
*/
private void doSearchEvent() {
String searchText = searchField.getText();
if (searchText.length() < MIN_LENGHT_SERCHING_STRING) {
Window.alert("Please enter at least " + MIN_LENGHT_SERCHING_STRING + " characters");
return;
}
resetSearch.setVisible(true);
// appManagerBus.fireEvent(new GetListOfRecordsEvent(RECORD_TYPE.CONCESSIONE,
// getCurrentSortFilter()));
searchProjects();
}
/**
* To sort filter.
*
* @param labelFilter the label filter
* @return the searching filter
*/
public SearchingFilter toSortFilter(String labelFilter) {
GWT.log("toSortFilter for label " + labelFilter);
String[] array = labelFilter.split(LABEL_FILTER_SEPARATOR);
SearchingFilter sortFilter = null;
try {
ItemFieldDV recordField = null;
for (ItemFieldDV value : sortByFields) {
if (array[0].equalsIgnoreCase(value.getDisplayName())) {
recordField = value;
break;
}
}
ORDER orderField = ORDER.valueOf(array[1]);
sortFilter = new SearchingFilter(Arrays.asList(recordField), orderField);
} catch (Exception e) {
}
GWT.log("toSortFilter Got " + sortFilter);
return sortFilter;
}
/**
* Built searching filter.
*
* @return the searching filter
*/
private SearchingFilter builtSearchingFilter() {
SearchingFilter searchingFilter = toSortFilter(listBoxSortBy.getSelectedValue());
String searchText = searchField.getText();
if (searchText != null && !searchText.isEmpty()) {
Map<String, Object> searchInto = new HashMap<String, Object>();
List<String> listOfSeachingFields = new ArrayList<String>();
for (ItemFieldDV recordField : searchForFields) {
if (recordField.getDisplayName().equals(listBoxSearchFor.getSelectedValue())) {
listOfSeachingFields = recordField.getJsonFields();
continue;
}
}
for (String fieldname : listOfSeachingFields) {
searchInto.put(fieldname, searchText);
}
WhereClause where = new WhereClause();
where.setSearchInto(searchInto);
where.setOperator(LOGICAL_OP.OR);
// THIS CLAUSE IS ADDED IN ORDER TO SEARCH ONLY PUBLISHED PRODUCT (WITH SUCCESS)
Map<String, Object> searchInto2 = new HashMap<String, Object>();
// searchInto2.put("report.status", "PASSED");
WhereClause where2 = new WhereClause(LOGICAL_OP.AND, searchInto2);
// searchingFilter.setConditions(Arrays.asList(where, where2));
searchingFilter.setConditions(Arrays.asList(where));
}
return searchingFilter;
}
/**
* Gets the current sort filter.
*
* @return the current sort filter
*/
public SearchingFilter getCurrentSortFilter() {
currentSortFilter = builtSearchingFilter();
GWT.log("currentSortFilter: " + currentSortFilter);
return currentSortFilter;
}
/**
* Sets the search button.
*
* @param searchFacilityButton the new search button
*/
public void setSearchButton(DropdownButton searchFacilityButton) {
this.searchFacilityButton = searchFacilityButton;
}
}