Compare commits

...

292 Commits

Author SHA1 Message Date
Michael S. Molina
ce91297dd6 chore: Updates CHANGELOG.md 2023-01-06 13:02:13 -05:00
Michael S. Molina
0adbf9c052 chore: Merge adjustments 2023-01-06 11:36:11 -05:00
Michael S. Molina
bf0e98c72e fix: Talisman configuration (#22591) 2023-01-05 15:05:44 -05:00
Mayur
e6384aa12f fix(reports): force data generation in csv reports (#22196)
(cherry picked from commit a8bc53d805)
2023-01-05 14:34:27 -05:00
Daniel Vaz Gaspar
81ad9cb0a7 fix: datasource save, improve data validation (#22038) 2023-01-05 14:32:45 -05:00
Daniel Vaz Gaspar
387ee4ff4f fix: deprecate approve and request_access endpoint (#22022)
Co-authored-by: Michael S. Molina <70410625+michael-s-molina@users.noreply.github.com>
(cherry picked from commit 358a4ecedd)
2023-01-05 14:02:22 -05:00
Michael S. Molina
0296c7443d feat: Improves SafeMarkdown HTML sanitization (#21895) 2023-01-05 12:02:15 -05:00
Daniel Vaz Gaspar
9ee1138c97 fix: dashboard api cache decorator (#21964)
(cherry picked from commit c9470cac91)
2023-01-05 10:46:06 -05:00
Beto Dealmeida
92863659a6 fix: check that imports are ZIPs (#21875) 2023-01-05 10:19:46 -05:00
Michael S. Molina
9126d13616 feat: Adds a Content Security Policy (CSP) check for production environments (#21874)
(cherry picked from commit f4da74ce8d)
2023-01-04 15:44:28 -05:00
Michael S. Molina
468c1d164e feat: Disables HTML rendering in Toast by default (#21853)
(cherry picked from commit 47b1e0ca9d)
2023-01-04 15:44:28 -05:00
Ville Brofeldt
7c98e266ce chore(sqla): refactor query utils (#21811)
Co-authored-by: Ville Brofeldt <ville.brofeldt@apple.com>
2023-01-04 12:44:21 -05:00
Daniel Vaz Gaspar
4c21c7b038 fix: flash message on database data upload forms (#21761)
(cherry picked from commit ba3275a4d0)
2023-01-04 10:54:36 -05:00
Daniel Vaz Gaspar
e65450520e fix: database schema selector on import data (#21759)
(cherry picked from commit 91f0de0c5d)
2023-01-04 10:54:35 -05:00
Mayur
f676a890d9 fix: allow adhoc columns in non-aggregate query (#21729) 2023-01-04 10:45:56 -05:00
Stephen Liu
e79e2b37ee fix(database-list): hidden upload file button if no permission (#21216) 2023-01-03 16:44:07 -05:00
Michael S. Molina
0c05300ce5 fix: Missing argument 2022-09-14 18:02:00 -03:00
Michael S. Molina
67e8b9912c Updates CHANGELOG.md 2022-09-14 17:50:14 -03:00
Mayur
7d70ea1235 fix: dashboard filter value is cleared when 2 similar dashboards opened in succession (#21461)
(cherry picked from commit 59ca7861c0)
2022-09-14 15:09:12 -03:00
Bogdan
f3153760cd perf: Memoize the common_bootstrap_payload and include user param (#21018) (#21439)
Co-authored-by: Bogdan Kyryliuk <bogdankyryliuk@dropbox.com>
2022-09-14 15:08:49 -03:00
Daniel Vaz Gaspar
93611064b4 fix: cached common bootstrap Revert (#21018) (#21419)
(cherry picked from commit 094400c308)
2022-09-14 14:55:23 -03:00
Michael S. Molina
79cb268279 fix: Test host reference 2022-09-07 09:08:09 -03:00
Michael S. Molina
cca31299d3 Updates CHANGELOG.md 2022-09-06 14:36:34 -03:00
Michael S. Molina
37bdf434bf fix: Connect database from top right corner button doesn't work 2022-09-06 14:13:32 -03:00
Daniel Vaz Gaspar
8e7fb96f06 fix: disallow users from viewing other user's profile on config (#21302) 2022-09-06 10:24:03 -03:00
Daniel Vaz Gaspar
85fb2433ab feat: adds TLS certificate validation option for SMTP (#21272)
(cherry picked from commit 9fd752057e)
2022-09-06 10:12:01 -03:00
ʈᵃᵢ
9861c2b9e7 fix(celery cache warmup): add auth and use warm_up_cache endpoint (#21076)
(cherry picked from commit 04dd8d414d)
2022-09-06 10:12:01 -03:00
Michael S. Molina
7ad097371e fix: Adds yeoman-environment to dev dependencies 2022-08-31 09:44:07 -03:00
Michael S. Molina
44e3d60c35 fix: Overrides omnibar React dependency 2022-08-31 08:47:48 -03:00
Jesse Yang
52e1349acc chore(build): upgrade less-loader (#19703) 2022-08-30 18:36:39 -03:00
Michael S. Molina
5a3bb82b8d Fixes lint errors 2022-08-30 15:28:07 -03:00
Michael S. Molina
a50b0a91fc chore: Updates CHANGELOG.md and package.json 2022-08-30 09:53:15 -03:00
nisheldo
fb0d6d57d6 chore: updating python docker image to 3.8.13 (#20550)
(cherry picked from commit 7275805e95)
2022-08-30 09:36:59 -03:00
Ilyas
5f3301aadb fix: exporting CSV can't apply pagination #17861 (#20178) 2022-08-30 09:35:41 -03:00
Diego Medina
e5de0909c3 fix: Support the Clipboard API in modern browsers (#20058)
* fix: Support the Clipboard API in modern browsers

* fix tests

* PR comment

* Improvements
2022-08-29 15:28:09 -03:00
Bogdan
6bcb9674da Memoize the common_bootstrap_payload (#21018)
Try patch

Co-authored-by: Bogdan Kyryliuk <bogdankyryliuk@dropbox.com>
(cherry picked from commit 495a205dec)
2022-08-29 14:26:51 -03:00
Bogdan
1e8259a410 perf: Implement model specific lookups by id to improve performance (#20974)
* Implement model specific lookups by id to improve performance

* Address comments e.g. better variable names and test cleanup

* commit after cleanup

* even better name and test cleanup via rollback

Co-authored-by: Bogdan Kyryliuk <bogdankyryliuk@dropbox.com>
2022-08-29 14:26:18 -03:00
Simon Thelin
094b17e8cc fix(20428): Address-Presto/Trino-Poll-Issue-Refactor (#20434)
* fix(20428)-Address-Presto/Trino-Poll-Issue-Refacto
r

Update linter

* Update to only use BaseEngineSpec handle_cursor

* Fix CI

Co-authored-by: John Bodley <4567245+john-bodley@users.noreply.github.com>
2022-08-29 11:24:07 -03:00
Multazim Deshmukh
991a453ff2 fix(docker): Make Gunicorn Keepalive Adjustable (#20348)
Co-authored-by: Multazim Deshmukh <multazim.deshmukh@morningstar.com>
(cherry picked from commit 86368dd406)
2022-06-24 17:43:14 -03:00
Stephen Liu
8e1b2a1354 fix(chart): chart gets cut off on the dashboard (#20315)
* fix(chart): chart gets cut off on the dashboard

* add some failsafe

* address comment

(cherry picked from commit 07b4a7159d)
2022-06-24 17:43:14 -03:00
Ensky
6dee53682e Fixes #20155 (#20273)
(cherry picked from commit 77e326fd95)
2022-06-24 17:43:14 -03:00
Diego Medina
4073b58aa2 fix: Box Plot Chart throws an error when the average (AVG) / SUM is being calculated on the Metrics (#20235)
* fix: Box Plot Chart throws an error when the average (AVG) / SUM is being calculated on the Metrics

* add test

(cherry picked from commit 8638f59b4c)
2022-06-24 15:19:33 -03:00
John Bodley
d512e89aa9 fix(csv): Ensure df_to_escaped_csv handles NULL (#20151)
Co-authored-by: John Bodley <john.bodley@airbnb.com>
(cherry picked from commit 97ce920d49)
2022-06-24 15:19:33 -03:00
Diego Medina
f8a369d233 fix: avoid while cycle in computeMaxFontSize for big Number run forever when css rule applied (#20173)
(cherry picked from commit 365acee663)
2022-06-24 15:19:33 -03:00
Beto Dealmeida
af5ded3fcb fix: sqloxide optional (#19570) 2022-06-24 15:18:21 -03:00
Michael S. Molina
48f3eb4273 Updates CHANGELOG 2022-05-27 12:22:43 -03:00
Ville Brofeldt
c3604dc4de fix: login button does not render (#19685)
* fix: login button does not render

* add type guard
2022-05-27 10:14:21 -03:00
Michael S. Molina
17e10b77ca Updates version and CHANGELOG 2022-05-26 10:36:35 -03:00
Ville Brofeldt
8089afce1e fix(temporary-cache): when user is anonymous (#20181)
* fix(temporary-cache): fail on anonymous user

* make exceptions generic

* fix test

* remove redundant bool return

* fix unit tests

(cherry picked from commit 64c4226817)
2022-05-26 10:28:14 -03:00
Ramunas Balukonis
d652e0cab2 fix: "Week Staring Monday" time grain for BigQuery (#20091)
* Week Staring From Monday added for BQ

* lint fix

(cherry picked from commit 694f75d376)
2022-05-26 10:28:14 -03:00
cccs-tom
562e3a769b fix: Allow dataset owners to see their datasets (#20135)
(cherry picked from commit b0c6935f06)
2022-05-26 10:28:14 -03:00
Ville Brofeldt
c5e2809c2c fix(presto,trino): use correct literal dttm separator (#20123)
* fix(presto,trino): use correct literal dttm separator

* remove redundant tests

(cherry picked from commit e2f11d3680)
2022-05-26 10:28:14 -03:00
Ville Brofeldt
97c6af196e fix(generic-axes): apply contribution before flatten (#20077)
(cherry picked from commit d5802f7896)
2022-05-26 10:28:14 -03:00
thinhnd2104
bda9044bfd fix: Athena timestamp literal format (#19970)
* Fix Athena timestamp literal format

related: [#19969]

* Update test_athena.py

Update test

* Update athena.py

* Resolving CI/CD

* lint

Co-authored-by: Thinh Nguyen Duc <thinhnd.it@tripi.vn>
Co-authored-by: Ville Brofeldt <ville.v.brofeldt@gmail.com>
(cherry picked from commit 85315460cb)
2022-05-26 10:28:13 -03:00
Ville Brofeldt
4e44f4cc11 fix(plugin-chart-echarts): support adhoc x-axis (#20055)
* fix(plugin-chart-echarts): support adhoc x-axis

* simplify code

(cherry picked from commit b53daa91ec)
2022-05-26 10:28:13 -03:00
Yeachan Park
8becd3e080 fix(sqllab/charts): casting from timestamp[us] to timestamp[ns] would result in out of bounds timestamp (#18873)
* fix casting from timestamp[us] to timestamp[ns] would result in out of bounds timestamp from sqllab and charts

* Add unittests

* Lint changes and parameter variable rename

* Fix linting

(cherry picked from commit 8b72354654)
2022-05-26 10:28:13 -03:00
Ville Brofeldt
9ca53b8905 fix(sqla): replace custom dttm type with literal_column (#19917)
(cherry picked from commit 99f1f9ec61)
2022-05-26 10:28:13 -03:00
Hugh A. Miles II
2bd89d1705 fix: Alpha should not be able to edit datasets that they don't own (#19854)
* fix api for checking owners

* fix styles for disabling

* fix styles for disabling

* fix lint

* fix lint

* add owners key

* plzz

* remove

* update test

* add tooltip

* add type

* fix test

* fix user reference

* lit

* fix test

* work

(cherry picked from commit 8b15b68979)
2022-05-26 10:28:13 -03:00
Ville Brofeldt
94d4179045 update changelog entries 2022-05-26 14:47:45 +03:00
Ville Brofeldt
054e6b2334 update changelog 2022-04-25 10:55:40 +03:00
Diego Medina
397a182c2f fix(sql lab): when editing a saved query, the status is lost when switching tabs (#19448)
(cherry picked from commit 800ced5e25)
2022-04-25 10:46:54 +03:00
Ville Brofeldt
1050fcbd3c fix(key_value): use longblob on mysql (#19805)
* fix(key_value): use longblob on mysql

* set length

(cherry picked from commit a1bd5b283c)
2022-04-25 10:46:54 +03:00
Kamil Gabryjelski
387138eb9e Fix display of column config in table chart (#19806)
(cherry picked from commit 12bc30e2c7)
2022-04-25 10:46:53 +03:00
Yongjie Zhao
4fa96d3a3b fix: lost renameOperator in mixed timeseries chart (#19802)
(cherry picked from commit 108a2a4eaf)
2022-04-25 10:46:53 +03:00
smileydev
5567828ee8 fix(chart & explore): Show labels for SliderControl (#19765)
* fix(chart & explore): make to show label of slidercontrol

* fix(chart & explore): make to update SliderControl props

* fix(chart & explore): make to fix lint

(cherry picked from commit dfbaba97c6)
2022-04-25 10:46:53 +03:00
Yongjie Zhao
8c8bbfb89f feat: add renameOperator (#19776)
(cherry picked from commit 3c28cd4625)
2022-04-25 10:46:53 +03:00
Cedric Gampert
2b6e35e039 fix: dashboard standalone class not added when parameter set (#16619)
Co-authored-by: Ville Brofeldt <ville.v.brofeldt@gmail.com>
(cherry picked from commit 5134c63ae2)
2022-04-25 10:46:53 +03:00
Diego Medina
1d141be463 fix: SQL Lab UI Error: Objects are not valid as a React child (#19783)
(cherry picked from commit dfba9ea596)
2022-04-25 10:46:52 +03:00
Diego Medina
87b51c26f4 fix(sql lab): replace the output column in the query history table (#19370)
* fix(sql lab): replace the output column in the query history table

* improvements

(cherry picked from commit d4e7c65f6a)
2022-04-25 10:46:52 +03:00
Ville Brofeldt
c9e3ca11e2 fix(dashboard): copy permalink to dashboard chart (#19772)
* fix(dashboard): copy permalink to dashboard chart

* lint

* address comments

(cherry picked from commit e061955fd0)
2022-04-25 10:43:09 +03:00
smileydev
5df14ed8f9 fix(explore): make to show the null value as N/A in view result (#19603)
* fix(explore): make to show the null value as N/A in view result

* fix(explore): make to remove console

* fix(explore): make to remove console in Cell

* fix(explore): make to translate N/A

(cherry picked from commit 34323f9b5f)
2022-04-25 10:43:09 +03:00
Ville Brofeldt
2d7d2dd373 fix(permalink): remove memoize on get salt func (#19749)
(cherry picked from commit cf5145918b)
2022-04-25 10:43:09 +03:00
Kamil Gabryjelski
28aa69628f chore: Clean redundant dependency from useMemo dep array (#19732)
(cherry picked from commit b7759e6fd1)
2022-04-25 10:35:31 +03:00
Michael S. Molina
f8b202f670 fix: Filter dependencies are not being applied in default values (#19698)
(cherry picked from commit 7bc9123fe5)
2022-04-25 10:35:31 +03:00
Ville Brofeldt
ccf296b786 update changelog 2022-04-15 15:11:31 +03:00
Jesse Yang
90b08fa095 chore: skip SIP-68 shadow writing for LTS 2022-04-15 14:52:25 +03:00
smileydev
cdc136c70a fix(dnd&column): make to fix the blank state issue when only one column select (#19651)
(cherry picked from commit c320c295dc)
2022-04-15 14:52:11 +03:00
Yongjie Zhao
98c4d943da fix: drop the first level of MultiIndex (#19716)
(cherry picked from commit 9425dd2cac)
2022-04-15 14:52:10 +03:00
Kamil Gabryjelski
3c8e65960f fix(dashboard): Fix BigNumber causing dashboard to crash when overflowing (#19688)
* fix(dashboard): fix(plugin-chart-echarts): Fix BigNumber causing dashboard to crash when overflowing

* Add tooltips for truncated titles

* Fix type

(cherry picked from commit ee85466f2e)
2022-04-15 14:52:10 +03:00
Ville Brofeldt
d657d813e3 fix(sql-lab): do not replace undefined schema with empty object (#19664)
(cherry picked from commit 87d47987b7)
2022-04-15 14:52:10 +03:00
Yongjie Zhao
95e5b59c38 fix: time comparision (#19659)
(cherry picked from commit d7dd4119d4)
2022-04-15 14:52:10 +03:00
Ville Brofeldt
419316e84a fix tests 2022-04-11 09:49:29 +03:00
Ville Brofeldt
13e81c683e update changelog 2022-04-08 18:19:18 +03:00
Ville Brofeldt
77d6207bed docs: release notes for 1.5 (#19530)
* docs: release notes for 1.5

* rephrase and remove secret key from 1.4

* address review comments

(cherry picked from commit 1c1beb653a)
2022-04-08 16:47:07 +03:00
Ville Brofeldt
ecaecf0b6c fix(select): render when empty multiselect (#19612)
* fix(select): render when empty multiselect

* disable flaky test

(cherry picked from commit 1ad82af058)
2022-04-08 16:41:34 +03:00
Ville Brofeldt
280ecab0e6 chore: remove redundant adodbapi warning (#19557)
(cherry picked from commit 0d331f5bd8)
2022-04-08 16:41:33 +03:00
Ville Brofeldt
5ca126698a fix(dataset): handle missing python_type gracefully (#19553)
* fix(dataset): handle missing python_type gracefully

* refactor TEMPORAL_TYPES

(cherry picked from commit d9343a4639)
2022-04-08 16:41:33 +03:00
Ville Brofeldt
44eb81e35f fix(sqla): apply jinja to metrics (#19565)
(cherry picked from commit 34b55765c4)
2022-04-08 16:41:33 +03:00
Ville Brofeldt
1e567999d9 fix(dataset): avoid crash if database missing (#19582)
(cherry picked from commit db2135109a)
2022-04-08 16:41:33 +03:00
Yongjie Zhao
d99a9a4134 fix: big number with trendline can't calculate cumsum (#19542)
(cherry picked from commit 2daa071633)
2022-04-08 16:41:32 +03:00
Ville Brofeldt
c4d24a09a8 fix(sqllab): null database with backend persistence (#19548)
(cherry picked from commit 2d81c4c79f)
2022-04-08 16:41:32 +03:00
Ville Brofeldt
34e3119c40 fix(migrations): reorder skipped 1.4 migrations (#19543)
(cherry picked from commit e1ef2baad7)
2022-04-08 16:41:32 +03:00
Ville Brofeldt
031fadbed8 chore(releasing): use node 16 for testing and remove redundant updating note (#19505)
* chore(releasing): use node 16 for testing

* remove note about required cache
2022-04-04 13:43:26 +03:00
Ville Brofeldt
cc51a84c26 fix bad conflict resolution 2022-04-04 11:58:52 +03:00
Ville Brofeldt
2001fb5037 add noop endpoint migration 2022-04-04 11:20:29 +03:00
Ville Brofeldt
96901d6c46 update changelog, updating, version 2022-04-04 11:11:19 +03:00
dudasaron
dba4610f9b fix(dashboard list): do not show favorite star for anonymous users #18210 (#19409)
* fix: Only show favorite star on dashboard list if user is logged in #18210

* Fix linter errors

(cherry picked from commit b8891acf4a)
2022-04-04 11:05:38 +03:00
Ville Brofeldt
f44ed063e8 chore(plugin-chart-echarts): upgrade echarts 5.3.2 (#19481)
(cherry picked from commit 11bf0d09cb)
2022-04-04 11:00:48 +03:00
Yongjie Zhao
90f49e261e fix: flaky test for dashboard changed on (#19483)
(cherry picked from commit a2e921bd03)
2022-04-04 11:00:48 +03:00
Yongjie Zhao
3ff9cdeb65 fix: can't sync temporal flag on virtual table (#19366)
(cherry picked from commit d954c3df86)
2022-04-04 11:00:48 +03:00
Ville Brofeldt
3c627bdc61 fix: request samples with default row limit (#19456)
* fix: request samples with default row limit

* lodashLint

* fix cypress test

(cherry picked from commit d684ad073d)
2022-04-04 11:00:47 +03:00
Jinghuayao
3eece91378 test(native filter): add new test for dependent filter (#19392)
* add new test for dependent filter

(cherry picked from commit 2a75e4c3c3)
2022-04-04 11:00:47 +03:00
Diego Medina
af0dc75207 feat(sql lab): enable ACE editor search in SQL editors (#19328)
(cherry picked from commit eab9388f7c)
2022-04-04 11:00:47 +03:00
Beto Dealmeida
840be9972f feat: improve adhoc SQL validation (#19454)
* feat: improve adhoc SQL validation

* Small changes

* Add more unit tests

(cherry picked from commit 6828624f61)
2022-04-04 11:00:47 +03:00
James Turton
e4cbbdc653 fix(drill): specify an SA URL parm of impersonation_target for drill+sadrill (#19252)
* Update drill+sadrill to specify an SA URL parm of "impersonation_target".

Sqlalchemy-drill is being updated to support impersonation with the
drill+sadrill driver, where previously it did not.  The way that callers
should specify impersonation matches that for the drill+jdbc driver in that
a SA URL parameter of impersonation_target should be set to the username
of the user to be impersonated, while the stadard SA username and password
should be those of the proxy user.

* Remove lint.

* Address review comments.

* Use idiomatic pytest to test for a raised exception.

* Fix import statement order in drill.py.

(cherry picked from commit 85e330e94b)
2022-04-04 11:00:46 +03:00
Michael S. Molina
a96ff005fd refactor: Removes the CSS files from the Heatmap plugin (#19417)
* refactor: Removes the CSS files from the Heatmap plugin

* Adds peer dependencies

(cherry picked from commit ac6b2f2d93)
2022-04-04 11:00:46 +03:00
Michael S. Molina
70d800dc27 refactor: Removes the CSS files from the Calendar Heatmap plugin (#19436)
(cherry picked from commit 13467beb53)
2022-04-04 11:00:46 +03:00
Michael S. Molina
99c8f9bd13 chore: Removes plugin-chart-pivot-table hard-coded colors (#19439)
(cherry picked from commit 31095a523d)
2022-04-04 11:00:46 +03:00
Michael S. Molina
91bf9bd68b chore: Removes hard-coded colors from legacy-preset-chart-nvd3 (#19443)
(cherry picked from commit 47abad8673)
2022-04-04 11:00:45 +03:00
smileydev
e93d64d58e fix(dashboard): make to show the correct owned objects (#19372)
* fix(dashboard): make to show the correct owned objects

* fix(dashboard): make to filter is reusable

* fix(homepage): make sure the type Array<Filters>

* fix(homepage): make to display dashboard correctly by owners

(cherry picked from commit 6d89ffbcb7)
2022-04-04 11:00:45 +03:00
Yongjie Zhao
3c09690ed2 fix: can't save dataset modal (#19452)
(cherry picked from commit 6b136c2bc9)
2022-04-04 11:00:45 +03:00
David Aaron Suddjian
795ed3c719 feat: Embedded dashboard configuration (#19364)
* embedded dashboard model

* embedded dashboard endpoints

* DRY up using the with_dashboard decorator elsewhere

* wip

* check feature flags and permissions

* wip

* sdk

* urls

* dao option for id column

* got it working

* Update superset/embedded/view.py

* use the curator check

* put back old endpoint, for now

* allow access by either embedded.uuid or dashboard.id

* keep the old endpoint around, for the time being

* openapi

* lint

* lint

* lint

* test stuff

* lint, test

* typo

* Update superset-frontend/src/embedded/index.tsx

* Update superset-frontend/src/embedded/index.tsx

* fix tests

* bump sdk

(cherry picked from commit 8e29ec5a66)
2022-04-04 11:00:45 +03:00
Ville Brofeldt
a7ee677154 docs: add 1.4.2 changelog entries (#19411)
(cherry picked from commit a4c261d72c)
2022-04-04 11:00:44 +03:00
Michael S. Molina
0c78522bfe chore: Disables no literal colors for the theme configuration (#19437)
(cherry picked from commit 193744842b)
2022-04-04 11:00:44 +03:00
Daniel Vaz Gaspar
bfa203aee0 fix: missing init on importexport pkg (#19435)
(cherry picked from commit 2451937097)
2022-04-04 11:00:44 +03:00
Daniel Vaz Gaspar
7aba89c486 fix: add missing init on python pkg key_value (#19428)
* fix: add missing init on python pkg key_value

* fix lint issues

* fix lint issues

(cherry picked from commit fa35109bf2)
2022-04-04 11:00:44 +03:00
Srini Kadamati
625555ac7e chore: attempt to force docs deploy (#19424)
(cherry picked from commit a8e7624eb5)
2022-04-04 11:00:44 +03:00
Beto Dealmeida
038d114b07 perf: improve perf in SIP-68 migration (#19416)
* chore: improve perf in SIP-68 migration

* Small fixes

* Create tables referenced in SQL

* Update logic in SqlaTable as well

* Fix unit tests

(cherry picked from commit 63b5e2e4fa)
2022-04-04 11:00:43 +03:00
Srini Kadamati
ba22905610 chore: update slack invite url (#19412)
* chore: update slack invite url

* small fix in CoC

(cherry picked from commit 9d71f33d62)
2022-04-03 19:16:14 +03:00
Ville Brofeldt
fb929ab649 run black on remaining files 2022-04-03 19:15:25 +03:00
Ville Brofeldt
a70f4dc52f chore: upgrade black (#19410) 2022-04-03 19:13:17 +03:00
Michael S. Molina
1edd5f1343 chore: Removes direct theme imports (#19368) 2022-04-03 19:08:52 +03:00
Beto Dealmeida
cccec50454 feat: disable edits on external assets (#19344)
* feat: disable edits on external assets

* Update tests

(cherry picked from commit d304849b46)
2022-04-03 19:04:00 +03:00
Evan Rusackas
495b29a4eb chore: bump storybook to 6.4.19, migrating config, and linting storybook config (#19245)
* chore: bump storybook to 6.4.19 and reconfigure accordingly

* now linting the storybook directory, since it gets validated by CI

* linting 

(cherry picked from commit b689ac2d11)
2022-04-03 19:04:00 +03:00
Yongjie Zhao
5f2ffb3ba4 feat: linear imputation in Resample (#19393)
(cherry picked from commit a39dd4493e)
2022-04-03 19:03:59 +03:00
Geido
56e78b9ef7 chore: Eslint custom plugin to warn about hex and literal colors (#19239)
* wip

* Add eslint custom plugin

* Refactor

* Clean up

* Update superset-frontend/buildtools/eslint-plugin-theme-colors/index.js

Co-authored-by: Michael S. Molina <70410625+michael-s-molina@users.noreply.github.com>

* Refactor

* Update superset-frontend/buildtools/eslint-plugin-theme-colors/index.js

Co-authored-by: Michael S. Molina <70410625+michael-s-molina@users.noreply.github.com>

* Clean up

Co-authored-by: Michael S. Molina <70410625+michael-s-molina@users.noreply.github.com>
(cherry picked from commit 6b9113a17b)
2022-04-03 19:03:59 +03:00
Sujith Kumar S
ae2763af53 docs: Correcting the document font size (#19390)
* Correcting with doc font size

Correcting with doc font size

* Correcting with doc font size

Correcting with doc font size

* Update docs/docs/installation/configuring-superset.mdx

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

Co-authored-by: Ville Brofeldt <33317356+villebro@users.noreply.github.com>
(cherry picked from commit d46a550774)
2022-04-03 19:03:59 +03:00
Stephen Liu
fb0ae24c6b chore: add type checking in plugin test directory (#19387)
(cherry picked from commit 6f5778273e)
2022-04-03 19:03:58 +03:00
smileydev
0c75d9ede0 fix(database): make to allow the expose db as default in sqlalchemy form db (#19337)
(cherry picked from commit 5ae7e54999)
2022-04-03 19:03:58 +03:00
Jean-Louis Queguiner
029cf73b75 Fix add-driver-docker in Readme (#19321)
(cherry picked from commit 2b53578ad7)
2022-04-03 19:03:58 +03:00
Ville Brofeldt
dead7c253c fix(caching): support metastore cache for non-required caches (#19369)
* fix(caching): support metastore cache for non-required caches

* lint

(cherry picked from commit 02308a6f78)
2022-04-03 19:03:58 +03:00
Ville Brofeldt
25c5e2b4c7 chore: add support for npm8 (#19365)
(cherry picked from commit 6141a9aa4a)
2022-04-03 19:03:58 +03:00
Kamil Gabryjelski
2f497190ed feat(explore): Dataset panel option tooltips (#19259)
* feat(explore): Add description to column/metric tooltips in dataset panel

* Fix tests

* Address code review comments

(cherry picked from commit 45c28c8046)
2022-04-03 19:03:57 +03:00
smileydev
7af92ed337 fix(explore-sqllab): make that Timestamp column keep the Is temporal flagged when overwriting (#19010)
(cherry picked from commit 446358642f)
2022-04-03 19:03:57 +03:00
Yongjie Zhao
da4a79f276 fix: number format should editable when AA in time comparison (#19351)
(cherry picked from commit e15573d445)
2022-04-03 19:03:57 +03:00
smileydev
d65954994c fix(report-add): make to add error toast message when already attached report is added again into dashboard or chart (#19122)
* fix(report-add): make to add error toast message when already attached report is added again into dashboard or chart

* fix(export-add): make to setup the default error message

* fix(report-add): make to allow the errorMessage undefined in LabeledErrorBoundInput component

(cherry picked from commit cb0357005e)
2022-04-03 19:03:57 +03:00
Smart-Codi
0439d8db40 fix: Remove gap from SQLLab results bottom (#19138)
* Remove gap from SQLLab results bottom

* resolve comment

(cherry picked from commit 8947eb9680)
2022-04-03 19:03:56 +03:00
Geido
549b475a94 Fix NoAuthorizationError (#19355)
(cherry picked from commit a2bb91243a)
2022-04-03 19:03:56 +03:00
Ville Brofeldt
a6a2def6d3 feat: introduce hashids permalink keys (#19324)
* feat: introduce hashids permalink keys

* implement dashboard permalinks

* remove shorturl notice from UPDATING.md

* lint

* fix test

* introduce KeyValueResource

* make filterState optional

* fix test

* fix resource names

(cherry picked from commit f4b71abb22)
2022-04-03 19:03:56 +03:00
Kasia
18f82411c9 fix: Adaptive formatting spelling (#19359)
Co-authored-by: Kasia Zajac <kasiazajac@Kasias-MacBook-Pro-2.local>
(cherry picked from commit dc769a9a34)
2022-04-03 19:03:56 +03:00
Beto Dealmeida
d9377559f6 feat: import external management columns (#19315)
* feat: import flags

* Add tests

(cherry picked from commit c7f9060a2f)
2022-04-03 19:03:55 +03:00
Ville Brofeldt
a591eccfc2 docs: update lock + general cleanup (#19350)
* docs: update lock file

* remove redundant npm lock file

* add missing peer deps

* fix TODO and bump antd

* fix API spec script

(cherry picked from commit 3313530f4d)
2022-04-03 19:03:55 +03:00
Erik Ritter
069d42ed14 fix: typo on doc string (#19346)
(cherry picked from commit 2af2d00e85)
2022-04-03 19:03:55 +03:00
Richard Whaling
89b7b3784a feat: add duckdb as DataSource - Fixes #14563 (#19317)
* + duckdb support

needs the forked version of [duckdb-engine](https://github.com/alitrack/duckdb_engine)

* Update duckdb.py

update  _time_grain_expressions

* removed superfluous get_all_datasource_names def in duckdb engine spec

* added exception handling for duckdb single-threaded RuntimeError

* fixed linter blips and other stylistic cleanup in duckdb.py

* one last round of linter tweaks in test_connection.py for duckdb support

Co-authored-by: Steven Lee <admin@alitrack.com>
Co-authored-by: Richard Whaling <richardwhaling@Richards-MacBook-Pro.local>
(cherry picked from commit 202e34a259)
2022-04-03 19:03:55 +03:00
Beto Dealmeida
3b0b60c57f feat: external management flags in CRUD (#19318)
(cherry picked from commit 9766726b26)
2022-04-03 19:03:55 +03:00
Michael S. Molina
a81b1ab374 fix: Null values on Explore filter (#19341)
(cherry picked from commit 65c204b288)
2022-04-03 19:03:54 +03:00
Norman Hooper
6ccc1c86fa Use three backticks for code blocks (#19331)
(cherry picked from commit 3340f05dd3)
2022-04-03 19:03:54 +03:00
ND
99f36f73d2 Correcting some typos (#19338)
Co-authored-by: Andreas Burner <andreas.burner@smartstream-stp.com>
(cherry picked from commit 7ba06ee944)
2022-04-03 19:03:54 +03:00
Lily Kuang
b21d4f841c fix(embedded): download chart as image (#19339)
(cherry picked from commit 0ad692511e)
2022-04-03 19:03:54 +03:00
Kamil Gabryjelski
158d442f0c fix(dashboard): Chart stuck in loading state when when datasets request and chart request fail (#19327)
(cherry picked from commit a08f83bc60)
2022-04-03 19:03:53 +03:00
smileydev
baeb36f8c6 fix(explore): make to convert null to N/A in view results (#19316)
* fix(explore): make to convert null to N/A in view results

* fix(explore): make to null formatter move before timeFormatter

(cherry picked from commit 468c5ca29a)
2022-04-03 19:03:53 +03:00
Diego Medina
52f9b718f2 fix: regression on Select component when handling null values (#19326)
(cherry picked from commit 9e58916d93)
2022-04-03 19:03:53 +03:00
Stephen Liu
bf92b2067e chore: add type checking in package tests directory (#19320)
(cherry picked from commit b0397beb8e)
2022-04-03 19:03:53 +03:00
Sujith Kumar S
d429bbd3b2 docs: SECRET_KEY Rotation Documentation (#19233)
* SECRET_KEY Rotation

Additional documentation for SECRET_KEY rotation and SECRET_KEY setting up.

* Bumped the helm chart version to 0.5.11

Bumped the helm chart version for the new changes.

* Removed the default secret key value from the configuration docs.

Removed the default secret key value from the configuration docs.
2022-04-03 19:02:44 +03:00
Daniel Vaz Gaspar
b51eadd657 chore: bump FAB to 3.4.5 (#19323)
(cherry picked from commit 87e36d6abb)
2022-04-03 19:01:40 +03:00
Daniel Vaz Gaspar
0664a05afb ci: add more code owners to helm chart source (#19322)
(cherry picked from commit ff6ee3766c)
2022-04-03 19:01:40 +03:00
Ville Brofeldt
3a9435df72 fix(dashboard): fix default filter bar visibility + add docs (#18741)
* fix(dashboard): fix default filter tab visibility + add tests

* fix types

* lint

* rename docs + add double bang to length

(cherry picked from commit b7ecb14230)
2022-04-03 19:01:40 +03:00
Yongjie Zhao
9bc76337cf feat(advanced analysis): support MultiIndex column in post processing stage (#19116) 2022-04-03 19:00:01 +03:00
AAfghahi
f8a92de75c docusearch (#19289)
(cherry picked from commit 6083545e86)
2022-04-03 18:57:31 +03:00
Evan Rusackas
12759ec264 chore: fixing a pluralization typo (#19295)
(cherry picked from commit e45235e482)
2022-04-03 18:57:31 +03:00
Ville Brofeldt
f0630a6ea7 fix(cache): only warn about fallback cache for non-debug mode (#19305)
(cherry picked from commit 7ca10fb770)
2022-04-03 18:57:31 +03:00
Beto Dealmeida
d4223d7dc4 feat: API for asset sync (#19220)
* feat: API for asset sync

* Add unit tests.

* Improve tests

* Move files

* Add more tests

(cherry picked from commit b05e7dbf2a)
2022-04-03 18:57:30 +03:00
Michael S. Molina
46dbf6c50c fix: Don't allow duplicated tag values in the Select (#19283)
* fix: Don't allow duplicated tag values in the Select

* Addresses comments and adds test

(cherry picked from commit d3ce398448)
2022-04-03 18:57:30 +03:00
Kamil Gabryjelski
19ee561092 chore: Make font-weights themable, fix font faces (#19236)
* fix(fonts): Import all necessary font packages

* Make html tags themable

* Set bold font weight to 600, add medium font weight to theme

* Replace hard coded font weights with theme variables

* Change some font weight light elements to normal

* Fix tests

* Fix bug in pivot table

* Address code review comments
2022-04-03 18:56:12 +03:00
David Aaron Suddjian
c6a4d75954 Update ToastPresenter.tsx (#19296)
(cherry picked from commit 35b8a72dae)
2022-04-03 14:10:50 +03:00
David Aaron Suddjian
55aac5a3cb allow overriding the guest token PyJWT instance (#19293)
(cherry picked from commit f9feb1b7f3)
2022-04-03 14:10:50 +03:00
Diego Medina
712212be6d fix: most Recently Selected Table Should Appear at the Top of the List on the Left Panel (#19258)
(cherry picked from commit 4669b6ce11)
2022-04-03 14:10:50 +03:00
smileydev
792473f6db fix(dashboard): make to show the correct owned objects (#19223)
* fix(dashboard): make to show the correct owned objects

* fix(dashboard): make to filter is reusable

* fix(homepage): make sure the type Array<Filters>

(cherry picked from commit 29cba2b00c)
2022-04-03 14:10:49 +03:00
Diego Medina
2a2105c8c8 chore: add missing keys to components inside lists (#19161)
(cherry picked from commit 54f1b35161)
2022-04-03 14:10:49 +03:00
Phillip Kelley-Dotson
e1964a8dfe feat: allow uploads in crud view (#18953)
* feat: allow uploads in crud view

* fix merge conflict and fix ts

* fix import

* fix tests

* fix lint

* remove unused var

* fix underline flash and alignment

* fix offset

* fix icon alignment

* fix labels and css issues

* make drowdown primary all the time

* make global

* fix lables

* add upload perms to utils

* remove unused code

* add suggested changes

* update menuright

(cherry picked from commit d771ddbb94)
2022-04-03 14:10:49 +03:00
Ville Brofeldt
f3172010d5 feat(key-value): add superset metastore cache (#19232)
(cherry picked from commit 72b9a7fa5b)
2022-04-03 14:10:49 +03:00
John Bodley
81a1abfab4 fix(presto/trino): Add TIME/TIMESTAMP WITH TIME ZONE (#19263)
Co-authored-by: John Bodley <john.bodley@airbnb.com>
(cherry picked from commit 82a6811e7e)
2022-04-03 14:10:48 +03:00
David Aaron Suddjian
dc0153151c feat: SupersetClient config to override 401 behavior (#19144)
* wip

* feat: make 401 responses configurable in SupersetClient

* sort

* guest unauthorized handler

* add toast container to embedded app

* add option for toast presenter to go at the top

* remove confusing comms logging

* lint

* Update superset-frontend/src/embedded/index.tsx

* type correction

(cherry picked from commit 96a123f553)
2022-04-03 14:10:48 +03:00
Elizabeth Thompson
910679aad5 fix dataset update table (#19269)
(cherry picked from commit 88029e21b6)
2022-04-03 14:10:48 +03:00
PApostol
70facad1b2 Various docstring fixes (#18221)
(cherry picked from commit c07a707eab)
2022-04-03 14:10:48 +03:00
prassanna-helixsense-com
565d83f9ec Update README.md (#19270)
(cherry picked from commit d215cbcdc8)
2022-04-03 14:10:48 +03:00
Stephen Liu
7d239b8958 feat: improve color consistency (save all labels) (#19038)
(cherry picked from commit dc575080d7)
2022-04-03 14:10:47 +03:00
Ville Brofeldt
408573d4d6 feat: add support for comments in adhoc clauses (#19248)
* feat: add support for comments in adhoc clauses

* sanitize remaining freeform clauses

* sanitize adhoc having in frontend

* address review comment

(cherry picked from commit f341025d80)
2022-04-03 14:10:47 +03:00
Diego Medina
f6346d627b fix: custom SQL in Sort By Breaks Bar Chart (#19069)
(cherry picked from commit 4f0074a4ae)
2022-04-03 14:10:47 +03:00
smileydev
fed1c24252 fix(chart-crud): make to update Viz type Filter label to Chart type (#19140)
(cherry picked from commit b888341090)
2022-04-03 14:10:47 +03:00
Lily Kuang
c793b7bfe9 fix: allow subquery in ad-hoc SQL (WIP) (#19242)
* allow adhoc subquery

* add config for allow ad hoc subquery

* default to true allow adhoc subquery

* fix test

* Update superset/errors.py

Co-authored-by: Beto Dealmeida <roberto@dealmeida.net>

* Update superset/connectors/sqla/utils.py

Co-authored-by: David Aaron Suddjian <1858430+suddjian@users.noreply.github.com>

* rename and add doc string

* fix for big query test

* Update superset/connectors/sqla/utils.py

Co-authored-by: Beto Dealmeida <roberto@dealmeida.net>

* Apply suggestions from code review

Co-authored-by: Beto Dealmeida <roberto@dealmeida.net>

* add test

* update validate adhoc subquery

Co-authored-by: Beto Dealmeida <roberto@dealmeida.net>
Co-authored-by: David Aaron Suddjian <1858430+suddjian@users.noreply.github.com>
(cherry picked from commit 50902d51f5)
2022-04-03 14:10:46 +03:00
Elizabeth Thompson
1953233b68 update changelog and updating files from 1.4.1 (#18648) 2022-04-03 14:09:25 +03:00
smileydev
1834a268a1 fix(explore comma): make that the comma can be added by removing it from token separators… (#18926)
* make that the comma can be added by removing it from token separators in select component.

* fix(explore comma): add the allowTokenSeperators props into Select

* fix(explore comma): make to allow to customize the token separators in Select.

* fix(explore comma): make to add the unit test and story book.

* fix(explore comma): make to fix the lint

* fix(explore comma): make to fix the spell  & add tokenSeparatprs props to PickedSelectProps

* Update Select.tsx

* fix(explore comma): make to run lint fix

(cherry picked from commit e7355b9610)
2022-04-03 14:04:53 +03:00
Venu Vardhan Reddy Tekula
1c53a76bcc docs: fix broken links in the documentation (#19235)
(cherry picked from commit 2a89da2ef1)
2022-04-03 14:04:53 +03:00
Stephen Liu
33beba96e3 chore: use order_desc shared control consistently (#19172)
(cherry picked from commit 10eb6c77a4)
2022-04-03 14:04:53 +03:00
Yongjie Zhao
f1ea0ad56c fix: adhoc column in legacy chart (#19234)
(cherry picked from commit b5e9fad11a)
2022-04-03 14:04:52 +03:00
Diego Medina
f2541429cd fix(sql lab): deleting the last saved query or the last executed from history (#19225)
* fix: fix issue when deleting the last saved query or the last executed query

* merge migration

(cherry picked from commit aa5c80bda6)
2022-04-03 14:04:52 +03:00
Beto Dealmeida
3de8370ead feat: import/export assets commands (#19217)
* feat: import/export assets commands

* Add overwrite test

* Fix tests

(cherry picked from commit 51061f0d67)
2022-04-03 14:04:52 +03:00
Jesse Yang
2651c1d925 chore: upgrade mypy (#19227)
(cherry picked from commit 92cd0a18e6)
2022-04-03 14:04:52 +03:00
Diego Medina
0522296607 fix: allow to select <NULL> in a native filter single mode (#19076)
* fix: allow to select <NULL> in a native filter single mode

* fix lint issue

* Update superset-frontend/src/components/Select/utils.ts

Co-authored-by: Michael S. Molina <70410625+michael-s-molina@users.noreply.github.com>

* fix

Co-authored-by: Michael S. Molina <70410625+michael-s-molina@users.noreply.github.com>
(cherry picked from commit 19fcd03c89)
2022-04-03 14:04:52 +03:00
smileydev
823b9b2ff2 fix(select): make to consider the case sensitive in case of d3 format selector (#19159)
(cherry picked from commit d099f5ed4a)
2022-04-03 14:04:51 +03:00
Craig Rueda
f91f9f5aae feat(ui): Adding manifest prefix config (#19141)
* Adding manifest prefix config

* Fixing broken tests

* Fixing import

* Adding prefix for remaining assets

* Changing static prefix strategy

* Fixing DST test

* Fixing up formatting

* Fixing up async_query_manager.py types
2022-04-03 14:03:35 +03:00
cccs-Dustin
a1b9b2946d feat(sqllab): Add a configuration option to disable data preview (#19104)
(cherry picked from commit 02ef9ca4cd)
2022-04-03 14:02:24 +03:00
Diego Medina
71338cab57 feat: scroll to bottom when adding a new native filter and the page is filled (#19053)
* feat: Scroll to bottom when adding a new native filter and the page is filled

* Add test

(cherry picked from commit cfb967f430)
2022-04-03 14:02:24 +03:00
Diego Medina
28be2311a0 fix: Popovers in Explore not attached to the fields they are triggered by (#19139)
* fix: Popovers in Explore not attached to the fields they are triggered by

* fix

* PR comment

* remove unused import

(cherry picked from commit 0277ebc225)
2022-04-03 14:02:24 +03:00
Diego Medina
ff277e0517 fix: auto-complete of tables and names are not working in SQL lab (#19152)
(cherry picked from commit 3b427b2029)
2022-04-03 14:02:24 +03:00
Beto Dealmeida
7bc6e14151 chore: refactor import command (#19216)
(cherry picked from commit a4848a2f46)
2022-04-03 14:02:24 +03:00
Ville Brofeldt
8c102174b8 feat: add permalink to dashboard and explore (#19078)
* rename key_value to temporary_cache

* add migration

* create new key_value package

* add commands

* lots of new stuff

* fix schema reference

* remove redundant filter state from bootstrap data

* add missing license headers

* fix pylint

* fix dashboard permalink access

* use valid json mocks for filter state tests

* fix temporary cache tests

* add anchors to dashboard state

* lint

* fix util test

* fix url shortlink button tests

* remove legacy shortner

* remove unused imports

* fix js tests

* fix test

* add native filter state to anchor link

* add UPDATING.md section

* address comments

* address comments

* lint

* fix test

* add utils tests + other test stubs

* add key_value integration tests

* add filter box state to permalink state

* fully support persisting url parameters

* lint, add redirects and a few integration tests

* fix test + clean up trailing comma

* fix anchor bug

* change value to LargeBinary to support persisting binary values

* fix urlParams type and simplify urlencode

* lint

* add optional entry expiration

* fix incorrect chart id + add test

(cherry picked from commit b7a0559aaf)
2022-04-03 14:02:23 +03:00
Beto Dealmeida
90f4d77422 feat: add export_related flag (#19215)
* feat: add export_related flag

* Fix lint

(cherry picked from commit d01fdad1d8)
2022-04-03 14:02:23 +03:00
Hugh A. Miles II
2979ff26cc fix: Revert "refactor: converted QueryAutoRefresh to functional component … (#19226)
* Revert "refactor: converted QueryAutoRefresh to functional component (#18179)"

This reverts commit f497c1900e.

* lint

(cherry picked from commit fc8721800b)
2022-04-03 14:02:23 +03:00
Jesse Yang
a68b1fd686 test: fix TimezoneSelector tests on daylight saving time (#19156)
(cherry picked from commit 8d53db1db6)
2022-04-03 14:02:23 +03:00
Hugh A. Miles II
ca0c12f2b3 fix: Logic for showing extension in Global Nav (#19158)
* fix logic for checking extensions

* add specific types

* fix lint

(cherry picked from commit 181ecf4509)
2022-04-03 14:02:22 +03:00
Lyndsi Kay Williams
3f1074e6a3 fix(sqllab): Updated blank states for query results and query history (#19111)
* Empty states updated on result tab and query history tab

* Testing on query history blank state

* Testing on result tab with empty state

* Forgot to remove a comment

* Corrected empty state image size and centered with drag bar

* Centered blank states vertically

(cherry picked from commit bb618a47ff)
2022-04-03 14:02:22 +03:00
David Aaron Suddjian
337ea4f59d fix: clean up chart metadata config (#19143)
* fix: clean up chart metadata config

* missed a spot

* missed another spot

* fix failing time-specific test

* can't call translation functions here

* Revert "fix failing time-specific test"

This reverts commit 3eeb8ab9cc.

* skip problematic test

* extra import

(cherry picked from commit 3d66912d89)
2022-04-03 14:02:22 +03:00
smileydev
db8b6af7c7 fix(dashboard-css): make to stay custom css when reload (#19084)
* fix(dashboard-css): make to stay custome css when reload

* fix(dashboard-css): make to add injectCustomCSS into HeaderActionsDropdown.test.tsx

(cherry picked from commit 30c97ad5bf)
2022-04-03 14:02:22 +03:00
smileydev
a0138af7f8 fix(dbs-dropdown): make to allow the search in supported db dropdown (#19125)
(cherry picked from commit 8e7af79aa9)
2022-04-03 14:02:22 +03:00
Diego Medina
ba57cb410e fix(dashboard): scrolling table viz overlaps next chart (#19121)
(cherry picked from commit 74910f99d8)
2022-04-03 14:02:21 +03:00
Jinghuayao
37162a923b test(native filter): add new native filter test (#19115)
* add new native filter test

(cherry picked from commit 981f09b5db)
2022-04-03 14:02:21 +03:00
David Aaron Suddjian
0598e95b1b chore(embedded): refresh the guest token (#19132)
* refresh the guest token

* put back the date logic

* version

* fix time hijinks

* test

* Update superset-embedded-sdk/src/guestTokenRefresh.ts

(cherry picked from commit 54b60ded8e)
2022-04-03 14:02:21 +03:00
Beto Dealmeida
2e6bd1590d feat: helper functions for RLS (#19055)
* feat: helper functions for RLS

* Add function to inject RLS

* Add UNION tests

* Add tests for schema

* Add more tests; cleanup

* has_table_query via tree traversal

* Wrap existing predicate in parenthesis

* Clean up logic

* Improve table matching

(cherry picked from commit 8234395466)
2022-04-03 14:02:21 +03:00
Hugh A. Miles II
20fd7a7cd5 fix: Add perm for showing DBC-UI in Global Nav (#19023)
* add perm for global db add

* fix permissions

* missing roles params

(cherry picked from commit c337491d0e)
2022-04-03 14:02:21 +03:00
Jesse Yang
fcca027b88 feat(select): keep options order when in single mode (#19085)
(cherry picked from commit ae13d8313b)
2022-04-03 14:02:20 +03:00
Lily Kuang
2b8b9b366a feat(embedded): add optional dashboard ui configuration (#19031)
* feat: add optional dashboard ui configuration

* change all flags to boolean

* update README and lint

(cherry picked from commit 124cb0dc66)
2022-04-03 14:02:20 +03:00
Stephen Liu
877ee42a1c feat(viz-gallery): add 'feature' tag and fuzzy search weighting (#18662)
* feat(viz-gallery): add 'feature' tag and fuzzy search weighting

* add search weight

* Update superset-frontend/src/explore/components/controls/VizTypeControl/VizTypeGallery.tsx

Co-authored-by: Evan Rusackas <evan@preset.io>

* Update superset-frontend/src/explore/components/controls/VizTypeControl/VizTypeGallery.tsx

Co-authored-by: Evan Rusackas <evan@preset.io>

* Update superset-frontend/src/explore/components/controls/VizTypeControl/VizTypeGallery.tsx

Co-authored-by: Evan Rusackas <evan@preset.io>

* Update superset-frontend/src/explore/components/controls/VizTypeControl/VizTypeGallery.tsx

Co-authored-by: Evan Rusackas <evan@preset.io>

* some improvements

* take metadata out

* use chartLabel enum to unify

* add test chart

* fix cache

* Resolving TS Lint issue

* Appeasing the linter

* Removing one example implementation

* Removing another example label implementation

* Removing the third example label implementation

Co-authored-by: Evan Rusackas <evan@preset.io>
(cherry picked from commit 7524e1e3c8)
2022-04-03 14:02:20 +03:00
Jesse Yang
a2fc96a9c3 refactor(TimezoneSelector): simplify override logics and tests (#19090)
(cherry picked from commit 3a78165d13)
2022-04-03 14:02:20 +03:00
smileydev
891798b871 fix(dashobard-edge-cutting): make to be not cut without Filter (#19080)
(cherry picked from commit 158396fb6c)
2022-04-03 14:02:20 +03:00
Lily Kuang
cb5d814fd7 fix: cache key with guest token rls (#19110)
* add guest rls clause to cache key

* lint

* pylint

* add app back

(cherry picked from commit 27268169e4)
2022-04-03 14:02:19 +03:00
7vikpeculiar
7d0ee284fa Modified alerts and reports docs for clarity (#19091)
(cherry picked from commit a37a4ed35f)
2022-04-03 14:02:19 +03:00
Kamil Gabryjelski
89edf8a7a9 fix(dashboard): Empty states overflowing small chart containers (#19095)
* fix(dashboard): Empty states overflowing small chart containers

* Fix test

(cherry picked from commit 70081a698f)
2022-04-03 14:02:19 +03:00
Kamil Gabryjelski
088f6f75ff perf(dashboard): Send chart requests before native filter requests (#19077)
(cherry picked from commit b8091e33a9)
2022-04-03 14:02:19 +03:00
smileydev
d0c9df4d7b fix(plugin-chart-echarts): make to allow the custome of x & y axis title margin i… (#18947)
* fix(chartviz): make to allow the custome of x & y axis title margin in  chart

* fix(chartviz): add eslint radix error in chart.js

* fix(chartviz): change the transformProps in chart plugin & creat helper.

* fix(chartviz): lint fix & chart.js back

* fix(plugin-chart-echarts): make to allow the custom margin of X & y axis in BoxPlot & Mixedtimeseries charts

* fix(plugin-chart-echarts): make to change changeNumber to changeInteger

* fix(plugin-chart-echarts): make to add license & change file name

(cherry picked from commit c79ee56884)
2022-04-03 14:02:19 +03:00
Ville Brofeldt
36561b7943 fix(dashboard): import handle missing excluded charts (#19088)
(cherry picked from commit 999c2c6826)
2022-04-03 14:02:18 +03:00
Smart-Codi
2193e17940 fix: Show Totals error with sort and group by together (#19072)
(cherry picked from commit bc6aad0a88)
2022-04-03 14:02:18 +03:00
Smart-Codi
dae9e7c020 fix database import error (#19037)
(cherry picked from commit e97cdba092)
2022-04-03 14:02:18 +03:00
Hugh A. Miles II
2c151f352e fix autocomplete (#19047)
(cherry picked from commit a21d8a0bf4)
2022-04-03 14:02:18 +03:00
Diego Medina
0aba34a807 fix: Pivot Table Conditional Formatting Doesn't Show All Options (#19071)
* fix: Pivot Table Conditional Formatting Doesn't Show All Options

* PR comments

* PR comments

(cherry picked from commit 0e0beceac1)
2022-04-03 14:02:18 +03:00
smileydev
67d7a7b115 fix(allow-db-explore): make that the set the allow-db-explore option (#19030)
(cherry picked from commit 62ad574c24)
2022-04-03 14:02:17 +03:00
Kamil Gabryjelski
cd2a958ce3 perf(dashboard): Improve performance of complex dashboards (#19064)
* perf(dashboard): Improve performance of filter indicators

* Improve perf of cross filters

* Rename old function

* Fix undefined

* fix type

* fix tests

* fix undefined

* Address code review comments

* Address code review comments

(cherry picked from commit 3c1fb944c1)
2022-04-03 14:02:17 +03:00
smileydev
4462cfeb0f fix(altered-modal): make specified text fields wrap in table (#18822)
* fix(altered-modal): make all text fields wrap

* fix(altered-modal): limit the wrap text in particular column

* fix(altered-modal): make to update the unit test

* fix(altered-modal): make to fix the type of columnsForWrapText

* fix(alerted-modal): make to fix the type of columnsForWrapTest with string type

(cherry picked from commit 220c46131e)
2022-04-03 14:02:17 +03:00
Diego Medina
4c9785f3e3 fix: enable find text browser functionality inside SQL Lab editor (#19061)
(cherry picked from commit fd757c4aa4)
2022-04-03 14:02:17 +03:00
Diego Medina
005949f6b9 fix: show the total row count in the SQL Lab Query History tab when limited by DISPLAY_MAX_ROW (#19054)
(cherry picked from commit bd76648e4e)
2022-04-03 14:02:17 +03:00
Geido
4bff8fe95e Control sortby based on series limit (#18950)
(cherry picked from commit f53f86f796)
2022-04-03 14:02:16 +03:00
Michael S. Molina
3729df2653 fix: Select clear and loading icons overlap (#19070)
(cherry picked from commit 79a7a5d1b1)
2022-04-03 14:02:16 +03:00
Michael S. Molina
56b1144abd fix: Dataset search when creating a chart (#19065)
(cherry picked from commit fd154f7ba6)
2022-04-03 14:02:16 +03:00
Elizabeth Thompson
253f80ab6d chore: log multiple errors (#14064)
* log all errors from db create

* return unique set of errors

* sort set for exceptions list

* run black

(cherry picked from commit c143b37128)
2022-04-03 14:02:16 +03:00
Grace Guo
e97b123961 fix(time-series table): display null values in time-series table and sortable (#19024)
* fix: display null values in time-series table and sortable

* add unit test

* fix unit test

* Add sortNumericValues with different nan treatment

Co-authored-by: Jesse Yang <jesse.yang@airbnb.com>
(cherry picked from commit d539fc217a)
2022-04-03 14:02:16 +03:00
Phillip Kelley-Dotson
bc65cf4509 fix: ensure validation for db modal for googlesheets (#19018)
* fix: ensure validation for db modal for googlesheets

* chain async function

(cherry picked from commit bb17decb06)
2022-04-03 14:02:15 +03:00
Srini Kadamati
3ce4f051d5 docs: renamed yugabyte to yugabytedb (#19068)
* docs: renamed yugabyte to yugabytedb

* fixed redirect error

* pass that test!

(cherry picked from commit 7af26a0492)
2022-04-03 14:02:15 +03:00
Diego Medina
8bef059624 Add previous line hotkey to SQL editor for macOS (#19052)
(cherry picked from commit aa0ec717a2)
2022-04-03 14:02:15 +03:00
Thomas Desrosiers
4b8fc06e5f fix: Update time grain expressions for Spark >= 3.x (#18690)
* Fix the time grain expressions for Spark >= 2.3.0

Spark removed date format string 'u' in Spark 3.0. Switch to using date_trunc which has been around since 2.3

* Review: Pull out time_grain_expressoins into its own thing

(cherry picked from commit 03b2b06e90)
2022-04-03 14:02:15 +03:00
Phillip Kelley-Dotson
29b46d00f9 fix: remove unnecessary divider (#19048)
* fix: remove unnecessary divider

* remove console

(cherry picked from commit 4d96393faf)
2022-04-03 14:02:15 +03:00
Jesse Yang
032f560c2c feat(select): sort exact and startsWith match to first (#18856)
(cherry picked from commit c75f233109)
2022-04-03 14:02:14 +03:00
Michael S. Molina
219fa570b0 chore: Moves Chart to the components folder (#19029)
(cherry picked from commit 04a36d5c92)
2022-04-03 14:02:14 +03:00
chanyou0311
05f25d350c Install and use vm-browserify for sandboxedEval (#19059)
(cherry picked from commit 2cc5678dfc)
2022-04-03 14:02:14 +03:00
Alex Rothberg
1658a9f6b4 docs(building): link frontend asset instructions correctly (#19050)
(cherry picked from commit e89f0abf95)
2022-04-03 14:02:14 +03:00
Erik Ritter
379676e1f6 fix: improve cypress flakiness (#19044)
(cherry picked from commit 002bd6ed0a)
2022-04-03 14:02:13 +03:00
Ville Brofeldt
02d9825b11 chore(plugin-chart-echarts): bump echarts 5.3.1 (#19041)
(cherry picked from commit 1b7d056126)
2022-04-03 14:02:13 +03:00
pablo-guerra
45dc7b5984 chore: adding Dutch language translations (NL) (#18965)
* added NL translations

* added Dutch to config

* fixed end of line on .po file

Co-authored-by: pablo.guerra-at-026399402087 <pablo.guerra@026399402087>
(cherry picked from commit 44675037bd)
2022-04-03 14:02:13 +03:00
Michael S. Molina
4e78efcf07 chore: Moves CRUD components to the Datasource component (#19032)
* chore: Moves CRUD components to the Datasource component

* Fixes imports

* Fixes less import

(cherry picked from commit 71b8d31e77)
2022-04-03 14:02:13 +03:00
Stephen Liu
1eac8712a4 fix(big-number): Big Number with Trendline Chart is not working if Time Grain is set to Month (#19043)
* fix(big-number): Big Number with Trendline Chart is not working if Time Grain is set to Month

* use start frequency.

(cherry picked from commit c32eaf47e5)
2022-04-03 14:02:12 +03:00
Duc Le Tu
9777e6d148 Update impala.mdx (#19040)
(cherry picked from commit b2ee13f6f8)
2022-04-03 14:02:12 +03:00
Karthikeyan Singaravelan
585b032a1a chore: Fix deprecated unittest aliases. (#19042)
(cherry picked from commit 864bafc655)
2022-04-03 14:02:12 +03:00
Hugh A. Miles II
fb5d77e404 feat: Allow users to bust cache in report dashboard + alerts charts + alert dashboards (#18795)
* wip

* add force cahce bypass option to alerts

* remove default for alerts to bypass cache

* save for now

* save for now

* fix

* commenting out for now

* fix linting

* remove link

* add back force id test

* add frontend test

* address

(cherry picked from commit 8c52fe3476)
2022-04-03 14:02:12 +03:00
Michael S. Molina
6178f0515a refactor: Deletes the common/components folder (#18999)
(cherry picked from commit 329855170e)
2022-04-03 14:02:12 +03:00
Kamil Gabryjelski
8640814a92 fix(plugin-chart-echarts): Apply temporary filters to Query B in explore (#18998)
* fix(explore): Extra filters not applied to query b in mixed timeseries

* Add return type

* Apply review comment

* Fix non-dnd filters

(cherry picked from commit 9f834e8317)
2022-04-03 14:02:11 +03:00
cccs-Dustin
00a53dae73 fix(SQL Editor): names new query tabs correctly (#18951)
* Added in code changes that now properly increment the Untitled Query SQL Lab tab names. All that is left is to add tests to make sure that the function works correctly

* Updated the code so that it adds to the untitled_query_numbers variable only if the character after the string 'Untitled Query ' is a number. This prevents any issues when trying to get the maximum value in the list.

* Refactored part of the mapping code, to make it shorter and easier to read/understand

* Fixed issues in the code that were causing some of the CI tests to fail

* Made code changes based on comments within the PR. Also added a unit test to make sure that the newQueryEditor function in the TabbedSqlEditors component works as intended

* Fixed the failing cypress test in tabs.test.js

(cherry picked from commit 5a5ff99c37)
2022-04-03 14:02:11 +03:00
Michael S. Molina
ea534e2386 feat: Adds support to multiple dependencies to the native filters (#18793)
* chore(native-filters): Remove cascading popovers from filter bar

Co-authored-by: Kamil Gabryjelski <kamil.gabryjelski@gmail.com>
2022-04-03 14:00:26 +03:00
Phillip Kelley-Dotson
073be5d74f chore: change case for upload selection (#19021)
* chore: change case for upload selection

* fix label

(cherry picked from commit 299b5dc644)
2022-04-03 13:52:39 +03:00
Beto Dealmeida
8951e23ac6 fix: remove unneeded complexity in migration (#19022)
(cherry picked from commit 50bb86d666)
2022-04-03 13:52:39 +03:00
smileydev
3500b31551 fix(nested-tab-available): make the another tabs into one tabs available (#18877)
* fix(nested-tab-available): make the another tabs into one tabs available

* fix(netsted-tab): remove code of disable nested tab

(cherry picked from commit 6fe2431676)
2022-04-03 13:52:39 +03:00
dependabot[bot]
fcf98ec889 chore(deps): bump url-parse from 1.5.7 to 1.5.10 in /docs (#19019)
Bumps [url-parse](https://github.com/unshiftio/url-parse) from 1.5.7 to 1.5.10.
- [Release notes](https://github.com/unshiftio/url-parse/releases)
- [Commits](https://github.com/unshiftio/url-parse/compare/1.5.7...1.5.10)

---
updated-dependencies:
- dependency-name: url-parse
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
(cherry picked from commit 6becd38e7f)
2022-04-03 13:52:39 +03:00
Jesse Yang
78e85aed02 feat: remove loading indicator when typing in select (#18799)
(cherry picked from commit 5a8eb09afb)
2022-04-03 13:52:39 +03:00
Beto Dealmeida
75afb3a7b6 feat: show user email in dashboard API (#19004)
* Feat: show user email in dashboard API

* Fix test

(cherry picked from commit be88cb9ba0)
2022-04-03 13:52:38 +03:00
John Bodley
3b2b6674f6 fix(sqllab): Replace stringified 'null' schema column values with NULL (#18992)
Co-authored-by: John Bodley <john.bodley@airbnb.com>
(cherry picked from commit 19eb73b316)
2022-04-03 13:52:38 +03:00
Ville Brofeldt
5a8cd3477b chore(cache): default to SimpleCache in debug mode (#18976)
* chore(cache): default to SimpleCache in debug mode

* lint

* clean up type

* use util

* fix integration test cache configs

* remove util from cache manager

* remove trailing comma

* fix more tests

* fix truthiness check

* fix tests and improve deprecation notice

* fix default cache threshold

* move debug check to cache_manager

* remove separate getter

* update docs

* remove default cache config

(cherry picked from commit a04f1d4c87)
2022-04-03 13:52:38 +03:00
Ville Brofeldt
6d2b583fee fix(chart): deprecate persisting url_params (#18960)
* fix(chart): deprecate peristing url_params

* remove duplicated backend logic

* use omitBy

* simplify omit

(cherry picked from commit bd63a1bd98)
2022-04-03 13:52:38 +03:00
Craig Rueda
3c90220cf6 fix(packages): Fixing users packages (#18973)
* Fixing users packages

* Linting me() fn

* Fixing tests / moving packages

* Fixing imports

(cherry picked from commit 5fc7adb55b)
2022-04-03 13:52:38 +03:00
Srini Kadamati
e8cf9446a6 docs: renamed yugabytedb to yugabyte as per request by Yugabyte team (#18983)
Co-authored-by: Srinivasa Kadamati <srinik@Srinivasas-MacBook-Air.local>
(cherry picked from commit 563cce1e29)
2022-04-03 13:52:37 +03:00
Brian Nguyen
4a91f76798 refactor: converted QueryAutoRefresh to functional component (#18179)
* converted file to functional component

* refactor: convert class component to functional component

* refactor: convert class component to functional"

* Working on converting the shouldCheckForQueries test to RTL

* Working on converting first test to RTL

* Working on first test for queryAutoRefresh

* Finished Tests, pushing for review

* Cleaned up comments and console logs

Co-authored-by: Josue Lugaro <josuelugaro15@gmail.com>
(cherry picked from commit f497c1900e)
2022-04-03 13:52:37 +03:00
Ville Brofeldt
603f43bd95 bump and harmonize urijs and xss (#18922)
(cherry picked from commit 834686a3d9)
2022-04-03 13:52:37 +03:00
Kamil Gabryjelski
8bfb2f854e chore(native-filters): Add unit tests for filter cards (#18967)
* chore(native-filters): Add unit tests for filter cards

* Fix test

(cherry picked from commit ec746c2a10)
2022-04-03 13:52:37 +03:00
smileydev
178736ad27 fix(tooltip-not-dissapeared): make the tooltip disappear when mouse away (#18892)
* fix(tooltip-not-dissapeared): make the tooltip disappear when mouse away

* fix(tooltip-not-dissapeared): change css props instead of sytles props

(cherry picked from commit ca93d63bbb)
2022-04-03 13:52:37 +03:00
smileydev
fe0f1de64b fix(external-link): change the external link in creating chart dashboard (#18982)
(cherry picked from commit 37752cea9b)
2022-04-03 13:52:36 +03:00
Kamil Gabryjelski
f7b72d9486 fix(native-filters): Default value not shown in native filters (#18963)
* fix(native-filters): Default value not shown in native filters

* Reuse stringified datamask

(cherry picked from commit 2072225a86)
2022-04-03 13:52:36 +03:00
Stephen Liu
1f4ff51322 fix(plugin-chart-echarts): fix customize margin (#18958)
(cherry picked from commit c4e3c45b3c)
2022-04-03 13:52:36 +03:00
Grace Guo
928309841c fix: add/find owners from report/alert modal (#18971)
(cherry picked from commit 7e336d1230)
2022-04-03 13:52:36 +03:00
John Bodley
10d382de56 chore(security): Remove obsolete FAB metric_access permission (#16860)
* Update manager.py

* Update manager.py

* Update manager.py

* Update manager.py

(cherry picked from commit 85f0715644)
2022-04-03 13:52:36 +03:00
serenajiang
46015e2c66 feat(TimeTableViz): sort by first metric (#18896)
(cherry picked from commit 760dab9abd)
2022-04-03 13:52:36 +03:00
Geido
da64e7966f fix(Explore): Pivot table V2 sort by failure with D&D enabled (#18835)
* wip

* Add tests and clean up

* Clean up

* Remove unused import

(cherry picked from commit eafe0cfc6f)
2022-04-03 13:52:35 +03:00
Kamil Gabryjelski
335a90a5ac feat(legacy-preset-chart-deckgl): Add ,.1f and ,.2f value formats to deckgl charts (#18945)
* Add ,.1f and ,.2f value formats to deckgl charts

* Remove duplicated code

(cherry picked from commit c56dc8eace)
2022-04-03 13:52:35 +03:00
GaryNg
ee3b3aea5d docs: fix sql templating typos (#18955)
(cherry picked from commit 4775d3900f)
2022-04-03 13:52:35 +03:00
Ville Brofeldt
268ce0ae8b fix(dataset): handle missing database in migration (#18948)
(cherry picked from commit 2baceddbf1)
2022-04-03 13:52:35 +03:00
AAfghahi
9375ebfbff fix(sql Lab tabs): Empty SQL Lab tabs (#18817)
* Empty SQL table message on zero tabs

* sql editor no editor tab bug fix

* Revert Error message

* empty state tab state

* added a unit test

* addressed reviews

* kasia feedback

Co-authored-by: Yahya Kayani <yahyakiani1@gmail.com>
(cherry picked from commit 147dc5af71)
2022-04-03 13:52:35 +03:00
John Bodley
5b465c2ff1 fix: bump Helm chart release version (#18751) (#18758)
Co-authored-by: wiktor2200 <wiktor2200@users.noreply.github.com>
(cherry picked from commit 099421770c)
2022-04-03 13:52:35 +03:00
Smart-Codi
a76ae2edb6 fix: null schema issue in saved queries (#18849)
(cherry picked from commit 79633ce673)
2022-04-03 13:52:34 +03:00
Michael S. Molina
419ca75412 chore: Moves components out of the commons folder (#18931)
* refactor: Moves components out of the commons folder

* Fixes tests

(cherry picked from commit fd4bd1edbc)
2022-04-03 13:52:34 +03:00
Stephen Liu
2fc2e275d4 fix(deck.gl): multiple layers map size is shrunk (#18939)
(cherry picked from commit 2cb3635256)
2022-04-03 13:52:34 +03:00
Stephen Liu
ce61dbc2bc fix(native-filter): fix required filters of a dashboard won't load properly (#18695)
(cherry picked from commit 0b1bc5b5de)
2022-04-03 13:52:34 +03:00
Jinghuayao
77c8987bbe test(Native Filter): User can create parent filters using "Filter is hierarchical (#18915)
* add new native test for parent filter

(cherry picked from commit 2bd8d3b349)
2022-04-03 13:52:33 +03:00
Smart-Codi
b78bced141 fix: Monospacing errors in dashboards & charts (#18796)
* fix: Monospacing errors in dashboards & charts

* removed unnecessary styling

(cherry picked from commit 4923256b01)
2022-04-03 13:52:33 +03:00
Smart-Codi
4167cfa30e fix Metadata browser in SQL not render nicely in Safari (#18855)
(cherry picked from commit 0db49b1a7c)
2022-04-03 13:52:33 +03:00
Phillip Kelley-Dotson
e20788c0e1 chore: add intersect method from backend to fontend for upload extensions (#18811)
* chore: add intersect method from be to font end

* fix lint

* add suggestion

* fix python test

* run precommit

* fix pytlint

* update changes from masters

(cherry picked from commit 8d38675cbc)
2022-04-03 13:52:33 +03:00
1064 changed files with 72214 additions and 32278 deletions

2
.github/CODEOWNERS vendored
View File

@@ -11,4 +11,4 @@
/superset-frontend/src/components/Select/ @michael-s-molina @geido
# Notify Helm Chart maintainers about changes in it
/helm/superset/ @craig-rueda
/helm/superset/ @craig-rueda @dpgaspar @villebro

View File

@@ -20,4 +20,5 @@ jobs:
node-version: "16"
registry-url: 'https://registry.npmjs.org'
- run: npm ci
- run: npm test
- run: npm run build

2
.gitignore vendored
View File

@@ -108,3 +108,5 @@ release.json
messages.mo
docker/requirements-local.txt
cache/

View File

@@ -20,7 +20,7 @@ repos:
hooks:
- id: isort
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v0.910
rev: v0.941
hooks:
- id: mypy
additional_dependencies: [types-all]
@@ -41,7 +41,7 @@ repos:
- id: trailing-whitespace
args: ["--markdown-linebreak-ext=md"]
- repo: https://github.com/psf/black
rev: 19.10b0
rev: 22.3.0
hooks:
- id: black
language_version: python3

File diff suppressed because it is too large Load Diff

View File

@@ -106,7 +106,7 @@ This statement thanks the following, on which it draws for content and inspirati
# Slack Community Guidelines
If you decide to join the [Community Slack](https://join.slack.com/t/apache-superset/shared_invite/zt-uxbh5g36-AISUtHbzOXcu0BIj7kgUaw), please adhere to the following rules:
If you decide to join the [Community Slack](https://join.slack.com/t/apache-superset/shared_invite/zt-16jvzmoi8-sI7jKWp~xc2zYRe~NqiY9Q), please adhere to the following rules:
**1. Treat everyone in the community with respect.**

View File

@@ -198,7 +198,7 @@ Finally, never submit a PR that will put master branch in broken state. If the P
#### Authoring
- Fill in all sections of the PR template.
- Title the PR with one of the following semantic prefixes (inspired by [Karma](http://karma-runner.github.io/0.10/dev/git-commit-msg.html])):
- Title the PR with one of the following semantic prefixes (inspired by [Karma](http://karma-runner.github.io/0.10/dev/git-commit-msg.html)):
- `feat` (new feature)
- `fix` (bug fix)
@@ -412,7 +412,7 @@ You also need to install MySQL or [MariaDB](https://mariadb.com/downloads).
Ensure that you are using Python version 3.7 or 3.8, then proceed with:
````bash
```bash
# Create a virtual environment and activate it (recommended)
python3 -m venv venv # setup a python3 virtualenv
source venv/bin/activate
@@ -457,7 +457,7 @@ $ make superset
# Setup pre-commit only
$ make pre-commit
````
```
**Note: the FLASK_APP env var should not need to be set, as it's currently controlled
via `.flaskenv`, however if needed, it should be set to `superset.app:create_app()`**
@@ -663,8 +663,8 @@ tox -e pylint
In terms of best practices please advoid blanket disablement of Pylint messages globally (via `.pylintrc`) or top-level within the file header, albeit there being a few exceptions. Disablement should occur inline as it prevents masking issues and provides context as to why said message is disabled.
Additionally the Python code is auto-formatted using [Black](https://github.com/python/black) which
is configured as a pre-commit hook. There are also numerous [editor integrations](https://black.readthedocs.io/en/stable/editor_integration.html)
Additionally, the Python code is auto-formatted using [Black](https://github.com/python/black) which
is configured as a pre-commit hook. There are also numerous [editor integrations](https://black.readthedocs.io/en/stable/integrations/editors.html)
### TypeScript

View File

@@ -18,7 +18,7 @@
######################################################################
# PY stage that simply does a pip install on our requirements
######################################################################
ARG PY_VER=3.8.12
ARG PY_VER=3.8.13
FROM python:${PY_VER} AS superset-py
RUN mkdir /app \
@@ -71,7 +71,7 @@ RUN cd /app/superset-frontend \
######################################################################
# Final lean image...
######################################################################
ARG PY_VER=3.8.12
ARG PY_VER=3.8.13
FROM python:${PY_VER} AS lean
ENV LANG=C.UTF-8 \

View File

@@ -25,7 +25,7 @@ under the License.
[![PyPI version](https://badge.fury.io/py/apache-superset.svg)](https://badge.fury.io/py/apache-superset)
[![Coverage Status](https://codecov.io/github/apache/superset/coverage.svg?branch=master)](https://codecov.io/github/apache/superset)
[![PyPI](https://img.shields.io/pypi/pyversions/apache-superset.svg?maxAge=2592000)](https://pypi.python.org/pypi/apache-superset)
[![Get on Slack](https://img.shields.io/badge/slack-join-orange.svg)](https://join.slack.com/t/apache-superset/shared_invite/zt-uxbh5g36-AISUtHbzOXcu0BIj7kgUaw)
[![Get on Slack](https://img.shields.io/badge/slack-join-orange.svg)](https://join.slack.com/t/apache-superset/shared_invite/zt-16jvzmoi8-sI7jKWp~xc2zYRe~NqiY9Q)
[![Documentation](https://img.shields.io/badge/docs-apache.org-blue.svg)](https://superset.apache.org)
<img
@@ -47,7 +47,7 @@ A modern, enterprise-ready business intelligence web application.
## Why Superset?
Superset is a modern data exploration and data visualization platform. Superset can replace or augment proprietary business intelligence tools for many teams.
Superset is a modern data exploration and data visualization platform. Superset can replace or augment proprietary business intelligence tools for many teams. Superset integrates well with a variety of data sources.
Superset provides:
@@ -129,7 +129,7 @@ Want to add support for your datastore or data engine? Read more [here](https://
## Get Involved
- Ask and answer questions on [StackOverflow](https://stackoverflow.com/questions/tagged/apache-superset) using the **apache-superset** tag
- [Join our community's Slack](https://join.slack.com/t/apache-superset/shared_invite/zt-uxbh5g36-AISUtHbzOXcu0BIj7kgUaw)
- [Join our community's Slack](https://join.slack.com/t/apache-superset/shared_invite/zt-16jvzmoi8-sI7jKWp~xc2zYRe~NqiY9Q)
and please read our [Slack Community Guidelines](https://github.com/apache/superset/blob/master/CODE_OF_CONDUCT.md#slack-community-guidelines)
- [Join our dev@superset.apache.org Mailing list](https://lists.apache.org/list.html?dev@superset.apache.org)
@@ -144,7 +144,7 @@ how to set up a development environment.
- Getting Started with Superset
- [Superset in 2 Minutes using Docker Compose](https://superset.apache.org/docs/installation/installing-superset-using-docker-compose#installing-superset-locally-using-docker-compose)
- [Installing Database Drivers](https://superset.apache.org/docs/databases/dockeradddrivers)
- [Installing Database Drivers](https://superset.apache.org/docs/databases/docker-add-drivers/)
- [Building New Database Connectors](https://preset.io/blog/building-database-connector/)
- [Create Your First Dashboard](https://superset.apache.org/docs/creating-charts-dashboards/first-dashboard)
- [Comprehensive Tutorial for Contributing Code to Apache Superset

View File

@@ -34,7 +34,7 @@ RUN apt-get install -y build-essential libssl-dev \
# Install nodejs for custom build
# https://nodejs.org/en/download/package-manager/
RUN curl -sL https://deb.nodesource.com/setup_12.x | bash - \
RUN curl -sL https://deb.nodesource.com/setup_16.x | bash - \
&& apt-get install -y nodejs
RUN mkdir -p /home/superset

View File

@@ -34,7 +34,7 @@ RUN apt-get install -y build-essential libssl-dev \
# Install nodejs for custom build
# https://nodejs.org/en/download/package-manager/
RUN curl -sL https://deb.nodesource.com/setup_12.x | bash - \
RUN curl -sL https://deb.nodesource.com/setup_16.x | bash - \
&& apt-get install -y nodejs
RUN mkdir -p /home/superset

View File

@@ -30,6 +30,7 @@ partaking in the process should join the channel.
## Release notes for recent releases
- [1.5](release-notes-1-5/README.md)
- [1.4](release-notes-1-4/README.md)
- [1.3](release-notes-1-3/README.md)
- [1.2](release-notes-1-2/README.md)
@@ -287,6 +288,8 @@ cd ~/src/superset/
git branch
# Create the release tag
git tag -f ${SUPERSET_VERSION}
# push the tag to the remote
git push upstream ${SUPERSET_VERSION}
```
### Update CHANGELOG and UPDATING on superset

View File

@@ -167,7 +167,10 @@ class GitChangeLog:
return f"### {self._version} ({self._logs[0].time})"
def _parse_change_log(
self, changelog: Dict[str, str], pr_info: Dict[str, str], github_login: str,
self,
changelog: Dict[str, str],
pr_info: Dict[str, str],
github_login: str,
) -> None:
formatted_pr = (
f"- [#{pr_info.get('id')}]"
@@ -355,7 +358,8 @@ def compare(base_parameters: BaseParameters) -> None:
@cli.command("changelog")
@click.option(
"--csv", help="The csv filename to export the changelog to",
"--csv",
help="The csv filename to export the changelog to",
)
@click.option(
"--access_token",
@@ -381,12 +385,12 @@ def change_log(
with open(csv, "w") as csv_file:
log_items = list(logs)
field_names = log_items[0].keys()
writer = lib_csv.DictWriter( # type: ignore
writer = lib_csv.DictWriter(
csv_file,
delimiter=",",
quotechar='"',
quoting=lib_csv.QUOTE_ALL,
fieldnames=field_names, # type: ignore
fieldnames=field_names,
)
writer.writeheader()
for log in logs:

View File

@@ -0,0 +1,142 @@
<!--
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.
-->
# Release Notes for Superset 1.5
Superset 1.5 focuses on polishing the dashboard native filters experience, while
improving performance and stability. Superset 1.5 is likely the last minor release of
version 1 of Superset, and will be succeeded by Superset 2.0. The 1.5 branch
introduces the notion of a Long Term Support (LTS) version of Superset, and will
receive security and other critical fixes even after Superset 2.x is released.
Therefore, users will have the choice of staying on the 1.5 branch or upgrading to 2.x
when available.
- [**User Experience**](#user-facing-features)
- [**Feature flags**](#feature-flags)
- [**Database Experience**](#database-experience)
- [**Breaking Changes and Full Changelog**](#breaking-changes-and-full-changelog)
## User Facing Features
- Complex dashboards with lots of native filters and charts will render considerably
faster. See the videos that shows the rendering time of a complex dashboard go from
11 to 3 seconds: [#19064](https://github.com/apache/superset/pull/19064). In
addition, applying filters and switching tabs is also much smoother.
- The Native Filter Bar has been redesigned, along with moving the "Apply" and
"Clear all" buttons to the bottom:
![Filter bar](media/filter_bar.png)
- Native filters can now be made dependent on multiple filters. This makes it possible
to restrict the available values in a filter based on the selection of other filters.
![Dependent filters](media/dependent_filters.png)
- In addition to being able to write Custom SQL for adhoc metrics and filters, the
column control now also features a Custom SQL tab. This makes it possible to write
custom expressions directly in charts without adding them to the dataset as saved
expressions.
![Adhoc columns](media/adhoc_columns.png)
- A new `SupersetMetastoreCache` has been added which makes it possible to cache data
in the Superset Metastore without the need for running a dedicated cache like Redis
or Memcached. The new cache will be used by default for required caches, but can also
be used for caching chart or other data. See the
[documentation](https://superset.apache.org/docs/installation/cache#caching) for
details on using the new cache.
- Previously it was possible for Dashboards with lots of filters to cause an error.
A similar issue existed on Explore. Now Superset stores Dashboard and Explore state
in the cache (as opposed to the URL), eliminating the infamous
[Long URL Problem](https://github.com/apache/superset/issues/17086).
- Previously permanent links to Dashboard and Explore pages were in fact shortened URLS
that relied on state being stored in the URL (see Long URL Problem above). In
addition, the links used numerical ids and didn't check user permissions making it
easy to iterate through links that were stored in the metastore. Now permanent links
state is stored as JSON objects in the metastore, making it possible to store
arbitrarily large Dashboard and Explore state in permalinks. In addition, the ids
are encoded using [`hashids`](https://hashids.org/) and check permissions, making
permalink state more secure.
![Dashboard permalink](media/permalink.png)
## Feature flags
- A new feature flag `GENERIC_CHART_AXES` has been added that makes it possible to
use a non-temporal x-axis on the ECharts Timeseries chart
([#17917](https://github.com/apache/superset/pull/17917)). When enabled, a new
control "X Axis" is added to the control panel of ECharts line, area, bar, step and
scatter charts, which makes it possible to use categorical or numerical x-axes on
those charts.
![Categorical line chart](media/categorical_line.png)
## Database Experience
- DuckDB: Add support for database:
[#19317](https://github.com/apache/superset/pull/19317)
- Kusto: Add support for Azure Data Explorer (Kusto):
[#17898](https://github.com/apache/superset/pull/17898)
- Trino: Add server cert support and new auth methods:
[#17593](https://github.com/apache/superset/pull/17593) and
[#16346](https://github.com/apache/superset/pull/16346)
- Microsoft SQL Server (MSSQL): support using CTEs in virtual tables:
[#18567](https://github.com/apache/superset/pull/18567)
- Teradata and MSSQL: add support for TOP limit syntax:
[#18746](https://github.com/apache/superset/pull/18746) and
[#18240](https://github.com/apache/superset/pull/18240)
- Apache Drill: User impersonation using `drill+sadrill`:
[#19252](https://github.com/apache/superset/pull/19252)
## Developer Experience
- `superset-ui` has now been integrated into the Superset codebase as per
[SIP-58](https://github.com/apache/superset/issues/13013) dubbed "Monorepo". This
makes development of plugins that ship with Superset considerably simpler. In
addition, it makes it possible to align `superset-ui` releases with official Superset
releases.
## Breaking Changes and Full Changelog
**Breaking Changes**
- Bump `mysqlclient` from v1 to v2:
[#17556](https://github.com/apache/superset/pull/17556)
- Single and double quotes will no longer be removed from filter values:
[#17881](https://github.com/apache/superset/pull/17881)
- Previously `QUERY_COST_FORMATTERS_BY_ENGINE`, `SQL_VALIDATORS_BY_ENGINE` and
`SCHEDULED_QUERIES` were expected to be defined in the feature flag dictionary in
the `config.py` file. These should now be defined as a top-level config, with the
feature flag dictionary being reserved for boolean only values:
[#15254](https://github.com/apache/superset/pull/15254)
- All Superset CLI commands (init, load_examples and etc) require setting the
`FLASK_APP` environment variable (which is set by default when `.flaskenv` is loaded):
[#17539](https://github.com/apache/superset/pull/17539)
**Changelog**
To see the complete changelog in this release, head to
[CHANGELOG.MD](https://github.com/apache/superset/blob/1.5/CHANGELOG.md).
As mentioned earlier, this release has a MASSIVE amount of bug fixes. The full
changelog lists all of them!

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 301 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 428 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 359 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 184 KiB

View File

@@ -106,7 +106,12 @@ def inter_send_email(
class BaseParameters(object):
def __init__(
self, email: str, username: str, password: str, version: str, version_rc: str,
self,
email: str,
username: str,
password: str,
version: str,
version_rc: str,
) -> None:
self.email = email
self.username = username

View File

@@ -22,14 +22,28 @@ under the License.
This file documents any backwards-incompatible changes in Superset and
assists people when migrating to a new version.
## Next
## 1.5.3
### Other
- [22022](https://github.com/apache/superset/pull/22022): HTTP API endpoints `/superset/approve` and `/superset/request_access` have been deprecated and their HTTP methods were changed from GET to POST
- [21895](https://github.com/apache/superset/pull/21895): Markdown components had their security increased by adhering to the same sanitization process enforced by Github. This means that some HTML elements found in markdowns are not allowed anymore due to the security risks they impose. If you're deploying Superset in a trusted environment and wish to use some of the blocked elements, then you can use the HTML_SANITIZATION_SCHEMA_EXTENSIONS configuration to extend the default sanitization schema. There's also the option to disable HTML sanitization using the HTML_SANITIZATION configuration but we do not recommend this approach because of the security risks. Given the provided configurations, we don't view the improved sanitization as a breaking change but as a security patch.
## 1.5.2
### Other
- [19570](https://github.com/apache/superset/pull/19570): makes [sqloxide](https://pypi.org/project/sqloxide/) optional so the SIP-68 migration can be run on aarch64. If the migration is taking too long installing sqloxide manually should improve the performance.
## 1.5.0
### Breaking Changes
- [18976](https://github.com/apache/superset/pull/18976): When running the app in debug mode, the app will default to use `SimpleCache` for `FILTER_STATE_CACHE_CONFIG` and `EXPLORE_FORM_DATA_CACHE_CONFIG`. When running in non-debug mode, a cache backend will need to be defined, otherwise the application will fail to start. For installations using Redis or other caching backends, it is recommended to use the same backend for both cache configs.
- [17881](https://github.com/apache/superset/pull/17881): Previously simple adhoc filter values on string columns were stripped of enclosing single and double quotes. To fully support literal quotes in filters, both single and double quotes will no longer be removed from filter values.
- [17984](https://github.com/apache/superset/pull/17984): Default Flask SECRET_KEY has changed for security reasons. You should always override with your own secret. Set `PREVIOUS_SECRET_KEY` (ex: PREVIOUS_SECRET_KEY = "\2\1thisismyscretkey\1\2\\e\\y\\y\\h") with your previous key and use `superset re-encrypt-secrets` to rotate you current secrets
- [15254](https://github.com/apache/superset/pull/15254): Previously `QUERY_COST_FORMATTERS_BY_ENGINE`, `SQL_VALIDATORS_BY_ENGINE` and `SCHEDULED_QUERIES` were expected to be defined in the feature flag dictionary in the `config.py` file. These should now be defined as a top-level config, with the feature flag dictionary being reserved for boolean only values.
- [17539](https://github.com/apache/superset/pull/17539): all Superset CLI commands (init, load_examples and etc) require setting the FLASK_APP environment variable (which is set by default when `.flaskenv` is loaded)
- [17556](https://github.com/apache/superset/pull/17556): Bumps `mysqlclient` from v1 to v2.
- [17539](https://github.com/apache/superset/pull/17539): All Superset CLI commands, e.g. `init`, `load_examples`, etc. require setting the `FLASK_APP` environment variable (which is set by default when `.flaskenv` is loaded).
- [15254](https://github.com/apache/superset/pull/15254): The `QUERY_COST_FORMATTERS_BY_ENGINE`, `SQL_VALIDATORS_BY_ENGINE` and `SCHEDULED_QUERIES` feature flags are now defined as config keys given that feature flags are reserved for boolean only values.
### Potential Downtime
@@ -42,11 +56,25 @@ assists people when migrating to a new version.
### Deprecations
- [18960](https://github.com/apache/superset/pull/18960): Persisting URL params in chart metadata is no longer supported. To set a default value for URL params in Jinja code, use the optional second argument: `url_param("my-param", "my-default-value")`.
### Other
- [17589](https://github.com/apache/incubator-superset/pull/17589): It is now possible to limit access to users' recent activity data by setting the `ENABLE_BROAD_ACTIVITY_ACCESS` config flag to false, or customizing the `raise_for_user_activity_access` method in the security manager.
- [17536](https://github.com/apache/superset/pull/17536): introduced a key-value endpoint to store dashboard filter state. This endpoint is backed by Flask-Caching and the default configuration assumes that the values will be stored in the file system. If you are already using another cache backend like Redis or Memchached, you'll probably want to change this setting in `superset_config.py`. The key is `FILTER_STATE_CACHE_CONFIG` and the available settings can be found in Flask-Caching [docs](https://flask-caching.readthedocs.io/en/latest/).
- [17882](https://github.com/apache/superset/pull/17882): introduced a key-value endpoint to store Explore form data. This endpoint is backed by Flask-Caching and the default configuration assumes that the values will be stored in the file system. If you are already using another cache backend like Redis or Memchached, you'll probably want to change this setting in `superset_config.py`. The key is `EXPLORE_FORM_DATA_CACHE_CONFIG` and the available settings can be found in Flask-Caching [docs](https://flask-caching.readthedocs.io/en/latest/).
- [17589](https://github.com/apache/superset/pull/17589): It is now possible to limit access to users' recent activity data by setting the `ENABLE_BROAD_ACTIVITY_ACCESS` config flag to false, or customizing the `raise_for_user_activity_access` method in the security manager.
- [17536](https://github.com/apache/superset/pull/17536): introduced a key-value endpoint to store dashboard filter state. This endpoint is backed by Flask-Caching and the default configuration assumes that the values will be stored in the file system. If you are already using another cache backend like Redis or Memcached, you'll probably want to change this setting in `superset_config.py`. The key is `FILTER_STATE_CACHE_CONFIG` and the available settings can be found in Flask-Caching [docs](https://flask-caching.readthedocs.io/en/latest/).
- [17882](https://github.com/apache/superset/pull/17882): introduced a key-value endpoint to store Explore form data. This endpoint is backed by Flask-Caching and the default configuration assumes that the values will be stored in the file system. If you are already using another cache backend like Redis or Memcached, you'll probably want to change this setting in `superset_config.py`. The key is `EXPLORE_FORM_DATA_CACHE_CONFIG` and the available settings can be found in Flask-Caching [docs](https://flask-caching.readthedocs.io/en/latest/).
## 1.4.1
### Breaking Changes
- [17984](https://github.com/apache/superset/pull/17984): Default Flask SECRET_KEY has changed for security reasons. You should always override with your own secret. Set `PREVIOUS_SECRET_KEY` (ex: PREVIOUS_SECRET_KEY = "\2\1thisismyscretkey\1\2\\e\\y\\y\\h") with your previous key and use `superset re-encrypt-secrets` to rotate you current secrets
### Potential Downtime
### Deprecations
### Other
## 1.4.0

View File

@@ -41,7 +41,7 @@ ADMIN_PASSWORD="admin"
# If Cypress run overwrite the password for admin and export env variables
if [ "$CYPRESS_CONFIG" == "true" ]; then
ADMIN_PASSWORD="general"
export SUPERSET_CONFIG=tests.superset_test_config
export SUPERSET_CONFIG=tests.integration_tests.superset_test_config
export SUPERSET_TESTENV=true
export ENABLE_REACT_CRUD_VIEWS=true
export SUPERSET__SQLALCHEMY_DATABASE_URI=postgresql+psycopg2://superset:superset@db:5432/superset

View File

@@ -69,6 +69,16 @@ REDIS_RESULTS_DB = get_env_variable("REDIS_RESULTS_DB", "1")
RESULTS_BACKEND = FileSystemCache("/app/superset_home/sqllab")
CACHE_CONFIG = {
"CACHE_TYPE": "redis",
"CACHE_DEFAULT_TIMEOUT": 300,
"CACHE_KEY_PREFIX": "superset_",
"CACHE_REDIS_HOST": REDIS_HOST,
"CACHE_REDIS_PORT": REDIS_PORT,
"CACHE_REDIS_DB": REDIS_RESULTS_DB,
}
DATA_CACHE_CONFIG = CACHE_CONFIG
class CeleryConfig(object):
BROKER_URL = f"redis://{REDIS_HOST}:{REDIS_PORT}/{REDIS_CELERY_DB}"

View File

@@ -27,6 +27,7 @@ gunicorn \
--worker-class ${SERVER_WORKER_CLASS:-gthread} \
--threads ${SERVER_THREADS_AMOUNT:-20} \
--timeout ${GUNICORN_TIMEOUT:-60} \
--keep-alive ${GUNICORN_KEEPALIVE:-2} \
--limit-request-line ${SERVER_LIMIT_REQUEST_LINE:-0} \
--limit-request-field_size ${SERVER_LIMIT_REQUEST_FIELD_SIZE:-0} \
"${FLASK_APP}"

View File

@@ -24,7 +24,7 @@ This website is built using [Docusaurus 2](https://docusaurus.io/), a modern sta
### Installation
```
$ yarn
$ yarn install
```
### Local Development

View File

@@ -4,12 +4,12 @@ hide_title: true
sidebar_position: 9
---
import { Buffer } from "buffer";
import { Buffer } from 'buffer';
global.Buffer = Buffer;
import SwaggerUI from "swagger-ui-react";
import openapi from "/resources/openapi.json";
import "swagger-ui-react/swagger-ui.css";
// import { Alert } from "antd";
import SwaggerUI from 'swagger-ui-react';
import openapi from '/resources/openapi.json';
import 'swagger-ui-react/swagger-ui.css';
import { Alert } from 'antd';
## API
@@ -18,28 +18,16 @@ Superset's public **REST API** follows the
documented here. The docs bellow are generated using
[Swagger React UI](https://www.npmjs.com/package/swagger-ui-react).
<!--
TODO: (corbinrobb) Uncomment Alert if/when antd gets added and remove Infima alert. Fix SwaggerUI readability in dark mode.
-->
<!-- <Alert
<Alert
type="info"
message={
<div>
<strong>NOTE! </strong>
You can find an interactive version of this documentation on your local Superset
instance at <strong>/swagger/v1</strong> (if enabled)
instance at <strong>/swagger/v1</strong> (unless disabled)
</div>
}
/> -->
<div class="alert alert--info" role="alert">
<strong>NOTE! </strong>
You can find an interactive version of this documentation on your local Superset
instance at <strong>/swagger/v1</strong> (if enabled)
</div>
}
/>
<br />
<br />

View File

@@ -8,11 +8,11 @@ version: 1
## Contributing to Superset
Superset is an [Apache Software foundation](https://www.apache.org/theapacheway/index.html) project.
The core contributors (or committers) to Superset communicate primarily in the following channels (all of
which you can join):
The core contributors (or committers) to Superset communicate primarily in the following channels (
which can be joined by anyone):
- [Mailing list](https://lists.apache.org/list.html?dev@superset.apache.org)
- [Apache Superset Slack community](https://join.slack.com/t/apache-superset/shared_invite/zt-uxbh5g36-AISUtHbzOXcu0BIj7kgUaw)
- [Apache Superset Slack community](https://join.slack.com/t/apache-superset/shared_invite/zt-16jvzmoi8-sI7jKWp~xc2zYRe~NqiY9Q)
- [Github issues and PR's](https://github.com/apache/superset/issues)
More references:

View File

@@ -39,10 +39,10 @@ We use [Pylint](https://pylint.org/) for linting which can be invoked via:
tox -e pylint
```
In terms of best practices please advoid blanket disablement of Pylint messages globally (via `.pylintrc`) or top-level within the file header, albeit there being a few exceptions. Disablement should occur inline as it prevents masking issues and provides context as to why said message is disabled.
In terms of best practices please avoid blanket disablement of Pylint messages globally (via `.pylintrc`) or top-level within the file header, albeit there being a few exceptions. Disablement should occur inline as it prevents masking issues and provides context as to why said message is disabled.
Additionally the Python code is auto-formatted using [Black](https://github.com/python/black) which
is configured as a pre-commit hook. There are also numerous [editor integrations](https://black.readthedocs.io/en/stable/editor_integration.html)
Additionally, the Python code is auto-formatted using [Black](https://github.com/python/black) which
is configured as a pre-commit hook. There are also numerous [editor integrations](https://black.readthedocs.io/en/stable/integrations/editors.html)
### TypeScript

View File

@@ -103,4 +103,4 @@ app.logger.info(form_data)
```
### Frontend Assets
See [Running Frontend Assets Locally](https://superset.apache.org/docs/installation/installing-superset-from-scratch#os-dependencies)
See [Building Frontend Assets Locally](https://github.com/apache/superset/blob/master/CONTRIBUTING.md#frontend)

View File

@@ -189,3 +189,23 @@ all charts will load their data even if feature flag is turned on and no roles a
to roles the access will fallback to **Dataset permissions**
<img src={useBaseUrl("/img/tutorial/tutorial_dashboard_access.png" )} />
### Customizing dashboard
The following URL parameters can be used to modify how the dashboard is rendered:
- `standalone`:
- `0` (default): dashboard is displayed normally
- `1`: Top Navigation is hidden
- `2`: Top Navigation + title is hidden
- `3`: Top Navigation + title + top level tabs are hidden
- `show_filters`:
- `0`: render dashboard without Filter Bar
- `1` (default): render dashboard with Filter Bar if native filters are enabled
- `expand_filters`:
- (default): render dashboard with Filter Bar expanded if there are native filters
- `0`: render dashboard with Filter Bar collapsed
- `1`: render dashboard with Filter Bar expanded
For example, when running the local development build, the following will disable the
Top Nav and remove the Filter Bar:
`http://localhost:8088/superset/dashboard/my-dashboard/?standalone=1&show_filters=0`

View File

@@ -7,7 +7,7 @@ version: 1
## Apache Impala
The recommended connector library to Apache Hive is [impyla](https://github.com/cloudera/impyla).
The recommended connector library to Apache Impala is [impyla](https://github.com/cloudera/impyla).
The expected connection string is formatted as follows:

View File

@@ -56,7 +56,7 @@ A list of some of the recommended packages.
| [SQL Server](/docs/databases/sql-server) | `pip install pymssql` | `mssql://` |
| [Teradata](/docs/databases/teradata) | `pip install teradatasqlalchemy ` | `teradata://{user}:{password}@{host}` |
| [Vertica](/docs/databases/vertica) | `pip install sqlalchemy-vertica-python` | `vertica+vertica_python://<UserName>:<DBPassword>@<Database Host>/<Database Name>` |
| [Yugabyte](/docs/databases/yugabyte) | `pip install psycopg2` | `postgresql://<UserName>:<DBPassword>@<Database Host>/<Database Name>` |
| [YugabyteDB](/docs/databases/yugabytedb) | `pip install psycopg2` | `postgresql://<UserName>:<DBPassword>@<Database Host>/<Database Name>` |
---

View File

@@ -7,7 +7,7 @@ version: 1
## MySQL
The recommended connector library for MySQL is `[mysqlclient](https://pypi.org/project/mysqlclient/)`.
The recommended connector library for MySQL is [mysqlclient](https://pypi.org/project/mysqlclient/).
Here's the connection string:

View File

@@ -1,5 +1,5 @@
---
title: Postgres
title: YugabyteDB
hide_title: true
sidebar_position: 38
version: 1

View File

@@ -33,6 +33,9 @@ Alerts and reports are disabled by default. To turn them on, you need to do some
- You must install a headless browser, for taking screenshots of the charts and dashboards. Only Firefox and Chrome are currently supported.
> If you choose Chrome, you must also change the value of `WEBDRIVER_TYPE` to `"chrome"` in your `superset_config.py`.
Note : All the components required (headless browser, redis, postgres db, celery worker and celery beat) are present in the docker image if you are following [Installing Superset Locally](https://superset.apache.org/docs/installation/installing-superset-using-docker-compose/).
All you need to do is add the required config (See `Detailed Config`). Set `ALERT_REPORTS_NOTIFICATION_DRY_RUN` to `False` in [superset config](https://github.com/apache/superset/blob/master/docker/pythonpath_dev/superset_config.py) to disable dry-run mode and start receiving email/slack notifications.
#### Slack integration
To send alerts and reports to Slack channels, you need to create a new Slack Application on your workspace.
@@ -123,6 +126,7 @@ SLACK_API_TOKEN = "xoxb-"
# Email configuration
SMTP_HOST = "smtp.sendgrid.net" #change to your host
SMTP_STARTTLS = True
SMTP_SSL_SERVER_AUTH = True # If your using an SMTP server with a valid certificate
SMTP_SSL = False
SMTP_USER = "your_user"
SMTP_PORT = 2525 # your port eg. 587

View File

@@ -7,20 +7,32 @@ version: 1
## Caching
Superset uses [Flask-Caching](https://flask-caching.readthedocs.io/) for caching purpose. For security reasons,
there are two separate cache configs for Superset's own metadata (`CACHE_CONFIG`) and charting data queried from
connected datasources (`DATA_CACHE_CONFIG`). However, Query results from SQL Lab are stored in another backend
called `RESULTS_BACKEND`, See [Async Queries via Celery](/docs/installation/async-queries-celery) for details.
Configuring caching is as easy as providing `CACHE_CONFIG` and `DATA_CACHE_CONFIG` in your
Superset uses [Flask-Caching](https://flask-caching.readthedocs.io/) for caching purposes. Configuring caching is as easy as providing a custom cache config in your
`superset_config.py` that complies with [the Flask-Caching specifications](https://flask-caching.readthedocs.io/en/latest/#configuring-flask-caching).
Flask-Caching supports various caching backends, including Redis, Memcached, SimpleCache (in-memory), or the
local filesystem.
local filesystem. Custom cache backends are also supported. See [here](https://flask-caching.readthedocs.io/en/latest/#custom-cache-backends) for specifics.
The following cache configurations can be customized:
- Metadata cache (optional): `CACHE_CONFIG`
- Charting data queried from datasets (optional): `DATA_CACHE_CONFIG`
- SQL Lab query results (optional): `RESULTS_BACKEND`. See [Async Queries via Celery](/docs/installation/async-queries-celery) for details
- Dashboard filter state (required): `FILTER_STATE_CACHE_CONFIG`.
- Explore chart form data (required): `EXPLORE_FORM_DATA_CACHE_CONFIG`
Please note, that Dashboard and Explore caching is required. If these caches are undefined, Superset falls back to using a built-in cache that stores data
in the metadata database. While it is recommended to use a dedicated cache, the built-in cache can also be used to cache other data.
For example, to use the built-in cache to store chart data, use the following config:
```python
DATA_CACHE_CONFIG = {
"CACHE_TYPE": "SupersetMetastoreCache",
"CACHE_KEY_PREFIX": "superset_results", # make sure this string is unique to avoid collisions
"CACHE_DEFAULT_TIMEOUT": 86400, # 60 seconds * 60 minutes * 24 hours
}
```
- Redis (recommended): we recommend the [redis](https://pypi.python.org/pypi/redis) Python package
- Memcached: we recommend using [pylibmc](https://pypi.org/project/pylibmc/) client library as
`python-memcached` does not handle storing binary data correctly.
- Redis: we recommend the [redis](https://pypi.python.org/pypi/redis) Python package
Both of these libraries can be installed using pip.
@@ -28,16 +40,7 @@ For chart data, Superset goes up a “timeout search path”, from a slice's con
to the datasources, the databases, then ultimately falls back to the global default
defined in `DATA_CACHE_CONFIG`.
```
DATA_CACHE_CONFIG = {
'CACHE_TYPE': 'redis',
'CACHE_DEFAULT_TIMEOUT': 60 * 60 * 24, # 1 day default (in secs)
'CACHE_KEY_PREFIX': 'superset_results',
'CACHE_REDIS_URL': 'redis://localhost:6379/0',
}
```
Custom cache backends are also supported. See [here](https://flask-caching.readthedocs.io/en/latest/#custom-cache-backends) for specifics.
## Celery beat
Superset has a Celery task that will periodically warm up the cache based on different strategies.
To use it, add the following to the `CELERYBEAT_SCHEDULE` section in `config.py`:

View File

@@ -10,7 +10,7 @@ version: 1
### Configuration
To configure your application, you need to create a file `superset_config.py` and add it to your
`PYTHONPATH`. If your applcation 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.
`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.
Here are some of the parameters you can set in that file:
```
@@ -20,8 +20,12 @@ ROW_LIMIT = 5000
SUPERSET_WEBSERVER_PORT = 8088
# Flask App Builder configuration
# Your App secret key
SECRET_KEY = '\2\1thisismyscretkey\1\2\e\y\y\h'
# Your App secret key will be used for securely signing the session cookie
# and encrypting sensitive information on the database
# Make sure you are changing this key for your deployment with a strong key.
# You can generate a strong key using `openssl rand -base64 42`
SECRET_KEY = 'YOUR_OWN_RANDOM_GENERATED_SECRET_KEY'
# The SQLAlchemy connection string to your database backend
# This connection defines the path to the database that stores your
@@ -303,3 +307,15 @@ defaults on a per database level via the `extra` parameter.
Note in a future release the interim SIP-15 logic will be removed (including the
`time_grain_endpoints` form-data field) via a code change and Alembic migration.
### SECRET_KEY Rotation
If you want to rotate the SECRET_KEY(change the existing secret key), follow the below steps.
Add the new SECRET_KEY and PREVIOUS_SECRET_KEY to `superset_config.py`:
```python
PREVIOUS_SECRET_KEY = 'CURRENT_SECRET_KEY' # The default SECRET_KEY for deployment is '21thisismyscretkey12eyyh'
SECRET_KEY = 'YOUR_OWN_RANDOM_GENERATED_SECRET_KEY'
```
Then run `superset re-encrypt-secrets`

View File

@@ -92,6 +92,35 @@ postgresql:
postgresqlPassword: superset
```
Make sure, you set a unique strong complex alphanumeric string for your SECRET_KEY and use a tool to help you generate
a sufficiently random sequence.
- To generate a good key you can run, `openssl rand -base64 42`
```yaml
configOverrides:
secret: |
SECRET_KEY = 'YOUR_OWN_RANDOM_GENERATED_SECRET_KEY'
```
If you want to change the previous secret key then you should rotate the keys.
Default secret key for kubernetes deployment is `thisISaSECRET_1234`
```yaml
configOverrides:
my_override: |
PREVIOUS_SECRET_KEY = 'YOUR_PREVIOUS_SECRET_KEY'
SECRET_KEY = 'YOUR_OWN_RANDOM_GENERATED_SECRET_KEY'
init:
command:
- /bin/sh
- -c
- |
. {{ .Values.configMountPath }}/superset_bootstrap.sh
superset re-encrypt-secrets
. {{ .Values.configMountPath }}/superset_init.sh
```
#### Dependencies
Install additional packages and do any other bootstrap configuration in this script. For production clusters it's
@@ -101,7 +130,7 @@ database drivers so that you can connect to those datasources in your Superset i
```yaml
bootstrapScript: |
#!/bin/bash
pip install psycopg2==2.8.5 \
pip install psycopg2==2.9.1 \
redis==3.2.1 \
pybigquery==2.26.0 \
elasticsearch-dbapi==0.2.5 &&\

View File

@@ -119,8 +119,8 @@ In this section, we'll walkthrough the pre-defined Jinja macros in Superset.
The `{{ current_username() }}` macro returns the username of the currently logged in user.
If you have caching enabled in your Superset configuration, then by defaul the the `username` value will be used
by Superset when calculating the cache key. A cache key is a unique identifer that determines if there's a
If you have caching enabled in your Superset configuration, then by default the the `username` value will be used
by Superset when calculating the cache key. A cache key is a unique identifier that determines if there's a
cache hit in the future and Superset can retrieve cached data.
You can disable the inclusion of the `username` value in the calculation of the
@@ -132,10 +132,10 @@ cache key by adding the following parameter to your Jinja code:
**Current User ID**
The `{{ current_user_id()}}` macro returns the user_id of the currently logged in user.
The `{{ current_user_id() }}` macro returns the user_id of the currently logged in user.
If you have caching enabled in your Superset configuration, then by defaul the the `user_id` value will be used
by Superset when calculating the cache key. A cache key is a unique identifer that determines if there's a
If you have caching enabled in your Superset configuration, then by default the the `user_id` value will be used
by Superset when calculating the cache key. A cache key is a unique identifier that determines if there's a
cache hit in the future and Superset can retrieve cached data.
You can disable the inclusion of the `user_id` value in the calculation of the
@@ -197,8 +197,8 @@ You can retrieve the value for a specific filter as a list using `{{ filter_valu
This is useful if:
- you want to use a filter component to filter a query where the name of filter component column doesn't match the one in the select statement
- you want to have the ability for filter inside the main query for performance purposes
- You want to use a filter component to filter a query where the name of filter component column doesn't match the one in the select statement
- You want to have the ability for filter inside the main query for performance purposes
Here's a concrete example:
@@ -218,9 +218,9 @@ returns the operator specified in the Explore UI.
This is useful if:
- you want to handle more than the IN operator in your SQL clause
- you want to handle generating custom SQL conditions for a filter
- you want to have the ability to filter inside the main query for speed purposes
- You want to handle more than the IN operator in your SQL clause
- You want to handle generating custom SQL conditions for a filter
- You want to have the ability to filter inside the main query for speed purposes
Here's a concrete example:

View File

@@ -131,6 +131,28 @@ For example, the filters `client_id=4` and `client_id=5`, applied to a role,
will result in users of that role having `client_id=4` AND `client_id=5`
added to their query, which can never be true.
### Content Security Policiy (CSP)
[Content Security Policy (CSP)](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) is an added
layer of security that helps to detect and mitigate certain types of attacks, including
Cross-Site Scripting (XSS) and data injection attacks.
CSP makes it possible for server administrators to reduce or eliminate the vectors by which XSS can
occur by specifying the domains that the browser should consider to be valid sources of executable scripts.
A CSP compatible browser will then only execute scripts loaded in source files received from those allowed domains,
ignoring all other scripts (including inline scripts and event-handling HTML attributes).
A policy is described using a series of policy directives, each of which describes the policy for
a certain resource type or policy area. You can check possible directives
[here](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy).
It's extremely important to correclty configure a Content Security Policy when deploying Superset to
prevent many types of attacks. For that matter, Superset provides the ` TALISMAN_CONFIG` key in `config.py`
where admnistrators can define the policy. When running in production mode, Superset will check for the presence
of a policy and if it's not able to find one, it will issue a warning with the security risks. For environments
where CSP policies are defined outside of Superset using other software, administrators can disable
the warning using the `CONTENT_SECURITY_POLICY_WARNING` key in `config.py`.
### Reporting Security Vulnerabilities
Apache Software Foundation takes a rigorous standpoint in annihilating the security issues in its

View File

@@ -35,10 +35,8 @@ const config = {
favicon: 'img/favicon.ico',
organizationName: 'apache', // Usually your GitHub org/user name.
projectName: 'superset', // Usually your repo name.
themes: [
'@saucelabs/theme-github-codeblock'
],
plugins: [
themes: ['@saucelabs/theme-github-codeblock'],
plugins: [
[
'@docusaurus/plugin-client-redirects',
{
@@ -117,6 +115,10 @@ const config = {
to: '/docs/contributing/contributing-page',
from: '/docs/contributing/contribution-guidelines',
},
{
to: '/docs/databases/yugabytedb',
from: '/docs/databases/yugabyte/',
},
],
},
],
@@ -155,6 +157,11 @@ const config = {
defaultMode: 'light',
disableSwitch: true,
},
algolia: {
appId: 'WR5FASX5ED',
apiKey: '299e4601d2fc5d0031bf9a0223c7f0c5',
indexName: 'superset-apache',
},
navbar: {
logo: {
alt: 'Superset Logo',
@@ -197,7 +204,7 @@ const config = {
},
{
label: 'Slack',
href: 'https://join.slack.com/t/apache-superset/shared_invite/zt-uxbh5g36-AISUtHbzOXcu0BIj7kgUaw',
href: 'https://join.slack.com/t/apache-superset/shared_invite/zt-16jvzmoi8-sI7jKWp~xc2zYRe~NqiY9Q',
},
{
label: 'Mailing List',
@@ -233,8 +240,6 @@ const config = {
darkTheme: darkCodeTheme,
},
}),
};
module.exports = config;

11303
docs/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -16,17 +16,19 @@
"typecheck": "tsc"
},
"dependencies": {
"@algolia/client-search": "^4.13.0",
"@ant-design/icons": "^4.7.0",
"@docusaurus/core": "^2.0.0-beta.15",
"@docusaurus/plugin-client-redirects": "^2.0.0-beta.15",
"@docusaurus/preset-classic": "^2.0.0-beta.15",
"@docsearch/react": "^3.0.0",
"@docusaurus/core": "^2.0.0-beta.17",
"@docusaurus/plugin-client-redirects": "^2.0.0-beta.17",
"@docusaurus/preset-classic": "^2.0.0-beta.17",
"@emotion/core": "^10.1.1",
"@emotion/styled": "^10.0.27",
"@mdx-js/react": "^1.6.21",
"@mdx-js/react": "^1.6.22",
"@saucelabs/theme-github-codeblock": "^0.1.1",
"@superset-ui/style": "^0.14.23",
"@svgr/webpack": "^5.5.0",
"antd": "^4.8.0",
"antd": "^4.19.3",
"buffer": "^6.0.3",
"clsx": "^1.1.1",
"file-loader": "^6.2.0",
@@ -36,13 +38,14 @@
"react-github-btn": "^1.2.0",
"stream": "^0.0.2",
"swagger-ui-react": "^4.1.2",
"theme-ui": "^0.3.1",
"url-loader": "^4.1.1"
},
"devDependencies": {
"@docusaurus/module-type-aliases": "^2.0.0-beta.15",
"@docusaurus/module-type-aliases": "^2.0.0-beta.17",
"@tsconfig/docusaurus": "^1.0.4",
"typescript": "^4.3.5"
"@types/react": "^17.0.42",
"typescript": "^4.3.5",
"webpack": "^5.61.0"
},
"browserslist": {
"production": [

View File

@@ -23,7 +23,7 @@ import Layout from '@theme/Layout';
const links = [
[
'https://join.slack.com/t/apache-superset/shared_invite/zt-uxbh5g36-AISUtHbzOXcu0BIj7kgUaw',
'https://join.slack.com/t/apache-superset/shared_invite/zt-16jvzmoi8-sI7jKWp~xc2zYRe~NqiY9Q',
'Slack',
'interact with other Superset users and community members',
],

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -22,7 +22,7 @@ maintainers:
- name: craig-rueda
email: craig@craigrueda.com
url: https://github.com/craig-rueda
version: 0.5.10
version: 0.5.11
dependencies:
- name: postgresql
version: 10.2.0

View File

@@ -148,6 +148,9 @@ configOverrides: {}
# AUTH_USER_REGISTRATION = True
# # The default user self registration role
# AUTH_USER_REGISTRATION_ROLE = "Admin"
# secret: |
# # Generate your own secret key for encryption. Use openssl rand -base64 42 to generate a good key
# SECRET_KEY = 'YOUR_OWN_RANDOM_GENERATED_SECRET_KEY'
# Same as above but the values are files
configOverridesFiles: {}
# extend_timeout: extend_timeout.py
@@ -302,6 +305,8 @@ init:
# Configure resources
# Warning: fab command consumes a lot of ram and can
# cause the process to be killed due to OOM if it exceeds limit
# Make sure you are giving a strong password for the admin user creation( else make sure you are changing after setup)
# Also change the admin email to your own custom email.
resources: {}
# limits:
# cpu:

View File

@@ -77,7 +77,7 @@ flask==1.1.4
# flask-openid
# flask-sqlalchemy
# flask-wtf
flask-appbuilder==3.4.3
flask-appbuilder==3.4.5
# via apache-superset
flask-babel==1.0.0
# via flask-appbuilder
@@ -113,6 +113,8 @@ graphlib-backport==1.0.3
# via apache-superset
gunicorn==20.1.0
# via apache-superset
hashids==1.3.1
# via apache-superset
holidays==0.10.3
# via apache-superset
humanize==3.11.0

View File

@@ -36,6 +36,7 @@ pytest
pytest-cov
statsd
pytest-mock
sqloxide
# DB dependencies
-e file:.[bigquery]
-e file:.[trino]

View File

@@ -1,4 +1,4 @@
# SHA1:7a8e256097b4758bdeda2529d3d4d31e421e1a3c
# SHA1:e273e8da6bfd5f6f8563fe067e243297cc7c588c
#
# This file is autogenerated by pip-compile-multi
# To update, run:
@@ -52,7 +52,6 @@ google-auth-oauthlib==0.4.6
google-cloud-bigquery[bqstorage,pandas]==2.29.0
# via
# -r requirements/testing.in
# apache-superset
# pandas-gbq
# pybigquery
google-cloud-bigquery-storage==2.9.1
@@ -105,9 +104,7 @@ openapi-schema-validator==0.1.5
openapi-spec-validator==0.3.1
# via -r requirements/testing.in
pandas-gbq==0.15.0
# via
# -r requirements/testing.in
# apache-superset
# via -r requirements/testing.in
parameterized==0.8.1
# via -r requirements/testing.in
parso==0.8.2
@@ -138,9 +135,7 @@ pyasn1==0.4.8
pyasn1-modules==0.2.8
# via google-auth
pybigquery==0.10.2
# via
# -r requirements/testing.in
# apache-superset
# via -r requirements/testing.in
pydata-google-auth==1.2.0
# via pandas-gbq
pyfakefs==4.5.0
@@ -168,6 +163,8 @@ rsa==4.7.2
# via google-auth
sqlalchemy-trino==0.4.1
# via apache-superset
sqloxide==0.1.15
# via -r requirements/testing.in
statsd==3.3.0
# via -r requirements/testing.in
traitlets==5.0.5

View File

@@ -102,7 +102,10 @@ def find_models(module: ModuleType) -> List[Type[Model]]:
while tables:
table = tables.pop()
seen.add(table)
model = getattr(Base.classes, table)
try:
model = getattr(Base.classes, table)
except AttributeError:
continue
model.__tablename__ = table
models.append(model)

View File

@@ -60,7 +60,8 @@ def request(
def list_runs(
repo: str, params: Optional[Dict[str, str]] = None,
repo: str,
params: Optional[Dict[str, str]] = None,
) -> Iterator[Dict[str, Any]]:
"""List all github workflow runs.
Returns:
@@ -193,7 +194,11 @@ def cancel_github_workflows(
if branch and ":" in branch:
[user, branch] = branch.split(":", 2)
runs = get_runs(
repo, branch=branch, user=user, statuses=statuses, events=events,
repo,
branch=branch,
user=user,
statuses=statuses,
events=events,
)
# sort old jobs to the front, so to cancel older jobs first

View File

@@ -23,8 +23,8 @@ import sys
from setuptools import find_packages, setup
BASE_DIR = os.path.abspath(os.path.dirname(__file__))
PACKAGE_JSON = os.path.join(BASE_DIR, "superset-frontend", "package.json")
with open(PACKAGE_JSON, "r") as package_file:
version_string = json.load(package_file)["version"]
@@ -78,7 +78,7 @@ setup(
"cryptography>=3.3.2",
"deprecation>=2.1.0, <2.2.0",
"flask>=1.1.0, <2.0.0",
"flask-appbuilder>=3.4.3, <4.0.0",
"flask-appbuilder>=3.4.5, <4.0.0",
"flask-caching>=1.10.0",
"flask-compress",
"flask-talisman",
@@ -88,6 +88,7 @@ setup(
"geopy",
"graphlib-backport",
"gunicorn>=20.1.0",
"hashids>=1.3.1, <2",
"holidays==0.10.3", # PINNED! https://github.com/dr-prodigy/python-holidays/issues/406
"humanize",
"itsdangerous>=1.0.0, <2.0.0", # https://github.com/apache/superset/pull/14627

View File

@@ -40,6 +40,7 @@ embedDashboard({
supersetDomain: "https://superset.example.com",
mountPoint: document.getElementById("my-superset-container"), // any html element that can contain an iframe
fetchGuestToken: () => fetchGuestTokenFromBackend(),
dashboardUiConfig: { hideTitle: true }, // dashboard UI config: hideTitle, hideTab, hideChartControls (optional)
});
```

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{
"name": "@superset-ui/embedded-sdk",
"version": "0.1.0-alpha.3",
"version": "0.1.0-alpha.7",
"description": "SDK for embedding resources from Superset into your own application",
"access": "public",
"keywords": [
@@ -24,7 +24,7 @@
"scripts": {
"build": "tsc ; babel src --out-dir lib --extensions '.ts,.tsx' ; webpack --mode production",
"ci:release": "node ./release-if-necessary.js",
"test": "echo \"Error: no test specified\" && exit 1"
"test": "jest"
},
"browserslist": [
"last 3 chrome versions",
@@ -40,8 +40,10 @@
"@babel/core": "^7.16.12",
"@babel/preset-env": "^7.16.11",
"@babel/preset-typescript": "^7.16.7",
"@types/jest": "^27.4.1",
"axios": "^0.25.0",
"babel-loader": "^8.2.3",
"jest": "^27.5.1",
"typescript": "^4.5.5",
"webpack": "^5.67.0",
"webpack-cli": "^4.9.2"

View File

@@ -0,0 +1,96 @@
/**
* 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 {
REFRESH_TIMING_BUFFER_MS,
getGuestTokenRefreshTiming,
MIN_REFRESH_WAIT_MS,
DEFAULT_TOKEN_EXP_MS,
} from "./guestTokenRefresh";
describe("guest token refresh", () => {
beforeAll(() => {
jest.useFakeTimers("modern"); // "modern" allows us to fake the system time
jest.setSystemTime(new Date("2022-03-03 01:00"));
jest.spyOn(global, "setTimeout");
});
afterAll(() => {
jest.useRealTimers();
});
function makeFakeJWT(claims: any) {
// not a valid jwt, but close enough for this code
const tokenifiedClaims = Buffer.from(JSON.stringify(claims)).toString(
"base64"
);
return `abc.${tokenifiedClaims}.xyz`;
}
it("schedules refresh with an epoch exp", () => {
// exp is in seconds
const ttl = 1300;
const exp = Date.now() / 1000 + ttl;
const fakeToken = makeFakeJWT({ exp });
const timing = getGuestTokenRefreshTiming(fakeToken);
expect(timing).toBeGreaterThan(MIN_REFRESH_WAIT_MS);
expect(timing).toBe(ttl * 1000 - REFRESH_TIMING_BUFFER_MS);
});
it("schedules refresh with an epoch exp containing a decimal", () => {
const ttl = 1300.123;
const exp = Date.now() / 1000 + ttl;
const fakeToken = makeFakeJWT({ exp });
const timing = getGuestTokenRefreshTiming(fakeToken);
expect(timing).toBeGreaterThan(MIN_REFRESH_WAIT_MS);
expect(timing).toBe(ttl * 1000 - REFRESH_TIMING_BUFFER_MS);
});
it("schedules refresh with iso exp", () => {
const exp = new Date("2022-03-03 01:09").toISOString();
const fakeToken = makeFakeJWT({ exp });
const timing = getGuestTokenRefreshTiming(fakeToken);
const expectedTiming = 1000 * 60 * 9 - REFRESH_TIMING_BUFFER_MS;
expect(timing).toBeGreaterThan(MIN_REFRESH_WAIT_MS);
expect(timing).toBe(expectedTiming);
});
it("avoids refresh spam", () => {
const fakeToken = makeFakeJWT({ exp: Date.now() / 1000 });
const timing = getGuestTokenRefreshTiming(fakeToken);
expect(timing).toBe(MIN_REFRESH_WAIT_MS - REFRESH_TIMING_BUFFER_MS);
});
it("uses a default when it cannot parse the date", () => {
const fakeToken = makeFakeJWT({ exp: "invalid date" });
const timing = getGuestTokenRefreshTiming(fakeToken);
expect(timing).toBeGreaterThan(MIN_REFRESH_WAIT_MS);
expect(timing).toBe(DEFAULT_TOKEN_EXP_MS - REFRESH_TIMING_BUFFER_MS);
});
});

View File

@@ -0,0 +1,32 @@
/**
* 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.
*/
export const REFRESH_TIMING_BUFFER_MS = 5000 // refresh guest token early to avoid failed superset requests
export const MIN_REFRESH_WAIT_MS = 10000 // avoid blasting requests as fast as the cpu can handle
export const DEFAULT_TOKEN_EXP_MS = 300000 // (5 min) used only when parsing guest token exp fails
// when do we refresh the guest token?
export function getGuestTokenRefreshTiming(currentGuestToken: string) {
const parsedJwt = JSON.parse(Buffer.from(currentGuestToken.split('.')[1], 'base64').toString());
// if exp is int, it is in seconds, but Date() takes milliseconds
const exp = new Date(/[^0-9\.]/g.test(parsedJwt.exp) ? parsedJwt.exp : parseFloat(parsedJwt.exp) * 1000);
const isValidDate = exp.toString() !== 'Invalid Date';
const ttl = isValidDate ? Math.max(MIN_REFRESH_WAIT_MS, exp.getTime() - Date.now()) : DEFAULT_TOKEN_EXP_MS;
return ttl - REFRESH_TIMING_BUFFER_MS;
}

View File

@@ -21,6 +21,7 @@ import { IFRAME_COMMS_MESSAGE_TYPE } from './const';
// We can swap this out for the actual switchboard package once it gets published
import { Switchboard } from '@superset-ui/switchboard';
import { getGuestTokenRefreshTiming } from './guestTokenRefresh';
/**
* The function to fetch a guest token from your Host App's backend server.
@@ -29,6 +30,12 @@ import { Switchboard } from '@superset-ui/switchboard';
*/
export type GuestTokenFetchFn = () => Promise<string>;
export type UiConfigType = {
hideTitle?: boolean
hideTab?: boolean
hideChartControls?: boolean
}
export type EmbedDashboardParams = {
/** The id provided by the embed configuration UI in Superset */
id: string
@@ -38,6 +45,8 @@ export type EmbedDashboardParams = {
mountPoint: HTMLElement
/** A function to fetch a guest token from the Host App's backend server */
fetchGuestToken: GuestTokenFetchFn
/** The dashboard UI config: hideTitle, hideTab, hideChartControls **/
dashboardUiConfig?: UiConfigType
/** Are we in debug mode? */
debug?: boolean
}
@@ -59,6 +68,7 @@ export async function embedDashboard({
supersetDomain,
mountPoint,
fetchGuestToken,
dashboardUiConfig,
debug = false
}: EmbedDashboardParams): Promise<EmbeddedDashboard> {
function log(...info: unknown[]) {
@@ -69,14 +79,32 @@ export async function embedDashboard({
log('embedding');
function calculateConfig() {
let configNumber = 0
if(dashboardUiConfig) {
if(dashboardUiConfig.hideTitle) {
configNumber += 1
}
if(dashboardUiConfig.hideTab) {
configNumber += 2
}
if(dashboardUiConfig.hideChartControls) {
configNumber += 8
}
}
return configNumber
}
async function mountIframe(): Promise<Switchboard> {
return new Promise(resolve => {
const iframe = document.createElement('iframe');
const dashboardConfig = dashboardUiConfig ? `?uiConfig=${calculateConfig()}` : ""
// setup the iframe's sandbox configuration
iframe.sandbox.add("allow-same-origin"); // needed for postMessage to work
iframe.sandbox.add("allow-scripts"); // obviously the iframe needs scripts
iframe.sandbox.add("allow-presentation"); // for fullscreen charts
iframe.sandbox.add("allow-downloads"); // for downloading charts as image
// add these ones if it turns out we need them:
// iframe.sandbox.add("allow-top-navigation");
// iframe.sandbox.add("allow-forms");
@@ -103,7 +131,7 @@ export async function embedDashboard({
resolve(new Switchboard({ port: ourPort, name: 'superset-embedded-sdk', debug }));
});
iframe.src = `${supersetDomain}/dashboard/${id}/embedded`;
iframe.src = `${supersetDomain}/embedded/${id}${dashboardConfig}`;
mountPoint.replaceChildren(iframe);
log('placed the iframe')
});
@@ -117,6 +145,14 @@ export async function embedDashboard({
ourPort.emit('guestToken', { guestToken });
log('sent guest token');
async function refreshGuestToken() {
const newGuestToken = await fetchGuestToken();
ourPort.emit('guestToken', { guestToken: newGuestToken });
setTimeout(refreshGuestToken, getGuestTokenRefreshTiming(newGuestToken));
}
setTimeout(refreshGuestToken, getGuestTokenRefreshTiming(guestToken));
function unmount() {
log('unmounting');
mountPoint.replaceChildren();

View File

@@ -67,7 +67,7 @@ module.exports = {
version: 'detect',
},
},
plugins: ['prettier', 'react', 'file-progress'],
plugins: ['prettier', 'react', 'file-progress', 'theme-colors'],
overrides: [
{
files: ['*.ts', '*.tsx'],
@@ -183,8 +183,27 @@ module.exports = {
'max-classes-per-file': 0,
},
},
{
files: [
'*.test.ts',
'*.test.tsx',
'*.test.js',
'*.test.jsx',
'*.stories.tsx',
'*.stories.jsx',
'fixtures.*',
'cypress-base/cypress/**/*',
'Stories.tsx',
'packages/superset-ui-core/src/style/index.tsx',
],
rules: {
'theme-colors/no-literal-colors': 0,
'no-restricted-imports': 0,
},
},
],
rules: {
'theme-colors/no-literal-colors': 1,
camelcase: [
'error',
{

View File

@@ -33,6 +33,7 @@ module.exports = {
'@storybook/addon-knobs',
'storybook-addon-paddings',
],
staticDirs: ['../src/assets/images'],
webpackFinal: config => ({
...config,
module: {

View File

@@ -1,7 +1,7 @@
{
"baseUrl": "http://localhost:8088",
"chromeWebSecurity": false,
"defaultCommandTimeout": 5000,
"defaultCommandTimeout": 8000,
"numTestsKeptInMemory": 0,
"experimentalFetchPolyfill": true,
"requestTimeout": 10000,
@@ -12,7 +12,7 @@
"viewportHeight": 1024,
"projectId": "ukwxzo",
"retries": {
"runMode": 1,
"runMode": 2,
"openMode": 0
}
}

View File

@@ -1,4 +1,9 @@
import { getChartAlias, Slice } from 'cypress/utils/vizPlugins';
import {
dashboardView,
editDashboardView,
nativeFilters,
} from 'cypress/support/directories';
/**
* Licensed to the Apache Software Foundation (ASF) under one
@@ -25,7 +30,13 @@ export const testItems = {
dashboard: 'Cypress Sales Dashboard',
dataset: 'Vehicle Sales',
chart: 'Cypress chart',
newChart: 'New Cypress Chart',
createdDashboard: 'New Dashboard',
defaultNameDashboard: '[ untitled dashboard ]',
newDashboardTitle: `Test dashboard [NEW TEST]`,
bulkFirstNameDashboard: 'First Dash',
bulkSecondNameDashboard: 'Second Dash',
worldBanksDataCopy: `World Bank's Data [copy]`,
};
export const CHECK_DASHBOARD_FAVORITE_ENDPOINT =
@@ -133,3 +144,112 @@ export function resize(selector: string) {
},
};
}
export function cleanUp() {
cy.deleteDashboardByName(testItems.dashboard);
cy.deleteDashboardByName(testItems.defaultNameDashboard);
cy.deleteDashboardByName('');
cy.deleteDashboardByName(testItems.newDashboardTitle);
cy.deleteDashboardByName(testItems.bulkFirstNameDashboard);
cy.deleteDashboardByName(testItems.bulkSecondNameDashboard);
cy.deleteDashboardByName(testItems.createdDashboard);
cy.deleteDashboardByName(testItems.worldBanksDataCopy);
cy.deleteChartByName(testItems.chart);
cy.deleteChartByName(testItems.newChart);
}
/** ************************************************************************
* Clicks on new filter button
* @returns {None}
* @summary helper for adding new filter
************************************************************************* */
export function clickOnAddFilterInModal() {
return cy
.get(nativeFilters.addFilterButton.button)
.first()
.click()
.then(() => {
cy.get(nativeFilters.addFilterButton.dropdownItem)
.contains('Filter')
.click({ force: true });
});
}
/** ************************************************************************
* Fills value native filter form with basic information
* @param {string} name name for filter
* @param {string} dataset which dataset should be used
* @param {string} filterColumn which column should be used
* @returns {None}
* @summary helper for filling value native filter form
************************************************************************* */
export function fillValueNativeFilterForm(
name: string,
dataset: string,
filterColumn: string,
) {
cy.get(nativeFilters.modal.container)
.find(nativeFilters.filtersPanel.filterName)
.last()
.click({ scrollBehavior: false })
.type(name, { scrollBehavior: false });
cy.get(nativeFilters.modal.container)
.find(nativeFilters.filtersPanel.datasetName)
.last()
.click({ scrollBehavior: false })
.type(`${dataset}{enter}`, { scrollBehavior: false });
cy.get(nativeFilters.silentLoading).should('not.exist');
cy.get(nativeFilters.filtersPanel.filterInfoInput)
.last()
.should('be.visible')
.click({ force: true });
cy.get(nativeFilters.filtersPanel.filterInfoInput).last().type(filterColumn);
cy.get(nativeFilters.filtersPanel.inputDropdown)
.should('be.visible', { timeout: 20000 })
.last()
.click();
}
/** ************************************************************************
* Get native filter placeholder e.g 9 options
* @param {number} index which input it fills
* @returns cy object for assertions
* @summary helper for getting placeholder value
************************************************************************* */
export function getNativeFilterPlaceholderWithIndex(index: number) {
return cy.get(nativeFilters.filtersPanel.columnEmptyInput).eq(index);
}
/** ************************************************************************
* Apply native filter value from dashboard view
* @param {number} index which input it fills
* @param {string} value what is filter value
* @returns {null}
* @summary put value to nth native filter input in view
************************************************************************* */
export function applyNativeFilterValueWithIndex(index: number, value: string) {
cy.get(nativeFilters.filterFromDashboardView.filterValueInput)
.eq(index)
.parent()
.should('be.visible', { timeout: 10000 })
.type(`${value}{enter}`);
// click the title to dismiss shown options
cy.get(nativeFilters.filterFromDashboardView.filterName).eq(index).click();
}
/** ************************************************************************
* Fills parent filter input
* @param {number} index which input it fills
* @param {string} value on which filter it depends on
* @returns {null}
* @summary takes first or second input and modify the depends on filter value
************************************************************************* */
export function addParentFilterWithValue(index: number, value: string) {
return cy
.get(nativeFilters.filterConfigurationSections.displayedSection)
.within(() => {
cy.get('input[aria-label="Limit type"]')
.eq(index)
.click({ force: true })
.type(`${value}{enter}`, { delay: 30, force: true });
});
}

View File

@@ -27,16 +27,19 @@ interface QueryString {
native_filters_key: string;
}
describe('nativefiler url param key', () => {
xdescribe('nativefiler url param key', () => {
// const urlParams = { param1: '123', param2: 'abc' };
before(() => {
cy.login();
});
let initialFilterKey: string;
it('should have cachekey in nativefilter param', () => {
// things in `before` will not retry and the `waitForChartLoad` check is
// especically flaky and may need more retries
cy.visit(WORLD_HEALTH_DASHBOARD);
WORLD_HEALTH_CHARTS.forEach(waitForChartLoad);
cy.wait(1000); // wait for key to be published (debounced)
});
let initialFilterKey: string;
it('should have cachekey in nativefilter param', () => {
cy.location().then(loc => {
const queryParams = qs.parse(loc.search) as QueryString;
expect(typeof queryParams.native_filters_key).eq('string');
@@ -44,6 +47,9 @@ describe('nativefiler url param key', () => {
});
it('should have different key when page reloads', () => {
cy.visit(WORLD_HEALTH_DASHBOARD);
WORLD_HEALTH_CHARTS.forEach(waitForChartLoad);
cy.wait(1000); // wait for key to be published (debounced)
cy.location().then(loc => {
const queryParams = qs.parse(loc.search) as QueryString;
expect(queryParams.native_filters_key).not.equal(initialFilterKey);

View File

@@ -43,7 +43,7 @@ describe('Dashboard edit markdown', () => {
cy.get('[data-test="dashboard-markdown-editor"]')
.should(
'have.text',
'✨Markdown✨Markdown✨MarkdownClick here to edit markdown',
'✨Markdown\n✨Markdown\n✨Markdown\n\nClick here to edit markdown',
)
.click();

View File

@@ -22,7 +22,17 @@ import {
nativeFilters,
exploreView,
} from 'cypress/support/directories';
import { testItems } from './dashboard.helper';
import {
cleanUp,
testItems,
WORLD_HEALTH_CHARTS,
waitForChartLoad,
clickOnAddFilterInModal,
fillValueNativeFilterForm,
getNativeFilterPlaceholderWithIndex,
addParentFilterWithValue,
applyNativeFilterValueWithIndex,
} from './dashboard.helper';
import { DASHBOARD_LIST } from '../dashboard_list/dashboard_list.helper';
import { CHART_LIST } from '../chart_list/chart_list.helper';
import { FORM_DATA_DEFAULTS } from '../explore/visualizations/shared.helper';
@@ -39,21 +49,27 @@ const milliseconds = new Date().getTime();
const dashboard = `Test Dashboard${milliseconds}`;
describe('Nativefilters Sanity test', () => {
before(() => {
beforeEach(() => {
cy.login();
cleanUp();
cy.intercept('/api/v1/dashboard/?q=**').as('dashboardsList');
cy.intercept('POST', '**/copy_dash/*').as('copy');
cy.intercept('/api/v1/dashboard/*').as('dashboard');
cy.request(
'api/v1/dashboard/?q=(order_column:changed_on_delta_humanized,order_direction:desc,page:0,page_size:100)',
).then(xhr => {
const dashboards = xhr.body.result;
cy.intercept('GET', '**/api/v1/dataset/**').as('datasetLoad');
cy.intercept('**/api/v1/dashboard/?q=**').as('dashboardsList');
cy.visit('dashboard/list/');
cy.contains('Actions');
cy.wait('@dashboardsList').then(xhr => {
const dashboards = xhr.response?.body.result;
/* eslint-disable no-unused-expressions */
expect(dashboards).not.to.be.undefined;
const worldBankDashboard = dashboards.find(
(d: { dashboard_title: string }) =>
d.dashboard_title === "World Bank's Data",
);
cy.visit(worldBankDashboard.url);
});
WORLD_HEALTH_CHARTS.forEach(waitForChartLoad);
cy.get(dashboardView.threeDotsMenuIcon).should('be.visible').click();
cy.get(dashboardView.saveAsMenuOption).should('be.visible').click();
cy.get(dashboardView.saveModal.dashboardNameInput)
@@ -65,19 +81,10 @@ describe('Nativefilters Sanity test', () => {
.its('response.statusCode')
.should('eq', 200);
});
beforeEach(() => {
cy.login();
cy.request(
'api/v1/dashboard/?q=(order_column:changed_on_delta_humanized,order_direction:desc,page:0,page_size:100)',
).then(xhr => {
const dashboards = xhr.body.result;
const testDashboard = dashboards.find(
(d: { dashboard_title: string }) =>
d.dashboard_title === testItems.dashboard,
);
cy.visit(testDashboard.url);
});
afterEach(() => {
cleanUp();
});
it('User can expand / retract native filter sidebar on a dashboard', () => {
cy.get(nativeFilters.createFilterButton).should('not.exist');
cy.get(nativeFilters.filterFromDashboardView.expand)
@@ -123,21 +130,10 @@ describe('Nativefilters Sanity test', () => {
.within(() =>
cy.get('input').type('wb_health_population{enter}', { force: true }),
);
// Add following step to avoid flaky enter value in line 177
cy.get(nativeFilters.filtersPanel.inputDropdown)
.should('be.visible', { timeout: 20000 })
.last()
.click();
cy.get('.loading inline-centered css-101mkpk').should('not.exist');
// hack for unclickable country_name
cy.wait(5000);
cy.get(nativeFilters.filtersPanel.filterInfoInput)
.last()
.should('be.visible', { timeout: 30000 })
.click({ force: true });
cy.get(nativeFilters.filtersPanel.filterInfoInput)
cy.get(`${nativeFilters.filtersPanel.filterInfoInput}:visible:last`)
.last()
.focus()
.type('country_name');
cy.get(nativeFilters.filtersPanel.inputDropdown)
.should('be.visible', { timeout: 20000 })
@@ -270,7 +266,6 @@ describe('Nativefilters Sanity test', () => {
'Filter has default value',
'Can select multiple values',
'Filter value is required',
'Filter is hierarchical',
'Select first filter value by default',
'Inverse selection',
'Dynamically search all filter values',
@@ -402,15 +397,6 @@ describe('Nativefilters Sanity test', () => {
cy.get('.line').within(() => {
cy.contains('United States').should('be.visible');
});
// clean up the default setting
cy.get(nativeFilters.filterFromDashboardView.expand).click({ force: true });
cy.get(nativeFilters.filterFromDashboardView.createFilterButton).click();
cy.contains('Filter has default value').click();
cy.get(nativeFilters.modal.footer)
.find(nativeFilters.modal.saveButton)
.should('be.visible')
.click({ force: true });
});
it('User can create a time grain filter', () => {
@@ -542,6 +528,87 @@ describe('Nativefilters Sanity test', () => {
.contains('year')
.should('be.visible');
});
it('User can create a value filter', () => {
cy.get(nativeFilters.filterFromDashboardView.expand).click({ force: true });
cy.get(nativeFilters.filterFromDashboardView.createFilterButton)
.should('be.visible')
.click();
cy.get(nativeFilters.modal.container).should('be.visible');
cy.get('body').type('{home}');
cy.get(nativeFilters.filtersPanel.filterTypeInput)
.click({ scrollBehavior: false })
.type('{home}Value{enter}', { scrollBehavior: false });
cy.get(nativeFilters.filtersPanel.filterTypeInput)
.find(nativeFilters.filtersPanel.filterTypeItem)
.should('have.text', 'Value');
cy.get(nativeFilters.modal.container)
.find(nativeFilters.filtersPanel.filterName)
.click({ scrollBehavior: false })
.clear()
.type('country_name', { scrollBehavior: false });
cy.get(nativeFilters.silentLoading).should('not.exist');
cy.get(nativeFilters.filtersPanel.filterInfoInput)
.last()
.should('be.visible')
.click({ force: true });
cy.get(nativeFilters.filtersPanel.filterInfoInput)
.last()
.type('country_name {enter}');
cy.get(nativeFilters.modal.footer)
.find(nativeFilters.modal.saveButton)
.should('be.visible')
.click({ force: true });
cy.get(nativeFilters.filterFromDashboardView.filterName)
.should('be.visible', { timeout: 40000 })
.contains('country_name');
});
it('User can create parent filters using "Values are dependent on other filters"', () => {
cy.get(nativeFilters.filterFromDashboardView.expand)
.should('be.visible')
.click({ force: true });
cy.get(nativeFilters.filterFromDashboardView.createFilterButton).click();
// Create parent filter 'region'.
fillValueNativeFilterForm('region', 'wb_health_population', 'region');
// Create filter 'country_name' depend on region filter.
clickOnAddFilterInModal();
fillValueNativeFilterForm(
'country_name',
'wb_health_population',
'country_name',
);
cy.get(nativeFilters.filterConfigurationSections.displayedSection).within(
() => {
cy.contains('Values are dependent on other filters')
.should('be.visible')
.click();
},
);
addParentFilterWithValue(0, 'region');
cy.wait(1000);
cy.get(nativeFilters.modal.footer)
.contains('Save')
.should('be.visible')
.click();
// Validate both filter in dashboard view.
WORLD_HEALTH_CHARTS.forEach(waitForChartLoad);
['region', 'country_name'].forEach(it => {
cy.get(nativeFilters.filterFromDashboardView.filterName)
.contains(it)
.should('be.visible');
});
getNativeFilterPlaceholderWithIndex(1)
.invoke('text')
.should('equal', '214 options', { timeout: 20000 });
// apply first filter value and validate 2nd filter is depden on 1st filter.
applyNativeFilterValueWithIndex(0, 'East Asia & Pacific');
getNativeFilterPlaceholderWithIndex(0).should('have.text', '36 options', {
timeout: 20000,
});
});
});
xdescribe('Nativefilters', () => {

View File

@@ -122,14 +122,14 @@ describe('Test datatable', () => {
});
it('Data Pane opens and loads results', () => {
cy.get('[data-test="data-tab"]').click();
cy.get('[data-test="row-count-label"]').contains('26 rows retrieved');
cy.get('[data-test="row-count-label"]').contains('25 rows retrieved');
cy.contains('View results');
cy.get('.ant-empty-description').should('not.exist');
});
it('Datapane loads view samples', () => {
cy.get('[data-test="data-tab"]').click();
cy.contains('View samples').click();
cy.get('[data-test="row-count-label"]').contains('10k rows retrieved');
cy.get('[data-test="row-count-label"]').contains('1k rows retrieved');
cy.get('.ant-empty-description').should('not.exist');
});
});

View File

@@ -37,8 +37,8 @@ describe('SqlLab query panel', () => {
const sampleResponse = {
status: 'success',
data: [{ '?column?': 1 }],
columns: [{ name: '?column?', type: 'INT', is_date: false }],
selected_columns: [{ name: '?column?', type: 'INT', is_date: false }],
columns: [{ name: '?column?', type: 'INT', is_dttm: false }],
selected_columns: [{ name: '?column?', type: 'INT', is_dttm: false }],
expanded_columns: [],
};

View File

@@ -31,11 +31,11 @@ describe('SqlLab query tabs', () => {
cy.get('[data-test="sql-editor-tabs"]')
.children()
.eq(0)
.contains(`Untitled Query ${initialTabCount + 1}`);
.contains(`Untitled Query ${initialTabCount}`);
cy.get('[data-test="sql-editor-tabs"]')
.children()
.eq(0)
.contains(`Untitled Query ${initialTabCount + 2}`);
.contains(`Untitled Query ${initialTabCount + 1}`);
});
});

View File

@@ -327,6 +327,10 @@ export const nativeFilters = {
addFilter: dataTestLocator('add-filter-button'),
defaultValueCheck: '.ant-checkbox-checked',
},
addFilterButton: {
button: `.ant-modal-content [data-test="new-dropdown-icon"]`,
dropdownItem: '.ant-dropdown-menu-item',
},
filtersPanel: {
filterName: dataTestLocator('filters-config-modal__name-input'),
datasetName: dataTestLocator('filters-config-modal__datasource-input'),
@@ -350,6 +354,7 @@ export const nativeFilters = {
removeFilter: '[aria-label="remove"]',
silentLoading: '.loading inline-centered css-101mkpk',
filterConfigurationSections: {
displayedSection: 'div[style="height: 100%; overflow-y: auto;"]',
collapseExpandButton: '.ant-collapse-arrow',
checkedCheckbox: '.ant-checkbox-wrapper-checked',
infoTooltip: '[aria-label="Show info tooltip"]',

View File

@@ -47,6 +47,20 @@ declare namespace Cypress {
querySubstring?: string | RegExp;
chartSelector?: JQuery.Selector;
}): cy;
/**
* Get
*/
getDashboards(): cy;
getCharts(): cy;
/**
* Delete
*/
deleteDashboard(id: number): cy;
deleteDashboardByName(name: string): cy;
deleteChartByName(name: string): cy;
deleteChart(id: number): cy;
}
}

View File

@@ -19,6 +19,7 @@
import '@cypress/code-coverage/support';
const BASE_EXPLORE_URL = '/superset/explore/?form_data=';
const TokenName = Cypress.env('TOKEN_NAME');
/* eslint-disable consistent-return */
Cypress.on('uncaught:exception', err => {
@@ -102,3 +103,88 @@ Cypress.Commands.add(
return cy;
},
);
Cypress.Commands.add('deleteDashboardByName', (name: string) =>
cy.getDashboards().then((dashboards: any) => {
dashboards?.forEach((element: any) => {
if (element.dashboard_title === name) {
const elementId = element.id;
cy.deleteDashboard(elementId);
}
});
}),
);
Cypress.Commands.add('deleteDashboard', (id: number) =>
cy
.request({
method: 'DELETE',
url: `api/v1/dashboard/${id}`,
headers: {
Cookie: `csrf_access_token=${window.localStorage.getItem(
'access_token',
)}`,
'Content-Type': 'application/json',
Authorization: `Bearer ${TokenName}`,
'X-CSRFToken': `${window.localStorage.getItem('access_token')}`,
Referer: `${Cypress.config().baseUrl}/`,
},
})
.then(resp => resp),
);
Cypress.Commands.add('getDashboards', () =>
cy
.request({
method: 'GET',
url: `api/v1/dashboard/`,
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${TokenName}`,
},
})
.then(resp => resp.body.result),
);
Cypress.Commands.add('deleteChart', (id: number) =>
cy
.request({
method: 'DELETE',
url: `api/v1/chart/${id}`,
headers: {
Cookie: `csrf_access_token=${window.localStorage.getItem(
'access_token',
)}`,
'Content-Type': 'application/json',
Authorization: `Bearer ${TokenName}`,
'X-CSRFToken': `${window.localStorage.getItem('access_token')}`,
Referer: `${Cypress.config().baseUrl}/`,
},
failOnStatusCode: false,
})
.then(resp => resp),
);
Cypress.Commands.add('getCharts', () =>
cy
.request({
method: 'GET',
url: `api/v1/chart/`,
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${TokenName}`,
},
})
.then(resp => resp.body.result),
);
Cypress.Commands.add('deleteChartByName', (name: string) =>
cy.getCharts().then((slices: any) => {
slices?.forEach((element: any) => {
if (element.slice_name === name) {
const elementId = element.id;
cy.deleteChart(elementId);
}
});
}),
);

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{
"name": "superset",
"version": "0.0.0dev",
"version": "1.5.3",
"description": "Superset is a data exploration platform designed to be visual, intuitive, and interactive.",
"keywords": [
"big",
@@ -34,7 +34,7 @@
],
"scripts": {
"_lint": "eslint --ignore-path=.eslintignore --ext .js,.jsx,.ts,tsx .",
"_prettier": "prettier './({src,spec,cypress-base,plugins,packages}/**/*{.js,.jsx,.ts,.tsx,.css,.less,.scss,.sass}|package.json)'",
"_prettier": "prettier './({src,spec,cypress-base,plugins,packages,.storybook}/**/*{.js,.jsx,.ts,.tsx,.css,.less,.scss,.sass}|package.json)'",
"build": "cross-env NODE_OPTIONS=--max_old_space_size=8192 NODE_ENV=production BABEL_ENV=\"${BABEL_ENV:=production}\" webpack --mode=production --color",
"build-dev": "cross-env NODE_OPTIONS=--max_old_space_size=8192 NODE_ENV=development webpack --mode=development --color",
"build-instrumented": "cross-env NODE_ENV=production BABEL_ENV=instrumented webpack --mode=production --color",
@@ -61,7 +61,7 @@
"prettier-check": "npm run _prettier -- --check",
"prod": "npm run build",
"prune": "rm -rf ./{packages,plugins}/*/{lib,esm,tsconfig.tsbuildinfo,package-lock.json}",
"storybook": "cross-env NODE_ENV=development BABEL_ENV=development start-storybook -s ./src/assets/images -p 6006",
"storybook": "cross-env NODE_ENV=development BABEL_ENV=development start-storybook -p 6006",
"tdd": "cross-env NODE_ENV=test jest --watch",
"test": "cross-env NODE_ENV=test jest",
"type": "tsc --noEmit"
@@ -127,8 +127,8 @@
"dom-to-image": "^2.6.0",
"emotion-rgba": "0.0.9",
"fast-glob": "^3.2.7",
"fontsource-fira-code": "^3.0.5",
"fontsource-inter": "^3.0.5",
"fontsource-fira-code": "^4.0.0",
"fontsource-inter": "^4.0.0",
"fs-extra": "^10.0.0",
"fuse.js": "^6.4.6",
"geolib": "^2.0.24",
@@ -170,7 +170,6 @@
"react-jsonschema-form": "^1.2.0",
"react-lines-ellipsis": "^0.15.0",
"react-loadable": "^5.5.0",
"react-markdown": "^4.3.1",
"react-redux": "^7.2.0",
"react-resize-detector": "^6.7.6",
"react-reverse-portal": "^2.0.1",
@@ -197,7 +196,8 @@
"rison": "^0.1.1",
"scroll-into-view-if-needed": "^2.2.28",
"shortid": "^2.2.6",
"urijs": "^1.19.6",
"tinycolor2": "^1.4.2",
"urijs": "^1.19.8",
"use-immer": "^0.6.0",
"use-query-params": "^1.1.9",
"yargs": "^15.4.1"
@@ -219,15 +219,15 @@
"@emotion/jest": "^11.3.0",
"@hot-loader/react-dom": "^16.13.0",
"@istanbuljs/nyc-config-typescript": "^1.0.1",
"@storybook/addon-actions": "^6.3.12",
"@storybook/addon-essentials": "^6.3.12",
"@storybook/addon-actions": "^6.4.19",
"@storybook/addon-essentials": "^6.4.19",
"@storybook/addon-knobs": "^6.3.1",
"@storybook/addon-links": "^6.3.12",
"@storybook/addons": "^6.3.12",
"@storybook/builder-webpack5": "^6.3.12",
"@storybook/client-api": "^6.3.12",
"@storybook/manager-webpack5": "^6.3.12",
"@storybook/react": "^6.3.12",
"@storybook/addon-links": "^6.4.19",
"@storybook/addons": "^6.4.19",
"@storybook/builder-webpack5": "^6.4.19",
"@storybook/client-api": "^6.4.19",
"@storybook/manager-webpack5": "^6.4.19",
"@storybook/react": "^6.4.19",
"@svgr/webpack": "^5.5.0",
"@testing-library/dom": "^7.29.4",
"@testing-library/jest-dom": "^5.11.6",
@@ -262,6 +262,7 @@
"@types/rison": "0.0.6",
"@types/shortid": "^0.0.29",
"@types/sinon": "^9.0.5",
"@types/tinycolor2": "^1.4.3",
"@types/yargs": "12 - 15",
"@typescript-eslint/eslint-plugin": "^5.3.0",
"@typescript-eslint/parser": "^5.3.0",
@@ -291,6 +292,7 @@
"eslint-plugin-react": "^7.22.0",
"eslint-plugin-react-hooks": "^4.2.0",
"eslint-plugin-testing-library": "^3.10.1",
"eslint-plugin-theme-colors": "file:tools/eslint-plugin-theme-colors",
"exports-loader": "^0.7.0",
"fetch-mock": "^7.7.3",
"fork-ts-checker-webpack-plugin": "^6.3.3",
@@ -303,7 +305,7 @@
"jsdom": "^16.4.0",
"lerna": "^4.0.0",
"less": "^3.12.2",
"less-loader": "^5.0.0",
"less-loader": "^10.2.0",
"mini-css-extract-plugin": "^2.3.0",
"mock-socket": "^9.0.3",
"node-fetch": "^2.6.1",
@@ -323,6 +325,7 @@
"transform-loader": "^0.2.4",
"ts-loader": "^9.2.5",
"typescript": "^4.5.4",
"vm-browserify": "^1.1.2",
"webpack": "^5.52.1",
"webpack-bundle-analyzer": "^4.4.2",
"webpack-cli": "^4.8.0",
@@ -332,6 +335,12 @@
},
"engines": {
"node": "^16.9.1",
"npm": "^7.5.4"
"npm": "^7.5.4 || ^8.1.2"
},
"overrides": {
"omnibar": {
"react": "^16.13.1",
"react-dom": "^16.13.0"
}
}
}

View File

@@ -2,40 +2,41 @@
"name": "@superset-ui/generator-superset",
"version": "0.18.25",
"description": "Scaffolder for Superset",
"bugs": {
"url": "https://github.com/apache-superset/superset-ui/issues"
},
"homepage": "https://github.com/apache-superset/superset-ui#readme",
"repository": {
"type": "git",
"url": "git+https://github.com/apache-superset/superset-ui.git"
},
"author": "Superset",
"files": [
"generators"
],
"main": "generators/index.js",
"keywords": [
"yeoman",
"generator",
"superset",
"yeoman-generator"
],
"devDependencies": {
"yeoman-assert": "^3.1.0",
"yeoman-test": "^6.2.0",
"fs-extra": "^10.0.0"
"homepage": "https://github.com/apache-superset/superset-ui#readme",
"bugs": {
"url": "https://github.com/apache-superset/superset-ui/issues"
},
"engines": {
"npm": ">= 4.0.0"
"repository": {
"type": "git",
"url": "git+https://github.com/apache-superset/superset-ui.git"
},
"license": "Apache-2.0",
"author": "Superset",
"main": "generators/index.js",
"files": [
"generators"
],
"dependencies": {
"chalk": "^4.0.0",
"lodash": "^4.17.11",
"yeoman-generator": "^4.0.0",
"yosay": "^2.0.2"
},
"license": "Apache-2.0",
"devDependencies": {
"fs-extra": "^10.0.0",
"yeoman-assert": "^3.1.0",
"yeoman-environment": "^3.3.0",
"yeoman-test": "^6.2.0"
},
"engines": {
"npm": ">= 4.0.0"
},
"publishConfig": {
"access": "public"
}

View File

@@ -2,6 +2,19 @@
"name": "@superset-ui/chart-controls",
"version": "0.18.25",
"description": "Superset UI control-utils",
"keywords": [
"superset"
],
"homepage": "https://github.com/apache-superset/superset-ui#readme",
"bugs": {
"url": "https://github.com/apache-superset/superset-ui/issues"
},
"repository": {
"type": "git",
"url": "git+https://github.com/apache-superset/superset-ui.git"
},
"license": "Apache-2.0",
"author": "Superset",
"sideEffects": false,
"main": "lib/index.js",
"module": "esm/index.js",
@@ -9,22 +22,6 @@
"esm",
"lib"
],
"repository": {
"type": "git",
"url": "git+https://github.com/apache-superset/superset-ui.git"
},
"keywords": [
"superset"
],
"author": "Superset",
"license": "Apache-2.0",
"bugs": {
"url": "https://github.com/apache-superset/superset-ui/issues"
},
"homepage": "https://github.com/apache-superset/superset-ui#readme",
"publishConfig": {
"access": "public"
},
"dependencies": {
"@react-icons/all-files": "^4.1.0",
"lodash": "^4.17.15",
@@ -33,10 +30,18 @@
"peerDependencies": {
"@emotion/react": "^11.4.1",
"@superset-ui/core": "*",
"@testing-library/dom": "^7.29.4",
"@testing-library/jest-dom": "^5.11.6",
"@testing-library/react": "^11.2.0",
"@testing-library/react-hooks": "^5.0.3",
"@testing-library/user-event": "^12.7.0",
"@types/enzyme": "^3.10.5",
"@types/react": "*",
"antd": "^4.9.4",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"@types/enzyme": "^3.10.5"
"react-dom": "^16.13.1"
},
"publishConfig": {
"access": "public"
}
}

View File

@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
import React, { useEffect, useState, ReactNode } from 'react';
import React, { useState, ReactNode, useLayoutEffect } from 'react';
import { styled } from '@superset-ui/core';
import { Tooltip } from './Tooltip';
import { ColumnTypeLabel } from './ColumnTypeLabel';
@@ -47,7 +47,7 @@ export function ColumnOption({
const type = hasExpression ? 'expression' : type_generic;
const [tooltipText, setTooltipText] = useState<ReactNode>(column.column_name);
useEffect(() => {
useLayoutEffect(() => {
setTooltipText(getColumnTooltipNode(column, labelRef));
}, [labelRef, column]);
@@ -61,26 +61,12 @@ export function ColumnOption({
details={column.certification_details}
/>
)}
<Tooltip
id="metric-name-tooltip"
title={tooltipText}
trigger={['hover']}
placement="top"
>
<Tooltip id="metric-name-tooltip" title={tooltipText}>
<span className="m-r-5 option-label column-option-label" ref={labelRef}>
{getColumnLabelText(column)}
</span>
</Tooltip>
{column.description && (
<InfoTooltipWithTrigger
className="m-r-5 text-muted"
icon="info"
tooltip={column.description}
label={`descr-${column.column_name}`}
placement="top"
/>
)}
{hasExpression && (
<InfoTooltipWithTrigger
className="m-r-5 text-muted"

View File

@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
import React, { useEffect, useState, ReactNode } from 'react';
import React, { useState, ReactNode, useLayoutEffect } from 'react';
import { styled, Metric, SafeMarkdown } from '@superset-ui/core';
import InfoTooltipWithTrigger from './InfoTooltipWithTrigger';
import { ColumnTypeLabel } from './ColumnTypeLabel';
@@ -63,7 +63,7 @@ export function MetricOption({
const [tooltipText, setTooltipText] = useState<ReactNode>(metric.metric_name);
useEffect(() => {
useLayoutEffect(() => {
setTooltipText(getMetricTooltipNode(metric, labelRef));
}, [labelRef, metric]);
@@ -77,24 +77,11 @@ export function MetricOption({
details={metric.certification_details}
/>
)}
<Tooltip
id="metric-name-tooltip"
title={tooltipText}
trigger={['hover']}
placement="top"
>
<Tooltip id="metric-name-tooltip" title={tooltipText}>
<span className="option-label metric-option-label" ref={labelRef}>
{link}
</span>
</Tooltip>
{metric.description && (
<InfoTooltipWithTrigger
className="text-muted"
icon="info"
tooltip={metric.description}
label={`descr-${metric.metric_name}`}
/>
)}
{showFormula && (
<InfoTooltipWithTrigger
className="text-muted"

View File

@@ -46,9 +46,17 @@ export const Tooltip = ({ overlayStyle, color, ...props }: TooltipProps) => {
overlayStyle={{
fontSize: theme.typography.sizes.s,
lineHeight: '1.6',
maxWidth: theme.gridUnit * 62,
minWidth: theme.gridUnit * 30,
...overlayStyle,
}}
// make the tooltip display closer to the label
align={{ offset: [0, 1] }}
color={defaultColor || color}
trigger="hover"
placement="bottom"
// don't allow hovering over the tooltip
mouseLeaveDelay={0}
{...props}
/>
</>

View File

@@ -18,9 +18,41 @@
*/
import React, { ReactNode } from 'react';
import { t } from '@superset-ui/core';
import { css, styled, t } from '@superset-ui/core';
import { ColumnMeta, Metric } from '@superset-ui/chart-controls';
const TooltipSectionWrapper = styled.div`
${({ theme }) => css`
display: flex;
flex-direction: column;
font-size: ${theme.typography.sizes.s}px;
line-height: 1.2;
&:not(:last-of-type) {
margin-bottom: ${theme.gridUnit * 2}px;
}
`}
`;
const TooltipSectionLabel = styled.span`
${({ theme }) => css`
font-weight: ${theme.typography.weights.bold};
`}
`;
const TooltipSection = ({
label,
text,
}: {
label: ReactNode;
text: ReactNode;
}) => (
<TooltipSectionWrapper>
<TooltipSectionLabel>{label}</TooltipSectionLabel>
<span>{text}</span>
</TooltipSectionWrapper>
);
export const isLabelTruncated = (labelRef?: React.RefObject<any>): boolean =>
!!(
labelRef &&
@@ -35,22 +67,25 @@ export const getColumnTooltipNode = (
column: ColumnMeta,
labelRef?: React.RefObject<any>,
): ReactNode => {
// don't show tooltip if it hasn't verbose_name and hasn't truncated
if (!column.verbose_name && !isLabelTruncated(labelRef)) {
if (
!column.verbose_name &&
!column.description &&
!isLabelTruncated(labelRef)
) {
return null;
}
if (column.verbose_name) {
return (
<>
<div>{t('column name: %s', column.column_name)}</div>
<div>{t('verbose name: %s', column.verbose_name)}</div>
</>
);
}
// show column name in tooltip when column truncated
return t('column name: %s', column.column_name);
return (
<>
<TooltipSection label={t('Column name')} text={column.column_name} />
{column.verbose_name && (
<TooltipSection label={t('Label')} text={column.verbose_name} />
)}
{column.description && (
<TooltipSection label={t('Description')} text={column.description} />
)}
</>
);
};
type MetricType = Omit<Metric, 'id'> & { label?: string };
@@ -59,23 +94,27 @@ export const getMetricTooltipNode = (
metric: MetricType,
labelRef?: React.RefObject<any>,
): ReactNode => {
// don't show tooltip if it hasn't verbose_name, label and hasn't truncated
if (!metric.verbose_name && !metric.label && !isLabelTruncated(labelRef)) {
if (
!metric.verbose_name &&
!metric.description &&
!metric.label &&
!isLabelTruncated(labelRef)
) {
return null;
}
if (metric.verbose_name) {
return (
<>
<div>{t('metric name: %s', metric.metric_name)}</div>
<div>{t('verbose name: %s', metric.verbose_name)}</div>
</>
);
}
if (isLabelTruncated(labelRef) && metric.label) {
return t('label name: %s', metric.label);
}
return t('metric name: %s', metric.metric_name);
return (
<>
<TooltipSection label={t('Metric name')} text={metric.metric_name} />
{(metric.label || metric.verbose_name) && (
<TooltipSection
label={t('Label')}
text={metric.label || metric.verbose_name}
/>
)}
{metric.description && (
<TooltipSection label={t('Description')} text={metric.description} />
)}
</>
);
};

View File

@@ -21,16 +21,16 @@ import {
getColumnLabel,
getMetricLabel,
PostProcessingBoxplot,
BoxPlotQueryObjectWhiskerType,
} from '@superset-ui/core';
import { PostProcessingFactory } from './types';
type BoxPlotQueryObjectWhiskerType =
PostProcessingBoxplot['options']['whisker_type'];
const PERCENTILE_REGEX = /(\d+)\/(\d+) percentiles/;
export const boxplotOperator: PostProcessingFactory<
PostProcessingBoxplot | undefined
> = (formData, queryObject) => {
export const boxplotOperator: PostProcessingFactory<PostProcessingBoxplot> = (
formData,
queryObject,
) => {
const { groupby, whiskerOptions } = formData;
if (whiskerOptions) {

View File

@@ -19,16 +19,15 @@
import { PostProcessingContribution } from '@superset-ui/core';
import { PostProcessingFactory } from './types';
export const contributionOperator: PostProcessingFactory<
PostProcessingContribution | undefined
> = (formData, queryObject) => {
if (formData.contributionMode) {
return {
operation: 'contribution',
options: {
orientation: formData.contributionMode,
},
};
}
return undefined;
};
export const contributionOperator: PostProcessingFactory<PostProcessingContribution> =
(formData, queryObject) => {
if (formData.contributionMode) {
return {
operation: 'contribution',
options: {
orientation: formData.contributionMode,
},
};
}
return undefined;
};

View File

@@ -0,0 +1,28 @@
/* eslint-disable camelcase */
/**
* 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 limitationsxw
* under the License.
*/
import { PostProcessingFlatten } from '@superset-ui/core';
import { PostProcessingFactory } from './types';
export const flattenOperator: PostProcessingFactory<PostProcessingFlatten> = (
formData,
queryObject,
) => ({
operation: 'flatten',
});

View File

@@ -23,7 +23,9 @@ export { timeComparePivotOperator } from './timeComparePivotOperator';
export { sortOperator } from './sortOperator';
export { pivotOperator } from './pivotOperator';
export { resampleOperator } from './resampleOperator';
export { renameOperator } from './renameOperator';
export { contributionOperator } from './contributionOperator';
export { prophetOperator } from './prophetOperator';
export { boxplotOperator } from './boxplotOperator';
export { flattenOperator } from './flattenOperator';
export * from './utils';

View File

@@ -24,23 +24,20 @@ import {
PostProcessingPivot,
} from '@superset-ui/core';
import { PostProcessingFactory } from './types';
import { isValidTimeCompare } from './utils';
import { timeComparePivotOperator } from './timeComparePivotOperator';
export const pivotOperator: PostProcessingFactory<
PostProcessingPivot | undefined
> = (formData, queryObject) => {
export const pivotOperator: PostProcessingFactory<PostProcessingPivot> = (
formData,
queryObject,
) => {
const metricLabels = ensureIsArray(queryObject.metrics).map(getMetricLabel);
const { x_axis: xAxis } = formData;
if ((xAxis || queryObject.is_timeseries) && metricLabels.length) {
if (isValidTimeCompare(formData, queryObject)) {
return timeComparePivotOperator(formData, queryObject);
}
if ((xAxis || queryObject.is_timeseries) && metricLabels.length) {
const index = [getColumnLabel(xAxis || DTTM_ALIAS)];
return {
operation: 'pivot',
options: {
index: [xAxis || DTTM_ALIAS],
index,
columns: ensureIsArray(queryObject.columns).map(getColumnLabel),
// Create 'dummy' mean aggregates to assign cell values in pivot table
// use the 'mean' aggregates to avoid drop NaN. PR: https://github.com/apache-superset/superset-ui/pull/1231
@@ -48,6 +45,8 @@ export const pivotOperator: PostProcessingFactory<
metricLabels.map(metric => [metric, { operator: 'mean' }]),
),
drop_missing_columns: false,
flatten_columns: false,
reset_index: false,
},
};
}

View File

@@ -16,12 +16,18 @@
* specific language governing permissions and limitationsxw
* under the License.
*/
import { DTTM_ALIAS, PostProcessingProphet } from '@superset-ui/core';
import {
DTTM_ALIAS,
getColumnLabel,
PostProcessingProphet,
} from '@superset-ui/core';
import { PostProcessingFactory } from './types';
export const prophetOperator: PostProcessingFactory<
PostProcessingProphet | undefined
> = (formData, queryObject) => {
export const prophetOperator: PostProcessingFactory<PostProcessingProphet> = (
formData,
queryObject,
) => {
const index = getColumnLabel(formData.x_axis || DTTM_ALIAS);
if (formData.forecastEnabled) {
return {
operation: 'prophet',
@@ -32,7 +38,7 @@ export const prophetOperator: PostProcessingFactory<
yearly_seasonality: formData.forecastSeasonalityYearly,
weekly_seasonality: formData.forecastSeasonalityWeekly,
daily_seasonality: formData.forecastSeasonalityDaily,
index: formData.x_axis || DTTM_ALIAS,
index,
},
};
}

View File

@@ -0,0 +1,89 @@
/* eslint-disable camelcase */
/**
* 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 limitationsxw
* under the License.
*/
import {
PostProcessingRename,
ensureIsArray,
getMetricLabel,
ComparisionType,
} from '@superset-ui/core';
import { PostProcessingFactory } from './types';
import { getMetricOffsetsMap, isValidTimeCompare } from './utils';
export const renameOperator: PostProcessingFactory<PostProcessingRename> = (
formData,
queryObject,
) => {
const metrics = ensureIsArray(queryObject.metrics);
const columns = ensureIsArray(queryObject.columns);
const { x_axis: xAxis } = formData;
// remove or rename top level of column name(metric name) in the MultiIndex when
// 1) only 1 metric
// 2) exist dimentsion
// 3) exist xAxis
// 4) exist time comparison, and comparison type is "actual values"
if (
metrics.length === 1 &&
columns.length > 0 &&
(xAxis || queryObject.is_timeseries) &&
!(
// todo: we should provide an approach to handle derived metrics
(
isValidTimeCompare(formData, queryObject) &&
[
ComparisionType.Difference,
ComparisionType.Ratio,
ComparisionType.Percentage,
].includes(formData.comparison_type)
)
)
) {
const renamePairs: [string, string | null][] = [];
if (
// "actual values" will add derived metric.
// we will rename the "metric" from the metricWithOffset label
// for example: "count__1 year ago" => "1 year ago"
isValidTimeCompare(formData, queryObject) &&
formData.comparison_type === ComparisionType.Values
) {
const metricOffsetMap = getMetricOffsetsMap(formData, queryObject);
const timeOffsets = ensureIsArray(formData.time_compare);
[...metricOffsetMap.keys()].forEach(metricWithOffset => {
const offsetLabel = timeOffsets.find(offset =>
metricWithOffset.includes(offset),
);
renamePairs.push([metricWithOffset, offsetLabel]);
});
}
renamePairs.push([getMetricLabel(metrics[0]), null]);
return {
operation: 'rename',
options: {
columns: Object.fromEntries(renamePairs),
level: 0,
inplace: true,
},
};
}
return undefined;
};

View File

@@ -17,36 +17,23 @@
* specific language governing permissions and limitationsxw
* under the License.
*/
import {
DTTM_ALIAS,
ensureIsArray,
isPhysicalColumn,
PostProcessingResample,
} from '@superset-ui/core';
import { PostProcessingResample } from '@superset-ui/core';
import { PostProcessingFactory } from './types';
export const resampleOperator: PostProcessingFactory<
PostProcessingResample | undefined
> = (formData, queryObject) => {
export const resampleOperator: PostProcessingFactory<PostProcessingResample> = (
formData,
queryObject,
) => {
const resampleZeroFill = formData.resample_method === 'zerofill';
const resampleMethod = resampleZeroFill ? 'asfreq' : formData.resample_method;
const resampleRule = formData.resample_rule;
if (resampleMethod && resampleRule) {
const groupby_columns = ensureIsArray(queryObject.columns).map(column => {
if (isPhysicalColumn(column)) {
return column;
}
return column.label;
});
return {
operation: 'resample',
options: {
method: resampleMethod,
rule: resampleRule,
fill_value: resampleZeroFill ? 0 : null,
time_column: formData.x_axis || DTTM_ALIAS,
groupby_columns,
},
};
}

View File

@@ -18,39 +18,25 @@
* under the License.
*/
import {
ComparisionType,
ensureIsArray,
ensureIsInt,
PostProcessingCum,
PostProcessingRolling,
RollingType,
} from '@superset-ui/core';
import {
getMetricOffsetsMap,
isValidTimeCompare,
TIME_COMPARISON_SEPARATOR,
} from './utils';
import { getMetricOffsetsMap, isValidTimeCompare } from './utils';
import { PostProcessingFactory } from './types';
export const rollingWindowOperator: PostProcessingFactory<
PostProcessingRolling | PostProcessingCum | undefined
PostProcessingRolling | PostProcessingCum
> = (formData, queryObject) => {
let columns: (string | undefined)[];
if (isValidTimeCompare(formData, queryObject)) {
const metricsMap = getMetricOffsetsMap(formData, queryObject);
const comparisonType = formData.comparison_type;
if (comparisonType === ComparisionType.Values) {
// time compare type: actual values
columns = [
...Array.from(metricsMap.values()),
...Array.from(metricsMap.keys()),
];
} else {
// time compare type: difference / percentage / ratio
columns = Array.from(metricsMap.entries()).map(([offset, metric]) =>
[comparisonType, metric, offset].join(TIME_COMPARISON_SEPARATOR),
);
}
columns = [
...Array.from(metricsMap.values()),
...Array.from(metricsMap.keys()),
];
} else {
columns = ensureIsArray(queryObject.metrics).map(metric => {
if (typeof metric === 'string') {
@@ -67,7 +53,6 @@ export const rollingWindowOperator: PostProcessingFactory<
options: {
operator: 'sum',
columns: columnsMap,
is_pivot_df: true,
},
};
}
@@ -84,7 +69,6 @@ export const rollingWindowOperator: PostProcessingFactory<
window: ensureIsInt(formData.rolling_periods, 1),
min_periods: ensureIsInt(formData.min_periods, 0),
columns: columnsMap,
is_pivot_df: true,
},
};
}

View File

@@ -20,9 +20,10 @@
import { DTTM_ALIAS, PostProcessingSort, RollingType } from '@superset-ui/core';
import { PostProcessingFactory } from './types';
export const sortOperator: PostProcessingFactory<
PostProcessingSort | undefined
> = (formData, queryObject) => {
export const sortOperator: PostProcessingFactory<PostProcessingSort> = (
formData,
queryObject,
) => {
const { x_axis: xAxis } = formData;
if (
(xAxis || queryObject.is_timeseries) &&

View File

@@ -21,26 +21,25 @@ import { ComparisionType, PostProcessingCompare } from '@superset-ui/core';
import { getMetricOffsetsMap, isValidTimeCompare } from './utils';
import { PostProcessingFactory } from './types';
export const timeCompareOperator: PostProcessingFactory<
PostProcessingCompare | undefined
> = (formData, queryObject) => {
const comparisonType = formData.comparison_type;
const metricOffsetMap = getMetricOffsetsMap(formData, queryObject);
export const timeCompareOperator: PostProcessingFactory<PostProcessingCompare> =
(formData, queryObject) => {
const comparisonType = formData.comparison_type;
const metricOffsetMap = getMetricOffsetsMap(formData, queryObject);
if (
isValidTimeCompare(formData, queryObject) &&
comparisonType !== ComparisionType.Values
) {
return {
operation: 'compare',
options: {
source_columns: Array.from(metricOffsetMap.values()),
compare_columns: Array.from(metricOffsetMap.keys()),
compare_type: comparisonType,
drop_original_columns: true,
},
};
}
if (
isValidTimeCompare(formData, queryObject) &&
comparisonType !== ComparisionType.Values
) {
return {
operation: 'compare',
options: {
source_columns: Array.from(metricOffsetMap.values()),
compare_columns: Array.from(metricOffsetMap.keys()),
compare_type: comparisonType,
drop_original_columns: true,
},
};
}
return undefined;
};
return undefined;
};

View File

@@ -18,54 +18,41 @@
* under the License.
*/
import {
ComparisionType,
DTTM_ALIAS,
ensureIsArray,
getColumnLabel,
NumpyFunction,
PostProcessingPivot,
} from '@superset-ui/core';
import {
getMetricOffsetsMap,
isValidTimeCompare,
TIME_COMPARISON_SEPARATOR,
} from './utils';
import { getMetricOffsetsMap, isValidTimeCompare } from './utils';
import { PostProcessingFactory } from './types';
export const timeComparePivotOperator: PostProcessingFactory<
PostProcessingPivot | undefined
> = (formData, queryObject) => {
const comparisonType = formData.comparison_type;
const metricOffsetMap = getMetricOffsetsMap(formData, queryObject);
export const timeComparePivotOperator: PostProcessingFactory<PostProcessingPivot> =
(formData, queryObject) => {
const metricOffsetMap = getMetricOffsetsMap(formData, queryObject);
if (isValidTimeCompare(formData, queryObject)) {
const valuesAgg = Object.fromEntries(
[...metricOffsetMap.values(), ...metricOffsetMap.keys()].map(metric => [
metric,
// use the 'mean' aggregates to avoid drop NaN
{ operator: 'mean' as NumpyFunction },
]),
);
const changeAgg = Object.fromEntries(
[...metricOffsetMap.entries()]
.map(([offset, metric]) =>
[comparisonType, metric, offset].join(TIME_COMPARISON_SEPARATOR),
)
// use the 'mean' aggregates to avoid drop NaN
.map(metric => [metric, { operator: 'mean' as NumpyFunction }]),
);
if (isValidTimeCompare(formData, queryObject)) {
const aggregates = Object.fromEntries(
[...metricOffsetMap.values(), ...metricOffsetMap.keys()].map(metric => [
metric,
// use the 'mean' aggregates to avoid drop NaN
{ operator: 'mean' as NumpyFunction },
]),
);
const index = [getColumnLabel(formData.x_axis || DTTM_ALIAS)];
return {
operation: 'pivot',
options: {
index: [formData.x_axis || DTTM_ALIAS],
columns: ensureIsArray(queryObject.columns).map(getColumnLabel),
aggregates:
comparisonType === ComparisionType.Values ? valuesAgg : changeAgg,
drop_missing_columns: false,
},
};
}
return {
operation: 'pivot',
options: {
index,
columns: ensureIsArray(queryObject.columns).map(getColumnLabel),
drop_missing_columns: false,
flatten_columns: false,
reset_index: false,
aggregates,
},
};
}
return undefined;
};
return undefined;
};

View File

@@ -170,6 +170,7 @@ export const advancedAnalyticsControls: ControlPanelSectionConfig = {
choices: [
['asfreq', 'Null imputation'],
['zerofill', 'Zero imputation'],
['linear', 'Linear interpolation'],
['ffill', 'Forward values'],
['bfill', 'Backward values'],
['median', 'Median values'],

View File

@@ -48,8 +48,10 @@ export default React.memo(function ColumnConfigItem({
>
<div
css={{
display: 'flex',
alignItems: 'center',
cursor: 'pointer',
padding: `${1.5 * gridUnit}px ${2 * gridUnit}px`,
padding: `${gridUnit}px ${2 * gridUnit}px`,
borderBottom: `1px solid ${colors.grayscale.light2}`,
position: 'relative',
paddingRight: caretWidth,

View File

@@ -80,7 +80,7 @@ export const dndEntity: typeof dndGroupByControl = {
export const dnd_adhoc_filters: SharedControlConfig<'DndFilterSelect'> = {
type: 'DndFilterSelect',
label: t('Filters'),
default: null,
default: [],
description: '',
mapStateToProps: ({ datasource, form_data }) => ({
columns: datasource?.columns.filter(c => c.filterable) || [],

View File

@@ -43,6 +43,8 @@ import {
SequentialScheme,
legacyValidateInteger,
validateNonEmpty,
JsonArray,
ComparisionType,
} from '@superset-ui/core';
import {
@@ -89,11 +91,21 @@ export const PRIMARY_COLOR = { r: 0, g: 122, b: 135, a: 1 };
const ROW_LIMIT_OPTIONS = [10, 50, 100, 250, 500, 1000, 5000, 10000, 50000];
const SERIES_LIMITS = [5, 10, 25, 50, 100, 500];
const appContainer = document.getElementById('app');
const { user } = JSON.parse(
appContainer?.getAttribute('data-bootstrap') || '{}',
);
type Control = {
savedMetrics?: Metric[] | null;
default?: unknown;
};
type SelectDefaultOption = {
label: string;
value: string;
};
const groupByControl: SharedControlConfig<'SelectControl', ColumnMeta> = {
type: 'SelectControl',
label: t('Group by'),
@@ -106,8 +118,6 @@ const groupByControl: SharedControlConfig<'SelectControl', ColumnMeta> = {
'One or many columns to group by. High cardinality groupings should include a sort by metric ' +
'and series limit to limit the number of fetched and rendered series.',
),
sortComparator: (a: { label: string }, b: { label: string }) =>
a.label.localeCompare(b.label),
optionRenderer: c => <ColumnOption showType column={c} />,
valueRenderer: c => <ColumnOption column={c} />,
valueKey: 'column_name',
@@ -162,6 +172,7 @@ const datasourceControl: SharedControlConfig<'DatasourceControl'> = {
mapStateToProps: ({ datasource, form_data }) => ({
datasource,
form_data,
user,
}),
};
@@ -201,6 +212,9 @@ const linear_color_scheme: SharedControlConfig<'ColorSchemeControl'> = {
renderTrigger: true,
schemes: () => sequentialSchemeRegistry.getMap(),
isLinear: true,
mapStateToProps: state => ({
dashboardId: state?.form_data?.dashboardId,
}),
};
const secondary_metric: SharedControlConfig<'MetricsControl'> = {
@@ -337,6 +351,18 @@ const row_limit: SharedControlConfig<'SelectControl'> = {
description: t('Limits the number of rows that get displayed.'),
};
const order_desc: SharedControlConfig<'CheckboxControl'> = {
type: 'CheckboxControl',
label: t('Sort Descending'),
default: true,
description: t('Whether to sort descending or ascending'),
visibility: ({ controls }) =>
Boolean(
controls?.timeseries_limit_metric.value &&
(controls?.timeseries_limit_metric.value as JsonArray).length,
),
};
const limit: SharedControlConfig<'SelectControl'> = {
type: 'SelectControl',
freeForm: true,
@@ -424,29 +450,33 @@ const size: SharedControlConfig<'MetricsControl'> = {
default: null,
};
const y_axis_format: SharedControlConfig<'SelectControl'> = {
type: 'SelectControl',
freeForm: true,
label: t('Y Axis Format'),
renderTrigger: true,
default: DEFAULT_NUMBER_FORMAT,
choices: D3_FORMAT_OPTIONS,
description: D3_FORMAT_DOCS,
mapStateToProps: state => {
const showWarning = state.controls?.comparison_type?.value === 'percentage';
return {
warning: showWarning
? t(
'When `Calculation type` is set to "Percentage change", the Y ' +
'Axis Format is forced to `.1%`',
)
: null,
disabled: showWarning,
};
},
};
const y_axis_format: SharedControlConfig<'SelectControl', SelectDefaultOption> =
{
type: 'SelectControl',
freeForm: true,
label: t('Y Axis Format'),
renderTrigger: true,
default: DEFAULT_NUMBER_FORMAT,
choices: D3_FORMAT_OPTIONS,
description: D3_FORMAT_DOCS,
tokenSeparators: ['\n', '\t', ';'],
filterOption: ({ data: option }, search) =>
option.label.includes(search) || option.value.includes(search),
mapStateToProps: state => {
const isPercentage =
state.controls?.comparison_type?.value === ComparisionType.Percentage;
return {
choices: isPercentage
? D3_FORMAT_OPTIONS.filter(option => option[0].includes('%'))
: D3_FORMAT_OPTIONS,
};
},
};
const x_axis_time_format: SharedControlConfig<'SelectControl'> = {
const x_axis_time_format: SharedControlConfig<
'SelectControl',
SelectDefaultOption
> = {
type: 'SelectControl',
freeForm: true,
label: t('Time format'),
@@ -454,12 +484,14 @@ const x_axis_time_format: SharedControlConfig<'SelectControl'> = {
default: DEFAULT_TIME_FORMAT,
choices: D3_TIME_FORMAT_OPTIONS,
description: D3_TIME_FORMAT_DOCS,
filterOption: ({ data: option }, search) =>
option.label.includes(search) || option.value.includes(search),
};
const adhoc_filters: SharedControlConfig<'AdhocFilterControl'> = {
type: 'AdhocFilterControl',
label: t('Filters'),
default: null,
default: [],
description: '',
mapStateToProps: ({ datasource, form_data }) => ({
columns: datasource?.columns.filter(c => c.filterable) || [],
@@ -508,6 +540,7 @@ const sharedControls = {
limit,
timeseries_limit_metric: enableExploreDnd ? dnd_sort_by : sort_by,
orderby: enableExploreDnd ? dnd_sort_by : sort_by,
order_desc,
series: enableExploreDnd ? dndSeries : series,
entity: enableExploreDnd ? dndEntity : entity,
x: enableExploreDnd ? dnd_x : x,

View File

@@ -171,6 +171,8 @@ export type TabOverride = 'data' | 'customize' | boolean;
* bubbled up to the control header, section header and query panel header.
* - warning: text shown as a tooltip on a warning icon in the control's header
* - error: text shown as a tooltip on a error icon in the control's header
* - shouldMapStateToProps: a function that receives the previous and current app state
* and determines if the control needs to recalculate it's props based on the new state.
* - mapStateToProps: a function that receives the App's state and return an object of k/v
* to overwrite configuration at runtime. This is useful to alter a component based on
* anything external to it, like another control's value. For instance it's possible to
@@ -198,6 +200,13 @@ export interface BaseControlConfig<
/**
* Add additional props to chart control.
*/
shouldMapStateToProps?: (
prevState: ControlPanelState,
state: ControlPanelState,
controlState: ControlState,
// TODO: add strict `chartState` typing (see superset-frontend/src/explore/types)
chartState?: AnyDict,
) => boolean;
mapStateToProps?: (
state: ControlPanelState,
controlState: ControlState,

View File

@@ -25,7 +25,7 @@ export const D3_FORMAT_DOCS = t(
// input choices & options
export const D3_FORMAT_OPTIONS: [string, string][] = [
[NumberFormats.SMART_NUMBER, t('Adaptative formating')],
[NumberFormats.SMART_NUMBER, t('Adaptive formatting')],
['~g', t('Original value')],
[',d', ',d (12345.432 => 12,345)'],
['.1s', '.1s (12345.432 => 10k)'],
@@ -34,6 +34,8 @@ export const D3_FORMAT_OPTIONS: [string, string][] = [
['.2%', '.2% (12345.432 => 1234543.20%)'],
['.3%', '.3% (12345.432 => 1234543.200%)'],
['.4r', '.4r (12345.432 => 12350)'],
[',.1f', ',.1f (12345.432 => 12,345.4)'],
[',.2f', ',.2f (12345.432 => 12,345.43)'],
[',.3f', ',.3f (12345.432 => 12,345.432)'],
['+,', '+, (12345.432 => +12,345.432)'],
['$,.2f', '$,.2f (12345.432 => $12,345.43)'],
@@ -46,7 +48,7 @@ export const D3_TIME_FORMAT_DOCS = t(
);
export const D3_TIME_FORMAT_OPTIONS: [string, string][] = [
[smartDateFormatter.id, t('Adaptative formating')],
[smartDateFormatter.id, t('Adaptive formatting')],
['%d/%m/%Y', '%d/%m/%Y | 14/01/2019'],
['%m/%d/%Y', '%m/%d/%Y | 01/14/2019'],
['%Y-%m-%d', '%Y-%m-%d | 2019-01-14'],

View File

@@ -53,12 +53,7 @@ describe('ColumnOption', () => {
expect(lbl).toHaveLength(1);
expect(lbl.first().text()).toBe('Foo');
});
it('shows 2 InfoTooltipWithTrigger', () => {
expect(wrapper.find(InfoTooltipWithTrigger)).toHaveLength(2);
});
it('shows only 1 InfoTooltipWithTrigger when no descr', () => {
delete props.column.description;
wrapper = shallow(factory(props));
it('shows 1 InfoTooltipWithTrigger', () => {
expect(wrapper.find(InfoTooltipWithTrigger)).toHaveLength(1);
});
it('shows a label with column_name when no verbose_name', () => {

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