[incubator-superset] branch filterselect-styles created (now 05927e6)

2020-07-28 Thread maximebeauchemin
This is an automated email from the ASF dual-hosted git repository.

maximebeauchemin pushed a change to branch filterselect-styles
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git.


  at 05927e6  lint

This branch includes the following new commits:

 new 05927e6  lint

The 1 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.




[incubator-superset] 01/01: lint

2020-07-28 Thread maximebeauchemin
This is an automated email from the ASF dual-hosted git repository.

maximebeauchemin pushed a commit to branch filterselect-styles
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git

commit 05927e65873e552a20adcdff656151ba64638b4b
Author: Maxime Beauchemin 
AuthorDate: Tue Jul 28 22:27:39 2020 -0700

lint
---
 superset-frontend/src/components/ListView/Filters.tsx | 6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/superset-frontend/src/components/ListView/Filters.tsx 
b/superset-frontend/src/components/ListView/Filters.tsx
index 8706c5d..aa34c0d 100644
--- a/superset-frontend/src/components/ListView/Filters.tsx
+++ b/superset-frontend/src/components/ListView/Filters.tsx
@@ -46,7 +46,7 @@ interface SelectFilterProps extends BaseFilter {
   emptyLabel?: string;
   fetchSelects?: Filter['fetchSelects'];
   paginate?: boolean;
-  theme: SupersetThemeProps["theme"];
+  theme: SupersetThemeProps['theme'];
 }
 
 const FilterContainer = styled.div`
@@ -80,8 +80,6 @@ const filterSelectStyles: PartialStylesConfig = {
 
 const CLEAR_SELECT_FILTER_VALUE = 'CLEAR_SELECT_FILTER_VALUE';
 
-const StyledSelectFilter = withTheme(SelectFilter);
-
 function SelectFilter({
   Header,
   selects = [],
@@ -92,7 +90,6 @@ function SelectFilter({
   paginate = false,
   theme,
 }: SelectFilterProps) {
-
   const filterSelectTheme: PartialThemeConfig = {
 spacing: {
   baseUnit: 2,
@@ -177,6 +174,7 @@ function SelectFilter({
 
   );
 }
+const StyledSelectFilter = withTheme(SelectFilter);
 
 interface SearchHeaderProps extends BaseFilter {
   Header: string;



[incubator-superset] branch master updated (d065633 -> c716f7a)

2020-07-28 Thread tai
This is an automated email from the ASF dual-hosted git repository.

tai pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git.


from d065633  fix: Implement updates to SQL-based email alerts (#10454)
 add c716f7a  fix: change "add new slice" copy to "add new chart" (#10457)

No new revisions were added by this update.

Summary of changes:
 superset/templates/superset/add_slice.html | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)



[incubator-superset] 03/03: types for jest-enzyme

2020-07-28 Thread suddjian
This is an automated email from the ASF dual-hosted git repository.

suddjian pushed a commit to branch jest-enzyme
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git

commit 571bd6cbf7388fa8ff350f165309eb54c4af249a
Author: David Aaron Suddjian 
AuthorDate: Tue Jul 28 17:06:33 2020 -0700

types for jest-enzyme
---
 superset-frontend/jest.config.js   |  2 +-
 superset-frontend/package-lock.json|  9 +++
 superset-frontend/package.json |  1 +
 .../spec/helpers/{shim.js => shim.ts}  | 28 ++
 4 files changed, 29 insertions(+), 11 deletions(-)

diff --git a/superset-frontend/jest.config.js b/superset-frontend/jest.config.js
index 99a29aa..6a5931e 100644
--- a/superset-frontend/jest.config.js
+++ b/superset-frontend/jest.config.js
@@ -26,7 +26,7 @@ module.exports = {
 '^spec/(.*)$': '/spec/$1',
   },
   testEnvironment: 'enzyme',
-  setupFilesAfterEnv: ['jest-enzyme', '/spec/helpers/shim.js'],
+  setupFilesAfterEnv: ['jest-enzyme', '/spec/helpers/shim.ts'],
   testURL: 'http://localhost',
   collectCoverageFrom: ['src/**/*.{js,jsx,ts,tsx}'],
   coverageDirectory: '/coverage/',
diff --git a/superset-frontend/package-lock.json 
b/superset-frontend/package-lock.json
index 7d3b2e1..5febb20 100644
--- a/superset-frontend/package-lock.json
+++ b/superset-frontend/package-lock.json
@@ -10005,6 +10005,15 @@
 "@types/react": "*"
   }
 },
+"@types/enzyme-adapter-react-16": {
+  "version": "1.0.6",
+  "resolved": 
"https://registry.npmjs.org/@types/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.0.6.tgz";,
+  "integrity": 
"sha512-VonDkZ15jzqDWL8mPFIQnnLtjwebuL9YnDkqeCDYnB4IVgwUm0mwKkqhrxLL6mb05xm7qqa3IE95m8CZE9imCg==",
+  "dev": true,
+  "requires": {
+"@types/enzyme": "*"
+  }
+},
 "@types/eslint-visitor-keys": {
   "version": "1.0.0",
   "resolved": 
"https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz";,
diff --git a/superset-frontend/package.json b/superset-frontend/package.json
index 6fa3791..ddd5b58 100644
--- a/superset-frontend/package.json
+++ b/superset-frontend/package.json
@@ -215,6 +215,7 @@
 "@svgr/webpack": "^5.4.0",
 "@types/classnames": "^2.2.9",
 "@types/dom-to-image": "^2.6.0",
+"@types/enzyme-adapter-react-16": "^1.0.6",
 "@types/jest": "^26.0.3",
 "@types/jquery": "^3.3.32",
 "@types/react": "^16.9.43",
diff --git a/superset-frontend/spec/helpers/shim.js 
b/superset-frontend/spec/helpers/shim.ts
similarity index 72%
rename from superset-frontend/spec/helpers/shim.js
rename to superset-frontend/spec/helpers/shim.ts
index 46264e2..029d8e7 100644
--- a/superset-frontend/spec/helpers/shim.js
+++ b/superset-frontend/spec/helpers/shim.ts
@@ -16,10 +16,11 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-/* eslint no-native-reassign: 0 */
 import 'core-js/stable';
 import 'regenerator-runtime/runtime';
 import 'abortcontroller-polyfill/dist/abortcontroller-polyfill-only';
+import 'jest-enzyme';
+import jQuery from 'jquery';
 import { configure } from 'enzyme';
 import Adapter from 'enzyme-adapter-react-16';
 import { configure as configureTranslation } from '@superset-ui/translation';
@@ -30,16 +31,23 @@ configure({ adapter: new Adapter() });
 
 const exposedProperties = ['window', 'navigator', 'document'];
 
-Object.keys(document.defaultView).forEach(property => {
-  if (typeof global[property] === 'undefined') {
-exposedProperties.push(property);
-global[property] = document.defaultView[property];
-  }
-});
+const defaultView = document.defaultView;
+if (defaultView != null) {
+  Object.keys(defaultView).forEach(property => {
+if (typeof global[property] === 'undefined') {
+  exposedProperties.push(property);
+  global[property] = defaultView[property];
+}
+  });
+}
 
-global.window.location = { href: 'about:blank' };
-global.window.performance = { now: () => new Date().getTime() };
-global.$ = require('jquery')(global.window);
+const g = global as any;
+
+g.window = g.window || {};
+g.window.location = { href: 'about:blank' };
+g.window.performance = { now: () => new Date().getTime() };
+
+g.$ = jQuery(g.window);
 
 configureTranslation();
 setupSupersetClient();



[incubator-superset] 01/03: adding jest-enzyme

2020-07-28 Thread suddjian
This is an automated email from the ASF dual-hosted git repository.

suddjian pushed a commit to branch jest-enzyme
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git

commit f998f378e10dce606759b7223bc3a53df036ed59
Author: David Aaron Suddjian 
AuthorDate: Tue Jul 28 16:14:21 2020 -0700

adding jest-enzyme
---
 superset-frontend/jest.config.js   |   3 +-
 superset-frontend/package-lock.json| 740 -
 superset-frontend/package.json |   2 +
 .../javascripts/components/AnchorLink_spec.jsx |   2 +-
 .../components/ConfirmStatusChange_spec.jsx|   2 +-
 .../components/ListView/ListView_spec.jsx  |   8 +-
 6 files changed, 749 insertions(+), 8 deletions(-)

diff --git a/superset-frontend/jest.config.js b/superset-frontend/jest.config.js
index 18b05cc..99a29aa 100644
--- a/superset-frontend/jest.config.js
+++ b/superset-frontend/jest.config.js
@@ -25,7 +25,8 @@ module.exports = {
 '^src/(.*)$': '/src/$1',
 '^spec/(.*)$': '/spec/$1',
   },
-  setupFilesAfterEnv: ['/spec/helpers/shim.js'],
+  testEnvironment: 'enzyme',
+  setupFilesAfterEnv: ['jest-enzyme', '/spec/helpers/shim.js'],
   testURL: 'http://localhost',
   collectCoverageFrom: ['src/**/*.{js,jsx,ts,tsx}'],
   coverageDirectory: '/coverage/',
diff --git a/superset-frontend/package-lock.json 
b/superset-frontend/package-lock.json
index 34d262f..7d3b2e1 100644
--- a/superset-frontend/package-lock.json
+++ b/superset-frontend/package-lock.json
@@ -11426,6 +11426,12 @@
   "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
   "dev": true
 },
+"array-equal": {
+  "version": "1.0.0",
+  "resolved": 
"https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz";,
+  "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=",
+  "dev": true
+},
 "array-filter": {
   "version": "1.0.0",
   "resolved": 
"https://registry.npmjs.org/array-filter/-/array-filter-1.0.0.tgz";,
@@ -14107,6 +14113,12 @@
 "safe-buffer": "^5.0.1"
   }
 },
+"circular-json-es6": {
+  "version": "2.0.2",
+  "resolved": 
"https://registry.npmjs.org/circular-json-es6/-/circular-json-es6-2.0.2.tgz";,
+  "integrity": 
"sha512-ODYONMMNb3p658Zv+Pp+/XPa5s6q7afhz3Tzyvo+VRh9WIrJ64J76ZC4GQxnlye/NesTn09jvOiuE8+xxfpwhQ==",
+  "dev": true
+},
 "class-utils": {
   "version": "0.3.6",
   "resolved": 
"https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz";,
@@ -15862,6 +15874,27 @@
 }
   }
 },
+"deep-equal-ident": {
+  "version": "1.1.1",
+  "resolved": 
"https://registry.npmjs.org/deep-equal-ident/-/deep-equal-ident-1.1.1.tgz";,
+  "integrity": "sha1-BvS4nlNxDNbOpKd4HHqVZkLejck=",
+  "dev": true,
+  "requires": {
+"lodash.isequal": "^3.0"
+  },
+  "dependencies": {
+"lodash.isequal": {
+  "version": "3.0.4",
+  "resolved": 
"https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-3.0.4.tgz";,
+  "integrity": "sha1-HDXrO27wzR/1F0Pj6jz3/f/ay2Q=",
+  "dev": true,
+  "requires": {
+"lodash._baseisequal": "^3.0.0",
+"lodash._bindcallback": "^3.0.0"
+  }
+}
+  }
+},
 "deep-is": {
   "version": "0.1.3",
   "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz";,
@@ -16635,6 +16668,34 @@
 "semver": "^5.6.0"
   }
 },
+"enzyme-matchers": {
+  "version": "7.1.2",
+  "resolved": 
"https://registry.npmjs.org/enzyme-matchers/-/enzyme-matchers-7.1.2.tgz";,
+  "integrity": 
"sha512-03WqAg2XDl7id9rARIO97HQ1JIw9F2heJ3R4meGu/13hx0ULTDEgl0E67MGl2Uq1jq1DyRnJfto1/VSzskdV5A==",
+  "dev": true,
+  "requires": {
+"circular-json-es6": "^2.0.1",
+"deep-equal-ident": "^1.1.1"
+  }
+},
+"enzyme-to-json": {
+  "version": "3.5.0",
+  "resolved": 
"https://registry.npmjs.org/enzyme-to-json/-/enzyme-to-json-3.5.0.tgz";,
+  "integrity": 
"sha512-clusXRsiaQhG7+wtyc4t7MU8N3zCOgf4eY9+CeSenYzKlFST4lxerfOvnWd4SNaToKhkuba+w6m242YpQOS7eA==",
+  "dev": true,
+  "requires": {
+"lodash": "^4.17.15",
+"react-is": "^16.12.0"
+  },
+  "dependencies": {
+"react-is": {
+  "version": "16.13.1",
+  "resolved": 
"https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz";,
+  "integrity": 
"sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
+  "dev": true
+}
+  }
+},
 "errno": {
   "version": "0.1.7",
   "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz";,
@@ -21032,6 +21093,600 @@
 }
   }
 },
+"jest-environment-enzyme": {
+  "version": "7.1.2",
+  "resolved": 
"https://registry.npmjs.org/jest-environment-enzyme/-/jest-environment-enzyme-7.1.2.tgz";,
+  "integrity": 
"sha512-3tfaYAzO7qZSRrv+sr

[incubator-superset] 02/03: enzymeify lots of assertions

2020-07-28 Thread suddjian
This is an automated email from the ASF dual-hosted git repository.

suddjian pushed a commit to branch jest-enzyme
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git

commit edbfd159194744225b43a4dec480ad4be29c8687
Author: David Aaron Suddjian 
AuthorDate: Tue Jul 28 16:18:50 2020 -0700

enzymeify lots of assertions
---
 .../spec/javascripts/CRUD/CollectionTable_spec.jsx |  2 +-
 .../addSlice/AddSliceContainer_spec.tsx|  6 +--
 .../spec/javascripts/chart/ChartRenderer_spec.jsx  |  4 +-
 .../components/AlteredSliceTag_spec.jsx|  2 +-
 .../javascripts/components/AnchorLink_spec.jsx |  6 +--
 .../javascripts/components/AsyncSelect_spec.jsx|  4 +-
 .../javascripts/components/CachedLabel_spec.jsx|  2 +-
 .../spec/javascripts/components/Checkbox_spec.jsx  |  4 +-
 .../FilterableTable/FilterableTable_spec.tsx   |  6 +--
 .../spec/javascripts/components/FormRow_spec.jsx   |  6 +--
 .../components/ListView/ListView_spec.jsx  |  4 +-
 .../spec/javascripts/components/Menu_spec.jsx  |  2 +-
 .../javascripts/components/PopoverSection_spec.jsx |  2 +-
 .../components/URLShortLinkButton_spec.jsx |  2 +-
 .../components/URLShortLinkModal_spec.jsx  |  2 +-
 .../dashboard/components/CodeModal_spec.jsx|  2 +-
 .../dashboard/components/CssEditor_spec.jsx|  2 +-
 .../dashboard/components/DashboardBuilder_spec.jsx | 10 ++---
 .../dashboard/components/DashboardGrid_spec.jsx|  8 ++--
 .../dashboard/components/Dashboard_spec.jsx|  2 +-
 .../components/FilterIndicatorGroup_spec.jsx   |  2 +-
 .../components/FilterIndicatorTooltip_spec.jsx |  2 +-
 .../dashboard/components/FilterIndicator_spec.jsx  |  2 +-
 .../components/FilterIndicatorsContainer_spec.jsx  | 10 ++---
 .../components/FilterTooltipWrapper_spec.jsx   |  4 +-
 .../components/HeaderActionsDropdown_spec.jsx  | 30 +++---
 .../dashboard/components/Header_spec.jsx   | 46 +++---
 .../dashboard/components/MissingChart_spec.jsx |  4 +-
 .../components/RefreshIntervalModal_spec.jsx   |  6 +--
 .../dashboard/components/SliceAdder_spec.jsx   |  2 +-
 .../components/dnd/DragDroppable_spec.jsx  |  4 +-
 .../components/gridComponents/ChartHolder_spec.jsx | 16 
 .../components/gridComponents/Chart_spec.jsx   |  8 ++--
 .../components/gridComponents/Column_spec.jsx  | 18 -
 .../components/gridComponents/Divider_spec.jsx | 12 +++---
 .../components/gridComponents/Header_spec.jsx  | 12 +++---
 .../components/gridComponents/Markdown_spec.jsx| 28 ++---
 .../components/gridComponents/Row_spec.jsx | 16 
 .../components/gridComponents/Tab_spec.jsx | 10 ++---
 .../components/gridComponents/Tabs_spec.jsx| 12 +++---
 .../new/DraggableNewComponent_spec.jsx |  4 +-
 .../gridComponents/new/NewColumn_spec.jsx  |  2 +-
 .../gridComponents/new/NewDivider_spec.jsx |  2 +-
 .../gridComponents/new/NewHeader_spec.jsx  |  2 +-
 .../components/gridComponents/new/NewRow_spec.jsx  |  2 +-
 .../components/gridComponents/new/NewTabs_spec.jsx |  2 +-
 .../dashboard/components/menu/HoverMenu_spec.jsx   |  2 +-
 .../components/menu/WithPopoverMenu_spec.jsx   | 12 +++---
 .../resizable/ResizableContainer_spec.jsx  |  2 +-
 .../components/resizable/ResizableHandle_spec.jsx  |  2 +-
 .../datasource/ChangeDatasourceModal_spec.jsx  |  2 +-
 .../datasource/DatasourceEditor_spec.jsx   |  2 +-
 .../datasource/DatasourceModal_spec.jsx|  4 +-
 .../explore/components/AdhocFilterControl_spec.jsx |  2 +-
 .../components/AdhocFilterEditPopover_spec.jsx | 22 +--
 .../explore/components/AdhocFilterOption_spec.jsx  |  2 +-
 .../AdhocMetricEditPopoverTitle_spec.jsx   |  2 +-
 .../components/AdhocMetricEditPopover_spec.jsx | 16 
 .../explore/components/AdhocMetricOption_spec.jsx  |  4 +-
 .../explore/components/ColorPickerControl_spec.jsx |  2 +-
 .../explore/components/ColorScheme_spec.jsx|  2 +-
 .../components/ControlPanelSection_spec.jsx|  2 +-
 .../explore/components/ControlRow_spec.jsx |  6 +--
 .../explore/components/DatasourceControl_spec.jsx  |  8 ++--
 .../explore/components/DateFilterControl_spec.jsx  |  4 +-
 .../explore/components/EmbedCodeButton_spec.jsx|  2 +-
 .../explore/components/ExploreChartHeader_spec.jsx |  4 +-
 .../components/ExploreViewContainer_spec.jsx   |  6 +--
 .../components/FilterBoxItemControl_spec.jsx   |  2 +-
 .../components/FilterDefinitionOption_spec.jsx |  4 +-
 .../components/FixedOrMetricControl_spec.jsx   |  4 +-
 .../components/MetricDefinitionOption_spec.jsx |  6 +--
 .../components/MetricDefinitionValue_spec.jsx  |  4 +-
 .../explore/components/MetricsControl_spec.jsx |  2 +-
 .../explore/components/RowCountLabel_spec.jsx  |  4 +-
 .../components/RunQueryActionButt

[incubator-superset] branch jest-enzyme created (now 571bd6c)

2020-07-28 Thread suddjian
This is an automated email from the ASF dual-hosted git repository.

suddjian pushed a change to branch jest-enzyme
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git.


  at 571bd6c  types for jest-enzyme

This branch includes the following new commits:

 new f998f37  adding jest-enzyme
 new edbfd15  enzymeify lots of assertions
 new 571bd6c  types for jest-enzyme

The 3 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.




[incubator-superset] branch master updated: fix: Implement updates to SQL-based email alerts (#10454)

2020-07-28 Thread bkyryliuk
This is an automated email from the ASF dual-hosted git repository.

bkyryliuk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git


The following commit(s) were added to refs/heads/master by this push:
 new d065633  fix: Implement updates to SQL-based email alerts (#10454)
d065633 is described below

commit d065633c81bdb77ea8b80c37502a2b94640c373d
Author: Jason Davis <32852580+jason...@users.noreply.github.com>
AuthorDate: Tue Jul 28 16:48:42 2020 -0700

fix: Implement updates to SQL-based email alerts (#10454)

* implemented updates to alerting

* fixed imports and teardown

* changed unittest to pytest conventions

* add app_context to tests

Co-authored-by: Jason Davis <@dropbox.com>
---
 superset/tasks/schedules.py |   7 +--
 superset/views/alerts.py|   6 ++-
 tests/alerts_tests.py   | 114 
 3 files changed, 122 insertions(+), 5 deletions(-)

diff --git a/superset/tasks/schedules.py b/superset/tasks/schedules.py
index 0c44f33..3e8d6fc 100644
--- a/superset/tasks/schedules.py
+++ b/superset/tasks/schedules.py
@@ -705,17 +705,18 @@ def schedule_window(
 for schedule in schedules:
 logging.info("Processing schedule %s", schedule)
 args = (report_type, schedule.id)
+schedule_start_at = start_at
 
 if (
 hasattr(schedule, "last_eval_dttm")
 and schedule.last_eval_dttm
 and schedule.last_eval_dttm > start_at
 ):
-# start_at = schedule.last_eval_dttm + timedelta(seconds=1)
-pass
+schedule_start_at = schedule.last_eval_dttm + timedelta(seconds=1)
+
 # Schedule the job for the specified time window
 for eta in next_schedules(
-schedule.crontab, start_at, stop_at, resolution=resolution
+schedule.crontab, schedule_start_at, stop_at, resolution=resolution
 ):
 get_scheduler_action(report_type).apply_async(args, eta=eta)  # 
type: ignore
 break
diff --git a/superset/views/alerts.py b/superset/views/alerts.py
index 9dbaf29..a06cf8a 100644
--- a/superset/views/alerts.py
+++ b/superset/views/alerts.py
@@ -59,11 +59,13 @@ class AlertModelView(SupersetModelView):  # pylint: 
disable=too-many-ancestors
 "crontab",
 "database",
 "sql",
-"alert_type",
+# TODO: implement different types of alerts
+# "alert_type",
 "owners",
 "recipients",
 "slice",
-"dashboard",
+# TODO: implement dashboard screenshots with alerts
+# "dashboard",
 "log_retention",
 "grace_period",
 )
diff --git a/tests/alerts_tests.py b/tests/alerts_tests.py
new file mode 100644
index 000..5c08acc
--- /dev/null
+++ b/tests/alerts_tests.py
@@ -0,0 +1,114 @@
+# 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.
+"""Unit tests for alerting in Superset"""
+import logging
+from unittest.mock import patch
+
+import pytest
+
+from superset import db
+from superset.models.alerts import Alert, AlertLog
+from superset.models.slice import Slice
+from superset.tasks.schedules import run_alert_query
+from superset.utils import core as utils
+from tests.test_app import app
+
+logging.basicConfig(level=logging.INFO)
+logger = logging.getLogger(__name__)
+
+
+@pytest.yield_fixture(scope="module")
+def setup_database():
+with app.app_context():
+slice_id = db.session.query(Slice).all()[0].id
+database_id = utils.get_example_database().id
+
+alert1 = Alert(
+id=1,
+label="alert_1",
+active=True,
+crontab="*/1 * * * *",
+sql="SELECT 0",
+alert_type="email",
+slice_id=slice_id,
+database_id=database_id,
+)
+alert2 = Alert(
+id=2,
+label="alert_2",
+active=True,
+crontab="*/1 * * * *",
+sql="SELECT 55",
+alert_type="email",
+slice_id=slice_id,
+database_id=database_id,
+)
+alert3 = Alert(
+id=3,
+label="alert_3",
+  

[incubator-superset] 01/02: adding jest-enzyme

2020-07-28 Thread suddjian
This is an automated email from the ASF dual-hosted git repository.

suddjian pushed a commit to branch jest-enzyme
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git

commit f998f378e10dce606759b7223bc3a53df036ed59
Author: David Aaron Suddjian 
AuthorDate: Tue Jul 28 16:14:21 2020 -0700

adding jest-enzyme
---
 superset-frontend/jest.config.js   |   3 +-
 superset-frontend/package-lock.json| 740 -
 superset-frontend/package.json |   2 +
 .../javascripts/components/AnchorLink_spec.jsx |   2 +-
 .../components/ConfirmStatusChange_spec.jsx|   2 +-
 .../components/ListView/ListView_spec.jsx  |   8 +-
 6 files changed, 749 insertions(+), 8 deletions(-)

diff --git a/superset-frontend/jest.config.js b/superset-frontend/jest.config.js
index 18b05cc..99a29aa 100644
--- a/superset-frontend/jest.config.js
+++ b/superset-frontend/jest.config.js
@@ -25,7 +25,8 @@ module.exports = {
 '^src/(.*)$': '/src/$1',
 '^spec/(.*)$': '/spec/$1',
   },
-  setupFilesAfterEnv: ['/spec/helpers/shim.js'],
+  testEnvironment: 'enzyme',
+  setupFilesAfterEnv: ['jest-enzyme', '/spec/helpers/shim.js'],
   testURL: 'http://localhost',
   collectCoverageFrom: ['src/**/*.{js,jsx,ts,tsx}'],
   coverageDirectory: '/coverage/',
diff --git a/superset-frontend/package-lock.json 
b/superset-frontend/package-lock.json
index 34d262f..7d3b2e1 100644
--- a/superset-frontend/package-lock.json
+++ b/superset-frontend/package-lock.json
@@ -11426,6 +11426,12 @@
   "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
   "dev": true
 },
+"array-equal": {
+  "version": "1.0.0",
+  "resolved": 
"https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz";,
+  "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=",
+  "dev": true
+},
 "array-filter": {
   "version": "1.0.0",
   "resolved": 
"https://registry.npmjs.org/array-filter/-/array-filter-1.0.0.tgz";,
@@ -14107,6 +14113,12 @@
 "safe-buffer": "^5.0.1"
   }
 },
+"circular-json-es6": {
+  "version": "2.0.2",
+  "resolved": 
"https://registry.npmjs.org/circular-json-es6/-/circular-json-es6-2.0.2.tgz";,
+  "integrity": 
"sha512-ODYONMMNb3p658Zv+Pp+/XPa5s6q7afhz3Tzyvo+VRh9WIrJ64J76ZC4GQxnlye/NesTn09jvOiuE8+xxfpwhQ==",
+  "dev": true
+},
 "class-utils": {
   "version": "0.3.6",
   "resolved": 
"https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz";,
@@ -15862,6 +15874,27 @@
 }
   }
 },
+"deep-equal-ident": {
+  "version": "1.1.1",
+  "resolved": 
"https://registry.npmjs.org/deep-equal-ident/-/deep-equal-ident-1.1.1.tgz";,
+  "integrity": "sha1-BvS4nlNxDNbOpKd4HHqVZkLejck=",
+  "dev": true,
+  "requires": {
+"lodash.isequal": "^3.0"
+  },
+  "dependencies": {
+"lodash.isequal": {
+  "version": "3.0.4",
+  "resolved": 
"https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-3.0.4.tgz";,
+  "integrity": "sha1-HDXrO27wzR/1F0Pj6jz3/f/ay2Q=",
+  "dev": true,
+  "requires": {
+"lodash._baseisequal": "^3.0.0",
+"lodash._bindcallback": "^3.0.0"
+  }
+}
+  }
+},
 "deep-is": {
   "version": "0.1.3",
   "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz";,
@@ -16635,6 +16668,34 @@
 "semver": "^5.6.0"
   }
 },
+"enzyme-matchers": {
+  "version": "7.1.2",
+  "resolved": 
"https://registry.npmjs.org/enzyme-matchers/-/enzyme-matchers-7.1.2.tgz";,
+  "integrity": 
"sha512-03WqAg2XDl7id9rARIO97HQ1JIw9F2heJ3R4meGu/13hx0ULTDEgl0E67MGl2Uq1jq1DyRnJfto1/VSzskdV5A==",
+  "dev": true,
+  "requires": {
+"circular-json-es6": "^2.0.1",
+"deep-equal-ident": "^1.1.1"
+  }
+},
+"enzyme-to-json": {
+  "version": "3.5.0",
+  "resolved": 
"https://registry.npmjs.org/enzyme-to-json/-/enzyme-to-json-3.5.0.tgz";,
+  "integrity": 
"sha512-clusXRsiaQhG7+wtyc4t7MU8N3zCOgf4eY9+CeSenYzKlFST4lxerfOvnWd4SNaToKhkuba+w6m242YpQOS7eA==",
+  "dev": true,
+  "requires": {
+"lodash": "^4.17.15",
+"react-is": "^16.12.0"
+  },
+  "dependencies": {
+"react-is": {
+  "version": "16.13.1",
+  "resolved": 
"https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz";,
+  "integrity": 
"sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
+  "dev": true
+}
+  }
+},
 "errno": {
   "version": "0.1.7",
   "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz";,
@@ -21032,6 +21093,600 @@
 }
   }
 },
+"jest-environment-enzyme": {
+  "version": "7.1.2",
+  "resolved": 
"https://registry.npmjs.org/jest-environment-enzyme/-/jest-environment-enzyme-7.1.2.tgz";,
+  "integrity": 
"sha512-3tfaYAzO7qZSRrv+sr

[incubator-superset] branch jest-enzyme created (now edbfd15)

2020-07-28 Thread suddjian
This is an automated email from the ASF dual-hosted git repository.

suddjian pushed a change to branch jest-enzyme
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git.


  at edbfd15  enzymeify lots of assertions

This branch includes the following new commits:

 new f998f37  adding jest-enzyme
 new edbfd15  enzymeify lots of assertions

The 2 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.




[incubator-superset] 02/02: enzymeify lots of assertions

2020-07-28 Thread suddjian
This is an automated email from the ASF dual-hosted git repository.

suddjian pushed a commit to branch jest-enzyme
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git

commit edbfd159194744225b43a4dec480ad4be29c8687
Author: David Aaron Suddjian 
AuthorDate: Tue Jul 28 16:18:50 2020 -0700

enzymeify lots of assertions
---
 .../spec/javascripts/CRUD/CollectionTable_spec.jsx |  2 +-
 .../addSlice/AddSliceContainer_spec.tsx|  6 +--
 .../spec/javascripts/chart/ChartRenderer_spec.jsx  |  4 +-
 .../components/AlteredSliceTag_spec.jsx|  2 +-
 .../javascripts/components/AnchorLink_spec.jsx |  6 +--
 .../javascripts/components/AsyncSelect_spec.jsx|  4 +-
 .../javascripts/components/CachedLabel_spec.jsx|  2 +-
 .../spec/javascripts/components/Checkbox_spec.jsx  |  4 +-
 .../FilterableTable/FilterableTable_spec.tsx   |  6 +--
 .../spec/javascripts/components/FormRow_spec.jsx   |  6 +--
 .../components/ListView/ListView_spec.jsx  |  4 +-
 .../spec/javascripts/components/Menu_spec.jsx  |  2 +-
 .../javascripts/components/PopoverSection_spec.jsx |  2 +-
 .../components/URLShortLinkButton_spec.jsx |  2 +-
 .../components/URLShortLinkModal_spec.jsx  |  2 +-
 .../dashboard/components/CodeModal_spec.jsx|  2 +-
 .../dashboard/components/CssEditor_spec.jsx|  2 +-
 .../dashboard/components/DashboardBuilder_spec.jsx | 10 ++---
 .../dashboard/components/DashboardGrid_spec.jsx|  8 ++--
 .../dashboard/components/Dashboard_spec.jsx|  2 +-
 .../components/FilterIndicatorGroup_spec.jsx   |  2 +-
 .../components/FilterIndicatorTooltip_spec.jsx |  2 +-
 .../dashboard/components/FilterIndicator_spec.jsx  |  2 +-
 .../components/FilterIndicatorsContainer_spec.jsx  | 10 ++---
 .../components/FilterTooltipWrapper_spec.jsx   |  4 +-
 .../components/HeaderActionsDropdown_spec.jsx  | 30 +++---
 .../dashboard/components/Header_spec.jsx   | 46 +++---
 .../dashboard/components/MissingChart_spec.jsx |  4 +-
 .../components/RefreshIntervalModal_spec.jsx   |  6 +--
 .../dashboard/components/SliceAdder_spec.jsx   |  2 +-
 .../components/dnd/DragDroppable_spec.jsx  |  4 +-
 .../components/gridComponents/ChartHolder_spec.jsx | 16 
 .../components/gridComponents/Chart_spec.jsx   |  8 ++--
 .../components/gridComponents/Column_spec.jsx  | 18 -
 .../components/gridComponents/Divider_spec.jsx | 12 +++---
 .../components/gridComponents/Header_spec.jsx  | 12 +++---
 .../components/gridComponents/Markdown_spec.jsx| 28 ++---
 .../components/gridComponents/Row_spec.jsx | 16 
 .../components/gridComponents/Tab_spec.jsx | 10 ++---
 .../components/gridComponents/Tabs_spec.jsx| 12 +++---
 .../new/DraggableNewComponent_spec.jsx |  4 +-
 .../gridComponents/new/NewColumn_spec.jsx  |  2 +-
 .../gridComponents/new/NewDivider_spec.jsx |  2 +-
 .../gridComponents/new/NewHeader_spec.jsx  |  2 +-
 .../components/gridComponents/new/NewRow_spec.jsx  |  2 +-
 .../components/gridComponents/new/NewTabs_spec.jsx |  2 +-
 .../dashboard/components/menu/HoverMenu_spec.jsx   |  2 +-
 .../components/menu/WithPopoverMenu_spec.jsx   | 12 +++---
 .../resizable/ResizableContainer_spec.jsx  |  2 +-
 .../components/resizable/ResizableHandle_spec.jsx  |  2 +-
 .../datasource/ChangeDatasourceModal_spec.jsx  |  2 +-
 .../datasource/DatasourceEditor_spec.jsx   |  2 +-
 .../datasource/DatasourceModal_spec.jsx|  4 +-
 .../explore/components/AdhocFilterControl_spec.jsx |  2 +-
 .../components/AdhocFilterEditPopover_spec.jsx | 22 +--
 .../explore/components/AdhocFilterOption_spec.jsx  |  2 +-
 .../AdhocMetricEditPopoverTitle_spec.jsx   |  2 +-
 .../components/AdhocMetricEditPopover_spec.jsx | 16 
 .../explore/components/AdhocMetricOption_spec.jsx  |  4 +-
 .../explore/components/ColorPickerControl_spec.jsx |  2 +-
 .../explore/components/ColorScheme_spec.jsx|  2 +-
 .../components/ControlPanelSection_spec.jsx|  2 +-
 .../explore/components/ControlRow_spec.jsx |  6 +--
 .../explore/components/DatasourceControl_spec.jsx  |  8 ++--
 .../explore/components/DateFilterControl_spec.jsx  |  4 +-
 .../explore/components/EmbedCodeButton_spec.jsx|  2 +-
 .../explore/components/ExploreChartHeader_spec.jsx |  4 +-
 .../components/ExploreViewContainer_spec.jsx   |  6 +--
 .../components/FilterBoxItemControl_spec.jsx   |  2 +-
 .../components/FilterDefinitionOption_spec.jsx |  4 +-
 .../components/FixedOrMetricControl_spec.jsx   |  4 +-
 .../components/MetricDefinitionOption_spec.jsx |  6 +--
 .../components/MetricDefinitionValue_spec.jsx  |  4 +-
 .../explore/components/MetricsControl_spec.jsx |  2 +-
 .../explore/components/RowCountLabel_spec.jsx  |  4 +-
 .../components/RunQueryActionButt

[incubator-superset] branch 0.36.0-lyft1 created (now be1c489)

2020-07-28 Thread beto
This is an automated email from the ASF dual-hosted git repository.

beto pushed a change to branch 0.36.0-lyft1
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git.


  at be1c489  fix(presto): Handle ROW data stored as string (#10456)

This branch includes the following new commits:

 new be1c489  fix(presto): Handle ROW data stored as string (#10456)

The 1 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.




[incubator-superset] 01/01: fix(presto): Handle ROW data stored as string (#10456)

2020-07-28 Thread beto
This is an automated email from the ASF dual-hosted git repository.

beto pushed a commit to branch 0.36.0-lyft1
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git

commit be1c48982044df50cfeb99d9696ddb989a161218
Author: Beto Dealmeida 
AuthorDate: Tue Jul 28 16:05:58 2020 -0700

fix(presto): Handle ROW data stored as string (#10456)

* Handle ROW data stored as string

* Use destringify

* Fix mypy

* Fix mypy with cast

* Bypass pylint
---
 superset/db_engine_specs/presto.py| 19 +++
 superset/result_set.py|  4 +++
 tests/db_engine_specs/presto_tests.py | 59 ++-
 3 files changed, 75 insertions(+), 7 deletions(-)

diff --git a/superset/db_engine_specs/presto.py 
b/superset/db_engine_specs/presto.py
index 038b25b..e6204d55 100644
--- a/superset/db_engine_specs/presto.py
+++ b/superset/db_engine_specs/presto.py
@@ -22,7 +22,7 @@ from collections import defaultdict, deque
 from contextlib import closing
 from datetime import datetime
 from distutils.version import StrictVersion
-from typing import Any, cast, Dict, List, Optional, Tuple, TYPE_CHECKING
+from typing import Any, cast, Dict, List, Optional, Tuple, TYPE_CHECKING, Union
 from urllib import parse
 
 import pandas as pd
@@ -40,6 +40,7 @@ from superset.db_engine_specs.base import BaseEngineSpec
 from superset.exceptions import SupersetTemplateException
 from superset.models.sql_lab import Query
 from superset.models.sql_types.presto_sql_types import type_map as 
presto_type_map
+from superset.result_set import destringify
 from superset.sql_parse import ParsedQuery
 from superset.utils import core as utils
 
@@ -560,9 +561,9 @@ class PrestoEngineSpec(BaseEngineSpec):
 return datasource_names
 
 @classmethod
-def expand_data(  # pylint: disable=too-many-locals
-cls, columns: List[dict], data: List[dict]
-) -> Tuple[List[dict], List[dict], List[dict]]:
+def expand_data(  # pylint: disable=too-many-locals,too-many-branches
+cls, columns: List[Dict[Any, Any]], data: List[Dict[Any, Any]]
+) -> Tuple[List[Dict[Any, Any]], List[Dict[Any, Any]], List[Dict[Any, 
Any]]]:
 """
 We do not immediately display rows and arrays clearly in the data 
grid. This
 method separates out nested fields and data values to help clearly 
display
@@ -608,6 +609,7 @@ class PrestoEngineSpec(BaseEngineSpec):
 current_array_level = level
 
 name = column["name"]
+values: Optional[Union[str, List[Any]]]
 
 if column["type"].startswith("ARRAY("):
 # keep processing array children; we append to the right so 
that
@@ -619,6 +621,8 @@ class PrestoEngineSpec(BaseEngineSpec):
 while i < len(data):
 row = data[i]
 values = row.get(name)
+if isinstance(values, str):
+row[name] = values = destringify(values)
 if values:
 # how many extra rows we need to unnest the data?
 extra_rows = len(values) - 1
@@ -645,12 +649,15 @@ class PrestoEngineSpec(BaseEngineSpec):
 # expand columns; we append them to the left so they are added
 # immediately after the parent
 expanded = get_children(column)
-to_process.extendleft((column, level) for column in expanded)
+to_process.extendleft((column, level) for column in 
expanded[::-1])
 expanded_columns.extend(expanded)
 
 # expand row objects into new columns
 for row in data:
-for value, col in zip(row.get(name) or [], expanded):
+values = row.get(name) or []
+if isinstance(values, str):
+row[name] = values = cast(List[Any], 
destringify(values))
+for value, col in zip(values, expanded):
 row[col["name"]] = value
 
 data = [
diff --git a/superset/result_set.py b/superset/result_set.py
index 1f42a28..5045c55 100644
--- a/superset/result_set.py
+++ b/superset/result_set.py
@@ -68,6 +68,10 @@ def stringify_values(array: np.ndarray) -> np.ndarray:
 return vstringify(array)
 
 
+def destringify(obj: str) -> Any:
+return json.loads(obj)
+
+
 class SupersetResultSet:
 def __init__(
 self,
diff --git a/tests/db_engine_specs/presto_tests.py 
b/tests/db_engine_specs/presto_tests.py
index cf62b28..f95aec2 100644
--- a/tests/db_engine_specs/presto_tests.py
+++ b/tests/db_engine_specs/presto_tests.py
@@ -216,9 +216,9 @@ class PrestoTests(DbEngineSpecTestCase):
 "name": "row_column",
 "type": "ROW(NESTED_OBJ1 VARCHAR, NESTED_ROW ROW(NESTED_OBJ2 
VARCHAR))",
 },
+{"name": "row_column.nested_obj1", "type": "VARCHAR"},
  

[incubator-superset] branch master updated (39fad85 -> 4f67827)

2020-07-28 Thread beto
This is an automated email from the ASF dual-hosted git repository.

beto pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git.


from 39fad85  feat: update dataset editor modal (#10347)
 add 4f67827  fix(presto): Handle ROW data stored as string (#10456)

No new revisions were added by this update.

Summary of changes:
 superset/db_engine_specs/presto.py| 15 ++---
 superset/result_set.py|  4 +++
 tests/db_engine_specs/presto_tests.py | 59 ++-
 3 files changed, 73 insertions(+), 5 deletions(-)



[incubator-superset] branch master updated (e89e60d -> 39fad85)

2020-07-28 Thread tai
This is an automated email from the ASF dual-hosted git repository.

tai pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git.


from e89e60d  style: update +NEW button to use Button component, add 
dropdownItems prop to Button (#10422)
 add 39fad85  feat: update dataset editor modal (#10347)

No new revisions were added by this update.

Summary of changes:
 .../datasource/ChangeDatasourceModal_spec.jsx  |  71 
 .../datasource/DatasourceModal_spec.jsx|  66 +---
 .../src/datasource/ChangeDatasourceModal.jsx   | 179 
 .../src/datasource/ChangeDatasourceModal.tsx   | 161 ++
 .../src/datasource/DatasourceEditor.jsx|  35 +++-
 .../src/datasource/DatasourceModal.jsx | 181 -
 .../src/datasource/DatasourceModal.tsx | 164 +++
 superset-frontend/src/datasource/main.less |  33 
 .../src/views/CRUD/dataset/DatasetList.tsx | 146 +++--
 superset/connectors/druid/models.py|   4 +
 superset/connectors/sqla/models.py |   8 +
 superset/datasets/api.py   |   3 +
 12 files changed, 541 insertions(+), 510 deletions(-)
 delete mode 100644 superset-frontend/src/datasource/ChangeDatasourceModal.jsx
 create mode 100644 superset-frontend/src/datasource/ChangeDatasourceModal.tsx
 delete mode 100644 superset-frontend/src/datasource/DatasourceModal.jsx
 create mode 100644 superset-frontend/src/datasource/DatasourceModal.tsx
 delete mode 100644 superset-frontend/src/datasource/main.less



[incubator-superset] branch handle_presto_row_data_str updated (77bd207 -> 63bf737)

2020-07-28 Thread beto
This is an automated email from the ASF dual-hosted git repository.

beto pushed a change to branch handle_presto_row_data_str
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git.


from 77bd207  Fix mypy with cast
 add 63bf737  Bypass pylint

No new revisions were added by this update.

Summary of changes:
 superset/db_engine_specs/presto.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)



[incubator-superset] branch master updated: style: update +NEW button to use Button component, add dropdownItems prop to Button (#10422)

2020-07-28 Thread tai
This is an automated email from the ASF dual-hosted git repository.

tai pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git


The following commit(s) were added to refs/heads/master by this push:
 new e89e60d  style: update +NEW button to use Button component, add 
dropdownItems prop to Button (#10422)
e89e60d is described below

commit e89e60df766de19e8effc79e8376ed0682c06ccc
Author: Moriah Kreeger 
AuthorDate: Tue Jul 28 14:29:52 2020 -0700

style: update +NEW button to use Button component, add dropdownItems prop 
to Button (#10422)
---
 superset-frontend/src/components/Button/index.tsx  | 47 ++
 superset-frontend/src/components/Menu/NewMenu.tsx  | 56 +++---
 .../stylesheets/less/cosmo/bootswatch.less |  5 --
 3 files changed, 64 insertions(+), 44 deletions(-)

diff --git a/superset-frontend/src/components/Button/index.tsx 
b/superset-frontend/src/components/Button/index.tsx
index 6861fc5..24028d0 100644
--- a/superset-frontend/src/components/Button/index.tsx
+++ b/superset-frontend/src/components/Button/index.tsx
@@ -22,11 +22,18 @@ import {
   Button as BootstrapButton,
   Tooltip,
   OverlayTrigger,
+  MenuItem,
 } from 'react-bootstrap';
 import styled from '@superset-ui/style';
 
 export type OnClickHandler = React.MouseEventHandler;
 
+export interface DropdownItemProps {
+  label: string;
+  url: string;
+  icon?: string;
+}
+
 export interface ButtonProps {
   className?: string;
   tooltip?: string;
@@ -38,6 +45,7 @@ export interface ButtonProps {
   bsSize?: BootstrapButton.ButtonProps['bsSize'];
   style?: BootstrapButton.ButtonProps['style'];
   children?: React.ReactNode;
+  dropdownItems?: DropdownItemProps[];
 }
 
 const BUTTON_WRAPPER_STYLE = { display: 'inline-block', cursor: 'not-allowed' 
};
@@ -82,23 +90,41 @@ export default function Button(props: ButtonProps) {
   };
   const tooltip = props.tooltip;
   const placement = props.placement;
+  const dropdownItems = props.dropdownItems;
   delete buttonProps.tooltip;
   delete buttonProps.placement;
 
+  if (tooltip && props.disabled) {
+// Working around the fact that tooltips don't get triggered when buttons 
are disabled
+// https://github.com/react-bootstrap/react-bootstrap/issues/1588
+buttonProps.style = { pointerEvents: 'none' };
+  }
+
   let button = (
 {props.children}
   );
+
+  if (dropdownItems) {
+button = (
+  
+
+  {props.children}
+
+
+  {dropdownItems.map(
+(dropdownItem: DropdownItemProps, index1: number) => (
+  
+
+  {dropdownItem.label}
+  
+),
+  )}
+
+  
+);
+  }
+
   if (tooltip) {
-if (props.disabled) {
-  // Working around the fact that tooltips don't get triggered when 
buttons are disabled
-  // https://github.com/react-bootstrap/react-bootstrap/issues/1588
-  buttonProps.style = { pointerEvents: 'none' };
-  button = (
-
-  {props.children}
-
-  );
-}
 return (
   
 );
   }
+
   return button;
 }
diff --git a/superset-frontend/src/components/Menu/NewMenu.tsx 
b/superset-frontend/src/components/Menu/NewMenu.tsx
index 1973652..055ca2e 100644
--- a/superset-frontend/src/components/Menu/NewMenu.tsx
+++ b/superset-frontend/src/components/Menu/NewMenu.tsx
@@ -17,44 +17,42 @@
  * under the License.
  */
 import React from 'react';
+import styled from '@superset-ui/style';
 import { t } from '@superset-ui/translation';
+import Button, { DropdownItemProps } from '../Button';
 
-const buttonStyle = {
-  marginTop: '12px',
-  marginRight: '30px',
-};
+const StyledButton = styled(Button)`
+  margin-top: 12px;
+  margin-right: 30px;
+`;
+
+const dropdownItems: DropdownItemProps[] = [
+  {
+label: t('SQL Query'),
+url: '/superset/sqllab',
+icon: 'fa-fw fa-search',
+  },
+  {
+label: t('Chart'),
+url: '/chart/add',
+icon: 'fa-fw fa-bar-chart',
+  },
+  {
+label: t('Dashboard'),
+url: '/dashboard/new',
+icon: 'fa-fw fa-dashboard',
+  },
+];
 
 export default function NewMenu() {
   return (
 
-  
  New
-  
-  
-
-  
-
-{t('SQL Query')}
-  
-
-
-  
-
-{t('Chart')}
-  
-
-
-  
-
-{t('Dashboard')}
-  
-
-  
+  
 
   );
 }
diff --git a/superset-frontend/stylesheets/less/cosmo/bootswatch.less 
b/superset-frontend/stylesheets/less/cosmo/bootswatch.less
index 057fa7e..f65e95a 100644
--- a/superset-frontend/stylesheets/less/cosmo/bootswatch.less
+++ b/superset-frontend/stylesheets/less/cosmo/bootswatch.less
@@ -70,11 +70,6 @@
   text-transform: uppercase;
 }
 
-.btn-default:hover {
-  color: @gray-dark;
-  background-color: @gray-bg;
-}
-
 .nav-tabs {
   .dropdown-to

[incubator-superset] branch handle_presto_row_data_str updated (ee0556f -> 77bd207)

2020-07-28 Thread beto
This is an automated email from the ASF dual-hosted git repository.

beto pushed a change to branch handle_presto_row_data_str
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git.


from ee0556f  Fix mypy
 add 77bd207  Fix mypy with cast

No new revisions were added by this update.

Summary of changes:
 superset/db_engine_specs/presto.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)



[incubator-superset] branch handle_presto_row_data_str updated (b8432e4 -> ee0556f)

2020-07-28 Thread beto
This is an automated email from the ASF dual-hosted git repository.

beto pushed a change to branch handle_presto_row_data_str
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git.


from b8432e4  Use destringify
 add ee0556f  Fix mypy

No new revisions were added by this update.

Summary of changes:
 superset/db_engine_specs/presto.py | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)



[incubator-superset] branch handle_presto_row_data_str updated (e19c927 -> b8432e4)

2020-07-28 Thread beto
This is an automated email from the ASF dual-hosted git repository.

beto pushed a change to branch handle_presto_row_data_str
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git.


from e19c927  Handle ROW data stored as string
 add b8432e4  Use destringify

No new revisions were added by this update.

Summary of changes:
 superset/db_engine_specs/presto.py | 13 -
 superset/result_set.py |  4 
 2 files changed, 12 insertions(+), 5 deletions(-)



[incubator-superset] branch master updated (fc28c92 -> 9914ae1)

2020-07-28 Thread tai
This is an automated email from the ASF dual-hosted git repository.

tai pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git.


from fc28c92  feat: support non-numeric columns in pivot table (#10389)
 add 9914ae1  chore: migrate Checkbox to tsx (#10453)

No new revisions were added by this update.

Summary of changes:
 .../src/components/{ChartIcon.jsx => ChartIcon.tsx}|  0
 .../src/components/{Checkbox.jsx => Checkbox.tsx}  | 14 ++
 .../components/{CheckboxIcons.jsx => CheckboxIcons.tsx}|  0
 3 files changed, 6 insertions(+), 8 deletions(-)
 rename superset-frontend/src/components/{ChartIcon.jsx => ChartIcon.tsx} (100%)
 rename superset-frontend/src/components/{Checkbox.jsx => Checkbox.tsx} (82%)
 rename superset-frontend/src/components/{CheckboxIcons.jsx => 
CheckboxIcons.tsx} (100%)



[incubator-superset] branch 0.37 updated: feat: support non-numeric columns in pivot table (#10389)

2020-07-28 Thread villebro
This is an automated email from the ASF dual-hosted git repository.

villebro pushed a commit to branch 0.37
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git


The following commit(s) were added to refs/heads/0.37 by this push:
 new 0f3670e  feat: support non-numeric columns in pivot table (#10389)
0f3670e is described below

commit 0f3670e1af8778aefefa179f02453cec1766e6e5
Author: Ville Brofeldt <33317356+ville...@users.noreply.github.com>
AuthorDate: Tue Jul 28 10:40:53 2020 +0300

feat: support non-numeric columns in pivot table (#10389)

* fix: support non-numeric columns in pivot table

* bump package and add unit tests

* mypy
---
 superset/viz.py| 39 +++
 tests/viz_tests.py | 38 ++
 2 files changed, 69 insertions(+), 8 deletions(-)

diff --git a/superset/viz.py b/superset/viz.py
index 2067f7c..8cb2aa6 100644
--- a/superset/viz.py
+++ b/superset/viz.py
@@ -29,7 +29,18 @@ import uuid
 from collections import defaultdict, OrderedDict
 from datetime import datetime, timedelta
 from itertools import product
-from typing import Any, cast, Dict, List, Optional, Set, Tuple, TYPE_CHECKING, 
Union
+from typing import (
+Any,
+Callable,
+cast,
+Dict,
+List,
+Optional,
+Set,
+Tuple,
+TYPE_CHECKING,
+Union,
+)
 
 import dataclasses
 import geohash
@@ -736,6 +747,7 @@ class PivotTableViz(BaseViz):
 verbose_name = _("Pivot Table")
 credits = 'a https://github.com/airbnb/superset";>Superset 
original'
 is_timeseries = False
+enforce_numerical_metrics = False
 
 def query_obj(self) -> QueryObjectDict:
 d = super().query_obj()
@@ -766,6 +778,18 @@ class PivotTableViz(BaseViz):
 raise QueryObjectValidationError(_("Group By' and 'Columns' can't 
overlap"))
 return d
 
+@staticmethod
+def get_aggfunc(
+metric: str, df: pd.DataFrame, form_data: Dict[str, Any]
+) -> Union[str, Callable[[Any], Any]]:
+aggfunc = form_data.get("pandas_aggfunc") or "sum"
+if pd.api.types.is_numeric_dtype(df[metric]):
+# Ensure that Pandas's sum function mimics that of SQL.
+if aggfunc == "sum":
+return lambda x: x.sum(min_count=1)
+# only min and max work properly for non-numerics
+return aggfunc if aggfunc in ("min", "max") else "max"
+
 def get_data(self, df: pd.DataFrame) -> VizData:
 if df.empty:
 return None
@@ -773,22 +797,21 @@ class PivotTableViz(BaseViz):
 if self.form_data.get("granularity") == "all" and DTTM_ALIAS in df:
 del df[DTTM_ALIAS]
 
-aggfunc = self.form_data.get("pandas_aggfunc") or "sum"
-
-# Ensure that Pandas's sum function mimics that of SQL.
-if aggfunc == "sum":
-aggfunc = lambda x: x.sum(min_count=1)
+metrics = [utils.get_metric_name(m) for m in self.form_data["metrics"]]
+aggfuncs: Dict[str, Union[str, Callable[[Any], Any]]] = {}
+for metric in metrics:
+aggfuncs[metric] = self.get_aggfunc(metric, df, self.form_data)
 
 groupby = self.form_data.get("groupby")
 columns = self.form_data.get("columns")
 if self.form_data.get("transpose_pivot"):
 groupby, columns = columns, groupby
-metrics = [utils.get_metric_name(m) for m in self.form_data["metrics"]]
+
 df = df.pivot_table(
 index=groupby,
 columns=columns,
 values=metrics,
-aggfunc=aggfunc,
+aggfunc=aggfuncs,
 margins=self.form_data.get("pivot_margins"),
 )
 
diff --git a/tests/viz_tests.py b/tests/viz_tests.py
index 8290fbf..17e43d8 100644
--- a/tests/viz_tests.py
+++ b/tests/viz_tests.py
@@ -1284,3 +1284,41 @@ class TestBigNumberViz(SupersetTestCase):
 )
 data = viz.BigNumberViz(datasource, {"metrics": ["y"]}).get_data(df)
 assert np.isnan(data[2]["y"])
+
+
+class TestPivotTableViz(SupersetTestCase):
+df = pd.DataFrame(
+data={
+"intcol": [1, 2, 3, None],
+"floatcol": [0.1, 0.2, 0.3, None],
+"strcol": ["a", "b", "c", None],
+}
+)
+
+def test_get_aggfunc_numeric(self):
+# is a sum function
+func = viz.PivotTableViz.get_aggfunc("intcol", self.df, {})
+assert hasattr(func, "__call__")
+assert func(self.df["intcol"]) == 6
+
+assert (
+viz.PivotTableViz.get_aggfunc("intcol", self.df, 
{"pandas_aggfunc": "min"})
+== "min"
+)
+assert (
+viz.PivotTableViz.get_aggfunc(
+"floatcol", self.df, {"pandas_aggfunc": "max"}
+)
+== "max"
+)
+
+def test_get_aggfunc_non_numeric(self):
+assert viz.PivotTableViz.get_aggfunc("strcol", self.df, {}) == "max"
+assert (
+viz.PivotTable

[incubator-superset] branch master updated: feat: support non-numeric columns in pivot table (#10389)

2020-07-28 Thread villebro
This is an automated email from the ASF dual-hosted git repository.

villebro pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git


The following commit(s) were added to refs/heads/master by this push:
 new fc28c92  feat: support non-numeric columns in pivot table (#10389)
fc28c92 is described below

commit fc28c92f57edd7bccac57715bef159c0f18daef1
Author: Ville Brofeldt <33317356+ville...@users.noreply.github.com>
AuthorDate: Tue Jul 28 10:40:53 2020 +0300

feat: support non-numeric columns in pivot table (#10389)

* fix: support non-numeric columns in pivot table

* bump package and add unit tests

* mypy
---
 superset/viz.py| 39 +++
 tests/viz_tests.py | 38 ++
 2 files changed, 69 insertions(+), 8 deletions(-)

diff --git a/superset/viz.py b/superset/viz.py
index 6ce4d5a..6f0ba53 100644
--- a/superset/viz.py
+++ b/superset/viz.py
@@ -29,7 +29,18 @@ import uuid
 from collections import defaultdict, OrderedDict
 from datetime import datetime, timedelta
 from itertools import product
-from typing import Any, cast, Dict, List, Optional, Set, Tuple, TYPE_CHECKING, 
Union
+from typing import (
+Any,
+Callable,
+cast,
+Dict,
+List,
+Optional,
+Set,
+Tuple,
+TYPE_CHECKING,
+Union,
+)
 
 import dataclasses
 import geohash
@@ -734,6 +745,7 @@ class PivotTableViz(BaseViz):
 verbose_name = _("Pivot Table")
 credits = 'a https://github.com/airbnb/superset";>Superset 
original'
 is_timeseries = False
+enforce_numerical_metrics = False
 
 def query_obj(self) -> QueryObjectDict:
 d = super().query_obj()
@@ -764,6 +776,18 @@ class PivotTableViz(BaseViz):
 raise QueryObjectValidationError(_("Group By' and 'Columns' can't 
overlap"))
 return d
 
+@staticmethod
+def get_aggfunc(
+metric: str, df: pd.DataFrame, form_data: Dict[str, Any]
+) -> Union[str, Callable[[Any], Any]]:
+aggfunc = form_data.get("pandas_aggfunc") or "sum"
+if pd.api.types.is_numeric_dtype(df[metric]):
+# Ensure that Pandas's sum function mimics that of SQL.
+if aggfunc == "sum":
+return lambda x: x.sum(min_count=1)
+# only min and max work properly for non-numerics
+return aggfunc if aggfunc in ("min", "max") else "max"
+
 def get_data(self, df: pd.DataFrame) -> VizData:
 if df.empty:
 return None
@@ -771,22 +795,21 @@ class PivotTableViz(BaseViz):
 if self.form_data.get("granularity") == "all" and DTTM_ALIAS in df:
 del df[DTTM_ALIAS]
 
-aggfunc = self.form_data.get("pandas_aggfunc") or "sum"
-
-# Ensure that Pandas's sum function mimics that of SQL.
-if aggfunc == "sum":
-aggfunc = lambda x: x.sum(min_count=1)
+metrics = [utils.get_metric_name(m) for m in self.form_data["metrics"]]
+aggfuncs: Dict[str, Union[str, Callable[[Any], Any]]] = {}
+for metric in metrics:
+aggfuncs[metric] = self.get_aggfunc(metric, df, self.form_data)
 
 groupby = self.form_data.get("groupby")
 columns = self.form_data.get("columns")
 if self.form_data.get("transpose_pivot"):
 groupby, columns = columns, groupby
-metrics = [utils.get_metric_name(m) for m in self.form_data["metrics"]]
+
 df = df.pivot_table(
 index=groupby,
 columns=columns,
 values=metrics,
-aggfunc=aggfunc,
+aggfunc=aggfuncs,
 margins=self.form_data.get("pivot_margins"),
 )
 
diff --git a/tests/viz_tests.py b/tests/viz_tests.py
index c6d0c80..d1ac508 100644
--- a/tests/viz_tests.py
+++ b/tests/viz_tests.py
@@ -1292,3 +1292,41 @@ class TestBigNumberViz(SupersetTestCase):
 )
 data = viz.BigNumberViz(datasource, {"metrics": ["y"]}).get_data(df)
 assert np.isnan(data[2]["y"])
+
+
+class TestPivotTableViz(SupersetTestCase):
+df = pd.DataFrame(
+data={
+"intcol": [1, 2, 3, None],
+"floatcol": [0.1, 0.2, 0.3, None],
+"strcol": ["a", "b", "c", None],
+}
+)
+
+def test_get_aggfunc_numeric(self):
+# is a sum function
+func = viz.PivotTableViz.get_aggfunc("intcol", self.df, {})
+assert hasattr(func, "__call__")
+assert func(self.df["intcol"]) == 6
+
+assert (
+viz.PivotTableViz.get_aggfunc("intcol", self.df, 
{"pandas_aggfunc": "min"})
+== "min"
+)
+assert (
+viz.PivotTableViz.get_aggfunc(
+"floatcol", self.df, {"pandas_aggfunc": "max"}
+)
+== "max"
+)
+
+def test_get_aggfunc_non_numeric(self):
+assert viz.PivotTableViz.get_aggfunc("strcol", self.df, {}) == "max"
+assert (
+viz.PivotT