You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by mi...@apache.org on 2024/02/22 17:41:39 UTC

(superset) branch 3.1 updated (24e7be605b -> 5ac4d830f0)

This is an automated email from the ASF dual-hosted git repository.

michaelsmolina pushed a change to branch 3.1
in repository https://gitbox.apache.org/repos/asf/superset.git


    from 24e7be605b chore: Adds 3.1.1 RC1 data to CHANGELOG.md
     new a57358ec49 fix: Timeseries Y-axis format with contribution mode (#27106)
     new 8819157336 fix: upgrade cryptography to major 42 (#27113)
     new f5dc821f3d fix: bump grpcio, urllib3 and paramiko (#27124)
     new 02d754e7c8 fix: gevent upgrade to 23.9.1 (#27112)
     new c743822031 fix: RLS modal overflow (#27128)
     new c94a4609bb fix(pivot-table-v2): Added forgotten translation pivot table v2 (#22840)
     new 0308095a22 chore: lower cryptography min version to 41.0.2 (#27129)
     new 7ab62e1aaa fix: Plain error message when visiting a dashboard via permalink without permissions (#27132)
     new c839c5734a fix: Duplicated toast messages (#27135)
     new 4b56670aa2 feat: bump FAB to 4.4.0 (#27159)
     new 7b589878b7 fix: unlock and bump werkzeug (#27164)
     new 1382aa6f39 fix: CSRF exempt unit_tests (#27168)
     new 0eec53ad96 fix(sqllab): typeahead search is broken in db selector (#27181)
     new 5ac4d830f0 fix: Failed to execute importScripts on worker-css (#27191)

The 14 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .github/workflows/superset-python-unittest.yml     | 14 +++-
 requirements/base.txt                              | 31 +++-----
 requirements/development.txt                       |  2 -
 requirements/docker.txt                            |  2 +-
 requirements/integration.txt                       |  6 --
 requirements/testing.txt                           |  8 +-
 setup.py                                           |  7 +-
 .../src/number-format/NumberFormats.ts             |  6 +-
 .../legacy-plugin-chart-heatmap/src/Heatmap.js     |  2 +-
 .../src/MixedTimeseries/transformProps.ts          |  2 +
 .../src/Timeseries/transformProps.ts               |  4 +-
 .../plugin-chart-echarts/src/utils/formatters.ts   | 11 ++-
 .../test/utils/formatters.test.ts}                 | 31 +++-----
 .../src/react-pivottable/TableRenderers.jsx        |  6 +-
 .../src/SqlLab/reducers/getInitialState.ts         |  4 -
 .../src/components/AsyncAceEditor/index.tsx        |  4 +
 .../DatabaseSelector/DatabaseSelector.test.tsx     | 26 +++++++
 .../src/components/DatabaseSelector/index.tsx      |  4 +-
 .../MessageToasts/getToastsFromPyFlashMessages.js  | 40 ----------
 .../getToastsFromPyFlashMessages.test.js           | 48 ------------
 .../src/dashboard/components/Dashboard.jsx         |  2 -
 .../src/dashboard/components/Dashboard.test.jsx    |  1 -
 .../FilterBarSettings/FilterBarSettings.test.tsx   |  1 -
 .../src/dashboard/containers/Dashboard.ts          |  1 -
 superset-frontend/src/dashboard/types.ts           |  1 -
 .../src/features/rls/RowLevelSecurityModal.tsx     | 88 ++++++++++------------
 superset-frontend/src/features/rls/constants.ts    |  2 +-
 .../index.ts => src/types/ace-builds.ts}           |  3 +-
 superset-frontend/webpack.config.js                |  4 +
 superset/views/core.py                             |  6 +-
 tests/integration_tests/async_events/api_tests.py  |  4 +-
 tests/integration_tests/charts/data/api_tests.py   |  2 +-
 tests/unit_tests/security/api_test.py              |  6 +-
 33 files changed, 157 insertions(+), 222 deletions(-)
 copy superset-frontend/{packages/superset-ui-core/test/query/getColumnLabel.test.ts => plugins/plugin-chart-echarts/test/utils/formatters.test.ts} (56%)
 delete mode 100644 superset-frontend/src/components/MessageToasts/getToastsFromPyFlashMessages.js
 delete mode 100644 superset-frontend/src/components/MessageToasts/getToastsFromPyFlashMessages.test.js
 copy superset-frontend/{packages/superset-ui-core/src/hooks/useChangeEffect/index.ts => src/types/ace-builds.ts} (93%)


(superset) 02/14: fix: upgrade cryptography to major 42 (#27113)

Posted by mi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

michaelsmolina pushed a commit to branch 3.1
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 88191573364c72806609a3052750661981da34d1
Author: Daniel Vaz Gaspar <da...@gmail.com>
AuthorDate: Wed Feb 14 19:11:51 2024 +0000

    fix: upgrade cryptography to major 42 (#27113)
    
    (cherry picked from commit 152cd70b5f77828f1f63c5c40f7a2cb2bcfa156e)
---
 requirements/base.txt | 2 +-
 setup.py              | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/requirements/base.txt b/requirements/base.txt
index 95eeaa450c..e134f367e2 100644
--- a/requirements/base.txt
+++ b/requirements/base.txt
@@ -76,7 +76,7 @@ cron-descriptor==1.2.24
     # via apache-superset
 croniter==1.0.15
     # via apache-superset
-cryptography==41.0.2
+cryptography==42.0.2
     # via
     #   apache-superset
     #   paramiko
diff --git a/setup.py b/setup.py
index 423a21d887..32c68d025c 100644
--- a/setup.py
+++ b/setup.py
@@ -80,7 +80,7 @@ setup(
         "colorama",
         "croniter>=0.3.28",
         "cron-descriptor",
-        "cryptography>=41.0.2, <41.1.0",
+        "cryptography>=42.0.0, <43.0.0",
         "deprecation>=2.1.0, <2.2.0",
         "flask>=2.2.5, <3.0.0",
         "flask-appbuilder>=4.3.11, <5.0.0",


(superset) 08/14: fix: Plain error message when visiting a dashboard via permalink without permissions (#27132)

Posted by mi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

michaelsmolina pushed a commit to branch 3.1
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 7ab62e1aaa03b01f8ecb2a5accf9e31b4566359a
Author: Michael S. Molina <70...@users.noreply.github.com>
AuthorDate: Thu Feb 15 16:26:33 2024 -0500

    fix: Plain error message when visiting a dashboard via permalink without permissions (#27132)
---
 superset/views/core.py | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/superset/views/core.py b/superset/views/core.py
index 9ad2f63fdc..3e895e6b4b 100755
--- a/superset/views/core.py
+++ b/superset/views/core.py
@@ -47,6 +47,7 @@ from superset.async_events.async_query_manager import AsyncQueryTokenException
 from superset.commands.chart.exceptions import ChartNotFoundError
 from superset.commands.chart.warm_up_cache import ChartWarmUpCacheCommand
 from superset.commands.dashboard.importers.v0 import ImportDashboardsCommand
+from superset.commands.dashboard.exceptions import DashboardAccessDeniedError
 from superset.commands.dashboard.permalink.get import GetDashboardPermalinkCommand
 from superset.commands.dataset.exceptions import DatasetNotFoundError
 from superset.commands.explore.form_data.create import CreateFormDataCommand
@@ -880,6 +881,9 @@ class Superset(BaseSupersetView):  # pylint: disable=too-many-public-methods
         except DashboardPermalinkGetFailedError as ex:
             flash(__("Error: %(msg)s", msg=ex.message), "danger")
             return redirect("/dashboard/list/")
+        except DashboardAccessDeniedError as ex:
+            flash(__("Error: %(msg)s", msg=ex.message), "danger")
+            return redirect("/dashboard/list/")
         if not value:
             return json_error_response(_("permalink state not found"), status=404)
         dashboard_id, state = value["dashboardId"], value.get("state", {})


(superset) 03/14: fix: bump grpcio, urllib3 and paramiko (#27124)

Posted by mi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

michaelsmolina pushed a commit to branch 3.1
in repository https://gitbox.apache.org/repos/asf/superset.git

commit f5dc821f3d520f0e2f9a8a76ea853031134c52af
Author: Daniel Vaz Gaspar <da...@gmail.com>
AuthorDate: Thu Feb 15 13:02:25 2024 +0000

    fix: bump grpcio, urllib3 and paramiko (#27124)
    
    (cherry picked from commit e43097329ff16f0661f275382f780165e4dad3ec)
---
 requirements/base.txt    | 4 ++--
 requirements/testing.txt | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/requirements/base.txt b/requirements/base.txt
index e134f367e2..e97e52fe54 100644
--- a/requirements/base.txt
+++ b/requirements/base.txt
@@ -232,7 +232,7 @@ packaging==23.1
     #   shillelagh
 pandas[performance]==2.0.3
     # via apache-superset
-paramiko==2.11.0
+paramiko==3.4.0
     # via sshtunnel
 parsedatetime==2.6
     # via apache-superset
@@ -350,7 +350,7 @@ tzdata==2023.3
     # via pandas
 url-normalize==1.4.3
     # via requests-cache
-urllib3==1.26.6
+urllib3==1.26.18
     # via
     #   requests
     #   requests-cache
diff --git a/requirements/testing.txt b/requirements/testing.txt
index b40497c8fc..e7095b7f72 100644
--- a/requirements/testing.txt
+++ b/requirements/testing.txt
@@ -68,12 +68,12 @@ googleapis-common-protos==1.59.0
     # via
     #   google-api-core
     #   grpcio-status
-grpcio==1.54.0
+grpcio==1.60.1
     # via
     #   google-api-core
     #   google-cloud-bigquery
     #   grpcio-status
-grpcio-status==1.54.0
+grpcio-status==1.60.1
     # via google-api-core
 iniconfig==2.0.0
     # via pytest


(superset) 04/14: fix: gevent upgrade to 23.9.1 (#27112)

Posted by mi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

michaelsmolina pushed a commit to branch 3.1
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 02d754e7c8e52bd7727715401ccd7db01a00af86
Author: Daniel Vaz Gaspar <da...@gmail.com>
AuthorDate: Thu Feb 15 16:20:30 2024 +0000

    fix: gevent upgrade to 23.9.1 (#27112)
---
 requirements/docker.txt | 2 +-
 setup.py                | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/requirements/docker.txt b/requirements/docker.txt
index 1c6009b944..be65b7d36b 100644
--- a/requirements/docker.txt
+++ b/requirements/docker.txt
@@ -10,7 +10,7 @@
     # via
     #   -r requirements/base.in
     #   -r requirements/docker.in
-gevent==22.10.2
+gevent==23.9.1
     # via -r requirements/docker.in
 psycopg2-binary==2.9.6
     # via apache-superset
diff --git a/setup.py b/setup.py
index 32c68d025c..5488a3d761 100644
--- a/setup.py
+++ b/setup.py
@@ -164,6 +164,7 @@ setup(
         "excel": ["xlrd>=1.2.0, <1.3"],
         "firebird": ["sqlalchemy-firebird>=0.7.0, <0.8"],
         "firebolt": ["firebolt-sqlalchemy>=0.0.1"],
+        "gevent": ["gevent>=23.9.1"],
         "gsheets": ["shillelagh[gsheetsapi]>=1.2.10, <2"],
         "hana": ["hdbcli==2.4.162", "sqlalchemy_hana==0.4.0"],
         "hive": [


(superset) 13/14: fix(sqllab): typeahead search is broken in db selector (#27181)

Posted by mi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

michaelsmolina pushed a commit to branch 3.1
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 0eec53ad9633cc64ad4395484657c5c29798adfe
Author: JUST.in DO IT <ju...@airbnb.com>
AuthorDate: Wed Feb 21 06:03:41 2024 -0800

    fix(sqllab): typeahead search is broken in db selector (#27181)
    
    (cherry picked from commit 8fbaf84f66585146c17c23ec3e530d59902efd75)
---
 .../DatabaseSelector/DatabaseSelector.test.tsx     | 26 ++++++++++++++++++++++
 .../src/components/DatabaseSelector/index.tsx      |  4 ++--
 2 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/superset-frontend/src/components/DatabaseSelector/DatabaseSelector.test.tsx b/superset-frontend/src/components/DatabaseSelector/DatabaseSelector.test.tsx
index 874d22ea6b..18e6769912 100644
--- a/superset-frontend/src/components/DatabaseSelector/DatabaseSelector.test.tsx
+++ b/superset-frontend/src/components/DatabaseSelector/DatabaseSelector.test.tsx
@@ -229,6 +229,32 @@ test('Should database select display options', async () => {
   expect(await screen.findByText('test-mysql')).toBeInTheDocument();
 });
 
+test('Should fetch the search keyword when total count exceeds initial options', async () => {
+  fetchMock.get(
+    databaseApiRoute,
+    {
+      ...fakeDatabaseApiResult,
+      count: fakeDatabaseApiResult.result.length + 1,
+    },
+    { overwriteRoutes: true },
+  );
+
+  const props = createProps();
+  render(<DatabaseSelector {...props} />, { useRedux: true, store });
+  const select = screen.getByRole('combobox', {
+    name: 'Select database or type to search databases',
+  });
+  await waitFor(() =>
+    expect(fetchMock.calls(databaseApiRoute)).toHaveLength(1),
+  );
+  expect(select).toBeInTheDocument();
+  userEvent.type(select, 'keywordtest');
+  await waitFor(() =>
+    expect(fetchMock.calls(databaseApiRoute)).toHaveLength(2),
+  );
+  expect(fetchMock.calls(databaseApiRoute)[1][0]).toContain('keywordtest');
+});
+
 test('should show empty state if there are no options', async () => {
   fetchMock.reset();
   fetchMock.get(databaseApiRoute, { result: [] });
diff --git a/superset-frontend/src/components/DatabaseSelector/index.tsx b/superset-frontend/src/components/DatabaseSelector/index.tsx
index 7b4afd9af0..0c0268db5c 100644
--- a/superset-frontend/src/components/DatabaseSelector/index.tsx
+++ b/superset-frontend/src/components/DatabaseSelector/index.tsx
@@ -167,7 +167,7 @@ export default function DatabaseSelector({
         });
         const endpoint = `/api/v1/database/?q=${queryParams}`;
         return SupersetClient.get({ endpoint }).then(({ json }) => {
-          const { result } = json;
+          const { result, count } = json;
           if (getDbList) {
             getDbList(result);
           }
@@ -189,7 +189,7 @@ export default function DatabaseSelector({
 
           return {
             data: options,
-            totalCount: options.length,
+            totalCount: count ?? options.length,
           };
         });
       },


(superset) 05/14: fix: RLS modal overflow (#27128)

Posted by mi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

michaelsmolina pushed a commit to branch 3.1
in repository https://gitbox.apache.org/repos/asf/superset.git

commit c743822031dafd16920331089373d8268f760e99
Author: Michael S. Molina <70...@users.noreply.github.com>
AuthorDate: Thu Feb 15 11:46:35 2024 -0500

    fix: RLS modal overflow (#27128)
    
    (cherry picked from commit 506ea756ad858f7325adecc73e4969f4476c642d)
---
 .../src/features/rls/RowLevelSecurityModal.tsx     | 88 ++++++++++------------
 superset-frontend/src/features/rls/constants.ts    |  2 +-
 2 files changed, 42 insertions(+), 48 deletions(-)

diff --git a/superset-frontend/src/features/rls/RowLevelSecurityModal.tsx b/superset-frontend/src/features/rls/RowLevelSecurityModal.tsx
index 7e4143e582..9997de5da7 100644
--- a/superset-frontend/src/features/rls/RowLevelSecurityModal.tsx
+++ b/superset-frontend/src/features/rls/RowLevelSecurityModal.tsx
@@ -28,12 +28,13 @@ import Modal from 'src/components/Modal';
 import React, { useCallback, useEffect, useMemo, useState } from 'react';
 import Icons from 'src/components/Icons';
 import Select from 'src/components/Select/Select';
+import { TextArea } from 'src/components/Input';
 import AsyncSelect from 'src/components/Select/AsyncSelect';
 import rison from 'rison';
 import { LabeledErrorBoundInput } from 'src/components/Form';
 import InfoTooltip from 'src/components/InfoTooltip';
 import { useSingleViewResource } from 'src/views/CRUD/hooks';
-import { FilterOptions } from './constants';
+import { FILTER_OPTIONS } from './constants';
 import { FilterType, RLSObject, RoleObject, TableObject } from './types';
 
 const noMargins = css`
@@ -48,13 +49,11 @@ const StyledModal = styled(Modal)`
   max-width: 1200px;
   min-width: min-content;
   width: 100%;
-  .ant-modal-body {
-    overflow: initial;
-  }
   .ant-modal-footer {
     white-space: nowrap;
   }
 `;
+
 const StyledIcon = (theme: SupersetTheme) => css`
   margin: auto ${theme.gridUnit * 2}px auto 0;
   color: ${theme.colors.grayscale.base};
@@ -106,11 +105,9 @@ const StyledInputContainer = styled.div`
   }
 `;
 
-const StyledTextArea = styled.textarea`
-  height: 100px;
+const StyledTextArea = styled(TextArea)`
   resize: none;
   margin-top: ${({ theme }) => theme.gridUnit}px;
-  border: 1px solid ${({ theme }) => theme.colors.secondary.light3};
 `;
 
 export interface RowLevelSecurityModalProps {
@@ -155,23 +152,25 @@ function RowLevelSecurityModal(props: RowLevelSecurityModalProps) {
     addDangerToast,
   );
 
-  // initialize
-  useEffect(() => {
-    if (!isEditMode) {
-      setCurrentRule({ ...DEAFULT_RULE });
-    } else if (rule?.id !== null && !loading && !fetchError) {
-      fetchResource(rule.id as number);
-    }
-  }, [rule]);
+  const updateRuleState = (name: string, value: any) => {
+    setCurrentRule(currentRuleData => ({
+      ...currentRuleData,
+      [name]: value,
+    }));
+  };
 
-  useEffect(() => {
-    if (resource) {
-      setCurrentRule({ ...resource, id: rule?.id });
-      const selectedTableAndRoles = getSelectedData();
-      updateRuleState('tables', selectedTableAndRoles?.tables || []);
-      updateRuleState('roles', selectedTableAndRoles?.roles || []);
+  // * state validators *
+  const validate = () => {
+    if (
+      currentRule?.name &&
+      currentRule?.clause &&
+      currentRule.tables?.length
+    ) {
+      setDisableSave(false);
+    } else {
+      setDisableSave(true);
     }
-  }, [resource]);
+  };
 
   // find selected tables and roles
   const getSelectedData = useCallback(() => {
@@ -202,6 +201,24 @@ function RowLevelSecurityModal(props: RowLevelSecurityModalProps) {
     return { tables, roles };
   }, [resource?.tables, resource?.roles]);
 
+  // initialize
+  useEffect(() => {
+    if (!isEditMode) {
+      setCurrentRule({ ...DEAFULT_RULE });
+    } else if (rule?.id !== null && !loading && !fetchError) {
+      fetchResource(rule.id as number);
+    }
+  }, [rule]);
+
+  useEffect(() => {
+    if (resource) {
+      setCurrentRule({ ...resource, id: rule?.id });
+      const selectedTableAndRoles = getSelectedData();
+      updateRuleState('tables', selectedTableAndRoles?.tables || []);
+      updateRuleState('roles', selectedTableAndRoles?.roles || []);
+    }
+  }, [resource]);
+
   // validate
   const currentRuleSafe = currentRule || {};
   useEffect(() => {
@@ -214,13 +231,6 @@ function RowLevelSecurityModal(props: RowLevelSecurityModalProps) {
     label: string;
   };
 
-  const updateRuleState = (name: string, value: any) => {
-    setCurrentRule(currentRuleData => ({
-      ...currentRuleData,
-      [name]: value,
-    }));
-  };
-
   const onTextChange = (target: HTMLInputElement | HTMLTextAreaElement) => {
     updateRuleState(target.name, target.value);
   };
@@ -318,19 +328,6 @@ function RowLevelSecurityModal(props: RowLevelSecurityModalProps) {
     [],
   );
 
-  // * state validators *
-  const validate = () => {
-    if (
-      currentRule?.name &&
-      currentRule?.clause &&
-      currentRule.tables?.length
-    ) {
-      setDisableSave(false);
-    } else {
-      setDisableSave(true);
-    }
-  };
-
   return (
     <StyledModal
       className="no-content-padding"
@@ -373,7 +370,6 @@ function RowLevelSecurityModal(props: RowLevelSecurityModalProps) {
               hasTooltip
             />
           </StyledInputContainer>
-
           <StyledInputContainer>
             <div className="control-label">
               {t('Filter Type')}{' '}
@@ -390,12 +386,11 @@ function RowLevelSecurityModal(props: RowLevelSecurityModalProps) {
                 placeholder={t('Filter Type')}
                 onChange={onFilterChange}
                 value={currentRule?.filter_type}
-                options={FilterOptions}
+                options={FILTER_OPTIONS}
                 data-test="rule-filter-type-test"
               />
             </div>
           </StyledInputContainer>
-
           <StyledInputContainer>
             <div className="control-label">
               {t('Datasets')} <span className="required">*</span>
@@ -455,7 +450,6 @@ function RowLevelSecurityModal(props: RowLevelSecurityModalProps) {
               data-test="group-key-test"
             />
           </StyledInputContainer>
-
           <StyledInputContainer>
             <div className="control-label">
               <LabeledErrorBoundInput
@@ -477,11 +471,11 @@ function RowLevelSecurityModal(props: RowLevelSecurityModalProps) {
               />
             </div>
           </StyledInputContainer>
-
           <StyledInputContainer>
             <div className="control-label">{t('Description')}</div>
             <div className="input-container">
               <StyledTextArea
+                rows={4}
                 name="description"
                 value={currentRule ? currentRule.description : ''}
                 onChange={event => onTextChange(event.target)}
diff --git a/superset-frontend/src/features/rls/constants.ts b/superset-frontend/src/features/rls/constants.ts
index ceb0982c5f..9bb0ca3e6c 100644
--- a/superset-frontend/src/features/rls/constants.ts
+++ b/superset-frontend/src/features/rls/constants.ts
@@ -19,7 +19,7 @@
 
 import { t } from '@superset-ui/core';
 
-export const FilterOptions = [
+export const FILTER_OPTIONS = [
   {
     label: t('Regular'),
     value: 'Regular',


(superset) 07/14: chore: lower cryptography min version to 41.0.2 (#27129)

Posted by mi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

michaelsmolina pushed a commit to branch 3.1
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 0308095a223ec046b142e43fb366062f422d770a
Author: Joe Li <jo...@preset.io>
AuthorDate: Thu Feb 15 10:27:30 2024 -0800

    chore: lower cryptography min version to 41.0.2 (#27129)
    
    (cherry picked from commit d2910b0b87232b88be1f8199a3501df99e108468)
---
 setup.py | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/setup.py b/setup.py
index 5488a3d761..998b134dc7 100644
--- a/setup.py
+++ b/setup.py
@@ -80,7 +80,8 @@ setup(
         "colorama",
         "croniter>=0.3.28",
         "cron-descriptor",
-        "cryptography>=42.0.0, <43.0.0",
+        # snowflake-connector-python as of 3.7.0 doesn't support >=42.* therefore lowering the min to 41.0.2
+        "cryptography>=41.0.2, <43.0.0",
         "deprecation>=2.1.0, <2.2.0",
         "flask>=2.2.5, <3.0.0",
         "flask-appbuilder>=4.3.11, <5.0.0",


(superset) 09/14: fix: Duplicated toast messages (#27135)

Posted by mi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

michaelsmolina pushed a commit to branch 3.1
in repository https://gitbox.apache.org/repos/asf/superset.git

commit c839c5734a8fc0ad2e564ad625ee35adec2a4193
Author: Michael S. Molina <70...@users.noreply.github.com>
AuthorDate: Fri Feb 16 08:13:34 2024 -0500

    fix: Duplicated toast messages (#27135)
---
 .../src/SqlLab/reducers/getInitialState.ts         |  4 --
 .../MessageToasts/getToastsFromPyFlashMessages.js  | 40 ------------------
 .../getToastsFromPyFlashMessages.test.js           | 48 ----------------------
 .../src/dashboard/components/Dashboard.jsx         |  2 -
 .../src/dashboard/components/Dashboard.test.jsx    |  1 -
 .../FilterBarSettings/FilterBarSettings.test.tsx   |  1 -
 .../src/dashboard/containers/Dashboard.ts          |  1 -
 superset-frontend/src/dashboard/types.ts           |  1 -
 8 files changed, 98 deletions(-)

diff --git a/superset-frontend/src/SqlLab/reducers/getInitialState.ts b/superset-frontend/src/SqlLab/reducers/getInitialState.ts
index 8d72a313b2..02bb5b45fc 100644
--- a/superset-frontend/src/SqlLab/reducers/getInitialState.ts
+++ b/superset-frontend/src/SqlLab/reducers/getInitialState.ts
@@ -17,7 +17,6 @@
  * under the License.
  */
 import { t } from '@superset-ui/core';
-import getToastsFromPyFlashMessages from 'src/components/MessageToasts/getToastsFromPyFlashMessages';
 import type { BootstrapData } from 'src/types/bootstrapTypes';
 import type { InitialState } from 'src/hooks/apiResources/sqlLab';
 import {
@@ -244,9 +243,6 @@ export default function getInitialState({
       queryCostEstimates: {},
       unsavedQueryEditor,
     },
-    messageToasts: getToastsFromPyFlashMessages(
-      (common || {})?.flash_messages || [],
-    ),
     localStorageUsageInKilobytes: 0,
     common,
     ...otherBootstrapData,
diff --git a/superset-frontend/src/components/MessageToasts/getToastsFromPyFlashMessages.js b/superset-frontend/src/components/MessageToasts/getToastsFromPyFlashMessages.js
deleted file mode 100644
index 982df17100..0000000000
--- a/superset-frontend/src/components/MessageToasts/getToastsFromPyFlashMessages.js
+++ /dev/null
@@ -1,40 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import { addToast } from './actions';
-import { ToastType } from './types';
-
-export default function toastsFromPyFlashMessages(flashMessages = []) {
-  const toasts = [];
-
-  flashMessages.forEach(([messageType, message]) => {
-    const toastType =
-      messageType === 'danger'
-        ? ToastType.DANGER
-        : (messageType === 'success' && ToastType.SUCCESS) || ToastType.INFO;
-
-    const toast = addToast({
-      text: message,
-      toastType,
-    }).payload;
-
-    toasts.push(toast);
-  });
-
-  return toasts;
-}
diff --git a/superset-frontend/src/components/MessageToasts/getToastsFromPyFlashMessages.test.js b/superset-frontend/src/components/MessageToasts/getToastsFromPyFlashMessages.test.js
deleted file mode 100644
index d19ac0c5d5..0000000000
--- a/superset-frontend/src/components/MessageToasts/getToastsFromPyFlashMessages.test.js
+++ /dev/null
@@ -1,48 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import { ToastType } from 'src/components/MessageToasts/types';
-import getToastsFromPyFlashMessages from 'src/components/MessageToasts/getToastsFromPyFlashMessages';
-
-describe('getToastsFromPyFlashMessages', () => {
-  it('should return an info toast', () => {
-    const toast = getToastsFromPyFlashMessages([['info', 'info test']])[0];
-    expect(toast).toMatchObject({
-      toastType: ToastType.INFO,
-      text: 'info test',
-    });
-  });
-
-  it('should return a success toast', () => {
-    const toast = getToastsFromPyFlashMessages([
-      ['success', 'success test'],
-    ])[0];
-    expect(toast).toMatchObject({
-      toastType: ToastType.SUCCESS,
-      text: 'success test',
-    });
-  });
-
-  it('should return a danger toast', () => {
-    const toast = getToastsFromPyFlashMessages([['danger', 'danger test']])[0];
-    expect(toast).toMatchObject({
-      toastType: ToastType.DANGER,
-      text: 'danger test',
-    });
-  });
-});
diff --git a/superset-frontend/src/dashboard/components/Dashboard.jsx b/superset-frontend/src/dashboard/components/Dashboard.jsx
index 6e909f3b15..45a1e3046f 100644
--- a/superset-frontend/src/dashboard/components/Dashboard.jsx
+++ b/superset-frontend/src/dashboard/components/Dashboard.jsx
@@ -59,13 +59,11 @@ const propTypes = {
   ownDataCharts: PropTypes.object.isRequired,
   layout: PropTypes.object.isRequired,
   impressionId: PropTypes.string.isRequired,
-  initMessages: PropTypes.array,
   timeout: PropTypes.number,
   userId: PropTypes.string,
 };
 
 const defaultProps = {
-  initMessages: [],
   timeout: 60,
   userId: '',
 };
diff --git a/superset-frontend/src/dashboard/components/Dashboard.test.jsx b/superset-frontend/src/dashboard/components/Dashboard.test.jsx
index a66eab37e3..d75bda27dc 100644
--- a/superset-frontend/src/dashboard/components/Dashboard.test.jsx
+++ b/superset-frontend/src/dashboard/components/Dashboard.test.jsx
@@ -47,7 +47,6 @@ describe('Dashboard', () => {
       triggerQuery() {},
       logEvent() {},
     },
-    initMessages: [],
     dashboardState,
     dashboardInfo,
     charts: chartQueries,
diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterBarSettings/FilterBarSettings.test.tsx b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterBarSettings/FilterBarSettings.test.tsx
index 8c236c2714..e2d198c3e9 100644
--- a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterBarSettings/FilterBarSettings.test.tsx
+++ b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterBarSettings/FilterBarSettings.test.tsx
@@ -50,7 +50,6 @@ const initialState: { dashboardInfo: DashboardInfo } = {
     filterBarOrientation: FilterBarOrientation.VERTICAL,
     common: {
       conf: {},
-      flash_messages: [],
     },
     crossFiltersEnabled: true,
   },
diff --git a/superset-frontend/src/dashboard/containers/Dashboard.ts b/superset-frontend/src/dashboard/containers/Dashboard.ts
index 5f9b29b95d..15de5c255c 100644
--- a/superset-frontend/src/dashboard/containers/Dashboard.ts
+++ b/superset-frontend/src/dashboard/containers/Dashboard.ts
@@ -48,7 +48,6 @@ function mapStateToProps(state: RootState) {
   } = state;
 
   return {
-    initMessages: dashboardInfo.common?.flash_messages,
     timeout: dashboardInfo.common?.conf?.SUPERSET_WEBSERVER_TIMEOUT,
     userId: dashboardInfo.userId,
     dashboardInfo,
diff --git a/superset-frontend/src/dashboard/types.ts b/superset-frontend/src/dashboard/types.ts
index 4f28e72186..604f264540 100644
--- a/superset-frontend/src/dashboard/types.ts
+++ b/superset-frontend/src/dashboard/types.ts
@@ -117,7 +117,6 @@ export type DashboardState = {
 export type DashboardInfo = {
   id: number;
   common: {
-    flash_messages: string[];
     conf: JsonObject;
   };
   userId: string;


(superset) 01/14: fix: Timeseries Y-axis format with contribution mode (#27106)

Posted by mi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

michaelsmolina pushed a commit to branch 3.1
in repository https://gitbox.apache.org/repos/asf/superset.git

commit a57358ec4961325cbf726204a43d95d47498fd5c
Author: Michael S. Molina <70...@users.noreply.github.com>
AuthorDate: Wed Feb 14 09:41:22 2024 -0500

    fix: Timeseries Y-axis format with contribution mode (#27106)
    
    (cherry picked from commit af577d64b17a9730e28e9021376318326fe31437)
---
 .../src/number-format/NumberFormats.ts             |  6 ++--
 .../legacy-plugin-chart-heatmap/src/Heatmap.js     |  2 +-
 .../src/MixedTimeseries/transformProps.ts          |  2 ++
 .../src/Timeseries/transformProps.ts               |  4 ++-
 .../plugin-chart-echarts/src/utils/formatters.ts   | 11 ++++++-
 .../test/utils/formatters.test.ts                  | 37 ++++++++++++++++++++++
 6 files changed, 56 insertions(+), 6 deletions(-)

diff --git a/superset-frontend/packages/superset-ui-core/src/number-format/NumberFormats.ts b/superset-frontend/packages/superset-ui-core/src/number-format/NumberFormats.ts
index 605da5d30e..3825430ca0 100644
--- a/superset-frontend/packages/superset-ui-core/src/number-format/NumberFormats.ts
+++ b/superset-frontend/packages/superset-ui-core/src/number-format/NumberFormats.ts
@@ -35,20 +35,20 @@ const FLOAT_SIGNED = FLOAT_SIGNED_2_POINT;
 const INTEGER = ',d';
 const INTEGER_SIGNED = '+,d';
 
+const PERCENT = ',.0%';
 const PERCENT_1_POINT = ',.1%';
 const PERCENT_2_POINT = ',.2%';
 const PERCENT_3_POINT = ',.3%';
-const PERCENT = PERCENT_2_POINT;
 
+const PERCENT_SIGNED = '+,.0%';
 const PERCENT_SIGNED_1_POINT = '+,.1%';
 const PERCENT_SIGNED_2_POINT = '+,.2%';
 const PERCENT_SIGNED_3_POINT = '+,.3%';
-const PERCENT_SIGNED = PERCENT_SIGNED_2_POINT;
 
+const SI = '.0s';
 const SI_1_DIGIT = '.1s';
 const SI_2_DIGIT = '.2s';
 const SI_3_DIGIT = '.3s';
-const SI = SI_3_DIGIT;
 
 const SMART_NUMBER = 'SMART_NUMBER';
 const SMART_NUMBER_SIGNED = 'SMART_NUMBER_SIGNED';
diff --git a/superset-frontend/plugins/legacy-plugin-chart-heatmap/src/Heatmap.js b/superset-frontend/plugins/legacy-plugin-chart-heatmap/src/Heatmap.js
index a6967301c6..18493f0602 100644
--- a/superset-frontend/plugins/legacy-plugin-chart-heatmap/src/Heatmap.js
+++ b/superset-frontend/plugins/legacy-plugin-chart-heatmap/src/Heatmap.js
@@ -250,7 +250,7 @@ function Heatmap(element, props) {
     hideYLabel();
   }
 
-  const fp = getNumberFormatter(NumberFormats.PERCENT);
+  const fp = getNumberFormatter(NumberFormats.PERCENT_2_POINT);
 
   const xScale = ordScale('x', null, sortXAxis);
   const yScale = ordScale('y', null, sortYAxis);
diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/MixedTimeseries/transformProps.ts b/superset-frontend/plugins/plugin-chart-echarts/src/MixedTimeseries/transformProps.ts
index 1d4eceb33f..ce6969213a 100644
--- a/superset-frontend/plugins/plugin-chart-echarts/src/MixedTimeseries/transformProps.ts
+++ b/superset-frontend/plugins/plugin-chart-echarts/src/MixedTimeseries/transformProps.ts
@@ -531,6 +531,7 @@ export default function transformProps(
             !!contributionMode,
             customFormatters,
             formatter,
+            yAxisFormat,
           ),
         },
         scale: truncateYAxis,
@@ -553,6 +554,7 @@ export default function transformProps(
             !!contributionMode,
             customFormattersSecondary,
             formatterSecondary,
+            yAxisFormatSecondary,
           ),
         },
         scale: truncateYAxis,
diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/transformProps.ts b/superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/transformProps.ts
index a5c380c5ff..451685ec0a 100644
--- a/superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/transformProps.ts
+++ b/superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/transformProps.ts
@@ -95,6 +95,7 @@ import {
 } from '../constants';
 import { getDefaultTooltip } from '../utils/tooltip';
 import {
+  getPercentFormatter,
   getTooltipTimeFormatter,
   getXAxisFormatter,
   getYAxisFormatter,
@@ -253,7 +254,7 @@ export default function transformProps(
   const series: SeriesOption[] = [];
 
   const forcePercentFormatter = Boolean(contributionMode || isAreaExpand);
-  const percentFormatter = getNumberFormatter(',.0%');
+  const percentFormatter = getPercentFormatter(yAxisFormat);
   const defaultFormatter = currencyFormat?.symbol
     ? new CurrencyFormatter({ d3Format: yAxisFormat, currency: currencyFormat })
     : getNumberFormatter(yAxisFormat);
@@ -486,6 +487,7 @@ export default function transformProps(
         forcePercentFormatter,
         customFormatters,
         defaultFormatter,
+        yAxisFormat,
       ),
     },
     scale: truncateYAxis,
diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/utils/formatters.ts b/superset-frontend/plugins/plugin-chart-echarts/src/utils/formatters.ts
index 5416fa1577..a8f9d2aa31 100644
--- a/superset-frontend/plugins/plugin-chart-echarts/src/utils/formatters.ts
+++ b/superset-frontend/plugins/plugin-chart-echarts/src/utils/formatters.ts
@@ -23,6 +23,7 @@ import {
   getNumberFormatter,
   getTimeFormatter,
   isSavedMetric,
+  NumberFormats,
   QueryFormMetric,
   smartDateDetailedFormatter,
   smartDateFormatter,
@@ -30,14 +31,22 @@ import {
   ValueFormatter,
 } from '@superset-ui/core';
 
+export const getPercentFormatter = (format?: string) =>
+  getNumberFormatter(
+    !format || format === NumberFormats.SMART_NUMBER
+      ? NumberFormats.PERCENT
+      : format,
+  );
+
 export const getYAxisFormatter = (
   metrics: QueryFormMetric[],
   forcePercentFormatter: boolean,
   customFormatters: Record<string, ValueFormatter>,
   defaultFormatter: ValueFormatter,
+  format?: string,
 ) => {
   if (forcePercentFormatter) {
-    return getNumberFormatter(',.0%');
+    return getPercentFormatter(format);
   }
   const metricsArray = ensureIsArray(metrics);
   if (
diff --git a/superset-frontend/plugins/plugin-chart-echarts/test/utils/formatters.test.ts b/superset-frontend/plugins/plugin-chart-echarts/test/utils/formatters.test.ts
new file mode 100644
index 0000000000..f8d40a5bd1
--- /dev/null
+++ b/superset-frontend/plugins/plugin-chart-echarts/test/utils/formatters.test.ts
@@ -0,0 +1,37 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import { NumberFormats } from '@superset-ui/core';
+import { getPercentFormatter } from '../../src/utils/formatters';
+
+describe('getPercentFormatter', () => {
+  const value = 0.6;
+  it('should format as percent if no format is specified', () => {
+    expect(getPercentFormatter().format(value)).toEqual('60%');
+  });
+  it('should format as percent if SMART_NUMBER is specified', () => {
+    expect(
+      getPercentFormatter(NumberFormats.SMART_NUMBER).format(value),
+    ).toEqual('60%');
+  });
+  it('should format using a provided format', () => {
+    expect(
+      getPercentFormatter(NumberFormats.PERCENT_2_POINT).format(value),
+    ).toEqual('60.00%');
+  });
+});


(superset) 11/14: fix: unlock and bump werkzeug (#27164)

Posted by mi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

michaelsmolina pushed a commit to branch 3.1
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 7b589878b73fb84a0563445a88bf1dda378517aa
Author: Daniel Vaz Gaspar <da...@gmail.com>
AuthorDate: Tue Feb 20 10:42:32 2024 +0000

    fix: unlock and bump werkzeug (#27164)
---
 requirements/base.txt                             | 22 ++++++----------------
 requirements/development.txt                      |  2 --
 requirements/integration.txt                      |  6 ------
 requirements/testing.txt                          |  4 ++--
 setup.py                                          |  1 -
 tests/integration_tests/async_events/api_tests.py |  4 +---
 tests/integration_tests/charts/data/api_tests.py  |  2 +-
 7 files changed, 10 insertions(+), 31 deletions(-)

diff --git a/requirements/base.txt b/requirements/base.txt
index c6c2c086da..edf8e5f931 100644
--- a/requirements/base.txt
+++ b/requirements/base.txt
@@ -88,8 +88,6 @@ dnspython==2.1.0
     # via email-validator
 email-validator==1.1.3
     # via flask-appbuilder
-exceptiongroup==1.2.0
-    # via cattrs
 flask==2.2.5
     # via
     #   apache-superset
@@ -116,7 +114,7 @@ flask-jwt-extended==4.3.1
     # via flask-appbuilder
 flask-limiter==3.3.1
     # via flask-appbuilder
-flask-login==0.6.0
+flask-login==0.6.3
     # via
     #   apache-superset
     #   flask-appbuilder
@@ -130,7 +128,7 @@ flask-sqlalchemy==2.5.1
     #   flask-migrate
 flask-talisman==1.0.0
     # via apache-superset
-flask-wtf==1.1.1
+flask-wtf==1.2.1
     # via
     #   apache-superset
     #   flask-appbuilder
@@ -140,7 +138,7 @@ geographiclib==1.52
     # via geopy
 geopy==2.2.0
     # via apache-superset
-greenlet==2.0.2
+greenlet==3.0.3
     # via shillelagh
 gunicorn==21.2.0
     # via apache-superset
@@ -155,10 +153,7 @@ idna==3.2
     #   email-validator
     #   requests
 importlib-metadata==6.6.0
-    # via
-    #   apache-superset
-    #   flask
-    #   shillelagh
+    # via apache-superset
 importlib-resources==5.12.0
     # via limits
 isodate==0.6.0
@@ -340,9 +335,7 @@ tabulate==0.8.9
 typing-extensions==4.4.0
     # via
     #   apache-superset
-    #   cattrs
     #   flask-limiter
-    #   kombu
     #   limits
     #   shillelagh
 tzdata==2023.3
@@ -361,9 +354,8 @@ vine==5.0.0
     #   kombu
 wcwidth==0.2.5
     # via prompt-toolkit
-werkzeug==2.3.3
+werkzeug==3.0.1
     # via
-    #   apache-superset
     #   flask
     #   flask-appbuilder
     #   flask-jwt-extended
@@ -381,9 +373,7 @@ wtforms-json==0.3.5
 xlsxwriter==3.0.7
     # via apache-superset
 zipp==3.15.0
-    # via
-    #   importlib-metadata
-    #   importlib-resources
+    # via importlib-metadata
 
 # The following packages are considered to be unsafe in a requirements file:
 # setuptools
diff --git a/requirements/development.txt b/requirements/development.txt
index ca80cd60ed..3831ae01f6 100644
--- a/requirements/development.txt
+++ b/requirements/development.txt
@@ -121,8 +121,6 @@ thrift==0.16.0
     #   thrift-sasl
 thrift-sasl==0.4.3
     # via pyhive
-tomli==2.0.1
-    # via pylint
 tomlkit==0.11.8
     # via pylint
 traitlets==5.9.0
diff --git a/requirements/integration.txt b/requirements/integration.txt
index 0defdfc659..cc533bfebc 100644
--- a/requirements/integration.txt
+++ b/requirements/integration.txt
@@ -52,12 +52,6 @@ pyproject-hooks==1.0.0
     # via build
 pyyaml==6.0.1
     # via pre-commit
-tomli==2.0.1
-    # via
-    #   build
-    #   pip-tools
-    #   pyproject-api
-    #   tox
 toposort==1.10
     # via pip-compile-multi
 tox==4.6.4
diff --git a/requirements/testing.txt b/requirements/testing.txt
index e7095b7f72..61082c4003 100644
--- a/requirements/testing.txt
+++ b/requirements/testing.txt
@@ -95,7 +95,7 @@ parameterized==0.9.0
     # via -r requirements/testing.in
 pathable==0.4.3
     # via jsonschema-spec
-playwright==1.37.0
+playwright==1.41.2
     # via apache-superset
 prophet==1.1.5
     # via apache-superset
@@ -113,7 +113,7 @@ protobuf==4.23.0
     #   proto-plus
 pydata-google-auth==1.7.0
     # via pandas-gbq
-pyee==9.0.4
+pyee==11.0.1
     # via playwright
 pyfakefs==5.2.2
     # via -r requirements/testing.in
diff --git a/setup.py b/setup.py
index 25c547f246..9f0f34e683 100644
--- a/setup.py
+++ b/setup.py
@@ -131,7 +131,6 @@ setup(
         "tabulate>=0.8.9, <0.9",
         "typing-extensions>=4, <5",
         "waitress; sys_platform == 'win32'",
-        "werkzeug>=2.3.3, <3",
         "wtforms>=2.3.3, <4",
         "wtforms-json",
         "xlsxwriter>=3.0.7, <3.1",
diff --git a/tests/integration_tests/async_events/api_tests.py b/tests/integration_tests/async_events/api_tests.py
index 5c12b29af4..4c2f16a7d3 100644
--- a/tests/integration_tests/async_events/api_tests.py
+++ b/tests/integration_tests/async_events/api_tests.py
@@ -117,8 +117,6 @@ class TestAsyncEventApi(SupersetTestCase):
 
     def test_events_no_token(self):
         self.login(username="admin")
-        self.client.set_cookie(
-            "localhost", app.config["GLOBAL_ASYNC_QUERIES_JWT_COOKIE_NAME"], ""
-        )
+        self.client.set_cookie(app.config["GLOBAL_ASYNC_QUERIES_JWT_COOKIE_NAME"], "")
         rv = self.fetch_events()
         assert rv.status_code == 401
diff --git a/tests/integration_tests/charts/data/api_tests.py b/tests/integration_tests/charts/data/api_tests.py
index 4def03ff4e..fc32501a4e 100644
--- a/tests/integration_tests/charts/data/api_tests.py
+++ b/tests/integration_tests/charts/data/api_tests.py
@@ -688,7 +688,7 @@ class TestPostChartDataApi(BaseTestChartDataApi):
         app._got_first_request = False
         async_query_manager_factory.init_app(app)
         test_client.set_cookie(
-            "localhost", app.config["GLOBAL_ASYNC_QUERIES_JWT_COOKIE_NAME"], "foo"
+            app.config["GLOBAL_ASYNC_QUERIES_JWT_COOKIE_NAME"], "foo"
         )
         rv = test_client.post(CHART_DATA_URI, json=self.query_context_payload)
         self.assertEqual(rv.status_code, 401)


(superset) 14/14: fix: Failed to execute importScripts on worker-css (#27191)

Posted by mi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

michaelsmolina pushed a commit to branch 3.1
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 5ac4d830f0e0c99d1ccdd5441061f907e10f3c63
Author: Michael S. Molina <70...@users.noreply.github.com>
AuthorDate: Wed Feb 21 13:01:26 2024 -0500

    fix: Failed to execute importScripts on worker-css (#27191)
    
    (cherry picked from commit 983a1646c439116d0f65b7f2e9907ebb5046d672)
---
 .../src/components/AsyncAceEditor/index.tsx           |  4 ++++
 superset-frontend/src/types/ace-builds.ts             | 19 +++++++++++++++++++
 superset-frontend/webpack.config.js                   |  4 ++++
 superset/views/core.py                                |  2 +-
 4 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/superset-frontend/src/components/AsyncAceEditor/index.tsx b/superset-frontend/src/components/AsyncAceEditor/index.tsx
index 2e499e150b..1b755f50ef 100644
--- a/superset-frontend/src/components/AsyncAceEditor/index.tsx
+++ b/superset-frontend/src/components/AsyncAceEditor/index.tsx
@@ -24,11 +24,15 @@ import {
   TextMode as OrigTextMode,
 } from 'brace';
 import AceEditor, { IAceEditorProps } from 'react-ace';
+import { config } from 'ace-builds';
 import { acequire } from 'ace-builds/src-noconflict/ace';
 import AsyncEsmComponent, {
   PlaceholderProps,
 } from 'src/components/AsyncEsmComponent';
 import useEffectEvent from 'src/hooks/useEffectEvent';
+import cssWorkerUrl from 'ace-builds/src-noconflict/worker-css';
+
+config.setModuleUrl('ace/mode/css_worker', cssWorkerUrl);
 
 export interface AceCompleterKeywordData {
   name: string;
diff --git a/superset-frontend/src/types/ace-builds.ts b/superset-frontend/src/types/ace-builds.ts
new file mode 100644
index 0000000000..0c34a85403
--- /dev/null
+++ b/superset-frontend/src/types/ace-builds.ts
@@ -0,0 +1,19 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+declare module 'ace-builds/src-noconflict/worker-css';
diff --git a/superset-frontend/webpack.config.js b/superset-frontend/webpack.config.js
index dea99be2cf..2fa922873e 100644
--- a/superset-frontend/webpack.config.js
+++ b/superset-frontend/webpack.config.js
@@ -346,6 +346,10 @@ const config = {
         ],
         use: [babelLoader],
       },
+      {
+        test: /ace-builds.*\/worker-.*$/,
+        type: 'asset/resource',
+      },
       // react-hot-loader use "ProxyFacade", which is a wrapper for react Component
       // see https://github.com/gaearon/react-hot-loader/issues/1311
       // TODO: refactor recurseReactClone
diff --git a/superset/views/core.py b/superset/views/core.py
index 3e895e6b4b..12230680ed 100755
--- a/superset/views/core.py
+++ b/superset/views/core.py
@@ -14,7 +14,7 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-# pylint: disable=invalid-name
+# pylint: disable=invalid-name,too-many-lines
 from __future__ import annotations
 
 import contextlib


(superset) 12/14: fix: CSRF exempt unit_tests (#27168)

Posted by mi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

michaelsmolina pushed a commit to branch 3.1
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 1382aa6f3939f123d3e33b075202117ec90a3034
Author: Daniel Vaz Gaspar <da...@gmail.com>
AuthorDate: Tue Feb 20 16:18:30 2024 +0000

    fix: CSRF exempt unit_tests (#27168)
---
 .github/workflows/superset-python-unittest.yml | 14 +++++++++++---
 tests/unit_tests/security/api_test.py          |  6 +++++-
 2 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/.github/workflows/superset-python-unittest.yml b/.github/workflows/superset-python-unittest.yml
index 5f7639e67c..6eb9dcae95 100644
--- a/.github/workflows/superset-python-unittest.yml
+++ b/.github/workflows/superset-python-unittest.yml
@@ -5,8 +5,16 @@ on:
   push:
     branches-ignore:
       - "dependabot/npm_and_yarn/**"
+    paths:
+      - "superset/**"
+      - "requirements/**"
+      - "tests/unit_tests/**"
   pull_request:
     types: [synchronize, opened, reopened, ready_for_review]
+    paths:
+      - "superset/**"
+      - "requirements/**"
+      - "tests/unit_tests/**"
 
 jobs:
   unit-tests:
@@ -34,9 +42,9 @@ jobs:
         uses: actions/setup-python@v4
         with:
           python-version: ${{ matrix.python-version }}
-          cache: 'pip'
-          cache-dependency-path: 'requirements/testing.txt'
-# TODO: separated requirements.txt file just for unit tests
+          cache: "pip"
+          cache-dependency-path: "requirements/testing.txt"
+      # TODO: separated requirements.txt file just for unit tests
       - name: Install dependencies
         if: steps.check.outcome == 'failure'
         uses: ./.github/actions/cached-dependencies
diff --git a/tests/unit_tests/security/api_test.py b/tests/unit_tests/security/api_test.py
index 5d596073e9..73227166c2 100644
--- a/tests/unit_tests/security/api_test.py
+++ b/tests/unit_tests/security/api_test.py
@@ -28,4 +28,8 @@ def test_csrf_not_exempt(app_context: None) -> None:
     """
     Test that REST API is not exempt from CSRF.
     """
-    assert csrf._exempt_blueprints == {"MenuApi", "SecurityApi", "OpenApi"}
+    assert {blueprint.name for blueprint in csrf._exempt_blueprints} == {
+        "MenuApi",
+        "SecurityApi",
+        "OpenApi",
+    }


(superset) 10/14: feat: bump FAB to 4.4.0 (#27159)

Posted by mi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

michaelsmolina pushed a commit to branch 3.1
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 4b56670aa2f151deebffa131a8050da58d18915c
Author: Daniel Vaz Gaspar <da...@gmail.com>
AuthorDate: Mon Feb 19 21:06:27 2024 +0000

    feat: bump FAB to 4.4.0 (#27159)
    
    (cherry picked from commit f7c5773a97bdea7ee767912d58a5cfdf23a5be87)
---
 requirements/base.txt | 3 +--
 setup.py              | 2 +-
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/requirements/base.txt b/requirements/base.txt
index e97e52fe54..c6c2c086da 100644
--- a/requirements/base.txt
+++ b/requirements/base.txt
@@ -104,7 +104,7 @@ flask==2.2.5
     #   flask-session
     #   flask-sqlalchemy
     #   flask-wtf
-flask-appbuilder==4.3.11
+flask-appbuilder==4.4.0
     # via apache-superset
 flask-babel==1.0.0
     # via flask-appbuilder
@@ -310,7 +310,6 @@ six==1.16.0
     # via
     #   click-repl
     #   isodate
-    #   paramiko
     #   prison
     #   python-dateutil
     #   url-normalize
diff --git a/setup.py b/setup.py
index 998b134dc7..25c547f246 100644
--- a/setup.py
+++ b/setup.py
@@ -84,7 +84,7 @@ setup(
         "cryptography>=41.0.2, <43.0.0",
         "deprecation>=2.1.0, <2.2.0",
         "flask>=2.2.5, <3.0.0",
-        "flask-appbuilder>=4.3.11, <5.0.0",
+        "flask-appbuilder>=4.4.0, <5.0.0",
         "flask-caching>=2.1.0, <3",
         "flask-compress>=1.13, <2.0",
         "flask-talisman>=1.0.0, <2.0",


(superset) 06/14: fix(pivot-table-v2): Added forgotten translation pivot table v2 (#22840)

Posted by mi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

michaelsmolina pushed a commit to branch 3.1
in repository https://gitbox.apache.org/repos/asf/superset.git

commit c94a4609bbac4ab74ff751162ba2b26f9c27a4e8
Author: Stepan <66...@users.noreply.github.com>
AuthorDate: Thu Feb 15 20:16:02 2024 +0300

    fix(pivot-table-v2): Added forgotten translation pivot table v2 (#22840)
    
    (cherry picked from commit 60fe58196a6e8dd1ea7a2e6aaf8401d0a718bc41)
---
 .../src/react-pivottable/TableRenderers.jsx                         | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/superset-frontend/plugins/plugin-chart-pivot-table/src/react-pivottable/TableRenderers.jsx b/superset-frontend/plugins/plugin-chart-pivot-table/src/react-pivottable/TableRenderers.jsx
index 760ff90c15..41063c290f 100644
--- a/superset-frontend/plugins/plugin-chart-pivot-table/src/react-pivottable/TableRenderers.jsx
+++ b/superset-frontend/plugins/plugin-chart-pivot-table/src/react-pivottable/TableRenderers.jsx
@@ -24,7 +24,11 @@ import { PivotData, flatKey } from './utilities';
 import { Styles } from './Styles';
 
 const parseLabel = value => {
-  if (typeof value === 'number' || typeof value === 'string') {
+  if (typeof value === 'string') {
+    if (value === 'metric') return t('metric');
+    return value;
+  }
+  if (typeof value === 'number') {
     return value;
   }
   return String(value);