Compare commits

..

2 Commits

Author SHA1 Message Date
Maxime Beauchemin
db3a0f50d6 clarify message 2025-06-30 09:38:13 -07:00
Maxime Beauchemin
379ef6b002 docs: add FAQ entry around how dashboard filters are broadcasted 2025-06-30 09:38:13 -07:00
10 changed files with 56 additions and 23 deletions

View File

@@ -43,7 +43,7 @@ assists people when migrating to a new version.
- [31198](https://github.com/apache/superset/pull/31198) Disallows by default the use of the following ClickHouse functions: "version", "currentDatabase", "hostName".
- [29798](https://github.com/apache/superset/pull/29798) Since 3.1.0, the intial schedule for an alert or report was mistakenly offset by the specified timezone's relation to UTC. The initial schedule should now begin at the correct time.
- [30021](https://github.com/apache/superset/pull/30021) The `dev` layer in our Dockerfile no long includes firefox binaries, only Chromium to reduce bloat/docker-build-time.
- [30099](https://github.com/apache/superset/pull/30099) Translations are no longer included in the default docker image builds. If your environment requires translations, you'll want to set the docker build arg `BUILD_TRANSLATIONS=true`.
- [30099](https://github.com/apache/superset/pull/30099) Translations are no longer included in the default docker image builds. If your environment requires translations, you'll want to set the docker build arg `BUILD_TRANSACTION=true`.
- [31262](https://github.com/apache/superset/pull/31262) NOTE: deprecated `pylint` in favor of `ruff` as our only python linter. Only affect development workflows positively (not the release itself). It should cover most important rules, be much faster, but some things linting rules that were enforced before may not be enforce in the exact same way as before.
- [31173](https://github.com/apache/superset/pull/31173) Modified `fetch_csrf_token` to align with HTTP standards, particularly regarding how cookies are handled. If you encounter any issues related to CSRF functionality, please report them as a new issue and reference this PR for context.
- [31413](https://github.com/apache/superset/pull/31413) Enable the DATE_FORMAT_IN_EMAIL_SUBJECT feature flag to allow users to specify a date format for the email subject, which will then be replaced with the actual date.

View File

@@ -283,3 +283,28 @@ You are talking about dependency CVEs: identified vulnerabilities in software th
We address these dependency CVEs as best we can by regularly updating our dependencies to newer versions. We use bots to assist with that and cheerfully welcome pull requests from humans that fix dependency CVEs.
The Superset [security team](https://superset.apache.org/docs/security/#reporting-security-vulnerabilities) focuses primarily on vulnerabilities _in Superset itself_. See our [CVEs page](https://superset.apache.org/docs/security/cves) for a list of past Superset CVEs.
## How are dashboard filters broadcasted?
In Superset, **filters on a dashboard are broadcasted to other charts by default** based on matching **column names**, even across different datasets.
### Default behavior
When you add a filter to a dashboard (e.g. selecting `country = Canada`), it will **automatically apply to all charts** that contain a column named `country`, regardless of which dataset they use. This default setting is labeled **"All panels"** in the filters configuration modal.
If two datasets both have a `country` column, the filter will be applied to both. Superset assumes the shared column name reflects the same semantic dimension.
### Things to watch out for
- Superset only matches by **column name**, not content. If one dataset uses `country = Canada` and another uses `country = CA`, the filter might produce **invalid or empty results**.
- This can lead to confusion or broken dashboards unless the datasets are aligned and filterable by the same values.
- When building dashboards that mix datasets, consider how your dimensions are named and whether their values match.
### Controlling filter scope
To manage this, open the **filter configuration modal**, and go to the **“Scoping”** tab. From there, you can:
- Limit the filter to specific charts.
- Avoid broadcasting to charts using datasets with incompatible dimension values.
- See exactly which charts will be affected.
This behavior is powerful, but it does require some care. Align your dataset schemas and be deliberate with scoping to avoid unexpected cross-chart filtering.

View File

@@ -69,10 +69,6 @@ const restrictedImportsRules = {
message:
'Please use the theme directly from the ThemeProvider rather than importing supersetTheme.',
},
'no-query-string': {
name: 'query-string',
message: 'Please use the URLSearchParams API instead of query-string.',
},
};
module.exports = {

View File

@@ -96,6 +96,7 @@
"ol": "^7.5.2",
"polished": "^4.3.1",
"prop-types": "^15.8.1",
"query-string": "^6.13.7",
"rc-trigger": "^5.3.4",
"re-resizable": "^6.10.1",
"react": "^17.0.2",
@@ -20957,7 +20958,6 @@
"resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz",
"integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==",
"license": "MIT",
"peer": true,
"engines": {
"node": ">=0.10"
}
@@ -24474,7 +24474,6 @@
"resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-1.1.0.tgz",
"integrity": "sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==",
"license": "MIT",
"peer": true,
"engines": {
"node": ">=0.10.0"
}
@@ -42263,7 +42262,6 @@
"resolved": "https://registry.npmjs.org/query-string/-/query-string-6.14.1.tgz",
"integrity": "sha512-XDxAeVmpfu1/6IjyT/gXHOl+S0vQ9owggJ30hhWKdHAsNPOcasn5o9BW0eejZqL2e4vMjhAxoW3jVHcD6mbcYw==",
"license": "MIT",
"peer": true,
"dependencies": {
"decode-uri-component": "^0.2.0",
"filter-obj": "^1.1.0",
@@ -47999,7 +47997,6 @@
"resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz",
"integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==",
"license": "MIT",
"peer": true,
"engines": {
"node": ">=6"
}
@@ -48476,7 +48473,6 @@
"resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz",
"integrity": "sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==",
"license": "MIT",
"peer": true,
"engines": {
"node": ">=4"
}

View File

@@ -164,6 +164,7 @@
"ol": "^7.5.2",
"polished": "^4.3.1",
"prop-types": "^15.8.1",
"query-string": "^6.13.7",
"rc-trigger": "^5.3.4",
"re-resizable": "^6.10.1",
"react": "^17.0.2",

View File

@@ -80,7 +80,6 @@ export class Theme {
// Forcing some default tokens
fontFamily: `'Inter', Helvetica, Arial`,
fontFamilyCode: `'Fira Code', 'Courier New', monospace`,
fontFeatureSettings: '"tnum" 1',
// Extra tokens
transitionTiming: 0.3,

View File

@@ -18,6 +18,7 @@
*/
import { useEffect, useCallback, useMemo, useState } from 'react';
import { shallowEqual, useDispatch, useSelector } from 'react-redux';
import querystring from 'query-string';
import { SqlLabRootState, Table } from 'src/SqlLab/types';
import {
@@ -99,7 +100,7 @@ const SqlEditorLeftBar = ({
);
useEffect(() => {
const bool = new URLSearchParams(window.location.search).get('db');
const bool = querystring.parse(window.location.search).db;
const userSelected = getItem(
LocalStorageKeys.Database,
null,

View File

@@ -55,6 +55,7 @@ import { PluginFilterSelectCustomizeProps } from 'src/filters/components/Select/
import { useSelector } from 'react-redux';
import { getChartDataRequest } from 'src/components/Chart/chartAction';
import {
Alert,
Constants,
FormItem,
type FormInstance,
@@ -1438,14 +1439,26 @@ const FiltersConfigForm = (
label: FilterTabs.scoping.name,
forceRender: true,
children: (
<FilterScope
updateFormValues={updateFormValues}
pathToFormValue={['filters', filterId]}
forceUpdate={forceUpdate}
filterScope={filterToEdit?.scope}
formFilterScope={formFilter?.scope}
initiallyExcludedCharts={initiallyExcludedCharts}
/>
<>
<Alert
type="info"
message={t('About filter scoping')}
style={{ margin: theme.sizeUnit * 2 }}
description={t(
'Dashboard filters are only applied when the same dataset ' +
'is shared across multiple charts OR when column names ' +
'match across different datasets within the same dashboard.',
)}
/>
<FilterScope
updateFormValues={updateFormValues}
pathToFormValue={['filters', filterId]}
forceUpdate={forceUpdate}
filterScope={filterToEdit?.scope}
formFilterScope={formFilter?.scope}
initiallyExcludedCharts={initiallyExcludedCharts}
/>
</>
),
},
]}

View File

@@ -16,6 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
import querystring from 'query-string';
import { JsonObject } from '@superset-ui/core';
const reservedQueryParams = new Set(['standalone', 'edit']);
@@ -28,8 +29,8 @@ export type UrlParamType = 'reserved' | 'regular' | 'all';
export default function extractUrlParams(
urlParamType: UrlParamType,
): JsonObject {
const queryParams = new URLSearchParams(window.location.search);
return [...queryParams.entries()].reduce((acc, [key, value]) => {
const queryParams = querystring.parse(window.location.search);
return Object.entries(queryParams).reduce((acc, [key, value]) => {
if (
(urlParamType === 'regular' && reservedQueryParams.has(key)) ||
(urlParamType === 'reserved' && !reservedQueryParams.has(key))

View File

@@ -18,6 +18,7 @@
*/
import { PureComponent, ReactNode } from 'react';
import rison from 'rison';
import querystring from 'query-string';
import {
isDefined,
JsonResponse,
@@ -205,7 +206,7 @@ export class ChartCreation extends PureComponent<
}
componentDidMount() {
const params = new URLSearchParams(window.location.search).get('dataset');
const params = querystring.parse(window.location.search)?.dataset as string;
if (params) {
this.loadDatasources(params, 0, 1).then(r => {
const datasource = r.data[0];