Skip to content

feat: [DHIS2-19940] Implement "No value" filtering for all filter types in working list#4468

Open
henrikmv wants to merge 248 commits intoDHIS2-21135from
hv/feat/DHIS2-19940_EmptyValueFiltersForAllValueTypes
Open

feat: [DHIS2-19940] Implement "No value" filtering for all filter types in working list#4468
henrikmv wants to merge 248 commits intoDHIS2-21135from
hv/feat/DHIS2-19940_EmptyValueFiltersForAllValueTypes

Conversation

@henrikmv
Copy link
Copy Markdown
Contributor

@henrikmv henrikmv commented Feb 27, 2026

DHIS2-19940

Pattern for Adding isEmpty Filtering

1. Types

  • Union the filter data type with EmptyValueFilterData
  • Add string to the Value type (used to carry the isEmpty value)

2. Component

  • Wrap the filter UI with WithEmptyValueFilter
  • This renders the checkboxes and passes undefined to children when isEmpty is active

3. Data Getter

  • Check isEmptyValueFilter(value) before normal conversion
  • If true, return getEmptyValueFilterData(value)

4. Manager

  • When restoring from a saved filter, check isEmptyFilterData(filter)
  • If true, return getEmptyValueFilterValue(filter)

5. Disable Flag

  • Set disableEmptyValueFilter to true for:
    • Main properties
    • transformRecordsFilter columns

devin-ai-integration bot and others added 30 commits February 10, 2026 10:43
…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>
@henrikmv henrikmv added testing and removed testing labels Apr 12, 2026
@henrikmv henrikmv added testing and removed testing labels Apr 12, 2026
@henrikmv henrikmv added testing and removed testing labels Apr 12, 2026
@henrikmv henrikmv added testing and removed testing labels Apr 12, 2026
@henrikmv henrikmv added testing and removed testing labels Apr 12, 2026
@henrikmv henrikmv marked this pull request as ready for review April 12, 2026 18:35
Comment thread src/core_modules/capture-core/components/FiltersForTypes/types/index.ts Outdated
Comment on lines -37 to -41
if (!allowMultiple) {
return getSingleSelectBooleanFilterData(value);
}

return getMultiSelectBooleanFilterData(value);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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

Copy link
Copy Markdown
Contributor Author

@henrikmv henrikmv Apr 16, 2026

Choose a reason for hiding this comment

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

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]).

Comment on lines -99 to -100
} else if (key === 'orgUnitId') {
queryArgsForCurrentMain = getOrgUnitFilterQueryArgs(filter);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Did we have an orgUnit main filter in the Events WLs prior to PR #4461, or has this code always been unreachable? Thanks!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

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!

Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

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

Devin Review found 2 potential issues.

View 4 additional findings in Devin Review.

Open in Devin Review

Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

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

Devin Review found 2 new potential issues.

View 8 additional findings in Devin Review.

Open in Devin Review

Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@sonarqubecloud
Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants