diff --git a/.github/workflows/bashlib.sh b/.github/workflows/bashlib.sh
index ff162de889509..bcb3b78e73b2b 100644
--- a/.github/workflows/bashlib.sh
+++ b/.github/workflows/bashlib.sh
@@ -192,7 +192,7 @@ cypress-run-all() {
say "::endgroup::"
# Rerun SQL Lab tests with backend persist enabled
- export SUPERSET_CONFIG=tests.superset_test_config_sqllab_backend_persist
+ export SUPERSET_CONFIG=tests.integration_tests.superset_test_config_sqllab_backend_persist
# Restart Flask with new configs
kill $flaskProcessId
diff --git a/.github/workflows/superset-e2e.yml b/.github/workflows/superset-e2e.yml
index 13564d51c2f18..3b3898b52091a 100644
--- a/.github/workflows/superset-e2e.yml
+++ b/.github/workflows/superset-e2e.yml
@@ -25,7 +25,7 @@ jobs:
env:
FLASK_ENV: development
ENABLE_REACT_CRUD_VIEWS: true
- SUPERSET_CONFIG: tests.superset_test_config
+ SUPERSET_CONFIG: tests.integration_tests.superset_test_config
SUPERSET__SQLALCHEMY_DATABASE_URI: postgresql+psycopg2://superset:superset@127.0.0.1:15432/superset
PYTHONPATH: ${{ github.workspace }}
REDIS_PORT: 16379
diff --git a/.github/workflows/superset-python-presto-hive.yml b/.github/workflows/superset-python-presto-hive.yml
index b7e05b3995a20..9177037822020 100644
--- a/.github/workflows/superset-python-presto-hive.yml
+++ b/.github/workflows/superset-python-presto-hive.yml
@@ -17,7 +17,7 @@ jobs:
python-version: [3.8]
env:
PYTHONPATH: ${{ github.workspace }}
- SUPERSET_CONFIG: tests.superset_test_config
+ SUPERSET_CONFIG: tests.integration_tests.superset_test_config
REDIS_PORT: 16379
SUPERSET__SQLALCHEMY_DATABASE_URI: postgresql+psycopg2://superset:superset@127.0.0.1:15432/superset
SUPERSET__SQLALCHEMY_EXAMPLES_URI: presto://localhost:15433/memory/default
@@ -91,7 +91,7 @@ jobs:
python-version: [3.8]
env:
PYTHONPATH: ${{ github.workspace }}
- SUPERSET_CONFIG: tests.superset_test_config
+ SUPERSET_CONFIG: tests.integration_tests.superset_test_config
REDIS_PORT: 16379
SUPERSET__SQLALCHEMY_DATABASE_URI: postgresql+psycopg2://superset:superset@127.0.0.1:15432/superset
SUPERSET__SQLALCHEMY_EXAMPLES_URI: hive://localhost:10000/default
diff --git a/.github/workflows/superset-python-unittest.yml b/.github/workflows/superset-python-unittest.yml
index 3a95556647bdd..0ff0266ae1630 100644
--- a/.github/workflows/superset-python-unittest.yml
+++ b/.github/workflows/superset-python-unittest.yml
@@ -17,7 +17,7 @@ jobs:
python-version: [3.7]
env:
PYTHONPATH: ${{ github.workspace }}
- SUPERSET_CONFIG: tests.superset_test_config
+ SUPERSET_CONFIG: tests.integration_tests.superset_test_config
REDIS_PORT: 16379
SUPERSET__SQLALCHEMY_DATABASE_URI: |
mysql+mysqldb://superset:superset@127.0.0.1:13306/superset?charset=utf8mb4&binary_prefix=true
@@ -80,7 +80,7 @@ jobs:
python-version: [3.7, 3.8]
env:
PYTHONPATH: ${{ github.workspace }}
- SUPERSET_CONFIG: tests.superset_test_config
+ SUPERSET_CONFIG: tests.integration_tests.superset_test_config
REDIS_PORT: 16379
SUPERSET__SQLALCHEMY_DATABASE_URI: postgresql+psycopg2://superset:superset@127.0.0.1:15432/superset
services:
@@ -144,7 +144,7 @@ jobs:
python-version: [3.7]
env:
PYTHONPATH: ${{ github.workspace }}
- SUPERSET_CONFIG: tests.superset_test_config
+ SUPERSET_CONFIG: tests.integration_tests.superset_test_config
REDIS_PORT: 16379
SUPERSET__SQLALCHEMY_DATABASE_URI: |
sqlite:///${{ github.workspace }}/.temp/unittest.db
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index cda776186c71a..619fec385b2ee 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -77,6 +77,8 @@ little bit helps, and credit will always be given.
- [Python Testing](#python-testing)
- [Frontend Testing](#frontend-testing)
- [Integration Testing](#integration-testing)
+ - [Debugging Server App](#debugging-server-app)
+ - [Debugging Server App in Kubernetes Environment](#debugging-server-app-in-kubernetes-environment)
- [Storybook](#storybook)
- [Translating](#translating)
- [Enabling language selection](#enabling-language-selection)
@@ -418,9 +420,10 @@ For example, the image referenced above actually lives in `superset-frontend/ima
#### OS Dependencies
-Make sure your machine meets the [OS dependencies](https://superset.apache.org/docs/installation/installing-superset-from-scratch#os-dependencies) before following these steps.
+Make sure your machine meets the [OS dependencies](https://superset.apache.org/docs/installation/installing-superset-from-scratch#os-dependencies) before following these steps.
+You also need to install MySQL or [MariaDB](https://mariadb.com/downloads).
-Ensure Python versions >3.7, Then proceed with:
+Ensure that you are using Python version 3.7 or 3.8, then proceed with:
````bash
# Create a virtual environment and activate it (recommended)
@@ -428,12 +431,12 @@ python3 -m venv venv # setup a python3 virtualenv
source venv/bin/activate
# Install external dependencies
-pip install -r requirements/local.txt
+pip install -r requirements/testing.txt
# Install Superset in editable (development) mode
pip install -e .
-# Create an admin user in your metadata database
+# Create an admin user in your metadata database (use `admin` as username to be able to load the examples)
superset fab create-admin
# Initialize the database
@@ -442,11 +445,12 @@ superset db upgrade
# Create default roles and permissions
superset init
-# Load some data to play with (you must create an Admin user with the username `admin` for this command to work)
+# Load some data to play with.
+# Note: you MUST have previously created an admin user with the username `admin` for this command to work.
superset load-examples
# Start the Flask dev web server from inside your virtualenv.
-# Note that your page may not have css at this point.
+# Note that your page may not have CSS at this point.
# See instructions below how to build the front-end assets.
FLASK_ENV=development superset run -p 8088 --with-threads --reload --debugger
@@ -767,7 +771,7 @@ npm run test -- path/to/file.js
We use [Cypress](https://www.cypress.io/) for integration tests. Tests can be run by `tox -e cypress`. To open Cypress and explore tests first setup and run test server:
```bash
-export SUPERSET_CONFIG=tests.superset_test_config
+export SUPERSET_CONFIG=tests.integration_tests.superset_test_config
export SUPERSET_TESTENV=true
export ENABLE_REACT_CRUD_VIEWS=true
export CYPRESS_BASE_URL="http://localhost:8081"
diff --git a/docker/docker-bootstrap.sh b/docker/docker-bootstrap.sh
index e4468b8ad0315..4a8e27966424a 100755
--- a/docker/docker-bootstrap.sh
+++ b/docker/docker-bootstrap.sh
@@ -21,7 +21,7 @@ set -eo pipefail
REQUIREMENTS_LOCAL="/app/docker/requirements-local.txt"
# If Cypress run – overwrite the password for admin and export env variables
if [ "$CYPRESS_CONFIG" == "true" ]; then
- export SUPERSET_CONFIG=tests.superset_test_config
+ export SUPERSET_CONFIG=tests.integration_tests.superset_test_config
export SUPERSET_TESTENV=true
export ENABLE_REACT_CRUD_VIEWS=true
export SUPERSET__SQLALCHEMY_DATABASE_URI=postgresql+psycopg2://superset:superset@db:5432/superset
diff --git a/docs/src/pages/docs/Miscellaneous/issue_codes.mdx b/docs/src/pages/docs/Miscellaneous/issue_codes.mdx
index b06a466ee01cd..9666dcfdbd367 100644
--- a/docs/src/pages/docs/Miscellaneous/issue_codes.mdx
+++ b/docs/src/pages/docs/Miscellaneous/issue_codes.mdx
@@ -312,7 +312,6 @@ The results stored in the backend were stored in a different format, and no long
The query results were stored in a format that is no longer supported. Please re-run your query.
-
## Issue 1034
```
@@ -320,3 +319,19 @@ The database port provided is invalid.
```
Please check that the provided database port is an integer between 0 and 65535 (inclusive).
+
+## Issue 1035
+
+```
+Failed to start remote query on a worker.
+```
+
+The query was not started by an asynchronous worker. Please reach out to your administrator for further assistance.
+
+## Issue 1036
+
+```
+The database was deleted.
+```
+
+The operation failed because the database referenced no longer exists. Please reach out to your administrator for further assistance.
diff --git a/helm/superset/Chart.yaml b/helm/superset/Chart.yaml
index d51c9b58496eb..dad44a82cfad1 100644
--- a/helm/superset/Chart.yaml
+++ b/helm/superset/Chart.yaml
@@ -22,7 +22,7 @@ maintainers:
- name: craig-rueda
email: craig@craigrueda.com
url: https://github.com/craig-rueda
-version: 0.3.1
+version: 0.3.2
dependencies:
- name: postgresql
version: 10.2.0
diff --git a/helm/superset/templates/ingress.yaml b/helm/superset/templates/ingress.yaml
index b0888e4ede043..a13767faae587 100644
--- a/helm/superset/templates/ingress.yaml
+++ b/helm/superset/templates/ingress.yaml
@@ -17,7 +17,7 @@
{{ if .Values.ingress.enabled -}}
{{- $fullName := include "superset.fullname" . -}}
{{- $ingressPath := .Values.ingress.path -}}
-apiVersion: extensions/v1beta1
+apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ $fullName }}
@@ -46,9 +46,12 @@ spec:
- host: {{ . }}
http:
paths:
- - path: {{ $ingressPath }}
+ - path: {{ .Values.ingress.path }}
+ pathType: {{ .Values.ingress.pathType }}
backend:
- serviceName: {{ $fullName }}
- servicePort: http
+ service:
+ name: {{ $fullName }}
+ port:
+ name: http
{{- end }}
{{- end }}
diff --git a/helm/superset/values.yaml b/helm/superset/values.yaml
index fd859fecf3e26..884ad6c18279a 100644
--- a/helm/superset/values.yaml
+++ b/helm/superset/values.yaml
@@ -147,6 +147,7 @@ ingress:
# nginx.ingress.kubernetes.io/proxy-read-timeout: "300"
# nginx.ingress.kubernetes.io/proxy-send-timeout: "300"
path: /
+ pathType: ImplementationSpecific
hosts:
- chart-example.local
tls: []
diff --git a/scripts/python_tests.sh b/scripts/python_tests.sh
index d34e605a21caa..b9ef2cee21048 100755
--- a/scripts/python_tests.sh
+++ b/scripts/python_tests.sh
@@ -18,7 +18,7 @@
#
set -e
-export SUPERSET_CONFIG=${SUPERSET_CONFIG:-tests.superset_test_config}
+export SUPERSET_CONFIG=${SUPERSET_CONFIG:-tests.integration_tests.superset_test_config}
export SUPERSET_TESTENV=true
echo "Superset config module: $SUPERSET_CONFIG"
diff --git a/scripts/tests/run.sh b/scripts/tests/run.sh
index be1a11988e976..9f78318b72b51 100755
--- a/scripts/tests/run.sh
+++ b/scripts/tests/run.sh
@@ -62,7 +62,7 @@ DB_NAME="test"
DB_USER="superset"
DB_PASSWORD="superset"
export SUPERSET__SQLALCHEMY_DATABASE_URI=${SUPERSET__SQLALCHEMY_DATABASE_URI:-postgresql+psycopg2://"${DB_USER}":"${DB_PASSWORD}"@localhost/"${DB_NAME}"}
-export SUPERSET_CONFIG=${SUPERSET_CONFIG:-tests.superset_test_config}
+export SUPERSET_CONFIG=${SUPERSET_CONFIG:-tests.integration_tests.superset_test_config}
RUN_INIT=1
RUN_RESET_DB=1
RUN_TESTS=1
diff --git a/superset-frontend/cypress-base/cypress/integration/chart_list/card_view.test.ts b/superset-frontend/cypress-base/cypress/integration/chart_list/card_view.test.ts
index 6910b23b2faf0..1335fcb422204 100644
--- a/superset-frontend/cypress-base/cypress/integration/chart_list/card_view.test.ts
+++ b/superset-frontend/cypress-base/cypress/integration/chart_list/card_view.test.ts
@@ -22,7 +22,7 @@ describe('chart card view', () => {
beforeEach(() => {
cy.login();
cy.visit(CHART_LIST);
- cy.get('[data-test="card-view"]').click();
+ cy.get('[aria-label="card-view"]').click();
});
it('should load cards', () => {
diff --git a/superset-frontend/cypress-base/cypress/integration/chart_list/filter.test.ts b/superset-frontend/cypress-base/cypress/integration/chart_list/filter.test.ts
index dd9b573ebaf94..6892651e00efe 100644
--- a/superset-frontend/cypress-base/cypress/integration/chart_list/filter.test.ts
+++ b/superset-frontend/cypress-base/cypress/integration/chart_list/filter.test.ts
@@ -22,7 +22,7 @@ describe('chart card view filters', () => {
beforeEach(() => {
cy.login();
cy.visit(CHART_LIST);
- cy.get('[data-test="card-view"]').click();
+ cy.get('[aria-label="card-view"]').click();
});
it('should filter by owners correctly', () => {
@@ -89,7 +89,7 @@ describe('chart list view filters', () => {
beforeEach(() => {
cy.login();
cy.visit(CHART_LIST);
- cy.get('[data-test="list-view"]').click();
+ cy.get('[aria-label="list-view"]').click();
});
it('should filter by owners correctly', () => {
diff --git a/superset-frontend/cypress-base/cypress/integration/chart_list/list_view.test.ts b/superset-frontend/cypress-base/cypress/integration/chart_list/list_view.test.ts
index 7b51e984e2e63..6da5d90106d15 100644
--- a/superset-frontend/cypress-base/cypress/integration/chart_list/list_view.test.ts
+++ b/superset-frontend/cypress-base/cypress/integration/chart_list/list_view.test.ts
@@ -22,7 +22,7 @@ describe('chart list view', () => {
beforeEach(() => {
cy.login();
cy.visit(CHART_LIST);
- cy.get('[data-test="list-view"]').click();
+ cy.get('[aria-label="list-view"]').click();
});
it('should load rows', () => {
diff --git a/superset-frontend/cypress-base/cypress/integration/dashboard_list/card_view.test.ts b/superset-frontend/cypress-base/cypress/integration/dashboard_list/card_view.test.ts
index 35f11a17ea566..8bfc35d71c846 100644
--- a/superset-frontend/cypress-base/cypress/integration/dashboard_list/card_view.test.ts
+++ b/superset-frontend/cypress-base/cypress/integration/dashboard_list/card_view.test.ts
@@ -22,7 +22,7 @@ describe('Dashboard card view', () => {
beforeEach(() => {
cy.login();
cy.visit(DASHBOARD_LIST);
- cy.get('[data-test="card-view"]').click();
+ cy.get('[aria-label="card-view"]').click();
});
xit('should load cards', () => {
diff --git a/superset-frontend/cypress-base/cypress/integration/dashboard_list/filter.test.ts b/superset-frontend/cypress-base/cypress/integration/dashboard_list/filter.test.ts
index caff4c03f6755..d9bf0bb77b65c 100644
--- a/superset-frontend/cypress-base/cypress/integration/dashboard_list/filter.test.ts
+++ b/superset-frontend/cypress-base/cypress/integration/dashboard_list/filter.test.ts
@@ -22,7 +22,7 @@ describe('dashboard filters card view', () => {
beforeEach(() => {
cy.login();
cy.visit(DASHBOARD_LIST);
- cy.get('[data-test="card-view"]').click();
+ cy.get('[aria-label="card-view"]').click();
});
it('should filter by owners correctly', () => {
@@ -73,7 +73,7 @@ describe('dashboard filters list view', () => {
beforeEach(() => {
cy.login();
cy.visit(DASHBOARD_LIST);
- cy.get('[data-test="list-view"]').click();
+ cy.get('[aria-label="list-view"]').click();
});
it('should filter by owners correctly', () => {
diff --git a/superset-frontend/cypress-base/cypress/integration/dashboard_list/list_view.test.ts b/superset-frontend/cypress-base/cypress/integration/dashboard_list/list_view.test.ts
index 045d43c4c5c4c..a758552481f90 100644
--- a/superset-frontend/cypress-base/cypress/integration/dashboard_list/list_view.test.ts
+++ b/superset-frontend/cypress-base/cypress/integration/dashboard_list/list_view.test.ts
@@ -22,7 +22,7 @@ describe('dashboard list view', () => {
beforeEach(() => {
cy.login();
cy.visit(DASHBOARD_LIST);
- cy.get('[data-test="list-view"]').click();
+ cy.get('[aria-label="list-view"]').click();
});
xit('should load rows', () => {
diff --git a/superset-frontend/spec/fixtures/mockNativeFilters.ts b/superset-frontend/spec/fixtures/mockNativeFilters.ts
index afc4959d39fa0..e087072bfa73c 100644
--- a/superset-frontend/spec/fixtures/mockNativeFilters.ts
+++ b/superset-frontend/spec/fixtures/mockNativeFilters.ts
@@ -45,7 +45,6 @@ export const nativeFilters: NativeFiltersState = {
rootPath: ['ROOT_ID'],
excluded: [],
},
- isInstant: true,
controlValues: {
multiSelect: false,
enableEmptyFilter: false,
@@ -79,7 +78,6 @@ export const nativeFilters: NativeFiltersState = {
enableEmptyFilter: false,
inverseSelection: false,
},
- isInstant: true,
},
},
};
@@ -136,7 +134,6 @@ export const singleNativeFiltersState = {
cascadeParentIds: [],
scope: { rootPath: ['ROOT_ID'], excluded: [227, 229] },
inverseSelection: false,
- isInstant: true,
allowsMultipleValues: false,
isRequired: false,
},
diff --git a/superset-frontend/spec/javascripts/dashboard/fixtures/mockNativeFilters.ts b/superset-frontend/spec/javascripts/dashboard/fixtures/mockNativeFilters.ts
index 8a106a2b5e881..0bf022d55fe8e 100644
--- a/superset-frontend/spec/javascripts/dashboard/fixtures/mockNativeFilters.ts
+++ b/superset-frontend/spec/javascripts/dashboard/fixtures/mockNativeFilters.ts
@@ -62,7 +62,6 @@ export const nativeFiltersInfo: NativeFiltersState = {
rootPath: [],
excluded: [],
},
- isInstant: true,
controlValues: {
allowsMultipleValues: true,
isRequired: false,
diff --git a/superset-frontend/src/components/ErrorMessage/types.ts b/superset-frontend/src/components/ErrorMessage/types.ts
index e58712e74ec2f..496a9b4cefe58 100644
--- a/superset-frontend/src/components/ErrorMessage/types.ts
+++ b/superset-frontend/src/components/ErrorMessage/types.ts
@@ -58,6 +58,7 @@ export const ErrorTypeEnum = {
// Other errors
BACKEND_TIMEOUT_ERROR: 'BACKEND_TIMEOUT_ERROR',
+ DATABASE_NOT_FOUND_ERROR: 'DATABASE_NOT_FOUND_ERROR',
// Sqllab error
MISSING_TEMPLATE_PARAMS_ERROR: 'MISSING_TEMPLATE_PARAMS_ERROR',
@@ -68,6 +69,7 @@ export const ErrorTypeEnum = {
INVALID_CVAS_QUERY_ERROR: 'INVALID_CVAS_QUERY_ERROR',
SQLLAB_TIMEOUT_ERROR: 'SQLLAB_TIMEOUT_ERROR',
RESULTS_BACKEND_ERROR: 'RESULTS_BACKEND_ERROR',
+ ASYNC_WORKERS_ERROR: 'ASYNC_WORKERS_ERROR',
// Generic errors
GENERIC_COMMAND_ERROR: 'GENERIC_COMMAND_ERROR',
diff --git a/superset-frontend/src/components/Form/LabeledErrorBoundInput.test.jsx b/superset-frontend/src/components/Form/LabeledErrorBoundInput.test.jsx
index 86b6324daed50..ebfd2b30e42b0 100644
--- a/superset-frontend/src/components/Form/LabeledErrorBoundInput.test.jsx
+++ b/superset-frontend/src/components/Form/LabeledErrorBoundInput.test.jsx
@@ -66,7 +66,7 @@ describe('LabeledErrorBoundInput', () => {
const label = screen.getByText(/username/i);
const textboxInput = screen.getByRole('textbox');
- const tooltipIcon = screen.getByTestId('info-solid-small');
+ const tooltipIcon = screen.getByRole('img');
fireEvent.mouseOver(tooltipIcon);
diff --git a/superset-frontend/src/components/InfoTooltip/index.tsx b/superset-frontend/src/components/InfoTooltip/index.tsx
index 245c95b026094..968f5df715980 100644
--- a/superset-frontend/src/components/InfoTooltip/index.tsx
+++ b/superset-frontend/src/components/InfoTooltip/index.tsx
@@ -20,7 +20,7 @@
import React from 'react';
import { styled } from '@superset-ui/core';
import { Tooltip } from 'src/components/Tooltip';
-import Icon from 'src/components/Icon';
+import Icons from 'src/components/Icons';
export interface InfoTooltipProps {
className?: string;
@@ -75,7 +75,7 @@ export default function InfoTooltip({
overlayStyle={overlayStyle}
color={bgColor}
>
-
+
);
}
diff --git a/superset-frontend/src/components/ListView/ListView.tsx b/superset-frontend/src/components/ListView/ListView.tsx
index 22729bd192e46..f74e799ee29da 100644
--- a/superset-frontend/src/components/ListView/ListView.tsx
+++ b/superset-frontend/src/components/ListView/ListView.tsx
@@ -23,7 +23,7 @@ import Alert from 'src/components/Alert';
import { ReactComponent as EmptyImage } from 'images/empty.svg';
import cx from 'classnames';
import Button from 'src/components/Button';
-import Icon from 'src/components/Icon';
+import Icons from 'src/components/Icons';
import IndeterminateCheckbox from 'src/components/IndeterminateCheckbox';
import { TableCollection, Pagination } from 'src/components/dataViewCommon';
import CardCollection from './CardCollection';
@@ -142,7 +142,7 @@ const ViewModeContainer = styled.div`
display: inline-block;
border-radius: ${({ theme }) => theme.gridUnit / 2}px;
padding: ${({ theme }) => theme.gridUnit}px;
- padding-bottom: 0;
+ padding-bottom: ${({ theme }) => theme.gridUnit * 0.5}px;
&:first-of-type {
margin-right: ${({ theme }) => theme.gridUnit * 2}px;
@@ -182,7 +182,7 @@ const ViewModeToggle = ({
}}
className={cx('toggle-button', { active: mode === 'card' })}
>
-
+
-
+
);
diff --git a/superset-frontend/src/dashboard/components/DashboardBuilder/DashboardContainer.tsx b/superset-frontend/src/dashboard/components/DashboardBuilder/DashboardContainer.tsx
index 6273d09550ba9..933843337a85d 100644
--- a/superset-frontend/src/dashboard/components/DashboardBuilder/DashboardContainer.tsx
+++ b/superset-frontend/src/dashboard/components/DashboardBuilder/DashboardContainer.tsx
@@ -68,22 +68,24 @@ const DashboardContainer: FC = ({ topLevelTabs }) => {
}, [getLeafComponentIdFromPath(directPathToChild)]);
// recalculate charts and tabs in scopes of native filters only when a scope or dashboard layout changes
- const nativeFiltersValues = Object.values(nativeFilters);
- const scopes = nativeFiltersValues.map(filter => filter.scope);
+ const filterScopes = Object.values(nativeFilters).map(filter => ({
+ id: filter.id,
+ scope: filter.scope,
+ }));
useEffect(() => {
if (
!isFeatureEnabled(FeatureFlag.DASHBOARD_NATIVE_FILTERS) ||
- nativeFiltersValues.length === 0
+ filterScopes.length === 0
) {
return;
}
- const filterScopes = nativeFiltersValues.map(filter => {
- const filterScope = filter.scope;
+ const scopes = filterScopes.map(filterScope => {
+ const { scope } = filterScope;
const chartsInScope: number[] = getChartIdsInFilterScope({
filterScope: {
- scope: filterScope.rootPath,
+ scope: scope.rootPath,
// @ts-ignore
- immune: filterScope.excluded,
+ immune: scope.excluded,
},
});
const tabsInScope = findTabsWithChartsInScope(
@@ -91,13 +93,13 @@ const DashboardContainer: FC = ({ topLevelTabs }) => {
chartsInScope,
);
return {
- filterId: filter.id,
+ filterId: filterScope.id,
tabsInScope: Array.from(tabsInScope),
chartsInScope,
};
});
- dispatch(setInScopeStatusOfFilters(filterScopes));
- }, [JSON.stringify(scopes), JSON.stringify(dashboardLayout)]);
+ dispatch(setInScopeStatusOfFilters(scopes));
+ }, [JSON.stringify(filterScopes), dashboardLayout, dispatch]);
const childIds: string[] = topLevelTabs
? topLevelTabs.children
diff --git a/superset-frontend/src/dashboard/components/gridComponents/ChartHolder.jsx b/superset-frontend/src/dashboard/components/gridComponents/ChartHolder.jsx
index 32b07953e1e85..84d121cddfea0 100644
--- a/superset-frontend/src/dashboard/components/gridComponents/ChartHolder.jsx
+++ b/superset-frontend/src/dashboard/components/gridComponents/ChartHolder.jsx
@@ -130,7 +130,7 @@ const FilterFocusHighlight = React.forwardRef(
if (focusedNativeFilterId) {
if (
- nativeFilters.filters[focusedNativeFilterId].chartsInScope.includes(
+ nativeFilters.filters[focusedNativeFilterId].chartsInScope?.includes(
chartId,
)
) {
diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterBar.test.tsx b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterBar.test.tsx
index 17fc50e772e6d..4507064eaa594 100644
--- a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterBar.test.tsx
+++ b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterBar.test.tsx
@@ -53,7 +53,7 @@ class MainPreset extends Preset {
}
}
-fetchMock.get(`glob:*/api/v1/dataset/1`, {
+fetchMock.get('glob:*/api/v1/dataset/7', {
description_columns: {},
id: 1,
label_columns: {
@@ -156,8 +156,7 @@ describe('FilterBar', () => {
"defaultDataMask":{"filterState":{"value":null}},
"controlValues":{},
"cascadeParentIds":[],
- "scope":{"rootPath":["ROOT_ID"],"excluded":[]},
- "isInstant":false
+ "scope":{"rootPath":["ROOT_ID"],"excluded":[]}
}],
"filter_sets_configuration":[{
"name":"${FILTER_SET_NAME}",
@@ -168,17 +167,16 @@ describe('FilterBar', () => {
"name":"${FILTER_NAME}",
"filterType":"filter_time",
"targets":[{}],
- "defaultDataMask":{"filterState":{"value":"Last week"},"extraFormData":{"time_range":"Last week"}},
+ "defaultDataMask":{"filterState":{},"extraFormData":{}},
"controlValues":{},
"cascadeParentIds":[],
- "scope":{"rootPath":["ROOT_ID"],"excluded":[]},
- "isInstant":false
+ "scope":{"rootPath":["ROOT_ID"],"excluded":[]}
}
},
"dataMask":{
"${filterId}":{
- "extraFormData":{"time_range":"Last week"},
- "filterState":{"value":"Last week"},
+ "extraFormData":{},
+ "filterState":{},
"ownState":{},
"id":"${filterId}"
}
@@ -192,7 +190,14 @@ describe('FilterBar', () => {
beforeEach(() => {
jest.clearAllMocks();
fetchMock.get(
- 'http://localhost/api/v1/time_range/?q=%27Last%20day%27',
+ 'glob:*/api/v1/time_range/?q=%27No%20filter%27',
+ {
+ result: { since: '', until: '', timeRange: 'No filter' },
+ },
+ { overwriteRoutes: true },
+ );
+ fetchMock.get(
+ 'glob:*/api/v1/time_range/?q=%27Last%20day%27',
{
result: {
since: '2021-04-13T00:00:00',
@@ -203,7 +208,7 @@ describe('FilterBar', () => {
{ overwriteRoutes: true },
);
fetchMock.get(
- 'http://localhost/api/v1/time_range/?q=%27Last%20week%27',
+ 'glob:*/api/v1/time_range/?q=%27Last%20week%27',
{
result: {
since: '2021-04-07T00:00:00',
diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/index.tsx b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/index.tsx
index 84d4b5657e19a..e175fc0127b09 100644
--- a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/index.tsx
+++ b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/index.tsx
@@ -216,11 +216,10 @@ const FilterBar: React.FC = ({
}
// force instant updating on initialization for filters with `requiredFirst` is true or instant filters
else if (
- (dataMaskSelected[filter.id] && filter.isInstant) ||
// filterState.value === undefined - means that value not initialized
- (dataMask.filterState?.value !== undefined &&
- dataMaskSelected[filter.id]?.filterState?.value === undefined &&
- filter.requiredFirst)
+ dataMask.filterState?.value !== undefined &&
+ dataMaskSelected[filter.id]?.filterState?.value === undefined &&
+ filter.requiredFirst
) {
dispatch(updateDataMask(filter.id, dataMask));
}
diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/ColumnSelect.tsx b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/ColumnSelect.tsx
index 5ee4095b35d9e..5a05119e54c6a 100644
--- a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/ColumnSelect.tsx
+++ b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/ColumnSelect.tsx
@@ -34,8 +34,9 @@ interface ColumnSelectProps {
formField?: string;
filterId: string;
datasetId?: number;
- value?: string;
+ value?: string | string[];
onChange?: (value: string) => void;
+ mode?: 'multiple' | 'tags';
}
const localCache = new Map();
@@ -57,6 +58,7 @@ export function ColumnSelect({
datasetId,
value,
onChange,
+ mode,
}: ColumnSelectProps) {
const [columns, setColumns] = useState();
const { addDangerToast } = useToasts();
@@ -101,11 +103,11 @@ export function ColumnSelect({
endpoint: `/api/v1/dataset/${datasetId}`,
}).then(
({ json: { result } }) => {
- if (
- !result.columns.some(
- (column: Column) => column.column_name === value,
- )
- ) {
+ const lookupValue = Array.isArray(value) ? value : [value];
+ const valueExists = result.columns.some((column: Column) =>
+ lookupValue?.includes(column.column_name),
+ );
+ if (!valueExists) {
resetColumnField();
}
setColumns(result.columns);
@@ -124,7 +126,8 @@ export function ColumnSelect({
return (