mirror of https://github.com/apache/superset.git
refactor: Removes the deprecated DASHBOARD_NATIVE_FILTERS feature flag (#26329)
This commit is contained in:
parent
3acda145f1
commit
69b57016b3
|
@ -84,7 +84,6 @@ These features flags currently default to True and **will be removed in a future
|
|||
[//]: # "PLEASE KEEP THE LIST SORTED ALPHABETICALLY"
|
||||
|
||||
- DASHBOARD_CROSS_FILTERS
|
||||
- DASHBOARD_NATIVE_FILTERS
|
||||
- ENABLE_JAVASCRIPT_CONTROLS
|
||||
- GENERIC_CHART_AXES
|
||||
- KV_STORE
|
||||
|
|
|
@ -43,6 +43,7 @@ assists people when migrating to a new version.
|
|||
- [26637](https://github.com/apache/superset/issues/26637): Sets the `DRILL_BY` feature flag to `True` by default given that the feature has been tested for a while and reached a stable state.
|
||||
- [26462](https://github.com/apache/superset/issues/26462): Removes the Profile feature given that it's not actively maintained and not widely used.
|
||||
- [26377](https://github.com/apache/superset/pull/26377): Removes the deprecated Redirect API that supported short URLs used before the permalink feature.
|
||||
- [26329](https://github.com/apache/superset/issues/26329): Removes the deprecated `DASHBOARD_NATIVE_FILTERS` feature flag. The previous value of the feature flag was `True` and now the feature is permanently enabled.
|
||||
|
||||
### Potential Downtime
|
||||
|
||||
|
|
|
@ -29,7 +29,6 @@ export enum FeatureFlag {
|
|||
CONFIRM_DASHBOARD_DIFF = 'CONFIRM_DASHBOARD_DIFF',
|
||||
/** @deprecated */
|
||||
DASHBOARD_CROSS_FILTERS = 'DASHBOARD_CROSS_FILTERS',
|
||||
DASHBOARD_NATIVE_FILTERS = 'DASHBOARD_NATIVE_FILTERS',
|
||||
DASHBOARD_VIRTUALIZATION = 'DASHBOARD_VIRTUALIZATION',
|
||||
DASHBOARD_RBAC = 'DASHBOARD_RBAC',
|
||||
DATAPANEL_CLOSED_BY_DEFAULT = 'DATAPANEL_CLOSED_BY_DEFAULT',
|
||||
|
|
|
@ -21,26 +21,22 @@ import {
|
|||
ControlSetItem,
|
||||
ControlSetRow,
|
||||
} from '@superset-ui/chart-controls';
|
||||
import { FeatureFlag, isFeatureEnabled, t } from '@superset-ui/core';
|
||||
import { t } from '@superset-ui/core';
|
||||
import { PAGE_SIZE_OPTIONS } from '../../consts';
|
||||
|
||||
export const serverPaginationControlSetRow: ControlSetRow =
|
||||
isFeatureEnabled(FeatureFlag.DASHBOARD_CROSS_FILTERS) ||
|
||||
isFeatureEnabled(FeatureFlag.DASHBOARD_NATIVE_FILTERS)
|
||||
? [
|
||||
{
|
||||
name: 'server_pagination',
|
||||
config: {
|
||||
type: 'CheckboxControl',
|
||||
label: t('Server pagination'),
|
||||
description: t(
|
||||
'Enable server side pagination of results (experimental feature)',
|
||||
),
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
]
|
||||
: [];
|
||||
export const serverPaginationControlSetRow: ControlSetRow = [
|
||||
{
|
||||
name: 'server_pagination',
|
||||
config: {
|
||||
type: 'CheckboxControl',
|
||||
label: t('Server pagination'),
|
||||
description: t(
|
||||
'Enable server side pagination of results (experimental feature)',
|
||||
),
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
export const serverPageLengthControlSetItem: ControlSetItem = {
|
||||
name: 'server_page_length',
|
||||
|
|
|
@ -21,11 +21,9 @@ import React from 'react';
|
|||
import {
|
||||
ChartDataResponseResult,
|
||||
ensureIsArray,
|
||||
FeatureFlag,
|
||||
GenericDataType,
|
||||
hasGenericChartAxes,
|
||||
isAdhocColumn,
|
||||
isFeatureEnabled,
|
||||
isPhysicalColumn,
|
||||
QueryFormColumn,
|
||||
QueryMode,
|
||||
|
@ -290,22 +288,19 @@ const config: ControlPanelConfig = {
|
|||
},
|
||||
},
|
||||
],
|
||||
isFeatureEnabled(FeatureFlag.DASHBOARD_CROSS_FILTERS) ||
|
||||
isFeatureEnabled(FeatureFlag.DASHBOARD_NATIVE_FILTERS)
|
||||
? [
|
||||
{
|
||||
name: 'server_pagination',
|
||||
config: {
|
||||
type: 'CheckboxControl',
|
||||
label: t('Server pagination'),
|
||||
description: t(
|
||||
'Enable server side pagination of results (experimental feature)',
|
||||
),
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
]
|
||||
: [],
|
||||
[
|
||||
{
|
||||
name: 'server_pagination',
|
||||
config: {
|
||||
type: 'CheckboxControl',
|
||||
label: t('Server pagination'),
|
||||
description: t(
|
||||
'Enable server side pagination of results (experimental feature)',
|
||||
),
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
name: 'row_limit',
|
||||
|
|
|
@ -20,7 +20,6 @@ import React from 'react';
|
|||
import fetchMock from 'fetch-mock';
|
||||
import { render } from 'spec/helpers/testing-library';
|
||||
import { fireEvent, within } from '@testing-library/react';
|
||||
import * as uiCore from '@superset-ui/core';
|
||||
import DashboardBuilder from 'src/dashboard/components/DashboardBuilder/DashboardBuilder';
|
||||
import useStoredSidebarWidth from 'src/components/ResizableSidebar/useStoredSidebarWidth';
|
||||
import {
|
||||
|
@ -247,35 +246,20 @@ describe('DashboardBuilder', () => {
|
|||
expect(await findByAltText('Loading...')).toBeVisible();
|
||||
});
|
||||
|
||||
describe('when nativeFiltersEnabled', () => {
|
||||
let isFeatureEnabledMock: jest.MockInstance<boolean, [string]>;
|
||||
beforeAll(() => {
|
||||
isFeatureEnabledMock = jest
|
||||
.spyOn(uiCore, 'isFeatureEnabled')
|
||||
.mockImplementation(
|
||||
flag => flag === uiCore.FeatureFlag.DASHBOARD_NATIVE_FILTERS,
|
||||
);
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
isFeatureEnabledMock.mockRestore();
|
||||
});
|
||||
|
||||
it('should set FilterBar width by useStoredSidebarWidth', () => {
|
||||
const expectedValue = 200;
|
||||
const setter = jest.fn();
|
||||
(useStoredSidebarWidth as jest.Mock).mockImplementation(() => [
|
||||
expectedValue,
|
||||
setter,
|
||||
]);
|
||||
const { getByTestId } = setup({
|
||||
dashboardInfo: {
|
||||
...mockState.dashboardInfo,
|
||||
dash_edit_perm: true,
|
||||
},
|
||||
});
|
||||
const filterbar = getByTestId('dashboard-filters-panel');
|
||||
expect(filterbar).toHaveStyleRule('width', `${expectedValue}px`);
|
||||
it('should set FilterBar width by useStoredSidebarWidth', () => {
|
||||
const expectedValue = 200;
|
||||
const setter = jest.fn();
|
||||
(useStoredSidebarWidth as jest.Mock).mockImplementation(() => [
|
||||
expectedValue,
|
||||
setter,
|
||||
]);
|
||||
const { getByTestId } = setup({
|
||||
dashboardInfo: {
|
||||
...mockState.dashboardInfo,
|
||||
dash_edit_perm: true,
|
||||
},
|
||||
});
|
||||
const filterbar = getByTestId('dashboard-filters-panel');
|
||||
expect(filterbar).toHaveStyleRule('width', `${expectedValue}px`);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -21,11 +21,9 @@
|
|||
import React, { FC, useCallback, useEffect, useMemo, useRef } from 'react';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import {
|
||||
FeatureFlag,
|
||||
Filter,
|
||||
Filters,
|
||||
getCategoricalSchemeRegistry,
|
||||
isFeatureEnabled,
|
||||
SupersetClient,
|
||||
useComponentDidUpdate,
|
||||
} from '@superset-ui/core';
|
||||
|
@ -104,10 +102,7 @@ const DashboardContainer: FC<DashboardContainerProps> = ({ topLevelTabs }) => {
|
|||
}, [dashboardLayout, directPathToChild]);
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
!isFeatureEnabled(FeatureFlag.DASHBOARD_NATIVE_FILTERS) ||
|
||||
nativeFilterScopes.length === 0
|
||||
) {
|
||||
if (nativeFilterScopes.length === 0) {
|
||||
return;
|
||||
}
|
||||
const scopes = nativeFilterScopes.map(filterScope => {
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
* under the License.
|
||||
*/
|
||||
import { useSelector } from 'react-redux';
|
||||
import { isFeatureEnabled, FeatureFlag } from '@superset-ui/core';
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import { URL_PARAMS } from 'src/constants';
|
||||
import { getUrlParam } from 'src/utils/urlUtils';
|
||||
|
@ -42,8 +41,7 @@ export const useNativeFilters = () => {
|
|||
);
|
||||
|
||||
const nativeFiltersEnabled =
|
||||
isFeatureEnabled(FeatureFlag.DASHBOARD_NATIVE_FILTERS) &&
|
||||
(canEdit || (!canEdit && filterValues.length !== 0));
|
||||
canEdit || (!canEdit && filterValues.length !== 0);
|
||||
|
||||
const requiredFirstFilter = filterValues.filter(
|
||||
filter => filter.requiredFirst,
|
||||
|
|
|
@ -133,10 +133,6 @@ describe('FiltersBadge', () => {
|
|||
});
|
||||
|
||||
it('shows the indicator when filters have been applied', () => {
|
||||
// @ts-ignore
|
||||
global.featureFlags = {
|
||||
[SupersetUI.FeatureFlag.DASHBOARD_NATIVE_FILTERS]: true,
|
||||
};
|
||||
const store = getMockStoreWithNativeFilters();
|
||||
// start with basic dashboard state, dispatch an event to simulate query completion
|
||||
store.dispatch({
|
||||
|
|
|
@ -24,12 +24,8 @@ import userEvent from '@testing-library/user-event';
|
|||
import fetchMock from 'fetch-mock';
|
||||
import { HeaderDropdownProps } from 'src/dashboard/components/Header/types';
|
||||
import injectCustomCss from 'src/dashboard/util/injectCustomCss';
|
||||
import { FeatureFlag } from '@superset-ui/core';
|
||||
import * as uiCore from '@superset-ui/core';
|
||||
import HeaderActionsDropdown from '.';
|
||||
|
||||
let isFeatureEnabledMock: jest.MockInstance<boolean, [feature: FeatureFlag]>;
|
||||
|
||||
const createProps = () => ({
|
||||
addSuccessToast: jest.fn(),
|
||||
addDangerToast: jest.fn(),
|
||||
|
@ -135,7 +131,7 @@ test('should render the menu items', async () => {
|
|||
|
||||
test('should render the menu items in edit mode', async () => {
|
||||
setup(editModeOnProps);
|
||||
expect(screen.getAllByRole('menuitem')).toHaveLength(5);
|
||||
expect(screen.getAllByRole('menuitem')).toHaveLength(4);
|
||||
expect(screen.getByText('Set auto-refresh interval')).toBeInTheDocument();
|
||||
expect(screen.getByText('Edit properties')).toBeInTheDocument();
|
||||
expect(screen.getByText('Edit CSS')).toBeInTheDocument();
|
||||
|
@ -150,56 +146,14 @@ test('should render the menu items in Embedded mode', async () => {
|
|||
expect(screen.getByText('Set auto-refresh interval')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
describe('with native filters feature flag disabled', () => {
|
||||
beforeAll(() => {
|
||||
isFeatureEnabledMock = jest
|
||||
.spyOn(uiCore, 'isFeatureEnabled')
|
||||
.mockImplementation(
|
||||
(featureFlag: FeatureFlag) =>
|
||||
featureFlag !== FeatureFlag.DASHBOARD_NATIVE_FILTERS,
|
||||
);
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
// @ts-ignore
|
||||
isFeatureEnabledMock.restore();
|
||||
});
|
||||
|
||||
it('should render filter mapping in edit mode if explicit filter scopes undefined', async () => {
|
||||
setup(editModeOnProps);
|
||||
expect(screen.getByText('Set filter mapping')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render filter mapping in edit mode if explicit filter scopes defined', async () => {
|
||||
setup(editModeOnWithFilterScopesProps);
|
||||
expect(screen.getByText('Set filter mapping')).toBeInTheDocument();
|
||||
});
|
||||
test('should not render filter mapping in edit mode if explicit filter scopes undefined', async () => {
|
||||
setup(editModeOnProps);
|
||||
expect(screen.queryByText('Set filter mapping')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
describe('with native filters feature flag enabled', () => {
|
||||
beforeAll(() => {
|
||||
isFeatureEnabledMock = jest
|
||||
.spyOn(uiCore, 'isFeatureEnabled')
|
||||
.mockImplementation(
|
||||
(featureFlag: FeatureFlag) =>
|
||||
featureFlag === FeatureFlag.DASHBOARD_NATIVE_FILTERS,
|
||||
);
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
// @ts-ignore
|
||||
isFeatureEnabledMock.restore();
|
||||
});
|
||||
|
||||
it('should not render filter mapping in edit mode if explicit filter scopes undefined', async () => {
|
||||
setup(editModeOnProps);
|
||||
expect(screen.queryByText('Set filter mapping')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render filter mapping in edit mode if explicit filter scopes defined', async () => {
|
||||
setup(editModeOnWithFilterScopesProps);
|
||||
expect(screen.getByText('Set filter mapping')).toBeInTheDocument();
|
||||
});
|
||||
test('should render filter mapping in edit mode if explicit filter scopes defined', async () => {
|
||||
setup(editModeOnWithFilterScopesProps);
|
||||
expect(screen.getByText('Set filter mapping')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('should show the share actions', async () => {
|
||||
|
|
|
@ -19,12 +19,7 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { isEmpty } from 'lodash';
|
||||
import {
|
||||
isFeatureEnabled,
|
||||
FeatureFlag,
|
||||
SupersetClient,
|
||||
t,
|
||||
} from '@superset-ui/core';
|
||||
import { SupersetClient, t } from '@superset-ui/core';
|
||||
import { Menu } from 'src/components/Menu';
|
||||
import { URL_PARAMS } from 'src/constants';
|
||||
import ShareMenuItems from 'src/dashboard/components/menu/ShareMenuItems';
|
||||
|
@ -361,18 +356,14 @@ class HeaderActionsDropdown extends React.PureComponent {
|
|||
</Menu>
|
||||
)
|
||||
) : null}
|
||||
{editMode &&
|
||||
!(
|
||||
isFeatureEnabled(FeatureFlag.DASHBOARD_NATIVE_FILTERS) &&
|
||||
isEmpty(dashboardInfo?.metadata?.filter_scopes)
|
||||
) && (
|
||||
<Menu.Item key={MENU_KEYS.SET_FILTER_MAPPING}>
|
||||
<FilterScopeModal
|
||||
className="m-r-5"
|
||||
triggerNode={t('Set filter mapping')}
|
||||
/>
|
||||
</Menu.Item>
|
||||
)}
|
||||
{editMode && !isEmpty(dashboardInfo?.metadata?.filter_scopes) && (
|
||||
<Menu.Item key={MENU_KEYS.SET_FILTER_MAPPING}>
|
||||
<FilterScopeModal
|
||||
className="m-r-5"
|
||||
triggerNode={t('Set filter mapping')}
|
||||
/>
|
||||
</Menu.Item>
|
||||
)}
|
||||
|
||||
<Menu.Item key={MENU_KEYS.AUTOREFRESH_MODAL}>
|
||||
<RefreshIntervalModal
|
||||
|
|
|
@ -23,7 +23,7 @@ import userEvent from '@testing-library/user-event';
|
|||
import { stateWithoutNativeFilters } from 'spec/fixtures/mockStore';
|
||||
import * as mockCore from '@superset-ui/core';
|
||||
import { testWithId } from 'src/utils/testUtils';
|
||||
import { FeatureFlag, Preset } from '@superset-ui/core';
|
||||
import { Preset } from '@superset-ui/core';
|
||||
import { TimeFilterPlugin, SelectFilterPlugin } from 'src/filters/components';
|
||||
import fetchMock from 'fetch-mock';
|
||||
import { FilterBarOrientation } from 'src/dashboard/types';
|
||||
|
@ -73,11 +73,6 @@ const getModalTestId = testWithId<string>(FILTERS_CONFIG_MODAL_TEST_ID, true);
|
|||
|
||||
const FILTER_NAME = 'Time filter 1';
|
||||
|
||||
// @ts-ignore
|
||||
global.featureFlags = {
|
||||
[FeatureFlag.DASHBOARD_NATIVE_FILTERS]: true,
|
||||
};
|
||||
|
||||
const addFilterFlow = async () => {
|
||||
// open filter config modal
|
||||
userEvent.click(screen.getByTestId(getTestId('collapsable')));
|
||||
|
@ -291,10 +286,6 @@ describe('FilterBar', () => {
|
|||
});
|
||||
|
||||
it('create filter and apply it flow', async () => {
|
||||
// @ts-ignore
|
||||
global.featureFlags = {
|
||||
[FeatureFlag.DASHBOARD_NATIVE_FILTERS]: true,
|
||||
};
|
||||
renderWrapper(openedBarProps, stateWithoutNativeFilters);
|
||||
expect(screen.getByTestId(getTestId('apply-button'))).toBeDisabled();
|
||||
|
||||
|
|
|
@ -212,23 +212,20 @@ const FilterControls: FC<FilterControlsProps> = ({
|
|||
selectedCrossFilters.at(-1),
|
||||
),
|
||||
}));
|
||||
if (isFeatureEnabled(FeatureFlag.DASHBOARD_NATIVE_FILTERS)) {
|
||||
const nativeFiltersInScope = filtersInScope.map((filter, index) => ({
|
||||
id: filter.id,
|
||||
element: (
|
||||
<div
|
||||
className="filter-item-wrapper"
|
||||
css={css`
|
||||
flex-shrink: 0;
|
||||
`}
|
||||
>
|
||||
{renderer(filter, index)}
|
||||
</div>
|
||||
),
|
||||
}));
|
||||
return [...crossFilters, ...nativeFiltersInScope];
|
||||
}
|
||||
return [...crossFilters];
|
||||
const nativeFiltersInScope = filtersInScope.map((filter, index) => ({
|
||||
id: filter.id,
|
||||
element: (
|
||||
<div
|
||||
className="filter-item-wrapper"
|
||||
css={css`
|
||||
flex-shrink: 0;
|
||||
`}
|
||||
>
|
||||
{renderer(filter, index)}
|
||||
</div>
|
||||
),
|
||||
}));
|
||||
return [...crossFilters, ...nativeFiltersInScope];
|
||||
}, [filtersInScope, renderer, rendererCrossFilter, selectedCrossFilters]);
|
||||
|
||||
const renderHorizontalContent = () => (
|
||||
|
|
|
@ -17,14 +17,7 @@
|
|||
* under the License.
|
||||
*/
|
||||
/* eslint-disable no-param-reassign */
|
||||
import {
|
||||
FeatureFlag,
|
||||
css,
|
||||
isFeatureEnabled,
|
||||
styled,
|
||||
t,
|
||||
useTheme,
|
||||
} from '@superset-ui/core';
|
||||
import { css, styled, t, useTheme } from '@superset-ui/core';
|
||||
import React, { FC, useMemo } from 'react';
|
||||
import Icons from 'src/components/Icons';
|
||||
import Button from 'src/components/Button';
|
||||
|
@ -124,7 +117,7 @@ const Header: FC<HeaderProps> = ({ toggleFiltersBar }) => {
|
|||
<Icons.Expand iconColor={theme.colors.grayscale.base} />
|
||||
</HeaderButton>
|
||||
</TitleArea>
|
||||
{canEdit && isFeatureEnabled(FeatureFlag.DASHBOARD_NATIVE_FILTERS) && (
|
||||
{canEdit && (
|
||||
<AddFiltersButtonContainer>
|
||||
<FilterConfigurationLink
|
||||
dashboardId={dashboardId}
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import React, { useMemo } from 'react';
|
||||
import React from 'react';
|
||||
import {
|
||||
DataMaskStateWithId,
|
||||
FeatureFlag,
|
||||
|
@ -129,12 +129,6 @@ const HorizontalFilterBar: React.FC<HorizontalBarProps> = ({
|
|||
: [];
|
||||
const hasFilters = filterValues.length > 0 || selectedCrossFilters.length > 0;
|
||||
|
||||
const actionsElement = useMemo(
|
||||
() =>
|
||||
isFeatureEnabled(FeatureFlag.DASHBOARD_NATIVE_FILTERS) ? actions : null,
|
||||
[actions],
|
||||
);
|
||||
|
||||
return (
|
||||
<HorizontalBar {...getFilterBarTestId()}>
|
||||
<HorizontalBarContent>
|
||||
|
@ -143,7 +137,7 @@ const HorizontalFilterBar: React.FC<HorizontalBarProps> = ({
|
|||
) : (
|
||||
<>
|
||||
<FilterBarSettings />
|
||||
{canEdit && isFeatureEnabled(FeatureFlag.DASHBOARD_NATIVE_FILTERS) && (
|
||||
{canEdit && (
|
||||
<FiltersLinkContainer hasFilters={hasFilters}>
|
||||
<FilterConfigurationLink
|
||||
dashboardId={dashboardId}
|
||||
|
@ -164,7 +158,7 @@ const HorizontalFilterBar: React.FC<HorizontalBarProps> = ({
|
|||
onFilterSelectionChange={onSelectionChange}
|
||||
/>
|
||||
)}
|
||||
{actionsElement}
|
||||
{actions}
|
||||
</>
|
||||
)}
|
||||
</HorizontalBarContent>
|
||||
|
|
|
@ -16,8 +16,7 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import { FeatureFlag, NativeFilterType } from '@superset-ui/core';
|
||||
import { NativeFilterType } from '@superset-ui/core';
|
||||
import React from 'react';
|
||||
import { render, screen, waitFor } from 'spec/helpers/testing-library';
|
||||
import HorizontalBar from './Horizontal';
|
||||
|
@ -32,11 +31,6 @@ const defaultProps = {
|
|||
onSelectionChange: jest.fn(),
|
||||
};
|
||||
|
||||
// @ts-ignore
|
||||
global.featureFlags = {
|
||||
[FeatureFlag.DASHBOARD_NATIVE_FILTERS]: true,
|
||||
};
|
||||
|
||||
const renderWrapper = (overrideProps?: Record<string, any>) =>
|
||||
waitFor(() =>
|
||||
render(<HorizontalBar {...defaultProps} {...overrideProps} />, {
|
||||
|
|
|
@ -196,12 +196,6 @@ const VerticalFilterBar: React.FC<VerticalBarProps> = ({
|
|||
[],
|
||||
);
|
||||
|
||||
const actionsElement = useMemo(
|
||||
() =>
|
||||
isFeatureEnabled(FeatureFlag.DASHBOARD_NATIVE_FILTERS) ? actions : null,
|
||||
[actions],
|
||||
);
|
||||
|
||||
return (
|
||||
<FilterBarScrollContext.Provider value={isScrolling}>
|
||||
<BarWrapper
|
||||
|
@ -234,12 +228,11 @@ const VerticalFilterBar: React.FC<VerticalBarProps> = ({
|
|||
<div css={tabPaneStyle} onScroll={onScroll}>
|
||||
<>
|
||||
{crossFilters}
|
||||
{isFeatureEnabled(FeatureFlag.DASHBOARD_NATIVE_FILTERS) &&
|
||||
filterControls}
|
||||
{filterControls}
|
||||
</>
|
||||
</div>
|
||||
)}
|
||||
{actionsElement}
|
||||
{actions}
|
||||
</Bar>
|
||||
</BarWrapper>
|
||||
</FilterBarScrollContext.Provider>
|
||||
|
|
|
@ -358,34 +358,31 @@ export const selectNativeIndicatorsForChart = (
|
|||
return cachedNativeIndicatorsForChart[chartId];
|
||||
}
|
||||
|
||||
let nativeFilterIndicators: any = [];
|
||||
if (isFeatureEnabled(FeatureFlag.DASHBOARD_NATIVE_FILTERS)) {
|
||||
nativeFilterIndicators =
|
||||
nativeFilters &&
|
||||
Object.values(nativeFilters)
|
||||
.filter(
|
||||
nativeFilter =>
|
||||
nativeFilter.type === NativeFilterType.NATIVE_FILTER &&
|
||||
nativeFilter.chartsInScope?.includes(chartId),
|
||||
)
|
||||
.map(nativeFilter => {
|
||||
const column = nativeFilter.targets?.[0]?.column?.name;
|
||||
const filterState = dataMask[nativeFilter.id]?.filterState;
|
||||
const label = extractLabel(filterState);
|
||||
return {
|
||||
const nativeFilterIndicators =
|
||||
nativeFilters &&
|
||||
Object.values(nativeFilters)
|
||||
.filter(
|
||||
nativeFilter =>
|
||||
nativeFilter.type === NativeFilterType.NATIVE_FILTER &&
|
||||
nativeFilter.chartsInScope?.includes(chartId),
|
||||
)
|
||||
.map(nativeFilter => {
|
||||
const column = nativeFilter.targets?.[0]?.column?.name;
|
||||
const filterState = dataMask[nativeFilter.id]?.filterState;
|
||||
const label = extractLabel(filterState);
|
||||
return {
|
||||
column,
|
||||
name: nativeFilter.name,
|
||||
path: [nativeFilter.id],
|
||||
status: getStatus({
|
||||
label,
|
||||
column,
|
||||
name: nativeFilter.name,
|
||||
path: [nativeFilter.id],
|
||||
status: getStatus({
|
||||
label,
|
||||
column,
|
||||
rejectedColumns,
|
||||
appliedColumns,
|
||||
}),
|
||||
value: label,
|
||||
};
|
||||
});
|
||||
}
|
||||
rejectedColumns,
|
||||
appliedColumns,
|
||||
}),
|
||||
value: label,
|
||||
};
|
||||
});
|
||||
|
||||
let crossFilterIndicators: any = [];
|
||||
if (isFeatureEnabled(FeatureFlag.DASHBOARD_CROSS_FILTERS)) {
|
||||
|
|
|
@ -55,41 +55,7 @@ describe('nativeFilterGate', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('with only native filters feature flag enabled', () => {
|
||||
beforeAll(() => {
|
||||
isFeatureEnabledMock = jest
|
||||
.spyOn(uiCore, 'isFeatureEnabled')
|
||||
.mockImplementation(
|
||||
(featureFlag: FeatureFlag) =>
|
||||
featureFlag === FeatureFlag.DASHBOARD_NATIVE_FILTERS,
|
||||
);
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
// @ts-ignore
|
||||
isFeatureEnabledMock.restore();
|
||||
});
|
||||
|
||||
it('should return true for regular chart', () => {
|
||||
expect(nativeFilterGate([])).toEqual(true);
|
||||
});
|
||||
|
||||
it('should return true for cross filter chart', () => {
|
||||
expect(nativeFilterGate([Behavior.INTERACTIVE_CHART])).toEqual(true);
|
||||
});
|
||||
|
||||
it('should return false for native filter chart with cross filter support', () => {
|
||||
expect(
|
||||
nativeFilterGate([Behavior.NATIVE_FILTER, Behavior.INTERACTIVE_CHART]),
|
||||
).toEqual(false);
|
||||
});
|
||||
|
||||
it('should return false for native filter behavior', () => {
|
||||
expect(nativeFilterGate([Behavior.NATIVE_FILTER])).toEqual(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('with native filters and experimental feature flag enabled', () => {
|
||||
describe('with cross filters and experimental feature flag enabled', () => {
|
||||
beforeAll(() => {
|
||||
isFeatureEnabledMock = jest
|
||||
.spyOn(uiCore, 'isFeatureEnabled')
|
||||
|
|
|
@ -16,13 +16,7 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import {
|
||||
DataMask,
|
||||
isFeatureEnabled,
|
||||
FeatureFlag,
|
||||
FilterConfiguration,
|
||||
Filters,
|
||||
} from '@superset-ui/core';
|
||||
import { DataMask, FilterConfiguration, Filters } from '@superset-ui/core';
|
||||
import { getInitialDataMask } from './reducer';
|
||||
|
||||
export const CLEAR_DATA_MASK_STATE = 'CLEAR_DATA_MASK_STATE';
|
||||
|
@ -73,14 +67,10 @@ export function updateDataMask(
|
|||
filterId: string | number,
|
||||
dataMask: DataMask,
|
||||
): UpdateDataMask {
|
||||
// Only apply data mask if one of the relevant features is enabled
|
||||
const isFeatureFlagActive =
|
||||
isFeatureEnabled(FeatureFlag.DASHBOARD_NATIVE_FILTERS) ||
|
||||
isFeatureEnabled(FeatureFlag.DASHBOARD_CROSS_FILTERS);
|
||||
return {
|
||||
type: UPDATE_DATA_MASK,
|
||||
filterId,
|
||||
dataMask: isFeatureFlagActive ? dataMask : {},
|
||||
dataMask,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -428,7 +428,6 @@ DEFAULT_FEATURE_FLAGS: dict[str, bool] = {
|
|||
"LISTVIEWS_DEFAULT_CARD_VIEW": False,
|
||||
# When True, this escapes HTML (rather than rendering it) in Markdown components
|
||||
"ESCAPE_MARKDOWN_HTML": False,
|
||||
"DASHBOARD_NATIVE_FILTERS": True, # deprecated
|
||||
"DASHBOARD_CROSS_FILTERS": True, # deprecated
|
||||
"DASHBOARD_VIRTUALIZATION": True,
|
||||
"GLOBAL_ASYNC_QUERIES": False,
|
||||
|
|
|
@ -69,7 +69,6 @@ FEATURE_FLAGS = {
|
|||
"SHARE_QUERIES_VIA_KV_STORE": True,
|
||||
"ENABLE_TEMPLATE_PROCESSING": True,
|
||||
"ALERT_REPORTS": True,
|
||||
"DASHBOARD_NATIVE_FILTERS": True,
|
||||
"DRILL_TO_DETAIL": True,
|
||||
"DRILL_BY": True,
|
||||
"HORIZONTAL_FILTER_BAR": True,
|
||||
|
|
Loading…
Reference in New Issue