From b7ecb14230383da679a3f61e38faa33cdb5014f7 Mon Sep 17 00:00:00 2001
From: Ville Brofeldt <33317356+villebro@users.noreply.github.com>
Date: Wed, 23 Mar 2022 08:55:03 +0200
Subject: [PATCH] fix(dashboard): fix default filter bar visibility + add docs
(#18741)
* fix(dashboard): fix default filter tab visibility + add tests
* fix types
* lint
* rename docs + add double bang to length
---
.../creating-your-first-dashboard.mdx | 20 +++++++++++++++++++
.../src/components/UiConfigContext/index.tsx | 2 +-
superset-frontend/src/constants.ts | 4 ++++
.../components/DashboardBuilder/state.ts | 18 ++++++++++-------
.../nativeFilters/FilterBar/keyValue.tsx | 4 ++--
superset-frontend/src/utils/urlUtils.ts | 20 +++++++++++++------
6 files changed, 52 insertions(+), 16 deletions(-)
diff --git a/docs/docs/creating-charts-dashboards/creating-your-first-dashboard.mdx b/docs/docs/creating-charts-dashboards/creating-your-first-dashboard.mdx
index 074458111f..39400a1c29 100644
--- a/docs/docs/creating-charts-dashboards/creating-your-first-dashboard.mdx
+++ b/docs/docs/creating-charts-dashboards/creating-your-first-dashboard.mdx
@@ -189,3 +189,23 @@ all charts will load their data even if feature flag is turned on and no roles a
to roles the access will fallback to **Dataset permissions**
+
+### Customizing dashboard
+
+The following URL parameters can be used to modify how the dashboard is rendered:
+- `standalone`:
+ - `0` (default): dashboard is displayed normally
+ - `1`: Top Navigation is hidden
+ - `2`: Top Navigation + title is hidden
+ - `3`: Top Navigation + title + top level tabs are hidden
+- `show_filters`:
+ - `0`: render dashboard without Filter Bar
+ - `1` (default): render dashboard with Filter Bar if native filters are enabled
+- `expand_filters`:
+ - (default): render dashboard with Filter Bar expanded if there are native filters
+ - `0`: render dashboard with Filter Bar collapsed
+ - `1`: render dashboard with Filter Bar expanded
+
+For example, when running the local development build, the following will disable the
+Top Nav and remove the Filter Bar:
+`http://localhost:8088/superset/dashboard/my-dashboard/?standalone=1&show_filters=0`
diff --git a/superset-frontend/src/components/UiConfigContext/index.tsx b/superset-frontend/src/components/UiConfigContext/index.tsx
index 4b77e42015..3943cde46c 100644
--- a/superset-frontend/src/components/UiConfigContext/index.tsx
+++ b/superset-frontend/src/components/UiConfigContext/index.tsx
@@ -41,7 +41,7 @@ export const useUiConfig = () => useContext(UiConfigContext);
export const EmbeddedUiConfigProvider: React.FC =
({ children }) => {
- const config = getUrlParam(URL_PARAMS.uiConfig);
+ const config = getUrlParam(URL_PARAMS.uiConfig) || 0;
const [embeddedConfig] = useState({
hideTitle: (config & 1) !== 0,
hideTab: (config & 2) !== 0,
diff --git a/superset-frontend/src/constants.ts b/superset-frontend/src/constants.ts
index 777d5f2a4e..2ef1bc7931 100644
--- a/superset-frontend/src/constants.ts
+++ b/superset-frontend/src/constants.ts
@@ -55,6 +55,10 @@ export const URL_PARAMS = {
name: 'show_filters',
type: 'boolean',
},
+ expandFilters: {
+ name: 'expand_filters',
+ type: 'boolean',
+ },
formDataKey: {
name: 'form_data_key',
type: 'string',
diff --git a/superset-frontend/src/dashboard/components/DashboardBuilder/state.ts b/superset-frontend/src/dashboard/components/DashboardBuilder/state.ts
index 4c56ab87eb..676ffd45cc 100644
--- a/superset-frontend/src/dashboard/components/DashboardBuilder/state.ts
+++ b/superset-frontend/src/dashboard/components/DashboardBuilder/state.ts
@@ -32,11 +32,10 @@ import {
export const useNativeFilters = () => {
const filterboxMigrationState = useContext(MigrationContext);
const [isInitialized, setIsInitialized] = useState(false);
- const [dashboardFiltersOpen, setDashboardFiltersOpen] = useState(
- getUrlParam(URL_PARAMS.showFilters) ?? true,
- );
const showNativeFilters = useSelector(
- state => state.dashboardInfo.metadata?.show_native_filters,
+ state =>
+ (getUrlParam(URL_PARAMS.showFilters) ?? true) &&
+ state.dashboardInfo.metadata?.show_native_filters,
);
const canEdit = useSelector(
({ dashboardInfo }) => dashboardInfo.dash_edit_perm,
@@ -44,6 +43,10 @@ export const useNativeFilters = () => {
const filters = useFilters();
const filterValues = Object.values(filters);
+ const expandFilters = getUrlParam(URL_PARAMS.expandFilters);
+ const [dashboardFiltersOpen, setDashboardFiltersOpen] = useState(
+ expandFilters ?? !!filterValues.length,
+ );
const nativeFiltersEnabled =
showNativeFilters &&
@@ -74,9 +77,10 @@ export const useNativeFilters = () => {
useEffect(() => {
if (
- filterValues.length === 0 &&
- nativeFiltersEnabled &&
- ['CONVERTED', 'REVIEWING', 'NOOP'].includes(filterboxMigrationState)
+ expandFilters === false ||
+ (filterValues.length === 0 &&
+ nativeFiltersEnabled &&
+ ['CONVERTED', 'REVIEWING', 'NOOP'].includes(filterboxMigrationState))
) {
toggleDashboardFiltersOpen(false);
} else {
diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/keyValue.tsx b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/keyValue.tsx
index ec9735f091..27a4d3b6ce 100644
--- a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/keyValue.tsx
+++ b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/keyValue.tsx
@@ -21,7 +21,7 @@ import { DashboardPermalinkValue } from 'src/dashboard/types';
const assembleEndpoint = (
dashId: string | number,
- key?: string,
+ key?: string | null,
tabId?: string,
) => {
let endpoint = `api/v1/dashboard/${dashId}/filter_state`;
@@ -65,7 +65,7 @@ export const createFilterKey = (
return null;
});
-export const getFilterValue = (dashId: string | number, key: string) =>
+export const getFilterValue = (dashId: string | number, key?: string | null) =>
SupersetClient.get({
endpoint: assembleEndpoint(dashId, key),
})
diff --git a/superset-frontend/src/utils/urlUtils.ts b/superset-frontend/src/utils/urlUtils.ts
index ffaf5621f2..be857517e0 100644
--- a/superset-frontend/src/utils/urlUtils.ts
+++ b/superset-frontend/src/utils/urlUtils.ts
@@ -30,14 +30,22 @@ import serializeActiveFilterValues from '../dashboard/util/serializeActiveFilter
export type UrlParamType = 'string' | 'number' | 'boolean' | 'object' | 'rison';
export type UrlParam = typeof URL_PARAMS[keyof typeof URL_PARAMS];
-export function getUrlParam(param: UrlParam & { type: 'string' }): string;
-export function getUrlParam(param: UrlParam & { type: 'number' }): number;
-export function getUrlParam(param: UrlParam & { type: 'boolean' }): boolean;
-export function getUrlParam(param: UrlParam & { type: 'object' }): object;
-export function getUrlParam(param: UrlParam & { type: 'rison' }): object;
+export function getUrlParam(
+ param: UrlParam & { type: 'string' },
+): string | null;
+export function getUrlParam(
+ param: UrlParam & { type: 'number' },
+): number | null;
+export function getUrlParam(
+ param: UrlParam & { type: 'boolean' },
+): boolean | null;
+export function getUrlParam(
+ param: UrlParam & { type: 'object' },
+): object | null;
+export function getUrlParam(param: UrlParam & { type: 'rison' }): object | null;
export function getUrlParam(
param: UrlParam & { type: 'rison | string' },
-): string | object;
+): string | object | null;
export function getUrlParam({ name, type }: UrlParam): unknown {
const urlParam = new URLSearchParams(window.location.search).get(name);
switch (type) {