This is an automated email from the ASF dual-hosted git repository.
rusackas pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/superset.git
The following commit(s) were added to refs/heads/master by this push:
new a8e2a340f19 fix(select): exclude null-valued options from "Select all"
count (#42220)
a8e2a340f19 is described below
commit a8e2a340f19243249d6d730f7d2a8d5cf1b8b223
Author: Gaurav Dubey <[email protected]>
AuthorDate: Tue Jul 28 08:54:44 2026 +0530
fix(select): exclude null-valued options from "Select all" count (#42220)
Co-authored-by: Evan Rusackas <[email protected]>
---
.../src/components/Select/Select.test.tsx | 29 ++++++++++++++++++++++
.../src/components/Select/Select.tsx | 5 ++++
2 files changed, 34 insertions(+)
diff --git
a/superset-frontend/packages/superset-ui-core/src/components/Select/Select.test.tsx
b/superset-frontend/packages/superset-ui-core/src/components/Select/Select.test.tsx
index dbae8d4efe4..d0e70e1df34 100644
---
a/superset-frontend/packages/superset-ui-core/src/components/Select/Select.test.tsx
+++
b/superset-frontend/packages/superset-ui-core/src/components/Select/Select.test.tsx
@@ -1032,6 +1032,35 @@ test('do not count unselected disabled options in
"Select all"', async () => {
).toBeInTheDocument();
});
+test('"Select all" does not count null-valued options', async () => {
+ // A falsy-valued option (e.g. <NULL>, value: null) is skipped by
+ // handleSelectAll, so it must not be counted in the "Select all" badge or
+ // the count overstates the selection. Regression test for #40228. Uses a
+ // local options array to stay isolated from tests that mutate OPTIONS.
+ const localOptions = [
+ { label: 'Alpha', value: 1 },
+ { label: 'Bravo', value: 2 },
+ ];
+ render(
+ <Select
+ {...defaultProps}
+ options={[...localOptions, NULL_OPTION]}
+ mode="multiple"
+ maxTagCount={0}
+ />,
+ );
+ await open();
+ // Three options are visible, but the <NULL> option is not bulk-selectable,
+ // so the badge must count only the two real options (would be 3 before fix).
+ await userEvent.click(
+ await screen.findByText(selectAllButtonText(localOptions.length)),
+ );
+ // And Select all selects exactly those two — the null option is skipped.
+ const values = await findAllSelectValues();
+ expect(values.length).toBe(1);
+ expect(values[0]).toHaveTextContent(`+ ${localOptions.length} ...`);
+});
+
test('"Deselect all" counts all selected options', async () => {
render(<Select {...defaultProps} allowNewOptions mode="multiple" />);
await open();
diff --git
a/superset-frontend/packages/superset-ui-core/src/components/Select/Select.tsx
b/superset-frontend/packages/superset-ui-core/src/components/Select/Select.tsx
index 181cc597d40..32ee99442c8 100644
---
a/superset-frontend/packages/superset-ui-core/src/components/Select/Select.tsx
+++
b/superset-frontend/packages/superset-ui-core/src/components/Select/Select.tsx
@@ -332,7 +332,12 @@ const Select = forwardRef(
const isDisabled = option.disabled;
const isNew = option.isNewOption;
+ // Mirror handleSelectAll, which skips falsy-valued options (e.g. the
+ // <NULL> option whose value is null): they are not bulk-selectable,
+ // so counting them here makes the "Select all" badge overstate what
+ // gets selected.
if (
+ option.value &&
(!isDisabled || isSelected) &&
((isNew && isSelected) || !isNew)
) {