From 0e0c99b2fb4cb275b65cc1293bafafe4f91ba33a Mon Sep 17 00:00:00 2001 From: simcha90 <56388545+simcha90@users.noreply.github.com> Date: Wed, 17 Mar 2021 14:00:32 +0200 Subject: [PATCH] feat(cross-filters): Add scoping for cross filters (#13625) * feat: cross filter modal * refactor: add charts metadata * refactor: add charts metadata * feat: cross filters scoping * fix: fix CR notes * test: fix test * lint: fix lint --- .../dashboard/components/Dashboard_spec.jsx | 6 +- .../util/getFormDataWithExtraFilters_spec.ts | 1 + .../src/dashboard/actions/dashboardInfo.ts | 81 ++++++++++++++++ .../src/dashboard/actions/nativeFilters.ts | 9 +- .../CrossFilterScopingForm.tsx | 54 +++++++++++ .../CrossFilterScopingModal.tsx | 97 +++++++++++++++++++ .../CrossFilterScopingModal/types.ts} | 9 +- .../CrossFilterScopingModal/utils.ts | 29 ++++++ .../src/dashboard/components/Dashboard.jsx | 5 +- .../components/SliceHeaderControls.jsx | 65 ++++++++++--- .../FiltersConfigForm/ControlItems.tsx | 4 +- .../FiltersConfigForm/DefaultValue.tsx | 4 +- .../FilterScope/FilterScope.tsx | 71 ++++++++------ .../FilterScope/ScopingTree.tsx | 24 ++--- .../FiltersConfigForm/FiltersConfigForm.tsx | 17 ++-- .../FiltersConfigForm/state.ts | 6 +- .../FiltersConfigForm/utils.ts | 2 +- .../components/nativeFilters/state.ts | 2 +- .../components/nativeFilters/utils.ts | 15 +-- .../src/dashboard/containers/Chart.jsx | 2 + .../src/dashboard/containers/Dashboard.jsx | 8 +- .../src/dashboard/reducers/getInitialState.js | 2 +- .../src/dashboard/reducers/types.ts | 19 +++- ...ilters.ts => activeAllDashboardFilters.ts} | 45 ++++----- .../charts/getFormDataWithExtraFilters.ts | 13 ++- superset/dashboards/schemas.py | 6 +- 26 files changed, 457 insertions(+), 139 deletions(-) create mode 100644 superset-frontend/src/dashboard/actions/dashboardInfo.ts create mode 100644 superset-frontend/src/dashboard/components/CrossFilterScopingModal/CrossFilterScopingForm.tsx create mode 100644 superset-frontend/src/dashboard/components/CrossFilterScopingModal/CrossFilterScopingModal.tsx rename superset-frontend/src/dashboard/{actions/dashboardInfo.js => components/CrossFilterScopingModal/types.ts} (79%) create mode 100644 superset-frontend/src/dashboard/components/CrossFilterScopingModal/utils.ts rename superset-frontend/src/dashboard/util/{activeDashboardNativeFilters.ts => activeAllDashboardFilters.ts} (77%) diff --git a/superset-frontend/spec/javascripts/dashboard/components/Dashboard_spec.jsx b/superset-frontend/spec/javascripts/dashboard/components/Dashboard_spec.jsx index 733f82490c43d..c9c13b1a02686 100644 --- a/superset-frontend/spec/javascripts/dashboard/components/Dashboard_spec.jsx +++ b/superset-frontend/spec/javascripts/dashboard/components/Dashboard_spec.jsx @@ -39,7 +39,7 @@ import dashboardInfo from 'spec/fixtures/mockDashboardInfo'; import { dashboardLayout } from 'spec/fixtures/mockDashboardLayout'; import dashboardState from 'spec/fixtures/mockDashboardState'; import { sliceEntitiesForChart as sliceEntities } from 'spec/fixtures/mockSliceEntities'; -import { getActiveNativeFilters } from 'src/dashboard/util/activeDashboardNativeFilters'; +import { getAllActiveFilters } from 'src/dashboard/util/activeAllDashboardFilters'; describe('Dashboard', () => { const props = { @@ -154,9 +154,9 @@ describe('Dashboard', () => { wrapper.setProps({ activeFilters: { ...OVERRIDE_FILTERS, - ...getActiveNativeFilters({ + ...getAllActiveFilters({ dataMask: dataMaskWith1Filter, - filters: singleNativeFiltersState.filters, + nativeFilters: singleNativeFiltersState.filters, layout: layoutForSingleNativeFilter, }), }, diff --git a/superset-frontend/spec/javascripts/dashboard/util/getFormDataWithExtraFilters_spec.ts b/superset-frontend/spec/javascripts/dashboard/util/getFormDataWithExtraFilters_spec.ts index 18242e32491a3..e30ef3f128f7f 100644 --- a/superset-frontend/spec/javascripts/dashboard/util/getFormDataWithExtraFilters_spec.ts +++ b/superset-frontend/spec/javascripts/dashboard/util/getFormDataWithExtraFilters_spec.ts @@ -41,6 +41,7 @@ describe('getFormDataWithExtraFilters', () => { }, }; const mockArgs: GetFormDataWithExtraFiltersArguments = { + chartConfiguration: {}, charts: { [chartId]: mockChart, }, diff --git a/superset-frontend/src/dashboard/actions/dashboardInfo.ts b/superset-frontend/src/dashboard/actions/dashboardInfo.ts new file mode 100644 index 0000000000000..3aa30936dcedd --- /dev/null +++ b/superset-frontend/src/dashboard/actions/dashboardInfo.ts @@ -0,0 +1,81 @@ +/** + * 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 { Dispatch } from 'redux'; +import { makeApi } from '@superset-ui/core'; +import { ChartConfiguration, DashboardInfo } from '../reducers/types'; + +export const DASHBOARD_INFO_UPDATED = 'DASHBOARD_INFO_UPDATED'; + +// updates partially changed dashboard info +export function dashboardInfoChanged(newInfo: { metadata: any }) { + return { type: DASHBOARD_INFO_UPDATED, newInfo }; +} +export const SET_CHART_CONFIG_BEGIN = 'SET_CHART_CONFIG_BEGIN'; +export interface SetChartConfigBegin { + type: typeof SET_CHART_CONFIG_BEGIN; + chartConfiguration: ChartConfiguration; +} +export const SET_CHART_CONFIG_COMPLETE = 'SET_CHART_CONFIG_COMPLETE'; +export interface SetChartConfigComplete { + type: typeof SET_CHART_CONFIG_COMPLETE; + chartConfiguration: ChartConfiguration; +} +export const SET_CHART_CONFIG_FAIL = 'SET_CHART_CONFIG_FAIL'; +export interface SetChartConfigFail { + type: typeof SET_CHART_CONFIG_FAIL; + chartConfiguration: ChartConfiguration; +} +export const setChartConfiguration = ( + chartConfiguration: ChartConfiguration, +) => async (dispatch: Dispatch, getState: () => any) => { + dispatch({ + type: SET_CHART_CONFIG_BEGIN, + chartConfiguration, + }); + const { id, metadata } = getState().dashboardInfo; + + // TODO extract this out when makeApi supports url parameters + const updateDashboard = makeApi< + Partial, + { result: DashboardInfo } + >({ + method: 'PUT', + endpoint: `/api/v1/dashboard/${id}`, + }); + + try { + const response = await updateDashboard({ + json_metadata: JSON.stringify({ + ...metadata, + chart_configuration: chartConfiguration, + }), + }); + dispatch( + dashboardInfoChanged({ + metadata: JSON.parse(response.result.json_metadata), + }), + ); + dispatch({ + type: SET_CHART_CONFIG_COMPLETE, + chartConfiguration, + }); + } catch (err) { + dispatch({ type: SET_CHART_CONFIG_FAIL, chartConfiguration }); + } +}; diff --git a/superset-frontend/src/dashboard/actions/nativeFilters.ts b/superset-frontend/src/dashboard/actions/nativeFilters.ts index 2e1c7e732dde3..8d183271e9edc 100644 --- a/superset-frontend/src/dashboard/actions/nativeFilters.ts +++ b/superset-frontend/src/dashboard/actions/nativeFilters.ts @@ -26,7 +26,7 @@ import { SET_DATA_MASK_FOR_FILTER_CONFIG_FAIL, } from 'src/dataMask/actions'; import { dashboardInfoChanged } from './dashboardInfo'; -import { FilterSet } from '../reducers/types'; +import { DashboardInfo, FilterSet } from '../reducers/types'; export const SET_FILTER_CONFIG_BEGIN = 'SET_FILTER_CONFIG_BEGIN'; export interface SetFilterConfigBegin { @@ -60,11 +60,6 @@ export interface SetFilterSetsConfigFail { filterSetsConfig: FilterSet[]; } -interface DashboardInfo { - id: number; - json_metadata: string; -} - export const setFilterConfiguration = ( filterConfig: FilterConfiguration, ) => async (dispatch: Dispatch, getState: () => any) => { @@ -87,7 +82,7 @@ export const setFilterConfiguration = ( const response = await updateDashboard({ json_metadata: JSON.stringify({ ...metadata, - filter_configuration: filterConfig, + native_filter_configuration: filterConfig, }), }); dispatch( diff --git a/superset-frontend/src/dashboard/components/CrossFilterScopingModal/CrossFilterScopingForm.tsx b/superset-frontend/src/dashboard/components/CrossFilterScopingModal/CrossFilterScopingForm.tsx new file mode 100644 index 0000000000000..7e98ee038cd5f --- /dev/null +++ b/superset-frontend/src/dashboard/components/CrossFilterScopingModal/CrossFilterScopingForm.tsx @@ -0,0 +1,54 @@ +/** + * 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 React, { FC } from 'react'; +import { FormInstance } from 'antd/lib/form'; +import FilterScope from '../nativeFilters/FiltersConfigModal/FiltersConfigForm/FilterScope/FilterScope'; +import { setCrossFilterFieldValues } from './utils'; +import { Scope } from '../nativeFilters/types'; +import { useForceUpdate } from '../nativeFilters/FiltersConfigModal/FiltersConfigForm/utils'; +import { CrossFilterScopingFormType } from './types'; + +type CrossFilterScopingFormProps = { + scope: Scope; + form: FormInstance; +}; + +const CrossFilterScopingForm: FC = ({ + form, + scope, +}) => { + const forceUpdate = useForceUpdate(); + const formScope = form.getFieldValue('scope'); + const formScoping = form.getFieldValue('scoping'); + return ( + { + setCrossFilterFieldValues(form, { + ...values, + }); + }} + scope={scope} + formScope={formScope} + forceUpdate={forceUpdate} + formScoping={formScoping} + /> + ); +}; + +export default CrossFilterScopingForm; diff --git a/superset-frontend/src/dashboard/components/CrossFilterScopingModal/CrossFilterScopingModal.tsx b/superset-frontend/src/dashboard/components/CrossFilterScopingModal/CrossFilterScopingModal.tsx new file mode 100644 index 0000000000000..765ff2b83b48f --- /dev/null +++ b/superset-frontend/src/dashboard/components/CrossFilterScopingModal/CrossFilterScopingModal.tsx @@ -0,0 +1,97 @@ +/** + * 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 } from '@superset-ui/core'; +import React, { FC } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; +import { StyledModal } from 'src/common/components/Modal'; +import Button from 'src/components/Button'; +import { Form } from 'src/common/components'; +import { setChartConfiguration } from 'src/dashboard/actions/dashboardInfo'; +import { ChartConfiguration } from 'src/dashboard/reducers/types'; +import CrossFilterScopingForm from './CrossFilterScopingForm'; +import { CrossFilterScopingFormType } from './types'; +import { StyledForm } from '../nativeFilters/FiltersConfigModal/FiltersConfigModal'; + +type CrossFilterScopingModalProps = { + chartId: number; + isOpen: boolean; + onClose: () => void; +}; + +const CrossFilterScopingModal: FC = ({ + isOpen, + chartId, + onClose, +}) => { + const dispatch = useDispatch(); + const [form] = Form.useForm(); + const chartConfig = useSelector( + ({ dashboardInfo }) => dashboardInfo?.metadata?.chart_configuration, + ); + const scope = chartConfig?.[chartId]?.crossFilters?.scope; + const handleSave = () => { + dispatch( + setChartConfiguration({ + ...chartConfig, + [chartId]: { crossFilters: { scope: form.getFieldValue('scope') } }, + }), + ); + onClose(); + }; + + return ( + + + + + } + > + + + + + ); +}; + +export default CrossFilterScopingModal; diff --git a/superset-frontend/src/dashboard/actions/dashboardInfo.js b/superset-frontend/src/dashboard/components/CrossFilterScopingModal/types.ts similarity index 79% rename from superset-frontend/src/dashboard/actions/dashboardInfo.js rename to superset-frontend/src/dashboard/components/CrossFilterScopingModal/types.ts index 10b6f21d67097..b56ffc0eea5ef 100644 --- a/superset-frontend/src/dashboard/actions/dashboardInfo.js +++ b/superset-frontend/src/dashboard/components/CrossFilterScopingModal/types.ts @@ -17,9 +17,8 @@ * under the License. */ -export const DASHBOARD_INFO_UPDATED = 'DASHBOARD_INFO_UPDATED'; +import { Scope } from '../nativeFilters/types'; -// updates partially changed dashboard info -export function dashboardInfoChanged(newInfo) { - return { type: DASHBOARD_INFO_UPDATED, newInfo }; -} +export type CrossFilterScopingFormType = { + scope: Scope; +}; diff --git a/superset-frontend/src/dashboard/components/CrossFilterScopingModal/utils.ts b/superset-frontend/src/dashboard/components/CrossFilterScopingModal/utils.ts new file mode 100644 index 0000000000000..27e694540c37a --- /dev/null +++ b/superset-frontend/src/dashboard/components/CrossFilterScopingModal/utils.ts @@ -0,0 +1,29 @@ +/** + * 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 { FormInstance } from 'antd/lib/form'; + +// eslint-disable-next-line import/prefer-default-export +export const setCrossFilterFieldValues = ( + form: FormInstance, + values: object, +) => { + form.setFieldsValue({ + ...values, + }); +}; diff --git a/superset-frontend/src/dashboard/components/Dashboard.jsx b/superset-frontend/src/dashboard/components/Dashboard.jsx index 859b5607529ff..a373d33e60f78 100644 --- a/superset-frontend/src/dashboard/components/Dashboard.jsx +++ b/superset-frontend/src/dashboard/components/Dashboard.jsx @@ -207,7 +207,10 @@ class Dashboard extends React.PureComponent { this.appliedOwnDataCharts, ); [...allKeys].forEach(filterKey => { - if (!currFilterKeys.includes(filterKey)) { + if ( + !currFilterKeys.includes(filterKey) && + appliedFilterKeys.includes(filterKey) + ) { // filterKey is removed? affectedChartIds.push(...appliedFilters[filterKey].scope); } else if (!appliedFilterKeys.includes(filterKey)) { diff --git a/superset-frontend/src/dashboard/components/SliceHeaderControls.jsx b/superset-frontend/src/dashboard/components/SliceHeaderControls.jsx index aeb94b9af3b46..8963b565e6b09 100644 --- a/superset-frontend/src/dashboard/components/SliceHeaderControls.jsx +++ b/superset-frontend/src/dashboard/components/SliceHeaderControls.jsx @@ -19,12 +19,19 @@ import React from 'react'; import PropTypes from 'prop-types'; import moment from 'moment'; -import { styled, t } from '@superset-ui/core'; +import { + Behavior, + getChartMetadataRegistry, + styled, + t, +} from '@superset-ui/core'; import { Menu, NoAnimationDropdown } from 'src/common/components'; import ShareMenuItems from 'src/dashboard/components/menu/ShareMenuItems'; import downloadAsImage from '../../utils/downloadAsImage'; import getDashboardUrl from '../util/getDashboardUrl'; import { getActiveFilters } from '../util/activeDashboardFilters'; +import { FeatureFlag, isFeatureEnabled } from '../../featureFlags'; +import CrossFilterScopingModal from './CrossFilterScopingModal/CrossFilterScopingModal'; const propTypes = { slice: PropTypes.object.isRequired, @@ -59,6 +66,7 @@ const defaultProps = { }; const MENU_KEYS = { + CROSS_FILTER_SCOPING: 'cross_filter_scoping', FORCE_REFRESH: 'force_refresh', TOGGLE_CHART_DESCRIPTION: 'toggle_chart_description', EXPLORE_CHART: 'explore_chart', @@ -111,6 +119,7 @@ class SliceHeaderControls extends React.PureComponent { this.state = { showControls: false, + showCrossFilterScopingModal: false, }; } @@ -134,6 +143,9 @@ class SliceHeaderControls extends React.PureComponent { case MENU_KEYS.FORCE_REFRESH: this.refreshChart(); break; + case MENU_KEYS.CROSS_FILTER_SCOPING: + this.setState({ showCrossFilterScopingModal: true }); + break; case MENU_KEYS.TOGGLE_CHART_DESCRIPTION: this.props.toggleExpandSlice(this.props.slice.slice_id); break; @@ -177,6 +189,14 @@ class SliceHeaderControls extends React.PureComponent { addDangerToast, isFullSize, } = this.props; + const crossFilterItems = getChartMetadataRegistry().items; + const isCrossFilter = Object.entries(crossFilterItems) + // @ts-ignore + .filter(([, { value }]) => + value.behaviors?.includes(Behavior.CROSS_FILTER), + ) + .find(([key]) => key === slice.viz_type); + const cachedWhen = cachedDttm.map(itemCachedDttm => moment.utc(itemCachedDttm).fromNow(), ); @@ -255,25 +275,38 @@ class SliceHeaderControls extends React.PureComponent { {this.props.supersetCanCSV && ( {t('Export CSV')} )} + {isFeatureEnabled(FeatureFlag.DASHBOARD_CROSS_FILTERS) && + isCrossFilter && ( + + {t('Cross-filter scoping')} + + )} ); return ( - - triggerNode.closest(SCREENSHOT_NODE_SELECTOR) - } - > - - - - + <> + this.setState({ showCrossFilterScopingModal: false })} + /> + + triggerNode.closest(SCREENSHOT_NODE_SELECTOR) + } + > + + + + + ); } } diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/ControlItems.tsx b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/ControlItems.tsx index 1480225330473..7deee0d85fa2e 100644 --- a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/ControlItems.tsx +++ b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/ControlItems.tsx @@ -21,7 +21,7 @@ import React, { FC } from 'react'; import { Checkbox } from 'src/common/components'; import { FormInstance } from 'antd/lib/form'; import { getChartControlPanelRegistry } from '@superset-ui/core'; -import { getControlItems, setFilterFieldValues } from './utils'; +import { getControlItems, setNativeFilterFieldValues } from './utils'; import { NativeFiltersForm, NativeFiltersFormItem } from '../types'; import { StyledCheckboxFormItem } from './FiltersConfigForm'; import { Filter } from '../../types'; @@ -71,7 +71,7 @@ const ControlItems: FC = ({ if (!controlItem.config.resetConfig) { return; } - setFilterFieldValues(form, filterId, { + setNativeFilterFieldValues(form, filterId, { defaultValue: null, }); forceUpdate(); diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/DefaultValue.tsx b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/DefaultValue.tsx index 1019bd6f4b6f9..4d0dcdd4f2107 100644 --- a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/DefaultValue.tsx +++ b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/DefaultValue.tsx @@ -19,7 +19,7 @@ import React, { FC } from 'react'; import { t, SuperChart, Behavior } from '@superset-ui/core'; import { FormInstance } from 'antd/lib/form'; -import { setFilterFieldValues } from './utils'; +import { setNativeFilterFieldValues } from './utils'; import { StyledFormItem, StyledLabel } from './FiltersConfigForm'; import { Filter } from '../../types'; import { NativeFiltersForm } from '../types'; @@ -68,7 +68,7 @@ const DefaultValue: FC = ({ chartType={formFilter?.filterType} hooks={{ setDataMask: ({ nativeFilters }) => { - setFilterFieldValues(form, filterId, { + setNativeFilterFieldValues(form, filterId, { defaultValue: nativeFilters?.currentState?.value, }); forceUpdate(); diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FilterScope/FilterScope.tsx b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FilterScope/FilterScope.tsx index e24dafe92e1ef..09321ca119979 100644 --- a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FilterScope/FilterScope.tsx +++ b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FilterScope/FilterScope.tsx @@ -20,52 +20,57 @@ import React, { FC } from 'react'; import { t, styled } from '@superset-ui/core'; import { Radio } from 'src/common/components/Radio'; -import { Form, Typography, Space, FormInstance } from 'src/common/components'; -import { NativeFiltersForm } from '../../types'; -import { Filter } from '../../../types'; +import { Form, Typography } from 'src/common/components'; +import { Scope } from '../../../types'; import { Scoping } from './types'; import ScopingTree from './ScopingTree'; -import { setFilterFieldValues, useForceUpdate } from '../utils'; import { getDefaultScopeValue, isScopingAll } from './utils'; type FilterScopeProps = { - filterId: string; - filterToEdit?: Filter; - form: FormInstance; + pathToFormValue?: string[]; + updateFormValues: (values: any) => void; + formScope?: Scope; + forceUpdate: Function; + scope?: Scope; + formScoping?: Scoping; }; +const Wrapper = styled.div` + display: flex; + flex-direction: column; + & > * { + margin-bottom: ${({ theme }) => theme.gridUnit}px; + } +`; + const CleanFormItem = styled(Form.Item)` margin-bottom: 0; `; const FilterScope: FC = ({ - filterId, - filterToEdit, - form, + pathToFormValue = [], + formScoping, + formScope, + forceUpdate, + scope, + updateFormValues, }) => { - const formFilter = form.getFieldValue('filters')?.[filterId]; - const initialScope = filterToEdit?.scope || getDefaultScopeValue(); - - const scoping = isScopingAll(initialScope) ? Scoping.all : Scoping.specific; - - const forceUpdate = useForceUpdate(); + const initialScope = scope || getDefaultScopeValue(); + const initialScoping = isScopingAll(initialScope) + ? Scoping.all + : Scoping.specific; return ( - - +