Skip to content

Commit

Permalink
fix(dashboard): fix default filter bar visibility + add docs (apache#…
Browse files Browse the repository at this point in the history
…18741)

* fix(dashboard): fix default filter tab visibility + add tests

* fix types

* lint

* rename docs + add double bang to length
  • Loading branch information
villebro authored and philipher29 committed Jun 9, 2022
1 parent 2e6bf73 commit b5ada58
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 75 deletions.
108 changes: 59 additions & 49 deletions docs/docs/creating-charts-dashboards/creating-your-first-dashboard.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ sidebar_position: 1
version: 1
---

import useBaseUrl from '@docusaurus/useBaseUrl';
import useBaseUrl from "@docusaurus/useBaseUrl";

## Creating Your First Dashboard

This section is focused on documentation for end-users who will be using Superset
for the data analysis and exploration workflow
(data analysts, business analysts, data
(data analysts, business analysts, data
scientists, etc). In addition to this site, [Preset.io](http://preset.io/) maintains an updated set of end-user
documentation at [docs.preset.io](https://docs.preset.io/).

Expand All @@ -33,20 +33,16 @@ pre-configured in Superset for you.

Under the **Data** menu, select the _Databases_ option:

<img
src={useBaseUrl('/img/tutorial/tutorial_01_sources_database.png')}
/> <br />
<br />
<img src={useBaseUrl("/img/tutorial/tutorial_01_sources_database.png" )} />{" "} <br/><br/>

Next, click the green **+ Database** button in the top right corner:

<img src={useBaseUrl('/img/tutorial/tutorial_02_add_database.png')} /> <br />
<br />
<img src={useBaseUrl("/img/tutorial/tutorial_02_add_database.png" )} />{" "} <br/><br/>

You can configure a number of advanced options in this window, but for this walkthrough you only
need to specify two things (the database name and SQLAlchemy URI):

<img src={useBaseUrl('/img/tutorial/tutorial_03_database_name.png')} />
<img src={useBaseUrl("/img/tutorial/tutorial_03_database_name.png" )} />

As noted in the text below
the URI, you should refer to the SQLAlchemy documentation on
Expand All @@ -56,7 +52,7 @@ for your target database.
Click the **Test Connection** button to confirm things work end to end. If the connection looks good, save the configuration
by clicking the **Add** button in the bottom right corner of the modal window:

<img src={useBaseUrl('/img/tutorial/tutorial_04_add_button.png')} />
<img src={useBaseUrl("/img/tutorial/tutorial_04_add_button.png" )} />

Congratulations, you've just added a new data source in Superset!

Expand All @@ -67,84 +63,82 @@ that you want exposed in Superset for querying.

Navigate to **Data ‣ Datasets** and select the **+ Dataset** button in the top right corner.

<img src={useBaseUrl('/img/tutorial/tutorial_08_sources_tables.png')} />
<img src={useBaseUrl("/img/tutorial/tutorial_08_sources_tables.png" )} />

A modal window should pop up in front of you. Select your **Database**,
**Schema**, and **Table** using the drop downs that appear. In the following example,
we register the **cleaned_sales_data** table from the **examples** database.

<img src={useBaseUrl('/img/tutorial/tutorial_09_add_new_table.png')} />
<img src={useBaseUrl("/img/tutorial/tutorial_09_add_new_table.png" )} />

To finish, click the **Add** button in the bottom right corner. You should now see your dataset in the list of datasets.

### Customizing column properties

Now that you've registered your dataset, you can configure column properties
for how the column should be treated in the Explore workflow:
for how the column should be treated in the Explore workflow:

- Is the column temporal? (should it be used for slicing & dicing in time series charts?)
- Should the column be filterable?
- Is the column dimensional?
- If it's a datetime column, how should Superset parse
the datetime format? (using the [ISO-8601 string pattern](https://en.wikipedia.org/wiki/ISO_8601))
the datetime format? (using the [ISO-8601 string pattern](https://en.wikipedia.org/wiki/ISO_8601))

<img src={useBaseUrl('/img/tutorial/tutorial_column_properties.png')} />
<img src={useBaseUrl("/img/tutorial/tutorial_column_properties.png" )} />

### Superset semantic layer

Superset has a thin semantic layer that adds many quality of life improvements for analysts.
The Superset semantic layer can store 2 types of computed data:

1. Virtual metrics: you can write SQL queries that aggregate values
from multiple column (e.g. `SUM(recovered) / SUM(confirmed)`) and make them
available as columns for (e.g. `recovery_rate`) visualization in Explore.
Agggregate functions are allowed and encouraged for metrics.
from multiple column (e.g. `SUM(recovered) / SUM(confirmed)`) and make them
available as columns for (e.g. `recovery_rate`) visualization in Explore.
Agggregate functions are allowed and encouraged for metrics.

<img src={useBaseUrl('/img/tutorial/tutorial_sql_metric.png')} />
<img src={useBaseUrl("/img/tutorial/tutorial_sql_metric.png" )} />

You can also certify metrics if you'd like for your team in this view.

2. Virtual calculated columns: you can write SQL queries that
customize the appearance and behavior
of a specific column (e.g. `CAST(recovery_rate) as float`).
Aggregate functions aren't allowed in calculated columns.
customize the appearance and behavior
of a specific column (e.g. `CAST(recovery_rate) as float`).
Aggregate functions aren't allowed in calculated columns.

<img src={useBaseUrl('/img/tutorial/tutorial_calculated_column.png')} />
<img src={useBaseUrl("/img/tutorial/tutorial_calculated_column.png" )} />

### Creating charts in Explore view

Superset has 2 main interfaces for exploring data:

- **Explore**: no-code viz builder. Select your dataset, select the chart,
customize the appearance, and publish.
customize the appearance, and publish.
- **SQL Lab**: SQL IDE for cleaning, joining, and preparing data for Explore workflow

We'll focus on the Explore view for creating charts right now.
To start the Explore workflow from the **Datasets** tab, start by clicking the name
of the dataset that will be powering your chart.

<img src={useBaseUrl('/img/tutorial/tutorial_launch_explore.png')} />
<br />
<br />
<img src={useBaseUrl("/img/tutorial/tutorial_launch_explore.png" )} /><br/><br/>

You're now presented with a powerful workflow for exploring data and iterating on charts.

- The **Dataset** view on the left-hand side has a list of columns and metrics,
scoped to the current dataset you selected.
scoped to the current dataset you selected.
- The **Data** preview below the chart area also gives you helpful data context.
- Using the **Data** tab and **Customize** tabs, you can change the visualization type,
select the temporal column, select the metric to group by, and customize
the aesthetics of the chart.
select the temporal column, select the metric to group by, and customize
the aesthetics of the chart.

As you customize your chart using drop-down menus, make sure to click the **Run** button
to get visual feedback.

<img src={useBaseUrl('/img/tutorial/tutorial_explore_run.jpg')} />
<img src={useBaseUrl("/img/tutorial/tutorial_explore_run.jpg" )} />

In the following screenshot, we craft a grouped Time-series Bar Chart to visualize
our quarterly sales data by product line just be clicking options in drop-down menus.

<img src={useBaseUrl('/img/tutorial/tutorial_explore_settings.jpg')} />
<img src={useBaseUrl("/img/tutorial/tutorial_explore_settings.jpg" )} />

### Creating a slice and dashboard

Expand All @@ -155,47 +149,63 @@ To save your chart, first click the **Save** button. You can either:

In the following screenshot, we save the chart to a new "Superset Duper Sales Dashboard":

<img src={useBaseUrl('/img/tutorial/tutorial_save_slice.png')} />
<img src={useBaseUrl("/img/tutorial/tutorial_save_slice.png" )} />

To publish, click **Save and goto Dashboard**.

Behind the scenes, Superset will create a slice and store all the information needed
to create your chart in its thin data layer
(the query, chart type, options selected, name, etc).
(the query, chart type, options selected, name, etc).

{' '}
<img src={useBaseUrl('/img/tutorial/tutorial_first_dashboard.png')} />
<img src={useBaseUrl("/img/tutorial/tutorial_first_dashboard.png" )} />

To resize the chart, start by clicking the pencil button in the top right corner.
To resize the chart, start by clicking the pencil button in the top right corner.

{' '}
<img src={useBaseUrl('/img/tutorial/tutorial_pencil_edit.png')} />
<img src={useBaseUrl("/img/tutorial/tutorial_pencil_edit.png" )} />

Then, click and drag the bottom right corner of the chart until the chart layout snaps
into a position you like onto the underlying grid.

{' '}
<img src={useBaseUrl('/img/tutorial/tutorial_chart_resize.png')} />
<img src={useBaseUrl("/img/tutorial/tutorial_chart_resize.png" )} />

Click **Save** to persist the changes.
Click **Save** to persist the changes.

Congrats! You’ve successfully linked, analyzed, and visualized data in Superset. There are a wealth
of other table configuration and visualization options, so please start exploring and creating
slices and dashboards of your own

ֿ

### Manage access to Dashboards


Access to dashboards is managed via owners (users that have edit permissions to the dashboard)

Non-owner users access can be managed two different ways:

1. Dataset permissions - if you add to the relevant role permissions to datasets it automatically grants implict access to all dashboards that uses those permitted datasets
2. Dashboard roles - if you enable **DASHBOARD_RBAC** feature flag then you be able to manage which roles can access the dashboard

2. Dashboard roles - if you enable **DASHBOARD_RBAC** feature flag then you be able to manage which roles can access the dashboard
- Having dashboard access implicitly grants read access to the associated datasets, therefore
all charts will load their data even if feature flag is turned on and no roles assigned
to roles the access will fallback to **Dataset permissions**

<img src={useBaseUrl('/img/tutorial/tutorial_dashboard_access.png')} />
all charts will load their data even if feature flag is turned on and no roles assigned
to roles the access will fallback to **Dataset permissions**

<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`
2 changes: 1 addition & 1 deletion superset-frontend/src/components/UiConfigContext/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export const useUiConfig = () => useContext(UiConfigContext);

export const EmbeddedUiConfigProvider: React.FC<EmbeddedUiConfigProviderProps> =
({ 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,
Expand Down
4 changes: 4 additions & 0 deletions superset-frontend/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,21 @@ 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<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>(
({ dashboardInfo }) => dashboardInfo.dash_edit_perm,
);

const filters = useFilters();
const filterValues = Object.values(filters);
const expandFilters = getUrlParam(URL_PARAMS.expandFilters);
const [dashboardFiltersOpen, setDashboardFiltersOpen] = useState(
expandFilters ?? !!filterValues.length,
);

const nativeFiltersEnabled =
showNativeFilters &&
Expand Down Expand Up @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { DashboardPermalinkValue } from 'src/dashboard/types';

const assembleEndpoint = (
dashId: string | number,
key?: string,
key?: string | null,
tabId?: string,
) => {
let endpoint = `Analytics/api/v1/dashboard/${dashId}/filter_state`;
Expand Down Expand Up @@ -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),
})
Expand Down
36 changes: 20 additions & 16 deletions superset-frontend/src/utils/urlUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +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) {
Expand Down Expand Up @@ -141,7 +148,7 @@ export function getChartPermalink(
formData: Pick<QueryFormData, 'datasource'>,
excludedUrlParams?: string[],
) {
return getPermalink(`${process.env.APP_PREFIX}/api/v1/explore/permalink`, {
return getPermalink('/api/v1/explore/permalink', {
formData,
urlParams: getChartUrlParams(excludedUrlParams),
});
Expand All @@ -153,12 +160,9 @@ export function getDashboardPermalink(
hash?: string,
) {
// only encode filter box state if non-empty
return getPermalink(
`${process.env.APP_PREFIX}/api/v1/dashboard/${dashboardId}/permalink`,
{
filterState,
urlParams: getDashboardUrlParams(),
hash,
},
);
return getPermalink(`/api/v1/dashboard/${dashboardId}/permalink`, {
filterState,
urlParams: getDashboardUrlParams(),
hash,
});
}

0 comments on commit b5ada58

Please sign in to comment.