Repository navigation
fix(shared): multi-select "contains any" filter matcher should use OR semantics - #23010
Conversation
The in-memory isMatchingMultiSelectFilter evaluated the containsAny operand with Array.every, which required a record to hold *all* of the selected options. The operand means "contains any", and the server runs it as a Postgres array-overlap (field::text[] && ARRAY[...]), i.e. a record matches when it shares at least one option. Because of every(), the client-side matcher disagreed with the server: records that overlap on some (but not all) options were treated as non-matching. This surfaces in optimistic cache updates (isRecordMatchingFilter) where a created/edited record that should join a "contains any" view was dropped until a refetch, and it also feeds the row-level-permission predicate matcher on the server. Switch to Array.some so the matcher mirrors the overlap semantics, and update the tests (the previous cases asserted the all-options behavior).
|
👋 Thanks for contributing to Twenty! We're excited to have you on board. Your PR has been set to draft while you work on it. Once you're done, mark it as Ready for review and our automated checks will run. By submitting your Pull Request, you acknowledge that you agree with the terms of our Contributor License Agreement. |
🔍 Visual Regression Review —
|
🔍 Visual Regression Review —
|
| Story | Verdict | Confidence | Explained by | |
|---|---|---|---|---|
| 🟡 | modules-settings-playground-graphqlplayground--default |
uncertain | 80% | No connection — PR only modifies packages/twenty-shared/src/utils/filter/utils/i… |
Changed stories
| Story | Diff % |
|---|---|
| modules-settings-playground-graphqlplayground--default | 3% |
| modules-settings-playground-settingsmcpsetup--default | 0% |
View run details · advisory mode
There was a problem hiding this comment.
Hi @winklemad thank you for your contribution. It works well. Please fix CI before I can approve your PR.
🔍 Automated Pre-Review✅ No issues detected - This PR is ready for human review. 🧭 External PR Quality Review🟠 Needs triage for the following reason(s):
Checks
Detailed findings (duplicate candidates, standards notes, summary) are in the workflow run logs. Automated pre-review — human approval still required. |
The in-memory
isMatchingMultiSelectFilterevaluated thecontainsAnyoperand withArray.every, which requires a record to hold all selected options. ButcontainsAnymeans "any overlap": the server evaluates it as a Postgres array-overlap (field::text[] && ARRAY[...]), and the "Contains" UI operand for a MULTI_SELECT field builds exactly this operand — both match on at least one shared option.So the matcher disagreed with the server. In a "Tags contains any of [A, B]" view, an optimistic create/update of a record whose tags are just
[A]was treated as not matching, so it failed to appear (or was wrongly dropped) until a refetch;DOES_NOT_CONTAIN(built asnot { containsAny }) inverted the same way. The same helper backs the row-level-permission predicate matcher.Switched to
Array.someto match the OR semantics, and updated the tests (partial-overlap, single-overlap, no-overlap, empty-array). The siblingisMatching*Filterhelpers were checked — this is the only affected one.