From 1937ae52f243771712451460cd6108638be67723 Mon Sep 17 00:00:00 2001 From: Diego Medina Date: Thu, 17 Mar 2022 13:05:32 -0400 Subject: [PATCH] fix: allow to select in a native filter single mode (#19076) * fix: allow to select in a native filter single mode * fix lint issue * Update superset-frontend/src/components/Select/utils.ts Co-authored-by: Michael S. Molina <70410625+michael-s-molina@users.noreply.github.com> * fix Co-authored-by: Michael S. Molina <70410625+michael-s-molina@users.noreply.github.com> (cherry picked from commit 19fcd03c8962b5ae2d2bb5cd196b1ef07a27b9c3) --- .../src/components/Select/utils.ts | 6 +++-- .../Select/SelectFilterPlugin.test.tsx | 27 ++++++++++++++++++- .../components/Select/SelectFilterPlugin.tsx | 3 ++- .../src/filters/components/Select/types.ts | 2 +- 4 files changed, 33 insertions(+), 5 deletions(-) diff --git a/superset-frontend/src/components/Select/utils.ts b/superset-frontend/src/components/Select/utils.ts index f62b93ade3668..f3880f52f7d01 100644 --- a/superset-frontend/src/components/Select/utils.ts +++ b/superset-frontend/src/components/Select/utils.ts @@ -60,8 +60,10 @@ export function findValue( return (Array.isArray(value) ? value : [value]).map(find); } -export function getValue(option: string | number | { value: string | number }) { - return typeof option === 'object' ? option.value : option; +export function getValue( + option: string | number | { value: string | number | null } | null, +) { + return option && typeof option === 'object' ? option.value : option; } type LabeledValue = { label?: ReactNode; value?: V }; diff --git a/superset-frontend/src/filters/components/Select/SelectFilterPlugin.test.tsx b/superset-frontend/src/filters/components/Select/SelectFilterPlugin.test.tsx index 549217619b78a..8c025c97119bd 100644 --- a/superset-frontend/src/filters/components/Select/SelectFilterPlugin.test.tsx +++ b/superset-frontend/src/filters/components/Select/SelectFilterPlugin.test.tsx @@ -20,6 +20,7 @@ import userEvent from '@testing-library/user-event'; import { AppSection } from '@superset-ui/core'; import React from 'react'; import { render, screen } from 'spec/helpers/testing-library'; +import { NULL_STRING } from 'src/utils/common'; import SelectFilterPlugin from './SelectFilterPlugin'; import transformProps from './transformProps'; @@ -55,7 +56,7 @@ const selectMultipleProps = { rowcount: 2, colnames: ['gender'], coltypes: [1], - data: [{ gender: 'boy' }, { gender: 'girl' }], + data: [{ gender: 'boy' }, { gender: 'girl' }, { gender: null }], applied_filters: [{ column: 'gender' }], rejected_filters: [], }, @@ -195,6 +196,30 @@ describe('SelectFilterPlugin', () => { }); }); + it('Select single null (empty) value', () => { + getWrapper(); + userEvent.click(screen.getByRole('combobox')); + userEvent.click(screen.getByTitle(NULL_STRING)); + expect(setDataMask).toHaveBeenLastCalledWith({ + __cache: { + value: ['boy'], + }, + extraFormData: { + filters: [ + { + col: 'gender', + op: 'IN', + val: ['boy', null], + }, + ], + }, + filterState: { + label: `boy, ${NULL_STRING}`, + value: ['boy', null], + }, + }); + }); + it('Add ownState with column types when search all options', () => { getWrapper({ searchAllOptions: true, multiSelect: false }); userEvent.click(screen.getByRole('combobox')); diff --git a/superset-frontend/src/filters/components/Select/SelectFilterPlugin.tsx b/superset-frontend/src/filters/components/Select/SelectFilterPlugin.tsx index 16c748a174b32..8388e13a3d594 100644 --- a/superset-frontend/src/filters/components/Select/SelectFilterPlugin.tsx +++ b/superset-frontend/src/filters/components/Select/SelectFilterPlugin.tsx @@ -209,7 +209,8 @@ export default function PluginFilterSelect(props: PluginFilterSelectProps) { const handleChange = useCallback( (value?: SelectValue | number | string) => { - const values = ensureIsArray(value); + const values = value === null ? [null] : ensureIsArray(value); + if (values.length === 0) { updateDataMask(null); } else { diff --git a/superset-frontend/src/filters/components/Select/types.ts b/superset-frontend/src/filters/components/Select/types.ts index 2d4f0c958669f..0497b58e55581 100644 --- a/superset-frontend/src/filters/components/Select/types.ts +++ b/superset-frontend/src/filters/components/Select/types.ts @@ -29,7 +29,7 @@ import { import { RefObject } from 'react'; import { PluginFilterHooks, PluginFilterStylesProps } from '../types'; -export type SelectValue = (number | string)[] | null | undefined; +export type SelectValue = (number | string | null)[] | null | undefined; export interface PluginFilterSelectCustomizeProps { defaultValue?: SelectValue;