fix(native-filters): handle null values in value filter (#16460)

* fix(native-filters): handle null values in value filter

* lint
This commit is contained in:
Ville Brofeldt 2021-08-26 15:26:53 +03:00 committed by GitHub
parent 1badcaed45
commit 1c71eda70f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 31 additions and 9 deletions

View File

@ -47,7 +47,6 @@ type PickedSelectProps = Pick<
AntdSelectAllProps,
| 'allowClear'
| 'autoFocus'
| 'value'
| 'disabled'
| 'filterOption'
| 'notFoundContent'

View File

@ -20,6 +20,7 @@
import {
AppSection,
DataMask,
DataRecordValue,
ensureIsArray,
ExtraFormData,
GenericDataType,
@ -36,7 +37,11 @@ import { useImmerReducer } from 'use-immer';
import { FormItemProps } from 'antd/lib/form';
import { PluginFilterSelectProps, SelectValue } from './types';
import { StyledFormItem, FilterPluginStyle, StatusMessage } from '../common';
import { getDataRecordFormatter, getSelectExtraFormData } from '../../utils';
import {
formatFilterValue,
getDataRecordFormatter,
getSelectExtraFormData,
} from '../../utils';
type DataMaskAction =
| { type: 'ownState'; ownState: JsonObject }
@ -119,7 +124,7 @@ export default function PluginFilterSelect(props: PluginFilterSelectProps) {
filterState: {
...filterState,
label: values?.length
? `${(values || []).join(', ')}${suffix}`
? `${(values || []).map(formatFilterValue).join(', ')}${suffix}`
: undefined,
value:
appSection === AppSection.FILTER_CONFIG_MODAL && defaultToFirstItem
@ -249,12 +254,12 @@ export default function PluginFilterSelect(props: PluginFilterSelectProps) {
}
const options = useMemo(() => {
const options: { label: string; value: string | number }[] = [];
const options: { label: string; value: DataRecordValue }[] = [];
data.forEach(row => {
const [value] = groupby.map(col => row[col]);
options.push({
label: labelFormatter(value, datatype),
value: typeof value === 'number' ? value : String(value),
value,
});
});
return options;
@ -286,6 +291,7 @@ export default function PluginFilterSelect(props: PluginFilterSelectProps) {
loading={isRefreshing}
maxTagCount={5}
invertSelection={inverseSelection}
// @ts-ignore
options={options}
/>
</StyledFormItem>

View File

@ -28,7 +28,7 @@ import { FALSE_STRING, NULL_STRING, TRUE_STRING } from 'src/utils/common';
export const getSelectExtraFormData = (
col: string,
value?: null | (string | number)[],
value?: null | (string | number | boolean | null)[],
emptyFilter = false,
inverseSelection = false,
): ExtraFormData => {
@ -46,6 +46,7 @@ export const getSelectExtraFormData = (
{
col,
op: inverseSelection ? ('NOT IN' as const) : ('IN' as const),
// @ts-ignore
val: value,
},
];
@ -116,3 +117,18 @@ export function getDataRecordFormatter({
return String(value);
};
}
export function formatFilterValue(
value: string | number | boolean | null,
): string {
if (value === null) {
return NULL_STRING;
}
if (typeof value === 'string') {
return value;
}
if (typeof value === 'number') {
return String(value);
}
return value ? TRUE_STRING : FALSE_STRING;
}

View File

@ -457,7 +457,7 @@ def cast_to_num(value: Optional[Union[float, int, str]]) -> Optional[Union[float
return None
def cast_to_boolean(value: Any) -> bool:
def cast_to_boolean(value: Any) -> Optional[bool]:
"""Casts a value to an int/float
>>> cast_to_boolean(1)
@ -473,12 +473,13 @@ def cast_to_boolean(value: Any) -> bool:
>>> cast_to_boolean('False')
False
>>> cast_to_boolean(None)
False
:param value: value to be converted to boolean representation
:returns: value cast to `bool`. when value is 'true' or value that are not 0
converte into True
converted into True. Return `None` if value is `None`
"""
if value is None:
return None
if isinstance(value, (int, float)):
return value != 0
if isinstance(value, str):