mirror of https://github.com/apache/superset.git
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
This commit is contained in:
parent
375c03e084
commit
b7ecb14230
|
@ -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**
|
to roles the access will fallback to **Dataset permissions**
|
||||||
|
|
||||||
<img src={useBaseUrl("/img/tutorial/tutorial_dashboard_access.png" )} />
|
<img src={useBaseUrl("/img/tutorial/tutorial_dashboard_access.png" )} />
|
||||||
|
|
||||||
|
### 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`
|
||||||
|
|
|
@ -41,7 +41,7 @@ export const useUiConfig = () => useContext(UiConfigContext);
|
||||||
|
|
||||||
export const EmbeddedUiConfigProvider: React.FC<EmbeddedUiConfigProviderProps> =
|
export const EmbeddedUiConfigProvider: React.FC<EmbeddedUiConfigProviderProps> =
|
||||||
({ children }) => {
|
({ children }) => {
|
||||||
const config = getUrlParam(URL_PARAMS.uiConfig);
|
const config = getUrlParam(URL_PARAMS.uiConfig) || 0;
|
||||||
const [embeddedConfig] = useState({
|
const [embeddedConfig] = useState({
|
||||||
hideTitle: (config & 1) !== 0,
|
hideTitle: (config & 1) !== 0,
|
||||||
hideTab: (config & 2) !== 0,
|
hideTab: (config & 2) !== 0,
|
||||||
|
|
|
@ -55,6 +55,10 @@ export const URL_PARAMS = {
|
||||||
name: 'show_filters',
|
name: 'show_filters',
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
},
|
},
|
||||||
|
expandFilters: {
|
||||||
|
name: 'expand_filters',
|
||||||
|
type: 'boolean',
|
||||||
|
},
|
||||||
formDataKey: {
|
formDataKey: {
|
||||||
name: 'form_data_key',
|
name: 'form_data_key',
|
||||||
type: 'string',
|
type: 'string',
|
||||||
|
|
|
@ -32,11 +32,10 @@ import {
|
||||||
export const useNativeFilters = () => {
|
export const useNativeFilters = () => {
|
||||||
const filterboxMigrationState = useContext(MigrationContext);
|
const filterboxMigrationState = useContext(MigrationContext);
|
||||||
const [isInitialized, setIsInitialized] = useState(false);
|
const [isInitialized, setIsInitialized] = useState(false);
|
||||||
const [dashboardFiltersOpen, setDashboardFiltersOpen] = useState(
|
|
||||||
getUrlParam(URL_PARAMS.showFilters) ?? true,
|
|
||||||
);
|
|
||||||
const showNativeFilters = useSelector<RootState, boolean>(
|
const showNativeFilters = useSelector<RootState, boolean>(
|
||||||
state => state.dashboardInfo.metadata?.show_native_filters,
|
state =>
|
||||||
|
(getUrlParam(URL_PARAMS.showFilters) ?? true) &&
|
||||||
|
state.dashboardInfo.metadata?.show_native_filters,
|
||||||
);
|
);
|
||||||
const canEdit = useSelector<RootState, boolean>(
|
const canEdit = useSelector<RootState, boolean>(
|
||||||
({ dashboardInfo }) => dashboardInfo.dash_edit_perm,
|
({ dashboardInfo }) => dashboardInfo.dash_edit_perm,
|
||||||
|
@ -44,6 +43,10 @@ export const useNativeFilters = () => {
|
||||||
|
|
||||||
const filters = useFilters();
|
const filters = useFilters();
|
||||||
const filterValues = Object.values(filters);
|
const filterValues = Object.values(filters);
|
||||||
|
const expandFilters = getUrlParam(URL_PARAMS.expandFilters);
|
||||||
|
const [dashboardFiltersOpen, setDashboardFiltersOpen] = useState(
|
||||||
|
expandFilters ?? !!filterValues.length,
|
||||||
|
);
|
||||||
|
|
||||||
const nativeFiltersEnabled =
|
const nativeFiltersEnabled =
|
||||||
showNativeFilters &&
|
showNativeFilters &&
|
||||||
|
@ -74,9 +77,10 @@ export const useNativeFilters = () => {
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (
|
if (
|
||||||
filterValues.length === 0 &&
|
expandFilters === false ||
|
||||||
nativeFiltersEnabled &&
|
(filterValues.length === 0 &&
|
||||||
['CONVERTED', 'REVIEWING', 'NOOP'].includes(filterboxMigrationState)
|
nativeFiltersEnabled &&
|
||||||
|
['CONVERTED', 'REVIEWING', 'NOOP'].includes(filterboxMigrationState))
|
||||||
) {
|
) {
|
||||||
toggleDashboardFiltersOpen(false);
|
toggleDashboardFiltersOpen(false);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -21,7 +21,7 @@ import { DashboardPermalinkValue } from 'src/dashboard/types';
|
||||||
|
|
||||||
const assembleEndpoint = (
|
const assembleEndpoint = (
|
||||||
dashId: string | number,
|
dashId: string | number,
|
||||||
key?: string,
|
key?: string | null,
|
||||||
tabId?: string,
|
tabId?: string,
|
||||||
) => {
|
) => {
|
||||||
let endpoint = `api/v1/dashboard/${dashId}/filter_state`;
|
let endpoint = `api/v1/dashboard/${dashId}/filter_state`;
|
||||||
|
@ -65,7 +65,7 @@ export const createFilterKey = (
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
|
||||||
export const getFilterValue = (dashId: string | number, key: string) =>
|
export const getFilterValue = (dashId: string | number, key?: string | null) =>
|
||||||
SupersetClient.get({
|
SupersetClient.get({
|
||||||
endpoint: assembleEndpoint(dashId, key),
|
endpoint: assembleEndpoint(dashId, key),
|
||||||
})
|
})
|
||||||
|
|
|
@ -30,14 +30,22 @@ import serializeActiveFilterValues from '../dashboard/util/serializeActiveFilter
|
||||||
|
|
||||||
export type UrlParamType = 'string' | 'number' | 'boolean' | 'object' | 'rison';
|
export type UrlParamType = 'string' | 'number' | 'boolean' | 'object' | 'rison';
|
||||||
export type UrlParam = typeof URL_PARAMS[keyof typeof URL_PARAMS];
|
export type UrlParam = typeof URL_PARAMS[keyof typeof URL_PARAMS];
|
||||||
export function getUrlParam(param: UrlParam & { type: 'string' }): string;
|
export function getUrlParam(
|
||||||
export function getUrlParam(param: UrlParam & { type: 'number' }): number;
|
param: UrlParam & { type: 'string' },
|
||||||
export function getUrlParam(param: UrlParam & { type: 'boolean' }): boolean;
|
): string | null;
|
||||||
export function getUrlParam(param: UrlParam & { type: 'object' }): object;
|
export function getUrlParam(
|
||||||
export function getUrlParam(param: UrlParam & { type: 'rison' }): object;
|
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(
|
export function getUrlParam(
|
||||||
param: UrlParam & { type: 'rison | string' },
|
param: UrlParam & { type: 'rison | string' },
|
||||||
): string | object;
|
): string | object | null;
|
||||||
export function getUrlParam({ name, type }: UrlParam): unknown {
|
export function getUrlParam({ name, type }: UrlParam): unknown {
|
||||||
const urlParam = new URLSearchParams(window.location.search).get(name);
|
const urlParam = new URLSearchParams(window.location.search).get(name);
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
|
Loading…
Reference in New Issue