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 searchForFields; private List 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 displayByFields; /** * The Interface SearchFacilityPanelUiBinder. * * @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it * * Dec 14, 2021 */ interface SearchFacilityPanelUiBinder extends UiBinder { } /** * 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 displayByFields, List sortByFields, List 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("
")); panelResults.add(new LoaderIcon("Searching...")); GeoportalDataViewerServiceAsync.Util.getInstance().getListProjects(profileID, 0, SEARCHING_LIMIT_RESULTS_TO, filter, false, new AsyncCallback() { @Override public void onFailure(Throwable caught) { // showLoading(false); // Window.alert(caught.getMessage()); panelResults.clear(); panelResults.add(new HTML("
")); 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("
")); 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 + ".
"; } 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 arrayValues = (ArrayList) value; String toReturn = "
    "; String toDisplayTitle = ""; for (Object arrayValue : arrayValues) { toReturn += "
  • " + arrayValue + "
  • "; toDisplayTitle += arrayValue + "; "; } toReturn += "
"; 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 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 searchInto = new HashMap(); List listOfSeachingFields = new ArrayList(); 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 searchInto2 = new HashMap(); // 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; } }