feat: [DHIS2-19940] Implement "No value" filtering for all filter types in working list#4468
feat: [DHIS2-19940] Implement "No value" filtering for all filter types in working list#4468henrikmv wants to merge 248 commits intoDHIS2-21135from
Conversation
…st filter Co-Authored-By: henrik.vadet@dhis2.org <henrik@devOtta.no>
Call getSearchOperator() in _setBaseProperties() so that program attributes used by working lists carry the correct searchOperator. This fixes both issues: - preferredSearchOperator was always undefined in working lists - unique TEAs were not using EQ operator (getSearchOperator handles this) Co-Authored-By: henrik.vadet@dhis2.org <henrik@devOtta.no>
Co-Authored-By: henrik.vadet@dhis2.org <henrik@devOtta.no>
…_EmptyValueFiltersForAllValueTypes
| if (!allowMultiple) { | ||
| return getSingleSelectBooleanFilterData(value); | ||
| } | ||
|
|
||
| return getMultiSelectBooleanFilterData(value); |
There was a problem hiding this comment.
Is allowMultiple and getMultiSelectBooleanFilterData logic safe to remove? I tried to trace their original logic, but did not find a metadata setup that triggers them
There was a problem hiding this comment.
The removal of getSingleSelectBooleanFilterData and getMultiSelectBooleanFilterData as separate exports is safe because the new unified getBooleanFilterData handles both cases.
It normalises the value into an array with const values = Array.isArray(value) ? value : [value], which is equivalent to what the old getSingleSelectBooleanFilterData did (wrapping in [value]).
| } else if (key === 'orgUnitId') { | ||
| queryArgsForCurrentMain = getOrgUnitFilterQueryArgs(filter); |
There was a problem hiding this comment.
Did we have an orgUnit main filter in the Events WLs prior to PR #4461, or has this code always been unreachable? Thanks!
There was a problem hiding this comment.
Thank you for raising the question! The Org unit main filter is a confusing one for both Tracker and Event programs. I will try to summarise my findings below:
The OrgUnit main filter became visible after [#4461]. Before that PR, only ordering on orgUnit was supported. However, even though the filter was visible, it did not work — the orgUnit filter value was not persisted when saving a working list view.
We had already disabled the OrgUnit main filter for Tracker programs because filtering (and ordering) on programOwnerId is not supported by the API. It was not immediately obvious that it also needed to be disabled for Event programs, since Event programs use orgUnit as the apiName rather than programOwnerId.
After investigating, I found that the orgUnit parameter in the Event program request is set by the context selector. The main filter value is not persisted because, unlike status, occurredAt, and assignee, the backend does not store orgUnit as part of the event query criteria. Routing the orgUnit filter through dataFilters instead does persist correctly, but this inconsistency with how the other main filters are handled is not a clean solution. Enabling the filter properly would require backend support for persisting orgUnit in the criteria.
Given this, in my opinion, there are good reasons for hiding the filter:
- It aligns Event program behaviour with Tracker program behaviour, where the filter is already hidden.
- Users can still filter events by org unit through the context selector.
- Persisting the orgUnit main filter requires backend support for storing orgUnit in the event query criteria.
Alternatively, we should ask the backend team to support us, but let's create another ticket for that. For now, I will keep the OrgUnit main filter cleanup in this PR.
Thank you!
Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>
|



DHIS2-19940
Pattern for Adding
isEmptyFiltering1. Types
EmptyValueFilterDatastringto theValuetype (used to carry the isEmpty value)2. Component
WithEmptyValueFilterundefinedto children whenisEmptyis active3. Data Getter
isEmptyValueFilter(value)before normal conversiongetEmptyValueFilterData(value)4. Manager
isEmptyFilterData(filter)getEmptyValueFilterValue(filter)5. Disable Flag
disableEmptyValueFiltertotruefor:transformRecordsFiltercolumns