From 606461f87a44a15ba352418e50b8c3b0987bade9 Mon Sep 17 00:00:00 2001 From: John Bodley Date: Wed, 22 Feb 2023 14:09:31 +1300 Subject: [PATCH] Revert "feat(native_filter_migration): add transition mode (#16992)" This reverts commit 7d22c9ce170d0bd6ad31c680d007881b61dd378f. --- RESOURCES/FEATURE_FLAGS.md | 1 - .../src/utils/featureFlags.ts | 1 - .../src/components/Chart/Chart.jsx | 21 +- superset-frontend/src/constants.ts | 4 - .../src/dashboard/actions/hydrate.js | 67 +-- .../src/dashboard/actions/sliceEntities.js | 32 +- .../dashboard/actions/sliceEntities.test.js | 4 +- .../components/DashboardBuilder/state.ts | 10 +- .../Header/HeaderActionsDropdown/index.jsx | 25 +- .../src/dashboard/components/Header/index.jsx | 11 +- .../src/dashboard/components/SliceAdder.jsx | 36 +- .../components/gridComponents/Chart.jsx | 24 +- .../components/gridComponents/Tabs.jsx | 13 +- .../nativeFilters/FilterBar/state.ts | 29 +- .../src/dashboard/containers/Chart.jsx | 1 - .../dashboard/containers/DashboardHeader.jsx | 1 - .../dashboard/containers/DashboardPage.tsx | 128 +----- .../src/dashboard/containers/SliceAdder.jsx | 1 - .../util/filterboxMigrationHelper.test.ts | 142 ------ .../util/filterboxMigrationHelper.ts | 423 ------------------ superset-frontend/src/explore/constants.ts | 10 - superset/config.py | 1 - superset/views/dashboard/views.py | 8 - 23 files changed, 60 insertions(+), 933 deletions(-) delete mode 100644 superset-frontend/src/dashboard/util/filterboxMigrationHelper.test.ts delete mode 100644 superset-frontend/src/dashboard/util/filterboxMigrationHelper.ts diff --git a/RESOURCES/FEATURE_FLAGS.md b/RESOURCES/FEATURE_FLAGS.md index 76138f3ea5d9f..a8f4cdfa326fd 100644 --- a/RESOURCES/FEATURE_FLAGS.md +++ b/RESOURCES/FEATURE_FLAGS.md @@ -56,7 +56,6 @@ These features are **finished** but currently being tested. They are usable, but - DASHBOARD_FILTERS_EXPERIMENTAL - DASHBOARD_NATIVE_FILTERS - DYNAMIC_PLUGINS: [(docs)](https://superset.apache.org/docs/installation/running-on-kubernetes) -- ENABLE_FILTER_BOX_MIGRATION - ENABLE_JAVASCRIPT_CONTROLS - GENERIC_CHART_AXES - GLOBAL_ASYNC_QUERIES [(docs)](https://github.com/apache/superset/blob/master/CONTRIBUTING.md#async-chart-queries) diff --git a/superset-frontend/packages/superset-ui-core/src/utils/featureFlags.ts b/superset-frontend/packages/superset-ui-core/src/utils/featureFlags.ts index c869874be86b2..1492d83846e39 100644 --- a/superset-frontend/packages/superset-ui-core/src/utils/featureFlags.ts +++ b/superset-frontend/packages/superset-ui-core/src/utils/featureFlags.ts @@ -44,7 +44,6 @@ export enum FeatureFlag { ENABLE_ADVANCED_DATA_TYPES = 'ENABLE_ADVANCED_DATA_TYPES', ENABLE_DND_WITH_CLICK_UX = 'ENABLE_DND_WITH_CLICK_UX', ENABLE_EXPLORE_DRAG_AND_DROP = 'ENABLE_EXPLORE_DRAG_AND_DROP', - ENABLE_FILTER_BOX_MIGRATION = 'ENABLE_FILTER_BOX_MIGRATION', ENABLE_JAVASCRIPT_CONTROLS = 'ENABLE_JAVASCRIPT_CONTROLS', ENABLE_TEMPLATE_PROCESSING = 'ENABLE_TEMPLATE_PROCESSING', ENABLE_TEMPLATE_REMOVE_FILTERS = 'ENABLE_TEMPLATE_REMOVE_FILTERS', diff --git a/superset-frontend/src/components/Chart/Chart.jsx b/superset-frontend/src/components/Chart/Chart.jsx index 9905c964fd21d..e8453ee27b44a 100644 --- a/superset-frontend/src/components/Chart/Chart.jsx +++ b/superset-frontend/src/components/Chart/Chart.jsx @@ -59,7 +59,6 @@ const propTypes = { triggerRender: PropTypes.bool, force: PropTypes.bool, isFiltersInitialized: PropTypes.bool, - isDeactivatedViz: PropTypes.bool, // state chartAlert: PropTypes.string, chartStatus: PropTypes.string, @@ -94,7 +93,6 @@ const defaultProps = { triggerRender: false, dashboardId: null, chartStackTrace: null, - isDeactivatedViz: false, force: false, isInView: true, }; @@ -140,25 +138,13 @@ class Chart extends React.PureComponent { } componentDidMount() { - // during migration, hold chart queries before user choose review or cancel - if ( - this.props.triggerQuery && - this.props.filterboxMigrationState !== 'UNDECIDED' - ) { + if (this.props.triggerQuery) { this.runQuery(); } } componentDidUpdate() { - // during migration, hold chart queries before user choose review or cancel - if ( - this.props.triggerQuery && - this.props.filterboxMigrationState !== 'UNDECIDED' - ) { - // if the chart is deactivated (filter_box), only load once - if (this.props.isDeactivatedViz && this.props.queriesResponse) { - return; - } + if (this.props.triggerQuery) { this.runQuery(); } } @@ -261,7 +247,6 @@ class Chart extends React.PureComponent { errorMessage, chartIsStale, queriesResponse = [], - isDeactivatedViz = false, width, } = this.props; @@ -332,7 +317,7 @@ class Chart extends React.PureComponent { )} - {isLoading && !isDeactivatedViz && } + {isLoading && } ); diff --git a/superset-frontend/src/constants.ts b/superset-frontend/src/constants.ts index 66f2f70aa795a..26282ed5fcd85 100644 --- a/superset-frontend/src/constants.ts +++ b/superset-frontend/src/constants.ts @@ -27,10 +27,6 @@ export const BOOL_TRUE_DISPLAY = 'True'; export const BOOL_FALSE_DISPLAY = 'False'; export const URL_PARAMS = { - migrationState: { - name: 'migration_state', - type: 'string', - }, standalone: { name: 'standalone', type: 'number', diff --git a/superset-frontend/src/dashboard/actions/hydrate.js b/superset-frontend/src/dashboard/actions/hydrate.js index efae72151ef94..2b550e0783f7d 100644 --- a/superset-frontend/src/dashboard/actions/hydrate.js +++ b/superset-frontend/src/dashboard/actions/hydrate.js @@ -50,11 +50,9 @@ import newComponentFactory from 'src/dashboard/util/newComponentFactory'; import { TIME_RANGE } from 'src/visualizations/FilterBox/FilterBox'; import { URL_PARAMS } from 'src/constants'; import { getUrlParam } from 'src/utils/urlUtils'; -import { FILTER_BOX_MIGRATION_STATES } from 'src/explore/constants'; import { ResourceStatus } from 'src/hooks/apiResources/apiResources'; import { FeatureFlag, isFeatureEnabled } from '../../featureFlags'; import extractUrlParams from '../util/extractUrlParams'; -import getNativeFilterConfig from '../util/filterboxMigrationHelper'; import { updateColorSchema } from './dashboardInfo'; import { getChartIdsInFilterScope } from '../util/getChartIdsInFilterScope'; import updateComponentParentsList from '../util/updateComponentParentsList'; @@ -63,14 +61,7 @@ import { FilterBarOrientation } from '../types'; export const HYDRATE_DASHBOARD = 'HYDRATE_DASHBOARD'; export const hydrateDashboard = - ({ - history, - dashboard, - charts, - filterboxMigrationState = FILTER_BOX_MIGRATION_STATES.NOOP, - dataMask, - activeTabs, - }) => + ({ history, dashboard, charts, dataMask, activeTabs }) => (dispatch, getState) => { const { user, common, dashboardState } = getState(); const { metadata, position_data: positionData } = dashboard; @@ -232,25 +223,18 @@ export const hydrateDashboard = const componentId = chartIdToLayoutId[key]; const directPathToFilter = (layout[componentId].parents || []).slice(); directPathToFilter.push(componentId); - if ( - [ - FILTER_BOX_MIGRATION_STATES.NOOP, - FILTER_BOX_MIGRATION_STATES.SNOOZED, - ].includes(filterboxMigrationState) - ) { - dashboardFilters[key] = { - ...dashboardFilter, - chartId: key, - componentId, - datasourceId: slice.form_data.datasource, - filterName: slice.slice_name, - directPathToFilter, - columns, - labels, - scopes: scopesByChartId, - isDateFilter: Object.keys(columns).includes(TIME_RANGE), - }; - } + dashboardFilters[key] = { + ...dashboardFilter, + chartId: key, + componentId, + datasourceId: slice.form_data.datasource, + filterName: slice.slice_name, + directPathToFilter, + columns, + labels, + scopes: scopesByChartId, + isDateFilter: Object.keys(columns).includes(TIME_RANGE), + }; } // sync layout names with current slice names in case a slice was edited @@ -319,28 +303,12 @@ export const hydrateDashboard = directPathToChild.push(directLinkComponentId); } - // should convert filter_box to filter component? - let filterConfig = metadata?.native_filter_configuration || []; - if (filterboxMigrationState === FILTER_BOX_MIGRATION_STATES.REVIEWING) { - filterConfig = getNativeFilterConfig( - charts, - filterScopes, - preselectFilters, - ); - metadata.native_filter_configuration = filterConfig; - metadata.show_native_filters = true; - } const nativeFilters = getInitialNativeFilterState({ - filterConfig, + filterConfig: metadata?.native_filter_configuration || [], }); - metadata.show_native_filters = - dashboard?.metadata?.show_native_filters ?? - (isFeatureEnabled(FeatureFlag.DASHBOARD_NATIVE_FILTERS) && - [ - FILTER_BOX_MIGRATION_STATES.CONVERTED, - FILTER_BOX_MIGRATION_STATES.REVIEWING, - FILTER_BOX_MIGRATION_STATES.NOOP, - ].includes(filterboxMigrationState)); + metadata.show_native_filters = isFeatureEnabled( + FeatureFlag.DASHBOARD_NATIVE_FILTERS, + ); if (isFeatureEnabled(FeatureFlag.DASHBOARD_CROSS_FILTERS)) { // If user just added cross filter to dashboard it's not saving it scope on server, @@ -465,7 +433,6 @@ export const hydrateDashboard = isRefreshing: false, isFiltersRefreshing: false, activeTabs: activeTabs || dashboardState?.activeTabs || [], - filterboxMigrationState, datasetsStatus: ResourceStatus.LOADING, }, dashboardLayout, diff --git a/superset-frontend/src/dashboard/actions/sliceEntities.js b/superset-frontend/src/dashboard/actions/sliceEntities.js index 74fd8fd7f2520..53a681de818a6 100644 --- a/superset-frontend/src/dashboard/actions/sliceEntities.js +++ b/superset-frontend/src/dashboard/actions/sliceEntities.js @@ -46,7 +46,6 @@ export function fetchAllSlicesFailed(error) { export function fetchSlices( userId, - excludeFilterBox, dispatch, filter_value, sortColumn = 'changed_on', @@ -84,11 +83,7 @@ export function fetchSlices( })}`, }) .then(({ json }) => { - let { result } = json; - // disable add filter_box viz to dashboard - if (excludeFilterBox) { - result = result.filter(slice => slice.viz_type !== 'filter_box'); - } + const { result } = json; result.forEach(slice => { let form_data = JSON.parse(slice.params); form_data = { @@ -135,46 +130,31 @@ export function fetchSlices( ); } -export function fetchAllSlices(userId, excludeFilterBox = false) { +export function fetchAllSlices(userId) { return (dispatch, getState) => { const { sliceEntities } = getState(); if (sliceEntities.lastUpdated === 0) { dispatch(fetchAllSlicesStarted()); - return fetchSlices(userId, excludeFilterBox, dispatch, undefined); + return fetchSlices(userId, dispatch, undefined); } return dispatch(setAllSlices(sliceEntities.slices)); }; } -export function fetchSortedSlices( - userId, - excludeFilterBox = false, - order_column, -) { +export function fetchSortedSlices(userId, order_column) { return dispatch => { dispatch(fetchAllSlicesStarted()); - return fetchSlices( - userId, - excludeFilterBox, - dispatch, - undefined, - order_column, - ); + return fetchSlices(userId, dispatch, undefined, order_column); }; } -export function fetchFilteredSlices( - userId, - excludeFilterBox = false, - filter_value, -) { +export function fetchFilteredSlices(userId, filter_value) { return (dispatch, getState) => { dispatch(fetchAllSlicesStarted()); const { sliceEntities } = getState(); return fetchSlices( userId, - excludeFilterBox, dispatch, filter_value, undefined, diff --git a/superset-frontend/src/dashboard/actions/sliceEntities.test.js b/superset-frontend/src/dashboard/actions/sliceEntities.test.js index 0fe9365fc9d1c..1f3d0cb440bed 100644 --- a/superset-frontend/src/dashboard/actions/sliceEntities.test.js +++ b/superset-frontend/src/dashboard/actions/sliceEntities.test.js @@ -67,7 +67,7 @@ describe('slice entity actions', () => { describe('fetchFilteredSlices', () => { it('should dispatch an fetchAllSlicesStarted action', async () => { const { dispatch, getState } = setup(); - const thunk1 = fetchFilteredSlices('userId', false, 'filter_value'); + const thunk1 = fetchFilteredSlices('userId', 'filter_value'); await thunk1(dispatch, getState); expect(dispatch.getCall(0).args[0]).toEqual({ type: FETCH_ALL_SLICES_STARTED, @@ -82,7 +82,7 @@ describe('slice entity actions', () => { sliceEntities: { slices: {}, lastUpdated: 1 }, }); - const thunk1 = fetchAllSlices('userId', false, 'filter_value'); + const thunk1 = fetchAllSlices('userId', 'filter_value'); await thunk1(dispatch, getState); expect(spy.get.callCount).toBe(0); diff --git a/superset-frontend/src/dashboard/components/DashboardBuilder/state.ts b/superset-frontend/src/dashboard/components/DashboardBuilder/state.ts index 676ffd45ccacd..850d195f44e07 100644 --- a/superset-frontend/src/dashboard/components/DashboardBuilder/state.ts +++ b/superset-frontend/src/dashboard/components/DashboardBuilder/state.ts @@ -18,11 +18,10 @@ */ import { useSelector } from 'react-redux'; import { FeatureFlag, isFeatureEnabled } from 'src/featureFlags'; -import { useCallback, useEffect, useState, useContext } from 'react'; +import { useCallback, useEffect, useState } from 'react'; import { URL_PARAMS } from 'src/constants'; import { getUrlParam } from 'src/utils/urlUtils'; import { RootState } from 'src/dashboard/types'; -import { MigrationContext } from 'src/dashboard/containers/DashboardPage'; import { useFilters, useNativeFiltersDataMask, @@ -30,7 +29,6 @@ import { // eslint-disable-next-line import/prefer-default-export export const useNativeFilters = () => { - const filterboxMigrationState = useContext(MigrationContext); const [isInitialized, setIsInitialized] = useState(false); const showNativeFilters = useSelector( state => @@ -78,15 +76,13 @@ export const useNativeFilters = () => { useEffect(() => { if ( expandFilters === false || - (filterValues.length === 0 && - nativeFiltersEnabled && - ['CONVERTED', 'REVIEWING', 'NOOP'].includes(filterboxMigrationState)) + (filterValues.length === 0 && nativeFiltersEnabled) ) { toggleDashboardFiltersOpen(false); } else { toggleDashboardFiltersOpen(true); } - }, [filterValues.length, filterboxMigrationState]); + }, [filterValues.length]); useEffect(() => { if (showDashboard) { diff --git a/superset-frontend/src/dashboard/components/Header/HeaderActionsDropdown/index.jsx b/superset-frontend/src/dashboard/components/Header/HeaderActionsDropdown/index.jsx index d4c9a8aadb6bc..971dd3507df34 100644 --- a/superset-frontend/src/dashboard/components/Header/HeaderActionsDropdown/index.jsx +++ b/superset-frontend/src/dashboard/components/Header/HeaderActionsDropdown/index.jsx @@ -35,7 +35,6 @@ import downloadAsImage from 'src/utils/downloadAsImage'; import getDashboardUrl from 'src/dashboard/util/getDashboardUrl'; import { getActiveFilters } from 'src/dashboard/util/activeDashboardFilters'; import { getUrlParam } from 'src/utils/urlUtils'; -import { FILTER_BOX_MIGRATION_STATES } from 'src/explore/constants'; import { LOG_ACTIONS_DASHBOARD_DOWNLOAD_AS_IMAGE } from 'src/logger/LogUtils'; const propTypes = { @@ -70,11 +69,6 @@ const propTypes = { refreshLimit: PropTypes.number, refreshWarning: PropTypes.string, lastModifiedTime: PropTypes.number.isRequired, - filterboxMigrationState: PropTypes.oneOf( - Object.keys(FILTER_BOX_MIGRATION_STATES).map( - key => FILTER_BOX_MIGRATION_STATES[key], - ), - ), }; const defaultProps = { @@ -82,7 +76,6 @@ const defaultProps = { colorScheme: undefined, refreshLimit: 0, refreshWarning: null, - filterboxMigrationState: FILTER_BOX_MIGRATION_STATES.NOOP, }; const MENU_KEYS = { @@ -230,7 +223,6 @@ class HeaderActionsDropdown extends React.PureComponent { lastModifiedTime, addSuccessToast, addDangerToast, - filterboxMigrationState, setIsDropdownVisible, isDropdownVisible, ...rest @@ -378,15 +370,14 @@ class HeaderActionsDropdown extends React.PureComponent { ) ) : null} - {editMode && - filterboxMigrationState !== FILTER_BOX_MIGRATION_STATES.CONVERTED && ( - - - - )} + {editMode && ( + + + + )} { this.searchUpdated(value); - const { userId, filterboxMigrationState } = this.props; - this.slicesRequest = this.props.fetchFilteredSlices( - userId, - isFeatureEnabled(FeatureFlag.ENABLE_FILTER_BOX_MIGRATION) && - filterboxMigrationState !== FILTER_BOX_MIGRATION_STATES.SNOOZED, - value, - ); + const { userId } = this.props; + this.slicesRequest = this.props.fetchFilteredSlices(userId, value); }, 300); searchUpdated(searchTerm) { @@ -226,13 +207,8 @@ class SliceAdder extends React.Component { ), })); - const { userId, filterboxMigrationState } = this.props; - this.slicesRequest = this.props.fetchSortedSlices( - userId, - isFeatureEnabled(FeatureFlag.ENABLE_FILTER_BOX_MIGRATION) && - filterboxMigrationState !== FILTER_BOX_MIGRATION_STATES.SNOOZED, - sortBy, - ); + const { userId } = this.props; + this.slicesRequest = this.props.fetchSortedSlices(userId, sortBy); } rowRenderer({ key, index, style }) { diff --git a/superset-frontend/src/dashboard/components/gridComponents/Chart.jsx b/superset-frontend/src/dashboard/components/gridComponents/Chart.jsx index 89d4fb94ce7cf..0d25a3722d258 100644 --- a/superset-frontend/src/dashboard/components/gridComponents/Chart.jsx +++ b/superset-frontend/src/dashboard/components/gridComponents/Chart.jsx @@ -38,7 +38,6 @@ import { LOG_ACTIONS_FORCE_REFRESH_CHART, } from 'src/logger/LogUtils'; import { areObjectsEqual } from 'src/reduxUtils'; -import { FILTER_BOX_MIGRATION_STATES } from 'src/explore/constants'; import { postFormData } from 'src/explore/exploreUtils/formData'; import { URL_PARAMS } from 'src/constants'; @@ -70,11 +69,6 @@ const propTypes = { sliceName: PropTypes.string.isRequired, timeout: PropTypes.number.isRequired, maxRows: PropTypes.number.isRequired, - filterboxMigrationState: PropTypes.oneOf( - Object.keys(FILTER_BOX_MIGRATION_STATES).map( - key => FILTER_BOX_MIGRATION_STATES[key], - ), - ), // all active filter fields in dashboard filters: PropTypes.object.isRequired, refreshChart: PropTypes.func.isRequired, @@ -129,11 +123,6 @@ const ChartOverlay = styled.div` top: 0; left: 0; z-index: 5; - - &.is-deactivated { - opacity: 0.5; - background-color: ${({ theme }) => theme.colors.grayscale.light1}; - } `; const SliceContainer = styled.div` @@ -405,7 +394,6 @@ class Chart extends React.Component { handleToggleFullSize, isFullSize, setControlValue, - filterboxMigrationState, postTransformProps, datasetsStatus, isInView, @@ -422,12 +410,6 @@ class Chart extends React.Component { const { queriesResponse, chartUpdateEndTime, chartStatus } = chart; const isLoading = chartStatus === 'loading'; - const isDeactivatedViz = - slice.viz_type === 'filter_box' && - [ - FILTER_BOX_MIGRATION_STATES.REVIEWING, - FILTER_BOX_MIGRATION_STATES.CONVERTED, - ].includes(filterboxMigrationState); // eslint-disable-next-line camelcase const isCached = queriesResponse?.map(({ is_cached }) => is_cached) || []; const cachedDttm = @@ -506,15 +488,15 @@ class Chart extends React.Component { isOverflowable && 'dashboard-chart--overflowable', )} > - {(isLoading || isDeactivatedViz) && ( + {isLoading && ( )} + FILTER_BOX_MIGRATION_STATES[key], - ), - ), // actions (from DashboardComponent.jsx) logEvent: PropTypes.func.isRequired, @@ -81,7 +75,6 @@ const defaultProps = { columnWidth: 0, activeTabs: [], directPathToChild: [], - filterboxMigrationState: FILTER_BOX_MIGRATION_STATES.NOOP, setActiveTabs() {}, onResizeStart() {}, onResize() {}, @@ -136,10 +129,7 @@ export class Tabs extends React.PureComponent { } componentDidUpdate(prevProps, prevState) { - if ( - prevState.activeKey !== this.state.activeKey || - prevProps.filterboxMigrationState !== this.props.filterboxMigrationState - ) { + if (prevState.activeKey !== this.state.activeKey) { this.props.setActiveTabs(this.state.activeKey, prevState.activeKey); } } @@ -446,7 +436,6 @@ function mapStateToProps(state) { nativeFilters: state.nativeFilters, activeTabs: state.dashboardState.activeTabs, directPathToChild: state.dashboardState.directPathToChild, - filterboxMigrationState: state.dashboardState.filterboxMigrationState, }; } export default connect(mapStateToProps)(Tabs); diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/state.ts b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/state.ts index 425029bb86872..dde47514768ef 100644 --- a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/state.ts +++ b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/state.ts @@ -18,7 +18,6 @@ */ /* eslint-disable no-param-reassign */ import { useSelector } from 'react-redux'; -import { filter, keyBy } from 'lodash'; import { DataMaskState, DataMaskStateWithId, @@ -27,10 +26,8 @@ import { Filters, FilterSets as FilterSetsType, } from '@superset-ui/core'; -import { useContext, useEffect, useMemo, useState } from 'react'; +import { useEffect, useMemo, useState } from 'react'; import { ChartsState, RootState } from 'src/dashboard/types'; -import { MigrationContext } from 'src/dashboard/containers/DashboardPage'; -import { FILTER_BOX_MIGRATION_STATES } from 'src/explore/constants'; import { NATIVE_FILTER_PREFIX } from '../FiltersConfigModal/utils'; export const useFilterSets = () => @@ -102,30 +99,14 @@ export const useFilterUpdates = ( export const useInitialization = () => { const [isInitialized, setIsInitialized] = useState(false); const filters = useFilters(); - const filterboxMigrationState = useContext(MigrationContext); - let charts = useSelector(state => state.charts); + const charts = useSelector(state => state.charts); // We need to know how much charts now shown on dashboard to know how many of all charts should be loaded let numberOfLoadingCharts = 0; if (!isInitialized) { - // do not load filter_box in reviewing - if (filterboxMigrationState === FILTER_BOX_MIGRATION_STATES.REVIEWING) { - charts = keyBy( - filter(charts, chart => chart.form_data?.viz_type !== 'filter_box'), - 'id', - ); - const numberOfFilterbox = document.querySelectorAll( - '[data-test-viz-type="filter_box"]', - ).length; - - numberOfLoadingCharts = - document.querySelectorAll('[data-ui-anchor="chart"]').length - - numberOfFilterbox; - } else { - numberOfLoadingCharts = document.querySelectorAll( - '[data-ui-anchor="chart"]', - ).length; - } + numberOfLoadingCharts = document.querySelectorAll( + '[data-ui-anchor="chart"]', + ).length; } useEffect(() => { if (isInitialized) { diff --git a/superset-frontend/src/dashboard/containers/Chart.jsx b/superset-frontend/src/dashboard/containers/Chart.jsx index 167ec0a043878..b42b4950d5c0a 100644 --- a/superset-frontend/src/dashboard/containers/Chart.jsx +++ b/superset-frontend/src/dashboard/containers/Chart.jsx @@ -100,7 +100,6 @@ function mapStateToProps( filterState: dataMask[id]?.filterState, maxRows: common.conf.SQL_MAX_ROW, setControlValue, - filterboxMigrationState: dashboardState.filterboxMigrationState, datasetsStatus, emitCrossFilters: !!dashboardInfo.crossFiltersEnabled, }; diff --git a/superset-frontend/src/dashboard/containers/DashboardHeader.jsx b/superset-frontend/src/dashboard/containers/DashboardHeader.jsx index 178568f064eaa..a38b121e5d0de 100644 --- a/superset-frontend/src/dashboard/containers/DashboardHeader.jsx +++ b/superset-frontend/src/dashboard/containers/DashboardHeader.jsx @@ -99,7 +99,6 @@ function mapStateToProps({ slug: dashboardInfo.slug, metadata: dashboardInfo.metadata, reports, - filterboxMigrationState: dashboardState.filterboxMigrationState, }; } diff --git a/superset-frontend/src/dashboard/containers/DashboardPage.tsx b/superset-frontend/src/dashboard/containers/DashboardPage.tsx index 0066354f589b5..6ece49537b244 100644 --- a/superset-frontend/src/dashboard/containers/DashboardPage.tsx +++ b/superset-frontend/src/dashboard/containers/DashboardPage.tsx @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -import React, { FC, useEffect, useMemo, useRef, useState } from 'react'; +import React, { FC, useEffect, useMemo, useRef } from 'react'; import { useHistory } from 'react-router-dom'; import { CategoricalColorNamespace, @@ -25,14 +25,11 @@ import { isFeatureEnabled, SharedLabelColorSource, t, - useTheme, } from '@superset-ui/core'; import pick from 'lodash/pick'; import { useDispatch, useSelector } from 'react-redux'; -import { Global } from '@emotion/react'; import { useToasts } from 'src/components/MessageToasts/withToasts'; import Loading from 'src/components/Loading'; -import FilterBoxMigrationModal from 'src/dashboard/components/FilterBoxMigrationModal'; import { useDashboard, useDashboardCharts, @@ -42,37 +39,25 @@ import { hydrateDashboard } from 'src/dashboard/actions/hydrate'; import { setDatasources } from 'src/dashboard/actions/datasources'; import injectCustomCss from 'src/dashboard/util/injectCustomCss'; import setupPlugins from 'src/setup/setupPlugins'; -import { UserWithPermissionsAndRoles } from 'src/types/bootstrapTypes'; -import { addWarningToast } from 'src/components/MessageToasts/actions'; import { getItem, LocalStorageKeys, setItem, } from 'src/utils/localStorageHelpers'; -import { - FILTER_BOX_MIGRATION_STATES, - FILTER_BOX_TRANSITION_SNOOZE_DURATION, -} from 'src/explore/constants'; import { URL_PARAMS } from 'src/constants'; import { getUrlParam } from 'src/utils/urlUtils'; -import { canUserEditDashboard } from 'src/dashboard/util/permissionUtils'; import { getFilterSets } from 'src/dashboard/actions/nativeFilters'; import { setDatasetsStatus } from 'src/dashboard/actions/dashboardState'; import { getFilterValue, getPermalinkValue, } from 'src/dashboard/components/nativeFilters/FilterBar/keyValue'; -import { filterCardPopoverStyle, headerStyles } from 'src/dashboard/styles'; import { DashboardContextForExplore } from 'src/types/DashboardContextForExplore'; import shortid from 'shortid'; import { RootState } from '../types'; import { getActiveFilters } from '../util/activeDashboardFilters'; -export const MigrationContext = React.createContext( - FILTER_BOX_MIGRATION_STATES.NOOP, -); - export const DashboardPageIdContext = React.createContext(''); setupPlugins(); @@ -156,11 +141,7 @@ const useSyncDashboardStateWithLocalStorage = () => { export const DashboardPage: FC = ({ idOrSlug }: PageProps) => { const dispatch = useDispatch(); - const theme = useTheme(); const history = useHistory(); - const user = useSelector( - state => state.user, - ); const dashboardPageId = useSyncDashboardStateWithLocalStorage(); const { addDangerToast } = useToasts(); const { result: dashboard, error: dashboardApiError } = @@ -176,16 +157,7 @@ export const DashboardPage: FC = ({ idOrSlug }: PageProps) => { const error = dashboardApiError || chartsApiError; const readyToRender = Boolean(dashboard && charts); - const migrationStateParam = getUrlParam( - URL_PARAMS.migrationState, - ) as FILTER_BOX_MIGRATION_STATES; - const isMigrationEnabled = isFeatureEnabled( - FeatureFlag.ENABLE_FILTER_BOX_MIGRATION, - ); const { dashboard_title, css, metadata, id = 0 } = dashboard || {}; - const [filterboxMigrationState, setFilterboxMigrationState] = useState( - migrationStateParam || FILTER_BOX_MIGRATION_STATES.NOOP, - ); useEffect(() => { // mark tab id as redundant when user closes browser tab - a new id will be @@ -210,67 +182,6 @@ export const DashboardPage: FC = ({ idOrSlug }: PageProps) => { dispatch(setDatasetsStatus(status)); }, [dispatch, status]); - useEffect(() => { - // should convert filter_box to filter component? - const hasFilterBox = charts?.some( - chart => chart.form_data?.viz_type === 'filter_box', - ); - const canEdit = dashboard && canUserEditDashboard(dashboard, user); - - if (canEdit) { - // can user edit dashboard? - if (metadata?.native_filter_configuration) { - setFilterboxMigrationState( - isMigrationEnabled - ? FILTER_BOX_MIGRATION_STATES.CONVERTED - : FILTER_BOX_MIGRATION_STATES.NOOP, - ); - return; - } - - // set filterbox migration state if has filter_box in the dash: - if (hasFilterBox) { - if (isMigrationEnabled) { - // has url param? - if ( - migrationStateParam && - Object.values(FILTER_BOX_MIGRATION_STATES).includes( - migrationStateParam, - ) - ) { - setFilterboxMigrationState(migrationStateParam); - return; - } - - // has cookie? - const snoozeDash = getItem( - LocalStorageKeys.filter_box_transition_snoozed_at, - {}, - ); - if ( - Date.now() - (snoozeDash[id] || 0) < - FILTER_BOX_TRANSITION_SNOOZE_DURATION - ) { - setFilterboxMigrationState(FILTER_BOX_MIGRATION_STATES.SNOOZED); - return; - } - - setFilterboxMigrationState(FILTER_BOX_MIGRATION_STATES.UNDECIDED); - } else if (isFeatureEnabled(FeatureFlag.DASHBOARD_NATIVE_FILTERS)) { - dispatch( - addWarningToast( - t( - 'filter_box will be deprecated ' + - 'in a future version of Superset. ' + - 'Please replace filter_box by dashboard filter components.', - ), - ), - ); - } - } - } - }, [readyToRender]); - useEffect(() => { // eslint-disable-next-line consistent-return async function getDataMaskApplied() { @@ -308,7 +219,6 @@ export const DashboardPage: FC = ({ idOrSlug }: PageProps) => { dashboard, charts, activeTabs, - filterboxMigrationState, dataMask, }), ); @@ -317,7 +227,7 @@ export const DashboardPage: FC = ({ idOrSlug }: PageProps) => { } if (id) getDataMaskApplied(); // eslint-disable-next-line react-hooks/exhaustive-deps - }, [readyToRender, filterboxMigrationState]); + }, [readyToRender]); useEffect(() => { if (dashboard_title) { @@ -364,37 +274,9 @@ export const DashboardPage: FC = ({ idOrSlug }: PageProps) => { if (!readyToRender) return ; return ( - <> - - { - // cancel button: only snooze this visit - setFilterboxMigrationState(FILTER_BOX_MIGRATION_STATES.SNOOZED); - }} - onClickReview={() => { - setFilterboxMigrationState(FILTER_BOX_MIGRATION_STATES.REVIEWING); - }} - onClickSnooze={() => { - const snoozedDash = getItem( - LocalStorageKeys.filter_box_transition_snoozed_at, - {}, - ); - setItem(LocalStorageKeys.filter_box_transition_snoozed_at, { - ...snoozedDash, - [id]: Date.now(), - }); - setFilterboxMigrationState(FILTER_BOX_MIGRATION_STATES.SNOOZED); - }} - /> - - - - - - - + + + ); }; diff --git a/superset-frontend/src/dashboard/containers/SliceAdder.jsx b/superset-frontend/src/dashboard/containers/SliceAdder.jsx index 580dedc2f8300..e3c8e1db87a2c 100644 --- a/superset-frontend/src/dashboard/containers/SliceAdder.jsx +++ b/superset-frontend/src/dashboard/containers/SliceAdder.jsx @@ -40,7 +40,6 @@ function mapStateToProps( errorMessage: sliceEntities.errorMessage, lastUpdated: sliceEntities.lastUpdated, editMode: dashboardState.editMode, - filterboxMigrationState: dashboardState.filterboxMigrationState, }; } diff --git a/superset-frontend/src/dashboard/util/filterboxMigrationHelper.test.ts b/superset-frontend/src/dashboard/util/filterboxMigrationHelper.test.ts deleted file mode 100644 index f59f36541e35f..0000000000000 --- a/superset-frontend/src/dashboard/util/filterboxMigrationHelper.test.ts +++ /dev/null @@ -1,142 +0,0 @@ -/** - * 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 getNativeFilterConfig from './filterboxMigrationHelper'; - -const regionFilter = { - cache_timeout: null, - changed_on: '2021-10-07 11:57:48.355047', - description: null, - description_markeddown: '', - form_data: { - compare_lag: '10', - compare_suffix: 'o10Y', - country_fieldtype: 'cca3', - datasource: '1__table', - date_filter: false, - entity: 'country_code', - filter_configs: [ - { - asc: false, - clearable: true, - column: 'region', - key: '2s98dfu', - metric: 'sum__SP_POP_TOTL', - multiple: false, - }, - { - asc: false, - clearable: true, - column: 'country_name', - key: 'li3j2lk', - metric: 'sum__SP_POP_TOTL', - multiple: true, - }, - ], - granularity_sqla: 'year', - groupby: [], - limit: '25', - markup_type: 'markdown', - row_limit: 50000, - show_bubbles: true, - slice_id: 32, - time_range: '2014-01-01 : 2014-01-02', - viz_type: 'filter_box', - }, - modified: '', - slice_name: 'Region Filter', - slice_url: '/explore/?form_data=%7B%22slice_id%22%3A%2032%7D', - slice_id: 32, -}; -const chart1 = { - cache_timeout: null, - changed_on: '2021-09-07 18:05:18.896212', - description: null, - description_markeddown: '', - form_data: { - compare_lag: '10', - compare_suffix: 'over 10Y', - country_fieldtype: 'cca3', - datasource: '1__table', - entity: 'country_code', - granularity_sqla: 'year', - groupby: [], - limit: '25', - markup_type: 'markdown', - metric: 'sum__SP_POP_TOTL', - row_limit: 50000, - show_bubbles: true, - slice_id: 33, - time_range: '2000 : 2014-01-02', - viz_type: 'big_number', - }, - modified: "", - slice_name: "World's Population", - slice_url: '/explore/?form_data=%7B%22slice_id%22%3A%2033%7D', - slice_id: 33, -}; -const chartData = [regionFilter, chart1]; -const preselectedFilters = { - '32': { - region: ['East Asia & Pacific'], - }, -}; - -test('should convert filter_box config to dashboard native filter config', () => { - const filterConfig = getNativeFilterConfig(chartData, {}, {}); - // convert to 2 components - expect(filterConfig.length).toEqual(2); - - expect(filterConfig[0].id).toBeDefined(); - expect(filterConfig[0].filterType).toBe('filter_select'); - expect(filterConfig[0].name).toBe('region'); - expect(filterConfig[0].targets).toEqual([ - { column: { name: 'region' }, datasetId: 1 }, - ]); - expect(filterConfig[0].scope).toEqual({ - excluded: [], - rootPath: ['ROOT_ID'], - }); - - expect(filterConfig[1].id).toBeDefined(); - expect(filterConfig[1].filterType).toBe('filter_select'); - expect(filterConfig[1].name).toBe('country_name'); - expect(filterConfig[1].targets).toEqual([ - { column: { name: 'country_name' }, datasetId: 1 }, - ]); - expect(filterConfig[1].scope).toEqual({ - excluded: [], - rootPath: ['ROOT_ID'], - }); -}); - -test('should convert preselected filters', () => { - const filterConfig = getNativeFilterConfig(chartData, {}, preselectedFilters); - const { defaultDataMask } = filterConfig[0]; - expect(defaultDataMask.filterState).toEqual({ - value: ['East Asia & Pacific'], - }); - expect(defaultDataMask.extraFormData?.filters).toEqual([ - { - col: 'region', - op: 'IN', - val: ['East Asia & Pacific'], - }, - ]); -}); diff --git a/superset-frontend/src/dashboard/util/filterboxMigrationHelper.ts b/superset-frontend/src/dashboard/util/filterboxMigrationHelper.ts deleted file mode 100644 index 3e9ceb1390ed8..0000000000000 --- a/superset-frontend/src/dashboard/util/filterboxMigrationHelper.ts +++ /dev/null @@ -1,423 +0,0 @@ -/** - * 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 shortid from 'shortid'; -import { find, isEmpty } from 'lodash'; - -import { - FILTER_CONFIG_ATTRIBUTES, - TIME_FILTER_LABELS, - TIME_FILTER_MAP, -} from 'src/explore/constants'; -import { DASHBOARD_FILTER_SCOPE_GLOBAL } from 'src/dashboard/reducers/dashboardFilters'; -import { Filter, NativeFilterType, TimeGranularity } from '@superset-ui/core'; -import { getChartIdsInFilterBoxScope } from './activeDashboardFilters'; -import getFilterConfigsFromFormdata from './getFilterConfigsFromFormdata'; - -interface FilterConfig { - asc: boolean; - clearable: boolean; - column: string; - defaultValue?: any; - key: string; - label?: string; - metric: string; - multiple: boolean; -} - -interface SliceData { - slice_id: number; - form_data: { - adhoc_filters?: []; - datasource: string; - date_filter?: boolean; - filter_configs?: FilterConfig[]; - granularity?: string; - granularity_sqla?: string; - time_grain_sqla?: string; - time_range?: string; - show_sqla_time_column?: boolean; - show_sqla_time_granularity?: boolean; - viz_type: string; - }; -} - -interface FilterScopeType { - scope: string[]; - immune: number[]; -} - -interface FilterScopesMetadata { - [key: string]: { - [key: string]: FilterScopeType; - }; -} - -interface PreselectedFilterColumn { - [key: string]: boolean | string | number | string[] | number[]; -} - -interface PreselectedFiltersMetadata { - [key: string]: PreselectedFilterColumn; -} - -interface FilterBoxToFilterComponentMap { - [key: string]: { - [key: string]: string; - }; -} - -interface FilterBoxDependencyMap { - [key: string]: { - [key: string]: number[]; - }; -} - -enum FILTER_COMPONENT_FILTER_TYPES { - FILTER_TIME = 'filter_time', - FILTER_TIMEGRAIN = 'filter_timegrain', - FILTER_TIMECOLUMN = 'filter_timecolumn', - FILTER_SELECT = 'filter_select', - FILTER_RANGE = 'filter_range', -} - -const getPreselectedValuesFromDashboard = - (preselectedFilters: PreselectedFiltersMetadata) => - (filterKey: string, column: string) => { - if (preselectedFilters[filterKey]?.[column]) { - // overwrite default values by dashboard default_filters - return preselectedFilters[filterKey][column]; - } - return null; - }; - -const getFilterBoxDefaultValues = (config: FilterConfig) => { - let defaultValues = config[FILTER_CONFIG_ATTRIBUTES.DEFAULT_VALUE]; - - // treat empty string as null (no default value) - if (defaultValues === '') { - defaultValues = null; - } - - // defaultValue could be ; separated values, - // could be null or '' - if (defaultValues && config[FILTER_CONFIG_ATTRIBUTES.MULTIPLE]) { - defaultValues = config.defaultValue.split(';'); - } - - return defaultValues; -}; - -const setValuesInArray = (value1: any, value2: any) => { - if (!isEmpty(value1)) { - return [value1]; - } - if (!isEmpty(value2)) { - return [value2]; - } - return []; -}; - -const getFilterboxDependencies = (filterScopes: FilterScopesMetadata) => { - const filterFieldsDependencies: FilterBoxDependencyMap = {}; - const filterChartIds: number[] = Object.keys(filterScopes).map(key => - parseInt(key, 10), - ); - Object.entries(filterScopes).forEach(([key, filterFields]) => { - filterFieldsDependencies[key] = {}; - Object.entries(filterFields).forEach(([filterField, filterScope]) => { - filterFieldsDependencies[key][filterField] = getChartIdsInFilterBoxScope({ - filterScope, - }).filter( - chartId => filterChartIds.includes(chartId) && String(chartId) !== key, - ); - }); - }); - return filterFieldsDependencies; -}; - -export default function getNativeFilterConfig( - chartData: SliceData[] = [], - filterScopes: FilterScopesMetadata = {}, - preselectFilters: PreselectedFiltersMetadata = {}, -): Filter[] { - const filterConfig: Filter[] = []; - const filterBoxToFilterComponentMap: FilterBoxToFilterComponentMap = {}; - - chartData.forEach(slice => { - const key = String(slice.slice_id); - - if (slice.form_data.viz_type === 'filter_box') { - filterBoxToFilterComponentMap[key] = {}; - const configs = getFilterConfigsFromFormdata(slice.form_data); - let { columns } = configs; - if (preselectFilters[key]) { - Object.keys(columns).forEach(col => { - if (preselectFilters[key][col]) { - columns = { - ...columns, - [col]: preselectFilters[key][col], - }; - } - }); - } - - const scopesByChartId = Object.keys(columns).reduce((map, column) => { - const scopeSettings = { - ...filterScopes[key], - }; - const { scope, immune }: FilterScopeType = { - ...DASHBOARD_FILTER_SCOPE_GLOBAL, - ...scopeSettings[column], - }; - - return { - ...map, - [column]: { - scope, - immune, - }, - }; - }, {}); - - const { - adhoc_filters = [], - datasource = '', - date_filter = false, - filter_configs = [], - granularity_sqla, - show_sqla_time_column = false, - show_sqla_time_granularity = false, - time_grain_sqla, - time_range, - } = slice.form_data; - - const getDashboardDefaultValues = - getPreselectedValuesFromDashboard(preselectFilters); - - if (date_filter) { - const { scope, immune }: FilterScopeType = - scopesByChartId[TIME_FILTER_MAP.time_range] || - DASHBOARD_FILTER_SCOPE_GLOBAL; - const timeRangeFilter: Filter = { - id: `NATIVE_FILTER-${shortid.generate()}`, - description: 'time range filter', - controlValues: {}, - name: TIME_FILTER_LABELS.time_range, - filterType: FILTER_COMPONENT_FILTER_TYPES.FILTER_TIME, - targets: [{}], - cascadeParentIds: [], - defaultDataMask: {}, - type: NativeFilterType.NATIVE_FILTER, - scope: { - rootPath: scope, - excluded: immune, - }, - }; - filterBoxToFilterComponentMap[key][TIME_FILTER_MAP.time_range] = - timeRangeFilter.id; - const dashboardDefaultValues = - getDashboardDefaultValues(key, TIME_FILTER_MAP.time_range) || - time_range; - if (!isEmpty(dashboardDefaultValues)) { - timeRangeFilter.defaultDataMask = { - extraFormData: { time_range: dashboardDefaultValues as string }, - filterState: { value: dashboardDefaultValues }, - }; - } - filterConfig.push(timeRangeFilter); - - if (show_sqla_time_granularity) { - const { scope, immune }: FilterScopeType = - scopesByChartId[TIME_FILTER_MAP.time_grain_sqla] || - DASHBOARD_FILTER_SCOPE_GLOBAL; - const timeGrainFilter: Filter = { - id: `NATIVE_FILTER-${shortid.generate()}`, - controlValues: {}, - description: 'time grain filter', - name: TIME_FILTER_LABELS.time_grain_sqla, - filterType: FILTER_COMPONENT_FILTER_TYPES.FILTER_TIMEGRAIN, - targets: [ - { - datasetId: parseInt(datasource.split('__')[0], 10), - }, - ], - cascadeParentIds: [], - defaultDataMask: {}, - type: NativeFilterType.NATIVE_FILTER, - scope: { - rootPath: scope, - excluded: immune, - }, - }; - filterBoxToFilterComponentMap[key][TIME_FILTER_MAP.time_grain_sqla] = - timeGrainFilter.id; - const dashboardDefaultValues = getDashboardDefaultValues( - key, - TIME_FILTER_MAP.time_grain_sqla, - ); - if (!isEmpty(dashboardDefaultValues)) { - timeGrainFilter.defaultDataMask = { - extraFormData: { - time_grain_sqla: (dashboardDefaultValues || - time_grain_sqla) as TimeGranularity, - }, - filterState: { - value: setValuesInArray( - dashboardDefaultValues, - time_grain_sqla, - ), - }, - }; - } - filterConfig.push(timeGrainFilter); - } - - if (show_sqla_time_column) { - const { scope, immune }: FilterScopeType = - scopesByChartId[TIME_FILTER_MAP.granularity_sqla] || - DASHBOARD_FILTER_SCOPE_GLOBAL; - const timeColumnFilter: Filter = { - id: `NATIVE_FILTER-${shortid.generate()}`, - description: 'time column filter', - controlValues: {}, - name: TIME_FILTER_LABELS.granularity_sqla, - filterType: FILTER_COMPONENT_FILTER_TYPES.FILTER_TIMECOLUMN, - targets: [ - { - datasetId: parseInt(datasource.split('__')[0], 10), - }, - ], - cascadeParentIds: [], - defaultDataMask: {}, - type: NativeFilterType.NATIVE_FILTER, - scope: { - rootPath: scope, - excluded: immune, - }, - }; - filterBoxToFilterComponentMap[key][TIME_FILTER_MAP.granularity_sqla] = - timeColumnFilter.id; - const dashboardDefaultValues = getDashboardDefaultValues( - key, - TIME_FILTER_MAP.granularity_sqla, - ); - if (!isEmpty(dashboardDefaultValues)) { - timeColumnFilter.defaultDataMask = { - extraFormData: { - granularity_sqla: (dashboardDefaultValues || - granularity_sqla) as string, - }, - filterState: { - value: setValuesInArray( - dashboardDefaultValues, - granularity_sqla, - ), - }, - }; - } - filterConfig.push(timeColumnFilter); - } - } - - filter_configs.forEach(config => { - const { scope, immune }: FilterScopeType = - scopesByChartId[config.column] || DASHBOARD_FILTER_SCOPE_GLOBAL; - const entry: Filter = { - id: `NATIVE_FILTER-${shortid.generate()}`, - description: '', - controlValues: { - enableEmptyFilter: !config[FILTER_CONFIG_ATTRIBUTES.CLEARABLE], - defaultToFirstItem: false, - inverseSelection: false, - multiSelect: config[FILTER_CONFIG_ATTRIBUTES.MULTIPLE], - sortAscending: config[FILTER_CONFIG_ATTRIBUTES.SORT_ASCENDING], - }, - name: config.label || config.column, - filterType: FILTER_COMPONENT_FILTER_TYPES.FILTER_SELECT, - targets: [ - { - datasetId: parseInt(datasource.split('__')[0], 10), - column: { - name: config.column, - }, - }, - ], - cascadeParentIds: [], - defaultDataMask: {}, - type: NativeFilterType.NATIVE_FILTER, - scope: { - rootPath: scope, - excluded: immune, - }, - adhoc_filters, - sortMetric: config[FILTER_CONFIG_ATTRIBUTES.SORT_METRIC], - time_range, - }; - filterBoxToFilterComponentMap[key][config.column] = entry.id; - const defaultValues = - getDashboardDefaultValues(key, config.column) || - getFilterBoxDefaultValues(config); - if (!isEmpty(defaultValues)) { - entry.defaultDataMask = { - extraFormData: { - filters: [{ col: config.column, op: 'IN', val: defaultValues }], - }, - filterState: { value: defaultValues }, - }; - } - filterConfig.push(entry); - }); - } - }); - - const dependencies: FilterBoxDependencyMap = - getFilterboxDependencies(filterScopes); - Object.entries(dependencies).forEach(([key, filterFields]) => { - Object.entries(filterFields).forEach(([field, childrenChartIds]) => { - const parentComponentId = filterBoxToFilterComponentMap[key][field]; - childrenChartIds.forEach(childrenChartId => { - const childComponentIds = Object.values( - filterBoxToFilterComponentMap[childrenChartId], - ); - childComponentIds.forEach(childComponentId => { - const childComponent = find( - filterConfig, - ({ id }) => id === childComponentId, - ); - if ( - childComponent && - // time related filter components don't have parent - [ - FILTER_COMPONENT_FILTER_TYPES.FILTER_SELECT, - FILTER_COMPONENT_FILTER_TYPES.FILTER_RANGE, - ].includes( - childComponent.filterType as FILTER_COMPONENT_FILTER_TYPES, - ) - ) { - childComponent.cascadeParentIds = - childComponent.cascadeParentIds || []; - childComponent.cascadeParentIds.push(parentComponentId); - } - }); - }); - }); - }); - - return filterConfig; -} diff --git a/superset-frontend/src/explore/constants.ts b/superset-frontend/src/explore/constants.ts index cd038dac20ca3..58c90cfba37a6 100644 --- a/superset-frontend/src/explore/constants.ts +++ b/superset-frontend/src/explore/constants.ts @@ -156,16 +156,6 @@ export const TIME_FILTER_MAP = { granularity: '__granularity', }; -export enum FILTER_BOX_MIGRATION_STATES { - CONVERTED = 'CONVERTED', - NOOP = 'NOOP', - REVIEWING = 'REVIEWING', - SNOOZED = 'SNOOZED', - UNDECIDED = 'UNDECIDED', -} - -export const FILTER_BOX_TRANSITION_SNOOZE_DURATION = 24 * 60 * 60 * 1000; // 24 hours - export const POPOVER_INITIAL_HEIGHT = 240; export const POPOVER_INITIAL_WIDTH = 320; export const UNRESIZABLE_POPOVER_WIDTH = 296; diff --git a/superset/config.py b/superset/config.py index 5a0aea77fbee5..5489d5f67dbfe 100644 --- a/superset/config.py +++ b/superset/config.py @@ -444,7 +444,6 @@ def _try_json_readsha(filepath: str, length: int) -> Optional[str]: "ALERT_REPORTS": False, "DASHBOARD_RBAC": False, "ENABLE_EXPLORE_DRAG_AND_DROP": True, - "ENABLE_FILTER_BOX_MIGRATION": False, "ENABLE_ADVANCED_DATA_TYPES": False, "ENABLE_DND_WITH_CLICK_UX": True, # Enabling ALERTS_ATTACH_REPORTS, the system sends email and slack message diff --git a/superset/views/dashboard/views.py b/superset/views/dashboard/views.py index 52cb2da82e911..4f122067719c2 100644 --- a/superset/views/dashboard/views.py +++ b/superset/views/dashboard/views.py @@ -114,17 +114,9 @@ class Dashboard(BaseSupersetView): @expose("/new/") def new(self) -> FlaskResponse: # pylint: disable=no-self-use """Creates a new, blank dashboard and redirects to it in edit mode""" - metadata = {} - if is_feature_enabled("ENABLE_FILTER_BOX_MIGRATION"): - metadata = { - "native_filter_configuration": [], - "show_native_filters": True, - } - new_dashboard = DashboardModel( dashboard_title="[ untitled dashboard ]", owners=[g.user], - json_metadata=json.dumps(metadata, sort_keys=True), ) db.session.add(new_dashboard) db.session.commit()