Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ private GridFilterModal initFilterColumn(CharSequence columnIdentifier, Filter.O
{
filterPanel.selectArrayFilterOperator(operator);
}
if (value != null)
if (value != null && !((List<String>) value).isEmpty())
{
List<String> values = (List<String>) value;
filterPanel.selectValue(values.get(0));
Expand Down
43 changes: 43 additions & 0 deletions src/org/labkey/test/util/data/TestArrayDataUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package org.labkey.test.util.data;

import org.labkey.remoteapi.query.Filter;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class TestArrayDataUtils
{
Comment on lines +10 to +11
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider moving TestDataUtils.parseMultiValueText and ResponsiveGrid.ARRAY_OPERATORS into this class.

/**
* Filtering Map according to filter and then sorting values in alphabetical order.
*
* @return filtered Map
*/
public static Map<String, String> filterMap(Map<String, List<String>> sourceMap, List<String> searchValues, Filter.Operator filterType)
{
return sourceMap.entrySet().stream()
.filter(entry -> isMatch(entry.getValue(), searchValues, filterType))
.collect(Collectors.toMap(
Map.Entry::getKey,
e -> e.getValue().stream().sorted().collect(Collectors.joining(", ")),
(e1, e2) -> e1,
LinkedHashMap::new
));
}
Comment on lines +17 to +27
Copy link
Member

@labkey-tchad labkey-tchad Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid losing information. filterMap should return the filtered map in the same format that it was passed in, Map<String, List<String>>.

Maybe create a separate method to sort and join the values in a standard format. Something like:

public static String formatValues(List<String> values)
{
    return TextUtils.normalizeSpace(values.stream().sorted().collect(Collectors.joining(", "));
}


private static boolean isMatch(List<String> actualValues, List<String> searchValues, Filter.Operator type)
{
return switch (type)
{
case ARRAY_CONTAINS_ALL -> actualValues.containsAll(searchValues);
case ARRAY_CONTAINS_ANY -> searchValues.stream().anyMatch(actualValues::contains);
case ARRAY_CONTAINS_EXACT -> actualValues.size() == searchValues.size() && actualValues.containsAll(searchValues);
case ARRAY_CONTAINS_NONE -> searchValues.stream().noneMatch(actualValues::contains);
case ARRAY_CONTAINS_NOT_EXACT -> !(actualValues.size() == searchValues.size() && actualValues.containsAll(searchValues));
case ARRAY_ISEMPTY -> actualValues.isEmpty();
case ARRAY_ISNOTEMPTY -> !actualValues.isEmpty();
default -> true;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this default to true for non-array operators? What does the server do?
Unless this matches the actual product behavior, we should just throw an IllegalArgumentException for non-array operators.

};
}
}