Compare commits

...

316 Commits

Author SHA1 Message Date
Michael S. Molina
cc5235829e chore: Adds 3.0.3 RC3 data to CHANGELOG.md 2024-01-09 09:53:05 -03:00
Ville Brofeldt
439979c73a fix(post-processing): handle missing values in cumulative operator (#26429)
(cherry picked from commit ff025b78f3)
2024-01-09 09:13:47 -03:00
Xuebin Zhang
2a30d59b05 fix(translations): Clear all (#26424)
(cherry picked from commit 4c2e818cd3)
2024-01-09 09:13:47 -03:00
Ville Brofeldt
52109e5f24 fix(plugin-chart-echarts): support forced categorical x-axis (#26404) 2024-01-09 09:13:26 -03:00
Siva Sathyaseelan
333b18db5a fix: In chart gallery thumbnail is rendered in case of no example in #16707 (#26415)
(cherry picked from commit 6d58566779)
2024-01-09 09:12:02 -03:00
Sonia Gautam
26b26e46e4 fix(chart): Resolve incorrect column customization when switching metrics in table chart (#26393)
Co-authored-by: Sonia <sonia.gautam@agoda.com>
(cherry picked from commit dfde2adf27)
2024-01-09 09:12:01 -03:00
JUST.in DO IT
3589f7ece4 fix(dashboard): narrow empty drop area (#26313)
(cherry picked from commit 300ddaedf9)
2024-01-09 09:12:01 -03:00
Siva Sathyaseelan
f467310cea fix(dashboard): Chart menu disable is fixed on chart-fullscreen in issue #25992 (#26410)
(cherry picked from commit d0ffe9af7c)
2024-01-09 09:12:01 -03:00
Michael S. Molina
37ad33bf5b fix: Reactivates native filters E2E tests (#26362)
(cherry picked from commit 6f6c37ec26)
2024-01-04 09:36:22 -03:00
Irina Shebarshina
3f97daca09 fix(SelectControl): select zero value (#26353)
(cherry picked from commit a0f0f698f4)
2024-01-04 09:36:22 -03:00
Michael S. Molina
9b99303c5c fix: Invalid references in the basic template (#26302)
(cherry picked from commit 9432bd88f5)
2024-01-04 09:36:22 -03:00
Michael S. Molina
8deb9b21d9 fix: Removes non-existent columns in the 2018 FCC Survey dataset (#26380)
(cherry picked from commit 77f58fc8fa)
2024-01-04 09:36:22 -03:00
Corbin Bullard
5de0ef904e fix(chart): Set max row limit + removed the option to use an empty row limit value (#26151)
Co-authored-by: Lily Kuang <lily@preset.io>
Co-authored-by: Michael S. Molina <70410625+michael-s-molina@users.noreply.github.com>
2023-12-27 09:17:03 -03:00
Vitor Avila
aaa458bf9d chore(Embedded): Avoid creating a filter key for guest users (#26312)
Co-authored-by: Michael S. Molina <70410625+michael-s-molina@users.noreply.github.com>
(cherry picked from commit fe9fbadade)
2023-12-27 09:15:55 -03:00
John Bodley
a679237c36 fix(logging): Add logging of change_dashboard_filter event for native dashboard filters (#26333)
(cherry picked from commit 5f5a656835)
2023-12-27 09:15:55 -03:00
arun
643cb9df2b fix(accessibility): Enable tabbing on sort header of table chart (#26326)
(cherry picked from commit b6d433de32)
2023-12-27 09:15:55 -03:00
Kamil Gabryjelski
71bf15e870 fix(dashboard): Don't switch to first tab when directPathToChild changes (#26340)
(cherry picked from commit 39ac45351b)
2023-12-27 09:15:55 -03:00
Michael S. Molina
0e9cbd4f00 chore: Adds a tooltip for the alert's SQL input (#26317)
(cherry picked from commit 5bd7fd7990)
2023-12-27 09:15:55 -03:00
gaurav7261
05bf190d87 fix(redshift): convert_dttm method for redshift dataset and tests (#26283)
Co-authored-by: GauravM <gaurav@ip-192-168-0-100.ap-south-1.compute.internal>
(cherry picked from commit 60abf7e2af)
2023-12-27 09:15:55 -03:00
Guen Prawiroatmodjo
f360a59f2c fix(sql lab): Use quote_schema instead of quote method to format schema name (#26281)
(cherry picked from commit 9d3796828c)
2023-12-27 09:15:55 -03:00
Michael S. Molina
9a63b6b32d chore: Disables minor ticks by default (#26310)
(cherry picked from commit eb65cea971)
2023-12-27 09:14:36 -03:00
Elizabeth Thompson
ad23deb373 chore: update changelog for 2.1.3 (#26287) 2023-12-27 09:14:16 -03:00
Gnought
d5a5d5f388 fix(typings): model_id is a multiple option (#25967)
(cherry picked from commit 04f1c356a5)
2023-12-27 09:09:50 -03:00
Michael S. Molina
e5ce25d91d chore: Adds 3.0.3 RC2 data to CHANGELOG.md 2023-12-15 13:23:25 -03:00
Michael S. Molina
9b21c93c47 fix: Cannot expand initially hidden SQL Lab tab (#26279) 2023-12-15 13:14:40 -03:00
Ville Brofeldt
91e970537b fix(plugin-chart-echarts): use scale for truncating x-axis (#26269) 2023-12-15 13:13:01 -03:00
Michael S. Molina
5f92c2f0dc fix: Stacked charts with numerical columns (#26264)
(cherry picked from commit 429e2a33c3)
2023-12-15 13:11:54 -03:00
Daniel Vaz Gaspar
c878e2e102 chore: improve CSP add base uri restriction (#26251)
(cherry picked from commit 578a899152)
2023-12-15 13:11:53 -03:00
cwegener
c99c6301c7 fix: bump pyarrow constraints (CVE-2023-47248) (#26187)
(cherry picked from commit 2ac28927a3)
2023-12-15 13:11:53 -03:00
Michael S. Molina
cefca2f000 chore: Adds 3.0.3 data to CHANGELOG.md 2023-12-08 11:30:29 -03:00
Ville Brofeldt
b0905ce0bd fix(plugin-chart-echarts): support truncated numeric x-axis (#26215)
Co-authored-by: Michael S. Molina <michael.s.molina@gmail.com>
2023-12-08 11:04:31 -03:00
Vitor Avila
8eb6bbba91 fix(chart-filter): Avoid column denormalization if not enabled (#26199)
(cherry picked from commit 05d7060d83)
2023-12-08 10:32:02 -03:00
Ville Brofeldt
52f12ba06e fix: support custom links in markdown (#26211)
(cherry picked from commit d2adc858cb)
2023-12-08 10:32:02 -03:00
ʈᵃᵢ
c6c71123ee fix(dashboard): use textContent to render hidden title (#26189)
(cherry picked from commit 88fb342887)
2023-12-08 10:32:02 -03:00
Michael S. Molina
2b7766afa6 chore: Adds note about numerical x-axis (#26208)
Co-authored-by: John Bodley <4567245+john-bodley@users.noreply.github.com>
2023-12-08 10:31:42 -03:00
Michael S. Molina
2532fa5dd9 fix: Includes 90° x-axis label rotation (#26207) 2023-12-08 10:29:35 -03:00
Suma Goud B
03abfba0f5 fix(init-job): Fix envFrom for init job in helm chart (#26157) 2023-12-08 10:28:13 -03:00
Jack Fragassi
b9e8cc958a fix(embedded): Hide sensitive payload data from guest users (#25878)
(cherry picked from commit 386d4e0541)
2023-12-08 10:27:03 -03:00
Michael S. Molina
f4873860fc chore: Clean up the examples dashboards (#26158) 2023-12-04 18:00:01 -03:00
Ross Mabbett
4cba277795 fix(Alerts/Reports): allow use of ";" separator in slack recipient entry (#25894)
Co-authored-by: John Bodley <4567245+john-bodley@users.noreply.github.com>
(cherry picked from commit b7a9c220e1)
2023-12-04 15:03:22 -03:00
Vitor Avila
0b040b4824 fix(database-import): Support importing a DB connection with a version set (#26116)
(cherry picked from commit c033ca959d)
2023-12-04 14:03:21 -03:00
Beto Dealmeida
ec6d31c817 fix: set label on adhoc column should persist (#26154)
(cherry picked from commit b2ea97a984)
2023-12-04 14:03:21 -03:00
Beto Dealmeida
a4c5340c7e fix(annotations): time grain column (#26140)
(cherry picked from commit cff473f825)
2023-12-04 14:03:21 -03:00
Daniel Vaz Gaspar
a5c842c876 fix: remove default secret key from helm (#23916)
(cherry picked from commit 6a5a765689)
2023-12-04 14:03:20 -03:00
Gnought
02188d8401 chore(deps): bump pillow deps (#25931)
(cherry picked from commit a27a0df1a4)
2023-12-04 14:03:20 -03:00
Beto Dealmeida
3edbb9fdbd fix: alias column when fetching values (#26120)
(cherry picked from commit 7223633da6)
2023-12-04 14:03:20 -03:00
Ville Brofeldt
a3212ccba8 fix: flaky test_explore_json_async test v2 (#26106)
(cherry picked from commit 91a8b69d36)
2023-12-04 14:03:20 -03:00
Daniel Vaz Gaspar
00db4dfb06 fix: bump node-fetch to 2.6.7 (#26091)
(cherry picked from commit 4fc2758e6a)
2023-12-04 14:03:20 -03:00
Ville Brofeldt
b900cb7c3a fix(plugin-chart-echarts): support numerical x-axis (#26087)
(cherry picked from commit aad67e43db)
2023-12-04 14:03:20 -03:00
Michael S. Molina
ea65c2467c fix: Flaky test_explore_json_async test (#26059)
Co-authored-by: John Bodley <4567245+john-bodley@users.noreply.github.com>
(cherry picked from commit 2b88225ee1)
2023-12-04 14:01:08 -03:00
Jack Fragassi
ff5de25478 fix: Prevent cached bootstrap data from leaking between users w/ same first/last name (#26023) 2023-12-04 14:00:37 -03:00
John Bodley
7916778585 fix: Optimize fetching samples logic (#26060)
(cherry picked from commit bd8951e958)
2023-12-04 13:57:11 -03:00
aehanno
79d8865ac6 fix: Remove annotation Fuzzy to get french translation (#26010)
(cherry picked from commit 25a737e83c)
2023-12-04 13:57:11 -03:00
Sam Firke
0c0bb50d41 fix(security): restore default value of SESSION_COOKIE_SECURE to False (#26005)
(cherry picked from commit bba7763825)
2023-12-04 13:57:11 -03:00
Ross Mabbett
44fb6b5551 fix(horizontal filter bar filter labels): Increase max-width to 96px (#25883)
Co-authored-by: Elizabeth Thompson <eschutho@gmail.com>
(cherry picked from commit e7797b65d1)
2023-12-04 13:57:10 -03:00
Michael S. Molina
961eba6d97 chore: Updates CHANGELOG.md for 3.0.2 (rc2) 2023-11-20 16:40:41 -03:00
Daniel Vaz Gaspar
08604cc686 fix: update FAB to 4.3.10, Azure user info fix (#26037)
(cherry picked from commit 628cd345f2)
2023-11-20 16:27:34 -03:00
JUST.in DO IT
49661bcc59 fix(native filters): rendering performance improvement by reduce overrendering (#25901)
(cherry picked from commit e1d73d5420)
2023-11-20 16:19:24 -03:00
John Bodley
da06206ea6 chore: Optimize fetching samples logic (#25995)
(cherry picked from commit 326ac4a6c4)
2023-11-20 16:19:24 -03:00
JUST.in DO IT
e3fbb01bb8 fix(explore): redandant force param (#25985)
(cherry picked from commit e7a1876807)
2023-11-20 16:19:24 -03:00
Jack Fragassi
ee1ba7e172 fix: Make Select component fire onChange listener when a selection is pasted in (#25993)
(cherry picked from commit 5fccf67cdc)
2023-11-16 18:30:35 -03:00
yousoph
8d873e6da6 fix(rls): Update text from tables to datasets in RLS modal (#25997)
(cherry picked from commit 210f1f8f95)
2023-11-16 17:28:25 -03:00
josedev-union
1d2a564d4e fix(helm): Restart all related deployments when bootstrap script changed (#25703) 2023-11-16 17:28:08 -03:00
Hugh A. Miles II
1c287dfc74 fix: naming denomalized to denormalized in helpers.py (#25973)
(cherry picked from commit 5def416f63)
2023-11-16 17:26:51 -03:00
John Bodley
fb1919a483 chore(colors): Updating Airbnb brand colors (#23619)
(cherry picked from commit 6d8424c104)
2023-11-16 17:26:51 -03:00
Hugh A. Miles II
e07eed10a2 fix: always denorm column value before querying values (#25919) 2023-11-16 17:26:15 -03:00
Giacomo Barone
a7fbdd607a fix: update flask-caching to avoid breaking redis cache, solves #25339 (#25947)
Co-authored-by: Ville Brofeldt <33317356+villebro@users.noreply.github.com>
2023-11-16 17:22:25 -03:00
JUST.in DO IT
6da18f8451 fix(sqllab): invalid sanitization on comparison symbol (#25903)
(cherry picked from commit 581d3c7108)
2023-11-16 17:21:04 -03:00
John Bodley
eea6a8ed4f fix(table): Double percenting ad-hoc percentage metrics (#25857)
(cherry picked from commit 784a478268)
2023-11-16 17:21:04 -03:00
FGrobelny
078b78f30b fix(trino): allow impersonate_user flag to be imported (#25872)
Co-authored-by: John Bodley <4567245+john-bodley@users.noreply.github.com>
(cherry picked from commit 458be8c848)
2023-11-16 17:21:04 -03:00
Michael S. Molina
c655a3e7dd chore: Updates CHANGELOG.md for 3.0.2 2023-11-13 16:44:20 -03:00
Beto Dealmeida
d265bd2ffc fix: trino cursor (#25897)
(cherry picked from commit cdb18e04ff)
2023-11-08 09:56:38 -03:00
Beto Dealmeida
8c099a3f6f fix: database version field (#25898)
(cherry picked from commit 06ffcd29e2)
2023-11-08 09:56:38 -03:00
Kamil Gabryjelski
81f7c63763 fix: Saving Mixed Chart with dashboard filter applied breaks adhoc_filter_b (#25877)
(cherry picked from commit 268c1dcdad)
2023-11-08 09:56:37 -03:00
Antonio Rivero
756324d713 fix(charts): Time grain is None when dataset uses Jinja (#25842)
(cherry picked from commit 7536dd12cd)
2023-11-08 09:56:37 -03:00
Beto Dealmeida
5198279a2b fix: remove update_charts_owners (#25843) 2023-11-06 10:18:36 -03:00
Arko
4534a070df fix(table chart): Show Cell Bars correctly #25625 (#25707)
(cherry picked from commit 916f7bcbba)
2023-11-06 09:40:48 -03:00
mapledan
d5901140a7 fix: the temporal x-axis results in a none time_range. (#25429)
Co-authored-by: Elizabeth Thompson <eschutho@gmail.com>
(cherry picked from commit ae619b169c)
2023-11-06 09:40:48 -03:00
Michael S. Molina
925c63d4a6 fix: Fires onChange when clearing all values of single select (#25853)
(cherry picked from commit 8061d5cce9)
2023-11-06 09:40:48 -03:00
JUST.in DO IT
28272527fc fix(sqllab): infinite fetching status after results are landed (#25814)
(cherry picked from commit 3f28eebb20)
2023-11-01 09:08:19 -03:00
Ross Mabbett
2d574963f0 fix(SQL field in edit dataset modal): display full sql query (#25768)
(cherry picked from commit 1eba7121aa)
2023-11-01 09:08:19 -03:00
John Bodley
04c11b477b fix: Resolve issue #24195 (#25804)
(cherry picked from commit 8737a8a546)
2023-11-01 09:08:19 -03:00
John Bodley
c216b3efdf fix: Revert "fix: Apply normalization to all dttm columns (#25147)" (#25801) 2023-10-31 11:47:45 -03:00
Beto Dealmeida
1d403dab98 fix: DB-specific quoting in Jinja macro (#25779)
(cherry picked from commit 5659c87ed2)
2023-10-31 11:22:13 -03:00
Elizabeth Thompson
2f468900c8 fix: allow for backward compatible errors (#25640) 2023-10-31 11:18:24 -03:00
JUST.in DO IT
fbe7e6265d fix(sqllab): slow pop datasource query (#25741)
(cherry picked from commit 2a2bc82a8b)
2023-10-31 10:47:06 -03:00
Beto Dealmeida
01d3ac20c7 fix: dataset update uniqueness (#25756)
(cherry picked from commit c7f8d11a7e)
2023-10-31 10:47:06 -03:00
Geido
fd2c2725d4 fix: Revert "fix(Charts): Set max row limit + removed the option to use an empty row limit value" (#25753)
(cherry picked from commit e2fe967788)
2023-10-31 10:47:06 -03:00
Ross Mabbett
9b31d97ac3 fix(horizontal filter label): show full tooltip with ellipsis (#25732)
(cherry picked from commit e4173d90c8)
2023-10-31 10:47:06 -03:00
Daniel Vaz Gaspar
8da27eda40 fix: bump to FAB 4.3.9 remove CSP exception (#25712)
(cherry picked from commit 8fb0c8da56)
2023-10-31 10:37:08 -03:00
Stepan
8483ab6c42 fix(chore): dashboard requests to database equal the number of slices it has (#24709)
(cherry picked from commit 75a7431379)
2023-10-31 10:37:08 -03:00
Igor Khrol
315e75811f fix: remove unnecessary redirect (#25679)
(cherry picked from commit da42bf2dbb)
2023-10-31 10:37:07 -03:00
Rob Moore
5293f5521d fix(sqllab): reinstate "Force trino client async execution" (#25680) 2023-10-31 10:36:30 -03:00
OskarNS
293568ad5a fix(dremio): Fixes issue with Dremio SQL generation for Charts with Series Limit (#25657)
(cherry picked from commit be82657940)
2023-10-19 10:05:46 -03:00
JUST.in DO IT
b380495516 fix: warning of nth-child (#23638)
(cherry picked from commit 16cc089b19)
2023-10-19 09:59:46 -03:00
Daniel Vaz Gaspar
b0f229ea7e fix: improve upload ZIP file validation (#25658) 2023-10-19 09:59:24 -03:00
Jack
b95ff2da23 fix(header navlinks): link navlinks to path prefix (#25495)
(cherry picked from commit 51c56dd2a0)
2023-10-19 09:56:44 -03:00
Hugh A. Miles II
236aef8126 fix: permalink save/overwrites in explore (#25112)
Co-authored-by: Elizabeth Thompson <eschutho@gmail.com>
(cherry picked from commit e58a3aba54)
2023-10-19 09:56:44 -03:00
Jack Fragassi
af1e71352a fix(import): Make sure query context is overwritten for overwriting imports (#25493)
(cherry picked from commit a0a0d8043f)
2023-10-19 09:56:43 -03:00
Igor Khrol
ec3bed709e fix: avoid 500 errors with SQLLAB_BACKEND_PERSISTENCE (#25553)
(cherry picked from commit 99f79f5143)
2023-10-19 09:56:43 -03:00
JUST.in DO IT
701ee30d1e fix(sqllab): template validation error within comments (#25626)
(cherry picked from commit b370c66308)
2023-10-19 09:56:43 -03:00
JUST.in DO IT
d7cbdca081 fix(sqllab): Mistitled for new tab after rename (#25523)
(cherry picked from commit a520124a78)
2023-10-19 09:56:43 -03:00
Michael S. Molina
890bf59ce4 chore: Updates 3.0.1 CHANGELOG 2023-10-13 10:52:07 -03:00
Ville Brofeldt
cd1b7a4c06 fix: revert fix(sqllab): Force trino client async execution (#24859) (#25541)
(cherry picked from commit e56e0de458)
2023-10-13 09:10:46 -03:00
Beto Dealmeida
c44f1a3299 fix: finestTemporalGrainFormatter (#25618)
(cherry picked from commit 62bffaf935)
2023-10-13 09:10:46 -03:00
Fabien
a0b2dc4266 fix(window): unavailable localStorage and sessionStorage (#25599) 2023-10-13 09:10:16 -03:00
Corbin Bullard
732c5b1f08 fix(Charts): Set max row limit + removed the option to use an empty row limit value (#25579)
(cherry picked from commit f556ef53f3)
2023-10-13 09:04:41 -03:00
Rui Zhao
254cc36b17 fix(Presto): catch DatabaseError when testing Presto views (#25559)
Co-authored-by: Rui Zhao <zhaorui@dropbox.com>
(cherry picked from commit be3714e131)
2023-10-13 09:04:41 -03:00
Igor Khrol
53b84b9664 fix: thubmnails loading - Talisman default config (#25486)
(cherry picked from commit 52f631a038)
2023-10-13 09:04:41 -03:00
Corbin Bullard
69c2378747 fix(RLS): Fix Info Tooltip + Button Alignment on RLS Modal (#25400)
(cherry picked from commit a6d0e6f37a)
2023-10-11 08:36:08 -03:00
Daniel Vaz Gaspar
286c095506 fix: REST API CSRF exempt list (#25590)
(cherry picked from commit 549abb542b)
2023-10-11 08:36:08 -03:00
Kamil Gabryjelski
dd769eb7a0 fix: Apply normalization to all dttm columns (#25147)
(cherry picked from commit 58fcd292a9)
2023-10-09 11:45:56 -03:00
Igor Khrol
8b66603566 fix: tags permissions error message (#25516)
(cherry picked from commit 50b0816e37)
2023-10-09 11:27:46 -03:00
JUST.in DO IT
220dc58fe0 chore: Expand error detail on screencapture (#25519)
(cherry picked from commit ba541e8022)
2023-10-04 15:18:35 -03:00
JUST.in DO IT
1367d7b954 fix(sqllab): Broken query containing 'children' (#25490)
(cherry picked from commit b92957e510)
2023-10-04 15:18:35 -03:00
mapledan
ae700d13cf fix: Unable to sync columns when database or dataset name contains + (#25390)
(cherry picked from commit dbe0838f8f)
2023-10-04 15:18:35 -03:00
Michael S. Molina
4ad2a05333 chore: Adds 3.0.1 CHANGELOG 2023-10-03 13:13:47 -03:00
John Bodley
9d1ab460c3 fix: Address Mypy issue which is causing CI to fail (#25494)
(cherry picked from commit 36ed617090)
2023-10-03 10:52:16 -03:00
ʈᵃᵢ
455b3d8a67 fix(sqllab): error with lazy_gettext for tab titles (#25469)
(cherry picked from commit ddde178e3b)
2023-10-02 11:58:07 -03:00
Kamil Gabryjelski
0dd1a3bea5 fix: Styles not loading because of faulty CSP setting (#25468)
(cherry picked from commit 0cebffd59a)
2023-10-02 11:03:05 -03:00
Ville Brofeldt
615d7f5ccc fix(mysql): handle string typed decimal results (#24241)
(cherry picked from commit 7eab59af51)
2023-10-02 11:03:05 -03:00
Celalettin Calis
f682dbae52 fix(helm chart): set chart appVersion to 3.0.0 (#25373) 2023-10-02 11:02:40 -03:00
Gyuil Han
d8e87aa3cc fix: update the SQLAlchemy model definition at json column for Log table (#25445)
(cherry picked from commit e83a76a586)
2023-10-02 11:01:38 -03:00
Michael S. Molina
58778a78b2 fix: Duplicate items when pasting into Select (#25447)
(cherry picked from commit 7cf96cd843)
2023-09-28 14:38:25 -03:00
Corbin Bullard
731cd65111 fix(SqlLab): make icon placement even (#25372)
(cherry picked from commit 11b49a6ceb)
2023-09-28 11:46:32 -03:00
Stepan
7b2b696a19 fix(nativeFilters): Speed up native filters by removing unnecessary rerenders (#25282)
Co-authored-by: JUST.in DO IT <justin.park@airbnb.com>
(cherry picked from commit a0eeb4d767)
2023-09-28 11:46:32 -03:00
JUST.in DO IT
b83bd5dc1c fix(sqllab): invalid start date (#25437) 2023-09-28 11:45:58 -03:00
Beto Dealmeida
8dfe95f89d fix: smarter date formatter (#25404)
(cherry picked from commit f0080f9c55)
2023-09-28 11:37:17 -03:00
Daniel Vaz Gaspar
0c6db230af fix: swagger UI CSP error (#25368)
(cherry picked from commit 1716b9f8f6)
2023-09-28 11:37:17 -03:00
Beto Dealmeida
1757ce49a9 fix: chart import (#25425)
(cherry picked from commit a4d8f36863)
2023-09-28 11:37:17 -03:00
Jack
4a65d41ce8 fix: preventing save button from flickering in SQL Lab (#25106)
(cherry picked from commit 296ff17f19)
2023-09-28 11:37:17 -03:00
John Bodley
eacdbdd877 fix: Rename on_delete parameter to ondelete (#25424)
(cherry picked from commit 893b45feef)
2023-09-26 16:29:47 -07:00
JUST.in DO IT
721db8a1a9 fix(sqllab): invalid persisted tab state (#25308) (#25398) 2023-09-26 11:19:05 -03:00
Michael S. Molina
c508a335e6 fix: Workaround for Cypress ECONNRESET error (#25399)
(cherry picked from commit d76ff39766)
2023-09-25 17:42:57 -03:00
Beto Dealmeida
88e6f22180 fix: datetime with timezone excel export (#25318)
Co-authored-by: Michael S. Molina <70410625+michael-s-molina@users.noreply.github.com>
(cherry picked from commit 5ebcd2a5f6)
2023-09-25 10:42:16 -03:00
Michael S. Molina
5390e2d826 fix: DashboardRoles cascade operation (#25349)
(cherry picked from commit a971a28a34)
2023-09-25 10:02:37 -03:00
Jack Fragassi
0d53446562 fix: Improve the reliability of alerts & reports (#25239)
(cherry picked from commit f672d5da5c)
2023-09-25 09:52:08 -03:00
Jack Fragassi
61dcc70db4 fix: Use RLS clause instead of ID for cache key (#25229)
(cherry picked from commit fba66c6250)
2023-09-25 09:52:08 -03:00
Zef Lin
8ca49d4e6f fix(chart): Supporting custom SQL as temporal x-axis column with filter (#25126)
Co-authored-by: Kamil Gabryjelski <kamil.gabryjelski@gmail.com>
2023-09-25 09:51:41 -03:00
John Bodley
2d1f1e3d71 fix: Add explicit ON DELETE CASCADE for dashboard_roles (#25320)
(cherry picked from commit d54e827bb9)
2023-09-25 09:48:33 -03:00
Beto Dealmeida
807a027a5f fix: is_select with UNION (#25290)
(cherry picked from commit bb002d6147)
2023-09-25 09:48:33 -03:00
Michael S. Molina
40d9c4c81f chore: Updates CHANGELOG.md 2023-09-13 08:46:07 -03:00
John Bodley
f55962fbb8 chore: Remove the ability to switch to filter-box chart when DASHBOARD_NATIVE_FILTERS feature is enabled (#25275)
(cherry picked from commit 8eff5a75b4)
2023-09-13 08:41:12 -03:00
Lily Kuang
28e944ae86 fix: inability to remove chart filter when dashboard time filter is applied (#25217)
(cherry picked from commit a9512c1eef)
2023-09-12 11:20:26 -03:00
Kamil Gabryjelski
1498c21d42 fix: Add line height to metadata bar (#25268)
(cherry picked from commit 242921bb4c)
2023-09-12 11:01:02 -03:00
Hugo Sjöberg
69db484d2d fix(dockefile): broken docker image (#25251) 2023-09-12 11:00:33 -03:00
Kamil Gabryjelski
39dcb29a69 fix: Currency formatting in Table raw mode (#25248)
(cherry picked from commit ea21e800a7)
2023-09-11 11:51:17 -03:00
Kamil Gabryjelski
6d1b969602 fix: Don't apply number formatting to the label in Treemap (#25249)
(cherry picked from commit 894f250229)
2023-09-11 11:07:48 -03:00
Michael S. Molina
2f1ce7f721 fix: Clearing the currency format has no effect on the chart (#25238)
(cherry picked from commit 6f4e63162f)
2023-09-11 11:07:48 -03:00
Ville Brofeldt
65a2ca9e6f chore(trino): remove unnecessary index checks (#25211)
(cherry picked from commit 0668d12e3b)
2023-09-11 11:07:48 -03:00
Kamil Gabryjelski
10e781d0ff feat: Add currencies controls in control panels (#24718) 2023-09-11 11:06:49 -03:00
Michael S. Molina
dfd699f440 fix: Cypress test to force mouseover (follow-up) (#25223)
(cherry picked from commit 0e17e4b06f)
2023-09-07 14:48:33 -03:00
Beto Dealmeida
2ae9d2ef05 fix: granularity_sqla and GENERIC_CHART_AXES (#25213) 2023-09-07 10:30:14 -03:00
Rob Moore
80df8bc558 fix(sqllab): Force trino client async execution (#24859)
(cherry picked from commit cfda30c81a)
2023-09-07 10:24:22 -03:00
Michael S. Molina
dac3009cc6 fix: Cypress test to force mouseover (#25209)
(cherry picked from commit 47518cb002)
2023-09-07 10:24:22 -03:00
Beto Dealmeida
2ac03c3bcc fix: is_select (#25189)
(cherry picked from commit 2f68010729)
2023-09-07 10:24:22 -03:00
Michael S. Molina
d8c72b86bc fix: All values being selected in Select (#25202)
(cherry picked from commit e605d6dddf)
2023-09-06 10:47:21 -03:00
Hugh A. Miles II
408708be62 fix: DML failures in SQL Lab (#25190)
(cherry picked from commit d8496425e2)
2023-09-06 10:47:21 -03:00
Sandeep Patel
e77bc066bd fix: Issue #24493; Resolved report selection menu in chart and dashboard page (#25157)
(cherry picked from commit d0305445b2)
2023-09-06 10:47:21 -03:00
Michael S. Molina
90a66ee76c chore: Add a note about adhoc subqueries in UPDATING.md (#25161) 2023-09-05 09:15:19 -03:00
Lily Kuang
331fefd3dd fix: Applying Dashboard Time Range Filters to Overwritten Charts (#25156)
Co-authored-by: Michael S. Molina <70410625+michael-s-molina@users.noreply.github.com>
(cherry picked from commit f2523b26fa)
2023-09-05 09:13:16 -03:00
JUST.in DO IT
c56948e1f1 fix(sqllab): Invalid start date (#25133)
(cherry picked from commit 8b2a408dea)
2023-09-05 09:13:16 -03:00
Michael S. Molina
b53042a7be fix: Sunburst chart error when secondary metric is null (#25159)
(cherry picked from commit aea916782d)
2023-09-05 09:13:15 -03:00
aehanno
f778b62712 fix: Fixing untranslated FR strings (#20078)
(cherry picked from commit 2c4629a77d)
2023-09-01 10:21:17 -03:00
KSPT-taylorjohn
76d7bf9011 fix: Chart series limit doesn't work for some databases (#25150)
(cherry picked from commit bbfaeb074e)
2023-09-01 10:21:17 -03:00
John Bodley
af8f074919 fix: Handle Python date format for GENERIC_CHART_AXES feature (#25135)
(cherry picked from commit de9515c294)
2023-09-01 10:21:17 -03:00
Ethan M Lewis
dd0475d63c fix: add format for timestamp in crdb to correctly use times values (#24711)
Co-authored-by: John Bodley <4567245+john-bodley@users.noreply.github.com>
(cherry picked from commit 321d968504)
2023-09-01 10:21:17 -03:00
John Bodley
9837dabb2c docs: Fix typo in UPDATING.md (#25127) 2023-09-01 10:20:37 -03:00
Michael S. Molina
372004d0e6 fix: Bumps Flask Caching to fix RCE vulnerability (#25090) 2023-08-31 08:55:54 -03:00
Sam Firke
46e6d32260 refactor(frontend): make "Search" box the first filter for charts and datasets (#25129)
(cherry picked from commit eeecd59c9d)
2023-08-31 08:54:32 -03:00
Vitor Avila
e2f89d7aa8 fix(DB Connection): Update placeholder values for Snowflake connection (#25119)
(cherry picked from commit 46a0a6e08a)
2023-08-31 08:54:31 -03:00
John Bodley
798b493f3a docs: Update UPDATING.md regarding potential breaking change to ab_user.email column (#25115)
Co-authored-by: Michael S. Molina <70410625+michael-s-molina@users.noreply.github.com>
2023-08-30 09:16:55 -03:00
Michael S. Molina
caa3b6d5ba fix: Date format when importing international timestamps (#25113)
(cherry picked from commit 00550d7c02)
2023-08-30 09:13:40 -03:00
JUST.in DO IT
90e7e769ce fix(sqllab): error while removing a referenced table (#25114)
(cherry picked from commit 29355577f1)
2023-08-30 09:13:39 -03:00
JUST.in DO IT
429ff9b0f8 fix(sqllab): rendering performance regression by resultset (#25091) 2023-08-29 09:27:33 -03:00
Jack Fragassi
6a461260fc fix: Allow embedded guest user datasource access with dashboard context (#25081)
(cherry picked from commit 2b8d8da22a)
2023-08-29 08:48:48 -03:00
Jack Fragassi
f34e21be69 fix(assets import): Ensure old datasource ids are not referenced in imported charts (#25086)
(cherry picked from commit b240b795b5)
2023-08-29 08:48:48 -03:00
Michael S. Molina
9ceba619c3 fix: Filter names overflow wrap (#25087)
(cherry picked from commit b5bac6c876)
2023-08-29 08:48:48 -03:00
Erich
76da1b59f9 refactor(pinot): The python_date_format for a temporal column was not being passed to get_timestamp_expr (#24942)
(cherry picked from commit c2a21d2da0)
2023-08-29 08:48:48 -03:00
Zef Lin
7d5cd72e43 fix: dataset update permission out of sync (#25043) 2023-08-29 08:48:28 -03:00
Jack Fragassi
0caaad7b0a fix(embedded sdk): Remove trailing slash from passed superset domain if there is one (#25020)
(cherry picked from commit 7402379346)
2023-08-29 08:39:58 -03:00
Lily Kuang
55c57b9277 chore: remove CssTemplate and Annotation access from gamma role (#24826)
(cherry picked from commit 6ac906f388)
2023-08-29 08:39:58 -03:00
Michael S. Molina
2c99366333 chore: Updates CHANGELOG.md 2023-08-24 14:11:50 -03:00
Michael S. Molina
e4affbfc95 fix: Cross filters initial scope (#25074)
(cherry picked from commit f584c8462b)
2023-08-24 13:06:53 -03:00
Stepan
f5d2075ace fix(table): condition formatting can't formate 0 values (#24008)
(cherry picked from commit 0d5be8e3f6)
2023-08-24 13:06:53 -03:00
Rémy DUBOIS
2554a89cc9 fix(cli): import-directory is missing the application context (#21255)
(cherry picked from commit 80fcbfab7c)
2023-08-24 13:06:53 -03:00
John Bodley
ad89ea549b fix: Ensure SQLAlchemy sessions are closed (#25031)
(cherry picked from commit adaab3550c)
2023-08-24 13:06:53 -03:00
Daniel Vaz Gaspar
931e1b2139 fix: dataset safe URL for explore_url (#24686)
(cherry picked from commit a9efd4b2e3)
2023-08-23 09:55:50 -03:00
Michael S. Molina
b5f7f54c7f fix: Error when using the legacy dataset editor (#25057)
Co-authored-by: John Bodley <4567245+john-bodley@users.noreply.github.com>
(cherry picked from commit c92a975e4b)
2023-08-23 09:55:50 -03:00
John Bodley
1af6df3190 fix: Native filter dashboard RBAC aware dataset permission (#25029)
(cherry picked from commit 60889d27ed)
2023-08-22 17:39:55 -03:00
Michael S. Molina
8cb5142f87 fix: docker-compose non-dev (#25055)
(cherry picked from commit 7317d9c0b2)
2023-08-22 17:39:55 -03:00
Daniel Vaz Gaspar
6003aa2485 fix: extend user email size (#25053)
(cherry picked from commit 6975084ea5)
2023-08-22 17:39:55 -03:00
Sebastian Liebscher
80f1eaf6d7 chore: use os.getenv to simplify superset_config.py (#25016)
(cherry picked from commit 969cd664cb)
2023-08-22 17:39:55 -03:00
Yuval Moshe
34bc86a484 fix(mssql): avoid trying to return a resultset for DML queries with not resultset (#24999)
(cherry picked from commit 66eabc253f)
2023-08-21 11:12:57 -03:00
Daniel Vaz Gaspar
994fd2301f fix: CTE queries with non-SELECT statements (#25014)
(cherry picked from commit 357986103b)
2023-08-21 10:46:15 -03:00
Michael S. Molina
a5a027d8d1 fix: Dashboard fullscreen is removing custom URL params (#25028)
(cherry picked from commit 0be1754666)
2023-08-21 10:46:15 -03:00
John Bodley
fad872fffb fix: Address regression introduced in #24789 (#25008)
(cherry picked from commit 3f93755be2)
2023-08-21 10:46:15 -03:00
Michael S. Molina
88383ded80 chore: Pass the dashboard id when requesting filter values (#25025)
(cherry picked from commit 52c7186b56)
2023-08-21 10:46:15 -03:00
Jack Fragassi
9ff1a63c3b fix: Don't let users see dashboards only because it's favorited (#24991)
(cherry picked from commit 258e56285a)
2023-08-18 10:32:39 -03:00
Michael S. Molina
696917905e fix: Downgrades Prophet to 1.1.1 and Holidays to 0.23 (#25017) 2023-08-18 10:28:11 -03:00
Michael S. Molina
f63cb47f35 fix: Date column in Heatmap is displayed as unix timestamp (#25009) 2023-08-17 16:38:59 -03:00
Daniel Vaz Gaspar
c2c5f232c8 chore: isolate examples database by default (#25003)
(cherry picked from commit 269c99293f)
2023-08-17 16:36:42 -03:00
Elizabeth Thompson
ea27cf13d3 fix: update permalink schema (#24970)
(cherry picked from commit bc1c5c2f84)
2023-08-17 16:36:42 -03:00
Elizabeth Thompson
e20c2967c4 fix: Revert "fix(chart): Time Series set showMaxLabel as null for time xAxis (#20627) (#24995)
(cherry picked from commit 2b63577046)
2023-08-17 16:36:42 -03:00
Ville Brofeldt
387549f69c fix(snowflake): opt-in denormalization of column names (#24982) 2023-08-16 11:29:03 -03:00
Gyuil Han
1569f0177f chore: modify UPDATING.md for logs table migrations (#24923)
Co-authored-by: John Bodley <4567245+john-bodley@users.noreply.github.com>
Co-authored-by: Evan Rusackas <evan@preset.io>
2023-08-16 10:58:09 -03:00
JUST.in DO IT
8d3a919f5e fix(sqllab): scroll position after run current sql (#24965)
(cherry picked from commit 155cf54c15)
2023-08-16 10:56:53 -03:00
Michael S. Molina
3ffc5b69f8 fix: Calendar Heatmap day offset (#24989)
(cherry picked from commit 025e4d4772)
2023-08-16 10:56:53 -03:00
Michael S. Molina
4b07b5d628 feat: Adds options to show subtotals in Pivot Table (#24960)
(cherry picked from commit be11556799)
2023-08-14 09:26:21 -03:00
Michael S. Molina
dd53b334d6 fix: Duplicated options in Select when using numerical values (#24906)
(cherry picked from commit b621ee92c9)
2023-08-14 09:26:21 -03:00
Michael S. Molina
5c931b1951 fix: Tooltips don't disappear on the Heatmap chart (#24959)
(cherry picked from commit 9703490129)
2023-08-14 09:26:21 -03:00
Beto Dealmeida
52319201f9 chore: rate limit requests (#24324)
(cherry picked from commit 4bc46003b5)
2023-08-14 09:26:21 -03:00
Beto Dealmeida
ff2ec23102 fix: calls to _get_sqla_engine (#24953)
(cherry picked from commit 6f24a4e7a8)
2023-08-14 09:26:20 -03:00
Rob Moore
5d8c65ae6f fix(charts): View in SQL Lab with relevant perm (#24903)
(cherry picked from commit ce65a3b9cd)
2023-08-14 09:26:20 -03:00
Multazim Deshmukh
7a7fa748f5 fix: remove unused file (#24946)
(cherry picked from commit bcd24936bc)
2023-08-10 13:37:21 -03:00
Michael S. Molina
2574e11544 chore: Removes duplicated featureFlags.ts (#24935)
(cherry picked from commit 284c12697b)
2023-08-10 13:15:58 -03:00
John Bodley
1e20c0bf8a chore: Add explicit ON DELETE CASCADE for embedded_dashboards (#24939)
Co-authored-by: Michael S. Molina <70410625+michael-s-molina@users.noreply.github.com>
2023-08-10 13:14:56 -03:00
John Bodley
9b3ec806cd chore: Add explicit ON DELETE CASCADE for dashboard_slices (#24938) 2023-08-10 13:14:08 -03:00
John Bodley
309582516d fix: Dashboard aware RBAC "Save as" menu item (#24806)
(cherry picked from commit f6c3f0cbbb)
2023-08-10 10:12:49 -03:00
John Bodley
dba72c4197 chore: Refine native dashboard cleanup logic (#24864)
(cherry picked from commit 34586648a5)
2023-08-10 10:12:48 -03:00
John Bodley
804cc36080 chore: Refactor dashboard security access (#24804)
(cherry picked from commit 5522facdc6)
2023-08-10 10:12:48 -03:00
Michael S. Molina
df92cc2d55 fix: Tooltip of area chart shows undefined total (#24916)
(cherry picked from commit ec9e9a46f2)
2023-08-10 10:12:48 -03:00
JUST.in DO IT
42451880a8 fix(explore): double resize triggered (#24886)
(cherry picked from commit 340bfd88ae)
2023-08-10 10:12:48 -03:00
Gyuil Han
ed56375d5f fix(logs): increase json field for logs table (#24911)
(cherry picked from commit eb7c14561e)
2023-08-10 10:12:48 -03:00
Jack Fragassi
abead484e1 fix: Migration to fix out of sync schema_perm in charts and datasets (#24884)
(cherry picked from commit 07992c11e7)
2023-08-07 16:29:30 -03:00
John Bodley
c8c7539ff1 fix: Dashboard aware RBAC dataset permission (#24789)
(cherry picked from commit 7397ab36f2)
2023-08-07 16:19:56 -03:00
John Bodley
215b3b5a4b fix: revert "fix(embedded): adding logic to check dataset used by filters (#24808) (#24892)
(cherry picked from commit 9f7f2c60d6)
2023-08-07 16:19:56 -03:00
Michael S. Molina
7fe61ccf7d fix: Pylint errors from cherry-picking 2023-08-07 16:17:10 -03:00
Elizabeth Thompson
e46f10a8a6 chore: add talisman env var to config (#24774)
(cherry picked from commit d23b20ea75)
2023-08-04 14:12:35 -03:00
JUST.in DO IT
b272814ff5 fix(dataset): resizable dataset layout left column (#24829)
(cherry picked from commit 6ff7fae0b0)
2023-08-04 14:12:35 -03:00
JUST.in DO IT
84035badab fix(explore): invalid "No Filter" applied (#24876)
(cherry picked from commit 371bffbfea)
2023-08-04 14:12:35 -03:00
John Bodley
21764f9ae3 fix(annotation): Address regression from #24694 (#24874)
(cherry picked from commit f05638ba84)
2023-08-04 14:12:35 -03:00
Hugh A. Miles II
8cf702bf3d fix: validation errors appearing after ssh tunnel switch (#24849)
(cherry picked from commit b71541fb7f)
2023-08-04 14:12:35 -03:00
Michael S. Molina
e47377e576 fix: Explore misleading save action (#24862)
(cherry picked from commit bf1b1a4c46)
2023-08-04 14:12:35 -03:00
JUST.in DO IT
21ded992ad fix(sqllab): Add docText for long keyword (#24847)
(cherry picked from commit 1a9c559a8f)
2023-08-04 14:12:35 -03:00
JUST.in DO IT
29528e9783 fix(legacy-chart): corrupted raw chart data (#24850)
(cherry picked from commit 1c5971d3af)
2023-08-02 08:38:09 -03:00
Michael S. Molina
34adeb4f4f fix: Links in tooltips of dashboard chart cards (#24846)
(cherry picked from commit ea17dd637c)
2023-08-01 10:54:41 -03:00
Vitor Avila
bbe4e016d8 fix(embedded): adding logic to check dataset used by filters (#24808)
(cherry picked from commit 7f9b0380e0)
2023-08-01 10:54:41 -03:00
EugeneTorap
161e05445c fix: Python3.11 (str, Enum) issue (#24803) 2023-08-01 10:54:20 -03:00
Stepan
b5df3f9e4e fix(datasets): give possibility to add dataset with slashes in name (#24796) 2023-07-31 09:25:24 -03:00
Jack Fragassi
a9b8c8e3ec fix: Allow chart import to update the dataset an existing chart points to (#24821)
(cherry picked from commit 77889b29fb)
2023-07-31 09:23:03 -03:00
John Bodley
1a0d270e5b fix(migration): Ensure cascadeParentIds key exists (#24831)
(cherry picked from commit caffe3cb1f)
2023-07-31 09:23:03 -03:00
Michael S. Molina
7d2da96e81 fix: Removes unnecessary query on filters (#24814)
(cherry picked from commit 5bb8e0da89)
2023-07-31 09:23:02 -03:00
Beto Dealmeida
b89d7387a2 fix: pass schema on dataset creation (#24815)
(cherry picked from commit ba508a786c)
2023-07-31 09:23:02 -03:00
Michael S. Molina
571f33536e chore: Updates CHANGELOG.md 2023-07-26 19:35:07 -03:00
Michael S. Molina
651c13b934 chore: Updates helm files 2023-07-26 18:39:24 -03:00
dependabot[bot]
af8c813cb6 build(deps): bump tox from 4.6.3 to 4.6.4 in /requirements (#24613)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-26 18:03:46 -03:00
Michael S. Molina
ad1a425269 fix: Filters alert width (#24801)
(cherry picked from commit 4b1f1d49d6)
2023-07-26 16:50:57 -03:00
JUST.in DO IT
84488b7c5e fix(sqllab): Replace autocomplete logic by a hook (#24677)
(cherry picked from commit 77505173ae)
2023-07-26 16:50:57 -03:00
Daniel Vaz Gaspar
d86ae30958 fix: docs invalid client redirect (#24816)
(cherry picked from commit d1eb9ea982)
2023-07-26 16:50:57 -03:00
Daniel Vaz Gaspar
d92f9a73d2 docs: update security policy and add CVE info (#24769)
(cherry picked from commit 165afee55a)
2023-07-26 16:50:57 -03:00
xavier-GitHub76
98ec90938d fix: Department names fixed for CountryMap of France (#23988)
(cherry picked from commit a9c4472d25)
2023-07-26 16:50:57 -03:00
Gyuil Han
25d42538d1 fix(dashboard): increase json_metadata field (#24510)
(cherry picked from commit ff7c1528db)
2023-07-26 16:50:57 -03:00
Stepan
a85da81815 fix(chore): switching between languages should be without timeout 60 seconds (#24798)
(cherry picked from commit 761fec2574)
2023-07-26 16:50:57 -03:00
JUST.in DO IT
d95241df9d fix(sqllab): Replace margin style by gap on query results (#24772)
(cherry picked from commit 4a81284056)
2023-07-25 15:24:40 -03:00
Michael S. Molina
d336431559 fix: Select onChange is being fired without explicit selection (#24698)
Co-authored-by: JUST.in DO IT <justin.park@airbnb.com>
(cherry picked from commit 6089b5fdae)
2023-07-25 15:24:40 -03:00
Zef Lin
e3d8ecb478 chore(view_api): return application/json as content-type for api/v1/form_data endpoint (#24758)
(cherry picked from commit 0631a8086c)
2023-07-24 09:47:23 -03:00
Elizabeth Thompson
a066ebbb5e fix: update svgr webpack config to use svg dimensions (#24747) 2023-07-24 09:47:04 -03:00
Beto Dealmeida
6947983d5f feat: migrate charts on import (#24703)
(cherry picked from commit abb8e28e49)
2023-07-24 09:43:52 -03:00
Evan Rusackas
00516c2088 chore(docs): Adding link to additional visualization content (#24759)
(cherry picked from commit e210da963d)
2023-07-24 09:43:52 -03:00
mattitoo
2e978bba14 docs: Fix STANDARD_ROLES.md for Gamma role permissions on tableschemaview (#24766)
(cherry picked from commit d642288092)
2023-07-24 09:43:52 -03:00
karsten-wagner
a8f808f7a8 fix(docs): respect no_proxy environment variable (#23816)
(cherry picked from commit a80ec15f4c)
2023-07-24 09:43:52 -03:00
Michael S. Molina
dd002a8cf6 fix: Tooltip no longer highlights hovered data series (#24756)
(cherry picked from commit ac19f58cf6)
2023-07-24 09:43:52 -03:00
Maxime Beauchemin
157cc621c5 fix: column/metric type icons look too small (#24740)
(cherry picked from commit 341b8d41c5)
2023-07-24 09:43:52 -03:00
Maxime Beauchemin
299dbb7012 chore: make control panel sub sections look better (#24736)
(cherry picked from commit 22a0fe555c)
2023-07-24 09:43:51 -03:00
Beto Dealmeida
2e222865bf fix: search_path in RDS (#24739)
(cherry picked from commit 7675e0db10)
2023-07-24 09:43:51 -03:00
JUST.in DO IT
d87724a6e3 fix(datasets): Replace left panel layout by TableSelector (#24599)
Co-authored-by: Justin Park <justinpark@apache.org>
(cherry picked from commit b2831b419e)
2023-07-24 09:43:51 -03:00
Stepan
6281f50bab fix(pvt2): migrations from legacy pivot table error when form_data have pieces of pvt2 (#24710)
(cherry picked from commit df106aa708)
2023-07-24 09:43:51 -03:00
JUST.in DO IT
06258a06ed chore(native filters): Expandable filter config modal (#24559)
Co-authored-by: Justin Park <justinpark@apache.org>
(cherry picked from commit 05e724f3d7)
2023-07-24 09:43:51 -03:00
Michael S. Molina
a7221c6dd4 fix: Dashboard time grain in Table (#24746)
(cherry picked from commit 317aa989c2)
2023-07-24 09:43:51 -03:00
JUST.in DO IT
66792beb8b fix(native filter): clean deleted parent filter ids (#24749)
Co-authored-by: John Bodley <john.bodley@gmail.com>
(cherry picked from commit 4086514fa5)
2023-07-24 09:43:51 -03:00
Maxime Beauchemin
aa5f0b1019 chore: make antd table font size same as data table (#24741)
(cherry picked from commit d1d5ff6f9f)
2023-07-24 09:43:51 -03:00
Daniel Vaz Gaspar
cc7983cd4a fix: import database engine validation (#24697)
(cherry picked from commit cb9b865a53)
2023-07-20 12:00:26 -03:00
Elizabeth Thompson
1625fe4104 chore: turn off talisman for ephemeral environments in ci (#24627)
(cherry picked from commit 1a9724582f)
2023-07-20 12:00:26 -03:00
Arjun Devarajan
91919569ba feat: use Scarf Gateway for Superset npm downloads (#24433)
Co-authored-by: Arjun Devarajan <arjun.devarajan@scarf.sh>
Co-authored-by: Evan Rusackas <evan@preset.io>
Co-authored-by: Evan Rusackas <evan@rusackas.com>
2023-07-20 12:00:04 -03:00
Stepan
befe41df14 fix(range-slider): removed localization of metric key (#24716)
(cherry picked from commit 2d58dddbdc)
2023-07-20 11:55:54 -03:00
John Bodley
a3138f2bbe fix(cache): Add cache warmup for non-legacy charts (#24671)
(cherry picked from commit 5f49e0fdd0)
2023-07-20 11:55:54 -03:00
John Bodley
82311edaf6 fix(druid): Delete obsolete Druid NoSQL slice parameters (#24737)
(cherry picked from commit 4c5ada421c)
2023-07-20 11:55:53 -03:00
Arjun Devarajan
757741942d feat: use Scarf Gateway for Superset helm charts/Docker compose downloads (#24432) 2023-07-19 10:56:54 -03:00
John Bodley
65822cab13 chore: Bump pyyaml bounds (#24731) 2023-07-19 10:53:05 -03:00
John Bodley
4390968dd7 chore: Remove obsolete legacy visualizations (#24694)
(cherry picked from commit 1b5a6790f0)
2023-07-19 10:50:30 -03:00
Lily Kuang
2e913492c9 fix: color collision in dashboard with tabs (#24670)
(cherry picked from commit 0328dd2704)
2023-07-19 10:50:30 -03:00
Vitor Avila
c94bee47aa fix(dataset-import): support empty strings for extra fields (#24663)
(cherry picked from commit 65fb8e10ba)
2023-07-19 10:50:30 -03:00
Daniel Vaz Gaspar
c6ecbc81ac chore: move deprecated default version to 4.0.0 (#24689)
(cherry picked from commit ca68250adf)
2023-07-19 10:50:30 -03:00
Beto Dealmeida
60385ed059 fix: embedded dashboard check (#24690)
(cherry picked from commit 9844b15e07)
2023-07-19 10:50:30 -03:00
Michael S. Molina
b0c90cb261 fix: Dashboard time grain in Pivot Table (#24665)
(cherry picked from commit 6e59f11f4c)
2023-07-19 10:50:30 -03:00
John Bodley
49605e763c chore(command): Condense delete/bulk-delete operations (#24607)
Co-authored-by: Michael S. Molina <70410625+michael-s-molina@users.noreply.github.com>
(cherry picked from commit a156816064)
2023-07-13 13:36:20 -03:00
Arkadii Yakovets
7243332082 chore: Bump holidays to 0.28 (#24647)
(cherry picked from commit 767afef398)
2023-07-13 13:36:20 -03:00
John Bodley
1872a651da chore: Bump/relax Flask libs (#24652)
(cherry picked from commit 462418ba82)
2023-07-12 11:20:05 -03:00
JUST.in DO IT
f60ab456f3 feat(sqllab): add shortcut for run current sql (#24329)
Co-authored-by: Justin Park <justinpark@apache.org>
(cherry picked from commit 1473d97055)
2023-07-12 11:20:05 -03:00
John Bodley
96cf6406f1 chore(dao): Add explicit ON DELETE CASCADE for ownership (#24628) 2023-07-12 11:19:43 -03:00
John Bodley
71eff954ba chore(dao): Condense delete/bulk-delete operations (#24466)
Co-authored-by: Michael S. Molina <70410625+michael-s-molina@users.noreply.github.com>
(cherry picked from commit 7409289762)
2023-07-12 11:17:04 -03:00
JUST.in DO IT
79a42c6509 fix(sqllab): missing column meta on autocomplete (#24611)
Co-authored-by: Justin Park <justinpark@apache.org>
(cherry picked from commit ca8c8d2ad3)
2023-07-12 11:03:47 -03:00
Jack Fragassi
d8bf955515 fix: Chart can be added to dashboard by non-owner via save as option (#24630)
(cherry picked from commit 4caf33b41d)
2023-07-12 11:03:47 -03:00
Kamil Gabryjelski
a2fdc84073 fix: Ensure config is a dict in cross filters scope migration (#24661)
(cherry picked from commit 2e4d9f2e2a)
2023-07-12 11:03:47 -03:00
Kamil Gabryjelski
5a4996c226 fix: Incorrect initial global scoping of cross filters (#24642)
(cherry picked from commit bbffc4c1f8)
2023-07-12 11:03:46 -03:00
Michael S. Molina
359bbe26f7 fix: Validation of out of scope filters and interaction with Clear All (#24610)
(cherry picked from commit 0efb88479e)
2023-07-12 11:03:46 -03:00
John Bodley
27dcc3e025 chore: Drop rouge constraints and tables (#24629)
(cherry picked from commit 65291a00c6)
2023-07-12 11:03:46 -03:00
Daniel Vaz Gaspar
d6296c1ad1 fix: CSP, bump FAB to 4.3.4 (#24646)
(cherry picked from commit 4881328fbf)
2023-07-12 11:03:46 -03:00
Hugh A. Miles II
846d3c03aa fix: fix extra insert for count on dataset creation (#24625)
(cherry picked from commit e6e8276a20)
2023-07-12 11:03:46 -03:00
Kamil Gabryjelski
2bd9ca3c94 fix: Ensure metrics is an array in Mixed Chart (#24643)
(cherry picked from commit fe2c14ff3a)
2023-07-12 11:03:46 -03:00
Daniel Vaz Gaspar
a15e809c0f fix: remove spaces and EOL from nonce attr (#24644)
(cherry picked from commit b809815436)
2023-07-12 11:03:46 -03:00
Michael S. Molina
b81ee82d3c fix: Wrong positioning of filter tooltips on scroll (#24617)
(cherry picked from commit c53b249998)
2023-07-10 10:27:25 -03:00
Kamil Gabryjelski
6b366a2cff feat: Implement support for currencies in more charts (#24594)
(cherry picked from commit d74d7eca23)
2023-07-10 10:27:25 -03:00
Hugh A. Miles II
9a96d8cf8b fix: change naming convention for count metric on Dataset creation (#24609)
(cherry picked from commit c573cfcd12)
2023-07-10 10:27:25 -03:00
Gyuil Han
744cf2ec29 chore: remove underscore from builtin_time_grains label (#24567)
(cherry picked from commit a6e749da87)
2023-07-10 10:27:25 -03:00
Michael S. Molina
26909bf517 fix: Incorrect dependency between filters related feature flags (#24608)
(cherry picked from commit 781a20423a)
2023-07-07 09:48:45 -03:00
Beto Dealmeida
967ca0470b fix(report): edit without custom width (#24612)
(cherry picked from commit 93ba4ade09)
2023-07-07 09:48:45 -03:00
Hugh A. Miles II
0976b5e51e fix(ssh): Editting Database w/ SSH Tunneling (#24552)
(cherry picked from commit d041648ad4)
2023-07-07 09:48:45 -03:00
jwilliams-ocient
67008f2c35 fix: set max version for pyocient (#24556)
(cherry picked from commit 64d728f80f)
2023-07-07 09:48:45 -03:00
John Bodley
af2689d501 fix: Bump prophet, re-enable tests, and remedy column eligibility logic (#24129)
(cherry picked from commit 383dac6a5e)
2023-07-07 09:48:45 -03:00
JUST.in DO IT
a5f3cfc726 chore(sqllab): Log current local storage usage (#24554)
Co-authored-by: Justin Park <justinpark@apache.org>
(cherry picked from commit 0836000f9f)
2023-07-07 09:48:45 -03:00
Michael S. Molina
9ab61c1103 fix: Clicking on a tag in the dashboard and charts lists does not work (#24593)
(cherry picked from commit 04ae259f3d)
2023-07-05 13:02:50 -03:00
Ville Brofeldt
6de6f47728 chore(metastore-cache): add codec support (#24586)
(cherry picked from commit a4880cabd4)
2023-07-05 11:50:50 -03:00
Hugh A. Miles II
1b41653d3b fix: SSH Tunnel creation with dynamic form (#24196)
(cherry picked from commit 226c7f807d)
2023-07-05 11:50:50 -03:00
Michael S. Molina
eb42fa7a2e chore: Updates CHANGELOG.md and UPDATING.md 2023-06-30 09:27:24 -03:00
654 changed files with 21306 additions and 9926 deletions

38
.github/SECURITY.md vendored Normal file
View File

@@ -0,0 +1,38 @@
# Security Policy
This is a project of the [Apache Software Foundation](https://apache.org) and follows the
ASF [vulnerability handling process](https://apache.org/security/#vulnerability-handling).
## Reporting Vulnerabilities
**⚠️ Please do not file GitHub issues for security vulnerabilities as they are public! ⚠️**
Apache Software Foundation takes a rigorous standpoint in annihilating the security issues
in its software projects. Apache Superset is highly sensitive and forthcoming to issues
pertaining to its features and functionality.
If you have any concern or believe you have found a vulnerability in Apache Superset,
please get in touch with the Apache Security Team privately at
e-mail address [security@apache.org](mailto:security@apache.org).
More details can be found on the ASF website at
[ASF vulnerability reporting process](https://apache.org/security/#reporting-a-vulnerability)
We kindly ask you to include the following information in your report:
- Apache Superset version that you are using
- A sanitized copy of your `superset_config.py` file or any config overrides
- Detailed steps to reproduce the vulnerability
Note that Apache Superset is not responsible for any third-party dependencies that may
have security issues. Any vulnerabilities found in third-party dependencies should be
reported to the maintainers of those projects. Results from security scans of Apache
Superset dependencies found on its official Docker image can be remediated at release time
by extending the image itself.
**Your responsible disclosure and collaboration are invaluable.**
## Extra Information
- [Apache Superset documentation](https://superset.apache.org/docs/security)
- [Common Vulnerabilities and Exposures by release](https://superset.apache.org/docs/security/cves)
- [How Security Vulnerabilities are Reported & Handled in Apache Superset (Blog)](https://preset.io/blog/how-security-vulnerabilities-are-reported-and-handled-in-apache-superset/)

View File

@@ -25,8 +25,12 @@
"value": "8080"
},
{
"name": "SUPERSET_SECRET_KEY",
"value": "super-secret-for-ephemerals"
"name": "SUPERSET_SECRET_KEY",
"value": "super-secret-for-ephemerals"
},
{
"name": "TALISMAN_ENABLED",
"value": "False"
}
],
"mountPoints": [],

View File

@@ -42,12 +42,13 @@ repos:
hooks:
- id: mypy
args: [--check-untyped-defs]
additional_dependencies:
[
additional_dependencies: [
types-simplejson,
types-python-dateutil,
types-requests,
types-redis,
# types-redis 4.6.0.5 is failing mypy
# because of https://github.com/python/typeshed/pull/10531
types-redis==4.6.0.4,
types-pytz,
types-croniter,
types-PyYAML,

View File

@@ -83,6 +83,7 @@ enable=
# no Warning level messages displayed, use"--disable=all --enable=classes
# --disable=W"
disable=
no-member, # re-enable once this no longer raises false positives. This will become redundant after the min required version is 3.11
missing-docstring,
duplicate-code,
unspecified-encoding,

File diff suppressed because it is too large Load Diff

View File

@@ -577,6 +577,19 @@ cd superset-frontend
npm ci
```
Note that Superset uses [Scarf](https://docs.scarf.sh) to capture telemetry/analytics about versions being installed, including the `scarf-js` npm package. As noted elsewhere in this documentation, Scarf gathers aggregated stats for the sake of security/release strategy, and does not capture/retain PII. [You can read here](https://docs.scarf.sh/package-analytics/) about the package, and various means to opt out of it, but one easy way to opt out is to add this setting in `superset-frontent/package.json`:
```json
// your-package/package.json
{
// ...
"scarfSettings": {
"enabled": false
}
// ...
}
```
#### Build assets
There are three types of assets you can build:
@@ -586,10 +599,13 @@ There are three types of assets you can build:
3. `npm run build-instrumented`: instrumented application code for collecting code coverage from Cypress tests
If this type of error comes while building assets(i.e using above commands):
```bash
Error: You must provide the URL of lib/mappings.wasm by calling SourceMapConsumer.initialize
```
Then put this:
```bash
export NODE_OPTIONS=--no-experimental-fetch
```
@@ -913,28 +929,22 @@ For debugging locally using VSCode, you can configure a launch configuration fil
```json
{
"version": "0.2.0",
"configurations": [
{
"name": "Python: Flask",
"type": "python",
"request": "launch",
"module": "flask",
"env": {
"FLASK_APP": "superset",
"SUPERSET_ENV": "development"
},
"args": [
"run",
"-p 8088",
"--with-threads",
"--reload",
"--debugger"
],
"jinja": true,
"justMyCode": true
}
]
"version": "0.2.0",
"configurations": [
{
"name": "Python: Flask",
"type": "python",
"request": "launch",
"module": "flask",
"env": {
"FLASK_APP": "superset",
"SUPERSET_ENV": "development"
},
"args": ["run", "-p 8088", "--with-threads", "--reload", "--debugger"],
"jinja": true,
"justMyCode": true
}
]
}
```
@@ -1019,24 +1029,24 @@ You are now ready to attach a debugger to the process. Using VSCode you can conf
```json
{
"version": "0.2.0",
"configurations": [
"version": "0.2.0",
"configurations": [
{
"name": "Attach to Superset App in Docker Container",
"type": "python",
"request": "attach",
"connect": {
"host": "127.0.0.1",
"port": 5678
},
"pathMappings": [
{
"name": "Attach to Superset App in Docker Container",
"type": "python",
"request": "attach",
"connect": {
"host": "127.0.0.1",
"port": 5678
},
"pathMappings": [
{
"localRoot": "${workspaceFolder}",
"remoteRoot": "/app"
}
]
},
]
"localRoot": "${workspaceFolder}",
"remoteRoot": "/app"
}
]
}
]
}
```
@@ -1337,7 +1347,7 @@ To do this, you'll need to:
but perfect for testing (stores cache in `/tmp`)
```python
from cachelib.file import FileSystemCache
from flask_caching.backends.filesystemcache import FileSystemCache
RESULTS_BACKEND = FileSystemCache('/tmp/sqllab')
```
@@ -1403,11 +1413,11 @@ Note not all fields are correctly categorized. The fields vary based on visualiz
### Time
| Field | Type | Notes |
| ------------------ | -------- | ------------------------------------- |
| `granularity_sqla` | _string_ | The SQLA **Time Column** widget |
| `time_grain_sqla` | _string_ | The SQLA **Time Grain** widget |
| `time_range` | _string_ | The **Time range** widget |
| Field | Type | Notes |
| ------------------ | -------- | ------------------------------- |
| `granularity_sqla` | _string_ | The SQLA **Time Column** widget |
| `time_grain_sqla` | _string_ | The SQLA **Time Grain** widget |
| `time_range` | _string_ | The **Time range** widget |
### GROUP BY

View File

@@ -25,8 +25,16 @@ ARG BUILDPLATFORM=${BUILDPLATFORM:-amd64}
FROM --platform=${BUILDPLATFORM} node:16-slim AS superset-node
ARG NPM_BUILD_CMD="build"
ENV BUILD_CMD=${NPM_BUILD_CMD}
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true
RUN apt-get update -q \
&& apt-get install -yq --no-install-recommends \
python3 \
make \
gcc \
g++
ENV BUILD_CMD=${NPM_BUILD_CMD} \
PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true
# NPM ci first, as to NOT invalidate previous steps except for when package.json changes
WORKDIR /app/superset-frontend

View File

@@ -81,9 +81,9 @@
|can available domains on Superset|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
|can request access on Superset|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
|can dashboard on Superset|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
|can post on TableSchemaView|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
|can expanded on TableSchemaView|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
|can delete on TableSchemaView|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
|can post on TableSchemaView|:heavy_check_mark:|:heavy_check_mark:|O|O|
|can expanded on TableSchemaView|:heavy_check_mark:|:heavy_check_mark:|O|O|
|can delete on TableSchemaView|:heavy_check_mark:|:heavy_check_mark:|O|O|
|can get on TabStateView|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|
|can post on TabStateView|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|
|can delete query on TabStateView|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|

View File

@@ -24,9 +24,25 @@ assists people when migrating to a new version.
## Next
### Breaking Changes
### Potential Downtime
### Other
## 3.0.3
- [26034](https://github.com/apache/superset/issues/26034): Fixes a problem where numeric x-axes were being treated as categorical values. As a consequence of that, the way labels are displayed might change given that ECharts has a different treatment for numerical and categorical values. To revert to the old behavior, users need to manually convert numerical columns to text so that they are treated as categories. Check https://github.com/apache/superset/issues/26159 for more details.
## 3.0.0
- [25053](https://github.com/apache/superset/pull/25053): Extends the `ab_user.email` column from 64 to 320 characters which has an associated unique key constraint. This will be problematic for MySQL metadata databases which use the InnoDB storage engine with the `innodb_large_prefix` parameter disabled as the key prefix limit is 767 bytes. Enabling said parameter and ensuring that the table uses either the `DYNAMIC` or `COMPRESSED` row format should remedy the problem. See [here](https://dev.mysql.com/doc/refman/5.7/en/innodb-limits.html) for more details.
- [24911](https://github.com/apache/superset/pull/24911): Changes the column type from `TEXT` to `MediumText` in table `logs`, potentially requiring a table lock on MySQL dbs or taking some time to complete on large deployments.
- [24939](https://github.com/apache/superset/pull/24939): Augments the foreign key constraints for the `embedded_dashboards` table to include an explicit CASCADE ON DELETE to ensure the relevant records are deleted when a dashboard is deleted. Scheduled downtime may be advised.
- [24938](https://github.com/apache/superset/pull/24938): Augments the foreign key constraints for the `dashboard_slices` table to include an explicit CASCADE ON DELETE to ensure the relevant records are deleted when a dashboard or slice is deleted. Scheduled downtime may be advised.
- [24628]https://github.com/apache/superset/pull/24628): Augments the foreign key constraints for the `dashboard_owner`, `report_schedule_owner`, and `slice_owner` tables to include an explicit CASCADE ON DELETE to ensure the relevant ownership records are deleted when a dataset is deleted. Scheduled downtime may be advised.
- [24488](https://github.com/apache/superset/pull/24488): Augments the foreign key constraints for the `sql_metrics`, `sqlatable_user`, and `table_columns` tables which reference the `tables` table to include an explicit CASCADE ON DELETE to ensure the relevant records are deleted when a dataset is deleted. Scheduled downtime may be advised.
- [24335](https://github.com/apache/superset/pull/24335): Removed deprecated API `/superset/filter/<datasource_type>/<int:datasource_id>/<column>/`
- [24185](https://github.com/apache/superset/pull/24185): `/api/v1/database/test_connection` and `api/v1/database/validate_parameters` permissions changed from `can_read` to `can_write`. Only Admin user's have access.
- [24232](https://github.com/apache/superset/pull/24232): Enables ENABLE_TEMPLATE_REMOVE_FILTERS, DRILL_TO_DETAIL, DASHBOARD_CROSS_FILTERS by default, marks VERSIONED_EXPORT and ENABLE_TEMPLATE_REMOVE_FILTERS as deprecated.
- [23652](https://github.com/apache/superset/pull/23652): Enables GENERIC_CHART_AXES feature flag by default.
- [23226](https://github.com/apache/superset/pull/23226): Migrated endpoint `/estimate_query_cost/<int:database_id>` to `/api/v1/sqllab/estimate/`. Corresponding permissions are can estimate query cost on SQLLab. Make sure you add/replace the necessary permissions on any custom roles you may have.
@@ -37,9 +53,11 @@ assists people when migrating to a new version.
make it more clear which envrionment your are in.
`SUPERSET_ENV=production` and `SUPERSET_ENV=development` are the two
supported switches based on the default config.
- [19242](https://github.com/apache/superset/pull/19242): Adhoc subqueries are now disabled by default for security reasons. To enable them, set the feature flag `ALLOW_ADHOC_SUBQUERY` to `True`.
### Breaking Changes
- [24686]https://github.com/apache/superset/pull/24686): All dataset's custom explore_url are handled as relative URLs on the frontend, behaviour controlled by PREVENT_UNSAFE_DEFAULT_URLS_ON_DATASET.
- [24262](https://github.com/apache/superset/pull/24262): Enabled `TALISMAN_ENABLED` flag by default and provided stricter default Content Security Policy
- [24415](https://github.com/apache/superset/pull/24415): Removed the obsolete Druid NoSQL REGEX operator.
- [24423](https://github.com/apache/superset/pull/24423): Removed deprecated APIs `/superset/slice_json/...`, `/superset/annotation_json/...`
@@ -70,10 +88,16 @@ assists people when migrating to a new version.
- [23663](https://github.com/apache/superset/pull/23663): Removes deprecated feature flags `ALLOW_DASHBOARD_DOMAIN_SHARDING`, `DISPLAY_MARKDOWN_HTML`, and `FORCE_DATABASE_CONNECTIONS_SSL`.
- [22325](https://github.com/apache/superset/pull/22325): "RLS_FORM_QUERY_REL_FIELDS" is replaced by "RLS_BASE_RELATED_FIELD_FILTERS" feature flag. Its value format stays same.
### Potential Downtime
## 2.1.1
- [24185](https://github.com/apache/superset/pull/24185): `/api/v1/database/test_connection` and `api/v1/database/validate_parameters` permissions changed from `can_read` to `can_write`. Only Admin user's have access.
- [24256](https://github.com/apache/superset/pull/24256): `Flask-Login` session validation is now set to `strong` by default. Previous setting was `basic`.
### Other
- [24982](https://github.com/apache/superset/pull/24982): By default, physical datasets on Oracle-like dialects like Snowflake will now use denormalized column names. However, existing datasets won't be affected. To change this behavior, the "Advanced" section on the dataset modal has a "Normalize column names" flag which can be changed to change this behavior.
- [23888](https://github.com/apache/superset/pull/23888): Database Migration for json serialization instead of pickle should upgrade/downgrade correctly when bumping to/from this patch version
## 2.1.0
- [22809](https://github.com/apache/superset/pull/22809): Migrated endpoint `/superset/sql_json` and `/superset/results/` to `/api/v1/sqllab/execute/` and `/api/v1/sqllab/results/` respectively. Corresponding permissions are `can sql_json on Superset` to `can execute on SQLLab`, `can results on Superset` to `can results on SQLLab`. Make sure you add/replace the necessary permissions on any custom roles you may have.

View File

@@ -14,12 +14,12 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
x-superset-image: &superset-image apache/superset:${TAG:-latest-dev}
x-superset-image: &superset-image apachesuperset.docker.scarf.sh/apache/superset:${TAG:-latest-dev}
x-superset-depends-on: &superset-depends-on
- db
- redis
x-superset-volumes: &superset-volumes
# /app/pythonpath_docker will be appended to the PYTHONPATH in the final container
x-superset-volumes:
&superset-volumes # /app/pythonpath_docker will be appended to the PYTHONPATH in the final container
- ./docker:/app/docker
- superset_home:/app/superset_home
@@ -39,6 +39,7 @@ services:
restart: unless-stopped
volumes:
- db_home:/var/lib/postgresql/data
- ./docker/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
superset:
env_file: docker/.env-non-dev
@@ -73,7 +74,11 @@ services:
user: "root"
volumes: *superset-volumes
healthcheck:
test: ["CMD-SHELL", "celery -A superset.tasks.celery_app:app inspect ping -d celery@$$HOSTNAME"]
test:
[
"CMD-SHELL",
"celery -A superset.tasks.celery_app:app inspect ping -d celery@$$HOSTNAME",
]
superset-worker-beat:
image: *superset-image

View File

@@ -14,7 +14,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
x-superset-image: &superset-image apache/superset:${TAG:-latest-dev}
x-superset-image: &superset-image apachesuperset.docker.scarf.sh/apache/superset:${TAG:-latest-dev}
x-superset-user: &superset-user root
x-superset-depends-on: &superset-depends-on
- db
@@ -47,6 +47,7 @@ services:
- "127.0.0.1:5432:5432"
volumes:
- db_home:/var/lib/postgresql/data
- ./docker/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
superset:
env_file: docker/.env

View File

@@ -22,6 +22,12 @@ DATABASE_HOST=db
DATABASE_PASSWORD=superset
DATABASE_USER=superset
EXAMPLES_DB=examples
EXAMPLES_HOST=db
EXAMPLES_USER=examples
EXAMPLES_PASSWORD=examples
EXAMPLES_PORT=5432
# database engine specific environment variables
# change the below if you prefer another database engine
DATABASE_PORT=5432

View File

@@ -21,11 +21,17 @@ DATABASE_DB=superset
DATABASE_HOST=db
DATABASE_PASSWORD=superset
DATABASE_USER=superset
DATABASE_PORT=5432
DATABASE_DIALECT=postgresql
EXAMPLES_DB=examples
EXAMPLES_HOST=db
EXAMPLES_USER=examples
EXAMPLES_PASSWORD=examples
EXAMPLES_PORT=5432
# database engine specific environment variables
# change the below if you prefer another database engine
DATABASE_PORT=5432
DATABASE_DIALECT=postgresql
POSTGRES_DB=superset
POSTGRES_USER=superset
POSTGRES_PASSWORD=superset

View File

@@ -0,0 +1,15 @@
# ------------------------------------------------------------------------
# Creates the examples database and repective user. This database location
# and access credentials are defined on the environment variables
# ------------------------------------------------------------------------
set -e
psql -v ON_ERROR_STOP=1 --username "${POSTGRES_USER}" <<-EOSQL
CREATE USER ${EXAMPLES_USER} WITH PASSWORD '${EXAMPLES_PASSWORD}';
CREATE DATABASE ${EXAMPLES_DB};
GRANT ALL PRIVILEGES ON DATABASE ${EXAMPLES_DB} TO ${EXAMPLES_USER};
EOSQL
psql -v ON_ERROR_STOP=1 --username "${POSTGRES_USER}" -d "${EXAMPLES_DB}" <<-EOSQL
GRANT ALL ON SCHEMA public TO ${EXAMPLES_USER};
EOSQL

View File

@@ -22,49 +22,42 @@
#
import logging
import os
from typing import Optional
from cachelib.file import FileSystemCache
from celery.schedules import crontab
from flask_caching.backends.filesystemcache import FileSystemCache
logger = logging.getLogger()
DATABASE_DIALECT = os.getenv("DATABASE_DIALECT")
DATABASE_USER = os.getenv("DATABASE_USER")
DATABASE_PASSWORD = os.getenv("DATABASE_PASSWORD")
DATABASE_HOST = os.getenv("DATABASE_HOST")
DATABASE_PORT = os.getenv("DATABASE_PORT")
DATABASE_DB = os.getenv("DATABASE_DB")
def get_env_variable(var_name: str, default: Optional[str] = None) -> str:
"""Get the environment variable or raise exception."""
try:
return os.environ[var_name]
except KeyError:
if default is not None:
return default
else:
error_msg = "The environment variable {} was missing, abort...".format(
var_name
)
raise OSError(error_msg)
DATABASE_DIALECT = get_env_variable("DATABASE_DIALECT")
DATABASE_USER = get_env_variable("DATABASE_USER")
DATABASE_PASSWORD = get_env_variable("DATABASE_PASSWORD")
DATABASE_HOST = get_env_variable("DATABASE_HOST")
DATABASE_PORT = get_env_variable("DATABASE_PORT")
DATABASE_DB = get_env_variable("DATABASE_DB")
EXAMPLES_USER = os.getenv("EXAMPLES_USER")
EXAMPLES_PASSWORD = os.getenv("EXAMPLES_PASSWORD")
EXAMPLES_HOST = os.getenv("EXAMPLES_HOST")
EXAMPLES_PORT = os.getenv("EXAMPLES_PORT")
EXAMPLES_DB = os.getenv("EXAMPLES_DB")
# The SQLAlchemy connection string.
SQLALCHEMY_DATABASE_URI = "{}://{}:{}@{}:{}/{}".format(
DATABASE_DIALECT,
DATABASE_USER,
DATABASE_PASSWORD,
DATABASE_HOST,
DATABASE_PORT,
DATABASE_DB,
SQLALCHEMY_DATABASE_URI = (
f"{DATABASE_DIALECT}://"
f"{DATABASE_USER}:{DATABASE_PASSWORD}@"
f"{DATABASE_HOST}:{DATABASE_PORT}/{DATABASE_DB}"
)
REDIS_HOST = get_env_variable("REDIS_HOST")
REDIS_PORT = get_env_variable("REDIS_PORT")
REDIS_CELERY_DB = get_env_variable("REDIS_CELERY_DB", "0")
REDIS_RESULTS_DB = get_env_variable("REDIS_RESULTS_DB", "1")
SQLALCHEMY_EXAMPLES_URI = (
f"{DATABASE_DIALECT}://"
f"{EXAMPLES_USER}:{EXAMPLES_PASSWORD}@"
f"{EXAMPLES_HOST}:{EXAMPLES_PORT}/{EXAMPLES_DB}"
)
REDIS_HOST = os.getenv("REDIS_HOST", "redis")
REDIS_PORT = os.getenv("REDIS_PORT", "6379")
REDIS_CELERY_DB = os.getenv("REDIS_CELERY_DB", "0")
REDIS_RESULTS_DB = os.getenv("REDIS_RESULTS_DB", "1")
RESULTS_BACKEND = FileSystemCache("/app/superset_home/sqllab")

2
docs/.gitignore vendored
View File

@@ -18,3 +18,5 @@
npm-debug.log*
yarn-debug.log*
yarn-error.log*
docs/.zshrc

View File

@@ -15,6 +15,8 @@ The Superset project is always happy to review proposals for new high quality vi
plugins. However, for highly custom viz types it is recommended to maintain a fork
of Superset, and add the custom built viz plugins by hand.
**Note:** Additional community-generated resources about creating and deploying custom visualization plugins can be found on the [Superset Wiki](https://github.com/apache/superset/wiki/Community-Resource-Library#creating-custom-data-visualizations)
### Prerequisites
In order to create a new viz plugin, you need the following:

View File

@@ -10,13 +10,13 @@ version: 1
To use ClickHouse with Superset, you will need to add the following Python library:
```
clickhouse-connect>=0.4.1
clickhouse-connect>=0.6.8
```
If running Superset using Docker Compose, add the following to your `./docker/requirements-local.txt` file:
```
clickhouse-connect>=0.4.1
clickhouse-connect>=0.6.8
```
The recommended connector library for ClickHouse is

View File

@@ -22,46 +22,47 @@ as well as the packages needed to connect to the databases you want to access th
Some of the recommended packages are shown below. Please refer to [setup.py](https://github.com/apache/superset/blob/master/setup.py) for the versions that are compatible with Superset.
| Database | PyPI package | Connection String |
| --------------------------------------------------------- | ---------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| [Amazon Athena](/docs/databases/athena) | `pip install pyathena[pandas]` , `pip install PyAthenaJDBC` | `awsathena+rest://{aws_access_key_id}:{aws_secret_access_key}@athena.{region_name}.amazonaws.com/{ ` |
| [Amazon DynamoDB](/docs/databases/dynamodb) | `pip install pydynamodb` | `dynamodb://{access_key_id}:{secret_access_key}@dynamodb.{region_name}.amazonaws.com?connector=superset` |
| [Amazon Redshift](/docs/databases/redshift) | `pip install sqlalchemy-redshift` | ` redshift+psycopg2://<userName>:<DBPassword>@<AWS End Point>:5439/<Database Name>` |
| [Apache Drill](/docs/databases/drill) | `pip install sqlalchemy-drill` | `drill+sadrill:// For JDBC drill+jdbc://` |
| [Apache Druid](/docs/databases/druid) | `pip install pydruid` | `druid://<User>:<password>@<Host>:<Port-default-9088>/druid/v2/sql` |
| [Apache Hive](/docs/databases/hive) | `pip install pyhive` | `hive://hive@{hostname}:{port}/{database}` |
| [Apache Impala](/docs/databases/impala) | `pip install impyla` | `impala://{hostname}:{port}/{database}` |
| [Apache Kylin](/docs/databases/kylin) | `pip install kylinpy` | `kylin://<username>:<password>@<hostname>:<port>/<project>?<param1>=<value1>&<param2>=<value2>` |
| [Apache Pinot](/docs/databases/pinot) | `pip install pinotdb` | `pinot://BROKER:5436/query?server=http://CONTROLLER:5983/` |
| [Apache Solr](/docs/databases/solr) | `pip install sqlalchemy-solr` | `solr://{username}:{password}@{hostname}:{port}/{server_path}/{collection}` |
| [Apache Spark SQL](/docs/databases/spark-sql) | `pip install pyhive` | `hive://hive@{hostname}:{port}/{database}` |
| [Ascend.io](/docs/databases/ascend) | `pip install impyla` | `ascend://{username}:{password}@{hostname}:{port}/{database}?auth_mechanism=PLAIN;use_ssl=true` |
| [Azure MS SQL](/docs/databases/sql-server) | `pip install pymssql` | `mssql+pymssql://UserName@presetSQL:TestPassword@presetSQL.database.windows.net:1433/TestSchema` |
| [Big Query](/docs/databases/bigquery) | `pip install sqlalchemy-bigquery` | `bigquery://{project_id}` |
| [ClickHouse](/docs/databases/clickhouse) | `pip install clickhouse-connect` | `clickhousedb://{username}:{password}@{hostname}:{port}/{database}` |
| [CockroachDB](/docs/databases/cockroachdb) | `pip install cockroachdb` | `cockroachdb://root@{hostname}:{port}/{database}?sslmode=disable` |
| [Dremio](/docs/databases/dremio) | `pip install sqlalchemy_dremio` | `dremio://user:pwd@host:31010/` |
| [Elasticsearch](/docs/databases/elasticsearch) | `pip install elasticsearch-dbapi` | `elasticsearch+http://{user}:{password}@{host}:9200/` |
| [Exasol](/docs/databases/exasol) | `pip install sqlalchemy-exasol` | `exa+pyodbc://{username}:{password}@{hostname}:{port}/my_schema?CONNECTIONLCALL=en_US.UTF-8&driver=EXAODBC` |
| [Google Sheets](/docs/databases/google-sheets) | `pip install shillelagh[gsheetsapi]` | `gsheets://` |
| [Firebolt](/docs/databases/firebolt) | `pip install firebolt-sqlalchemy` | `firebolt://{username}:{password}@{database} or firebolt://{username}:{password}@{database}/{engine_name}` |
| [Hologres](/docs/databases/hologres) | `pip install psycopg2` | `postgresql+psycopg2://<UserName>:<DBPassword>@<Database Host>/<Database Name>` |
| [IBM Db2](/docs/databases/ibm-db2) | `pip install ibm_db_sa` | `db2+ibm_db://` |
| [IBM Netezza Performance Server](/docs/databases/netezza) | `pip install nzalchemy` | `netezza+nzpy://<UserName>:<DBPassword>@<Database Host>/<Database Name>` |
| [MySQL](/docs/databases/mysql) | `pip install mysqlclient` | `mysql://<UserName>:<DBPassword>@<Database Host>/<Database Name>` |
| [Oracle](/docs/databases/oracle) | `pip install cx_Oracle` | `oracle://` |
| [PostgreSQL](/docs/databases/postgres) | `pip install psycopg2` | `postgresql://<UserName>:<DBPassword>@<Database Host>/<Database Name>` |
| [Trino](/docs/databases/trino) | `pip install trino` | `trino://{username}:{password}@{hostname}:{port}/{catalog}` |
| [Presto](/docs/databases/presto) | `pip install pyhive` | `presto://` |
| [SAP Hana](/docs/databases/hana) | `pip install hdbcli sqlalchemy-hana or pip install apache-superset[hana]` | `hana://{username}:{password}@{host}:{port}` |
| [StarRocks](/docs/databases/starrocks) | `pip install starrocks` | `starrocks://<User>:<Password>@<Host>:<Port>/<Catalog>.<Database>` |
| [Snowflake](/docs/databases/snowflake) | `pip install snowflake-sqlalchemy` | `snowflake://{user}:{password}@{account}.{region}/{database}?role={role}&warehouse={warehouse}` |
| SQLite | No additional library needed | `sqlite://` |
| [SQL Server](/docs/databases/sql-server) | `pip install pymssql` | `mssql+pymssql://` |
| [Teradata](/docs/databases/teradata) | `pip install teradatasqlalchemy` | `teradatasql://{user}:{password}@{host}` |
| [TimescaleDB](/docs/databases/timescaledb) | `pip install psycopg2` | `postgresql://<UserName>:<DBPassword>@<Database Host>:<Port>/<Database Name>` |
| [Vertica](/docs/databases/vertica) | `pip install sqlalchemy-vertica-python` | `vertica+vertica_python://<UserName>:<DBPassword>@<Database Host>/<Database Name>` |
| [YugabyteDB](/docs/databases/yugabytedb) | `pip install psycopg2` | `postgresql://<UserName>:<DBPassword>@<Database Host>/<Database Name>` |
| Database | PyPI package | Connection String |
| --------------------------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| [Amazon Athena](/docs/databases/athena) | `pip install pyathena[pandas]` , `pip install PyAthenaJDBC` | `awsathena+rest://{aws_access_key_id}:{aws_secret_access_key}@athena.{region_name}.amazonaws.com/{ ` |
| [Amazon DynamoDB](/docs/databases/dynamodb) | `pip install pydynamodb` | `dynamodb://{access_key_id}:{secret_access_key}@dynamodb.{region_name}.amazonaws.com?connector=superset` |
| [Amazon Redshift](/docs/databases/redshift) | `pip install sqlalchemy-redshift` | ` redshift+psycopg2://<userName>:<DBPassword>@<AWS End Point>:5439/<Database Name>` |
| [Apache Drill](/docs/databases/drill) | `pip install sqlalchemy-drill` | `drill+sadrill:// For JDBC drill+jdbc://` |
| [Apache Druid](/docs/databases/druid) | `pip install pydruid` | `druid://<User>:<password>@<Host>:<Port-default-9088>/druid/v2/sql` |
| [Apache Hive](/docs/databases/hive) | `pip install pyhive` | `hive://hive@{hostname}:{port}/{database}` |
| [Apache Impala](/docs/databases/impala) | `pip install impyla` | `impala://{hostname}:{port}/{database}` |
| [Apache Kylin](/docs/databases/kylin) | `pip install kylinpy` | `kylin://<username>:<password>@<hostname>:<port>/<project>?<param1>=<value1>&<param2>=<value2>` |
| [Apache Pinot](/docs/databases/pinot) | `pip install pinotdb` | `pinot://BROKER:5436/query?server=http://CONTROLLER:5983/` |
| [Apache Solr](/docs/databases/solr) | `pip install sqlalchemy-solr` | `solr://{username}:{password}@{hostname}:{port}/{server_path}/{collection}` |
| [Apache Spark SQL](/docs/databases/spark-sql) | `pip install pyhive` | `hive://hive@{hostname}:{port}/{database}` |
| [Ascend.io](/docs/databases/ascend) | `pip install impyla` | `ascend://{username}:{password}@{hostname}:{port}/{database}?auth_mechanism=PLAIN;use_ssl=true` |
| [Azure MS SQL](/docs/databases/sql-server) | `pip install pymssql` | `mssql+pymssql://UserName@presetSQL:TestPassword@presetSQL.database.windows.net:1433/TestSchema` |
| [Big Query](/docs/databases/bigquery) | `pip install sqlalchemy-bigquery` | `bigquery://{project_id}` |
| [ClickHouse](/docs/databases/clickhouse) | `pip install clickhouse-connect` | `clickhousedb://{username}:{password}@{hostname}:{port}/{database}` |
| [CockroachDB](/docs/databases/cockroachdb) | `pip install cockroachdb` | `cockroachdb://root@{hostname}:{port}/{database}?sslmode=disable` |
| [Dremio](/docs/databases/dremio) | `pip install sqlalchemy_dremio` | `dremio://user:pwd@host:31010/` |
| [Elasticsearch](/docs/databases/elasticsearch) | `pip install elasticsearch-dbapi` | `elasticsearch+http://{user}:{password}@{host}:9200/` |
| [Exasol](/docs/databases/exasol) | `pip install sqlalchemy-exasol` | `exa+pyodbc://{username}:{password}@{hostname}:{port}/my_schema?CONNECTIONLCALL=en_US.UTF-8&driver=EXAODBC` |
| [Google Sheets](/docs/databases/google-sheets) | `pip install shillelagh[gsheetsapi]` | `gsheets://` |
| [Firebolt](/docs/databases/firebolt) | `pip install firebolt-sqlalchemy` | `firebolt://{username}:{password}@{database} or firebolt://{username}:{password}@{database}/{engine_name}` |
| [Hologres](/docs/databases/hologres) | `pip install psycopg2` | `postgresql+psycopg2://<UserName>:<DBPassword>@<Database Host>/<Database Name>` |
| [IBM Db2](/docs/databases/ibm-db2) | `pip install ibm_db_sa` | `db2+ibm_db://` |
| [IBM Netezza Performance Server](/docs/databases/netezza) | `pip install nzalchemy` | `netezza+nzpy://<UserName>:<DBPassword>@<Database Host>/<Database Name>` |
| [MySQL](/docs/databases/mysql) | `pip install mysqlclient` | `mysql://<UserName>:<DBPassword>@<Database Host>/<Database Name>` |
| [Oracle](/docs/databases/oracle) | `pip install cx_Oracle` | `oracle://` |
| [PostgreSQL](/docs/databases/postgres) | `pip install psycopg2` | `postgresql://<UserName>:<DBPassword>@<Database Host>/<Database Name>` |
| [Trino](/docs/databases/trino) | `pip install trino` | `trino://{username}:{password}@{hostname}:{port}/{catalog}` |
| [Presto](/docs/databases/presto) | `pip install pyhive` | `presto://` |
| [SAP Hana](/docs/databases/hana) | `pip install hdbcli sqlalchemy-hana or pip install apache-superset[hana]` | `hana://{username}:{password}@{host}:{port}` |
| [StarRocks](/docs/databases/starrocks) | `pip install starrocks` | `starrocks://<User>:<Password>@<Host>:<Port>/<Catalog>.<Database>` |
| [Snowflake](/docs/databases/snowflake) | `pip install snowflake-sqlalchemy` | `snowflake://{user}:{password}@{account}.{region}/{database}?role={role}&warehouse={warehouse}` |
| SQLite | No additional library needed | `sqlite://path/to/file.db?check_same_thread=false` |
| [SQL Server](/docs/databases/sql-server) | `pip install pymssql` | `mssql+pymssql://` |
| [Teradata](/docs/databases/teradata) | `pip install teradatasqlalchemy` | `teradatasql://{user}:{password}@{host}` |
| [TimescaleDB](/docs/databases/timescaledb) | `pip install psycopg2` | `postgresql://<UserName>:<DBPassword>@<Database Host>:<Port>/<Database Name>` |
| [Vertica](/docs/databases/vertica) | `pip install sqlalchemy-vertica-python` | `vertica+vertica_python://<UserName>:<DBPassword>@<Database Host>/<Database Name>` |
| [YugabyteDB](/docs/databases/yugabytedb) | `pip install psycopg2` | `postgresql://<UserName>:<DBPassword>@<Database Host>/<Database Name>` |
---
Note that many other databases are supported, the main criteria being the existence of a functional

View File

@@ -168,7 +168,7 @@ Another workaround is to change where superset stores the sqlite database by add
`superset_config.py`:
```
SQLALCHEMY_DATABASE_URI = 'sqlite:////new/location/superset.db'
SQLALCHEMY_DATABASE_URI = 'sqlite:////new/location/superset.db?check_same_thread=false'
```
You can read more about customizing Superset using the configuration file
@@ -282,3 +282,9 @@ guarantees and are not recommended but may fit your use case temporarily:
In the Edit Dataset view, you can specify a time offset. This field lets you configure the
number of hours to be added or subtracted from the time column.
This can be used, for example, to convert UTC time to local time.
### Does Superset collect any telemetry data?
Superset uses [Scarf](https://about.scarf.sh/) by default to collect basic telemetry data upon installing and/or running Superset. This data helps the maintainers of Superset better understand which versions of Superset are being used, in order to prioritize patch/minor releases and security fixes.
We use the [Scarf Gateway](https://docs.scarf.sh/gateway/) to sit in front of container registries, and the [scarf-js](https://about.scarf.sh/package-sdks) package to track `npm` installations.
Scarf purges PII and provides aggregated statistics. Superset users can easily opt out of analytics in various ways documented [here](https://docs.scarf.sh/gateway/#do-not-track) and [here](https://docs.scarf.sh/package-analytics/#as-a-user-of-a-package-using-scarf-js-how-can-i-opt-out-of-analytics). Additional opt-out instructions for Docker users are available on the [Docker Installation](https://superset.apache.org/docs/installation/installing-superset-using-docker-compose) page.

View File

@@ -66,7 +66,7 @@ celery --app=superset.tasks.celery_app:app beat
```
To setup a result backend, you need to pass an instance of a derivative of from
cachelib.base.BaseCache to the RESULTS_BACKEND configuration key in your superset_config.py. You can
from flask_caching.backends.base import BaseCache to the RESULTS_BACKEND configuration key in your superset_config.py. You can
use Memcached, Redis, S3 (https://pypi.python.org/pypi/s3werkzeugcache), memory or the file system
(in a single server-type setup or for testing), or to write your own caching interface. Your
`superset_config.py` may look something like:
@@ -79,7 +79,7 @@ S3_CACHE_KEY_PREFIX = 'sql_lab_result'
RESULTS_BACKEND = S3Cache(S3_CACHE_BUCKET, S3_CACHE_KEY_PREFIX)
# On Redis
from cachelib.redis import RedisCache
from flask_caching.backends.rediscache import RedisCache
RESULTS_BACKEND = RedisCache(
host='localhost', port=6379, key_prefix='superset_results')
```

View File

@@ -13,6 +13,7 @@ To configure your application, you need to create a file `superset_config.py` an
`PYTHONPATH`. If your application was installed using docker-compose an alternative configuration is required. See [https://github.com/apache/superset/tree/master/docker#readme](https://github.com/apache/superset/tree/master/docker#readme) for details.
The following is an example of just a few of the parameters you can set in your `superset_config.py` file:
```
# Superset specific config
ROW_LIMIT = 5000
@@ -31,7 +32,9 @@ SECRET_KEY = 'YOUR_OWN_RANDOM_GENERATED_SECRET_KEY'
# superset metadata (slices, connections, tables, dashboards, ...).
# Note that the connection information to connect to the datasources
# you want to explore are managed directly in the web UI
SQLALCHEMY_DATABASE_URI = 'sqlite:////path/to/superset.db'
# The check_same_thread=false property ensures the sqlite client does not attempt
# to enforce single-threaded access, which may be problematic in some edge cases
SQLALCHEMY_DATABASE_URI = 'sqlite:////path/to/superset.db?check_same_thread=false'
# Flask-WTF flag for CSRF
WTF_CSRF_ENABLED = True
@@ -72,7 +75,7 @@ WTF_CSRF_EXEMPT_LIST = []
#### Adding an initial SECRET_KEY
Superset requires a user-specified SECRET_KEY to start up. This requirement was [added in version 2.1.0 to force secure configurations](https://preset.io/blog/superset-security-update-default-secret_key-vulnerability/). Add a strong SECRET_KEY to your `superset_config.py` file like:
Superset requires a user-specified SECRET_KEY to start up. This requirement was [added in version 2.1.0 to force secure configurations](https://preset.io/blog/superset-security-update-default-secret_key-vulnerability/). Add a strong SECRET_KEY to your `superset_config.py` file like:
```python
SECRET_KEY = 'YOUR_OWN_RANDOM_GENERATED_SECRET_KEY'
@@ -83,7 +86,7 @@ You can generate a strong secure key with `openssl rand -base64 42`.
#### Rotating to a newer SECRET_KEY
If you wish to change your existing SECRET_KEY, add the existing SECRET_KEY to your `superset_config.py` file as
`PREVIOUS_SECRET_KEY = `and provide your new key as `SECRET_KEY =`. You can find your current SECRET_KEY with these
`PREVIOUS_SECRET_KEY = `and provide your new key as `SECRET_KEY =`. You can find your current SECRET_KEY with these
commands - if running Superset with Docker, execute from within the Superset application container:
```python
@@ -103,23 +106,21 @@ database engine on a separate host or container.
Superset supports the following database engines/versions:
| Database Engine | Supported Versions |
| --------------------------------------------------------- | --------------------------------- |
| [PostgreSQL](https://www.postgresql.org/) | 10.X, 11.X, 12.X, 13.X, 14.X |
| [MySQL](https://www.mysql.com/) | 5.X |
| Database Engine | Supported Versions |
| ----------------------------------------- | ---------------------------------- |
| [PostgreSQL](https://www.postgresql.org/) | 10.X, 11.X, 12.X, 13.X, 14.X, 15.X |
| [MySQL](https://www.mysql.com/) | 5.7, 8.X |
Use the following database drivers and connection strings:
| Database | PyPI package | Connection String |
| ----------------------------------------- | --------------------------------- | ------------------------------------------------------------------------ |
| [PostgreSQL](https://www.postgresql.org/) | `pip install psycopg2` | `postgresql://<UserName>:<DBPassword>@<Database Host>/<Database Name>` |
| [MySQL](https://www.mysql.com/) | `pip install mysqlclient` | `mysql://<UserName>:<DBPassword>@<Database Host>/<Database Name>` |
| Database | PyPI package | Connection String |
| ----------------------------------------- | ------------------------- | ---------------------------------------------------------------------- |
| [PostgreSQL](https://www.postgresql.org/) | `pip install psycopg2` | `postgresql://<UserName>:<DBPassword>@<Database Host>/<Database Name>` |
| [MySQL](https://www.mysql.com/) | `pip install mysqlclient` | `mysql://<UserName>:<DBPassword>@<Database Host>/<Database Name>` |
To configure Superset metastore set `SQLALCHEMY_DATABASE_URI` config key on `superset_config`
to the appropriate connection string.
### Running on a WSGI HTTP Server
While you can run Superset on NGINX or Apache, we recommend using Gunicorn in async mode. This

View File

@@ -96,7 +96,14 @@ You can configure the Docker Compose environment varirables for dev and non-dev
One important variable is `SUPERSET_LOAD_EXAMPLES` which determines whether the `superset_init` container will load example data and visualizations into the database and Superset. These examples are quite helpful for most people, but probably unnecessary for experienced users. The loading process can sometimes take a few minutes and a good amount of CPU, so you may want to disable it on a resource-constrained device.
**Note:** Users often want to connect to other databases from Superset. Currently, the easiest way to do this is to modify the `docker-compose-non-dev.yml` file and add your database as a service that the other services depend on (via `x-superset-depends-on`). Others have attempted to set `network_mode: host` on the Superset services, but these generally break the installation, because the configuration requires use of the Docker Compose DNS resolver for the service names. If you have a good solution for this, let us know!
:::note
Users often want to connect to other databases from Superset. Currently, the easiest way to do this is to modify the `docker-compose-non-dev.yml` file and add your database as a service that the other services depend on (via `x-superset-depends-on`). Others have attempted to set `network_mode: host` on the Superset services, but these generally break the installation, because the configuration requires use of the Docker Compose DNS resolver for the service names. If you have a good solution for this, let us know!
:::
:::note
Superset uses [Scarf Gateway](https://about.scarf.sh/scarf-gateway) to collect telmetry data to better understand and support the need for patch versions of Sueprset. Scarf purges PII and provides aggregated statistics. Superset users can easily opt out of analytics in various ways documented [here](https://docs.scarf.sh/gateway/#do-not-track). However, if you wish to opt-out of this in your Docker-based installation, you can simply edit your `docker-compose.yml` or `docker-compose-non-dev.yml` file and remove `apachesuperset.docker.scarf.sh/` from the `x-superset-image` setting, so that it's simply pulling `apache/superset:${TAG:-latest-dev}`
:::
### 4. Log in to Superset

View File

@@ -121,6 +121,10 @@ init:
. {{ .Values.configMountPath }}/superset_init.sh
```
:::note
Superset uses [Scarf Gateway](https://about.scarf.sh/scarf-gateway) to collect telmetry data to better understand and support the need for patch versions of Sueprset. Scarf purges PII and provides aggregated statistics. Superset users can easily opt out of analytics in various ways documented [here](https://docs.scarf.sh/gateway/#do-not-track). However, if you wish to opt-out of this in your Helm-based installation, you can simply edit your `helm/superset/values.yaml` file and remove `apachesuperset.docker.scarf.sh/` from the `repository` field, so that it's simply pulling `apache/superset`
:::
#### Dependencies
Install additional packages and do any other bootstrap configuration in the bootstrap script.

View File

@@ -0,0 +1,4 @@
{
"label": "Security",
"position": 10
}

View File

@@ -0,0 +1,27 @@
---
title: CVEs by release
hide_title: true
sidebar_position: 2
---
#### Version 2.1.0
| CVE | Title | Affected |
| :------------- | :---------------------------------------------------------------------- | -----------------:|
| CVE-2023-25504 | Possible SSRF on import datasets | <= 2.1.0 |
| CVE-2023-27524 | Session validation vulnerability when using provided default SECRET_KEY | <= 2.1.0 |
| CVE-2023-27525 | Incorrect default permissions for Gamma role | <= 2.1.0 |
| CVE-2023-30776 | Database connection password leak | <= 2.1.0 |
#### Version 2.0.1
| CVE | Title | Affected |
| :------------- | :---------------------------------------------------------- | -----------------:|
| CVE-2022-41703 | SQL injection vulnerability in adhoc clauses | < 2.0.1 or <1.5.2 |
| CVE-2022-43717 | Cross-Site Scripting on dashboards | < 2.0.1 or <1.5.2 |
| CVE-2022-43718 | Cross-Site Scripting vulnerability on upload forms | < 2.0.1 or <1.5.2 |
| CVE-2022-43719 | Cross Site Request Forgery (CSRF) on accept, request access | < 2.0.1 or <1.5.2 |
| CVE-2022-43720 | Improper rendering of user input | < 2.0.1 or <1.5.2 |
| CVE-2022-43721 | Open Redirect Vulnerability | < 2.0.1 or <1.5.2 |
| CVE-2022-45438 | Dashboard metadata information leak | < 2.0.1 or <1.5.2 |

View File

@@ -1,7 +1,7 @@
---
title: Security
title: Role based Access
hide_title: true
sidebar_position: 10
sidebar_position: 1
---
### Roles

View File

@@ -68,7 +68,7 @@ const config = {
from: '/usertutorial.html',
},
{
to: '/docs/security',
to: '/docs/security/',
from: '/security.html',
},
{

File diff suppressed because it is too large Load Diff

View File

@@ -15,7 +15,7 @@
# limitations under the License.
#
apiVersion: v2
appVersion: "2.1.0"
appVersion: "3.0.3"
description: Apache Superset is a modern, enterprise-ready business intelligence web application
name: superset
icon: https://artifacthub.io/image/68c1d717-0e97-491f-b046-754e46f46922@2x
@@ -29,7 +29,7 @@ maintainers:
- name: craig-rueda
email: craig@craigrueda.com
url: https://github.com/craig-rueda
version: 0.10.3
version: 0.11.2
dependencies:
- name: postgresql
version: 12.1.6

View File

@@ -23,7 +23,7 @@ NOTE: This file is generated by helm-docs: https://github.com/norwoodj/helm-docs
# superset
![Version: 0.10.3](https://img.shields.io/badge/Version-0.10.3-informational?style=flat-square)
![Version: 0.11.2](https://img.shields.io/badge/Version-0.11.2-informational?style=flat-square)
Apache Superset is a modern, enterprise-ready business intelligence web application
@@ -40,6 +40,12 @@ helm repo add superset http://apache.github.io/superset/
helm install my-superset superset/superset
```
Make sure you set your own `SECRET_KEY` to something unique and secret. This secret key is used by Flask for
securely signing the session cookie and will be used to encrypt sensitive data on Superset's metadata database.
It should be a long random bytes or str.
On helm this can be set on `extraSecretEnv.SUPERSET_SECRET_KEY` or `configOverrides.secrets`
## Requirements
| Repository | Name | Version |
@@ -70,7 +76,7 @@ helm install my-superset superset/superset
| fullnameOverride | string | `nil` | Provide a name to override the full names of resources |
| hostAliases | list | `[]` | Custom hostAliases for all superset pods # https://kubernetes.io/docs/tasks/network/customize-hosts-file-for-pods/ |
| image.pullPolicy | string | `"IfNotPresent"` | |
| image.repository | string | `"apache/superset"` | |
| image.repository | string | `"apachesuperset.docker.scarf.sh/apache/superset"` | |
| image.tag | string | `""` | |
| imagePullSecrets | list | `[]` | |
| ingress.annotations | object | `{}` | |

View File

@@ -39,6 +39,12 @@ helm repo add superset http://apache.github.io/superset/
helm install my-superset superset/superset
```
Make sure you set your own `SECRET_KEY` to something unique and secret. This secret key is used by Flask for
securely signing the session cookie and will be used to encrypt sensitive data on Superset's metadata database.
It should be a long random bytes or str.
On helm this can be set on `extraSecretEnv.SUPERSET_SECRET_KEY` or `configOverrides.secrets`
{{ template "chart.requirementsSection" . }}
{{ template "chart.valuesSection" . }}

View File

@@ -63,7 +63,7 @@ Create chart name and version as used by the chart label.
{{- define "superset-config" }}
import os
from cachelib.redis import RedisCache
from flask_caching.backends.rediscache import RedisCache
def env(key, default=None):
return os.getenv(key, default)
@@ -82,7 +82,6 @@ DATA_CACHE_CONFIG = CACHE_CONFIG
SQLALCHEMY_DATABASE_URI = f"postgresql+psycopg2://{env('DB_USER')}:{env('DB_PASS')}@{env('DB_HOST')}:{env('DB_PORT')}/{env('DB_NAME')}"
SQLALCHEMY_TRACK_MODIFICATIONS = True
SECRET_KEY = env('SECRET_KEY', 'thisISaSECRET_1234')
class CeleryConfig(object):
CELERY_IMPORTS = ('superset.sql_lab', )

View File

@@ -42,6 +42,7 @@ spec:
metadata:
annotations:
checksum/superset_config.py: {{ include "superset-config" . | sha256sum }}
checksum/superset_bootstrap.sh: {{ tpl .Values.bootstrapScript . | sha256sum }}
checksum/connections: {{ .Values.supersetNode.connections | toYaml | sha256sum }}
checksum/extraConfigs: {{ .Values.extraConfigs | toYaml | sha256sum }}
checksum/extraSecrets: {{ .Values.extraSecrets | toYaml | sha256sum }}

View File

@@ -46,6 +46,7 @@ spec:
metadata:
annotations:
checksum/superset_config.py: {{ include "superset-config" . | sha256sum }}
checksum/superset_bootstrap.sh: {{ tpl .Values.bootstrapScript . | sha256sum }}
checksum/connections: {{ .Values.supersetNode.connections | toYaml | sha256sum }}
checksum/extraConfigs: {{ .Values.extraConfigs | toYaml | sha256sum }}
checksum/extraSecrets: {{ .Values.extraSecrets | toYaml | sha256sum }}

View File

@@ -63,7 +63,7 @@ spec:
name: {{ tpl .Values.envFromSecret . }}
{{- range .Values.envFromSecrets }}
- secretRef:
name: {{ tpl . $ }}
name: {{ tpl . $ | quote }}
{{- end }}
imagePullPolicy: {{ .Values.image.pullPolicy }}
{{- if .Values.init.containerSecurityContext }}

View File

@@ -93,6 +93,8 @@ extraSecretEnv: {}
# # Google API Keys: https://console.cloud.google.com/apis/credentials
# GOOGLE_KEY: ...
# GOOGLE_SECRET: ...
# # Generate your own secret key for encryption. Use openssl rand -base64 42 to generate a good key
# SUPERSET_SECRET_KEY: 'CHANGE_ME_TO_A_COMPLEX_RANDOM_SECRET'
# -- Extra files to mount on `/app/pythonpath`
extraConfigs: {}
@@ -176,7 +178,7 @@ configMountPath: "/app/pythonpath"
extraConfigMountPath: "/app/configs"
image:
repository: apache/superset
repository: apachesuperset.docker.scarf.sh/apache/superset
tag: ""
pullPolicy: IfNotPresent

View File

@@ -27,8 +27,9 @@ billiard==3.6.4.0
# via celery
brotli==1.0.9
# via flask-compress
cachelib==0.4.1
# via apache-superset
cachelib==0.9.0
# via
# flask-caching
celery==5.2.2
# via apache-superset
cffi==1.15.1
@@ -88,11 +89,11 @@ flask==2.2.5
# flask-migrate
# flask-sqlalchemy
# flask-wtf
flask-appbuilder==4.3.3
flask-appbuilder==4.3.10
# via apache-superset
flask-babel==1.0.0
# via flask-appbuilder
flask-caching==1.10.1
flask-caching==2.1.0
# via apache-superset
flask-compress==1.13
# via apache-superset
@@ -112,7 +113,7 @@ flask-sqlalchemy==2.5.1
# flask-migrate
flask-talisman==1.0.0
# via apache-superset
flask-wtf==1.0.1
flask-wtf==1.1.1
# via
# apache-superset
# flask-appbuilder
@@ -126,7 +127,7 @@ gunicorn==20.1.0
# via apache-superset
hashids==1.3.1
# via apache-superset
hijri-converter==2.2.4
hijri-converter==2.3.1
# via holidays
holidays==0.23
# via apache-superset
@@ -135,9 +136,7 @@ humanize==3.11.0
idna==3.2
# via email-validator
importlib-metadata==6.6.0
# via
# apache-superset
# flask
# via apache-superset
importlib-resources==5.12.0
# via limits
isodate==0.6.0
@@ -154,7 +153,7 @@ jsonschema==4.17.3
# via flask-appbuilder
kombu==5.2.4
# via celery
korean-lunar-calendar==0.2.1
korean-lunar-calendar==0.3.1
# via holidays
limits==3.4.0
# via flask-limiter
@@ -212,7 +211,7 @@ prison==0.2.1
# via flask-appbuilder
prompt-toolkit==3.0.38
# via click-repl
pyarrow==12.0.0
pyarrow==14.0.1
# via apache-superset
pycparser==2.20
# via cffi
@@ -223,7 +222,7 @@ pyjwt==2.4.0
# apache-superset
# flask-appbuilder
# flask-jwt-extended
pymeeus==0.5.11
pymeeus==0.5.12
# via convertdate
pynacl==1.5.0
# via paramiko
@@ -251,7 +250,7 @@ pytz==2021.3
# celery
# flask-babel
# pandas
pyyaml==5.4.1
pyyaml==6.0.1
# via
# apache-superset
# apispec
@@ -311,6 +310,7 @@ werkzeug==2.3.3
# via
# apache-superset
# flask
# flask-appbuilder
# flask-jwt-extended
# flask-login
wrapt==1.12.1
@@ -326,9 +326,7 @@ wtforms-json==0.3.5
xlsxwriter==3.0.7
# via apache-superset
zipp==3.15.0
# via
# importlib-metadata
# importlib-resources
# via importlib-metadata
# The following packages are considered to be unsafe in a requirements file:
# setuptools

View File

@@ -10,6 +10,8 @@
# via
# -r requirements/base.in
# -r requirements/development.in
appnope==0.1.3
# via ipython
astroid==2.6.6
# via pylint
asttokens==2.2.1

View File

@@ -38,11 +38,11 @@ pip-compile-multi==2.6.3
# via -r integration.in
pip-tools==6.13.0
# via pip-compile-multi
platformdirs==3.5.3
platformdirs==3.8.1
# via
# tox
# virtualenv
pluggy==1.0.0
pluggy==1.2.0
# via tox
pre-commit==3.3.3
# via -r integration.in
@@ -50,12 +50,12 @@ pyproject-api==1.5.2
# via tox
pyproject-hooks==1.0.0
# via build
pyyaml==5.4.1
pyyaml==6.0.1
# via pre-commit
toposort==1.10
# via pip-compile-multi
tox==4.6.3
# via -r integration.in
tox==4.6.4
# via -r requirements/integration.in
virtualenv==20.23.1
# via
# pre-commit

View File

@@ -16,7 +16,7 @@
#
-r development.in
-r integration.in
-e file:.[bigquery,hive,presto,trino]
-e file:.[bigquery,hive,presto,prophet,trino]
docker
flask-testing
freezegun

View File

@@ -1,4 +1,4 @@
# SHA1:623feb0dd2b6bd376238ecf75069bc82136c2d70
# SHA1:78fe89f88adf34ac75513d363d7d9d0b5cc8cd1c
#
# This file is autogenerated by pip-compile-multi
# To update, run:
@@ -12,16 +12,26 @@
# -r requirements/base.in
# -r requirements/development.in
# -r requirements/testing.in
cmdstanpy==1.1.0
# via prophet
contourpy==1.0.7
# via matplotlib
coverage[toml]==7.2.5
# via pytest-cov
cycler==0.11.0
# via matplotlib
db-dtypes==1.1.1
# via pandas-gbq
docker==6.1.1
# via -r requirements/testing.in
ephem==4.1.4
# via lunarcalendar
exceptiongroup==1.1.1
# via pytest
flask-testing==0.8.1
# via -r requirements/testing.in
fonttools==4.39.4
# via matplotlib
freezegun==1.2.2
# via -r requirements/testing.in
google-api-core[grpc]==2.11.0
@@ -73,6 +83,12 @@ iniconfig==2.0.0
# via pytest
jsonschema-spec==0.1.4
# via openapi-spec-validator
kiwisolver==1.4.4
# via matplotlib
lunarcalendar==0.0.9
# via prophet
matplotlib==3.7.1
# via prophet
oauthlib==3.2.2
# via requests-oauthlib
openapi-schema-validator==0.4.4
@@ -85,6 +101,8 @@ parameterized==0.9.0
# via -r requirements/testing.in
pathable==0.4.3
# via jsonschema-spec
prophet==1.1.1
# via apache-superset
proto-plus==1.22.2
# via
# google-cloud-bigquery
@@ -97,12 +115,6 @@ protobuf==4.23.0
# googleapis-common-protos
# grpcio-status
# proto-plus
pyasn1==0.5.0
# via
# pyasn1-modules
# rsa
pyasn1-modules==0.3.0
# via google-auth
pydata-google-auth==1.7.0
# via pandas-gbq
pyfakefs==5.2.2
@@ -126,10 +138,16 @@ rfc3339-validator==0.1.4
# via openapi-schema-validator
rsa==4.9
# via google-auth
setuptools-git==1.2
# via prophet
sqlalchemy-bigquery==1.6.1
# via apache-superset
statsd==4.0.1
# via -r requirements/testing.in
tqdm==4.65.0
# via
# cmdstanpy
# prophet
trino==0.324.0
# via apache-superset
tzdata==2023.3

View File

@@ -30,7 +30,7 @@ combine_as_imports = true
include_trailing_comma = true
line_length = 88
known_first_party = superset
known_third_party =alembic,apispec,backoff,cachelib,celery,click,colorama,cron_descriptor,croniter,cryptography,dateutil,deprecation,flask,flask_appbuilder,flask_babel,flask_caching,flask_compress,flask_jwt_extended,flask_login,flask_migrate,flask_sqlalchemy,flask_talisman,flask_testing,flask_wtf,freezegun,geohash,geopy,holidays,humanize,isodate,jinja2,jwt,markdown,markupsafe,marshmallow,msgpack,nh3,numpy,pandas,parameterized,parsedatetime,pgsanity,pkg_resources,polyline,prison,progress,pyarrow,sqlalchemy_bigquery,pyhive,pyparsing,pytest,pytest_mock,pytz,redis,requests,selenium,setuptools,simplejson,slack,sqlalchemy,sqlalchemy_utils,sqlparse,typing_extensions,urllib3,werkzeug,wtforms,wtforms_json,yaml
known_third_party =alembic,apispec,backoff,celery,click,colorama,cron_descriptor,croniter,cryptography,dateutil,deprecation,flask,flask_appbuilder,flask_babel,flask_caching,flask_compress,flask_jwt_extended,flask_login,flask_migrate,flask_sqlalchemy,flask_talisman,flask_testing,flask_wtf,freezegun,geohash,geopy,holidays,humanize,isodate,jinja2,jwt,markdown,markupsafe,marshmallow,msgpack,nh3,numpy,pandas,parameterized,parsedatetime,pgsanity,pkg_resources,polyline,prison,progress,pyarrow,sqlalchemy_bigquery,pyhive,pyparsing,pytest,pytest_mock,pytz,redis,requests,selenium,setuptools,simplejson,slack,sqlalchemy,sqlalchemy_utils,sqlparse,typing_extensions,urllib3,werkzeug,wtforms,wtforms_json,yaml
multi_line_output = 3
order_by_type = false

View File

@@ -71,7 +71,6 @@ setup(
},
install_requires=[
"backoff>=1.8.0",
"cachelib>=0.4.1,<0.5",
"celery>=5.2.2, <6.0.0",
"click>=8.0.3",
"click-option-group",
@@ -81,13 +80,13 @@ setup(
"cryptography>=39.0.1, <40",
"deprecation>=2.1.0, <2.2.0",
"flask>=2.2.5, <3.0.0",
"flask-appbuilder>=4.3.3, <5.0.0",
"flask-caching>=1.10.1, <1.11",
"flask-appbuilder>=4.3.10, <5.0.0",
"flask-caching>=2.1.0, <3",
"flask-compress>=1.13, <2.0",
"flask-talisman>=1.0.0, <2.0",
"flask-login==0.6.0",
"flask-login>=0.6.0, < 1.0",
"flask-migrate>=3.1.0, <4.0",
"flask-wtf>=1.0.1, <1.1",
"flask-wtf>=1.1.0, <2.0",
"func_timeout",
"geopy",
"gunicorn>=20.1.0; sys_platform != 'win32'",
@@ -110,8 +109,8 @@ setup(
"python-dateutil",
"python-dotenv",
"python-geohash",
"pyarrow>=12.0.0, <13",
"pyyaml>=5.4",
"pyarrow>=14.0.1, <15",
"pyyaml>=6.0.0, <7.0.0",
"PyJWT>=2.4.0, <3.0",
"redis>=4.5.4, <5.0",
"selenium>=3.141.0, <4.10.0",
@@ -167,7 +166,7 @@ setup(
"mysql": ["mysqlclient>=2.1.0, <3"],
"ocient": [
"sqlalchemy-ocient>=1.0.0",
"pyocient>=1.0.15",
"pyocient>=1.0.15, <2",
"shapely",
"geojson",
],
@@ -176,7 +175,7 @@ setup(
"postgres": ["psycopg2-binary==2.9.6"],
"presto": ["pyhive[presto]>=0.6.5"],
"trino": ["trino>=0.324.0"],
"prophet": ["prophet>=1.0.1, <1.1", "pystan<3.0"],
"prophet": ["prophet==1.1.1"],
"redshift": ["sqlalchemy-redshift>=0.8.1, < 0.9"],
"rockset": ["rockset>=0.8.10, <0.9"],
"shillelagh": [
@@ -185,7 +184,7 @@ setup(
"snowflake": ["snowflake-sqlalchemy>=1.2.4, <2"],
"spark": ["pyhive[hive]>=0.6.5", "tableschema", "thrift>=0.14.1, <1.0.0"],
"teradata": ["teradatasql>=16.20.0.23"],
"thumbnails": ["Pillow>=9.5.0, <10.0.0"],
"thumbnails": ["Pillow>=10.0.1, <11"],
"vertica": ["sqlalchemy-vertica-python>=0.5.9, < 0.6"],
"netezza": ["nzalchemy>=11.0.2"],
"starrocks": ["starrocks>=1.0.0"],

View File

@@ -1,12 +1,12 @@
{
"name": "@superset-ui/embedded-sdk",
"version": "0.1.0-alpha.9",
"version": "0.1.0-alpha.10",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@superset-ui/embedded-sdk",
"version": "0.1.0-alpha.9",
"version": "0.1.0-alpha.10",
"license": "Apache-2.0",
"dependencies": {
"@superset-ui/switchboard": "^0.18.26-0",

View File

@@ -1,6 +1,6 @@
{
"name": "@superset-ui/embedded-sdk",
"version": "0.1.0-alpha.9",
"version": "0.1.0-alpha.10",
"description": "SDK for embedding resources from Superset into your own application",
"access": "public",
"keywords": [

View File

@@ -89,6 +89,10 @@ export async function embedDashboard({
log('embedding');
if (supersetDomain.endsWith("/")) {
supersetDomain = supersetDomain.slice(0, -1);
}
function calculateConfig() {
let configNumber = 0
if(dashboardUiConfig) {

View File

@@ -38,6 +38,23 @@ export default defineConfig({
// We've imported your old cypress plugins here.
// You may want to clean this up later by importing these.
setupNodeEvents(on, config) {
// ECONNRESET on Chrome/Chromium 117.0.5851.0 when using Cypress <12.15.0
// Check https://github.com/cypress-io/cypress/issues/27804 for context
// TODO: This workaround should be removed when upgrading Cypress
on('before:browser:launch', (browser, launchOptions) => {
if (browser.name === 'chrome' && browser.isHeadless) {
// eslint-disable-next-line no-param-reassign
launchOptions.args = launchOptions.args.map(arg => {
if (arg === '--headless') {
return '--headless=new';
}
return arg;
});
}
return launchOptions;
});
// eslint-disable-next-line global-require,import/extensions
return require('./cypress/plugins/index.js')(on, config);
},

View File

@@ -422,17 +422,17 @@ describe('Dashboard edit', () => {
'[data-test-chart-name="Top 10 California Names Timeseries"] .line .nv-legend-symbol',
)
.first()
.should('have.css', 'fill', 'rgb(252, 199, 0)');
.should('have.css', 'fill', 'rgb(69, 78, 124)');
cy.get(
'[data-test-chart-name="Top 10 California Names Timeseries"] .line .nv-legend-symbol',
)
.eq(1)
.should('have.css', 'fill', 'rgb(143, 211, 228)');
.should('have.css', 'fill', 'rgb(224, 67, 85)');
cy.get(
'[data-test-chart-name="Top 10 California Names Timeseries"] .line .nv-legend-symbol',
)
.eq(2)
.should('have.css', 'fill', 'rgb(172, 225, 196)');
.should('have.css', 'fill', 'rgb(163, 143, 121)');
});
it('should show the same colors in Explore', () => {
@@ -463,7 +463,7 @@ describe('Dashboard edit', () => {
'[data-test-chart-name="Top 10 California Names Timeseries"] .line .nv-legend-symbol',
)
.eq(1)
.should('have.css', 'fill', 'rgb(51, 61, 71)');
.should('have.css', 'fill', 'rgb(172, 32, 119)');
openExplore('Top 10 California Names Timeseries');
@@ -474,7 +474,7 @@ describe('Dashboard edit', () => {
// label Christopher
cy.get('[data-test="chart-container"] .line .nv-legend-symbol')
.eq(1)
.should('have.css', 'fill', 'rgb(108, 131, 142)');
.should('have.css', 'fill', 'rgb(172, 32, 119)');
});
it('should change color scheme multiple times', () => {
@@ -515,7 +515,7 @@ describe('Dashboard edit', () => {
// label Anthony
cy.get('[data-test-chart-name="Trends"] .line .nv-legend-symbol')
.eq(2)
.should('have.css', 'fill', 'rgb(0, 122, 135)');
.should('have.css', 'fill', 'rgb(244, 176, 42)');
// open main tab and nested tab
openTab(0, 0);
@@ -526,7 +526,7 @@ describe('Dashboard edit', () => {
'[data-test-chart-name="Top 10 California Names Timeseries"] .line .nv-legend-symbol',
)
.first()
.should('have.css', 'fill', 'rgb(0, 122, 135)');
.should('have.css', 'fill', 'rgb(244, 176, 42)');
});
it('should apply the color scheme across main tabs', () => {
@@ -557,7 +557,7 @@ describe('Dashboard edit', () => {
cy.get('[data-test-chart-name="Trends"] .line .nv-legend-symbol')
.first()
.should('have.css', 'fill', 'rgb(204, 0, 134)');
.should('have.css', 'fill', 'rgb(156, 52, 152)');
// change scheme now that charts are rendered across the main tabs
editDashboard();

View File

@@ -113,7 +113,7 @@ function prepareDashboardFilters(
},
type: 'NATIVE_FILTER',
description: '',
chartsInScope: [6],
chartsInScope: [5],
tabsInScope: [],
});
});
@@ -150,7 +150,7 @@ function prepareDashboardFilters(
meta: {
width: 4,
height: 50,
chartId: 6,
chartId: 5,
sliceName: 'Most Populated Countries',
},
},

View File

@@ -25,7 +25,6 @@ import { TABBED_DASHBOARD } from 'cypress/utils/urls';
import { expandFilterOnLeftPanel } from './utils';
const TREEMAP = { name: 'Treemap', viz: 'treemap_v2' };
const FILTER_BOX = { name: 'Region Filter', viz: 'filter_box' };
const LINE_CHART = { name: 'Growth Rate', viz: 'line' };
const BOX_PLOT = { name: 'Box plot', viz: 'box_plot' };
const BIG_NUMBER = { name: 'Number of Girls', viz: 'big_number_total' };
@@ -41,7 +40,6 @@ function topLevelTabs() {
function resetTabs() {
topLevelTabs();
cy.get('@top-level-tabs').first().click();
waitForChartLoad(FILTER_BOX);
waitForChartLoad(TREEMAP);
waitForChartLoad(BIG_NUMBER);
waitForChartLoad(TABLE);
@@ -96,7 +94,6 @@ describe('Dashboard tabs', () => {
it.skip('should send new queries when tab becomes visible', () => {
// landing in first tab
waitForChartLoad(FILTER_BOX);
waitForChartLoad(TREEMAP);
getChartAliasBySpec(TREEMAP).then(treemapAlias => {

View File

@@ -23,7 +23,6 @@ import { ChartSpec, waitForChartLoad } from 'cypress/utils';
export const WORLD_HEALTH_CHARTS = [
{ name: '% Rural', viz: 'world_map' },
{ name: 'Most Populated Countries', viz: 'table' },
{ name: 'Region Filter', viz: 'filter_box' },
{ name: "World's Population", viz: 'big_number' },
{ name: 'Growth Rate', viz: 'line' },
{ name: 'Rural Breakdown', viz: 'sunburst' },
@@ -322,7 +321,7 @@ export function applyNativeFilterValueWithIndex(index: number, value: string) {
cy.get(nativeFilters.filterFromDashboardView.filterValueInput)
.eq(index)
.should('exist', { timeout: 10000 })
.type(`${value}{enter}`);
.type(`${value}{enter}`, { force: true });
// click the title to dismiss shown options
cy.get(nativeFilters.filterFromDashboardView.filterName)
.eq(index)

View File

@@ -62,8 +62,8 @@ describe('Add database', () => {
it('show error alerts on dynamic form for bad host', () => {
// click postgres dynamic form
cy.get('.preferred > :nth-child(1)').click();
cy.get('input[name="host"]').focus().type('badhost');
cy.get('input[name="port"]').focus().type('5432');
cy.get('input[name="host"]').focus().type('badhost', { force: true });
cy.get('input[name="port"]').focus().type('5432', { force: true });
cy.get('.ant-form-item-explain-error').contains(
"The hostname provided can't be resolved",
);
@@ -72,8 +72,8 @@ describe('Add database', () => {
it('show error alerts on dynamic form for bad port', () => {
// click postgres dynamic form
cy.get('.preferred > :nth-child(1)').click();
cy.get('input[name="host"]').focus().type('localhost');
cy.get('input[name="port"]').focus().type('123');
cy.get('input[name="host"]').focus().type('localhost', { force: true });
cy.get('input[name="port"]').focus().type('123', { force: true });
cy.get('input[name="database"]').focus();
cy.get('.ant-form-item-explain-error').contains('The port is closed');
});

View File

@@ -39,6 +39,7 @@ describe('Advanced analytics', () => {
cy.get('[data-test=time_compare]')
.find('input[type=search]')
.clear()
.type('1 year{enter}');
cy.get('button[data-test="run-query-button"]').click();

View File

@@ -32,13 +32,13 @@ function openDashboardsAddedTo() {
cy.getBySel('actions-trigger').click();
cy.get('.ant-dropdown-menu-submenu-title')
.contains('Dashboards added to')
.trigger('mouseover');
.trigger('mouseover', { force: true });
}
function closeDashboardsAddedTo() {
cy.get('.ant-dropdown-menu-submenu-title')
.contains('Dashboards added to')
.trigger('mouseout');
.trigger('mouseout', { force: true });
cy.getBySel('actions-trigger').click();
}

View File

@@ -89,6 +89,6 @@ describe('Visualization > Distribution bar chart', () => {
).should('exist');
cy.get('.dist_bar .nv-legend .nv-legend-symbol')
.first()
.should('have.css', 'fill', 'rgb(255, 90, 95)');
.should('have.css', 'fill', 'rgb(41, 105, 107)');
});
});

View File

@@ -85,7 +85,7 @@ describe('Visualization > Line', () => {
).should('exist');
cy.get('.line .nv-legend .nv-legend-symbol')
.first()
.should('have.css', 'fill', 'rgb(255, 90, 95)');
.should('have.css', 'fill', 'rgb(41, 105, 107)');
});
it('should work with adhoc metric', () => {

View File

@@ -17,6 +17,9 @@
* under the License.
*/
// timezone for unit tests
process.env.TZ = 'America/New_York';
module.exports = {
testRegex:
'\\/superset-frontend\\/(spec|src|plugins|packages|tools)\\/.*(_spec|\\.test)\\.[jt]sx?$',

View File

@@ -21,6 +21,7 @@
"@emotion/styled": "^11.3.0",
"@fontsource/inter": "^4.0.0",
"@reduxjs/toolkit": "^1.9.3",
"@scarf/scarf": "^1.1.1",
"@superset-ui/chart-controls": "file:./packages/superset-ui-chart-controls",
"@superset-ui/core": "file:./packages/superset-ui-core",
"@superset-ui/legacy-plugin-chart-calendar": "file:./plugins/legacy-plugin-chart-calendar",
@@ -256,7 +257,7 @@
"less-loader": "^10.2.0",
"mini-css-extract-plugin": "^2.3.0",
"mock-socket": "^9.0.3",
"node-fetch": "^2.6.1",
"node-fetch": "^2.6.7",
"prettier": "^2.4.1",
"prettier-plugin-packagejson": "^2.2.15",
"process": "^0.11.10",
@@ -13827,6 +13828,12 @@
}
}
},
"node_modules/@scarf/scarf": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@scarf/scarf/-/scarf-1.1.1.tgz",
"integrity": "sha512-VGbKDbk1RFIaSmdVb0cNjjWJoRWRI/Weo23AjRCC2nryO0iAS8pzsToJfPVPtVs74WHw4L1UTADNdIYRLkirZQ==",
"hasInstallScript": true
},
"node_modules/@sinonjs/commons": {
"version": "1.8.3",
"resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz",
@@ -72301,6 +72308,11 @@
"any-observable": "^0.3.0"
}
},
"@scarf/scarf": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@scarf/scarf/-/scarf-1.1.1.tgz",
"integrity": "sha512-VGbKDbk1RFIaSmdVb0cNjjWJoRWRI/Weo23AjRCC2nryO0iAS8pzsToJfPVPtVs74WHw4L1UTADNdIYRLkirZQ=="
},
"@sinonjs/commons": {
"version": "1.8.3",
"resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz",

View File

@@ -1,6 +1,6 @@
{
"name": "superset",
"version": "0.0.0-dev",
"version": "3.0.3",
"description": "Superset is a data exploration platform designed to be visual, intuitive, and interactive.",
"keywords": [
"big",
@@ -86,6 +86,7 @@
"@emotion/styled": "^11.3.0",
"@fontsource/inter": "^4.0.0",
"@reduxjs/toolkit": "^1.9.3",
"@scarf/scarf": "^1.1.1",
"@superset-ui/chart-controls": "file:./packages/superset-ui-chart-controls",
"@superset-ui/core": "file:./packages/superset-ui-core",
"@superset-ui/legacy-plugin-chart-calendar": "file:./plugins/legacy-plugin-chart-calendar",
@@ -321,7 +322,7 @@
"less-loader": "^10.2.0",
"mini-css-extract-plugin": "^2.3.0",
"mock-socket": "^9.0.3",
"node-fetch": "^2.6.1",
"node-fetch": "^2.6.7",
"prettier": "^2.4.1",
"prettier-plugin-packagejson": "^2.2.15",
"process": "^0.11.10",
@@ -357,5 +358,8 @@
}
},
"readme": "ERROR: No README data found!",
"scarfSettings": {
"allowTopLevel": true
},
"_id": "superset@0.0.0-dev"
}

View File

@@ -44,6 +44,8 @@ const TypeIconWrapper = styled.div`
&& svg {
margin-right: 0;
margin-left: 0;
width: 100%;
height: 100%;
}
`};
`;

View File

@@ -1,92 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import React, { ReactNode } from 'react';
import { Slider, InputNumber, Input } from 'antd';
import Checkbox, { CheckboxProps } from 'antd/lib/checkbox';
import Select, { SelectOption } from '../Select';
import RadioButtonControl, {
RadioButtonOption,
} from '../../shared-controls/components/RadioButtonControl';
export const ControlFormItemComponents = {
Slider,
InputNumber,
Input,
Select,
// Directly export Checkbox will result in "using name from external module" error
// ref: https://stackoverflow.com/questions/43900035/ts4023-exported-variable-x-has-or-is-using-name-y-from-external-module-but
Checkbox: Checkbox as React.ForwardRefExoticComponent<
CheckboxProps & React.RefAttributes<HTMLInputElement>
>,
RadioButtonControl,
};
export type ControlType = keyof typeof ControlFormItemComponents;
export type ControlFormValueValidator<V> = (value: V) => string | false;
export type ControlFormItemSpec<T extends ControlType = ControlType> = {
controlType: T;
label: ReactNode;
description: ReactNode;
placeholder?: string;
required?: boolean;
validators?: ControlFormValueValidator<any>[];
width?: number | string;
/**
* Time to delay change propagation.
*/
debounceDelay?: number;
} & (T extends 'Select'
? {
options: SelectOption<any>[];
value?: string;
defaultValue?: string;
creatable?: boolean;
minWidth?: number | string;
validators?: ControlFormValueValidator<string>[];
}
: T extends 'RadioButtonControl'
? {
options: RadioButtonOption[];
value?: string;
defaultValue?: string;
}
: T extends 'Checkbox'
? {
value?: boolean;
defaultValue?: boolean;
}
: T extends 'InputNumber' | 'Slider'
? {
min?: number;
max?: number;
step?: number;
value?: number;
defaultValue?: number;
validators?: ControlFormValueValidator<number>[];
}
: T extends 'Input'
? {
controlType: 'Input';
value?: string;
defaultValue?: string;
validators?: ControlFormValueValidator<string>[];
}
: {});

View File

@@ -16,22 +16,11 @@
* specific language governing permissions and limitations
* under the License.
*/
import { FeatureFlag, FeatureFlagMap } from '@superset-ui/core';
import { styled } from '@superset-ui/core';
export function initFeatureFlags(featureFlags?: FeatureFlagMap) {
if (!window.featureFlags) {
window.featureFlags = featureFlags || {};
}
}
export function isFeatureEnabled(feature: FeatureFlag) {
try {
return !!window.featureFlags[feature];
} catch (error) {
// eslint-disable-next-line no-console
console.error(`Failed to query feature flag ${feature} (see error below)`);
// eslint-disable-next-line no-console
console.error(error);
return false;
}
}
export const ControlSubSectionHeader = styled.div`
font-weight: ${({ theme }) => theme.typography.weights.bold};
font-size: ${({ theme }) => theme.typography.sizes.s};
margin-bottom: ${({ theme }) => theme.gridUnit}px;
`;
export default ControlSubSectionHeader;

View File

@@ -17,15 +17,16 @@
* under the License.
*/
import {
t,
QueryMode,
DTTM_ALIAS,
GenericDataType,
QueryColumn,
DatasourceType,
QueryMode,
t,
} from '@superset-ui/core';
import { ColumnMeta, SortSeriesData, SortSeriesType } from './types';
export const DEFAULT_MAX_ROW = 100000;
// eslint-disable-next-line import/prefer-default-export
export const TIME_FILTER_LABELS = {
time_range: t('Time Range'),
@@ -41,6 +42,7 @@ export const COLUMN_NAME_ALIASES: Record<string, string> = {
export const DATASET_TIME_COLUMN_OPTION: ColumnMeta = {
verbose_name: COLUMN_NAME_ALIASES[DTTM_ALIAS],
column_name: DTTM_ALIAS,
type: 'TIMESTAMP',
type_generic: GenericDataType.TEMPORAL,
description: t(
'A reference to the [Time] configuration, taking granularity into account',
@@ -49,8 +51,9 @@ export const DATASET_TIME_COLUMN_OPTION: ColumnMeta = {
export const QUERY_TIME_COLUMN_OPTION: QueryColumn = {
column_name: DTTM_ALIAS,
type: DatasourceType.Query,
is_dttm: false,
is_dttm: true,
type: 'TIMESTAMP',
type_generic: GenericDataType.TEMPORAL,
};
export const QueryModeLabel = {

View File

@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
import { DatasourceType } from '@superset-ui/core';
import { DatasourceType, GenericDataType } from '@superset-ui/core';
import { Dataset } from './types';
export const TestDataset: Dataset = {
@@ -37,7 +37,7 @@ export const TestDataset: Dataset = {
is_dttm: false,
python_date_format: null,
type: 'BIGINT',
type_generic: 0,
type_generic: GenericDataType.NUMERIC,
verbose_name: null,
warning_markdown: null,
},
@@ -55,7 +55,7 @@ export const TestDataset: Dataset = {
is_dttm: false,
python_date_format: null,
type: 'VARCHAR(16)',
type_generic: 1,
type_generic: GenericDataType.STRING,
verbose_name: '',
warning_markdown: null,
},
@@ -73,7 +73,7 @@ export const TestDataset: Dataset = {
is_dttm: false,
python_date_format: null,
type: 'VARCHAR(10)',
type_generic: 1,
type_generic: GenericDataType.STRING,
verbose_name: null,
warning_markdown: null,
},
@@ -91,7 +91,7 @@ export const TestDataset: Dataset = {
is_dttm: true,
python_date_format: null,
type: 'TIMESTAMP WITHOUT TIME ZONE',
type_generic: 2,
type_generic: GenericDataType.TEMPORAL,
verbose_name: null,
warning_markdown: null,
},
@@ -109,7 +109,7 @@ export const TestDataset: Dataset = {
is_dttm: false,
python_date_format: null,
type: 'VARCHAR(255)',
type_generic: 1,
type_generic: GenericDataType.STRING,
verbose_name: null,
warning_markdown: null,
},

View File

@@ -29,6 +29,7 @@ export * from './components/InfoTooltipWithTrigger';
export * from './components/ColumnOption';
export * from './components/ColumnTypeLabel/ColumnTypeLabel';
export * from './components/MetricOption';
export * from './components/ControlSubSectionHeader';
export * from './shared-controls';
export * from './types';

View File

@@ -18,6 +18,8 @@
*/
import React from 'react';
import { t, RollingType, ComparisonType } from '@superset-ui/core';
import { ControlSubSectionHeader } from '../components/ControlSubSectionHeader';
import { ControlPanelSectionConfig } from '../types';
import { formatSelectOptions } from '../utils';
@@ -30,7 +32,7 @@ export const advancedAnalyticsControls: ControlPanelSectionConfig = {
'of query results',
),
controlSetRows: [
[<div className="section-header">{t('Rolling window')}</div>],
[<ControlSubSectionHeader>{t('Rolling window')}</ControlSubSectionHeader>],
[
{
name: 'rolling_type',
@@ -99,7 +101,7 @@ export const advancedAnalyticsControls: ControlPanelSectionConfig = {
},
},
],
[<div className="section-header">{t('Time comparison')}</div>],
[<ControlSubSectionHeader>{t('Time comparison')}</ControlSubSectionHeader>],
[
{
name: 'time_compare',
@@ -150,7 +152,7 @@ export const advancedAnalyticsControls: ControlPanelSectionConfig = {
},
},
],
[<div className="section-header">{t('Resample')}</div>],
[<ControlSubSectionHeader>{t('Resample')}</ControlSubSectionHeader>],
[
{
name: 'resample_rule',

View File

@@ -18,6 +18,8 @@
*/
import React from 'react';
import { t } from '@superset-ui/core';
import { ControlSubSectionHeader } from '../components/ControlSubSectionHeader';
import { ControlPanelSectionConfig } from '../types';
import { formatSelectOptions } from '../utils';
@@ -33,7 +35,7 @@ export const titleControls: ControlPanelSectionConfig = {
tabOverride: 'customize',
expanded: true,
controlSetRows: [
[<div className="section-header">{t('X Axis')}</div>],
[<ControlSubSectionHeader>{t('X Axis')}</ControlSubSectionHeader>],
[
{
name: 'x_axis_title',
@@ -61,7 +63,7 @@ export const titleControls: ControlPanelSectionConfig = {
},
},
],
[<div className="section-header">{t('Y Axis')}</div>],
[<ControlSubSectionHeader>{t('Y Axis')}</ControlSubSectionHeader>],
[
{
name: 'y_axis_title',
@@ -81,7 +83,7 @@ export const titleControls: ControlPanelSectionConfig = {
type: 'SelectControl',
freeForm: true,
clearable: true,
label: t('Y AXIS TITLE MARGIN'),
label: t('Y Axis Title Margin'),
renderTrigger: true,
default: TITLE_MARGIN_OPTIONS[0],
choices: formatSelectOptions(TITLE_MARGIN_OPTIONS),
@@ -96,7 +98,7 @@ export const titleControls: ControlPanelSectionConfig = {
type: 'SelectControl',
freeForm: true,
clearable: false,
label: t('Y AXIS TITLE POSITION'),
label: t('Y Axis Title Position'),
renderTrigger: true,
default: TITLE_POSITION_OPTIONS[0][0],
choices: TITLE_POSITION_OPTIONS,

View File

@@ -20,6 +20,7 @@ import { hasGenericChartAxes, t } from '@superset-ui/core';
import { ControlPanelSectionConfig, ControlSetRow } from '../types';
import {
contributionModeControl,
xAxisForceCategoricalControl,
xAxisSortAscControl,
xAxisSortControl,
xAxisSortSeriesAscendingControl,
@@ -55,6 +56,7 @@ export const echartsTimeSeriesQueryWithXAxisSort: ControlPanelSectionConfig = {
controlSetRows: [
[hasGenericChartAxes ? 'x_axis' : null],
[hasGenericChartAxes ? 'time_grain_sqla' : null],
[hasGenericChartAxes ? xAxisForceCategoricalControl : null],
[hasGenericChartAxes ? xAxisSortControl : null],
[hasGenericChartAxes ? xAxisSortAscControl : null],
[hasGenericChartAxes ? xAxisSortSeriesControl : null],

View File

@@ -1,73 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import React from 'react';
import { GenericDataType } from '@superset-ui/core';
import ControlForm, {
ControlFormRow,
ControlFormItem,
ControlFormItemSpec,
} from '../../../components/ControlForm';
import {
SHARED_COLUMN_CONFIG_PROPS,
SharedColumnConfigProp,
} from './constants';
import {
ColumnConfig,
ColumnConfigFormLayout,
ColumnConfigInfo,
} from './types';
export type ColumnConfigPopoverProps = {
column: ColumnConfigInfo;
configFormLayout: ColumnConfigFormLayout;
onChange: (value: ColumnConfig) => void;
};
export default function ColumnConfigPopover({
column,
configFormLayout,
onChange,
}: ColumnConfigPopoverProps) {
return (
<ControlForm onChange={onChange} value={column.config}>
{configFormLayout[
column.type === undefined ? GenericDataType.STRING : column.type
].map((row, i) => (
<ControlFormRow key={i}>
{row.map(meta => {
const key = typeof meta === 'string' ? meta : meta.name;
const override =
typeof meta === 'string'
? {}
: 'override' in meta
? meta.override
: meta.config;
const props = {
...(key in SHARED_COLUMN_CONFIG_PROPS
? SHARED_COLUMN_CONFIG_PROPS[key as SharedColumnConfigProp]
: undefined),
...override,
} as ControlFormItemSpec;
return <ControlFormItem key={key} name={key} {...props} />;
})}
</ControlFormRow>
))}
</ControlForm>
);
}

View File

@@ -17,10 +17,8 @@
* under the License.
*/
import RadioButtonControl from './RadioButtonControl';
import ColumnConfigControl from './ColumnConfigControl';
export * from './RadioButtonControl';
export * from './ColumnConfigControl';
/**
* Shared chart controls. Can be referred via string shortcuts in chart control
@@ -28,5 +26,4 @@ export * from './ColumnConfigControl';
*/
export default {
RadioButtonControl,
ColumnConfigControl,
};

View File

@@ -20,9 +20,9 @@
import {
ContributionType,
ensureIsArray,
GenericDataType,
getColumnLabel,
getMetricLabel,
isDefined,
QueryFormColumn,
QueryFormMetric,
t,
@@ -38,6 +38,7 @@ import {
DEFAULT_XAXIS_SORT_SERIES_DATA,
SORT_SERIES_CHOICES,
} from '../constants';
import { checkColumnType } from '../utils/checkColumnType';
export const contributionModeControl = {
name: 'contributionMode',
@@ -54,18 +55,29 @@ export const contributionModeControl = {
},
};
function isTemporal(controls: ControlStateMapping): boolean {
return !(
isDefined(controls?.x_axis?.value) &&
!isTemporalColumn(
function isForcedCategorical(controls: ControlStateMapping): boolean {
return (
checkColumnType(
getColumnLabel(controls?.x_axis?.value as QueryFormColumn),
controls?.datasource?.datasource,
[GenericDataType.NUMERIC],
) && !!controls?.xAxisForceCategorical?.value
);
}
function isSortable(controls: ControlStateMapping): boolean {
return (
isForcedCategorical(controls) ||
checkColumnType(
getColumnLabel(controls?.x_axis?.value as QueryFormColumn),
controls?.datasource?.datasource,
[GenericDataType.STRING, GenericDataType.BOOLEAN],
)
);
}
const xAxisSortVisibility = ({ controls }: { controls: ControlStateMapping }) =>
!isTemporal(controls) &&
isSortable(controls) &&
ensureIsArray(controls?.groupby?.value).length === 0 &&
ensureIsArray(controls?.metrics?.value).length === 1;
@@ -74,7 +86,7 @@ const xAxisMultiSortVisibility = ({
}: {
controls: ControlStateMapping;
}) =>
!isTemporal(controls) &&
isSortable(controls) &&
(!!ensureIsArray(controls?.groupby?.value).length ||
ensureIsArray(controls?.metrics?.value).length > 1);
@@ -141,7 +153,29 @@ export const xAxisSortAscControl = {
: t('X-Axis Sort Ascending'),
default: true,
description: t('Whether to sort ascending or descending on the base Axis.'),
visibility: xAxisSortVisibility,
visibility: ({ controls }: { controls: ControlStateMapping }) =>
controls?.x_axis_sort?.value !== undefined &&
xAxisSortVisibility({ controls }),
},
};
export const xAxisForceCategoricalControl = {
name: 'xAxisForceCategorical',
config: {
type: 'CheckboxControl',
label: () => t('Force categorical'),
default: false,
description: t('Treat values as categorical.'),
initialValue: (control: ControlState, state: ControlPanelState | null) =>
state?.form_data?.x_axis_sort !== undefined || control.value,
renderTrigger: true,
visibility: ({ controls }: { controls: ControlStateMapping }) =>
checkColumnType(
getColumnLabel(controls?.x_axis?.value as QueryFormColumn),
controls?.datasource?.datasource,
[GenericDataType.NUMERIC],
),
shouldMapStateToProps: () => true,
},
};
@@ -173,6 +207,8 @@ export const xAxisSortSeriesAscendingControl = {
default: DEFAULT_XAXIS_SORT_SERIES_DATA.sort_series_ascending,
description: t('Whether to sort ascending or descending on the base Axis.'),
renderTrigger: true,
visibility: xAxisMultiSortVisibility,
visibility: ({ controls }: { controls: ControlStateMapping }) =>
controls?.x_axis_sort_series?.value !== undefined &&
xAxisMultiSortVisibility({ controls }),
},
};

View File

@@ -47,6 +47,7 @@ import {
isDefined,
hasGenericChartAxes,
NO_TIME_RANGE,
validateMaxValue,
} from '@superset-ui/core';
import {
@@ -58,7 +59,7 @@ import {
DEFAULT_TIME_FORMAT,
DEFAULT_NUMBER_FORMAT,
} from '../utils';
import { TIME_FILTER_LABELS } from '../constants';
import { DEFAULT_MAX_ROW, TIME_FILTER_LABELS } from '../constants';
import {
SharedControlConfig,
Dataset,
@@ -245,7 +246,12 @@ const row_limit: SharedControlConfig<'SelectControl'> = {
type: 'SelectControl',
freeForm: true,
label: t('Row limit'),
validators: [legacyValidateInteger],
clearable: false,
validators: [
legacyValidateInteger,
(v, state) =>
validateMaxValue(v, state?.common?.conf?.SQL_MAX_ROW || DEFAULT_MAX_ROW),
],
default: 10000,
choices: formatSelectOptions(ROW_LIMIT_OPTIONS),
description: t('Limits the number of rows that get displayed.'),
@@ -317,6 +323,12 @@ const y_axis_format: SharedControlConfig<'SelectControl', SelectDefaultOption> =
},
};
const currency_format: SharedControlConfig<'CurrencyControl'> = {
type: 'CurrencyControl',
label: t('Currency format'),
renderTrigger: true,
};
const x_axis_time_format: SharedControlConfig<
'SelectControl',
SelectDefaultOption
@@ -406,4 +418,5 @@ export default {
x_axis: dndXAxisControl,
show_empty_columns,
temporal_columns_lookup,
currency_format,
};

View File

@@ -34,7 +34,6 @@ import type {
import { sharedControls, sharedControlComponents } from './shared-controls';
export type { Metric } from '@superset-ui/core';
export type { ControlFormItemSpec } from './components/ControlForm';
export type { ControlComponentProps } from './shared-controls/components/types';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -167,6 +166,12 @@ export type InternalControlType =
| 'DndColumnSelect'
| 'DndFilterSelect'
| 'DndMetricSelect'
| 'CurrencyControl'
| 'InputNumber'
| 'Checkbox'
| 'Select'
| 'Slider'
| 'Input'
| keyof SharedControlComponents; // expanded in `expandControlConfig`
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -474,13 +479,15 @@ export function isControlPanelSectionConfig(
export function isDataset(
datasource: Dataset | QueryResponse | null | undefined,
): datasource is Dataset {
return !!datasource && 'columns' in datasource;
return (
!!datasource && 'columns' in datasource && !('sqlEditorId' in datasource)
);
}
export function isQueryResponse(
datasource: Dataset | QueryResponse | null | undefined,
): datasource is QueryResponse {
return !!datasource && 'results' in datasource && 'sql' in datasource;
return !!datasource && 'results' in datasource && 'sqlEditorId' in datasource;
}
export enum SortSeriesType {
@@ -495,3 +502,60 @@ export type SortSeriesData = {
sort_series_type: SortSeriesType;
sort_series_ascending: boolean;
};
export type ControlFormValueValidator<V> = (value: V) => string | false;
export type ControlFormItemSpec<T extends ControlType = ControlType> = {
controlType: T;
label: ReactNode;
description: ReactNode;
placeholder?: string;
validators?: ControlFormValueValidator<any>[];
width?: number | string;
/**
* Time to delay change propagation.
*/
debounceDelay?: number;
} & (T extends 'Select'
? {
options: any;
value?: string;
defaultValue?: string;
creatable?: boolean;
minWidth?: number | string;
validators?: ControlFormValueValidator<string>[];
}
: T extends 'RadioButtonControl'
? {
options: [string, ReactNode][];
value?: string;
defaultValue?: string;
}
: T extends 'Checkbox'
? {
value?: boolean;
defaultValue?: boolean;
}
: T extends 'InputNumber' | 'Slider'
? {
min?: number;
max?: number;
step?: number;
value?: number;
defaultValue?: number;
validators?: ControlFormValueValidator<number>[];
}
: T extends 'Input'
? {
controlType: 'Input';
value?: string;
defaultValue?: string;
validators?: ControlFormValueValidator<string>[];
}
: T extends 'CurrencyControl'
? {
controlType: 'CurrencyControl';
value?: Currency;
defaultValue?: Currency;
}
: {});

View File

@@ -0,0 +1,49 @@
/**
* 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 { ensureIsArray, GenericDataType, ValueOf } from '@superset-ui/core';
import {
ControlPanelState,
isDataset,
isQueryResponse,
} from '@superset-ui/chart-controls';
export function checkColumnType(
columnName: string,
datasource: ValueOf<Pick<ControlPanelState, 'datasource'>>,
columnTypes: GenericDataType[],
): boolean {
if (isDataset(datasource)) {
return ensureIsArray(datasource.columns).some(
c =>
c.type_generic !== undefined &&
columnTypes.includes(c.type_generic) &&
columnName === c.column_name,
);
}
if (isQueryResponse(datasource)) {
return ensureIsArray(datasource.columns)
.filter(
c =>
c.type_generic !== undefined && columnTypes.includes(c.type_generic),
)
.map(c => c.column_name)
.some(c => columnName === c);
}
return false;
}

View File

@@ -17,7 +17,7 @@
* under the License.
*/
import { QueryResponse } from '@superset-ui/core';
import { Dataset, isColumnMeta, isDataset } from '../types';
import { Dataset, isDataset, isQueryResponse } from '../types';
/**
* Convert Datasource columns to column choices
@@ -25,11 +25,13 @@ import { Dataset, isColumnMeta, isDataset } from '../types';
export default function columnChoices(
datasource?: Dataset | QueryResponse | null,
): [string, string][] {
if (isDataset(datasource) && isColumnMeta(datasource.columns[0])) {
if (isDataset(datasource) || isQueryResponse(datasource)) {
return datasource.columns
.map((col): [string, string] => [
col.column_name,
col.verbose_name || col.column_name,
'verbose_name' in col
? col.verbose_name || col.column_name
: col.column_name,
])
.sort((opt1, opt2) =>
opt1[1].toLowerCase() > opt2[1].toLowerCase() ? 1 : -1,

View File

@@ -16,6 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
export * from './checkColumnType';
export * from './selectOptions';
export * from './D3Formatting';
export * from './expandControlConfig';

View File

@@ -0,0 +1,48 @@
/**
* 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 { GenericDataType, testQueryResponse } from '@superset-ui/core';
import { checkColumnType, TestDataset } from '../../src';
test('checkColumnType columns from a Dataset', () => {
expect(
checkColumnType('num', TestDataset, [GenericDataType.NUMERIC]),
).toEqual(true);
expect(checkColumnType('num', TestDataset, [GenericDataType.STRING])).toEqual(
false,
);
expect(
checkColumnType('gender', TestDataset, [GenericDataType.STRING]),
).toEqual(true);
expect(
checkColumnType('gender', TestDataset, [GenericDataType.NUMERIC]),
).toEqual(false);
});
test('checkColumnType from a QueryResponse', () => {
expect(
checkColumnType('Column 1', testQueryResponse, [GenericDataType.STRING]),
).toEqual(true);
expect(
checkColumnType('Column 1', testQueryResponse, [GenericDataType.NUMERIC]),
).toEqual(false);
});
test('checkColumnType from null', () => {
expect(checkColumnType('col', null, [])).toEqual(false);
});

View File

@@ -16,7 +16,11 @@
* specific language governing permissions and limitations
* under the License.
*/
import { DatasourceType, testQueryResponse } from '@superset-ui/core';
import {
DatasourceType,
GenericDataType,
testQueryResponse,
} from '@superset-ui/core';
import { columnChoices } from '../../src';
describe('columnChoices()', () => {
@@ -31,14 +35,20 @@ describe('columnChoices()', () => {
columns: [
{
column_name: 'fiz',
type: 'INT',
type_generic: GenericDataType.NUMERIC,
},
{
column_name: 'about',
verbose_name: 'right',
type: 'VARCHAR',
type_generic: GenericDataType.STRING,
},
{
column_name: 'foo',
verbose_name: 'bar',
verbose_name: undefined,
type: 'TIMESTAMP',
type_generic: GenericDataType.TEMPORAL,
},
],
verbose_map: {},
@@ -48,8 +58,8 @@ describe('columnChoices()', () => {
description: 'this is my datasource',
}),
).toEqual([
['foo', 'bar'],
['fiz', 'fiz'],
['foo', 'foo'],
['about', 'right'],
]);
});

View File

@@ -16,7 +16,11 @@
* specific language governing permissions and limitations
* under the License.
*/
import { testQueryResponse, testQueryResults } from '@superset-ui/core';
import {
GenericDataType,
testQueryResponse,
testQueryResults,
} from '@superset-ui/core';
import {
Dataset,
getTemporalColumns,
@@ -55,8 +59,9 @@ test('get temporal columns from a QueryResponse', () => {
temporalColumns: [
{
column_name: 'Column 2',
type: 'TIMESTAMP',
is_dttm: true,
type: 'TIMESTAMP',
type_generic: GenericDataType.TEMPORAL,
},
],
defaultTemporalColumn: 'Column 2',

View File

@@ -78,15 +78,20 @@ class CategoricalColorScale extends ExtensibleFunction {
cleanedValue: string,
) {
// make sure we don't overwrite the origin colors
const updatedRange = [...this.originColors];
const updatedRange = new Set(this.originColors);
// remove the color option from shared color
sharedColorMap.forEach((value: string, key: string) => {
if (key !== cleanedValue) {
const index = updatedRange.indexOf(value);
updatedRange.splice(index, 1);
updatedRange.delete(value);
}
});
this.range(updatedRange.length > 0 ? updatedRange : this.originColors);
// remove the color option from forced colors
Object.entries(this.parentForcedColors).forEach(([key, value]) => {
if (key !== cleanedValue) {
updatedRange.delete(value);
}
});
this.range(updatedRange.size > 0 ? [...updatedRange] : this.originColors);
}
getColor(value?: string, sliceId?: number) {

View File

@@ -24,27 +24,19 @@ const schemes = [
id: 'bnbColors',
label: 'Airbnb Colors',
colors: [
'#ff5a5f', // rausch
'#7b0051', // hackb
'#007A87', // kazan
'#00d1c1', // babu
'#8ce071', // lima
'#ffb400', // beach
'#b4a76c', // barol
'#ff8083',
'#cc0086',
'#00a1b3',
'#00ffeb',
'#bbedab',
'#ffd266',
'#cbc29a',
'#ff3339',
'#ff1ab1',
'#005c66',
'#00b3a5',
'#55d12e',
'#b37e00',
'#988b4e',
'#29696B',
'#5BCACE',
'#F4B02A',
'#F1826A',
'#792EB2',
'#C96EC6',
'#921E50',
'#B27700',
'#9C3498',
'#9C3498',
'#E4679D',
'#C32F0E',
'#9D63CA',
],
},
].map(s => new CategoricalScheme(s));

View File

@@ -67,6 +67,7 @@ function SafeMarkdown({
rehypePlugins={rehypePlugins}
remarkPlugins={[remarkGfm]}
skipHtml={false}
transformLinkUri={null}
>
{source}
</ReactMarkdown>

View File

@@ -31,7 +31,7 @@ interface CurrencyFormatter {
(value: number | null | undefined): string;
}
export const getCurrencySymbol = (currency: Currency) =>
export const getCurrencySymbol = (currency: Partial<Currency>) =>
new Intl.NumberFormat('en-US', {
style: 'currency',
currency: currency.symbol,

View File

@@ -19,3 +19,4 @@
export { default as CurrencyFormatter } from './CurrencyFormatter';
export * from './CurrencyFormatter';
export * from './utils';

View File

@@ -0,0 +1,99 @@
/**
* 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 {
Currency,
CurrencyFormatter,
ensureIsArray,
getNumberFormatter,
isSavedMetric,
QueryFormMetric,
ValueFormatter,
} from '@superset-ui/core';
export const buildCustomFormatters = (
metrics: QueryFormMetric | QueryFormMetric[] | undefined,
savedCurrencyFormats: Record<string, Currency>,
savedColumnFormats: Record<string, string>,
d3Format: string | undefined,
currencyFormat: Currency | undefined,
) => {
const metricsArray = ensureIsArray(metrics);
return metricsArray.reduce((acc, metric) => {
if (isSavedMetric(metric)) {
const actualD3Format = d3Format ?? savedColumnFormats[metric];
const actualCurrencyFormat = currencyFormat?.symbol
? currencyFormat
: savedCurrencyFormats[metric];
return actualCurrencyFormat
? {
...acc,
[metric]: new CurrencyFormatter({
d3Format: actualD3Format,
currency: actualCurrencyFormat,
}),
}
: {
...acc,
[metric]: getNumberFormatter(actualD3Format),
};
}
return acc;
}, {});
};
export const getCustomFormatter = (
customFormatters: Record<string, ValueFormatter>,
metrics: QueryFormMetric | QueryFormMetric[] | undefined,
key?: string,
) => {
const metricsArray = ensureIsArray(metrics);
if (metricsArray.length === 1 && isSavedMetric(metricsArray[0])) {
return customFormatters[metricsArray[0]];
}
return key ? customFormatters[key] : undefined;
};
export const getValueFormatter = (
metrics: QueryFormMetric | QueryFormMetric[] | undefined,
savedCurrencyFormats: Record<string, Currency>,
savedColumnFormats: Record<string, string>,
d3Format: string | undefined,
currencyFormat: Currency | undefined,
key?: string,
) => {
const customFormatter = getCustomFormatter(
buildCustomFormatters(
metrics,
savedCurrencyFormats,
savedColumnFormats,
d3Format,
currencyFormat,
),
metrics,
key,
);
if (customFormatter) {
return customFormatter;
}
if (currencyFormat?.symbol) {
return new CurrencyFormatter({ currency: currencyFormat, d3Format });
}
return getNumberFormatter(d3Format);
};

View File

@@ -70,10 +70,7 @@ export function normalizeTimeColumn(
};
}
const newQueryObject = omit(queryObject, [
'extras.time_grain_sqla',
'is_timeseries',
]);
const newQueryObject = omit(queryObject, ['is_timeseries']);
newQueryObject.columns = mutatedColumns;
return newQueryObject;

View File

@@ -159,7 +159,6 @@ export function isTableAnnotationLayer(
}
export type RecordAnnotationResult = {
columns: string[];
records: DataRecord[];
};
@@ -181,7 +180,7 @@ export function isTimeseriesAnnotationResult(
export function isRecordAnnotationResult(
result: any,
): result is RecordAnnotationResult {
return Array.isArray(result?.columns) && Array.isArray(result?.records);
return Array.isArray(result?.records);
}
export type AnnotationData = { [key: string]: AnnotationResult };

View File

@@ -31,6 +31,7 @@ import { Maybe } from '../../types';
import { PostProcessingRule } from './PostProcessing';
import { JsonObject } from '../../connection';
import { TimeGranularity } from '../../time-format';
import { GenericDataType } from './QueryResponse';
export type BaseQueryObjectFilterClause = {
col: QueryFormColumn;
@@ -250,6 +251,7 @@ export type QueryColumn = {
name?: string;
column_name: string;
type: string | null;
type_generic: GenericDataType;
is_dttm: boolean;
};
@@ -383,16 +385,19 @@ export const testQuery: Query = {
column_name: 'Column 1',
type: 'STRING',
is_dttm: false,
type_generic: GenericDataType.STRING,
},
{
column_name: 'Column 3',
type: 'STRING',
is_dttm: false,
type_generic: GenericDataType.STRING,
},
{
column_name: 'Column 2',
type: 'TIMESTAMP',
is_dttm: true,
type_generic: GenericDataType.TEMPORAL,
},
],
};
@@ -404,16 +409,19 @@ export const testQueryResults = {
{
column_name: 'Column 1',
type: 'STRING',
type_generic: GenericDataType.STRING,
is_dttm: false,
},
{
column_name: 'Column 3',
type: 'STRING',
type_generic: GenericDataType.STRING,
is_dttm: false,
},
{
column_name: 'Column 2',
type: 'TIMESTAMP',
type_generic: GenericDataType.TEMPORAL,
is_dttm: true,
},
],
@@ -425,16 +433,19 @@ export const testQueryResults = {
{
column_name: 'Column 1',
type: 'STRING',
type_generic: GenericDataType.STRING,
is_dttm: false,
},
{
column_name: 'Column 3',
type: 'STRING',
type_generic: GenericDataType.STRING,
is_dttm: false,
},
{
column_name: 'Column 2',
type: 'TIMESTAMP',
type_generic: GenericDataType.TEMPORAL,
is_dttm: true,
},
],

View File

@@ -0,0 +1,63 @@
/*
* 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 finestTemporalGrain from './finestTemporalGrain';
test('finestTemporalGrain', () => {
const monthFormatter = finestTemporalGrain([
new Date('2003-01-01 00:00:00Z').getTime(),
new Date('2003-02-01 00:00:00Z').getTime(),
]);
expect(monthFormatter(new Date('2003-01-01 00:00:00Z').getTime())).toBe(
'2003-01-01',
);
expect(monthFormatter(new Date('2003-02-01 00:00:00Z').getTime())).toBe(
'2003-02-01',
);
const yearFormatter = finestTemporalGrain([
new Date('2003-01-01 00:00:00Z').getTime(),
new Date('2004-01-01 00:00:00Z').getTime(),
]);
expect(yearFormatter(new Date('2003-01-01 00:00:00Z').getTime())).toBe(
'2003',
);
expect(yearFormatter(new Date('2004-01-01 00:00:00Z').getTime())).toBe(
'2004',
);
const milliSecondFormatter = finestTemporalGrain([
new Date('2003-01-01 00:00:00Z').getTime(),
new Date('2003-04-05 06:07:08.123Z').getTime(),
]);
expect(milliSecondFormatter(new Date('2003-01-01 00:00:00Z').getTime())).toBe(
'2003-01-01 00:00:00.000',
);
const localTimeFormatter = finestTemporalGrain(
[
new Date('2003-01-01 00:00:00Z').getTime(),
new Date('2003-02-01 00:00:00Z').getTime(),
],
true,
);
expect(localTimeFormatter(new Date('2003-01-01 00:00:00Z').getTime())).toBe(
'2002-12-31 19:00',
);
});

View File

@@ -0,0 +1,80 @@
/*
* 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 { utcFormat, timeFormat } from 'd3-time-format';
import { utcUtils, localTimeUtils } from '../utils/d3Time';
import TimeFormatter from '../TimeFormatter';
/*
* A formatter that examines all the values, and uses the finest temporal grain.
*/
export default function finestTemporalGrain(
values: any[],
useLocalTime = false,
) {
const format = useLocalTime ? timeFormat : utcFormat;
const formatMillisecond = format('%Y-%m-%d %H:%M:%S.%L');
const formatSecond = format('%Y-%m-%d %H:%M:%S');
const formatMinute = format('%Y-%m-%d %H:%M');
const formatHour = format('%Y-%m-%d %H:%M');
const formatDay = format('%Y-%m-%d');
const formatMonth = format('%Y-%m-%d');
const formatYear = format('%Y');
const {
hasMillisecond,
hasSecond,
hasMinute,
hasHour,
isNotFirstDayOfMonth,
isNotFirstMonth,
} = useLocalTime ? localTimeUtils : utcUtils;
let formatFunc = formatYear;
values.forEach((value: any) => {
if (formatFunc === formatYear && isNotFirstMonth(value)) {
formatFunc = formatMonth;
}
if (formatFunc === formatMonth && isNotFirstDayOfMonth(value)) {
formatFunc = formatDay;
}
if (formatFunc === formatDay && hasHour(value)) {
formatFunc = formatHour;
}
if (formatFunc === formatHour && hasMinute(value)) {
formatFunc = formatMinute;
}
if (formatFunc === formatMinute && hasSecond(value)) {
formatFunc = formatSecond;
}
if (formatFunc === formatSecond && hasMillisecond(value)) {
formatFunc = formatMillisecond;
}
});
return new TimeFormatter({
description:
'Use the finest grain in an array of dates to format all dates in the array',
formatFunc,
id: 'finest_temporal_grain',
label: 'Format temporal columns with the finest grain',
useLocalTime,
});
}

View File

@@ -35,6 +35,7 @@ export { default as createMultiFormatter } from './factories/createMultiFormatte
export { default as smartDateFormatter } from './formatters/smartDate';
export { default as smartDateDetailedFormatter } from './formatters/smartDateDetailed';
export { default as smartDateVerboseFormatter } from './formatters/smartDateVerbose';
export { default as finestTemporalGrainFormatter } from './formatters/finestTemporalGrain';
export { default as normalizeTimestamp } from './utils/normalizeTimestamp';
export { default as denormalizeTimestamp } from './utils/denormalizeTimestamp';

View File

@@ -16,6 +16,8 @@
* specific language governing permissions and limitations
* under the License.
*/
import logger from './logging';
// We can codegen the enum definition based on a list of supported flags that we
// check into source control. We're hardcoding the supported flags for now.
export enum FeatureFlag {
@@ -85,11 +87,17 @@ declare global {
}
}
export function initFeatureFlags(featureFlags?: FeatureFlagMap) {
if (!window.featureFlags) {
window.featureFlags = featureFlags || {};
}
}
export function isFeatureEnabled(feature: FeatureFlag): boolean {
try {
return !!window.featureFlags[feature];
} catch (error) {
console.error(`Failed to query feature flag ${feature}`);
logger.error(`Failed to query feature flag ${feature}`);
}
return false;
}

View File

@@ -44,6 +44,9 @@ describe('isProbablyHTML', () => {
const plainText = 'Just a plain text';
const isHTML = isProbablyHTML(plainText);
expect(isHTML).toBe(false);
const trickyText = 'a <= 10 and b > 10';
expect(isProbablyHTML(trickyText)).toBe(false);
});
});

View File

@@ -28,7 +28,9 @@ export function sanitizeHtml(htmlString: string) {
}
export function isProbablyHTML(text: string) {
return /<[^>]+>/.test(text);
return Array.from(
new DOMParser().parseFromString(text, 'text/html').body.childNodes,
).some(({ nodeType }) => nodeType === 1);
}
export function sanitizeHtmlIfNeeded(htmlString: string) {

View File

@@ -22,3 +22,4 @@ export { default as legacyValidateNumber } from './legacyValidateNumber';
export { default as validateInteger } from './validateInteger';
export { default as validateNumber } from './validateNumber';
export { default as validateNonEmpty } from './validateNonEmpty';
export { default as validateMaxValue } from './validateMaxValue';

View File

@@ -0,0 +1,8 @@
import { t } from '../translation';
export default function validateMaxValue(v: unknown, max: Number) {
if (Number(v) > +max) {
return t('Value cannot exceed %s', max);
}
return false;
}

View File

@@ -273,5 +273,21 @@ describe('CategoricalColorScale', () => {
expect(scale.range()).toEqual(['blue', 'green', 'red']);
sharedLabelColor.clear();
});
it('should remove parentForcedColors from range', () => {
const parentForcedColors = { house: 'blue', cow: 'red' };
const scale = new CategoricalColorScale(
['blue', 'red', 'green'],
parentForcedColors,
);
const sharedLabelColor = getSharedLabelColor();
sharedLabelColor.clear();
const colorMap = sharedLabelColor.getColorMap();
scale.removeSharedLabelColorFromRange(colorMap, 'pig');
expect(scale.range()).toEqual(['green']);
scale.removeSharedLabelColorFromRange(colorMap, 'cow');
expect(scale.range()).toEqual(['red', 'green']);
sharedLabelColor.clear();
});
});
});

View File

@@ -0,0 +1,207 @@
/*
* 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 {
buildCustomFormatters,
CurrencyFormatter,
getCustomFormatter,
getNumberFormatter,
getValueFormatter,
NumberFormatter,
ValueFormatter,
} from '@superset-ui/core';
test('buildCustomFormatters without saved metrics returns empty object', () => {
expect(
buildCustomFormatters(
[
{
expressionType: 'SIMPLE',
aggregate: 'COUNT',
column: { column_name: 'test' },
},
],
{
sum__num: { symbol: 'USD', symbolPosition: 'prefix' },
},
{},
',.1f',
undefined,
),
).toEqual({});
expect(
buildCustomFormatters(
undefined,
{
sum__num: { symbol: 'USD', symbolPosition: 'prefix' },
},
{},
',.1f',
undefined,
),
).toEqual({});
});
test('buildCustomFormatters with saved metrics returns custom formatters object', () => {
const customFormatters: Record<string, ValueFormatter> =
buildCustomFormatters(
[
{
expressionType: 'SIMPLE',
aggregate: 'COUNT',
column: { column_name: 'test' },
},
'sum__num',
'count',
],
{
sum__num: { symbol: 'USD', symbolPosition: 'prefix' },
},
{ sum__num: ',.2' },
',.1f',
undefined,
);
expect(customFormatters).toEqual({
sum__num: expect.any(Function),
count: expect.any(Function),
});
expect(customFormatters.sum__num).toBeInstanceOf(CurrencyFormatter);
expect(customFormatters.count).toBeInstanceOf(NumberFormatter);
expect((customFormatters.sum__num as CurrencyFormatter).d3Format).toEqual(
',.1f',
);
});
test('buildCustomFormatters uses dataset d3 format if not provided in control panel', () => {
const customFormatters: Record<string, ValueFormatter> =
buildCustomFormatters(
[
{
expressionType: 'SIMPLE',
aggregate: 'COUNT',
column: { column_name: 'test' },
},
'sum__num',
'count',
],
{
sum__num: { symbol: 'USD', symbolPosition: 'prefix' },
},
{ sum__num: ',.2' },
undefined,
undefined,
);
expect((customFormatters.sum__num as CurrencyFormatter).d3Format).toEqual(
',.2',
);
});
test('getCustomFormatter', () => {
const customFormatters = {
sum__num: new CurrencyFormatter({
currency: { symbol: 'USD', symbolPosition: 'prefix' },
}),
count: getNumberFormatter(),
};
expect(getCustomFormatter(customFormatters, 'count')).toEqual(
customFormatters.count,
);
expect(
getCustomFormatter(customFormatters, ['count', 'sum__num'], 'count'),
).toEqual(customFormatters.count);
expect(getCustomFormatter(customFormatters, ['count', 'sum__num'])).toEqual(
undefined,
);
});
test('getValueFormatter', () => {
expect(
getValueFormatter(['count', 'sum__num'], {}, {}, ',.1f', undefined),
).toBeInstanceOf(NumberFormatter);
expect(
getValueFormatter(
['count', 'sum__num'],
{},
{},
',.1f',
undefined,
'count',
),
).toBeInstanceOf(NumberFormatter);
expect(
getValueFormatter(
['count', 'sum__num'],
{ count: { symbol: 'USD', symbolPosition: 'prefix' } },
{},
',.1f',
undefined,
'count',
),
).toBeInstanceOf(CurrencyFormatter);
});
test('getValueFormatter with currency from control panel', () => {
const countFormatter = getValueFormatter(
['count', 'sum__num'],
{ count: { symbol: 'USD', symbolPosition: 'prefix' } },
{},
',.1f',
{ symbol: 'EUR', symbolPosition: 'suffix' },
'count',
);
expect(countFormatter).toBeInstanceOf(CurrencyFormatter);
expect((countFormatter as CurrencyFormatter).currency).toEqual({
symbol: 'EUR',
symbolPosition: 'suffix',
});
});
test('getValueFormatter with currency from control panel when no saved currencies', () => {
const formatter = getValueFormatter(
['count', 'sum__num'],
{},
{},
',.1f',
{ symbol: 'EUR', symbolPosition: 'suffix' },
undefined,
);
expect(formatter).toBeInstanceOf(CurrencyFormatter);
expect((formatter as CurrencyFormatter).currency).toEqual({
symbol: 'EUR',
symbolPosition: 'suffix',
});
});
test('getValueFormatter return NumberFormatter when no currency formatters', () => {
const formatter = getValueFormatter(
['count', 'sum__num'],
{},
{},
',.1f',
undefined,
undefined,
);
expect(formatter).toBeInstanceOf(NumberFormatter);
});

View File

@@ -92,7 +92,9 @@ describe('GENERIC_CHART_AXES is disabled', () => {
datasource: '5__table',
viz_type: 'table',
granularity: 'time_column',
extras: {},
extras: {
time_grain_sqla: 'P1Y',
},
time_range: '1 year ago : 2013',
orderby: [['count(*)', true]],
columns: [
@@ -182,7 +184,7 @@ describe('GENERIC_CHART_AXES is enabled', () => {
datasource: '5__table',
viz_type: 'table',
granularity: 'time_column',
extras: { where: '', having: '' },
extras: { where: '', having: '', time_grain_sqla: 'P1Y' },
time_range: '1 year ago : 2013',
orderby: [['count(*)', true]],
columns: [
@@ -240,7 +242,7 @@ describe('GENERIC_CHART_AXES is enabled', () => {
datasource: '5__table',
viz_type: 'table',
granularity: 'time_column',
extras: { where: '', having: '' },
extras: { where: '', having: '', time_grain_sqla: 'P1Y' },
time_range: '1 year ago : 2013',
orderby: [['count(*)', true]],
columns: [

Some files were not shown because too many files have changed in this diff Show More