feat: move filters from superset-ui to incubator (#12154)

* feat: move filters from superset-ui to incubator

* refactor: add safety check

* refactor: move extraForm data utils

* refactor: move extraForm data utils

* lint: fix lint

* chore: add license

* chore: undo changes to file

* refactor: fix CR notes / add tests

* test: update tests

* fix: fix range logic

Co-authored-by: Amit Miran <47772523+amitmiran137@users.noreply.github.com>
This commit is contained in:
simchaNielsen 2021-01-08 14:44:25 +02:00 committed by GitHub
parent d760e885d7
commit fecfc34cd3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 937 additions and 5 deletions

View File

@ -0,0 +1,156 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import {
getRangeExtraFormData,
getSelectExtraFormData,
} from '../../../src/filters/utils';
describe('Filter utils', () => {
describe('getRangeExtraFormData', () => {
it('getRangeExtraFormData - col: "testCol", lower: 1, upper: 2', () => {
expect(getRangeExtraFormData('testCol', 1, 2)).toEqual({
append_form_data: {
filters: [
{
col: 'testCol',
op: '>=',
val: 1,
},
{
col: 'testCol',
op: '<=',
val: 2,
},
],
},
});
});
it('getRangeExtraFormData - col: "testCol", lower: 0, upper: 0', () => {
expect(getRangeExtraFormData('testCol', 0, 0)).toEqual({
append_form_data: {
filters: [
{
col: 'testCol',
op: '>=',
val: 0,
},
{
col: 'testCol',
op: '<=',
val: 0,
},
],
},
});
});
it('getRangeExtraFormData - col: "testCol", lower: null, upper: 2', () => {
expect(getRangeExtraFormData('testCol', null, 2)).toEqual({
append_form_data: {
filters: [
{
col: 'testCol',
op: '<=',
val: 2,
},
],
},
});
});
it('getRangeExtraFormData - col: "testCol", lower: 1, upper: undefined', () => {
expect(getRangeExtraFormData('testCol', 1, undefined)).toEqual({
append_form_data: {
filters: [
{
col: 'testCol',
op: '>=',
val: 1,
},
],
},
});
});
});
describe('getSelectExtraFormData', () => {
it('getSelectExtraFormData - col: "testCol", value: ["value"], emptyFilter: false, inverseSelection: false', () => {
expect(
getSelectExtraFormData('testCol', ['value'], false, false),
).toEqual({
append_form_data: {
filters: [
{
col: 'testCol',
op: 'IN',
val: ['value'],
},
],
},
});
});
it('getSelectExtraFormData - col: "testCol", value: ["value"], emptyFilter: true, inverseSelection: false', () => {
expect(getSelectExtraFormData('testCol', ['value'], true, false)).toEqual(
{
append_form_data: {
extras: {
where: '1 = 0',
},
},
},
);
});
it('getSelectExtraFormData - col: "testCol", value: ["value"], emptyFilter: false, inverseSelection: true', () => {
expect(getSelectExtraFormData('testCol', ['value'], false, true)).toEqual(
{
append_form_data: {
filters: [
{
col: 'testCol',
op: 'NOT IN',
val: ['value'],
},
],
},
},
);
});
it('getSelectExtraFormData - col: "testCol", value: [], emptyFilter: false, inverseSelection: false', () => {
expect(getSelectExtraFormData('testCol', [], false, false)).toEqual({
append_form_data: {
filters: [],
},
});
});
it('getSelectExtraFormData - col: "testCol", value: undefined, emptyFilter: false, inverseSelection: false', () => {
expect(
getSelectExtraFormData('testCol', undefined, false, false),
).toEqual({
append_form_data: {
filters: [],
},
});
});
it('getSelectExtraFormData - col: "testCol", value: null, emptyFilter: false, inverseSelection: false', () => {
expect(getSelectExtraFormData('testCol', null, false, false)).toEqual({
append_form_data: {
filters: [],
},
});
});
});
});

View File

@ -44,6 +44,7 @@ export {
Typography,
Tree,
Popover,
Slider,
Radio,
Row,
Select,

View File

@ -222,7 +222,7 @@ const FilterValue: React.FC<FilterProps> = ({
} = filter;
const cascadingFilters = useCascadingFilters(id);
const [loading, setLoading] = useState<boolean>(true);
const [state, setState] = useState({ data: undefined });
const [state, setState] = useState([]);
const [formData, setFormData] = useState<Partial<QueryFormData>>({});
const [target] = targets;
const { datasetId = 18, column } = target;
@ -256,7 +256,7 @@ const FilterValue: React.FC<FilterProps> = ({
force: false,
requestParams: { dashboardId: 0 },
}).then(response => {
setState({ data: response.result[0].data });
setState(response.result);
setLoading(false);
});
}

View File

@ -0,0 +1,56 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { styled } from '@superset-ui/core';
import React from 'react';
import { Slider } from 'src/common/components';
import { AntdPluginFilterRangeProps } from './types';
import { AntdPluginFilterStylesProps } from '../types';
import { getRangeExtraFormData } from '../../utils';
const Styles = styled.div<AntdPluginFilterStylesProps>`
height: ${({ height }) => height};
width: ${({ width }) => width};
`;
export default function AntdRangeFilter(props: AntdPluginFilterRangeProps) {
const { data, formData, height, width, setExtraFormData } = props;
const [row] = data;
// @ts-ignore
const { min, max }: { min: number; max: number } = row;
const { groupby } = formData;
const [col] = groupby || [];
const handleChange = (value: [number, number]) => {
const [lower, upper] = value;
setExtraFormData(getRangeExtraFormData(col, lower, upper));
};
return (
<Styles height={height} width={width}>
<Slider
range
min={min}
max={max}
defaultValue={[min, max]}
onChange={handleChange}
/>
</Styles>
);
}

View File

@ -0,0 +1,74 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import {
buildQueryContext,
ColumnType,
QueryFormData,
} from '@superset-ui/core';
/**
* The buildQuery function is used to create an instance of QueryContext that's
* sent to the chart data endpoint. In addition to containing information of which
* datasource to use, it specifies the type (e.g. full payload, samples, query) and
* format (e.g. CSV or JSON) of the result and whether or not to force refresh the data from
* the datasource as opposed to using a cached copy of the data, if available.
*
* More importantly though, QueryContext contains a property `queries`, which is an array of
* QueryObjects specifying individual data requests to be made. A QueryObject specifies which
* columns, metrics and filters, among others, to use during the query. Usually it will be enough
* to specify just one query based on the baseQueryObject, but for some more advanced use cases
* it is possible to define post processing operations in the QueryObject, or multiple queries
* if a viz needs multiple different result sets.
*/
export default function buildQuery(formData: QueryFormData) {
const { groupby } = formData;
const [column] = groupby || [];
return buildQueryContext(formData, baseQueryObject => {
return [
{
...baseQueryObject,
groupby: [],
metrics: [
{
aggregate: 'MIN',
column: {
columnName: column,
id: 1,
type: ColumnType.FLOAT,
},
expressionType: 'SIMPLE',
hasCustomLabel: true,
label: 'min',
},
{
aggregate: 'MAX',
column: {
columnName: column,
id: 2,
type: ColumnType.FLOAT,
},
expressionType: 'SIMPLE',
hasCustomLabel: true,
label: 'max',
},
],
},
];
});
}

View File

@ -0,0 +1,44 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { t, validateNonEmpty } from '@superset-ui/core';
import { ControlPanelConfig, sections } from '@superset-ui/chart-controls';
const config: ControlPanelConfig = {
// For control input types, see: superset-frontend/src/explore/components/controls/index.js
controlPanelSections: [
// @ts-ignore
sections.legacyRegularTime,
{
label: t('Query'),
expanded: true,
controlSetRows: [['groupby'], ['adhoc_filters']],
},
],
controlOverrides: {
groupby: {
validators: [validateNonEmpty],
clearable: false,
},
row_limit: {
default: 100,
},
},
};
export default config;

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

View File

@ -0,0 +1,42 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { t, ChartMetadata, ChartPlugin } from '@superset-ui/core';
import buildQuery from './buildQuery';
import controlPanel from './controlPanel';
import transformProps from './transformProps';
import thumbnail from './images/thumbnail.png';
export default class AntdRangeFilterPlugin extends ChartPlugin {
constructor() {
const metadata = new ChartMetadata({
name: t('Range Filter Plugin'),
description: 'Range Filter Plugin using AntD',
isNativeFilter: true,
thumbnail,
});
super({
buildQuery,
controlPanel,
loadChart: () => import('./AntdRangeFilter'),
metadata,
transformProps,
});
}
}

View File

@ -0,0 +1,33 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { ChartProps } from '@superset-ui/core';
export default function transformProps(chartProps: ChartProps) {
const { formData, height, hooks, queriesData, width } = chartProps;
const { setExtraFormData } = hooks;
const { data } = queriesData[0];
return {
data,
formData,
height,
setExtraFormData,
width,
};
}

View File

@ -0,0 +1,39 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import {
DataRecord,
QueryFormData,
SetExtraFormDataHook,
} from '@superset-ui/core';
import { AntdPluginFilterStylesProps } from '../types';
interface AntdPluginFilterSelectCustomizeProps {
max?: number;
min?: number;
}
export type PluginFilterRangeQueryFormData = QueryFormData &
AntdPluginFilterStylesProps &
AntdPluginFilterSelectCustomizeProps;
export type AntdPluginFilterRangeProps = AntdPluginFilterStylesProps & {
data: DataRecord[];
formData: PluginFilterRangeQueryFormData;
setExtraFormData: SetExtraFormDataHook;
};

View File

@ -0,0 +1,94 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { styled } from '@superset-ui/core';
import React, { useEffect, useState } from 'react';
import { Select } from 'src/common/components';
import { DEFAULT_FORM_DATA, AntdPluginFilterSelectProps } from './types';
import { AntdPluginFilterStylesProps } from '../types';
import { getSelectExtraFormData } from '../../utils';
const Styles = styled.div<AntdPluginFilterStylesProps>`
height: ${({ height }) => height};
width: ${({ width }) => width};
`;
const { Option } = Select;
export default function AntdPluginFilterSelect(
props: AntdPluginFilterSelectProps,
) {
const [values, setValues] = useState<(string | number)[]>([]);
const { data, formData, height, width, setExtraFormData } = props;
const {
defaultValues,
enableEmptyFilter,
multiSelect,
showSearch,
inverseSelection,
} = {
...DEFAULT_FORM_DATA,
...formData,
};
useEffect(() => {
setValues(defaultValues || []);
}, [defaultValues]);
let { groupby = [] } = formData;
groupby = Array.isArray(groupby) ? groupby : [groupby];
function handleChange(value?: number[] | string[] | null) {
setValues(value || []);
const [col] = groupby;
const emptyFilter =
enableEmptyFilter &&
!inverseSelection &&
(value === undefined || value === null || value.length === 0);
setExtraFormData(
getSelectExtraFormData(col, value, emptyFilter, inverseSelection),
);
}
const placeholderText =
(data || []).length === 0
? 'No data'
: `${data.length} option${data.length > 1 ? 's' : 0}`;
return (
<Styles height={height} width={width}>
<Select
allowClear
value={values}
showSearch={showSearch}
style={{ width: '100%' }}
mode={multiSelect ? 'multiple' : undefined}
placeholder={placeholderText}
// @ts-ignore
onChange={handleChange}
>
{(data || []).map(row => {
const option = `${groupby.map(col => row[col])[0]}`;
return (
<Option key={option} value={option}>
{option}
</Option>
);
})}
</Select>
</Styles>
);
}

View File

@ -0,0 +1,43 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { buildQueryContext, QueryFormData } from '@superset-ui/core';
/**
* The buildQuery function is used to create an instance of QueryContext that's
* sent to the chart data endpoint. In addition to containing information of which
* datasource to use, it specifies the type (e.g. full payload, samples, query) and
* format (e.g. CSV or JSON) of the result and whether or not to force refresh the data from
* the datasource as opposed to using a cached copy of the data, if available.
*
* More importantly though, QueryContext contains a property `queries`, which is an array of
* QueryObjects specifying individual data requests to be made. A QueryObject specifies which
* columns, metrics and filters, among others, to use during the query. Usually it will be enough
* to specify just one query based on the baseQueryObject, but for some more advanced use cases
* it is possible to define post processing operations in the QueryObject, or multiple queries
* if a viz needs multiple different result sets.
*/
export default function buildQuery(formData: QueryFormData) {
return buildQueryContext(formData, baseQueryObject => {
return [
{
...baseQueryObject,
},
];
});
}

View File

@ -0,0 +1,114 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { t, validateNonEmpty } from '@superset-ui/core';
import { ControlPanelConfig, sections } from '@superset-ui/chart-controls';
import { DEFAULT_FORM_DATA } from './types';
const {
enableEmptyFilter,
fetchPredicate,
inverseSelection,
multiSelect,
showSearch,
} = DEFAULT_FORM_DATA;
const config: ControlPanelConfig = {
controlPanelSections: [
// @ts-ignore
sections.legacyRegularTime,
{
label: t('Query'),
expanded: true,
controlSetRows: [
['groupby'],
['metrics'],
['adhoc_filters'],
[
{
name: 'multiSelect',
config: {
type: 'CheckboxControl',
label: t('Multiple Select'),
default: multiSelect,
description: t('Allow selecting multiple values'),
},
},
],
[
{
name: 'enableEmptyFilter',
config: {
type: 'CheckboxControl',
label: t('Enable Empty Filter'),
default: enableEmptyFilter,
description: t(
'When selection is empty, should an always false filter event be emitted',
),
},
},
],
[
{
name: 'inverseSelection',
config: {
type: 'CheckboxControl',
label: t('Inverse Selection'),
default: inverseSelection,
description: t('Exclude selected values'),
},
},
],
[
{
name: 'showSearch',
config: {
type: 'CheckboxControl',
label: t('Search Field'),
default: showSearch,
description: t('Allow typing search terms'),
},
},
],
[
{
name: 'fetchPredicate',
config: {
type: 'TextControl',
label: t('Fetch predicate'),
default: fetchPredicate,
description: t(
'Predicate applied when fetching distinct value to populate the filter control component.',
),
},
},
null,
],
['row_limit', null],
],
},
],
controlOverrides: {
groupby: {
multi: false,
validators: [validateNonEmpty],
},
},
};
export default config;

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

View File

@ -0,0 +1,42 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { t, ChartMetadata, ChartPlugin } from '@superset-ui/core';
import buildQuery from './buildQuery';
import controlPanel from './controlPanel';
import transformProps from './transformProps';
import thumbnail from './images/thumbnail.png';
export default class AntdFilterSelectPlugin extends ChartPlugin {
constructor() {
const metadata = new ChartMetadata({
name: t('Select Filter Plugin'),
description: 'Select Filter Plugin using AntD',
isNativeFilter: true,
thumbnail,
});
super({
buildQuery,
controlPanel,
loadChart: () => import('./AntdSelectFilter'),
metadata,
transformProps,
});
}
}

View File

@ -0,0 +1,36 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { ChartProps } from '@superset-ui/core';
import { DEFAULT_FORM_DATA } from './types';
export default function transformProps(chartProps: ChartProps) {
const { formData, height, hooks, queriesData, width } = chartProps;
const newFormData = { ...DEFAULT_FORM_DATA, ...formData };
const { setExtraFormData = () => {} } = hooks;
const { data } = queriesData[0];
return {
width,
height,
data,
formData: newFormData,
setExtraFormData,
};
}

View File

@ -0,0 +1,52 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import {
QueryFormData,
DataRecord,
SetExtraFormDataHook,
} from '@superset-ui/core';
import { AntdPluginFilterStylesProps } from '../types';
interface AntdPluginFilterSelectCustomizeProps {
defaultValues?: (string | number)[];
enableEmptyFilter: boolean;
fetchPredicate?: string;
inverseSelection: boolean;
multiSelect: boolean;
showSearch: boolean;
}
export type AntdPluginFilterSelectQueryFormData = QueryFormData &
AntdPluginFilterStylesProps &
AntdPluginFilterSelectCustomizeProps;
export type AntdPluginFilterSelectProps = AntdPluginFilterStylesProps & {
data: DataRecord[];
setExtraFormData: SetExtraFormDataHook;
formData: AntdPluginFilterSelectQueryFormData;
};
export const DEFAULT_FORM_DATA: AntdPluginFilterSelectCustomizeProps = {
defaultValues: [],
enableEmptyFilter: false,
fetchPredicate: '',
inverseSelection: false,
multiSelect: true,
showSearch: true,
};

View File

@ -0,0 +1,20 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
export { default as AntdSelectFilterPlugin } from './Select';
export { default as AntdRangeFilterPlugin } from './Range';

View File

@ -0,0 +1,22 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
export interface AntdPluginFilterStylesProps {
height: number;
width: number;
}

View File

@ -0,0 +1,65 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { QueryObjectFilterClause } from '@superset-ui/core';
export const getSelectExtraFormData = (
col: string,
value?: undefined | null | string[] | number[],
emptyFilter = false,
inverseSelection = false,
) => ({
append_form_data: emptyFilter
? {
extras: {
where: '1 = 0',
},
}
: {
filters:
value === undefined || value === null || value.length === 0
? []
: [
{
col,
op: inverseSelection ? ('NOT IN' as const) : ('IN' as const),
val: value,
},
],
},
});
export const getRangeExtraFormData = (
col: string,
lower?: number | null,
upper?: number | null,
) => {
const filters: QueryObjectFilterClause[] = [];
if (lower !== undefined && lower !== null) {
filters.push({ col, op: '>=', val: lower });
}
if (upper !== undefined && upper !== null) {
filters.push({ col, op: '<=', val: upper });
}
return {
append_form_data: {
filters,
},
};
};

View File

@ -60,10 +60,9 @@ import {
EchartsTimeseriesChartPlugin,
} from '@superset-ui/plugin-chart-echarts';
import {
AntdRangeFilterPlugin,
AntdSelectFilterPlugin,
} from '@superset-ui/plugin-filter-antd';
AntdRangeFilterPlugin,
} from 'src/filters/components/';
import FilterBoxChartPlugin from '../FilterBox/FilterBoxChartPlugin';
import TimeTableChartPlugin from '../TimeTable/TimeTableChartPlugin';