Compare commits

...

24 Commits

Author SHA1 Message Date
Ville Brofeldt
9d16c488fa update changelog and version number 2021-02-25 08:52:05 +02:00
Evan Rusackas
caa18cea65 feat: adding feature flags to escape/hide html in markdown (#11340)
* utilizing feature flag for html escapement

* use src alias

* Feature flag to allow hiding of HTML tags

* strips js attr

* better feature flag naming

* simplifying

* Adding comments to new feature flags

* shorter comment, because pylint,

* pedantic change to get black to format a file
2021-02-25 08:04:10 +02:00
Ville Brofeldt
6d605c958a docs: update changelog 2020-11-17 09:45:16 +02:00
Evan Rusackas
36489fc84e fix: prior npm font source had a glitch (#11724) 2020-11-17 09:40:17 +02:00
Evan Rusackas
140be0003a refactor: Load fonts from packages rather than local binaries (#11718)
* removing binaries

* adding npm packages

* nixing unused specimen sheet

* deleting specimen sheets

* using imported css sheets from npm

* package lock

* fixing webpack issue with font loading

* raising specificity on ACE editor fonts

* linting 
2020-11-17 09:40:10 +02:00
Ville Brofeldt
de23349e7b docs: update changelog 2020-11-05 09:23:28 +02:00
serenajiang
34bbc77cec fix(sqla): allow 'unknown' type queries in explore view (#11365) 2020-11-04 08:32:29 +02:00
Jesse Yang
c8d0778b89 build: update webpack for npm linking plugins (#11253) 2020-11-04 08:32:23 +02:00
Daniel Gaspar
9fd2a11531 Update changelog with rc2 cherries 2020-11-02 10:22:10 +00:00
Daniel Gaspar
548053ed05 Update changelog and updating 2020-11-02 09:28:32 +00:00
Daniel Vaz Gaspar
5d27e2c989 docs(release): script to generate a CHANGELOG.md (#11469)
* docs(release): script to generate a CHANGELOG.md

* remove preset cache

* black

* lint typing

* Update RELEASING/changelog.py

Co-authored-by: Ville Brofeldt <33317356+villebro@users.noreply.github.com>

* Update RELEASING/changelog.py

Co-authored-by: Ville Brofeldt <33317356+villebro@users.noreply.github.com>

* address comments

* remove duplicated import and EOL print

Co-authored-by: Ville Brofeldt <33317356+villebro@users.noreply.github.com>
2020-10-30 15:42:21 +00:00
Ville Brofeldt
504ef50b9e chore(chart-data): add annotations and url params to chart data schema (#11393)
* chore(chart-data): add annotations to chart data schema

* bump superset-ui packages

* xit flaky cypress tests
2020-10-30 11:07:31 +00:00
Jesse Yang
4217d21f10 chore: upgrade vis plugins npm packages (#11272)
https://github.com/apache-superset/superset-ui/compare/v0.15.4...v0.15.8
2020-10-30 11:06:08 +00:00
Daniel Gaspar
72fc1cad85 release: fix changelog username 2020-10-28 11:48:25 +00:00
Daniel Gaspar
93743e3591 release: 0.38.0 and changelog 2020-10-28 11:33:13 +00:00
Ville Brofeldt
131b51656c Revert "fix: disable jinja2 SQL templating"
This reverts commit 922b8aa7c9.
2020-10-28 11:01:34 +02:00
Grace Guo
c917e7d102 fix: Fix Time Column dropdown for date filter (#11149) 2020-10-22 11:24:39 +03:00
Ville Brofeldt
44b7e8e6e8 fix(crud): set default extra value (#11262) 2020-10-15 10:14:12 +01:00
Lily Kuang
f0cd671f4c fix(dataset): update user list endpoint (#11221) 2020-10-12 17:31:08 +01:00
Daniel Vaz Gaspar
c2e8f98854 feat(datasets): REST API bulk delete (#11237)
* feat(datasets): REST API bulk delete

* doc HTTP 400
2020-10-12 17:30:39 +01:00
Ville Brofeldt
76f6e85eb3 chore(sqla): assert query is single read-only statement (#11236) 2020-10-12 17:30:25 +01:00
Ville Brofeldt
9aba607149 chore(sql-lab): catch PyArrow deserialization error (#11201) 2020-10-12 17:30:12 +01:00
Daniel Gaspar
922b8aa7c9 fix: disable jinja2 SQL templating
# Conflicts:
#	superset/config.py
2020-10-06 13:34:22 +01:00
Ville Brofeldt
5db86822df fix(examples): missing expressions in birth_names (#11141)
* fix(examples): missing expressions in birth_names

* disable flaky tests
2020-10-06 12:02:05 +01:00
88 changed files with 1962 additions and 898 deletions

View File

@@ -18,6 +18,424 @@ under the License.
-->
## Change Log
### 0.38.1 (Wed Feb 25 06:48:35 2021 +00:00)
- [#11340](https://github.com/apache/superset/pull/11340) feat: adding feature flags to escape/hide html in markdown (#11340)
### 0.38.0 (Mon Nov 17 07:23:54 2020 +00:00)
- [#11724](https://github.com/apache/incubator-superset/pull/11724) fix: prior npm font source had a glitch (#11724) (@rusackas)
- [#11718](https://github.com/apache/incubator-superset/pull/11718) refactor: Load fonts from packages rather than local binaries (#11718) (@rusackas)
- [#11365](https://github.com/apache/incubator-superset/pull/11365) fix(sqla): allow 'unknown' type queries in explore view (#11365) (@serenajiang)
- [#11253](https://github.com/apache/incubator-superset/pull/11253) build: update webpack for npm linking plugins (#11253) (@ktmud)
- [#11469](https://github.com/apache/incubator-superset/pull/11469) docs(release): script to generate a CHANGELOG.md (#11469) (@dpgaspar)
- [#11393](https://github.com/apache/incubator-superset/pull/11393) chore(chart-data): add annotations and url params to chart data schema (#11393) (@villebro)
- [#11272](https://github.com/apache/incubator-superset/pull/11272) chore: upgrade vis plugins npm packages (#11272) (@ktmud)
- [#11149](https://github.com/apache/incubator-superset/pull/11149) fix: Fix Time Column dropdown for date filter (#11149) (@graceguo-supercat)
- [#11262](https://github.com/apache/incubator-superset/pull/11262) fix(crud): set default extra value (#11262) (@villebro)
- [#11221](https://github.com/apache/incubator-superset/pull/11221) fix(dataset): update user list endpoint (#11221) (@lilykuang)
- [#11237](https://github.com/apache/incubator-superset/pull/11237) feat(datasets): REST API bulk delete (#11237) (@dpgaspar)
- [#11236](https://github.com/apache/incubator-superset/pull/11236) chore(sqla): assert query is single read-only statement (#11236) (@villebro)
- [#11201](https://github.com/apache/incubator-superset/pull/11201) chore(sql-lab): catch PyArrow deserialization error (#11201) (@villebro)
- [#11141](https://github.com/apache/incubator-superset/pull/11141) fix(examples): missing expressions in birth_names (#11141) (@villebro)
- [#11136](https://github.com/apache/incubator-superset/pull/11136) fix: Alembic migration 18532d70ab98 (#11136) (@john-bodley)
- [#11140](https://github.com/apache/incubator-superset/pull/11140) docs: docs site footer link tweak (#11140) (@rusackas)
- [#11133](https://github.com/apache/incubator-superset/pull/11133) docs: comply to ASF requirements (#11133) (@mistercrunch)
- [#11124](https://github.com/apache/incubator-superset/pull/11124) add info about case sensitive search (#11124) (@eschutho)
- [#11111](https://github.com/apache/incubator-superset/pull/11111) style(listview): dynamic card size and grid spacing (#11111) (@nytai)
- [#11126](https://github.com/apache/incubator-superset/pull/11126) style: rename label 'table name'->'dataset name' (#11126) (@mistercrunch)
- [#11083](https://github.com/apache/incubator-superset/pull/11083) feat: custom favorite filter for dashboards, charts and saved queries (#11083) (@dpgaspar)
- [#11102](https://github.com/apache/incubator-superset/pull/11102) chore: refactor submenu's right nav to accept list of buttons (#11102) (@pkdotson)
- [#11132](https://github.com/apache/incubator-superset/pull/11132) docs: use the Apache-Superset logo on README / pypi (#11132) (@mistercrunch)
- [#11121](https://github.com/apache/incubator-superset/pull/11121) fix: remove extra flash import (#11121) (@eschutho)
- [#11125](https://github.com/apache/incubator-superset/pull/11125) fix: Revert "Replace reactable with DataTable from superset-ui in QueryTable (#10981)" (#11125) (@nytai)
- [#11115](https://github.com/apache/incubator-superset/pull/11115) fix: alembic migration error msg trying to delete constraint on tables (#11115) (@dpgaspar)
- [#11114](https://github.com/apache/incubator-superset/pull/11114) feat: CRUD REST API for CSS Templates (#11114) (@dpgaspar)
- [#11127](https://github.com/apache/incubator-superset/pull/11127) fix: SpatialControl popover won't open (#11127) (@mistercrunch)
- [#11109](https://github.com/apache/incubator-superset/pull/11109) feat: saved query list actions (#11109) (@riahk)
- [#11067](https://github.com/apache/incubator-superset/pull/11067) feat: add created by chart CRUD view (#11067) (@lilykuang)
- [#11107](https://github.com/apache/incubator-superset/pull/11107) fix: Disabling timezone of dataframe before passing Prophet (#11107) (@kkalyan)
- [#11112](https://github.com/apache/incubator-superset/pull/11112) fix(chart-data-api): ignore missing filters (#11112) (@villebro)
- [#11099](https://github.com/apache/incubator-superset/pull/11099) feat: more specific presto error messages (#11099) (@etr2460)
- [#11110](https://github.com/apache/incubator-superset/pull/11110) Fix alembic migration (#11110) (@bkyryliuk)
- [#11066](https://github.com/apache/incubator-superset/pull/11066) fix: fix table existence validation function (#11066) (@bkyryliuk)
- [#11100](https://github.com/apache/incubator-superset/pull/11100) style: fix secondary label border (#11100) (@rusackas)
- [#11005](https://github.com/apache/incubator-superset/pull/11005) feat: saved query list view + sort/filters (#11005) (@riahk)
- [#10972](https://github.com/apache/incubator-superset/pull/10972) chore: Remove Obsolete WARNING_MSG from config (#10972) (@john-bodley)
- [#10963](https://github.com/apache/incubator-superset/pull/10963) feat: enable ETag header for dashboard GET requests (#10963) (@graceguo-supercat)
- [#11045](https://github.com/apache/incubator-superset/pull/11045) Updated lint in schedules.py in tasks: unused_import, ungrouped_import and changed argument name to remove unused-argument (#11045) (@kkucharc)
- [#11019](https://github.com/apache/incubator-superset/pull/11019) fix(api): unable to delete virtual dataset, wrong permission name (#11019) (@dpgaspar)
- [#11103](https://github.com/apache/incubator-superset/pull/11103) fix: echarts timeseries groupby (#11103) (@villebro)
- [#11095](https://github.com/apache/incubator-superset/pull/11095) fix: double scroll bars on dataset editor (#11095) (@lilykuang)
- [#11059](https://github.com/apache/incubator-superset/pull/11059) docs: Add Zeta to list of companies using Apache Superset (#11059) (@shaikidris)
- [#11064](https://github.com/apache/incubator-superset/pull/11064) chore: pylint fixes in files in project's root (#11064) (@kkucharc)
- [#11062](https://github.com/apache/incubator-superset/pull/11062) chore: updated utils with pylint rules (#11062) (@kkucharc)
- [#10914](https://github.com/apache/incubator-superset/pull/10914) refactor: table selector on dataset editor (#10914) (@lilykuang)
- [#11015](https://github.com/apache/incubator-superset/pull/11015) Reorganize steps (#11015) (@brylie)
- [#11054](https://github.com/apache/incubator-superset/pull/11054) feat(charts): modify custom api filter to include more fields (#11054) (@nytai)
- [#11061](https://github.com/apache/incubator-superset/pull/11061) chore: Clean up some console warnings (#11061) (@kgabryje)
- [#11046](https://github.com/apache/incubator-superset/pull/11046) refactor: Remove usages of reactable from TimeTable (#11046) (@kgabryje)
- [#11012](https://github.com/apache/incubator-superset/pull/11012) refactor: Remove usages of reactable from AlteredSliceTag (#11012) (@kgabryje)
- [#11069](https://github.com/apache/incubator-superset/pull/11069) feat: improve presto query perf (#11069) (@etr2460)
- [#10971](https://github.com/apache/incubator-superset/pull/10971) style: improve "Datasource & Chart Type" <Label>s (#10971) (@mistercrunch)
- [#11086](https://github.com/apache/incubator-superset/pull/11086) docs: add changelog entries for 0.37.2 (#11086) (@villebro)
- [#11074](https://github.com/apache/incubator-superset/pull/11074) fix: Adding timeout to flaky cypress test, to wait for animation to complete (#11074) (@rusackas)
- [#11076](https://github.com/apache/incubator-superset/pull/11076) chore: cleaning out unused code from utils (#11076) (@rusackas)
- [#11077](https://github.com/apache/incubator-superset/pull/11077) fix: surface connection error messages on the client (#11077) (@mistercrunch)
- [#11079](https://github.com/apache/incubator-superset/pull/11079) fix(jest): using UTC mock date (#11079) (@zhaoyongjie)
- [#11072](https://github.com/apache/incubator-superset/pull/11072) removing unused component (#11072) (@rusackas)
- [#11073](https://github.com/apache/incubator-superset/pull/11073) changing to the correct hex color (#11073) (@rusackas)
- [#11071](https://github.com/apache/incubator-superset/pull/11071) style: remove unecessary padding (#11071) (@mistercrunch)
- [#11068](https://github.com/apache/incubator-superset/pull/11068) fix: database list checkboxes (#11068) (@riahk)
- [#11033](https://github.com/apache/incubator-superset/pull/11033) feat: adding all icons from the design system to the codebase (#11033) (@rusackas)
- [#11063](https://github.com/apache/incubator-superset/pull/11063) fix: sql lab autocomplete width (#11063) (@etr2460)
- [#11034](https://github.com/apache/incubator-superset/pull/11034) clickable labels have outlines, storybook shows them (#11034) (@rusackas)
- [#11052](https://github.com/apache/incubator-superset/pull/11052) fixed routes for customer in docs (#11052) (@srinify)
- [#11051](https://github.com/apache/incubator-superset/pull/11051) Revert "style: fix checkbox color (#10970)" (#11051) (@graceguo-supercat)
- [#11030](https://github.com/apache/incubator-superset/pull/11030) feat: add "created by" to dashboard CRUD view (#11030) (@lilykuang)
- [#11037](https://github.com/apache/incubator-superset/pull/11037) Changed `tags.py` and `helpers.py` in `models` module: removed disabled pylint rule `unused_import`, changed unused arguments to private and removed disabled rule `unused-argument. Removed redundant rules.` (#11037) (@kkucharc)
- [#11036](https://github.com/apache/incubator-superset/pull/11036) chore: updated lint rules in models module (#11036) (@kkucharc)
- [#11038](https://github.com/apache/incubator-superset/pull/11038) Removed disable global pytlint rule `standarderror-builtin` which isn't appearing for Python3 (#11038) (@kkucharc)
- [#11039](https://github.com/apache/incubator-superset/pull/11039) Enabled argument-differ for bulk_delete (#11039) (@kkucharc)
- [#11041](https://github.com/apache/incubator-superset/pull/11041) Enabled no-self-use pylint rule in security. Formatter (#11041) (@kkucharc)
- [#11044](https://github.com/apache/incubator-superset/pull/11044) Changed variable name from capitals to lowercase and changed lint rule (#11044) (@kkucharc)
- [#11050](https://github.com/apache/incubator-superset/pull/11050) Revert "ESLint: Re-enable rule default-props-match-prop-types (#10868)" (#11050) (@graceguo-supercat)
- [#11031](https://github.com/apache/incubator-superset/pull/11031) feat(saved_queries): add custom api filter for all string & text fields (#11031) (@nytai)
- [#11008](https://github.com/apache/incubator-superset/pull/11008) Support jinja templates (#11008) (@bkyryliuk)
- [#11018](https://github.com/apache/incubator-superset/pull/11018) chore: bump pandas to latest stable version (#11018) (@villebro)
- [#11029](https://github.com/apache/incubator-superset/pull/11029) fix: dashboard edit button (again) (#11029) (@graceguo-supercat)
- [#11011](https://github.com/apache/incubator-superset/pull/11011) style(explore): use tertiary button against gray background (#11011) (@mistercrunch)
- [#11023](https://github.com/apache/incubator-superset/pull/11023) docs: add security vulnerability GH issue template (#11023) (@robdiciuccio)
- [#11024](https://github.com/apache/incubator-superset/pull/11024) fix: [dashboard] should not show edit button when user has no edit permit (#11024) (@graceguo-supercat)
- [#11004](https://github.com/apache/incubator-superset/pull/11004) fix: timer component, fixes #10849, closes #11002 (#11004) (@ktmud)
- [#11000](https://github.com/apache/incubator-superset/pull/11000) fix: enable several pylint rules partially in db_engines_specs module (#11000) (@kkucharc)
- [#10974](https://github.com/apache/incubator-superset/pull/10974) fix: pylint checks in connectors/sqla/models.py (#10974) (@kkucharc)
- [#11014](https://github.com/apache/incubator-superset/pull/11014) fix: reenable pylint rule `unused-import` in charts and connectors modules (#11014) (@kkucharc)
- [#11016](https://github.com/apache/incubator-superset/pull/11016) Enabled pylint rules in `db_engines` module: (#11016) (@kkucharc)
- [#10978](https://github.com/apache/incubator-superset/pull/10978) fix: changes a pylint check in dashboard module (#10978) (@kkucharc)
- [#11009](https://github.com/apache/incubator-superset/pull/11009) fix: menu shows a 0 when there are not settings (#11009) (@nytai)
- [#11017](https://github.com/apache/incubator-superset/pull/11017) fix: query search low privileged user search access denied (#11017) (@dpgaspar)
- [#10994](https://github.com/apache/incubator-superset/pull/10994) chore: downgrade expected exception from error to info (#10994) (@nytai)
- [#10983](https://github.com/apache/incubator-superset/pull/10983) fix: Add Item Overflow on Dataset Editor (#10983) (@lilykuang)
- [#11007](https://github.com/apache/incubator-superset/pull/11007) Bring back import menu (#11007) (@betodealmeida)
- [#10986](https://github.com/apache/incubator-superset/pull/10986) feat(listview): feature flag config to set default viewing mode (#10986) (@nytai)
- [#11006](https://github.com/apache/incubator-superset/pull/11006) build: add react-hooks linting (#11006) (@ktmud)
- [#11003](https://github.com/apache/incubator-superset/pull/11003) fix: unbreak ci (#11003) (@etr2460)
- [#10998](https://github.com/apache/incubator-superset/pull/10998) fix: enable pylint rules in db_engine_specs module (#10998) (@kkucharc)
- [#10981](https://github.com/apache/incubator-superset/pull/10981) Replace reactable with DataTable from superset-ui in QueryTable (#10981) (@kgabryje)
- [#10868](https://github.com/apache/incubator-superset/pull/10868) ESLint: Re-enable rule default-props-match-prop-types (#10868) (@kgabryje)
- [#10966](https://github.com/apache/incubator-superset/pull/10966) feat: add ECharts Pie chart (#10966) (@villebro)
- [#10991](https://github.com/apache/incubator-superset/pull/10991) Enable subqueries in gsheetsdb (#10991) (@betodealmeida)
- [#10710](https://github.com/apache/incubator-superset/pull/10710) fix: deprecation warnings due to invalid escape sequences. (#10710) (@tirkarthi)
- [#10753](https://github.com/apache/incubator-superset/pull/10753) fix(presto): default unknown types to string type (#10753) (@villebro)
- [#10946](https://github.com/apache/incubator-superset/pull/10946) feat(row-level-security): add base filter type and filter grouping (#10946) (@villebro)
- [#10988](https://github.com/apache/incubator-superset/pull/10988) docs: add gallery screenshot & link in README (#10988) (@mistercrunch)
- [#10968](https://github.com/apache/incubator-superset/pull/10968) docs: add a "Gallery" page (#10968) (@mistercrunch)
- [#10990](https://github.com/apache/incubator-superset/pull/10990) build: add PR lint action (#10990) (@nytai)
- [#10989](https://github.com/apache/incubator-superset/pull/10989) adding filters back that caused issues (#10989) (@rusackas)
- [#10944](https://github.com/apache/incubator-superset/pull/10944) chore: selectors refactor in SQLLab test suite (Cypress) (#10944) (@adam-stasiak)
- [#10933](https://github.com/apache/incubator-superset/pull/10933) ESLint: Remove ts-ignore comments (#10933) (@kgabryje)
- [#10970](https://github.com/apache/incubator-superset/pull/10970) style: fix checkbox color (#10970) (@mistercrunch)
- [#10979](https://github.com/apache/incubator-superset/pull/10979) fix: changed disabled rules in datasets module (#10979) (@kkucharc)
- [#10829](https://github.com/apache/incubator-superset/pull/10829) fix: update the time filter for 'Last Year' option in explore (#10829) (@riahk)
- [#10938](https://github.com/apache/incubator-superset/pull/10938) fix: use nullpool even for user lookup in the celery (#10938) (@bkyryliuk)
- [#10939](https://github.com/apache/incubator-superset/pull/10939) Allow empty observations in alerting (#10939) (@bkyryliuk)
- [#10957](https://github.com/apache/incubator-superset/pull/10957) fix: re-enabling several globally disabled lint rules (#10957) (@kkucharc)
- [#10942](https://github.com/apache/incubator-superset/pull/10942) fix: setting specific exceptions common/query_context.py (#10942) (@kkucharc)
- [#10975](https://github.com/apache/incubator-superset/pull/10975) Pylint disabled rule `pointless-string-statement` is not raising warining anymore - removing (#10975) (@kkucharc)
- [#10976](https://github.com/apache/incubator-superset/pull/10976) fix: pylint disabled rules in dashboard/api.py (#10976) (@kkucharc)
- [#10958](https://github.com/apache/incubator-superset/pull/10958) fix: removed disabled lint rule `too-many-locals` in connectors/base/models.py (#10958) (@kkucharc)
- [#10870](https://github.com/apache/incubator-superset/pull/10870) ESLint: Re-enable rule no-access-state-in-setstate (#10870) (@kgabryje)
- [#10879](https://github.com/apache/incubator-superset/pull/10879) ESLint: Enable rule no-named-as-default (#10879) (@kgabryje)
- [#10961](https://github.com/apache/incubator-superset/pull/10961) ESLint: Remove ts-ignore (#10961) (@kgabryje)
- [#10921](https://github.com/apache/incubator-superset/pull/10921) docs: set up client-side redirects from previous era docs urls (#10921) (@srinify)
- [#10949](https://github.com/apache/incubator-superset/pull/10949) Ignore '/docs' on some GH actions, give docs its own action (#10949) (@rusackas)
- [#10959](https://github.com/apache/incubator-superset/pull/10959) fix: typo in prefer typescript (#10959) (@ktmud)
- [#10889](https://github.com/apache/incubator-superset/pull/10889) ESLint: no-restricted-syntax (#10889) (@kgabryje)
- [#10909](https://github.com/apache/incubator-superset/pull/10909) fix: several disabled pylint rules in models/helpers.py (#10909) (@kkucharc)
- [#10941](https://github.com/apache/incubator-superset/pull/10941) fix: update pylint disabled checks in common/query_context.py (#10941) (@kkucharc)
- [#10906](https://github.com/apache/incubator-superset/pull/10906) Updated `type: ignore` in model's helper: (#10906) (@kkucharc)
- [#10923](https://github.com/apache/incubator-superset/pull/10923) chore: upgrade cypress to use retries (#10923) (@eschutho)
- [#10926](https://github.com/apache/incubator-superset/pull/10926) chore: remove SIP_34_DATABASE_UI (#10926) (@nytai)
- [#10932](https://github.com/apache/incubator-superset/pull/10932) fix: address all disabled pylint checks in charts/api.py (#10932) (@kkucharc)
- [#10915](https://github.com/apache/incubator-superset/pull/10915) Removed global pylintrc rule: old-ne-operator. Which is not applicable in code anymore. (#10915) (@kkucharc)
- [#10922](https://github.com/apache/incubator-superset/pull/10922) feat: update saved query backend routing + add savedquery list (#10922) (@riahk)
- [#10911](https://github.com/apache/incubator-superset/pull/10911) Removed disabled linting redefined-outer-name. Url parameters are renamed where url was already defined in class attributes (#10911) (@kkucharc)
- [#10840](https://github.com/apache/incubator-superset/pull/10840) feat: adding dashboard toggle fullscreen button (#10840) (@zhaoyongjie)
- [#10918](https://github.com/apache/incubator-superset/pull/10918) fix lint errors (#10918) (@eschutho)
- [#10902](https://github.com/apache/incubator-superset/pull/10902) fix: babel script broken by format string (#10902) (@zhaoyongjie)
- [#10848](https://github.com/apache/incubator-superset/pull/10848) Update FOSSA configuration for new requirements layout (#10848) (@robdiciuccio)
- [#10908](https://github.com/apache/incubator-superset/pull/10908) Enable anchor-has-content rule (#10908) (@kgabryje)
- [#10898](https://github.com/apache/incubator-superset/pull/10898) docs: Client side redirects (one POC) (#10898) (@rusackas)
- [#10847](https://github.com/apache/incubator-superset/pull/10847) chore: update port that cypress runs on for local vs test (#10847) (@eschutho)
- [#10799](https://github.com/apache/incubator-superset/pull/10799) feat: use svg for checkbox component (#10799) (@eschutho)
- [#10897](https://github.com/apache/incubator-superset/pull/10897) fix: front end CI tests and test runner (#10897) (@eschutho)
- [#10891](https://github.com/apache/incubator-superset/pull/10891) fix: superset alerting misc fixes (#10891) (@bkyryliuk)
- [#10882](https://github.com/apache/incubator-superset/pull/10882) simplifying/clarifying youtube video code/datastructures (#10882) (@rusackas)
- [#10886](https://github.com/apache/incubator-superset/pull/10886) Fixing docs site home screen mobile layout issues (#10886) (@rusackas)
- [#10912](https://github.com/apache/incubator-superset/pull/10912) fix: spelling in docs homepage (#10912) (@etr2460)
- [#10903](https://github.com/apache/incubator-superset/pull/10903) docs: add back issue code links (#10903) (@mistercrunch)
- [#10901](https://github.com/apache/incubator-superset/pull/10901) build: optimize eslint import resolver configs (#10901) (@ktmud)
- [#10900](https://github.com/apache/incubator-superset/pull/10900) docs: redirect http -> https (#10900) (@mistercrunch)
- [#10875](https://github.com/apache/incubator-superset/pull/10875) refactor: ASF only dependencies on base.txt (#10875) (@dpgaspar)
- [#10893](https://github.com/apache/incubator-superset/pull/10893) docs: add changelog entries for 0.37.1 (#10893) (@villebro)
- [#10899](https://github.com/apache/incubator-superset/pull/10899) correcting 2 steps in docs deployment readme (#10899) (@rusackas)
- [#10895](https://github.com/apache/incubator-superset/pull/10895) chore: enable eslint-import-resolver-typescript (#10895) (@ktmud)
- [#10880](https://github.com/apache/incubator-superset/pull/10880) feat: data menu routing (#10880) (@riahk)
- [#10892](https://github.com/apache/incubator-superset/pull/10892) fix(cypress): prevent CI failure on codecov failure (#10892) (@nytai)
- [#10837](https://github.com/apache/incubator-superset/pull/10837) feat: move ace-editor and mathjs to async modules (#10837) (@ktmud)
- [#10885](https://github.com/apache/incubator-superset/pull/10885) fixing broken links (#10885) (@rusackas)
- [#10887](https://github.com/apache/incubator-superset/pull/10887) chore: Using cache factory method (#10887) (@john-bodley)
- [#10761](https://github.com/apache/incubator-superset/pull/10761) feat: implement cache invalidation api (#10761) (@bkyryliuk)
- [#10888](https://github.com/apache/incubator-superset/pull/10888) docs: fix ubuntu 20.04 installation instructions (#10888) (@villebro)
- [#10884](https://github.com/apache/incubator-superset/pull/10884) fix(cypress): wait for filterValues request (#10884) (@nytai)
- [#10877](https://github.com/apache/incubator-superset/pull/10877) Reviewed and repaired disabled pylint in dashboard file (#10877) (@kkucharc)
- [#10844](https://github.com/apache/incubator-superset/pull/10844) Feat: Adding table comment and columns comment for SQLLab (#10844) (@zhaoyongjie)
- [#10883](https://github.com/apache/incubator-superset/pull/10883) chore: clean up aphrodite (#10883) (@ktmud)
- [#10865](https://github.com/apache/incubator-superset/pull/10865) ESLint: Re-enable rule no-unused-vars (#10865) (@kgabryje)
- [#10862](https://github.com/apache/incubator-superset/pull/10862) Re-enable rule line-between-class-members (#10862) (@kgabryje)
- [#10873](https://github.com/apache/incubator-superset/pull/10873) Re-enable rule state-in-constructor (#10873) (@kgabryje)
- [#10866](https://github.com/apache/incubator-superset/pull/10866) ESLint: Re-enable rule control-has-associated-label (#10866) (@kgabryje)
- [#10861](https://github.com/apache/incubator-superset/pull/10861) Re-enable rule no-else-return (#10861) (@kgabryje)
- [#10876](https://github.com/apache/incubator-superset/pull/10876) Enable rule no-plusplus (#10876) (@kgabryje)
- [#10853](https://github.com/apache/incubator-superset/pull/10853) docs(style): make more responsive for mobile (#10853) (@mistercrunch)
- [#10872](https://github.com/apache/incubator-superset/pull/10872) Re-enable rule sort-comp (#10872) (@kgabryje)
- [#10869](https://github.com/apache/incubator-superset/pull/10869) Re-enable rule jsx-curly-brace-presence (#10869) (@kgabryje)
- [#10864](https://github.com/apache/incubator-superset/pull/10864) Re-enable rule no-non-null-assertion (#10864) (@kgabryje)
- [#10863](https://github.com/apache/incubator-superset/pull/10863) ESLint: Re-enable rule no-restricted-globals (#10863) (@kgabryje)
- [#10860](https://github.com/apache/incubator-superset/pull/10860) Re-enable no-useless-path-segments rule (#10860) (@kgabryje)
- [#10871](https://github.com/apache/incubator-superset/pull/10871) Re-enable rule no-unused-state (#10871) (@kgabryje)
- [#10867](https://github.com/apache/incubator-superset/pull/10867) Re-enable rule prefer-destructuring (only for objects) (#10867) (@kgabryje)
- [#10874](https://github.com/apache/incubator-superset/pull/10874) Re-enable no-confusing-arrow rule (#10874) (@kgabryje)
- [#10855](https://github.com/apache/incubator-superset/pull/10855) Adding editorconfig setting for IDE hints (#10855) (@zhaoyongjie)
- [#10859](https://github.com/apache/incubator-superset/pull/10859) Improvement contributing.md (#10859) (@zhaoyongjie)
- [#10839](https://github.com/apache/incubator-superset/pull/10839) Eslint dependencies versions updates (#10839) (@kgabryje)
- [#10850](https://github.com/apache/incubator-superset/pull/10850) feat: server side dashboard css for less repaint (#10850) (@ktmud)
- [#10846](https://github.com/apache/incubator-superset/pull/10846) Fix test_connection POST body (#10846) (@riahk)
- [#10851](https://github.com/apache/incubator-superset/pull/10851) style: white toolbar for SQL Lab (#10851) (@mistercrunch)
- [#10784](https://github.com/apache/incubator-superset/pull/10784) docs(new docs site): removes old sphinx doc site with gatsby (#10784) (@pkdotson)
- [#10745](https://github.com/apache/incubator-superset/pull/10745) feat: add/edit database modal form sections UI (#10745) (@riahk)
- [#10842](https://github.com/apache/incubator-superset/pull/10842) fix(test): missing auth on tests (#10842) (@dpgaspar)
- [#10841](https://github.com/apache/incubator-superset/pull/10841) update all python version in the Dockerfile to 3.7 (#10841) (@cyw233)
- [#10793](https://github.com/apache/incubator-superset/pull/10793) feat: SavedQuery REST API for bulk delete and new API fields (#10793) (@dpgaspar)
- [#10823](https://github.com/apache/incubator-superset/pull/10823) fix: Making the database read-only (#10823) (@john-bodley)
- [#10831](https://github.com/apache/incubator-superset/pull/10831) build: optimize webpack code split (#10831) (@ktmud)
- [#10824](https://github.com/apache/incubator-superset/pull/10824) fix(databases): test connection api endpoint (#10824) (@lilykuang)
- [#10819](https://github.com/apache/incubator-superset/pull/10819) fix: use nullpool in the celery workers (#10819) (@bkyryliuk)
- [#10821](https://github.com/apache/incubator-superset/pull/10821) build: split hive and presto tests to separate jobs (#10821) (@ktmud)
- [#10818](https://github.com/apache/incubator-superset/pull/10818) fix(tests): export dataset tests fails with presto (#10818) (@dpgaspar)
- [#10822](https://github.com/apache/incubator-superset/pull/10822) Revert "chore: add logging for "dashboard" action (#10744)" (#10822) (@graceguo-supercat)
- [#10798](https://github.com/apache/incubator-superset/pull/10798) Spanish translations (#10798) (@rubenSastre)
- [#10723](https://github.com/apache/incubator-superset/pull/10723) feat(databases): test connection api (#10723) (@lilykuang)
- [#10790](https://github.com/apache/incubator-superset/pull/10790) refactor: merge/upgrade superset-ui packages (#10790) (@ktmud)
- [#10813](https://github.com/apache/incubator-superset/pull/10813) fix: bump node version on Dockerfile to be on par with docker-compose (#10813) (@fguarini)
- [#10795](https://github.com/apache/incubator-superset/pull/10795) fix: Database API missing allow none on fields (#10795) (@dpgaspar)
- [#10803](https://github.com/apache/incubator-superset/pull/10803) chore: deprecate python 3.6 support (#10803) (@villebro)
- [#10800](https://github.com/apache/incubator-superset/pull/10800) feat: database delete warning (#10800) (@nytai)
- [#10810](https://github.com/apache/incubator-superset/pull/10810) test: add rls jinja extra cache key test (#10810) (@villebro)
- [#10796](https://github.com/apache/incubator-superset/pull/10796) docs: Add a note to contributing.md on reporting security vulnerabilities (#10796) (@suddjian)
- [#10772](https://github.com/apache/incubator-superset/pull/10772) feat: filters for database list view (#10772) (@nytai)
- [#10781](https://github.com/apache/incubator-superset/pull/10781) fix: MVC show saved query (#10781) (@dpgaspar)
- [#10789](https://github.com/apache/incubator-superset/pull/10789) added creator column and adjusted order columns (#10789) (@JasonD28)
- [#10777](https://github.com/apache/incubator-superset/pull/10777) feat: CRUD REST API for saved queries (#10777) (@dpgaspar)
- [#10787](https://github.com/apache/incubator-superset/pull/10787) fix: disable domain sharding on explore view (#10787) (@graceguo-supercat)
- [#10778](https://github.com/apache/incubator-superset/pull/10778) fix: can not type `0.05` in `TextControl` (#10778) (@hushaoqing)
- [#10762](https://github.com/apache/incubator-superset/pull/10762) fix: add validator information to email/slack alerts (#10762) (@JasonD28)
- [#10722](https://github.com/apache/incubator-superset/pull/10722) More Label touchups (margins) (#10722) (@rusackas)
- [#10692](https://github.com/apache/incubator-superset/pull/10692) fix: dashboard extra filters (#10692) (@john-bodley)
- [#10766](https://github.com/apache/incubator-superset/pull/10766) fix: re-installing local superset in cache image (#10766) (@craig-rueda)
- [#10705](https://github.com/apache/incubator-superset/pull/10705) feat: SIP-34 table list view for databases (#10705) (@nytai)
- [#10746](https://github.com/apache/incubator-superset/pull/10746) refactor: convert DatasetList schema filter to use new distinct api (#10746) (@nytai)
- [#10751](https://github.com/apache/incubator-superset/pull/10751) chore: removing fsevents dependency (#10751) (@rusackas)
- [#10759](https://github.com/apache/incubator-superset/pull/10759) Fix precommit hook for docs/installation.rst (#10759) (@willbarrett)
- [#10741](https://github.com/apache/incubator-superset/pull/10741) feat(database): POST, PUT, DELETE API endpoints (#10741) (@dpgaspar)
- [#10748](https://github.com/apache/incubator-superset/pull/10748) docs: Update OAuth configuration in installation.rst (#10748) (@jagamts1)
- [#10752](https://github.com/apache/incubator-superset/pull/10752) feat(viz): add ECharts Timeseries chart (#10752) (@villebro)
- [#10744](https://github.com/apache/incubator-superset/pull/10744) chore: add logging for "dashboard" action (#10744) (@graceguo-supercat)
- [#10758](https://github.com/apache/incubator-superset/pull/10758) merge db migrations (#10758) (@JasonD28)
- [#10738](https://github.com/apache/incubator-superset/pull/10738) fix: local docker deployment (#10738) (@vigneshTheDev)
- [#10750](https://github.com/apache/incubator-superset/pull/10750) moving all @types to dev dependencies (#10750) (@rusackas)
- [#10511](https://github.com/apache/incubator-superset/pull/10511) docs: Updated Docker local install instructions (#10511) (@ceohockey60)
- [#10605](https://github.com/apache/incubator-superset/pull/10605) feat: refractored SQL-based alerting framework (#10605) (@JasonD28)
- [#10678](https://github.com/apache/incubator-superset/pull/10678) chore: log cache keys to the logs (#10678) (@bkyryliuk)
- [#10747](https://github.com/apache/incubator-superset/pull/10747) Fix: Rejiggering some dependencies, trying to get CI to pass (#10747) (@rusackas)
- [#10728](https://github.com/apache/incubator-superset/pull/10728) style: Tabs now support AntD compound components (+ basic stories) (#10728) (@rusackas)
- [#10733](https://github.com/apache/incubator-superset/pull/10733) chore: bump pyarrow (#10733) (@villebro)
- [#10715](https://github.com/apache/incubator-superset/pull/10715) style: rename 'Source' top nav item to 'Data' (#10715) (@mistercrunch)
- [#10649](https://github.com/apache/incubator-superset/pull/10649) style: Pass at propagating (and enhancing) Button component throughout Superset (#10649) (@rusackas)
- [#10704](https://github.com/apache/incubator-superset/pull/10704) Covert celery tests to the pytest (#10704) (@bkyryliuk)
- [#10720](https://github.com/apache/incubator-superset/pull/10720) chore: update samesite config documentation (#10720) (@etr2460)
- [#10717](https://github.com/apache/incubator-superset/pull/10717) fix: move menu reorg logic from crud app into Menu component (#10717) (@nytai)
- [#10674](https://github.com/apache/incubator-superset/pull/10674) fix: change public role like gamma procedure (#10674) (@dpgaspar)
- [#10668](https://github.com/apache/incubator-superset/pull/10668) feat: base tabbed modal for new database CRUD UI (#10668) (@riahk)
- [#10698](https://github.com/apache/incubator-superset/pull/10698) style: add border between menu and submenu (#10698) (@nytai)
- [#10695](https://github.com/apache/incubator-superset/pull/10695) Use test name for the custom macros testing: (#10695) (@bkyryliuk)
- [#10699](https://github.com/apache/incubator-superset/pull/10699) fix: card view failed cypress tests (#10699) (@lilykuang)
- [#10439](https://github.com/apache/incubator-superset/pull/10439) style: Move security/manage navigation tabs into a settings dropdown (#10439) (@riahk)
- [#10693](https://github.com/apache/incubator-superset/pull/10693) fix: shorten url with extra request parameters (#10693) (@graceguo-supercat)
- [#10593](https://github.com/apache/incubator-superset/pull/10593) chore: ci Initial hive support (#10593) (@bkyryliuk)
- [#10691](https://github.com/apache/incubator-superset/pull/10691) feat(listview): set default view mode based on THUMBNAIL feature flag (#10691) (@nytai)
- [#10669](https://github.com/apache/incubator-superset/pull/10669) feat: chart and dashboard card list view e2e cypress test (#10669) (@lilykuang)
- [#10690](https://github.com/apache/incubator-superset/pull/10690) chore: Fix indentation issue (#10690) (@john-bodley)
- [#10680](https://github.com/apache/incubator-superset/pull/10680) refactor: useListViewResource hook for charts, dashboards, datasets (#10680) (@nytai)
- [#10682](https://github.com/apache/incubator-superset/pull/10682) fix: SubMenu css (#10682) (@nytai)
- [#10681](https://github.com/apache/incubator-superset/pull/10681) fix: layout flexiness (#10681) (@rusackas)
- [#10677](https://github.com/apache/incubator-superset/pull/10677) fix: only call signal if executing on the main thread (#10677) (@henryyeh)
- [#10675](https://github.com/apache/incubator-superset/pull/10675) feature: Adding extra_filters to warm_up_cache (#10675) (@john-bodley)
- [#10676](https://github.com/apache/incubator-superset/pull/10676) fix(sqllab): log exceptions caused by the user as debug and not error (#10676) (@nytai)
- [#10423](https://github.com/apache/incubator-superset/pull/10423) style: Fancier menus, more SIP-34-ish (#10423) (@rusackas)
- [#10657](https://github.com/apache/incubator-superset/pull/10657) Eslint error cleanup (#10657) (@rusackas)
- [#10658](https://github.com/apache/incubator-superset/pull/10658) fix(db_engine_specs): improve Presto column type matching (#10658) (@villebro)
- [#10661](https://github.com/apache/incubator-superset/pull/10661) fix(db_engine_specs): mysql longtext type should not be numeric (#10661) (@villebro)
- [#10652](https://github.com/apache/incubator-superset/pull/10652) Remove incorrect comment (#10652) (@willbarrett)
- [#9321](https://github.com/apache/incubator-superset/pull/9321) Fix add chart page frontend i18n issue (#9321) (@auxten)
- [#10401](https://github.com/apache/incubator-superset/pull/10401) fix: remove FAB rendered menu in favor of react based one (#10401) (@nytai)
- [#10651](https://github.com/apache/incubator-superset/pull/10651) feat: use shorten url in standalone iframe (#10651) (@graceguo-supercat)
- [#10606](https://github.com/apache/incubator-superset/pull/10606) feat(listview): skeleton loading states for table and card collections (#10606) (@nytai)
- [#10647](https://github.com/apache/incubator-superset/pull/10647) feat: Getting fancier with Storybook (#10647) (@rusackas)
- [#10650](https://github.com/apache/incubator-superset/pull/10650) feat: bump superset-ui for certified tag (#10650) (@etr2460)
- [#10642](https://github.com/apache/incubator-superset/pull/10642) feat: setup react page with submenu for datasources listview (#10642) (@nytai)
- [#10630](https://github.com/apache/incubator-superset/pull/10630) feat: add certification to metrics (#10630) (@etr2460)
- [#10644](https://github.com/apache/incubator-superset/pull/10644) fix: controls scroll issue (#10644) (@rusackas)
- [#10634](https://github.com/apache/incubator-superset/pull/10634) feat: Allow tests files in /src (plus Label component tests) (#10634) (@rusackas)
- [#10643](https://github.com/apache/incubator-superset/pull/10643) fix: remove duplicated params and cache_timeout from list_columns; add viz_type to list_columns (#10643) (@lilykuang)
- [#10631](https://github.com/apache/incubator-superset/pull/10631) chore: splitting button stories into separate stories (#10631) (@rusackas)
- [#10603](https://github.com/apache/incubator-superset/pull/10603) refactor: remove slice level label_colors from dashboard init load (#10603) (@graceguo-supercat)
- [#10607](https://github.com/apache/incubator-superset/pull/10607) feat: card view bulk select (#10607) (@lilykuang)
- [#10627](https://github.com/apache/incubator-superset/pull/10627) style: Label styling/storybook touchups (#10627) (@rusackas)
- [#10625](https://github.com/apache/incubator-superset/pull/10625) fix: removing unsupported modal sizes (#10625) (@rusackas)
- [#10619](https://github.com/apache/incubator-superset/pull/10619) feat(datasource): remove deleted columns and update column type on metadata refresh (#10619) (@villebro)
- [#10613](https://github.com/apache/incubator-superset/pull/10613) chore: npm audit fix as of 2020-08-15 (#10613) (@mistercrunch)
- [#10595](https://github.com/apache/incubator-superset/pull/10595) feat: dataset REST API for distinct values (#10595) (@dpgaspar)
- [#10602](https://github.com/apache/incubator-superset/pull/10602) chore: bump react-redux to 5.1.2, whittling console noise (#10602) (@rusackas)
- [#10604](https://github.com/apache/incubator-superset/pull/10604) fixing console error about bad html attribute (#10604) (@rusackas)
- [#10608](https://github.com/apache/incubator-superset/pull/10608) chore: migrate console logs to logging service (#10608) (@rusackas)
- [#10590](https://github.com/apache/incubator-superset/pull/10590) refactor: [migration] convert iframe chart into dashboard markdown component (#10590) (@graceguo-supercat)
- [#10601](https://github.com/apache/incubator-superset/pull/10601) feat: sort card view by Alphabetical, Recently Modified, and Least Recently Modified (#10601) (@lilykuang)
- [#10600](https://github.com/apache/incubator-superset/pull/10600) docs: update CHANGELOG.md and UPDATING.md for 0.37.0 (#10600) (@villebro)
- [#10562](https://github.com/apache/incubator-superset/pull/10562) fix(thumbnails): missing field, logging and new config var (#10562) (@dpgaspar)
- [#10526](https://github.com/apache/incubator-superset/pull/10526) feat: SIP-34 card/grid views for dashboards and charts (#10526) (@nytai)
- [#10504](https://github.com/apache/incubator-superset/pull/10504) fix: More tweaks needed after adding Doctype tag (#10504) (@rusackas)
- [#10592](https://github.com/apache/incubator-superset/pull/10592) feat: add extra column to tables and sql_metrics (#10592) (@etr2460)
- [#10567](https://github.com/apache/incubator-superset/pull/10567) chore: Migrating reports to AuthWebdriverProxy (#10567) (@craig-rueda)
- [#10509](https://github.com/apache/incubator-superset/pull/10509) docs: Update engine installation (#10509) (@john-bodley)
- [#10584](https://github.com/apache/incubator-superset/pull/10584) fix: add None checking to cast_to_num (#10584) (@villebro)
- [#10580](https://github.com/apache/incubator-superset/pull/10580) fix: error message modal overflow (#10580) (@etr2460)
- [#10581](https://github.com/apache/incubator-superset/pull/10581) Update .asf.yaml (#10581) (@etr2460)
- [#10549](https://github.com/apache/incubator-superset/pull/10549) feat(table-viz): translation and metric column header align right (#10549) (@ktmud)
- [#10573](https://github.com/apache/incubator-superset/pull/10573) fix: add translate for dropdown menu (#10573) (@stuarthu)
- [#10566](https://github.com/apache/incubator-superset/pull/10566) feat: slack integration for SQL-based alerts (#10566) (@JasonD28)
- [#10518](https://github.com/apache/incubator-superset/pull/10518) fix(sqllab): Handle long table names in SQL Lab (#10518) (@suddjian)
- [#10529](https://github.com/apache/incubator-superset/pull/10529) fix: misaligned LimitControl buttons and port jsx->tsx (#10529) (@mistercrunch)
- [#10545](https://github.com/apache/incubator-superset/pull/10545) chore: move load examples to the fixture (#10545) (@bkyryliuk)
- [#10558](https://github.com/apache/incubator-superset/pull/10558) fix drill installation (#10558) (@blcksrx)
- [#10556](https://github.com/apache/incubator-superset/pull/10556) chore: clean up csv tests (#10556) (@bkyryliuk)
- [#10542](https://github.com/apache/incubator-superset/pull/10542) fix: add retry to SQL-based alerting celery task (#10542) (@JasonD28)
- [#10536](https://github.com/apache/incubator-superset/pull/10536) fix: Resolves #10535 (#10536) (@john-bodley)
- [#10550](https://github.com/apache/incubator-superset/pull/10550) fix: Updating Dockerfile to work with updated python requirements. (#10550) (@craig-rueda)
- [#10557](https://github.com/apache/incubator-superset/pull/10557) Removing trailing space and fix CI (#10557) (@bkyryliuk)
- [#10527](https://github.com/apache/incubator-superset/pull/10527) fix(dashboard): changing the chart title, except not (#10527) (@suddjian)
- [#10553](https://github.com/apache/incubator-superset/pull/10553) docs: add additional project tags (#10553) (@ceohockey60)
- [#10455](https://github.com/apache/incubator-superset/pull/10455) chore: Migrate Timer component from jsx to tsx (#10455) (@tanmaylaud)
- [#10477](https://github.com/apache/incubator-superset/pull/10477) docs: Update and refresh homepage of superset.apache.org (#10477) (@ceohockey60)
- [#10494](https://github.com/apache/incubator-superset/pull/10494) chore: TypeScript <Label /> (#10494) (@mistercrunch)
- [#10541](https://github.com/apache/incubator-superset/pull/10541) ci: bump pre-commit py36 to py37 (#10541) (@villebro)
- [#10537](https://github.com/apache/incubator-superset/pull/10537) Revert "chore: Cleanup database sessions (#10427)" (#10537) (@etr2460)
- [#10473](https://github.com/apache/incubator-superset/pull/10473) feat: refactor error components and add database issue code (#10473) (@etr2460)
- [#10498](https://github.com/apache/incubator-superset/pull/10498) feat: welcome presto to the suite of tested databases (#10498) (@bkyryliuk)
- [#10394](https://github.com/apache/incubator-superset/pull/10394) style: use tabs in dashboard edit pane (#10394) (@mistercrunch)
- [#10508](https://github.com/apache/incubator-superset/pull/10508) feat: Add antd to the codebase (#10508) (@nruhe)
- [#10110](https://github.com/apache/incubator-superset/pull/10110) ci: bump tests to 3.7 and add support for 3.8 (#10110) (@villebro)
- [#10412](https://github.com/apache/incubator-superset/pull/10412) fix: show label for filters in filter box in explore (#10412) (@simchaNielsen)
- [#10515](https://github.com/apache/incubator-superset/pull/10515) feat: storybook for Icon component (#10515) (@rusackas)
- [#10425](https://github.com/apache/incubator-superset/pull/10425) fix db installaion (#10425) (@blcksrx)
- [#10499](https://github.com/apache/incubator-superset/pull/10499) chore: Adding pip-compile-multi et al. (#10499) (@john-bodley)
- [#10510](https://github.com/apache/incubator-superset/pull/10510) feat: add favorite star to dashboard and chart lists (#10510) (@riahk)
- [#10519](https://github.com/apache/incubator-superset/pull/10519) fix: make SQL-based alert email links user friendly (#10519) (@JasonD28)
- [#10505](https://github.com/apache/incubator-superset/pull/10505) fix: explore panel missing padding (#10505) (@ktmud)
- [#10513](https://github.com/apache/incubator-superset/pull/10513) Add link to July community meetup (#10513) (@ceohockey60)
- [#10512](https://github.com/apache/incubator-superset/pull/10512) feat: updated email format for SQL-based email alerts (#10512) (@JasonD28)
- [#10444](https://github.com/apache/incubator-superset/pull/10444) feat: dataset editor improvements (#10444) (@lilykuang)
- [#10506](https://github.com/apache/incubator-superset/pull/10506) fix: refactored SQL-based alerts to not pass sqlalchemy objects as args (#10506) (@JasonD28)
- [#10507](https://github.com/apache/incubator-superset/pull/10507) docs: new contributing language around adding new plugins (#10507) (@rusackas)
- [#10502](https://github.com/apache/incubator-superset/pull/10502) docs: add a '.asf.yaml' file to configure our GitHub (#10502) (@mistercrunch)
- [#10368](https://github.com/apache/incubator-superset/pull/10368) docs: Add supported database logos (#10368) (@ceohockey60)
- [#10378](https://github.com/apache/incubator-superset/pull/10378) authentication type methods docs (#10378) (@blcksrx)
- [#10487](https://github.com/apache/incubator-superset/pull/10487) Sample test data (#10487) (@bkyryliuk)
- [#10500](https://github.com/apache/incubator-superset/pull/10500) chore: pre-commit run --all-files (#10500) (@john-bodley)
- [#10492](https://github.com/apache/incubator-superset/pull/10492) test: schedules test refactor (#10492) (@ktmud)
- [#10481](https://github.com/apache/incubator-superset/pull/10481) add translate string to zh locale (#10481) (@stuarthu)
- [#10420](https://github.com/apache/incubator-superset/pull/10420) style: replace inclusive/exclusive on DateFilterControl with </≤ (#10420) (@villebro)
- [#10482](https://github.com/apache/incubator-superset/pull/10482) fix: enforce mandatory chart name on save and edit (#10482) (@villebro)
- [#10474](https://github.com/apache/incubator-superset/pull/10474) feat: add linear color scale to sunburst chart (#10474) (@villebro)
- [#10427](https://github.com/apache/incubator-superset/pull/10427) chore: Cleanup database sessions (#10427) (@john-bodley)
- [#10485](https://github.com/apache/incubator-superset/pull/10485) build: optimize GitHub Actions for building speed and stability (#10485) (@ktmud)
- [#10476](https://github.com/apache/incubator-superset/pull/10476) feat: add test email functionality to SQL-based email alerts (#10476) (@JasonD28)
- [#10472](https://github.com/apache/incubator-superset/pull/10472) made screenshot drivertype configurable (#10472) (@JasonD28)
- [#10302](https://github.com/apache/incubator-superset/pull/10302) style: DOCTYPE tag, and related CSS cleanup/refactoring (#10302) (@rusackas)
- [#10446](https://github.com/apache/incubator-superset/pull/10446) style: FilterSelect style tweaks (#10446) (@mistercrunch)
- [#10461](https://github.com/apache/incubator-superset/pull/10461) fix(sqllab): button width isn't wide enough for 'Run Selection' (#10461) (@mistercrunch)
- [#10462](https://github.com/apache/incubator-superset/pull/10462) style: make database list less bloated (#10462) (@mistercrunch)
- [#10478](https://github.com/apache/incubator-superset/pull/10478) fix: timeout error message (#10478) (@etr2460)
- [#10467](https://github.com/apache/incubator-superset/pull/10467) test: upload excel (#10467) (@blcksrx)
- [#10442](https://github.com/apache/incubator-superset/pull/10442) refactor(listviews): use correct filter endpoints for charts and datasets (#10442) (@nytai)
- [#10459](https://github.com/apache/incubator-superset/pull/10459) test: Add jest-enzyme assertion library for better frontend tests (#10459) (@suddjian)
- [#10436](https://github.com/apache/incubator-superset/pull/10436) feat(api): database schemas migration to new API (#10436) (@dpgaspar)
- [#10457](https://github.com/apache/incubator-superset/pull/10457) fix: change "add new slice" copy to "add new chart" (#10457) (@riahk)
- [#10454](https://github.com/apache/incubator-superset/pull/10454) fix: Implement updates to SQL-based email alerts (#10454) (@JasonD28)
- [#10456](https://github.com/apache/incubator-superset/pull/10456) fix(presto): Handle ROW data stored as string (#10456) (@betodealmeida)
- [#10347](https://github.com/apache/incubator-superset/pull/10347) feat: update dataset editor modal (#10347) (@lilykuang)
- [#10422](https://github.com/apache/incubator-superset/pull/10422) style: update +NEW button to use Button component, add dropdownItems prop to Button (#10422) (@riahk)
- [#10453](https://github.com/apache/incubator-superset/pull/10453) chore: migrate Checkbox to tsx (#10453) (@tanmaylaud)
- [#10251](https://github.com/apache/incubator-superset/pull/10251) docs: pointers to plugins blog post (#10251) (@mistercrunch)
- [#10445](https://github.com/apache/incubator-superset/pull/10445) chore: removing VictoryTheme.js (#10445) (@rusackas)
- [#10335](https://github.com/apache/incubator-superset/pull/10335) feat(listviews): SIP-34 filters for charts, dashboards, datasets (#10335) (@nytai)
- [#10426](https://github.com/apache/incubator-superset/pull/10426) chore: migrated Menu component to tsx (#10426) (@tanmaylaud)
- [#10241](https://github.com/apache/incubator-superset/pull/10241) fix(permissions): alpha role has all full features (#10241) (@dpgaspar)
- [#10403](https://github.com/apache/incubator-superset/pull/10403) style: SIP-34 labels (#10403) (@mistercrunch)
- [#10369](https://github.com/apache/incubator-superset/pull/10369) fix: allow creating table option and remove schema requirement in dataset add modal (#10369) (@nytai)
- [#10404](https://github.com/apache/incubator-superset/pull/10404) style(sqllab): fixed button width as label changes (#10404) (@mistercrunch)
- [#10406](https://github.com/apache/incubator-superset/pull/10406) chore: deactive flaky filter test (#10406) (@mistercrunch)
- [#10402](https://github.com/apache/incubator-superset/pull/10402) style: add fade transition to bottom border on navbar menu items (#10402) (@riahk)
- [#10392](https://github.com/apache/incubator-superset/pull/10392) fix(api): fixes perf on charts and introduces sorting by database on datasets (#10392) (@dpgaspar)
- [#10397](https://github.com/apache/incubator-superset/pull/10397) fix(charts): disable CSRF for chart data endpoint (#10397) (@dpgaspar)
- [#10393](https://github.com/apache/incubator-superset/pull/10393) fix(api): fixes openapi spec errors and adds a test to validate all spec (#10393) (@dpgaspar)
- [#10388](https://github.com/apache/incubator-superset/pull/10388) chore: wiring ControlLabel to a new FormLabel (#10388) (@mistercrunch)
- [#10355](https://github.com/apache/incubator-superset/pull/10355) feat: SIP-34 explore save modal (#10355) (@mistercrunch)
- [#10398](https://github.com/apache/incubator-superset/pull/10398) fix: dataset list filters bug (#10398) (@lilykuang)
- [#10383](https://github.com/apache/incubator-superset/pull/10383) feat: adding Storybook to Superset (#10383) (@rusackas)
- [#10380](https://github.com/apache/incubator-superset/pull/10380) fix(datasets): sort and humanized modified by (#10380) (@dpgaspar)
- [#10384](https://github.com/apache/incubator-superset/pull/10384) style: make listviews overflow scroll; convert less to emotion (#10384) (@nytai)
- [#10381](https://github.com/apache/incubator-superset/pull/10381) style: SIP-34 control-label (#10381) (@mistercrunch)
- [#10379](https://github.com/apache/incubator-superset/pull/10379) style: add warning msg to "Change Datasource" modal (#10379) (@mistercrunch)
- [#10162](https://github.com/apache/incubator-superset/pull/10162) chore: remove QueryView (ModelView) (#10162) (@mistercrunch)
- [#10371](https://github.com/apache/incubator-superset/pull/10371) feat: add TXT as default CSV extension (#10371) (@villebro)
- [#10363](https://github.com/apache/incubator-superset/pull/10363) chore: uniform icons across list views (#10363) (@mistercrunch)
- [#10274](https://github.com/apache/incubator-superset/pull/10274) feat: update timeout error UX (#10274) (@etr2460)
- [#10366](https://github.com/apache/incubator-superset/pull/10366) docs: add and update README badges (#10366) (@ceohockey60)
- [#10346](https://github.com/apache/incubator-superset/pull/10346) move control panel to filterbox folder (#10346) (@pkdotson)
- [#10324](https://github.com/apache/incubator-superset/pull/10324) feat: add optional prophet forecasting functionality to chart data api (#10324) (@villebro)
- [#10361](https://github.com/apache/incubator-superset/pull/10361) check for empty dataframes before processing results (#10361) (@bryanck)
- [#10360](https://github.com/apache/incubator-superset/pull/10360) fix: update community Slack link (#10360) (@ceohockey60)
- [#10291](https://github.com/apache/incubator-superset/pull/10291) chore: Silencing unused thumbnail cache config (#10291) (@john-bodley)
- [#10351](https://github.com/apache/incubator-superset/pull/10351) chore: enable no-static-element-interactions eslint rule (#10351) (@etr2460)
- [#10350](https://github.com/apache/incubator-superset/pull/10350) chore: enable no-unused-vars and prefer-template eslint rules (#10350) (@etr2460)
- [#10298](https://github.com/apache/incubator-superset/pull/10298) feat(listviews): SIP-34 Bulk Select (#10298) (@nytai)
- [#10339](https://github.com/apache/incubator-superset/pull/10339) tests: update test run doc and add some improvements (#10339) (@dpgaspar)
- [#10303](https://github.com/apache/incubator-superset/pull/10303) refactor: database API OpenAPI spec and location (#10303) (@dpgaspar)
- [#10315](https://github.com/apache/incubator-superset/pull/10315) docs(readme): move Slack guidelines to CODE_OF_CONDUCT (#10315) (@mistercrunch)
- [#10275](https://github.com/apache/incubator-superset/pull/10275) fix: add additional ui tweaks (#10275) (@graceguo-supercat)
- [#10320](https://github.com/apache/incubator-superset/pull/10320) chore: prefer allow/deny terminology (#10320) (@villebro)
- [#10318](https://github.com/apache/incubator-superset/pull/10318) chore: remove unused files from root (#10318) (@mistercrunch)
- [#10297](https://github.com/apache/incubator-superset/pull/10297) feat: add download as image button to explore (#10297) (@etr2460)
- [#10267](https://github.com/apache/incubator-superset/pull/10267) fix: broken glyphicons used in react-json-schema (#10267) (@mistercrunch)
- [#10314](https://github.com/apache/incubator-superset/pull/10314) docs(readme): license info in README is redundant (#10314) (@mistercrunch)
- [#10301](https://github.com/apache/incubator-superset/pull/10301) refactor: dashboards OpenAPI spec (#10301) (@dpgaspar)
- [#10306](https://github.com/apache/incubator-superset/pull/10306) chore: clarify logging source field (#10306) (@etr2460)
- [#10271](https://github.com/apache/incubator-superset/pull/10271) Add more fields to the log API (#10271) (@bkyryliuk)
- [#10287](https://github.com/apache/incubator-superset/pull/10287) refactor: charts OpenAPI spec (#10287) (@dpgaspar)
- [#10289](https://github.com/apache/incubator-superset/pull/10289) fix: saving custom CSS correctly (#10289) (@rusackas)
- [#10212](https://github.com/apache/incubator-superset/pull/10212) docs: create INTHEWILD.md (#10212) (@ceohockey60)
- [#10290](https://github.com/apache/incubator-superset/pull/10290) fix: fetch datasets list after dataset created successfully (#10290) (@lilykuang)
### 0.37.2 (2020/09/21 11:45 +00:00)
- [#10964](https://github.com/apache/incubator-superset/pull/10964) fix: simply is_adhoc_metric (#10964) (@villebro)
- [#10934](https://github.com/apache/incubator-superset/pull/10934) fix(jinja): make context attrs private on SQL templates (#10934) (@dpgaspar)

View File

@@ -105,14 +105,15 @@ git push upstream $SUPERSET_GITHUB_BRANCH
Next, update the `CHANGELOG.md` with all the changes that are included in the release.
Make sure the branch has been pushed to `upstream` to ensure the changelog generator
can pick up changes since the previous release (otherwise `github-changes` will raise
an `Error: Not Found` exception).
can pick up changes since the previous release.
Example:
```bash
# will overwrites the local CHANGELOG.md, somehow you need to merge it in
github-changes -o apache -r incubator-superset --token $GITHUB_TOKEN -b $SUPERSET_GITHUB_BRANCH
python changelog.py --previous_version 0.37 --current_version 0.38 changelog
```
The script will checkout both branches and compare all the PR's, copy the output and paste it on the `CHANGELOG.md`
Then, in `UPDATING.md`, a file that contains a list of notifications around
deprecations and upgrading-related topics,
make sure to move the content now under the `Next Version` section under a new

268
RELEASING/changelog.py Normal file
View File

@@ -0,0 +1,268 @@
#
# 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 json
import os
import re
from dataclasses import dataclass
from time import sleep
from typing import Any, Dict, List, Optional, Union
from urllib import request
from urllib.error import HTTPError
import click
@dataclass
class GitLog:
"""
Represents a git log entry
"""
sha: str
author: str
time: str
message: str
pr_number: Union[int, None] = None
def __eq__(self, other: object) -> bool:
""" A log entry is considered equal if it has the same PR number """
if isinstance(other, self.__class__):
return other.pr_number == self.pr_number
return False
def __repr__(self):
return f"[{self.pr_number}]: {self.message} {self.time} {self.author}"
class GitChangeLog:
"""
Helper class to output a list of logs entries on a superset changelog format
We want to map a git author to a github login, for that we call github's API
"""
def __init__(self, version: str, logs: List[GitLog]) -> None:
self._version = version
self._logs = logs
self._github_login_cache: Dict[str, Optional[str]] = {}
self._wait = 10
def _wait_github_rate_limit(self) -> None:
"""
Waits for available rate limit slots on the github API
"""
while True:
rate_limit_payload = self._fetch_github_rate_limit()
if rate_limit_payload["rate"]["remaining"] > 1:
break
print(".", end="", flush=True)
sleep(self._wait)
print()
def _fetch_github_rate_limit(self) -> Dict[str, Any]:
"""
Fetches current github rate limit info
"""
with request.urlopen(f"https://api.github.com/rate_limit") as response:
payload = json.loads(response.read())
return payload
def _fetch_github_pr(self, pr_number) -> Dict[str, Any]:
"""
Fetches a github PR info
"""
payload = {}
try:
self._wait_github_rate_limit()
with request.urlopen(
f"https://api.github.com/repos/apache/incubator-superset/pulls/"
f"{pr_number}"
) as response:
payload = json.loads(response.read())
except HTTPError as ex:
print(f"{ex}", flush=True)
return payload
def _get_github_login(self, git_log: GitLog) -> Optional[str]:
"""
Tries to fetch a github login (username) from a git author
"""
author_name = git_log.author
github_login = self._github_login_cache.get(author_name)
if github_login:
return github_login
pr_info = self._fetch_github_pr(git_log.pr_number)
if pr_info:
github_login = pr_info["user"]["login"]
else:
github_login = author_name
# set cache
self._github_login_cache[author_name] = github_login
return github_login
def _get_changelog_version_head(self):
return f"### {self._version} ({self._logs[0].time})"
def __repr__(self):
result = f"\n{self._get_changelog_version_head()}\n"
for i, log in enumerate(self._logs):
github_login = self._get_github_login(log)
if not github_login:
github_login = log.author
result = result + (
f"- [#{log.pr_number}]"
f"(https://github.com/apache/incubator-superset/pull/{log.pr_number}) "
f"{log.message} (@{github_login})\n"
)
print(f"\r {i}/{len(self._logs)}", end="", flush=True)
return result
class GitLogs:
"""
Manages git log entries from a specific branch/tag
Can compare git log entries by PR number
"""
def __init__(self, git_ref: str) -> None:
self._git_ref = git_ref
self._logs: List[GitLog] = []
@property
def git_ref(self) -> str:
return self._git_ref
@property
def logs(self) -> List[GitLog]:
return self._logs
def fetch(self):
self._logs = list(map(self._parse_log, self._git_logs()))[::-1]
def diff(self, git_logs: "GitLogs") -> List[GitLog]:
return [log for log in git_logs.logs if log not in self._logs]
def __repr__(self):
return f"{self._git_ref}, Log count:{len(self._logs)}"
def _git_get_current_head(self) -> str:
output = os.popen("git status | head -1").read()
match = re.match("(?:HEAD detached at|On branch) (.*)", output)
if not match:
return ""
return match.group(1)
def _git_checkout(self, git_ref: str):
os.popen(f"git checkout {git_ref}").read()
current_head = self._git_get_current_head()
if current_head != git_ref:
print(f"Could not checkout {git_ref}")
exit(1)
def _git_logs(self) -> List[str]:
# let's get current git ref so we can revert it back
current_git_ref = self._git_get_current_head()
self._git_checkout(self._git_ref)
output = (
os.popen('git --no-pager log --pretty=format:"%h|%an|%ad|%s|"')
.read()
.split("\n")
)
# revert to git ref, let's be nice
self._git_checkout(current_git_ref)
return output
def _parse_log(self, log_item: str) -> GitLog:
pr_number = None
split_log_item = log_item.split("|")
# parse the PR number from the log message
match = re.match(".*\(\#(\d*)\)", split_log_item[3])
if match:
pr_number = int(match.group(1))
return GitLog(
sha=split_log_item[0],
author=split_log_item[1],
time=split_log_item[2],
message=split_log_item[3],
pr_number=pr_number,
)
@dataclass
class BaseParameters:
previous_logs: GitLogs
current_logs: GitLogs
def print_title(message: str) -> None:
print(f"{50*'-'}")
print(message)
print(f"{50*'-'}")
@click.group()
@click.pass_context
@click.option(
"--previous_version", help="The previous release version",
)
@click.option(
"--current_version", help="The current release version",
)
def cli(ctx, previous_version: str, current_version: str):
""" Welcome to change log generator """
previous_logs = GitLogs(previous_version)
current_logs = GitLogs(current_version)
previous_logs.fetch()
current_logs.fetch()
base_parameters = BaseParameters(previous_logs, current_logs)
ctx.obj = base_parameters
@cli.command("compare")
@click.pass_obj
def compare(base_parameters):
""" Compares both versions (by PR) """
previous_logs = base_parameters.previous_logs
current_logs = base_parameters.current_logs
print_title(
f"Pull requests from " f"{current_logs.git_ref} not in {previous_logs.git_ref}"
)
previous_diff_logs = previous_logs.diff(current_logs)
for diff_log in previous_diff_logs:
print(f"{diff_log}")
print_title(
f"Pull requests from " f"{previous_logs.git_ref} not in {current_logs.git_ref}"
)
current_diff_logs = current_logs.diff(previous_logs)
for diff_log in current_diff_logs:
print(f"{diff_log}")
@cli.command("changelog")
@click.pass_obj
def changelog(base_parameters):
""" Outputs a changelog (by PR) """
previous_logs = base_parameters.previous_logs
current_logs = base_parameters.current_logs
previous_diff_logs = previous_logs.diff(current_logs)
print("Fetching github usernames, this may take a while:")
print(GitChangeLog(current_logs.git_ref, previous_diff_logs[::-1]))
cli()

View File

@@ -21,7 +21,7 @@ under the License.
This file documents any backwards-incompatible changes in Superset and
assists people when migrating to a new version.
## Next
## 0.38.0
* [10887](https://github.com/apache/incubator-superset/pull/10887): Breaking change: The custom cache backend changed in order to support the Flask-Caching factory method approach and thus must be registered as a custom type. See [here](https://flask-caching.readthedocs.io/en/latest/#custom-cache-backends) for specifics.

View File

@@ -56,9 +56,10 @@ describe('AdhocMetrics', () => {
});
});
it('Switch from simple to custom sql', () => {
cy.visitChartByName('Num Births Trend');
cy.verifySliceSuccess({ waitAlias: '@postJson' });
xit('Switch from simple to custom sql', () => {
cy.get('[data-test=metrics]')
.find('[data-test="metric-option"]')
.should('have.length', 1);
// select column "num"
cy.get('[data-test=metrics]').find('.Select__clear-indicator').click();
@@ -87,7 +88,7 @@ describe('AdhocMetrics', () => {
});
});
it('Switch from custom sql tabs to simple', () => {
xit('Switch from custom sql tabs to simple', () => {
cy.get('[data-test=metrics]').within(() => {
cy.get('.Select__dropdown-indicator').click();
cy.get('input[type=text]').type('sum_girls{enter}');
@@ -113,7 +114,7 @@ describe('AdhocMetrics', () => {
});
});
it('Typing starts with aggregate function name', () => {
xit('Typing starts with aggregate function name', () => {
// select column "num"
cy.get('[data-test=metrics]').within(() => {
cy.get('.Select__dropdown-indicator').click();

View File

@@ -1,59 +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.
*/
@font-face {
font-family: 'Fira Code';
src: url('woff2/FiraCode-Light.woff2') format('woff2'),
url("woff/FiraCode-Light.woff") format("woff");
font-weight: 300;
font-style: normal;
}
@font-face {
font-family: 'Fira Code';
src: url('woff2/FiraCode-Regular.woff2') format('woff2'),
url("woff/FiraCode-Regular.woff") format("woff");
font-weight: 400;
font-style: normal;
}
@font-face {
font-family: 'Fira Code';
src: url('woff2/FiraCode-Medium.woff2') format('woff2'),
url("woff/FiraCode-Medium.woff") format("woff");
font-weight: 500;
font-style: normal;
}
@font-face {
font-family: 'Fira Code';
src: url('woff2/FiraCode-Bold.woff2') format('woff2'),
url("woff/FiraCode-Bold.woff") format("woff");
font-weight: 700;
font-style: normal;
}
@font-face {
font-family: 'Fira Code VF';
src: url('woff2/FiraCode-VF.woff2') format('woff2-variations'),
url('woff/FiraCode-VF.woff') format('woff-variations');
/* font-weight requires a range: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Fonts/Variable_Fonts_Guide#Using_a_variable_font_font-face_changes */
font-weight: 300 700;
font-style: normal;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{
"name": "superset",
"version": "0.999.0dev",
"version": "0.38.1",
"description": "Superset is a data exploration platform designed to be visual, intuitive, and interactive.",
"license": "Apache-2.0",
"directories": {
@@ -63,34 +63,34 @@
"@babel/runtime-corejs3": "^7.8.4",
"@data-ui/sparkline": "^0.0.84",
"@emotion/core": "^10.0.28",
"@superset-ui/chart-controls": "^0.15.3",
"@superset-ui/core": "^0.15.2",
"@superset-ui/legacy-plugin-chart-calendar": "^0.15.3",
"@superset-ui/legacy-plugin-chart-chord": "^0.15.3",
"@superset-ui/legacy-plugin-chart-country-map": "^0.15.3",
"@superset-ui/legacy-plugin-chart-event-flow": "^0.15.3",
"@superset-ui/legacy-plugin-chart-force-directed": "^0.15.3",
"@superset-ui/legacy-plugin-chart-heatmap": "^0.15.3",
"@superset-ui/legacy-plugin-chart-histogram": "^0.15.3",
"@superset-ui/legacy-plugin-chart-horizon": "^0.15.3",
"@superset-ui/legacy-plugin-chart-map-box": "^0.15.3",
"@superset-ui/legacy-plugin-chart-paired-t-test": "^0.15.3",
"@superset-ui/legacy-plugin-chart-parallel-coordinates": "^0.15.3",
"@superset-ui/legacy-plugin-chart-partition": "^0.15.3",
"@superset-ui/legacy-plugin-chart-pivot-table": "^0.15.3",
"@superset-ui/legacy-plugin-chart-rose": "^0.15.3",
"@superset-ui/legacy-plugin-chart-sankey": "^0.15.3",
"@superset-ui/legacy-plugin-chart-sankey-loop": "^0.15.3",
"@superset-ui/legacy-plugin-chart-sunburst": "^0.15.3",
"@superset-ui/legacy-plugin-chart-treemap": "^0.15.3",
"@superset-ui/legacy-plugin-chart-world-map": "^0.15.3",
"@superset-ui/legacy-preset-chart-big-number": "^0.15.3",
"@superset-ui/chart-controls": "^0.15.5",
"@superset-ui/core": "^0.15.10",
"@superset-ui/legacy-plugin-chart-calendar": "^0.15.10",
"@superset-ui/legacy-plugin-chart-chord": "^0.15.10",
"@superset-ui/legacy-plugin-chart-country-map": "^0.15.10",
"@superset-ui/legacy-plugin-chart-event-flow": "^0.15.10",
"@superset-ui/legacy-plugin-chart-force-directed": "^0.15.10",
"@superset-ui/legacy-plugin-chart-heatmap": "^0.15.10",
"@superset-ui/legacy-plugin-chart-histogram": "^0.15.10",
"@superset-ui/legacy-plugin-chart-horizon": "^0.15.10",
"@superset-ui/legacy-plugin-chart-map-box": "^0.15.10",
"@superset-ui/legacy-plugin-chart-paired-t-test": "^0.15.10",
"@superset-ui/legacy-plugin-chart-parallel-coordinates": "^0.15.10",
"@superset-ui/legacy-plugin-chart-partition": "^0.15.10",
"@superset-ui/legacy-plugin-chart-pivot-table": "^0.15.10",
"@superset-ui/legacy-plugin-chart-rose": "^0.15.10",
"@superset-ui/legacy-plugin-chart-sankey": "^0.15.10",
"@superset-ui/legacy-plugin-chart-sankey-loop": "^0.15.10",
"@superset-ui/legacy-plugin-chart-sunburst": "^0.15.10",
"@superset-ui/legacy-plugin-chart-treemap": "^0.15.10",
"@superset-ui/legacy-plugin-chart-world-map": "^0.15.10",
"@superset-ui/legacy-preset-chart-big-number": "^0.15.10",
"@superset-ui/legacy-preset-chart-deckgl": "^0.3.1",
"@superset-ui/legacy-preset-chart-nvd3": "^0.15.3",
"@superset-ui/plugin-chart-echarts": "^0.15.4",
"@superset-ui/plugin-chart-table": "^0.15.3",
"@superset-ui/plugin-chart-word-cloud": "^0.15.3",
"@superset-ui/preset-chart-xy": "^0.15.3",
"@superset-ui/legacy-preset-chart-nvd3": "^0.15.10",
"@superset-ui/plugin-chart-echarts": "^0.15.11",
"@superset-ui/plugin-chart-table": "^0.15.10",
"@superset-ui/plugin-chart-word-cloud": "^0.15.10",
"@superset-ui/preset-chart-xy": "^0.15.10",
"@vx/responsive": "^0.0.195",
"abortcontroller-polyfill": "^1.1.9",
"antd": "^4.5.2",
@@ -106,6 +106,8 @@
"d3-scale": "^2.1.2",
"dnd-core": "^2.6.0",
"dom-to-image": "^2.6.0",
"fontsource-fira-code": "^3.0.5",
"fontsource-inter": "^3.0.5",
"geolib": "^2.0.24",
"global-box": "^1.2.0",
"immutable": "^4.0.0-rc.12",

View File

@@ -18,7 +18,8 @@
*/
import React from 'react';
import { ColumnOption, t } from '@superset-ui/core';
import { t } from '@superset-ui/core';
import { ColumnOption } from '@superset-ui/chart-controls';
export const controlPanelSectionsChartOptions = [
{

View File

@@ -417,7 +417,8 @@ div.tablePopover {
margin-top: 48px;
}
.ace_editor {
.ace_editor.ace_editor {
//double class is better than !important
border: 1px solid @gray-light;
font-feature-settings: @font-feature-settings;
font-family: @font-family-monospace;

View File

@@ -19,23 +19,26 @@
import React from 'react';
import PropTypes from 'prop-types';
import ReactMarkdown from 'react-markdown';
import htmlParser from 'react-markdown/plugins/html-parser';
import cx from 'classnames';
import { t } from '@superset-ui/core';
import { Logger, LOG_ACTIONS_RENDER_CHART } from 'src/logger/LogUtils';
import { MarkdownEditor } from 'src/components/AsyncAceEditor';
import { isFeatureEnabled, FeatureFlag } from 'src/featureFlags';
import DeleteComponentButton from '../DeleteComponentButton';
import DragDroppable from '../dnd/DragDroppable';
import ResizableContainer from '../resizable/ResizableContainer';
import MarkdownModeDropdown from '../menu/MarkdownModeDropdown';
import WithPopoverMenu from '../menu/WithPopoverMenu';
import { componentShape } from '../../util/propShapes';
import { ROW_TYPE, COLUMN_TYPE } from '../../util/componentTypes';
import DeleteComponentButton from 'src/dashboard/components/DeleteComponentButton';
import DragDroppable from 'src/dashboard/components/dnd/DragDroppable';
import ResizableContainer from 'src/dashboard/components/resizable/ResizableContainer';
import MarkdownModeDropdown from 'src/dashboard/components/menu/MarkdownModeDropdown';
import WithPopoverMenu from 'src/dashboard/components/menu/WithPopoverMenu';
import { componentShape } from 'src/dashboard/util/propShapes';
import { ROW_TYPE, COLUMN_TYPE } from 'src/dashboard/util/componentTypes';
import {
GRID_MIN_COLUMN_COUNT,
GRID_MIN_ROW_UNITS,
GRID_BASE_UNIT,
} from '../../util/constants';
} from 'src/dashboard/util/constants';
const propTypes = {
id: PropTypes.string.isRequired,
@@ -84,6 +87,7 @@ function isSafeMarkup(node) {
return true;
}
class Markdown extends React.PureComponent {
constructor(props) {
super(props);
@@ -259,8 +263,14 @@ class Markdown extends React.PureComponent {
? MARKDOWN_ERROR_MESSAGE
: this.state.markdownSource || MARKDOWN_PLACE_HOLDER
}
escapeHtml={false}
escapeHtml={isFeatureEnabled(FeatureFlag.ESCAPE_MARKDOWN_HTML)}
skipHtml={!isFeatureEnabled(FeatureFlag.DISPLAY_MARKDOWN_HTML)}
allowNode={isSafeMarkup}
astPlugins={[
htmlParser({
isValidNode: node => node.type !== 'script',
}),
]}
/>
);
}

View File

@@ -527,12 +527,12 @@ class DatasourceEditor extends React.PureComponent {
description={t('Owners of the datasource')}
control={
<SelectAsyncControl
dataEndpoint="/users/api/read"
dataEndpoint="api/v1/dataset/related/owners"
multi
mutator={data =>
data.pks.map((pk, i) => ({
value: pk,
label: `${data.result[i].first_name} ${data.result[i].last_name}`,
data.result.map(pk => ({
value: pk.value,
label: `${pk.text}`,
}))
}
/>

View File

@@ -63,9 +63,8 @@ import {
getSequentialSchemeRegistry,
legacyValidateInteger,
validateNonEmpty,
ColumnOption,
} from '@superset-ui/core';
import { ColumnOption } from '@superset-ui/chart-controls';
import { formatSelectOptions, mainMetric } from 'src/modules/utils';
import { TIME_FILTER_LABELS } from './constants';

View File

@@ -29,6 +29,8 @@ export enum FeatureFlag {
THUMBNAILS = 'THUMBNAILS',
SIP_34_SAVED_QUERIES_UI = 'SIP_34_SAVED_QUERIES_UI',
LISTVIEWS_DEFAULT_CARD_VIEW = 'LISTVIEWS_DEFAULT_CARD_VIEW',
DISPLAY_MARKDOWN_HTML = 'DISPLAY_MARKDOWN_HTML',
ESCAPE_MARKDOWN_HTML = 'ESCAPE_MARKDOWN_HTML',
}
export type FeatureFlagMap = {

View File

@@ -126,6 +126,9 @@ const DatabaseModal: FunctionComponent<DatabaseModalProps> = ({
const [isHidden, setIsHidden] = useState<boolean>(true);
const isEditMode = database !== null;
const defaultExtra =
'{\n "metadata_params": {},\n "engine_params": {},' +
'\n "metadata_cache_timeout": {},\n "schemas_allowed_for_csv_upload": [] \n}';
// Database fetch logic
const {
@@ -589,11 +592,7 @@ const DatabaseModal: FunctionComponent<DatabaseModalProps> = ({
<div className="input-container">
<textarea
name="extra"
value={db ? db.extra || '' : ''}
placeholder={
'{\n "metadata_params": {},\n "engine_params": {},' +
'\n "metadata_cache_timeout": {},\n "schemas_allowed_for_csv_upload": [] \n}'
}
value={(db && db.extra) ?? defaultExtra}
onChange={onTextChange}
/>
</div>

View File

@@ -1,63 +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.
*/
@font-face {
font-family: 'Fira Code';
src: url('../../../fonts/FiraCode/woff2/FiraCode-Light.woff2') format('woff2'),
url('../../../fonts/FiraCode/woff/FiraCode-Light.woff') format('woff');
font-weight: 300;
font-style: normal;
}
@font-face {
font-family: 'Fira Code';
src: url('../../../fonts/FiraCode/woff2/FiraCode-Regular.woff2')
format('woff2'),
url('../../../fonts/FiraCode/woff/FiraCode-Regular.woff') format('woff');
font-weight: 400;
font-style: normal;
}
@font-face {
font-family: 'Fira Code';
src: url('../../../fonts/FiraCode/woff2/FiraCode-Medium.woff2')
format('woff2'),
url('../../../fonts/FiraCode/woff/FiraCode-Medium.woff') format('woff');
font-weight: 500;
font-style: normal;
}
@font-face {
font-family: 'Fira Code';
src: url('../../../fonts/FiraCode/woff2/FiraCode-Bold.woff2') format('woff2'),
url('../../../fonts/FiraCode/woff/FiraCode-Bold.woff') format('woff');
font-weight: 700;
font-style: normal;
}
@font-face {
font-family: 'Fira Code VF';
src: url('../../../fonts/FiraCode/woff2/FiraCode-VF.woff2')
format('woff2-variations'),
url('../../../fonts/FiraCode/woff/FiraCode-VF.woff')
format('woff-variations');
/* font-weight requires a range: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Fonts/Variable_Fonts_Guide#Using_a_variable_font_font-face_changes */
font-weight: 300 700;
font-style: normal;
}

View File

@@ -1,225 +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.
*/
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 100;
font-display: swap;
src: url('../../../fonts/InterUI/Inter-Thin.woff2?v=3.12') format('woff2'),
url('../../../fonts/InterUI/Inter-Thin.woff?v=3.12') format('woff');
}
@font-face {
font-family: 'Inter';
font-style: italic;
font-weight: 100;
font-display: swap;
src: url('../../../fonts/InterUI/Inter-ThinItalic.woff2?v=3.12')
format('woff2'),
url('../../../fonts/InterUI/Inter-ThinItalic.woff?v=3.12') format('woff');
}
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 200;
font-display: swap;
src: url('../../../fonts/InterUI/Inter-ExtraLight.woff2?v=3.12')
format('woff2'),
url('../../../fonts/InterUI/Inter-ExtraLight.woff?v=3.12') format('woff');
}
@font-face {
font-family: 'Inter';
font-style: italic;
font-weight: 200;
font-display: swap;
src: url('../../../fonts/InterUI/Inter-ExtraLightItalic.woff2?v=3.12')
format('woff2'),
url('../../../fonts/InterUI/Inter-ExtraLightItalic.woff?v=3.12')
format('woff');
}
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 300;
font-display: swap;
src: url('../../../fonts/InterUI/Inter-Light.woff2?v=3.12') format('woff2'),
url('../../../fonts/InterUI/Inter-Light.woff?v=3.12') format('woff');
}
@font-face {
font-family: 'Inter';
font-style: italic;
font-weight: 300;
font-display: swap;
src: url('../../../fonts/InterUI/Inter-LightItalic.woff2?v=3.12')
format('woff2'),
url('../../../fonts/InterUI/Inter-LightItalic.woff?v=3.12') format('woff');
}
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('../../../fonts/InterUI/Inter-Regular.woff2?v=3.12') format('woff2'),
url('../../../fonts/InterUI/Inter-Regular.woff?v=3.12') format('woff');
}
@font-face {
font-family: 'Inter';
font-style: italic;
font-weight: 400;
font-display: swap;
src: url('../../../fonts/InterUI/Inter-Italic.woff2?v=3.12') format('woff2'),
url('../../../fonts/InterUI/Inter-Italic.woff?v=3.12') format('woff');
}
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 500;
font-display: swap;
src: url('../../../fonts/InterUI/Inter-Medium.woff2?v=3.12') format('woff2'),
url('../../../fonts/InterUI/Inter-Medium.woff?v=3.12') format('woff');
}
@font-face {
font-family: 'Inter';
font-style: italic;
font-weight: 500;
font-display: swap;
src: url('../../../fonts/InterUI/Inter-MediumItalic.woff2?v=3.12')
format('woff2'),
url('../../../fonts/InterUI/Inter-MediumItalic.woff?v=3.12') format('woff');
}
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 600;
font-display: swap;
src: url('../../../fonts/InterUI/Inter-SemiBold.woff2?v=3.12') format('woff2'),
url('../../../fonts/InterUI/Inter-SemiBold.woff?v=3.12') format('woff');
}
@font-face {
font-family: 'Inter';
font-style: italic;
font-weight: 600;
font-display: swap;
src: url('../../../fonts/InterUI/Inter-SemiBoldItalic.woff2?v=3.12')
format('woff2'),
url('../../../fonts/InterUI/Inter-SemiBoldItalic.woff?v=3.12')
format('woff');
}
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url('../../../fonts/InterUI/Inter-Bold.woff2?v=3.12') format('woff2'),
url('../../../fonts/InterUI/Inter-Bold.woff?v=3.12') format('woff');
}
@font-face {
font-family: 'Inter';
font-style: italic;
font-weight: 700;
font-display: swap;
src: url('../../../fonts/InterUI/Inter-BoldItalic.woff2?v=3.12')
format('woff2'),
url('../../../fonts/InterUI/Inter-BoldItalic.woff?v=3.12') format('woff');
}
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 800;
font-display: swap;
src: url('../../../fonts/InterUI/Inter-ExtraBold.woff2?v=3.12')
format('woff2'),
url('../../../fonts/InterUI/Inter-ExtraBold.woff?v=3.12') format('woff');
}
@font-face {
font-family: 'Inter';
font-style: italic;
font-weight: 800;
font-display: swap;
src: url('../../../fonts/InterUI/Inter-ExtraBoldItalic.woff2?v=3.12')
format('woff2'),
url('../../../fonts/InterUI/Inter-ExtraBoldItalic.woff?v=3.12')
format('woff');
}
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 900;
font-display: swap;
src: url('../../../fonts/InterUI/Inter-Black.woff2?v=3.12') format('woff2'),
url('../../../fonts/InterUI/Inter-Black.woff?v=3.12') format('woff');
}
@font-face {
font-family: 'Inter';
font-style: italic;
font-weight: 900;
font-display: swap;
src: url('../../../fonts/InterUI/Inter-BlackItalic.woff2?v=3.12')
format('woff2'),
url('../../../fonts/InterUI/Inter-BlackItalic.woff?v=3.12') format('woff');
}
/* -------------------------------------------------------
Variable font.
Usage:
html { font-family: 'Inter', sans-serif; }
@supports (font-variation-settings: normal) {
html { font-family: 'Inter var', sans-serif; }
}
*/
@font-face {
font-family: 'Inter var';
font-weight: 100 900;
font-display: swap;
font-style: normal;
font-named-instance: 'Regular';
src: url('../../../fonts/InterUI/Inter-roman.var.woff2?v=3.12')
format('woff2');
}
@font-face {
font-family: 'Inter var';
font-weight: 100 900;
font-display: swap;
font-style: italic;
font-named-instance: 'Italic';
src: url('../../../fonts/InterUI/Inter-italic.var.woff2?v=3.12')
format('woff2');
}
/* --------------------------------------------------------------------------
[EXPERIMENTAL] Multi-axis, single variable font.
Slant axis is not yet widely supported (as of February 2019) and thus this
multi-axis single variable font is opt-in rather than the default.
When using this, you will probably need to set font-variation-settings
explicitly, e.g.
* { font-variation-settings: "slnt" 0deg }
.italic { font-variation-settings: "slnt" 10deg }
*/
@font-face {
font-family: 'Inter var experimental';
font-weight: 100 900;
font-display: swap;
font-style: oblique 0deg 10deg;
src: url('../../../fonts/InterUI/Inter.var.woff2?v=3.12') format('woff2');
}

View File

@@ -18,14 +18,11 @@
*/
/*************************************************************************/
/* USAGE NOTES */
/* Each typeface used in Superset should have local webfont files. */
/* Maintain separate specimen sheets so it's easier to add/remove fonts. */
/* NOTE: Add font all licenses to LICENSE.text */
/* USAGE NOTES : Add font all licenses to LICENSE.text */
/*************************************************************************/
/******************************* Inter UI ********************************/
@import './font_specimens/inter_ui.less';
@import '~fontsource-inter/index.css';
/******************************* Fira Code ********************************/
@import './font_specimens/fira_code.less';
@import '~fontsource-fira-code/index.css';

View File

@@ -30,5 +30,6 @@
"./node_modules/*superset-ui*/**/types/**/*",
// and the type defs of their dependencies
"./node_modules/*superset-ui*/**/node_modules/**/*.d.ts"
]
],
"exclude": ["./node_modules/*superset-ui*/**/node_modules/@superset-ui/**/*"]
}

View File

@@ -265,12 +265,19 @@ const config = {
},
},
resolve: {
modules: [APP_DIR, 'node_modules'],
alias: {
src: path.resolve(APP_DIR, './src'),
'react-dom': '@hot-loader/react-dom',
stylesheets: path.resolve(APP_DIR, './stylesheets'),
images: path.resolve(APP_DIR, './images'),
spec: path.resolve(APP_DIR, './spec'),
// force using absolute import path of the @superset-ui/core and @superset-ui/chart-controls
// so that we can `npm link` viz plugins without linking these two base packages
'@superset-ui/core': path.resolve(
APP_DIR,
'./node_modules/@superset-ui/core',
),
'@superset-ui/chart-controls': path.resolve(
APP_DIR,
'./node_modules/@superset-ui/chart-controls',
),
},
extensions: ['.ts', '.tsx', '.js', '.jsx'],
symlinks: false,
@@ -382,6 +389,9 @@ const config = {
{
test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: 'url-loader?limit=10000&mimetype=application/font-woff',
options: {
esModule: false,
},
},
{
test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,

View File

@@ -704,7 +704,94 @@ class ChartDataExtrasSchema(Schema):
)
class AnnotationLayerSchema(Schema):
annotationType = fields.String(
description="Type of annotation layer",
validate=validate.OneOf(
choices=("EVENT", "FORMULA", "INTERVAL", "TIME_SERIES",)
),
)
color = fields.String(description="Layer color", allow_none=True,)
descriptionColumns = fields.List(
fields.String(),
description="Columns to use as the description. If none are provided, "
"all will be shown.",
)
hideLine = fields.Boolean(
description="Should line be hidden. Only applies to line annotations",
allow_none=True,
)
intervalEndColumn = fields.String(
description=(
"Column containing end of interval. Only applies to interval layers"
),
allow_none=True,
)
name = fields.String(description="Name of layer", required=True)
opacity = fields.String(
description="Opacity of layer",
validate=validate.OneOf(
choices=("", "opacityLow", "opacityMedium", "opacityHigh"),
),
allow_none=True,
required=False,
)
overrides = fields.Dict(
keys=fields.String(
desciption="Name of property to be overridden",
validate=validate.OneOf(
choices=("granularity", "time_grain_sqla", "time_range", "time_shift"),
),
),
values=fields.Raw(allow_none=True),
description="which properties should be overridable",
allow_none=True,
)
show = fields.Boolean(description="Should the layer be shown", required=True)
showMarkers = fields.Boolean(
description="Should markers be shown. Only applies to line annotations.",
required=True,
)
sourceType = fields.String(
description="Type of source for annotation data",
validate=validate.OneOf(choices=("", "line", "NATIVE", "table",)),
)
style = fields.String(
description="Line style. Only applies to time-series annotations",
validate=validate.OneOf(choices=("dashed", "dotted", "solid", "longDashed",)),
)
timeColumn = fields.String(
description="Column with event date or interval start date", allow_none=True,
)
titleColumn = fields.String(description="Column with title", allow_none=True,)
width = fields.Float(
description="Width of annotation line",
validate=[
Range(
min=0,
min_inclusive=True,
error=_("`width` must be greater or equal to 0"),
)
],
)
value = fields.Raw(
description="For formula annotations, this contains the formula. "
"For other types, this is the primary key of the source object.",
required=True,
)
class ChartDataQueryObjectSchema(Schema):
annotation_layers = fields.List(
fields.Nested(AnnotationLayerSchema),
description="Annotation layers to apply to chart",
allow_none=True,
)
applied_time_extras = fields.Dict(
description="A mapping of temporal extras that have been applied to the query",
required=False,
example={"__time_range": "1 year ago : now"},
)
filters = fields.List(fields.Nested(ChartDataFilterSchema), required=False)
granularity = fields.String(
description="Name of temporal column used for time filtering. For legacy Druid "
@@ -816,6 +903,19 @@ class ChartDataQueryObjectSchema(Schema):
"as `having_druid`.",
deprecated=True,
)
druid_time_origin = fields.String(
description="Starting point for time grain counting on legacy Druid "
"datasources. Used to change e.g. Monday/Sunday first-day-of-week. "
"This field is deprecated and should be passed to `extras` "
"as `druid_time_origin`.",
allow_none=True,
)
url_params = fields.Dict(
description="Optional query parameters passed to a dashboard or Explore view",
keys=fields.String(description="The query parameter"),
values=fields.String(description="The value of the query parameter"),
allow_none=True,
)
class ChartDataDatasourceSchema(Schema):
@@ -852,7 +952,28 @@ class ChartDataQueryContextSchema(Schema):
# pylint: enable=no-self-use,unused-argument
class AnnotationDataSchema(Schema):
columns = fields.List(
fields.String(),
description="columns available in the annotation result",
required=True,
)
records = fields.List(
fields.Dict(keys=fields.String(),),
description="records mapping the column name to it's value",
required=True,
)
class ChartDataResponseResult(Schema):
annotation_data = fields.List(
fields.Dict(
keys=fields.String(description="Annotation layer name"),
values=fields.String(),
),
description="All requested annotation data",
allow_none=True,
)
cache_key = fields.String(
description="Unique cache key for query object", required=True, allow_none=True,
)

View File

@@ -155,6 +155,8 @@ class QueryContext:
query_obj.row_offset = 0
query_obj.columns = [o.column_name for o in self.datasource.columns]
payload = self.get_df_payload(query_obj)
# TODO: implement
payload["annotation_data"] = []
df = payload["df"]
status = payload["status"]
if status != utils.QueryStatus.FAILED:

View File

@@ -59,6 +59,7 @@ class QueryObject:
and druid. The query objects are constructed on the client.
"""
annotation_layers: List[Dict[str, Any]]
granularity: Optional[str]
from_dttm: Optional[datetime]
to_dttm: Optional[datetime]
@@ -79,6 +80,7 @@ class QueryObject:
def __init__(
self,
annotation_layers: Optional[List[Dict[str, Any]]] = None,
granularity: Optional[str] = None,
metrics: Optional[List[Union[Dict[str, Any], str]]] = None,
groupby: Optional[List[str]] = None,
@@ -97,9 +99,11 @@ class QueryObject:
post_processing: Optional[List[Optional[Dict[str, Any]]]] = None,
**kwargs: Any,
):
annotation_layers = annotation_layers or []
metrics = metrics or []
extras = extras or {}
is_sip_38 = is_feature_enabled("SIP_38_VIZ_REARCHITECTURE")
self.annotation_layers = annotation_layers
self.granularity = granularity
self.from_dttm, self.to_dttm = utils.get_since_until(
relative_start=extras.get(

View File

@@ -309,6 +309,10 @@ DEFAULT_FEATURE_FLAGS: Dict[str, bool] = {
"TAGGING_SYSTEM": False,
"SQLLAB_BACKEND_PERSISTENCE": False,
"LISTVIEWS_DEFAULT_CARD_VIEW": False,
# When True, this flag allows display of HTML tags in Markdown components
"DISPLAY_MARKDOWN_HTML": True,
# When True, this escapes HTML (rather than rendering it) in Markdown components
"ESCAPE_MARKDOWN_HTML": False,
}
# Set the default view to card/grid view if thumbnail support is enabled.

View File

@@ -64,6 +64,7 @@ from superset.jinja_context import (
from superset.models.annotations import Annotation
from superset.models.core import Database
from superset.models.helpers import AuditMixinNullable, QueryResult
from superset.sql_parse import ParsedQuery
from superset.typing import Metric, QueryObjectDict
from superset.utils import core as utils, import_datasource
@@ -755,6 +756,15 @@ class SqlaTable( # pylint: disable=too-many-public-methods,too-many-instance-at
)
from_sql = sqlparse.format(from_sql, strip_comments=True)
if len(sqlparse.split(from_sql)) > 1:
raise QueryObjectValidationError(
_("Virtual dataset query cannot consist of multiple statements")
)
parsed_query = ParsedQuery(from_sql)
if not (parsed_query.is_unknown() or parsed_query.is_readonly()):
raise QueryObjectValidationError(
_("Virtual dataset query must be read-only")
)
return TextAsFrom(sa.text(from_sql), []).alias("expr_qry")
return self.get_sqla_table()

View File

@@ -21,14 +21,17 @@ import yaml
from flask import g, request, Response
from flask_appbuilder.api import expose, protect, rison, safe
from flask_appbuilder.models.sqla.interface import SQLAInterface
from flask_babel import ngettext
from marshmallow import ValidationError
from superset.connectors.sqla.models import SqlaTable
from superset.constants import RouteMethod
from superset.databases.filters import DatabaseFilter
from superset.datasets.commands.bulk_delete import BulkDeleteDatasetCommand
from superset.datasets.commands.create import CreateDatasetCommand
from superset.datasets.commands.delete import DeleteDatasetCommand
from superset.datasets.commands.exceptions import (
DatasetBulkDeleteFailedError,
DatasetCreateFailedError,
DatasetDeleteFailedError,
DatasetForbiddenError,
@@ -44,6 +47,7 @@ from superset.datasets.schemas import (
DatasetPostSchema,
DatasetPutSchema,
DatasetRelatedObjectsResponse,
get_delete_ids_schema,
get_export_ids_schema,
)
from superset.views.base import DatasourceFilter, generate_download_headers
@@ -68,6 +72,7 @@ class DatasetRestApi(BaseSupersetModelRestApi):
RouteMethod.EXPORT,
RouteMethod.RELATED,
RouteMethod.DISTINCT,
"bulk_delete",
"refresh",
"related_objects",
}
@@ -489,3 +494,62 @@ class DatasetRestApi(BaseSupersetModelRestApi):
charts={"count": len(charts), "result": charts},
dashboards={"count": len(dashboards), "result": dashboards},
)
@expose("/", methods=["DELETE"])
@protect()
@safe
@statsd_metrics
@rison(get_delete_ids_schema)
def bulk_delete(self, **kwargs: Any) -> Response:
"""Delete bulk Datasets
---
delete:
description: >-
Deletes multiple Datasets in a bulk operation.
parameters:
- in: query
name: q
content:
application/json:
schema:
$ref: '#/components/schemas/get_delete_ids_schema'
responses:
200:
description: Dataset bulk delete
content:
application/json:
schema:
type: object
properties:
message:
type: string
400:
$ref: '#/components/responses/400'
401:
$ref: '#/components/responses/401'
403:
$ref: '#/components/responses/403'
404:
$ref: '#/components/responses/404'
422:
$ref: '#/components/responses/422'
500:
$ref: '#/components/responses/500'
"""
item_ids = kwargs["rison"]
try:
BulkDeleteDatasetCommand(g.user, item_ids).run()
return self.response(
200,
message=ngettext(
"Deleted %(num)d dataset",
"Deleted %(num)d datasets",
num=len(item_ids),
),
)
except DatasetNotFoundError:
return self.response_404()
except DatasetForbiddenError:
return self.response_403()
except DatasetBulkDeleteFailedError as ex:
return self.response_422(message=str(ex))

View File

@@ -0,0 +1,88 @@
# 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 logging
from typing import List, Optional
from flask_appbuilder.security.sqla.models import User
from superset.commands.base import BaseCommand
from superset.commands.exceptions import DeleteFailedError
from superset.connectors.sqla.models import SqlaTable
from superset.datasets.commands.exceptions import (
DatasetBulkDeleteFailedError,
DatasetForbiddenError,
DatasetNotFoundError,
)
from superset.datasets.dao import DatasetDAO
from superset.exceptions import SupersetSecurityException
from superset.extensions import db, security_manager
from superset.views.base import check_ownership
logger = logging.getLogger(__name__)
class BulkDeleteDatasetCommand(BaseCommand):
def __init__(self, user: User, model_ids: List[int]):
self._actor = user
self._model_ids = model_ids
self._models: Optional[List[SqlaTable]] = None
def run(self) -> None:
self.validate()
if not self._models:
return None
try:
DatasetDAO.bulk_delete(self._models)
for model in self._models:
view_menu = (
security_manager.find_view_menu(model.get_perm()) if model else None
)
if view_menu:
permission_views = (
db.session.query(security_manager.permissionview_model)
.filter_by(view_menu=view_menu)
.all()
)
for permission_view in permission_views:
db.session.delete(permission_view)
if view_menu:
db.session.delete(view_menu)
else:
if not view_menu:
logger.error(
"Could not find the data access permission for the dataset"
)
db.session.commit()
return None
except DeleteFailedError as ex:
logger.exception(ex.exception)
raise DatasetBulkDeleteFailedError()
def validate(self) -> None:
# Validate/populate model exists
self._models = DatasetDAO.find_by_ids(self._model_ids)
if not self._models or len(self._models) != len(self._model_ids):
raise DatasetNotFoundError()
# Check ownership
for model in self._models:
try:
check_ownership(model)
except SupersetSecurityException:
raise DatasetForbiddenError()

View File

@@ -160,6 +160,10 @@ class DatasetDeleteFailedError(DeleteFailedError):
message = _("Dataset could not be deleted.")
class DatasetBulkDeleteFailedError(DeleteFailedError):
message = _("Dataset(s) could not be bulk deleted.")
class DatasetRefreshFailedError(UpdateFailedError):
message = _("Dataset could not be updated.")

View File

@@ -207,6 +207,32 @@ class DatasetDAO(BaseDAO):
"""
return DatasetMetricDAO.create(properties, commit=commit)
@staticmethod
def bulk_delete(models: Optional[List[SqlaTable]], commit: bool = True) -> None:
item_ids = [model.id for model in models] if models else []
# bulk delete, first delete related data
if models:
for model in models:
model.owners = []
db.session.merge(model)
db.session.query(SqlMetric).filter(SqlMetric.table_id.in_(item_ids)).delete(
synchronize_session="fetch"
)
db.session.query(TableColumn).filter(
TableColumn.table_id.in_(item_ids)
).delete(synchronize_session="fetch")
# bulk delete itself
try:
db.session.query(SqlaTable).filter(SqlaTable.id.in_(item_ids)).delete(
synchronize_session="fetch"
)
if commit:
db.session.commit()
except SQLAlchemyError as ex:
if commit:
db.session.rollback()
raise ex
class DatasetColumnDAO(BaseDAO):
model_cls = TableColumn

View File

@@ -20,6 +20,7 @@ from flask_babel import lazy_gettext as _
from marshmallow import fields, Schema, ValidationError
from marshmallow.validate import Length
get_delete_ids_schema = {"type": "array", "items": {"type": "integer"}}
get_export_ids_schema = {"type": "array", "items": {"type": "integer"}}

View File

@@ -101,6 +101,7 @@ def load_birth_names(
obj.main_dttm_col = "ds"
obj.database = database
obj.filter_select_enabled = True
obj.fetch_metadata()
if not any(col.column_name == "num_california" for col in obj.columns):
col_state = str(column("state").compile(db.engine))
@@ -117,7 +118,6 @@ def load_birth_names(
obj.metrics.append(SqlMetric(metric_name="sum__num", expression=f"SUM({col})"))
db.session.commit()
obj.fetch_metadata()
tbl = obj
metrics = [

View File

@@ -93,3 +93,7 @@ class QueryObjectValidationError(SupersetException):
class DashboardImportException(SupersetException):
pass
class SerializationError(SupersetException):
pass

View File

@@ -113,6 +113,9 @@ class ParsedQuery:
def is_explain(self) -> bool:
return self.stripped().upper().startswith("EXPLAIN")
def is_unknown(self) -> bool:
return self._parsed[0].get_type() == "UNKNOWN"
def is_readonly(self) -> bool:
"""Pessimistic readonly, 100% sure statement won't mutate anything"""
return self.is_select() or self.is_explain()

View File

@@ -82,6 +82,7 @@ from superset.databases.filters import DatabaseFilter
from superset.exceptions import (
CertificateException,
DatabaseNotFound,
SerializationError,
SupersetException,
SupersetSecurityException,
SupersetTimeoutException,
@@ -1959,7 +1960,9 @@ class Superset(BaseSupersetView): # pylint: disable=too-many-public-methods
return self.results_exec(key)
@staticmethod
def results_exec(key: str) -> FlaskResponse:
def results_exec( # pylint: disable=too-many-return-statements
key: str,
) -> FlaskResponse:
"""Serves a key off of the results backend
It is possible to pass the `rows` query argument to limit the number
@@ -1993,9 +1996,15 @@ class Superset(BaseSupersetView): # pylint: disable=too-many-public-methods
return json_errors_response([ex.error], status=403)
payload = utils.zlib_decompress(blob, decode=not results_backend_use_msgpack)
obj = _deserialize_results_payload(
payload, query, cast(bool, results_backend_use_msgpack)
)
try:
obj = _deserialize_results_payload(
payload, query, cast(bool, results_backend_use_msgpack)
)
except SerializationError:
return json_error_response(
__("Data could not be deserialized. You may want to re-run the query."),
status=404,
)
if "rows" in request.args:
try:

View File

@@ -39,7 +39,11 @@ from superset import (
)
from superset.connectors.connector_registry import ConnectorRegistry
from superset.errors import ErrorLevel, SupersetError, SupersetErrorType
from superset.exceptions import SupersetException, SupersetSecurityException
from superset.exceptions import (
SerializationError,
SupersetException,
SupersetSecurityException,
)
from superset.legacy import update_time_range
from superset.models.core import Database
from superset.models.dashboard import Dashboard
@@ -559,7 +563,10 @@ def _deserialize_results_payload(
ds_payload = msgpack.loads(payload, raw=False)
with stats_timing("sqllab.query.results_backend_pa_deserialize", stats_logger):
pa_table = pa.deserialize(ds_payload["data"])
try:
pa_table = pa.deserialize(ds_payload["data"])
except pa.ArrowSerializationError:
raise SerializationError("Unable to deserialize table")
df = result_set.SupersetResultSet.convert_table_to_df(pa_table)
ds_payload["data"] = dataframe.df_to_records(df) or []

View File

@@ -20,6 +20,7 @@ from typing import List
from unittest.mock import patch
import prison
import pytest
import yaml
from sqlalchemy.sql import func
@@ -34,12 +35,14 @@ from superset.extensions import db, security_manager
from superset.models.core import Database
from superset.utils.core import backend, get_example_database, get_main_database
from superset.utils.dict_import_export import export_to_dict
from superset.views.base import generate_download_headers
from tests.base_tests import SupersetTestCase
from tests.conftest import CTAS_SCHEMA_NAME
class TestDatasetApi(SupersetTestCase):
fixture_tables_names = ("ab_permission", "ab_permission_view", "ab_view_menu")
@staticmethod
def insert_dataset(
table_name: str, schema: str, owners: List[int], database: Database
@@ -61,6 +64,30 @@ class TestDatasetApi(SupersetTestCase):
"ab_permission", "", [self.get_user("admin").id], get_main_database()
)
def get_fixture_datasets(self) -> List[SqlaTable]:
return (
db.session.query(SqlaTable)
.filter(SqlaTable.table_name.in_(self.fixture_tables_names))
.all()
)
@pytest.fixture()
def create_datasets(self):
with self.create_app().app_context():
datasets = []
admin = self.get_user("admin")
main_db = get_main_database()
for tables_name in self.fixture_tables_names:
datasets.append(
self.insert_dataset(tables_name, "", [admin.id], main_db)
)
yield datasets
# rollback changes
for dataset in datasets:
db.session.delete(dataset)
db.session.commit()
@staticmethod
def get_energy_usage_dataset():
example_db = get_example_database()
@@ -789,6 +816,89 @@ class TestDatasetApi(SupersetTestCase):
db.session.delete(dataset)
db.session.commit()
@pytest.mark.usefixtures("create_datasets")
def test_bulk_delete_dataset_items(self):
"""
Dataset API: Test bulk delete dataset items
"""
datasets = self.get_fixture_datasets()
dataset_ids = [dataset.id for dataset in datasets]
view_menu_names = []
for dataset in datasets:
view_menu_names.append(dataset.get_perm())
self.login(username="admin")
uri = f"api/v1/dataset/?q={prison.dumps(dataset_ids)}"
rv = self.delete_assert_metric(uri, "bulk_delete")
data = json.loads(rv.data.decode("utf-8"))
assert rv.status_code == 200
expected_response = {"message": f"Deleted {len(datasets)} datasets"}
assert data == expected_response
datasets = (
db.session.query(SqlaTable)
.filter(SqlaTable.table_name.in_(self.fixture_tables_names))
.all()
)
assert datasets == []
# Assert permissions get cleaned
for view_menu_name in view_menu_names:
assert security_manager.find_view_menu(view_menu_name) is None
@pytest.mark.usefixtures("create_datasets")
def test_bulk_delete_item_dataset_not_owned(self):
"""
Dataset API: Test bulk delete item not owned
"""
datasets = self.get_fixture_datasets()
dataset_ids = [dataset.id for dataset in datasets]
self.login(username="alpha")
uri = f"api/v1/dataset/?q={prison.dumps(dataset_ids)}"
rv = self.delete_assert_metric(uri, "bulk_delete")
assert rv.status_code == 403
@pytest.mark.usefixtures("create_datasets")
def test_bulk_delete_item_not_found(self):
"""
Dataset API: Test bulk delete item not found
"""
datasets = self.get_fixture_datasets()
dataset_ids = [dataset.id for dataset in datasets]
dataset_ids.append(db.session.query(func.max(SqlaTable.id)).scalar())
self.login(username="admin")
uri = f"api/v1/dataset/?q={prison.dumps(dataset_ids)}"
rv = self.delete_assert_metric(uri, "bulk_delete")
assert rv.status_code == 404
@pytest.mark.usefixtures("create_datasets")
def test_bulk_delete_dataset_item_not_authorized(self):
"""
Dataset API: Test bulk delete item not authorized
"""
datasets = self.get_fixture_datasets()
dataset_ids = [dataset.id for dataset in datasets]
self.login(username="gamma")
uri = f"api/v1/dataset/?q={prison.dumps(dataset_ids)}"
rv = self.client.delete(uri)
assert rv.status_code == 401
@pytest.mark.usefixtures("create_datasets")
def test_bulk_delete_dataset_item_incorrect(self):
"""
Dataset API: Test bulk delete item incorrect request
"""
datasets = self.get_fixture_datasets()
dataset_ids = [dataset.id for dataset in datasets]
dataset_ids.append("Wrong")
self.login(username="admin")
uri = f"api/v1/dataset/?q={prison.dumps(dataset_ids)}"
rv = self.client.delete(uri)
assert rv.status_code == 400
def test_dataset_item_refresh(self):
"""
Dataset API: Test item refresh

View File

@@ -187,3 +187,45 @@ class TestDatabaseModel(SupersetTestCase):
if get_example_database().backend != "presto":
with pytest.raises(QueryObjectValidationError):
table.get_sqla_query(**query_obj)
def test_multiple_sql_statements_raises_exception(self):
base_query_obj = {
"granularity": None,
"from_dttm": None,
"to_dttm": None,
"groupby": ["grp"],
"metrics": [],
"is_timeseries": False,
"filter": [],
}
table = SqlaTable(
table_name="test_has_extra_cache_keys_table",
sql="SELECT 'foo' as grp, 1 as num; SELECT 'bar' as grp, 2 as num",
database=get_example_database(),
)
query_obj = dict(**base_query_obj, extras={})
with pytest.raises(QueryObjectValidationError):
table.get_sqla_query(**query_obj)
def test_dml_statement_raises_exception(self):
base_query_obj = {
"granularity": None,
"from_dttm": None,
"to_dttm": None,
"groupby": ["grp"],
"metrics": [],
"is_timeseries": False,
"filter": [],
}
table = SqlaTable(
table_name="test_has_extra_cache_keys_table",
sql="DELETE FROM foo",
database=get_example_database(),
)
query_obj = dict(**base_query_obj, extras={})
with pytest.raises(QueryObjectValidationError):
table.get_sqla_query(**query_obj)