diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/component/search/SearchConfigurationMerger.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/component/search/SearchConfigurationMerger.java index 270b0250e23..b24c4ae916c 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/component/search/SearchConfigurationMerger.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/component/search/SearchConfigurationMerger.java @@ -97,25 +97,46 @@ private static SearchItemsType combineSearchItems(SearchItemsType searchItems, S return searchItems; } - private static List getSearchItemsWithDisplayOrder(SearchItemsType searchItems) { + /** + * Checks all search items in the list whether they have displayOrder set. + * For each search item without displayOrder we set its displayOrder to its index in the list. + * + * @param searchItems for which we need to have displayOrder set + * @return list of SearchItem where each have displayOrder set + */ + private static List getSearchItemsWithDisplayOrder(final SearchItemsType searchItems) { return IntStream .range(0, searchItems.getSearchItem().size()) .mapToObj(i -> { final SearchItemType customSearchItem = searchItems.getSearchItem().get(i); - if (customSearchItem.getDisplayOrder() == null) { - customSearchItem.setDisplayOrder(i); - } - return customSearchItem; + return customSearchItem.getDisplayOrder() == null ? + updateDisplayOrder(customSearchItem, i) : + customSearchItem; }).collect(Collectors.toList()); } - private static List getSearchItemsWithRemovedVisibleByDefault(SearchItemsType searchItems) { + /** + * Sets displayOrder of given SearchItem to given value. + * + * @param searchItem for which we want set new displayOrder + * @param newDisplayOrder new value of displayOrder + * @return SearchItem with updated displayOrder + */ + private static SearchItemType updateDisplayOrder(final SearchItemType searchItem, final Integer newDisplayOrder) { + searchItem.setDisplayOrder(newDisplayOrder); + return searchItem; + } + + /** + * Removes (sets to null) visibleByDefault property for all given SearchItems. + * + * @param searchItems for which we want to remove visibleByDefault property + * @return list of SearchItem where each have visibleByDefault set to null + */ + private static List getSearchItemsWithRemovedVisibleByDefault(final SearchItemsType searchItems) { return searchItems.getSearchItem().stream() - .peek(searchItem -> { - if (searchItem.isVisibleByDefault() != null) { - searchItem.setVisibleByDefault(null); - } - }).toList(); + .peek(searchItem -> searchItem.setVisibleByDefault(null)) + .toList(); } private static Predicate searchItemMatch(SearchItemType searchItem) { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/component/search/SearchItemWrapperComparator.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/component/search/SearchItemWrapperComparator.java index 81d038d72e2..d43b18fd162 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/component/search/SearchItemWrapperComparator.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/component/search/SearchItemWrapperComparator.java @@ -14,6 +14,9 @@ import org.apache.commons.lang3.StringUtils; /** + * Compares Search Items firstly by their displayOrder. + * If two Search Items have the same displayOrder (or have displayOrder null) they will be sorted alphabetically by their Name property. + * * @author matisovaa * */ diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/component/search/factory/SearchItemContext.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/component/search/factory/SearchItemContext.java index 964febee744..d6edf80cba4 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/component/search/factory/SearchItemContext.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/component/search/factory/SearchItemContext.java @@ -194,10 +194,7 @@ public boolean isVisible() { } public Integer getDisplayOrder() { - if (item.getDisplayOrder() != null) { - return item.getDisplayOrder(); - } - return null; + return item.getDisplayOrder(); } public IModel getDisplayName() { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/component/search/panel/BasicSearchPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/component/search/panel/BasicSearchPanel.java index a56930270ce..6af2dac6271 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/component/search/panel/BasicSearchPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/component/search/panel/BasicSearchPanel.java @@ -93,22 +93,7 @@ protected void populateItem(ListItem> item) { }; add(items); - currentBiggestDisplayOrder = getModelObject().getItemsList().stream() - .peek(item -> { - // add displayOrder for default search items which are visible, so they are properly sorted before items added by More button - // this case occurs when only default search items are in search box - if (item.isVisible() && item.getDisplayOrder() == null) { - item.setDisplayOrder(++currentBiggestDisplayOrder); - } - // it is needed to remove displayOrder for not visible search items, so they are properly sorted in More button alphabetically - // this case occurs when you switch between Saved filters - if (!item.isVisible() && item.getDisplayOrder() != null) { - item.setDisplayOrder(null); - } - }) - .map(FilterableSearchItemWrapper::getDisplayOrder) - .filter(Objects::nonNull) - .reduce(0, Integer::max); + currentBiggestDisplayOrder = calculateCurrentBiggestDisplayOrder(); // it is needed to sort search items after removal of displayOrder for not visible search items, // so they are properly sorted in More button alphabetically @@ -195,6 +180,41 @@ public void sortItems() { getModelObject().getItemsList().sort(new SearchItemWrapperComparator<>()); } + /** + * Calculates Current Biggest Display Order of visible Search panel items. + * It updates displayOrder of some search items before calculation to ensure that all visible items have displayOrder set and + * all not visible items have displayOrder null. + * Setting of displayOrder only for all visible items is crucial to preserve their order after adding of new items by More button. + * + * @return the biggest displayOrder of item in search box + */ + private int calculateCurrentBiggestDisplayOrder() { + return getModelObject().getItemsList().stream() + .peek(this::updateDisplayOrderIfNeeded) + .map(FilterableSearchItemWrapper::getDisplayOrder) + .filter(Objects::nonNull) + .reduce(0, Integer::max); + } + + /** + * Updates displayOrder of search item if needed to ensure that visible item have displayOrder set and + * not visible item have displayOrder null. + * + * @param item for update of displayOrder if needed + */ + private void updateDisplayOrderIfNeeded(FilterableSearchItemWrapper item) { + // add displayOrder for default search items which are visible, so they are properly sorted before items added by More button + // this case occurs when only default search items are in search box + if (item.isVisible() && item.getDisplayOrder() == null) { + item.setDisplayOrder(++currentBiggestDisplayOrder); + } + // it is needed to remove displayOrder for not visible search items, so they are properly sorted in More button alphabetically + // this case occurs when you switch between Saved filters + if (!item.isVisible() && item.getDisplayOrder() != null) { + item.setDisplayOrder(null); + } + } + private void addPopoverStatusMessage(AjaxRequestTarget target, String markupId, String message, int refreshInMillis) { target.appendJavaScript(String.format("MidPointTheme.updateStatusMessage('%s', '%s', %d);", markupId, message, refreshInMillis));