diff --git a/superset-frontend/src/dashboard/actions/hydrate.js b/superset-frontend/src/dashboard/actions/hydrate.js index 0206d91f73f..9e4e2b05191 100644 --- a/superset-frontend/src/dashboard/actions/hydrate.js +++ b/superset-frontend/src/dashboard/actions/hydrate.js @@ -302,6 +302,13 @@ export const hydrateDashboard = (dashboardData, chartData, datasourcesData) => ( filterSetsConfig: metadata?.filter_sets_configuration || [], }); + if (!metadata) { + metadata = {}; + } + + metadata.show_native_filters = + dashboardData?.metadata?.show_native_filters ?? true; + if (isFeatureEnabled(FeatureFlag.DASHBOARD_CROSS_FILTERS)) { // If user just added cross filter to dashboard it's not saving it scope on server, // so we tweak it until user will update scope and will save it in server @@ -314,10 +321,6 @@ export const hydrateDashboard = (dashboardData, chartData, datasourcesData) => ( ) ?? {} )?.behaviors ?? []; - if (!metadata) { - metadata = {}; - } - if (!metadata.chart_configuration) { metadata.chart_configuration = {}; } diff --git a/superset-frontend/src/dashboard/components/DashboardBuilder/DashboardBuilder.tsx b/superset-frontend/src/dashboard/components/DashboardBuilder/DashboardBuilder.tsx index 463a7700fd2..23b332ef1f1 100644 --- a/superset-frontend/src/dashboard/components/DashboardBuilder/DashboardBuilder.tsx +++ b/superset-frontend/src/dashboard/components/DashboardBuilder/DashboardBuilder.tsx @@ -102,6 +102,12 @@ const DashboardBuilder: FC = () => { const dashboardLayout = useSelector( state => state.dashboardLayout.present, ); + const showNativeFilters = useSelector( + state => state.dashboardInfo.metadata?.show_native_filters, + ); + const canEdit = useSelector( + ({ dashboardInfo }) => dashboardInfo.dash_edit_perm, + ); const editMode = useSelector( state => state.dashboardState.editMode, ); @@ -112,9 +118,10 @@ const DashboardBuilder: FC = () => { const filters = useFilters(); const filterValues = Object.values(filters); - const nativeFiltersEnabled = isFeatureEnabled( - FeatureFlag.DASHBOARD_NATIVE_FILTERS, - ); + const nativeFiltersEnabled = + showNativeFilters && + isFeatureEnabled(FeatureFlag.DASHBOARD_NATIVE_FILTERS) && + (canEdit || (!canEdit && filterValues.length !== 0)); const [dashboardFiltersOpen, setDashboardFiltersOpen] = useState(true); diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/Header/index.tsx b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/Header/index.tsx index f9844a9ff7b..096e58b003b 100644 --- a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/Header/index.tsx +++ b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/Header/index.tsx @@ -28,6 +28,7 @@ import FilterConfigurationLink from 'src/dashboard/components/nativeFilters/Filt import { useFilters } from 'src/dashboard/components/nativeFilters/FilterBar/state'; import { Filter } from 'src/dashboard/components/nativeFilters/types'; import { getFilterBarTestId } from '..'; +import { RootState } from '../../../../types'; const TitleArea = styled.h4` display: flex; @@ -79,7 +80,7 @@ const Header: FC = ({ }) => { const filters = useFilters(); const filterValues = Object.values(filters); - const canEdit = useSelector( + const canEdit = useSelector( ({ dashboardInfo }) => dashboardInfo.dash_edit_perm, ); diff --git a/superset-frontend/src/dashboard/types.ts b/superset-frontend/src/dashboard/types.ts index 7731a7a344c..ddc5d8cf84d 100644 --- a/superset-frontend/src/dashboard/types.ts +++ b/superset-frontend/src/dashboard/types.ts @@ -44,6 +44,10 @@ export type Chart = { export type DashboardLayout = { [key: string]: LayoutItem }; export type DashboardLayoutState = { present: DashboardLayout }; export type DashboardState = { editMode: boolean; directPathToChild: string[] }; +export type DashboardInfo = { + dash_edit_perm: boolean; + metadata: { show_native_filters: boolean }; +}; /** Root state of redux */ export type RootState = { @@ -53,6 +57,7 @@ export type RootState = { dashboardLayout: DashboardLayoutState; dashboardFilters: {}; dashboardState: DashboardState; + dashboardInfo: DashboardInfo; dataMask: DataMaskStateWithId; dashboardInfo: JsonObject; impressionId: string; diff --git a/superset/dashboards/schemas.py b/superset/dashboards/schemas.py index 0d89c2cf390..629337322e5 100644 --- a/superset/dashboards/schemas.py +++ b/superset/dashboards/schemas.py @@ -106,6 +106,7 @@ def validate_json_metadata(value: Union[bytes, bytearray, str]) -> None: class DashboardJSONMetadataSchema(Schema): + show_native_filters = fields.Boolean() # native_filter_configuration is for dashboard-native filters native_filter_configuration = fields.List(fields.Dict(), allow_none=True) # chart_configuration for now keeps data about cross-filter scoping for charts