Skip to content

Share the All exclusivity rule between MultiValueVariable and the picker - #1601

Draft
samjewell wants to merge 1 commit into
sj/query-var-all-exclusivityfrom
cursor/sj/all-value-exclusivity-shared-helper-a3e1
Draft

Share the All exclusivity rule between MultiValueVariable and the picker#1601
samjewell wants to merge 1 commit into
sj/query-var-all-exclusivityfrom
cursor/sj/all-value-exclusivity-shared-helper-a3e1

Conversation

@samjewell

Copy link
Copy Markdown
Contributor

Stacked on #1596 — this targets sj/query-var-all-exclusivity, so the diff here is only the refactor. Opened for comparison; fold it into #1596 or drop it.

What

#1596 implements the All exclusivity rule twice:

  • changeValueTo decides by array position — if the last value is the All value it wins, otherwise the All value is dropped from a mixed selection.
  • enforceAllExclusivity in VariableValueSelect decides by react-select action — if the user selected the All option it wins, otherwise the All value is filtered out of a selection with more than one entry.

This extracts a single applyAllValueExclusivity helper and calls it from both.

Why

The duplication is the same shape as the bug #1596 fixes: the picker and the commit path each carrying their own copy of the rule is exactly how they drifted apart. Two copies also means two behaviours — they agree for every picker-driven path, but only the model's copy applies to programmatic updates, URL values and anything else that reaches changeValueTo directly.

The position rule subsumes the action rule because react-select appends a newly selected option to the end of the value array, so "the user just selected All" and "the All value is last" are the same statement for the picker. That is why every existing test, including the three interaction tests and the toggle-all header test added in #1596, passes unchanged.

Side effect worth noting: the helper copies rather than splices in place, so changeValueTo no longer mutates the value and text arrays its caller handed it.

The helper is exported from the module but deliberately not added to the package index — it stays internal until something outside needs it.

Testing

  • Full suite (1753 passed), typecheck, lint and prettier pass. No existing test needed changing.
  • New unit tests for applyAllValueExclusivity: the All value added last, mid-array and first; selections without the All value; missing and non-array text; and that it does not mutate its inputs.
  • Verified in a real Grafana (12.4.0, scenes-app "Variables with object values" demo) that the picker behaviour is byte-for-byte the same as VariableValueSelect: Make All value selection exclusive in the multi picker #1596: ticking a value with All selected deselects All and commits the concrete value; ticking All then another value commits only that value, with no $__all reaching state.
Open in Web Open in Cursor 

The rule was implemented twice: changeValueTo decided by array position
(the last value wins) while the picker's enforceAllExclusivity decided by
the react-select action. That is the same duplication that let the dropdown
and the commit path drift apart in the first place, and the two copies would
disagree for any selection not driven by the picker.

react-select appends a newly selected option to the end of the value array,
so the position rule already covers every case the action rule handled.
Extract it as applyAllValueExclusivity and call it from both, which also
stops changeValueTo mutating the value and text arrays it is handed.

Co-authored-by: Sam Jewell <samjewell@users.noreply.github.com>
@cla-assistant

cla-assistant Bot commented Jul 31, 2026

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants