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 (