Compare commits
72 Commits
fix-query-
...
3.1.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0cd2431989 | ||
|
|
3de71e25e8 | ||
|
|
c8c8136ac3 | ||
|
|
8db06b4cb2 | ||
|
|
136c0e3b4a | ||
|
|
1daab2731d | ||
|
|
ed29c5b855 | ||
|
|
faad565fab | ||
|
|
0e85a43acf | ||
|
|
802dc24a76 | ||
|
|
bd195893af | ||
|
|
79e7f2732d | ||
|
|
d356d83bf6 | ||
|
|
ac7d281e8a | ||
|
|
f6803f628c | ||
|
|
28c518e578 | ||
|
|
c520cf463e | ||
|
|
5d49100a22 | ||
|
|
76e2388656 | ||
|
|
3dad685b6e | ||
|
|
1c77945980 | ||
|
|
5249815fbf | ||
|
|
b1b2b57df2 | ||
|
|
4a8727d8d0 | ||
|
|
7b969c9450 | ||
|
|
5b6e9abf00 | ||
|
|
ba4319472d | ||
|
|
c19447ee88 | ||
|
|
57155fdfc7 | ||
|
|
b5cb3ec13c | ||
|
|
9c109700ff | ||
|
|
ba9eef0407 | ||
|
|
dd68c6e2e5 | ||
|
|
31bb9a690a | ||
|
|
9632014402 | ||
|
|
103d23781b | ||
|
|
4d0404119c | ||
|
|
dbc779f30a | ||
|
|
3d7b827d79 | ||
|
|
0ac833d0c5 | ||
|
|
2dc29cee9a | ||
|
|
be81aaa31a | ||
|
|
8185ac3e33 | ||
|
|
463989dbc9 | ||
|
|
38b8b03f90 | ||
|
|
d0961d0ed8 | ||
|
|
b699df7030 | ||
|
|
c2612d8c26 | ||
|
|
ec0a338aa3 | ||
|
|
6fa75b7047 | ||
|
|
77c73b63db | ||
|
|
fb50819fcd | ||
|
|
5c24c580dd | ||
|
|
2104a9a853 | ||
|
|
0925d75dfa | ||
|
|
96c0497fa9 | ||
|
|
5bcd3ef17e | ||
|
|
5ec1edc876 | ||
|
|
aaa50c4b4a | ||
|
|
880086c750 | ||
|
|
d0aa34bf79 | ||
|
|
77332bfb38 | ||
|
|
ceac19fa2f | ||
|
|
79d5975028 | ||
|
|
4a4f9983df | ||
|
|
26e59662fb | ||
|
|
fad4616d2f | ||
|
|
2c3bf2895f | ||
|
|
93319696de | ||
|
|
e382d0dd28 | ||
|
|
f4fd0e19e2 | ||
|
|
c8844bdd5e |
475
CHANGELOG.md
@@ -19,9 +19,13 @@ under the License.
|
||||
|
||||
## Change Log
|
||||
|
||||
- [3.1.0](#310-tue-jan-9-150500-2023--0800)
|
||||
- [3.0.3](#303-fri-dec-8-054009-2023--0800)
|
||||
- [3.0.2](#302-mon-nov-20-073838-2023--0500)
|
||||
- [3.0.1](#301-tue-oct-13-103221-2023--0700)
|
||||
- [3.0.0](#300-thu-aug-24-133627-2023--0600)
|
||||
- [2.1.3](#213-fri-dec-8-163651-2023--0700)
|
||||
- [2.1.2](#212-wed-oct-18-165930-2023--0700)
|
||||
- [2.1.1](#211-sun-apr-23-154421-2023-0100)
|
||||
- [2.1.0](#210-thu-mar-16-211305-2023--0700)
|
||||
- [2.0.1](#201-fri-nov-4-103402-2022--0400)
|
||||
@@ -33,6 +37,436 @@ under the License.
|
||||
- [1.4.2](#142-sat-mar-19-000806-2022-0200)
|
||||
- [1.4.1](#141)
|
||||
|
||||
### 3.1.0 (Tue Jan 9 15:05:00 2023 -0800)
|
||||
|
||||
**Database Migrations**
|
||||
|
||||
- [#26160](https://github.com/apache/superset/pull/26160) fix: Migration order due to cherry which went astray (@john-bodley)
|
||||
- [#24776](https://github.com/apache/superset/pull/24776) chore(sqlalchemy): Remove erroneous SQLAlchemy ORM session.merge operations (@john-bodley)
|
||||
- [#25819](https://github.com/apache/superset/pull/25819) chore: Singularize tag models (@john-bodley)
|
||||
- [#25911](https://github.com/apache/superset/pull/25911) chore: remove deprecated functions in SQLAlchemy (@gnought)
|
||||
- [#25304](https://github.com/apache/superset/pull/25304) feat: Adds CLI commands to execute viz migrations (@michael-s-molina)
|
||||
- [#25204](https://github.com/apache/superset/pull/25204) feat(datasource): Checkbox for always filtering main dttm in datasource (@Always-prog)
|
||||
- [#24832](https://github.com/apache/superset/pull/24832) fix: Alembic migration head (@john-bodley)
|
||||
- [#24701](https://github.com/apache/superset/pull/24701) feat(Tags): Allow users to favorite Tags on CRUD Listview page (@hughhhh)
|
||||
- [#24755](https://github.com/apache/superset/pull/24755) feat: Add line width unit control in deckgl Polygon and Path (@kgabryje)
|
||||
- [#24700](https://github.com/apache/superset/pull/24700) chore: Update pylint to 2.17.4 (@EugeneTorap)
|
||||
|
||||
**Features**
|
||||
|
||||
- [#26031](https://github.com/apache/superset/pull/26031) feat(deckgl-map): use an arbitraty Mabpox style URL (#26027) (@francois-travais)
|
||||
- [#26136](https://github.com/apache/superset/pull/26136) feat: Adds legacy time support for Waterfall chart (@michael-s-molina)
|
||||
- [#26123](https://github.com/apache/superset/pull/26123) feat(helm): Add option to deploy extra containers to remaining deployments (@bluemalkin)
|
||||
- [#24714](https://github.com/apache/superset/pull/24714) feat: Add Apache Doris support (@liujiwen-up)
|
||||
- [#26033](https://github.com/apache/superset/pull/26033) feat: Add Bubble chart migration logic (@michael-s-molina)
|
||||
- [#25921](https://github.com/apache/superset/pull/25921) feat(metadb): handle decimals (@betodealmeida)
|
||||
- [#24539](https://github.com/apache/superset/pull/24539) feat(sqllab): non-blocking persistence mode (@justinpark)
|
||||
- [#25861](https://github.com/apache/superset/pull/25861) feat(sqllab): Show duration as separate column in Query History view (@sebastianliebscher)
|
||||
- [#25809](https://github.com/apache/superset/pull/25809) feat(sqllab): TRINO_EXPAND_ROWS: expand columns from ROWs (@giftig)
|
||||
- [#25952](https://github.com/apache/superset/pull/25952) feat: Add Area chart migration and tweaks the Timeseries chart migration (@michael-s-molina)
|
||||
- [#25950](https://github.com/apache/superset/pull/25950) feat(explore): dataset macro: dttm filter context (@giftig)
|
||||
- [#23973](https://github.com/apache/superset/pull/23973) feat: Adds Line chart migration logic (@michael-s-molina)
|
||||
- [#20323](https://github.com/apache/superset/pull/20323) feat: safer insert RLS (@betodealmeida)
|
||||
- [#25882](https://github.com/apache/superset/pull/25882) feat: method for dynamic `allows_alias_in_select` (@betodealmeida)
|
||||
- [#25855](https://github.com/apache/superset/pull/25855) feat(sqllab): Dynamic query limit dropdown (@giftig)
|
||||
- [#25344](https://github.com/apache/superset/pull/25344) feat(sqllab): Format sql (@justinpark)
|
||||
- [#25557](https://github.com/apache/superset/pull/25557) feat: Improves the Waterfall chart (@michael-s-molina)
|
||||
- [#23308](https://github.com/apache/superset/pull/23308) feat: support databend for superset (@hantmac)
|
||||
- [#25795](https://github.com/apache/superset/pull/25795) feat: support server-side sessions (@dpgaspar)
|
||||
- [#25783](https://github.com/apache/superset/pull/25783) feat(helm): Add option to deploy extra containers to init job (@bluemalkin)
|
||||
- [#25696](https://github.com/apache/superset/pull/25696) feat(Export as PDF - rasterized): Adding rasterized pdf functionality to dashboard (@fisjac)
|
||||
- [#25676](https://github.com/apache/superset/pull/25676) feat: add France's regions to country map visualization (@dmeaux)
|
||||
- [#25569](https://github.com/apache/superset/pull/25569) feat: add database and schema names to dataset option (@soniagtm)
|
||||
- [#25666](https://github.com/apache/superset/pull/25666) feat: Funnel/tooltip-customization (@CorbinBullard)
|
||||
- [#25683](https://github.com/apache/superset/pull/25683) feat: Add week time grain for Elasticsearch datasets (@mikelv92)
|
||||
- [#25423](https://github.com/apache/superset/pull/25423) feat(sqllab): ResultTable extension (@justinpark)
|
||||
- [#25542](https://github.com/apache/superset/pull/25542) feat(sqllab): Add keyboard shortcut helper (@justinpark)
|
||||
- [#25565](https://github.com/apache/superset/pull/25565) feat: migrate to docker compose v2 (@mdeshmu)
|
||||
- [#24154](https://github.com/apache/superset/pull/24154) feat: Add Deck.gl Contour Layer (@Mattc1221)
|
||||
- [#17906](https://github.com/apache/superset/pull/17906) feat(plugin-chart-echarts): Echarts Waterfall (@stephenLYZ)
|
||||
- [#22107](https://github.com/apache/superset/pull/22107) feat: Adds the ECharts Bubble chart (@mayurnewase)
|
||||
- [#25151](https://github.com/apache/superset/pull/25151) feat(sqllab): SPA migration (@justinpark)
|
||||
- [#25247](https://github.com/apache/superset/pull/25247) feat: Implement using Playwright for taking screenshots in reports (@kgabryje)
|
||||
- [#25303](https://github.com/apache/superset/pull/25303) feat: generic marshmallow error component (@betodealmeida)
|
||||
- [#25377](https://github.com/apache/superset/pull/25377) feat(docker): Use docker buildx and Add ARM builds for dockerize and websocket (@alekseyolg)
|
||||
- [#25343](https://github.com/apache/superset/pull/25343) feat: Adds Sunburst chart migration logic (@michael-s-molina)
|
||||
- [#25345](https://github.com/apache/superset/pull/25345) feat(sqllab): extra logging when chart is downloaded (@zephyring)
|
||||
- [#25280](https://github.com/apache/superset/pull/25280) feat(helm): Support HPA for supersetNode and supersetWorker (@tenkian4)
|
||||
- [#25309](https://github.com/apache/superset/pull/25309) feat(tag): fast follow for Tags flatten api + update client with generator + some bug fixes (@hughhhh)
|
||||
- [#24964](https://github.com/apache/superset/pull/24964) feat: Tags ListView Page (@hughhhh)
|
||||
- [#24787](https://github.com/apache/superset/pull/24787) feat(sqllab): Show sql in the current result (@justinpark)
|
||||
- [#25105](https://github.com/apache/superset/pull/25105) feat: removing renderCard from Tags/index.tsc to remove cardview from Tags ListView (@fisjac)
|
||||
- [#25089](https://github.com/apache/superset/pull/25089) feat(docker): refactor docker images (@alekseyolg)
|
||||
- [#24839](https://github.com/apache/superset/pull/24839) feat: Update Tags CRUD API (@hughhhh)
|
||||
- [#25065](https://github.com/apache/superset/pull/25065) feat: adding Scarf pixels to gather telemetry on readme and website (@rusackas)
|
||||
- [#14225](https://github.com/apache/superset/pull/14225) feat: a native SQLAlchemy dialect for Superset (@betodealmeida)
|
||||
- [#25001](https://github.com/apache/superset/pull/25001) feat: Moves Profile to Single Page App (SPA) (@michael-s-molina)
|
||||
- [#24983](https://github.com/apache/superset/pull/24983) feat(sqllab): Add /sqllab endpoint to the v1 api (@justinpark)
|
||||
- [#24918](https://github.com/apache/superset/pull/24918) feat: command to test DB engine specs (@betodealmeida)
|
||||
- [#24921](https://github.com/apache/superset/pull/24921) feat(gsheets): file upload (@betodealmeida)
|
||||
- [#24934](https://github.com/apache/superset/pull/24934) feat: add MotherDuck DB engine spec (@betodealmeida)
|
||||
- [#24909](https://github.com/apache/superset/pull/24909) feat: improve SQLite DB engine spec (@betodealmeida)
|
||||
- [#24870](https://github.com/apache/superset/pull/24870) feat(chart): Added Central Asia countries to countries map (@Zoynels)
|
||||
- [#24702](https://github.com/apache/superset/pull/24702) feat: add empty state for Tags (@hughhhh)
|
||||
- [#24768](https://github.com/apache/superset/pull/24768) feat: add pandas performance dependencies (@sebastianliebscher)
|
||||
- [#24618](https://github.com/apache/superset/pull/24618) feat(csv-upload): Configurable max filesize (@giftig)
|
||||
- [#24580](https://github.com/apache/superset/pull/24580) feat(database): Database Filtering via custom configuration (@Antonio-RiveroMartnez)
|
||||
|
||||
**Fixes**
|
||||
|
||||
- [#26429](https://github.com/apache/superset/pull/26429) fix(post-processing): handle missing values in cumulative operator (@villebro)
|
||||
- [#26424](https://github.com/apache/superset/pull/26424) fix(translations): Clear all (@capping)
|
||||
- [#26404](https://github.com/apache/superset/pull/26404) fix(plugin-chart-echarts): support forced categorical x-axis (@villebro)
|
||||
- [#26415](https://github.com/apache/superset/pull/26415) fix: In chart gallery thumbnail is rendered in case of no example in #16707 (@sivasathyaseeelan)
|
||||
- [#26393](https://github.com/apache/superset/pull/26393) fix(chart): Resolve incorrect column customization when switching metrics in table chart (@soniagtm)
|
||||
- [#26405](https://github.com/apache/superset/pull/26405) fix(sqllab): Bump duckdb-engine version to 0.9.5 (@guenp)
|
||||
- [#26313](https://github.com/apache/superset/pull/26313) fix(dashboard): narrow empty drop area (@justinpark)
|
||||
- [#26410](https://github.com/apache/superset/pull/26410) fix(dashboard): Chart menu disable is fixed on chart-fullscreen in issue #25992 (@sivasathyaseeelan)
|
||||
- [#26362](https://github.com/apache/superset/pull/26362) fix: Reactivates native filters E2E tests (@michael-s-molina)
|
||||
- [#26398](https://github.com/apache/superset/pull/26398) fix(embed): an error occurred while rendering the visualization: error: Item with key ... is not registered. (@rowdyroad)
|
||||
- [#26353](https://github.com/apache/superset/pull/26353) fix(SelectControl): select zero value (@rekilina)
|
||||
- [#26380](https://github.com/apache/superset/pull/26380) fix: Removes non-existent columns in the 2018 FCC Survey dataset (@michael-s-molina)
|
||||
- [#26302](https://github.com/apache/superset/pull/26302) fix: Invalid references in the basic template (@michael-s-molina)
|
||||
- [#26379](https://github.com/apache/superset/pull/26379) fix: Duplicated plugin registration (@michael-s-molina)
|
||||
- [#26378](https://github.com/apache/superset/pull/26378) fix(databend): databend time grain expression (@hantmac)
|
||||
- [#26151](https://github.com/apache/superset/pull/26151) fix(chart): Set max row limit + removed the option to use an empty row limit value (@CorbinBullard)
|
||||
- [#26312](https://github.com/apache/superset/pull/26312) fix(Embedded): Avoid creating a filter key for guest users (@Vitor-Avila)
|
||||
- [#26333](https://github.com/apache/superset/pull/26333) fix(logging): Add logging of change_dashboard_filter event for native dashboard filters (@john-bodley)
|
||||
- [#26326](https://github.com/apache/superset/pull/26326) fix(accessibility): Enable tabbing on sort header of table chart (@arunthirumani)
|
||||
- [#26324](https://github.com/apache/superset/pull/26324) fix(tagging): adding tags containing a “:” to dashboards (@lilykuang)
|
||||
- [#26340](https://github.com/apache/superset/pull/26340) fix(dashboard): Don't switch to first tab when directPathToChild changes (@kgabryje)
|
||||
- [#26283](https://github.com/apache/superset/pull/26283) fix(redshift): convert_dttm method for redshift dataset and tests (@gaurav7261)
|
||||
- [#26281](https://github.com/apache/superset/pull/26281) fix(sql lab): Use quote_schema instead of quote method to format schema name (@guenp)
|
||||
- [#25967](https://github.com/apache/superset/pull/25967) fix(typings): model_id is a multiple option (@gnought)
|
||||
- [#26284](https://github.com/apache/superset/pull/26284) fix: Revert "fix(sqllab): flaky json explore modal due to over-rendering (#26156)" (@justinpark)
|
||||
- [#26279](https://github.com/apache/superset/pull/26279) fix: Cannot expand initially hidden SQL Lab tab (@michael-s-molina)
|
||||
- [#26269](https://github.com/apache/superset/pull/26269) fix(plugin-chart-echarts): use scale for truncating x-axis (@villebro)
|
||||
- [#26264](https://github.com/apache/superset/pull/26264) fix: Stacked charts with numerical columns (@michael-s-molina)
|
||||
- [#26243](https://github.com/apache/superset/pull/26243) fix(plugin-chart-echarts): undefined bounds for bubble chart (@villebro)
|
||||
- [#26224](https://github.com/apache/superset/pull/26224) fix: Use page.locator in Playwright reports (@kgabryje)
|
||||
- [#26156](https://github.com/apache/superset/pull/26156) fix(sqllab): flaky json explore modal due to over-rendering (@justinpark)
|
||||
- [#25533](https://github.com/apache/superset/pull/25533) fix(menu): Styling active menu in SPA navigation (@justinpark)
|
||||
- [#25977](https://github.com/apache/superset/pull/25977) fix(sqllab): table preview has gone (@justinpark)
|
||||
- [#26066](https://github.com/apache/superset/pull/26066) fix: move driver import to method (@giftig)
|
||||
- [#25934](https://github.com/apache/superset/pull/25934) fix(tag): update state to clear form on success (@hughhhh)
|
||||
- [#25941](https://github.com/apache/superset/pull/25941) fix(sqllab): Allow router navigation to explore (@justinpark)
|
||||
- [#25875](https://github.com/apache/superset/pull/25875) fix(typo): replace 'datasouce_id' with 'datasource_id' in openapi.json (@nero5700)
|
||||
- [#25856](https://github.com/apache/superset/pull/25856) fix(tagging): change key from name to id for tagToSelectOption (@lilykuang)
|
||||
- [#25831](https://github.com/apache/superset/pull/25831) fix: add validation on tag name to have name + onDelete refresh list view (@hughhhh)
|
||||
- [#25851](https://github.com/apache/superset/pull/25851) fix: databend png pic (@hantmac)
|
||||
- [#25803](https://github.com/apache/superset/pull/25803) fix(helm): Fix init extra containers (@bluemalkin)
|
||||
- [#25739](https://github.com/apache/superset/pull/25739) fix(README): mismatched picture tags (@andy-clapson)
|
||||
- [#25727](https://github.com/apache/superset/pull/25727) fix(metadb): handle durations (@betodealmeida)
|
||||
- [#25718](https://github.com/apache/superset/pull/25718) fix(driver): bumping DuckDB to 0.9.2 (@rusackas)
|
||||
- [#25603](https://github.com/apache/superset/pull/25603) fix(tags): +n tags for listview (@hughhhh)
|
||||
- [#25578](https://github.com/apache/superset/pull/25578) fix(tags): Polish + Better messaging for skipped tags with bad permissions (@hughhhh)
|
||||
- [#25582](https://github.com/apache/superset/pull/25582) fix(sqllab): Allow opening of SQL Lab in new browser tab (@justinpark)
|
||||
- [#25615](https://github.com/apache/superset/pull/25615) fix(test-db): engine params (@betodealmeida)
|
||||
- [#25532](https://github.com/apache/superset/pull/25532) fix: Breaking change in MachineAuthProvider constructor (@kgabryje)
|
||||
- [#25547](https://github.com/apache/superset/pull/25547) fix: Make `host.docker.internal` available on linux (@sebastianliebscher)
|
||||
- [#25536](https://github.com/apache/superset/pull/25536) fix: Tags Page ListView size to 10 (@hughhhh)
|
||||
- [#25525](https://github.com/apache/superset/pull/25525) fix(test-db): removed attribute (@betodealmeida)
|
||||
- [#25473](https://github.com/apache/superset/pull/25473) fix(tags): Update loading + pagination for Tags Page (@hughhhh)
|
||||
- [#25470](https://github.com/apache/superset/pull/25470) fix(tags): fix clears delete on Tags Modal (@hughhhh)
|
||||
- [#25496](https://github.com/apache/superset/pull/25496) fix: Tags Polish II (@hughhhh)
|
||||
- [#24927](https://github.com/apache/superset/pull/24927) fix(Indian Map Changes): fixed-Indian-map-border (@Yaswanth-Perumalla)
|
||||
- [#25403](https://github.com/apache/superset/pull/25403) fix: Tags Page Polish (@hughhhh)
|
||||
- [#25306](https://github.com/apache/superset/pull/25306) fix(sqllab): misplaced limit warning alert (@justinpark)
|
||||
- [#25361](https://github.com/apache/superset/pull/25361) fix: update helm chart app version (@hugosjoberg)
|
||||
- [#25308](https://github.com/apache/superset/pull/25308) fix(sqllab): invalid persisted tab state (@justinpark)
|
||||
- [#25216](https://github.com/apache/superset/pull/25216) fix(docs): Fixing a typo in README.md (@yousoph)
|
||||
- [#25152](https://github.com/apache/superset/pull/25152) fix(sqllab): invalid reducer key name (@justinpark)
|
||||
- [#25124](https://github.com/apache/superset/pull/25124) fix: Partially reverts #25007 (@michael-s-molina)
|
||||
- [#25067](https://github.com/apache/superset/pull/25067) fix: small fixes for the meta DB (@betodealmeida)
|
||||
- [#24963](https://github.com/apache/superset/pull/24963) fix(gsheets): add column names on file upload (@betodealmeida)
|
||||
- [#24955](https://github.com/apache/superset/pull/24955) fix: timezone issue in Pandas 2 (@betodealmeida)
|
||||
- [#24952](https://github.com/apache/superset/pull/24952) fix: `to_datetime` in Pandas 2 (@betodealmeida)
|
||||
- [#24871](https://github.com/apache/superset/pull/24871) fix: Ignores hot update files when generating the manifest (@michael-s-molina)
|
||||
- [#24868](https://github.com/apache/superset/pull/24868) fix: Ignores ResizeObserver errors in development mode (@michael-s-molina)
|
||||
|
||||
**Others**
|
||||
|
||||
- [#25770](https://github.com/apache/superset/pull/25770) chore: Add example charts for deck.gl (@willie-hung)
|
||||
- [#26317](https://github.com/apache/superset/pull/26317) chore: Adds a tooltip for the alert's SQL input (@michael-s-molina)
|
||||
- [#26297](https://github.com/apache/superset/pull/26297) chore: Add downloadAsImage types, change filter selector (@kgabryje)
|
||||
- [#26315](https://github.com/apache/superset/pull/26315) chore: Use WEBDRIVER_OPTION_ARGS with Playwright (@kgabryje)
|
||||
- [#26310](https://github.com/apache/superset/pull/26310) chore: Disables minor ticks by default (@michael-s-molina)
|
||||
- [#26287](https://github.com/apache/superset/pull/26287) chore: update changelog for 2.1.3 (@eschutho)
|
||||
- [#26251](https://github.com/apache/superset/pull/26251) chore: improve CSP add base uri restriction (@dpgaspar)
|
||||
- [#26082](https://github.com/apache/superset/pull/26082) chore: lock the databend-sqlalchemy version (@hantmac)
|
||||
- [#26212](https://github.com/apache/superset/pull/26212) chore: Moves xAxisLabelRotation to shared controls (@michael-s-molina)
|
||||
- [#26188](https://github.com/apache/superset/pull/26188) chore: Lower giveup log level for retried functions to warning (@jfrag1)
|
||||
- [#25961](https://github.com/apache/superset/pull/25961) chore: harmonize and clean up list views (@villebro)
|
||||
- [#26147](https://github.com/apache/superset/pull/26147) chore: Rename SET_ACTIVE_TABS action, add a new action (@kgabryje)
|
||||
- [#25996](https://github.com/apache/superset/pull/25996) chore(tags): Allow for lookup via ids vs. name in the API (@hughhhh)
|
||||
- [#26058](https://github.com/apache/superset/pull/26058) chore: Adds the 3.1.0 Release Notes (@michael-s-molina)
|
||||
- [#26000](https://github.com/apache/superset/pull/26000) docs(databases): Update pinot.mdx to incorporate username and password based connection. (@raamri)
|
||||
- [#26075](https://github.com/apache/superset/pull/26075) chore: Adds 3.0.2 data to CHANGELOG.md (@michael-s-molina)
|
||||
- [#25850](https://github.com/apache/superset/pull/25850) chore(command): Organize Commands according to SIP-92 (@john-bodley)
|
||||
- [#26073](https://github.com/apache/superset/pull/26073) chore: Updates Announce template to include CHANGELOG.md and UPDATING.md files (@michael-s-molina)
|
||||
- [#26064](https://github.com/apache/superset/pull/26064) build(deps-dev): bump @types/node from 20.9.3 to 20.9.4 in /superset-websocket (@dependabot[bot])
|
||||
- [#26063](https://github.com/apache/superset/pull/26063) build(deps): bump @types/lodash from 4.14.201 to 4.14.202 in /superset-websocket (@dependabot[bot])
|
||||
- [#25844](https://github.com/apache/superset/pull/25844) chore: Allow only iterables for BaseDAO.delete() (@john-bodley)
|
||||
- [#25917](https://github.com/apache/superset/pull/25917) docs: update security policy and contributing (@dpgaspar)
|
||||
- [#24773](https://github.com/apache/superset/pull/24773) chore(connector): Cleanup base models and views according to SIP-92 (@john-bodley)
|
||||
- [#26039](https://github.com/apache/superset/pull/26039) docs(intro): fix a single broken link (BugHerd #97) (@sfirke)
|
||||
- [#26049](https://github.com/apache/superset/pull/26049) build(deps-dev): bump @types/node from 20.9.1 to 20.9.3 in /superset-websocket (@dependabot[bot])
|
||||
- [#26048](https://github.com/apache/superset/pull/26048) build(deps-dev): bump @types/ws from 8.5.9 to 8.5.10 in /superset-websocket (@dependabot[bot])
|
||||
- [#26043](https://github.com/apache/superset/pull/26043) chore: bump shillelagh (@betodealmeida)
|
||||
- [#26004](https://github.com/apache/superset/pull/26004) chore: Allow external extensions to include their own package.json files (@kgabryje)
|
||||
- [#26044](https://github.com/apache/superset/pull/26044) docs(BH#109): Athena URI spec fix (@rusackas)
|
||||
- [#26025](https://github.com/apache/superset/pull/26025) build(deps-dev): bump eslint from 8.53.0 to 8.54.0 in /superset-websocket (@dependabot[bot])
|
||||
- [#26013](https://github.com/apache/superset/pull/26013) chore: cleanup unused code in pandas 2.0+ (@gnought)
|
||||
- [#26012](https://github.com/apache/superset/pull/26012) build(deps-dev): bump @types/node from 20.9.0 to 20.9.1 in /superset-websocket (@dependabot[bot])
|
||||
- [#26009](https://github.com/apache/superset/pull/26009) chore: Remove unnecessary autoflush from tagging and key/value workflows (@john-bodley)
|
||||
- [#25551](https://github.com/apache/superset/pull/25551) docs: handling "System limit for number of file watchers reached" error (@nitish-samsung-jha)
|
||||
- [#25986](https://github.com/apache/superset/pull/25986) chore: Remove more redundant code in utils/core (@sebastianliebscher)
|
||||
- [#24485](https://github.com/apache/superset/pull/24485) style: Transition of Navbar from dark to light and vice-versa is now smooth (@git-init-priyanshu)
|
||||
- [#25059](https://github.com/apache/superset/pull/25059) docs: add Tentacle to users list (@jdclarke5)
|
||||
- [#25968](https://github.com/apache/superset/pull/25968) chore: Add entry point for SliceHeader frontend extension (@kgabryje)
|
||||
- [#25891](https://github.com/apache/superset/pull/25891) chore: support different JWT CSRF cookie names (@dpgaspar)
|
||||
- [#25953](https://github.com/apache/superset/pull/25953) build(deps-dev): bump axios from 0.25.0 to 1.6.0 in /superset-embedded-sdk (@dependabot[bot])
|
||||
- [#25927](https://github.com/apache/superset/pull/25927) build(deps-dev): bump @types/jsonwebtoken from 9.0.4 to 9.0.5 in /superset-websocket (@dependabot[bot])
|
||||
- [#25929](https://github.com/apache/superset/pull/25929) build(deps-dev): bump @types/uuid from 9.0.6 to 9.0.7 in /superset-websocket (@dependabot[bot])
|
||||
- [#25958](https://github.com/apache/superset/pull/25958) test: Reduce flaky integration tests triggered by `test_get_tag` (@sebastianliebscher)
|
||||
- [#25948](https://github.com/apache/superset/pull/25948) chore: Simplify views/base (@sebastianliebscher)
|
||||
- [#25951](https://github.com/apache/superset/pull/25951) build(deps): bump axios from 1.4.0 to 1.6.1 in /superset-frontend (@dependabot[bot])
|
||||
- [#25881](https://github.com/apache/superset/pull/25881) chore(issue template): attempting to fix two entries/links (@rusackas)
|
||||
- [#25926](https://github.com/apache/superset/pull/25926) chore: removing unused chartMetadata field (@rusackas)
|
||||
- [#25928](https://github.com/apache/superset/pull/25928) build(deps-dev): bump @types/node from 20.8.10 to 20.9.0 in /superset-websocket (@dependabot[bot])
|
||||
- [#25885](https://github.com/apache/superset/pull/25885) docs: Remove Python 3.8 from CONTRIBUTING.md (@koushik-rout-samsung)
|
||||
- [#25900](https://github.com/apache/superset/pull/25900) chore: Simplify utils/cache by using default argument values (@sebastianliebscher)
|
||||
- [#25912](https://github.com/apache/superset/pull/25912) chore: remove unused functions in utils/core (@sebastianliebscher)
|
||||
- [#25907](https://github.com/apache/superset/pull/25907) build(deps): bump @types/lodash from 4.14.200 to 4.14.201 in /superset-websocket (@dependabot[bot])
|
||||
- [#25906](https://github.com/apache/superset/pull/25906) build(deps-dev): bump @types/ws from 8.5.7 to 8.5.9 in /superset-websocket (@dependabot[bot])
|
||||
- [#25905](https://github.com/apache/superset/pull/25905) build(deps-dev): bump @types/cookie from 0.5.3 to 0.5.4 in /superset-websocket (@dependabot[bot])
|
||||
- [#25262](https://github.com/apache/superset/pull/25262) chore: add more migration tests (@eschutho)
|
||||
- [#25886](https://github.com/apache/superset/pull/25886) build(deps): bump cookie from 0.5.0 to 0.6.0 in /superset-websocket (@dependabot[bot])
|
||||
- [#25714](https://github.com/apache/superset/pull/25714) chore: Update INTHEWILD.md (@codek)
|
||||
- [#25867](https://github.com/apache/superset/pull/25867) build(deps-dev): bump eslint from 8.52.0 to 8.53.0 in /superset-websocket (@dependabot[bot])
|
||||
- [#25852](https://github.com/apache/superset/pull/25852) chore: Updates Databend image extension reference in README.md (@michael-s-molina)
|
||||
- [#25531](https://github.com/apache/superset/pull/25531) docs: Update location of `async_query_manager.py` (@emmanuel-ferdman)
|
||||
- [#25817](https://github.com/apache/superset/pull/25817) chore(docker-compose): more host network specifiers (@giftig)
|
||||
- [#25812](https://github.com/apache/superset/pull/25812) chore: Removes border of the color picker control (@michael-s-molina)
|
||||
- [#25826](https://github.com/apache/superset/pull/25826) chore(websocket): Adding support for redis username in websocket server (@craig-rueda)
|
||||
- [#25822](https://github.com/apache/superset/pull/25822) chore: Update sip.md to have a better call to action (@rusackas)
|
||||
- [#25823](https://github.com/apache/superset/pull/25823) chore(issues): config.yaml added with feature request link to open a discussion (@rusackas)
|
||||
- [#25816](https://github.com/apache/superset/pull/25816) build(deps-dev): bump @types/node from 20.8.7 to 20.8.10 in /superset-websocket (@dependabot[bot])
|
||||
- [#25530](https://github.com/apache/superset/pull/25530) docs: Add Cyberhaven to Users list (@ghost)
|
||||
- [#25314](https://github.com/apache/superset/pull/25314) chore(celery): Cleanup config and async query specifications (@john-bodley)
|
||||
- [#25778](https://github.com/apache/superset/pull/25778) build(deps): bump browserify-sign from 4.2.1 to 4.2.2 in /superset-frontend (@dependabot[bot])
|
||||
- [#24046](https://github.com/apache/superset/pull/24046) chore(security): Make get_database_perm/get_dataset_perm return optional (@john-bodley)
|
||||
- [#25765](https://github.com/apache/superset/pull/25765) chore: Add config options for Playwright wait_until and default timeout (@kgabryje)
|
||||
- [#25721](https://github.com/apache/superset/pull/25721) style(readme): reformatted (@bipinct)
|
||||
- [#25737](https://github.com/apache/superset/pull/25737) chore: bump pymssql version (@gnought)
|
||||
- [#25521](https://github.com/apache/superset/pull/25521) chore(websocket): [WIP] Making JWT algos configurable (@craig-rueda)
|
||||
- [#25735](https://github.com/apache/superset/pull/25735) build(deps-dev): bump eslint from 8.51.0 to 8.52.0 in /superset-websocket (@dependabot[bot])
|
||||
- [#25726](https://github.com/apache/superset/pull/25726) chore: updated base DAO find_by_id to return generic type (@zephyring)
|
||||
- [#25717](https://github.com/apache/superset/pull/25717) refactor: use DATE_TRUNC for Elasticsearch time grain (@mikelv92)
|
||||
- [#25709](https://github.com/apache/superset/pull/25709) chore: helm chart: bump appVersion to 3.0.1 (@mdavidsen)
|
||||
- [#25577](https://github.com/apache/superset/pull/25577) chore: Change the format for sha512 sum for releases (@sebastianliebscher)
|
||||
- [#25689](https://github.com/apache/superset/pull/25689) build(deps-dev): bump @types/cookie from 0.5.1 to 0.5.3 in /superset-websocket (@dependabot[bot])
|
||||
- [#25701](https://github.com/apache/superset/pull/25701) build(deps-dev): bump @types/uuid from 9.0.4 to 9.0.6 in /superset-websocket (@dependabot[bot])
|
||||
- [#25710](https://github.com/apache/superset/pull/25710) docs(README): Fix typo (@RahulK4102)
|
||||
- [#25700](https://github.com/apache/superset/pull/25700) build(deps-dev): bump @types/node from 20.8.6 to 20.8.7 in /superset-websocket (@dependabot[bot])
|
||||
- [#25322](https://github.com/apache/superset/pull/25322) chore: add latest docker tag (@eschutho)
|
||||
- [#25691](https://github.com/apache/superset/pull/25691) chore: Adds 3.0.1 data to CHANGELOG.md (@michael-s-molina)
|
||||
- [#25688](https://github.com/apache/superset/pull/25688) build(deps-dev): bump @types/jsonwebtoken from 9.0.3 to 9.0.4 in /superset-websocket (@dependabot[bot])
|
||||
- [#25543](https://github.com/apache/superset/pull/25543) chore: Cleanup hostNamesConfig.js (@john-bodley)
|
||||
- [#25654](https://github.com/apache/superset/pull/25654) docs: make project-specific security page more prominent (@raboof)
|
||||
- [#25667](https://github.com/apache/superset/pull/25667) chore: sync lock files (@villebro)
|
||||
- [#25661](https://github.com/apache/superset/pull/25661) build(deps-dev): bump @babel/traverse from 7.16.0 to 7.23.2 in /superset-websocket (@dependabot[bot])
|
||||
- [#25653](https://github.com/apache/superset/pull/25653) build(deps-dev): bump @types/node from 20.8.5 to 20.8.6 in /superset-websocket (@dependabot[bot])
|
||||
- [#25645](https://github.com/apache/superset/pull/25645) chore: bump pip-tools (@villebro)
|
||||
- [#25537](https://github.com/apache/superset/pull/25537) docs: invert logo color for dark theme in README (@Sea-n)
|
||||
- [#25629](https://github.com/apache/superset/pull/25629) chore: adding resource links to readme (@rusackas)
|
||||
- [#25638](https://github.com/apache/superset/pull/25638) build(ci): Provide diff for pre-commit failures (@jsoref)
|
||||
- [#25632](https://github.com/apache/superset/pull/25632) build(deps-dev): bump @types/node from 20.8.4 to 20.8.5 in /superset-websocket (@dependabot[bot])
|
||||
- [#25455](https://github.com/apache/superset/pull/25455) chore(helm): spelling: initialize (@jsoref)
|
||||
- [#25567](https://github.com/apache/superset/pull/25567) docs: BugHerd Tasks 88, 89, 90, 91 (@mdeshmu)
|
||||
- [#25602](https://github.com/apache/superset/pull/25602) chore(feature?): Bump `scarf-js` to 1.3.0 to get more telemetry data (@rusackas)
|
||||
- [#25502](https://github.com/apache/superset/pull/25502) build(deps): bump postcss from 8.3.11 to 8.4.31 in /docs (@dependabot[bot])
|
||||
- [#19056](https://github.com/apache/superset/pull/19056) docs: Add timezone information (@john-bodley)
|
||||
- [#25340](https://github.com/apache/superset/pull/25340) refactor: Issue #25040; Refactored sync_role_definition function in order to reduce number of query. (@suicide11)
|
||||
- [#25606](https://github.com/apache/superset/pull/25606) build(deps-dev): bump @types/ws from 8.5.6 to 8.5.7 in /superset-websocket (@dependabot[bot])
|
||||
- [#25585](https://github.com/apache/superset/pull/25585) build(deps): bump winston from 3.10.0 to 3.11.0 in /superset-websocket (@dependabot[bot])
|
||||
- [#25584](https://github.com/apache/superset/pull/25584) build(deps-dev): bump @types/node from 20.8.2 to 20.8.4 in /superset-websocket (@dependabot[bot])
|
||||
- [#25566](https://github.com/apache/superset/pull/25566) chore: Update pylint to 2.17.7 (@EugeneTorap)
|
||||
- [#25574](https://github.com/apache/superset/pull/25574) build(deps-dev): bump eslint from 8.49.0 to 8.51.0 in /superset-websocket (@dependabot[bot])
|
||||
- [#25228](https://github.com/apache/superset/pull/25228) chore(sqllab): Typescript for SqlEditor component (@justinpark)
|
||||
- [#25507](https://github.com/apache/superset/pull/25507) chore(tags): don't allow users to create new tags from property dropdowns (@hughhhh)
|
||||
- [#25504](https://github.com/apache/superset/pull/25504) chore(tags): move tags column in dashboard and chart list (@lilykuang)
|
||||
- [#24481](https://github.com/apache/superset/pull/24481) docs: fix for domain sharding results in failed requests with "Missing Authorization Header" (@ved-kashyap-samsung)
|
||||
- [#25508](https://github.com/apache/superset/pull/25508) build(deps): bump ws and @types/ws in /superset-websocket (@dependabot[bot])
|
||||
- [#25498](https://github.com/apache/superset/pull/25498) build(deps-dev): bump @types/node from 20.6.0 to 20.8.2 in /superset-websocket (@dependabot[bot])
|
||||
- [#25480](https://github.com/apache/superset/pull/25480) docs: define localhost for docker (@mdeshmu)
|
||||
- [#25479](https://github.com/apache/superset/pull/25479) docs: update docker compose instructions (@mdeshmu)
|
||||
- [#25482](https://github.com/apache/superset/pull/25482) docs: add a FAQ about asset recovery from UI (@mdeshmu)
|
||||
- [#25477](https://github.com/apache/superset/pull/25477) docs: add https & ldap instructions (@mdeshmu)
|
||||
- [#25466](https://github.com/apache/superset/pull/25466) chore(async): Initial Refactoring of Global Async Queries (@craig-rueda)
|
||||
- [#25120](https://github.com/apache/superset/pull/25120) build(deps-dev): bump prettier from 3.0.2 to 3.0.3 in /superset-websocket (@dependabot[bot])
|
||||
- [#25325](https://github.com/apache/superset/pull/25325) build(deps-dev): bump @types/jsonwebtoken from 9.0.2 to 9.0.3 in /superset-websocket (@dependabot[bot])
|
||||
- [#25435](https://github.com/apache/superset/pull/25435) docs(FAQ): remove reference to filter box, add Q&A re: usage analytics (@sfirke)
|
||||
- [#25438](https://github.com/apache/superset/pull/25438) chore: Update Explore tooltip copy (@yousoph)
|
||||
- [#25465](https://github.com/apache/superset/pull/25465) chore(misc): Typos in config.py (@JZ6)
|
||||
- [#25457](https://github.com/apache/superset/pull/25457) chore(backend): Spelling (@jsoref)
|
||||
- [#25456](https://github.com/apache/superset/pull/25456) chore(misc): Spelling (@jsoref)
|
||||
- [#25453](https://github.com/apache/superset/pull/25453) chore(docs): Spelling (@jsoref)
|
||||
- [#25441](https://github.com/apache/superset/pull/25441) build(deps): bump get-func-name from 2.0.0 to 2.0.2 in /superset-frontend/cypress-base (@dependabot[bot])
|
||||
- [#25276](https://github.com/apache/superset/pull/25276) chore: cryptography version bump (@lilykuang)
|
||||
- [#25332](https://github.com/apache/superset/pull/25332) docs: update docker-compose (@nytai)
|
||||
- [#25362](https://github.com/apache/superset/pull/25362) chore: upgrade node to most recent 16.x (@villebro)
|
||||
- [#25360](https://github.com/apache/superset/pull/25360) chore: Adds 3.0 data to CHANGELOG and UPDATING (@michael-s-molina)
|
||||
- [#25346](https://github.com/apache/superset/pull/25346) chore(async): Making create app configurable (@craig-rueda)
|
||||
- [#24928](https://github.com/apache/superset/pull/24928) docs: jwks_uri addition to OAUTH provider (@kravi21)
|
||||
- [#25312](https://github.com/apache/superset/pull/25312) docs: add snowflake-sqlalchemy in ./docker/requirements-local.txt (@janhavitripurwar)
|
||||
- [#25324](https://github.com/apache/superset/pull/25324) docs: add ReadyTech to INTHEWILD.md (@jbat)
|
||||
- [#25313](https://github.com/apache/superset/pull/25313) chore: bump gunicorn to v21 (@villebro)
|
||||
- [#25311](https://github.com/apache/superset/pull/25311) build(deps-dev): bump @types/uuid from 9.0.3 to 9.0.4 in /superset-websocket (@dependabot[bot])
|
||||
- [#25274](https://github.com/apache/superset/pull/25274) chore(sqllab): Migrate tests to typescript (@justinpark)
|
||||
- [#25291](https://github.com/apache/superset/pull/25291) chore: changing one word (disablement -> disabling) (@rusackas)
|
||||
- [#25287](https://github.com/apache/superset/pull/25287) build(docker): bump geckodriver and firefox to latest (@alekseyolg)
|
||||
- [#25293](https://github.com/apache/superset/pull/25293) build(deps): bump ws from 8.13.0 to 8.14.1 in /superset-websocket (@dependabot[bot])
|
||||
- [#25296](https://github.com/apache/superset/pull/25296) docs: rewrite superset docker localhost prose (@jsoref)
|
||||
- [#25279](https://github.com/apache/superset/pull/25279) build(deps): bump uuid from 9.0.0 to 9.0.1 in /superset-websocket (@dependabot[bot])
|
||||
- [#25263](https://github.com/apache/superset/pull/25263) build(deps-dev): bump eslint from 8.48.0 to 8.49.0 in /superset-websocket (@dependabot[bot])
|
||||
- [#25253](https://github.com/apache/superset/pull/25253) build(deps-dev): bump @types/node from 20.5.7 to 20.6.0 in /superset-websocket (@dependabot[bot])
|
||||
- [#20631](https://github.com/apache/superset/pull/20631) refactor: Remove obsolete HiveEngineSpec.fetch_logs method (@john-bodley)
|
||||
- [#25226](https://github.com/apache/superset/pull/25226) chore(read_csv): remove deprecated argument (@betodealmeida)
|
||||
- [#25177](https://github.com/apache/superset/pull/25177) chore: Convert deckgl class components to functional (@kgabryje)
|
||||
- [#24992](https://github.com/apache/superset/pull/24992) docs(FAQ): add answer re: necessary specs, copy-edit existing answer (@sfirke)
|
||||
- [#25165](https://github.com/apache/superset/pull/25165) chore: back port 2.1.1 doc changes (@eschutho)
|
||||
- [#25206](https://github.com/apache/superset/pull/25206) docs: add CVEs for 2.1.1 (@dpgaspar)
|
||||
- [#25200](https://github.com/apache/superset/pull/25200) docs: fix wrong type in PREFERRED_DATABASES example (@cmontemuino)
|
||||
- [#25160](https://github.com/apache/superset/pull/25160) chore: fix broken link to Celery worker docs (@wAVeckx)
|
||||
- [#25142](https://github.com/apache/superset/pull/25142) build(deps-dev): bump @types/uuid from 9.0.2 to 9.0.3 in /superset-websocket (@dependabot[bot])
|
||||
- [#25141](https://github.com/apache/superset/pull/25141) build(deps): bump jsonwebtoken from 9.0.1 to 9.0.2 in /superset-websocket (@dependabot[bot])
|
||||
- [#25140](https://github.com/apache/superset/pull/25140) build(deps): bump jsonwebtoken from 9.0.1 to 9.0.2 in /superset-websocket/utils/client-ws-app (@dependabot[bot])
|
||||
- [#25088](https://github.com/apache/superset/pull/25088) chore: consolidate sqllab store into SPA store (@justinpark)
|
||||
- [#25121](https://github.com/apache/superset/pull/25121) chore: move TypedDict from typing_extensions to typing (@sebastianliebscher)
|
||||
- [#24896](https://github.com/apache/superset/pull/24896) chore: use contextlib.surpress instead of passing on error (@sebastianliebscher)
|
||||
- [#25098](https://github.com/apache/superset/pull/25098) build(deps-dev): bump eslint from 8.47.0 to 8.48.0 in /superset-websocket (@dependabot[bot])
|
||||
- [#25097](https://github.com/apache/superset/pull/25097) build(deps-dev): bump @types/node from 20.5.6 to 20.5.7 in /superset-websocket (@dependabot[bot])
|
||||
- [#24933](https://github.com/apache/superset/pull/24933) chore: Refactor deck.gl plugins to Typescript (@kgabryje)
|
||||
- [#24980](https://github.com/apache/superset/pull/24980) chore: Update docs for docker-compose installation (@hughhhh)
|
||||
- [#24771](https://github.com/apache/superset/pull/24771) docs(docker-compose): add missing parenthesis (@sfirke)
|
||||
- [#25082](https://github.com/apache/superset/pull/25082) build(deps-dev): bump @types/node from 20.5.1 to 20.5.6 in /superset-websocket (@dependabot[bot])
|
||||
- [#25080](https://github.com/apache/superset/pull/25080) chore(reports): add metrics to report schedule and log prune (@villebro)
|
||||
- [#25047](https://github.com/apache/superset/pull/25047) chore(sqllab): typescript for getInitialState (@justinpark)
|
||||
- [#25030](https://github.com/apache/superset/pull/25030) build(deps): Bump PyHive (@mdeshmu)
|
||||
- [#24872](https://github.com/apache/superset/pull/24872) test(cypress): Fail Cypress on Console errors (@rusackas)
|
||||
- [#25046](https://github.com/apache/superset/pull/25046) chore: Organizes the files of the ReportModal feature (@michael-s-molina)
|
||||
- [#25045](https://github.com/apache/superset/pull/25045) chore(tests): Adding missing **init**.py files to various test packages (@craig-rueda)
|
||||
- [#25038](https://github.com/apache/superset/pull/25038) build(deps-dev): bump @types/node from 20.5.0 to 20.5.1 in /superset-websocket (@dependabot[bot])
|
||||
- [#25010](https://github.com/apache/superset/pull/25010) chore(sqllab): Relocate user in SqlLab to root (@justinpark)
|
||||
- [#25034](https://github.com/apache/superset/pull/25034) docs: fix line break in Apache Druid page (@giuliotal)
|
||||
- [#24994](https://github.com/apache/superset/pull/24994) chore: rename `get_iterable` (@betodealmeida)
|
||||
- [#25007](https://github.com/apache/superset/pull/25007) chore: Removes Saved Query old code (@michael-s-molina)
|
||||
- [#24894](https://github.com/apache/superset/pull/24894) chore: Update DAOs to use singular deletion method instead of bulk (@jfrag1)
|
||||
- [#25005](https://github.com/apache/superset/pull/25005) chore: Removes src/modules top folder (@michael-s-molina)
|
||||
- [#24998](https://github.com/apache/superset/pull/24998) build(deps-dev): bump prettier from 3.0.1 to 3.0.2 in /superset-websocket (@dependabot[bot])
|
||||
- [#24941](https://github.com/apache/superset/pull/24941) chore(dashboard import/export): include additional fields to export/import commands (@Vitor-Avila)
|
||||
- [#24967](https://github.com/apache/superset/pull/24967) chore(dao): Remove redundant convenience methods (@john-bodley)
|
||||
- [#24973](https://github.com/apache/superset/pull/24973) build(deps-dev): bump @types/node from 20.4.9 to 20.5.0 in /superset-websocket (@dependabot[bot])
|
||||
- [#24972](https://github.com/apache/superset/pull/24972) build(deps-dev): bump eslint from 8.46.0 to 8.47.0 in /superset-websocket (@dependabot[bot])
|
||||
- [#24936](https://github.com/apache/superset/pull/24936) chore(sqllab): Relocate get bootstrap data logic (@justinpark)
|
||||
- [#24467](https://github.com/apache/superset/pull/24467) chore(dao): Replace save/overwrite with create/update respectively (@john-bodley)
|
||||
- [#24962](https://github.com/apache/superset/pull/24962) docs: Add wattbewerb to users list (@hbruch)
|
||||
- [#24961](https://github.com/apache/superset/pull/24961) chore: Add Automattic to the list of users and contributors (@Khrol)
|
||||
- [#24958](https://github.com/apache/superset/pull/24958) build(deps): bump tough-cookie and @cypress/request in /superset-frontend/cypress-base (@dependabot[bot])
|
||||
- [#24920](https://github.com/apache/superset/pull/24920) docs: Fixing Superset typo in docker-compose local installation guide (@TannerBarcelos)
|
||||
- [#24924](https://github.com/apache/superset/pull/24924) build(deps-dev): bump @types/node from 20.4.8 to 20.4.9 in /superset-websocket (@dependabot[bot])
|
||||
- [#24915](https://github.com/apache/superset/pull/24915) docs: fix tip box in "Installing From Scratch" page (@giuliotal)
|
||||
- [#24878](https://github.com/apache/superset/pull/24878) build(deps-dev): bump prettier from 2.8.8 to 3.0.1 in /superset-websocket (@dependabot[bot])
|
||||
- [#24900](https://github.com/apache/superset/pull/24900) build(deps-dev): bump eslint-config-prettier from 8.10.0 to 9.0.0 in /superset-websocket (@dependabot[bot])
|
||||
- [#24901](https://github.com/apache/superset/pull/24901) build(deps-dev): bump @types/node from 20.4.7 to 20.4.8 in /superset-websocket (@dependabot[bot])
|
||||
- [#24888](https://github.com/apache/superset/pull/24888) build(deps-dev): bump @types/node from 20.4.6 to 20.4.7 in /superset-websocket (@dependabot[bot])
|
||||
- [#24880](https://github.com/apache/superset/pull/24880) build(deps-dev): bump @types/node from 20.4.5 to 20.4.6 in /superset-websocket (@dependabot[bot])
|
||||
- [#24879](https://github.com/apache/superset/pull/24879) build(deps-dev): bump eslint-config-prettier from 8.8.0 to 8.10.0 in /superset-websocket (@dependabot[bot])
|
||||
- [#24873](https://github.com/apache/superset/pull/24873) docs(native-filters): Remove outdated statement (@john-bodley)
|
||||
- [#24657](https://github.com/apache/superset/pull/24657) chore: Bump cryptography (@suryadev99)
|
||||
- [#24842](https://github.com/apache/superset/pull/24842) build(deps-dev): bump eslint from 8.45.0 to 8.46.0 in /superset-websocket (@dependabot[bot])
|
||||
- [#24838](https://github.com/apache/superset/pull/24838) chore(api): clean up API spec (@sebastianliebscher)
|
||||
- [#24834](https://github.com/apache/superset/pull/24834) docs(Kubernetes): Fix typos, clarify language re: Scarf (@sfirke)
|
||||
- [#24819](https://github.com/apache/superset/pull/24819) chore: remove get_columns_description duplication (@betodealmeida)
|
||||
- [#24817](https://github.com/apache/superset/pull/24817) docs: Adding a couple links to contributing page (@rusackas)
|
||||
- [#24820](https://github.com/apache/superset/pull/24820) docs: fixing stack overflow link (@rusackas)
|
||||
- [#24809](https://github.com/apache/superset/pull/24809) build(deps-dev): bump @types/node from 20.4.4 to 20.4.5 in /superset-websocket (@dependabot[bot])
|
||||
- [#19959](https://github.com/apache/superset/pull/19959) docs(K8s): Add instructions for loading the examples (@charris-msft)
|
||||
- [#24147](https://github.com/apache/superset/pull/24147) chore: bump postgresql in docker-compose and github workflows (@sebastianliebscher)
|
||||
- [#24779](https://github.com/apache/superset/pull/24779) build(deps-dev): bump @types/node from 20.4.2 to 20.4.4 in /superset-websocket (@dependabot[bot])
|
||||
- [#24751](https://github.com/apache/superset/pull/24751) docs: update AWS Athena and Redshift docs (@mdeshmu)
|
||||
- [#24461](https://github.com/apache/superset/pull/24461) docs(docker-compose): note the risk of running a Docker Postgres volume in production (@sfirke)
|
||||
- [#24705](https://github.com/apache/superset/pull/24705) chore(deps): bump pandas >=2.0 (@sebastianliebscher)
|
||||
- [#24732](https://github.com/apache/superset/pull/24732) build(deps-dev): bump word-wrap from 1.2.3 to 1.2.4 in /superset-websocket (@dependabot[bot])
|
||||
- [#24715](https://github.com/apache/superset/pull/24715) chore: update deprecated arguments in schema (@sebastianliebscher)
|
||||
- [#24733](https://github.com/apache/superset/pull/24733) build(deps): bump word-wrap from 1.2.3 to 1.2.4 in /superset-frontend/cypress-base (@dependabot[bot])
|
||||
- [#24735](https://github.com/apache/superset/pull/24735) build(deps-dev): bump word-wrap from 1.2.3 to 1.2.4 in /superset-frontend (@dependabot[bot])
|
||||
- [#24734](https://github.com/apache/superset/pull/24734) build(deps-dev): bump word-wrap from 1.2.3 to 1.2.4 in /superset-embedded-sdk (@dependabot[bot])
|
||||
- [#24712](https://github.com/apache/superset/pull/24712) build(deps-dev): bump eslint from 8.44.0 to 8.45.0 in /superset-websocket (@dependabot[bot])
|
||||
- [#24669](https://github.com/apache/superset/pull/24669) chore: remove obsolete fetchExploreJson function (@john-bodley)
|
||||
- [#24682](https://github.com/apache/superset/pull/24682) build(deps-dev): bump @types/node from 20.4.1 to 20.4.2 in /superset-websocket (@dependabot[bot])
|
||||
- [#24674](https://github.com/apache/superset/pull/24674) docs: Fix typo in Rockset docs (@gadhagod)
|
||||
- [#24672](https://github.com/apache/superset/pull/24672) build(deps-dev): bump @types/node from 20.4.0 to 20.4.1 in /superset-websocket (@dependabot[bot])
|
||||
- [#24673](https://github.com/apache/superset/pull/24673) build(deps-dev): bump @typescript-eslint/parser from 5.61.0 to 5.62.0 in /superset-websocket (@dependabot[bot])
|
||||
- [#24649](https://github.com/apache/superset/pull/24649) chore: Update Rockset—switching out rockset for rockset-sqlalchemy (@gadhagod)
|
||||
- [#24653](https://github.com/apache/superset/pull/24653) build(deps): bump semver from 5.7.1 to 5.7.2 in /superset-frontend (@dependabot[bot])
|
||||
- [#24654](https://github.com/apache/superset/pull/24654) build(deps): bump semver from 6.3.0 to 6.3.1 in /superset-websocket (@dependabot[bot])
|
||||
- [#24655](https://github.com/apache/superset/pull/24655) build(deps): bump semver from 6.3.0 to 6.3.1 in /superset-frontend/cypress-base (@dependabot[bot])
|
||||
- [#24656](https://github.com/apache/superset/pull/24656) build(deps): bump trim and @superset-ui/core in /superset-frontend/cypress-base (@dependabot[bot])
|
||||
- [#24659](https://github.com/apache/superset/pull/24659) build(deps): bump winston from 3.9.0 to 3.10.0 in /superset-websocket (@dependabot[bot])
|
||||
- [#24626](https://github.com/apache/superset/pull/24626) chore: Re-enable some GitHub action workflows in draft mode (@john-bodley)
|
||||
- [#24633](https://github.com/apache/superset/pull/24633) docs(databases): correct the way of using use environment variables (@duyet)
|
||||
- [#24648](https://github.com/apache/superset/pull/24648) chore: update UI dev libs and fix warnings & vulnerabilities (@EugeneTorap)
|
||||
- [#24651](https://github.com/apache/superset/pull/24651) build(deps): bump semver from 5.7.1 to 5.7.2 in /docs (@dependabot[bot])
|
||||
- [#24634](https://github.com/apache/superset/pull/24634) build(deps): bump tough-cookie from 4.0.0 to 4.1.3 in /superset-embedded-sdk (@dependabot[bot])
|
||||
- [#24614](https://github.com/apache/superset/pull/24614) build(deps): bump jsonwebtoken from 9.0.0 to 9.0.1 in /superset-websocket (@dependabot[bot])
|
||||
- [#23987](https://github.com/apache/superset/pull/23987) docs(frontend): Fixed typo in command (@ved-kashyap-samsung)
|
||||
- [#23992](https://github.com/apache/superset/pull/23992) docs: correct databricks pip package name (@devonkinghorn)
|
||||
- [#24632](https://github.com/apache/superset/pull/24632) build(deps): bump tough-cookie from 4.0.0 to 4.1.3 in /superset-websocket (@dependabot[bot])
|
||||
- [#24585](https://github.com/apache/superset/pull/24585) build(deps-dev): bump @typescript-eslint/eslint-plugin from 5.60.1 to 5.61.0 in /superset-websocket (@dependabot[bot])
|
||||
- [#24576](https://github.com/apache/superset/pull/24576) build(deps-dev): bump eslint from 8.43.0 to 8.44.0 in /superset-websocket (@dependabot[bot])
|
||||
- [#24601](https://github.com/apache/superset/pull/24601) build(deps-dev): bump @types/node from 20.3.2 to 20.4.0 in /superset-websocket (@dependabot[bot])
|
||||
- [#24584](https://github.com/apache/superset/pull/24584) build(deps-dev): bump @typescript-eslint/parser from 5.60.1 to 5.61.0 in /superset-websocket (@dependabot[bot])
|
||||
- [#24600](https://github.com/apache/superset/pull/24600) build(deps): bump jsonwebtoken from 9.0.0 to 9.0.1 in /superset-websocket/utils/client-ws-app (@dependabot[bot])
|
||||
- [#24570](https://github.com/apache/superset/pull/24570) docs(helm): reference the correct chart (@muniter)
|
||||
- [#24564](https://github.com/apache/superset/pull/24564) docs: add notice not to use gevent worker with bigquery datasource (@okayhooni)
|
||||
- [#24578](https://github.com/apache/superset/pull/24578) refactor: pkg_resources -> importlib.resources (@cwegener)
|
||||
- [#24523](https://github.com/apache/superset/pull/24523) build(deps-dev): bump @typescript-eslint/eslint-plugin from 5.60.0 to 5.60.1 in /superset-websocket (@dependabot[bot])
|
||||
|
||||
### 3.0.3 (Fri Dec 8 05:40:09 2023 -0800)
|
||||
|
||||
**Fixes**
|
||||
|
||||
- [#26215](https://github.com/apache/superset/pull/26215) fix(plugin-chart-echarts): support truncated numeric x-axis (@villebro)
|
||||
- [#26199](https://github.com/apache/superset/pull/26199) fix(chart-filter): Avoid column denormalization if not enabled (@Vitor-Avila)
|
||||
- [#26211](https://github.com/apache/superset/pull/26211) fix: support custom links in markdown (@villebro)
|
||||
- [#26189](https://github.com/apache/superset/pull/26189) fix(dashboard): title formatting (@nytai)
|
||||
- [#26207](https://github.com/apache/superset/pull/26207) fix: Includes 90° x-axis label rotation (@michael-s-molina)
|
||||
- [#26157](https://github.com/apache/superset/pull/26157) fix(init-job): Fix envFrom for init job in helm chart (@sumagoudb)
|
||||
- [#25878](https://github.com/apache/superset/pull/25878) fix(embedded): Hide sensitive payload data from guest users (@jfrag1)
|
||||
- [#25894](https://github.com/apache/superset/pull/25894) fix(Alerts/Reports): allow use of ";" separator in slack recipient entry (@rtexelm)
|
||||
- [#26116](https://github.com/apache/superset/pull/26116) fix(database-import): Support importing a DB connection with a version set (@Vitor-Avila)
|
||||
- [#26154](https://github.com/apache/superset/pull/26154) fix: set label on adhoc column should persist (@betodealmeida)
|
||||
- [#26140](https://github.com/apache/superset/pull/26140) fix(annotations): time grain column (@betodealmeida)
|
||||
- [#23916](https://github.com/apache/superset/pull/23916) fix: remove default secret key from helm (@dpgaspar)
|
||||
- [#26120](https://github.com/apache/superset/pull/26120) fix: alias column when fetching values (@betodealmeida)
|
||||
- [#26106](https://github.com/apache/superset/pull/26106) fix: flaky test_explore_json_async test v2 (@villebro)
|
||||
- [#26091](https://github.com/apache/superset/pull/26091) fix: bump node-fetch to 2.6.7 (@dpgaspar)
|
||||
- [#26087](https://github.com/apache/superset/pull/26087) fix(plugin-chart-echarts): support numerical x-axis (@villebro)
|
||||
- [#26059](https://github.com/apache/superset/pull/26059) fix: Flaky test_explore_json_async test (@michael-s-molina)
|
||||
- [#26023](https://github.com/apache/superset/pull/26023) fix: Prevent cached bootstrap data from leaking between users w/ same first/last name (@jfrag1)
|
||||
- [#26060](https://github.com/apache/superset/pull/26060) fix: Optimize fetching samples logic (@john-bodley)
|
||||
- [#26010](https://github.com/apache/superset/pull/26010) fix: Remove annotation Fuzzy to get french translation (@aehanno)
|
||||
- [#26005](https://github.com/apache/superset/pull/26005) fix(security): restore default value of SESSION_COOKIE_SECURE to False (@sfirke)
|
||||
- [#25883](https://github.com/apache/superset/pull/25883) fix(horizontal filter bar filter labels): Increase max-width to 96px (@rtexelm)
|
||||
|
||||
**Others**
|
||||
|
||||
- [#26208](https://github.com/apache/superset/pull/26208) chore: Adds note about numerical x-axis (@michael-s-molina)
|
||||
- [#26158](https://github.com/apache/superset/pull/26158) chore: Clean up the examples dashboards (@michael-s-molina)
|
||||
- [#25931](https://github.com/apache/superset/pull/25931) chore(deps): bump pillow deps (@gnought)
|
||||
|
||||
### 3.0.2 (Mon Nov 20 07:38:38 2023 -0500)
|
||||
|
||||
**Fixes**
|
||||
@@ -903,6 +1337,47 @@ under the License.
|
||||
- [#23158](https://github.com/apache/superset/pull/23158) chore: Bump cryptography to 39.0.1 (@EugeneTorap)
|
||||
- [#23108](https://github.com/apache/superset/pull/23108) chore: Remove yarn.lock from the root folder (@EugeneTorap)
|
||||
|
||||
### 2.1.3 (Fri Dec 8 16:36:51 2023 -0700)
|
||||
|
||||
**Database Migrations**
|
||||
|
||||
**Features**
|
||||
|
||||
**Fixes**
|
||||
|
||||
- [#25658](https://github.com/apache/superset/pull/25658) fix: improve upload ZIP file validation (@dpgaspar)
|
||||
- [#25779](https://github.com/apache/superset/pull/25779) fix: DB-specific quoting in Jinja macro (@betodealmeida)
|
||||
- [#25843](https://github.com/apache/superset/pull/25843) fix: remove `update_charts_owners` (@betodealmeida)
|
||||
|
||||
**Others**
|
||||
|
||||
- [#23862](https://github.com/apache/superset/pull/23862) chore: Use nh3 lib instead of bleach (@EugeneTorap)
|
||||
- [#23965](https://github.com/apache/superset/pull/23965) chore: bump werkzeug and Flask (@dpgaspar)
|
||||
- [#24033](https://github.com/apache/superset/pull/24033) chore: Update mypy and fix stubs issue (@EugeneTorap)
|
||||
- [#24045](https://github.com/apache/superset/pull/24045) chore: Bump sqlparse to 0.4.4 (@EugeneTorap)
|
||||
- [#24324](https://github.com/apache/superset/pull/24324) chore: rate limit requests (@betodealmeida)
|
||||
|
||||
### 2.1.2 (Wed Oct 18 16:59:30 2023 -0700)
|
||||
|
||||
**Database Migrations**
|
||||
|
||||
**Features**
|
||||
|
||||
**Fixes**
|
||||
|
||||
- [#25150](https://github.com/apache/superset/pull/25150) fix: Chart series limit doesn't work for some databases (@KSPT-taylorjohn)
|
||||
- [#25014](https://github.com/apache/superset/pull/25014) fix: CTE queries with non-SELECT statements (@dpgaspar)
|
||||
- [#24849](https://github.com/apache/superset/pull/24849) fix: validation errors appearing after ssh tunnel switch (@hughhhh)
|
||||
- [#24196](https://github.com/apache/superset/pull/24196) fix: SSH Tunnel creation with dynamic form (@hughhhh)
|
||||
- [#24821](https://github.com/apache/superset/pull/24821) fix: Allow chart import to update the dataset an existing chart points to (@jfrag1)
|
||||
- [#24317](https://github.com/apache/superset/pull/24317) fix: update order of build for testing a release (@eschutho)
|
||||
|
||||
**Others**
|
||||
|
||||
- [#24826](https://github.com/apache/superset/pull/24826) chore: remove CssTemplate and Annotation access from gamma role (@lilykuang)
|
||||
- [#23680](https://github.com/apache/superset/pull/23680) chore: bump wtforms and add missing flask-limiter (@dpgaspar)
|
||||
- [#24758](https://github.com/apache/superset/pull/24758) chore(view_api): return application/json as content-type for api/v1/form_data endpoint (@zephyring)
|
||||
|
||||
### 2.1.1 (Sun Apr 23 15:44:21 2023 +0100)
|
||||
|
||||
**Database Migrations**
|
||||
|
||||
14
Dockerfile
@@ -61,9 +61,7 @@ ENV LANG=C.UTF-8 \
|
||||
SUPERSET_HOME="/app/superset_home" \
|
||||
SUPERSET_PORT=8088
|
||||
|
||||
RUN --mount=target=/var/lib/apt/lists,type=cache \
|
||||
--mount=target=/var/cache/apt,type=cache \
|
||||
mkdir -p ${PYTHONPATH} superset/static superset-frontend apache_superset.egg-info requirements \
|
||||
RUN mkdir -p ${PYTHONPATH} superset/static superset-frontend apache_superset.egg-info requirements \
|
||||
&& useradd --user-group -d ${SUPERSET_HOME} -m --no-log-init --shell /bin/bash superset \
|
||||
&& apt-get update -qq && apt-get install -yqq --no-install-recommends \
|
||||
build-essential \
|
||||
@@ -75,7 +73,8 @@ RUN --mount=target=/var/lib/apt/lists,type=cache \
|
||||
libecpg-dev \
|
||||
libldap2-dev \
|
||||
&& touch superset/static/version_info.json \
|
||||
&& chown -R superset:superset ./*
|
||||
&& chown -R superset:superset ./* \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
COPY --chown=superset:superset setup.py MANIFEST.in README.md ./
|
||||
# setup.py uses the version information in package.json
|
||||
@@ -112,9 +111,8 @@ ARG GECKODRIVER_VERSION=v0.33.0 \
|
||||
|
||||
USER root
|
||||
|
||||
RUN --mount=target=/var/lib/apt/lists,type=cache \
|
||||
--mount=target=/var/cache/apt,type=cache \
|
||||
apt-get install -yqq --no-install-recommends \
|
||||
RUN apt-get update -qq \
|
||||
&& apt-get install -yqq --no-install-recommends \
|
||||
libnss3 \
|
||||
libdbus-glib-1-2 \
|
||||
libgtk-3-0 \
|
||||
@@ -127,7 +125,7 @@ RUN --mount=target=/var/lib/apt/lists,type=cache \
|
||||
# Install Firefox
|
||||
&& wget -q https://download-installer.cdn.mozilla.net/pub/firefox/releases/${FIREFOX_VERSION}/linux-x86_64/en-US/firefox-${FIREFOX_VERSION}.tar.bz2 -O - | tar xfj - -C /opt \
|
||||
&& ln -s /opt/firefox/firefox /usr/local/bin/firefox \
|
||||
&& apt-get autoremove -yqq --purge wget && rm -rf /var/[log,tmp]/* /tmp/*
|
||||
&& apt-get autoremove -yqq --purge wget && rm -rf /var/[log,tmp]/* /tmp/* /var/lib/apt/lists/*
|
||||
# Cache everything for dev purposes...
|
||||
RUN --mount=type=bind,target=./requirements/base.txt,src=./requirements/base.txt \
|
||||
--mount=type=bind,target=./requirements/docker.txt,src=./requirements/docker.txt \
|
||||
|
||||
10
UPDATING.md
@@ -22,18 +22,18 @@ under the License.
|
||||
This file documents any backwards-incompatible changes in Superset and
|
||||
assists people when migrating to a new version.
|
||||
|
||||
## Next
|
||||
## 3.1.0
|
||||
|
||||
- [24657](https://github.com/apache/superset/pull/24657): Bumps the cryptography package to augment the OpenSSL security vulnerability.
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
### Potential Downtime
|
||||
|
||||
### Other
|
||||
|
||||
- [24982](https://github.com/apache/superset/pull/24982): By default, physical datasets on Oracle-like dialects like Snowflake will now use denormalized column names. However, existing datasets won't be affected. To change this behavior, the "Advanced" section on the dataset modal has a "Normalize column names" flag which can be changed to change this behavior.
|
||||
|
||||
## 3.0.3
|
||||
|
||||
- [26034](https://github.com/apache/superset/issues/26034): Fixes a problem where numeric x-axes were being treated as categorical values. As a consequence of that, the way labels are displayed might change given that ECharts has a different treatment for numerical and categorical values. To revert to the old behavior, users need to manually convert numerical columns to text so that they are treated as categories. Check https://github.com/apache/superset/issues/26159 for more details.
|
||||
|
||||
## 3.0.0
|
||||
|
||||
- [25053](https://github.com/apache/superset/pull/25053): Extends the `ab_user.email` column from 64 to 320 characters which has an associated unique key constraint. This will be problematic for MySQL metadata databases which use the InnoDB storage engine with the `innodb_large_prefix` parameter disabled as the key prefix limit is 767 bytes. Enabling said parameter and ensuring that the table uses either the `DYNAMIC` or `COMPRESSED` row format should remedy the problem. See [here](https://dev.mysql.com/doc/refman/5.7/en/innodb-limits.html) for more details.
|
||||
|
||||
@@ -29,7 +29,7 @@ maintainers:
|
||||
- name: craig-rueda
|
||||
email: craig@craigrueda.com
|
||||
url: https://github.com/craig-rueda
|
||||
version: 0.10.15
|
||||
version: 0.11.2
|
||||
dependencies:
|
||||
- name: postgresql
|
||||
version: 12.1.6
|
||||
|
||||
@@ -23,7 +23,7 @@ NOTE: This file is generated by helm-docs: https://github.com/norwoodj/helm-docs
|
||||
|
||||
# superset
|
||||
|
||||

|
||||

|
||||
|
||||
Apache Superset is a modern, enterprise-ready business intelligence web application
|
||||
|
||||
@@ -40,6 +40,12 @@ helm repo add superset http://apache.github.io/superset/
|
||||
helm install my-superset superset/superset
|
||||
```
|
||||
|
||||
Make sure you set your own `SECRET_KEY` to something unique and secret. This secret key is used by Flask for
|
||||
securely signing the session cookie and will be used to encrypt sensitive data on Superset's metadata database.
|
||||
It should be a long random bytes or str.
|
||||
|
||||
On helm this can be set on `extraSecretEnv.SUPERSET_SECRET_KEY` or `configOverrides.secrets`
|
||||
|
||||
## Requirements
|
||||
|
||||
| Repository | Name | Version |
|
||||
@@ -124,6 +130,7 @@ helm install my-superset superset/superset
|
||||
| supersetCeleryBeat.containerSecurityContext | object | `{}` | |
|
||||
| supersetCeleryBeat.deploymentAnnotations | object | `{}` | Annotations to be added to supersetCeleryBeat deployment |
|
||||
| supersetCeleryBeat.enabled | bool | `false` | This is only required if you intend to use alerts and reports |
|
||||
| supersetCeleryBeat.extraContainers | list | `[]` | Launch additional containers into supersetCeleryBeat pods |
|
||||
| supersetCeleryBeat.forceReload | bool | `false` | If true, forces deployment to reload on each upgrade |
|
||||
| supersetCeleryBeat.initContainers | list | a container waiting for postgres | List of init containers |
|
||||
| supersetCeleryBeat.podAnnotations | object | `{}` | Annotations to be added to supersetCeleryBeat pods |
|
||||
@@ -136,6 +143,7 @@ helm install my-superset superset/superset
|
||||
| supersetCeleryFlower.containerSecurityContext | object | `{}` | |
|
||||
| supersetCeleryFlower.deploymentAnnotations | object | `{}` | Annotations to be added to supersetCeleryFlower deployment |
|
||||
| supersetCeleryFlower.enabled | bool | `false` | Enables a Celery flower deployment (management UI to monitor celery jobs) WARNING: on superset 1.x, this requires a Superset image that has `flower<1.0.0` installed (which is NOT the case of the default images) flower>=1.0.0 requires Celery 5+ which Superset 1.5 does not support |
|
||||
| supersetCeleryFlower.extraContainers | list | `[]` | Launch additional containers into supersetCeleryFlower pods |
|
||||
| supersetCeleryFlower.initContainers | list | a container waiting for postgres and redis | List of init containers |
|
||||
| supersetCeleryFlower.livenessProbe.failureThreshold | int | `3` | |
|
||||
| supersetCeleryFlower.livenessProbe.httpGet.path | string | `"/api/workers"` | |
|
||||
@@ -223,6 +231,7 @@ helm install my-superset superset/superset
|
||||
| supersetWebsockets.containerSecurityContext | object | `{}` | |
|
||||
| supersetWebsockets.deploymentAnnotations | object | `{}` | |
|
||||
| supersetWebsockets.enabled | bool | `false` | This is only required if you intend to use `GLOBAL_ASYNC_QUERIES` in `ws` mode see https://github.com/apache/superset/blob/master/CONTRIBUTING.md#async-chart-queries |
|
||||
| supersetWebsockets.extraContainers | list | `[]` | Launch additional containers into supersetWebsockets pods |
|
||||
| supersetWebsockets.image.pullPolicy | string | `"IfNotPresent"` | |
|
||||
| supersetWebsockets.image.repository | string | `"oneacrefund/superset-websocket"` | There is no official image (yet), this one is community-supported |
|
||||
| supersetWebsockets.image.tag | string | `"latest"` | |
|
||||
|
||||
@@ -39,6 +39,12 @@ helm repo add superset http://apache.github.io/superset/
|
||||
helm install my-superset superset/superset
|
||||
```
|
||||
|
||||
Make sure you set your own `SECRET_KEY` to something unique and secret. This secret key is used by Flask for
|
||||
securely signing the session cookie and will be used to encrypt sensitive data on Superset's metadata database.
|
||||
It should be a long random bytes or str.
|
||||
|
||||
On helm this can be set on `extraSecretEnv.SUPERSET_SECRET_KEY` or `configOverrides.secrets`
|
||||
|
||||
{{ template "chart.requirementsSection" . }}
|
||||
|
||||
{{ template "chart.valuesSection" . }}
|
||||
|
||||
@@ -82,7 +82,6 @@ DATA_CACHE_CONFIG = CACHE_CONFIG
|
||||
|
||||
SQLALCHEMY_DATABASE_URI = f"postgresql+psycopg2://{env('DB_USER')}:{env('DB_PASS')}@{env('DB_HOST')}:{env('DB_PORT')}/{env('DB_NAME')}"
|
||||
SQLALCHEMY_TRACK_MODIFICATIONS = True
|
||||
SECRET_KEY = env('SECRET_KEY', 'thisISaSECRET_1234')
|
||||
|
||||
class CeleryConfig:
|
||||
imports = ("superset.sql_lab", )
|
||||
|
||||
@@ -120,6 +120,9 @@ spec:
|
||||
{{- else }}
|
||||
{{- toYaml .Values.resources | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- if .Values.supersetCeleryBeat.extraContainers }}
|
||||
{{- toYaml .Values.supersetCeleryBeat.extraContainers | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.nodeSelector }}
|
||||
nodeSelector: {{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
|
||||
@@ -115,6 +115,9 @@ spec:
|
||||
{{- else }}
|
||||
{{- toYaml .Values.resources | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- if .Values.supersetCeleryFlower.extraContainers }}
|
||||
{{- toYaml .Values.supersetCeleryFlower.extraContainers | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.nodeSelector }}
|
||||
nodeSelector: {{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
|
||||
@@ -114,6 +114,9 @@ spec:
|
||||
{{- if .Values.supersetWebsockets.livenessProbe }}
|
||||
livenessProbe: {{- .Values.supersetWebsockets.livenessProbe | toYaml | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- if .Values.supersetWebsockets.extraContainers }}
|
||||
{{- toYaml .Values.supersetWebsockets.extraContainers | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.nodeSelector }}
|
||||
nodeSelector: {{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
|
||||
@@ -63,7 +63,7 @@ spec:
|
||||
name: {{ tpl .Values.envFromSecret . }}
|
||||
{{- range .Values.envFromSecrets }}
|
||||
- secretRef:
|
||||
name: {{ tpl . $ }}
|
||||
name: {{ tpl . $ | quote }}
|
||||
{{- end }}
|
||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||
{{- if .Values.init.containerSecurityContext }}
|
||||
|
||||
@@ -93,6 +93,8 @@ extraSecretEnv: {}
|
||||
# # Google API Keys: https://console.cloud.google.com/apis/credentials
|
||||
# GOOGLE_KEY: ...
|
||||
# GOOGLE_SECRET: ...
|
||||
# # Generate your own secret key for encryption. Use openssl rand -base64 42 to generate a good key
|
||||
# SUPERSET_SECRET_KEY: 'CHANGE_ME_TO_A_COMPLEX_RANDOM_SECRET'
|
||||
|
||||
# -- Extra files to mount on `/app/pythonpath`
|
||||
extraConfigs: {}
|
||||
@@ -441,6 +443,8 @@ supersetCeleryBeat:
|
||||
- /bin/sh
|
||||
- -c
|
||||
- dockerize -wait "tcp://$DB_HOST:$DB_PORT" -wait "tcp://$REDIS_HOST:$REDIS_PORT" -timeout 120s
|
||||
# -- Launch additional containers into supersetCeleryBeat pods
|
||||
extraContainers: []
|
||||
# -- Annotations to be added to supersetCeleryBeat deployment
|
||||
deploymentAnnotations: {}
|
||||
# -- Affinity to be added to supersetCeleryBeat deployment
|
||||
@@ -522,6 +526,8 @@ supersetCeleryFlower:
|
||||
- /bin/sh
|
||||
- -c
|
||||
- dockerize -wait "tcp://$DB_HOST:$DB_PORT" -wait "tcp://$REDIS_HOST:$REDIS_PORT" -timeout 120s
|
||||
# -- Launch additional containers into supersetCeleryFlower pods
|
||||
extraContainers: []
|
||||
# -- Annotations to be added to supersetCeleryFlower deployment
|
||||
deploymentAnnotations: {}
|
||||
# -- Affinity to be added to supersetCeleryFlower deployment
|
||||
@@ -588,6 +594,8 @@ supersetWebsockets:
|
||||
http: nil
|
||||
command: []
|
||||
resources: {}
|
||||
# -- Launch additional containers into supersetWebsockets pods
|
||||
extraContainers: []
|
||||
deploymentAnnotations: {}
|
||||
# -- Affinity to be added to supersetWebsockets deployment
|
||||
affinity: {}
|
||||
|
||||
@@ -252,7 +252,7 @@ prison==0.2.1
|
||||
# via flask-appbuilder
|
||||
prompt-toolkit==3.0.38
|
||||
# via click-repl
|
||||
pyarrow==12.0.0
|
||||
pyarrow==14.0.1
|
||||
# via apache-superset
|
||||
pycparser==2.20
|
||||
# via cffi
|
||||
@@ -371,6 +371,7 @@ werkzeug==2.3.3
|
||||
# via
|
||||
# apache-superset
|
||||
# flask
|
||||
# flask-appbuilder
|
||||
# flask-jwt-extended
|
||||
# flask-login
|
||||
wrapt==1.15.0
|
||||
|
||||
7
setup.py
@@ -113,7 +113,7 @@ setup(
|
||||
"python-dateutil",
|
||||
"python-dotenv",
|
||||
"python-geohash",
|
||||
"pyarrow>=12.0.0, <13",
|
||||
"pyarrow>=14.0.1, <15",
|
||||
"pyyaml>=6.0.0, <7.0.0",
|
||||
"PyJWT>=2.4.0, <3.0",
|
||||
"redis>=4.5.4, <5.0",
|
||||
@@ -146,6 +146,7 @@ setup(
|
||||
"cockroachdb": ["cockroachdb>=0.3.5, <0.4"],
|
||||
"cors": ["flask-cors>=2.0.0"],
|
||||
"crate": ["crate[sqlalchemy]>=0.26.0, <0.27"],
|
||||
"databend": ["databend-sqlalchemy>=0.3.2, <1.0"],
|
||||
"databricks": [
|
||||
"databricks-sql-connector>=2.0.2, <3",
|
||||
"sqlalchemy-databricks>=0.2.0",
|
||||
@@ -154,7 +155,7 @@ setup(
|
||||
"dremio": ["sqlalchemy-dremio>=1.1.5, <1.3"],
|
||||
"drill": ["sqlalchemy-drill==0.1.dev"],
|
||||
"druid": ["pydruid>=0.6.5,<0.7"],
|
||||
"duckdb": ["duckdb-engine==0.9.2"],
|
||||
"duckdb": ["duckdb-engine>=0.9.5, <0.10"],
|
||||
"dynamodb": ["pydynamodb>=0.4.2"],
|
||||
"solr": ["sqlalchemy-solr >= 0.2.0"],
|
||||
"elasticsearch": ["elasticsearch-dbapi>=0.2.9, <0.3.0"],
|
||||
@@ -201,7 +202,7 @@ setup(
|
||||
"thrift>=0.14.1, <1.0.0",
|
||||
],
|
||||
"teradata": ["teradatasql>=16.20.0.23"],
|
||||
"thumbnails": ["Pillow>=9.5.0, <10.0.0"],
|
||||
"thumbnails": ["Pillow>=10.0.1, <11"],
|
||||
"vertica": ["sqlalchemy-vertica-python>=0.5.9, < 0.6"],
|
||||
"netezza": ["nzalchemy>=11.0.2"],
|
||||
"starrocks": ["starrocks>=1.0.0"],
|
||||
|
||||
@@ -29,10 +29,9 @@ describe('Alert list view', () => {
|
||||
cy.getBySel('sort-header').eq(2).contains('Name');
|
||||
cy.getBySel('sort-header').eq(3).contains('Schedule');
|
||||
cy.getBySel('sort-header').eq(4).contains('Notification method');
|
||||
cy.getBySel('sort-header').eq(5).contains('Created by');
|
||||
cy.getBySel('sort-header').eq(6).contains('Owners');
|
||||
cy.getBySel('sort-header').eq(7).contains('Modified');
|
||||
cy.getBySel('sort-header').eq(8).contains('Active');
|
||||
cy.getBySel('sort-header').eq(5).contains('Owners');
|
||||
cy.getBySel('sort-header').eq(6).contains('Last modified');
|
||||
cy.getBySel('sort-header').eq(7).contains('Active');
|
||||
// TODO Cypress won't recognize the Actions column
|
||||
// cy.getBySel('sort-header').eq(9).contains('Actions');
|
||||
});
|
||||
|
||||
@@ -29,10 +29,9 @@ describe('Report list view', () => {
|
||||
cy.getBySel('sort-header').eq(2).contains('Name');
|
||||
cy.getBySel('sort-header').eq(3).contains('Schedule');
|
||||
cy.getBySel('sort-header').eq(4).contains('Notification method');
|
||||
cy.getBySel('sort-header').eq(5).contains('Created by');
|
||||
cy.getBySel('sort-header').eq(6).contains('Owners');
|
||||
cy.getBySel('sort-header').eq(7).contains('Modified');
|
||||
cy.getBySel('sort-header').eq(8).contains('Active');
|
||||
cy.getBySel('sort-header').eq(5).contains('Owners');
|
||||
cy.getBySel('sort-header').eq(6).contains('Last modified');
|
||||
cy.getBySel('sort-header').eq(7).contains('Active');
|
||||
// TODO Cypress won't recognize the Actions column
|
||||
// cy.getBySel('sort-header').eq(9).contains('Actions');
|
||||
});
|
||||
|
||||
@@ -35,14 +35,14 @@ describe('Charts filters', () => {
|
||||
setFilter('Owner', 'admin user');
|
||||
});
|
||||
|
||||
it('should allow filtering by "Created by" correctly', () => {
|
||||
setFilter('Created by', 'alpha user');
|
||||
setFilter('Created by', 'admin user');
|
||||
it('should allow filtering by "Modified by" correctly', () => {
|
||||
setFilter('Modified by', 'alpha user');
|
||||
setFilter('Modified by', 'admin user');
|
||||
});
|
||||
|
||||
it('should allow filtering by "Chart type" correctly', () => {
|
||||
setFilter('Chart type', 'Area Chart (legacy)');
|
||||
setFilter('Chart type', 'Bubble Chart');
|
||||
it('should allow filtering by "Type" correctly', () => {
|
||||
setFilter('Type', 'Area Chart (legacy)');
|
||||
setFilter('Type', 'Bubble Chart');
|
||||
});
|
||||
|
||||
it('should allow filtering by "Dataset" correctly', () => {
|
||||
@@ -51,7 +51,7 @@ describe('Charts filters', () => {
|
||||
});
|
||||
|
||||
it('should allow filtering by "Dashboards" correctly', () => {
|
||||
setFilter('Dashboards', 'Unicode Test');
|
||||
setFilter('Dashboards', 'Tabbed Dashboard');
|
||||
setFilter('Dashboard', 'Unicode Test');
|
||||
setFilter('Dashboard', 'Tabbed Dashboard');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -109,14 +109,12 @@ describe('Charts list', () => {
|
||||
|
||||
it('should load rows in list mode', () => {
|
||||
cy.getBySel('listview-table').should('be.visible');
|
||||
cy.getBySel('sort-header').eq(1).contains('Chart');
|
||||
cy.getBySel('sort-header').eq(2).contains('Visualization type');
|
||||
cy.getBySel('sort-header').eq(1).contains('Name');
|
||||
cy.getBySel('sort-header').eq(2).contains('Type');
|
||||
cy.getBySel('sort-header').eq(3).contains('Dataset');
|
||||
// cy.getBySel('sort-header').eq(4).contains('Dashboards added to');
|
||||
cy.getBySel('sort-header').eq(4).contains('Modified by');
|
||||
cy.getBySel('sort-header').eq(4).contains('Owners');
|
||||
cy.getBySel('sort-header').eq(5).contains('Last modified');
|
||||
cy.getBySel('sort-header').eq(6).contains('Created by');
|
||||
cy.getBySel('sort-header').eq(7).contains('Actions');
|
||||
cy.getBySel('sort-header').eq(6).contains('Actions');
|
||||
});
|
||||
|
||||
it('should sort correctly in list mode', () => {
|
||||
|
||||
@@ -113,7 +113,7 @@ function prepareDashboardFilters(
|
||||
},
|
||||
type: 'NATIVE_FILTER',
|
||||
description: '',
|
||||
chartsInScope: [6],
|
||||
chartsInScope: [5],
|
||||
tabsInScope: [],
|
||||
});
|
||||
});
|
||||
@@ -150,7 +150,7 @@ function prepareDashboardFilters(
|
||||
meta: {
|
||||
width: 4,
|
||||
height: 50,
|
||||
chartId: 6,
|
||||
chartId: 5,
|
||||
sliceName: 'Most Populated Countries',
|
||||
},
|
||||
},
|
||||
|
||||
@@ -25,7 +25,6 @@ import { TABBED_DASHBOARD } from 'cypress/utils/urls';
|
||||
import { expandFilterOnLeftPanel } from './utils';
|
||||
|
||||
const TREEMAP = { name: 'Treemap', viz: 'treemap_v2' };
|
||||
const FILTER_BOX = { name: 'Region Filter', viz: 'filter_box' };
|
||||
const LINE_CHART = { name: 'Growth Rate', viz: 'line' };
|
||||
const BOX_PLOT = { name: 'Box plot', viz: 'box_plot' };
|
||||
const BIG_NUMBER = { name: 'Number of Girls', viz: 'big_number_total' };
|
||||
@@ -41,7 +40,6 @@ function topLevelTabs() {
|
||||
function resetTabs() {
|
||||
topLevelTabs();
|
||||
cy.get('@top-level-tabs').first().click();
|
||||
waitForChartLoad(FILTER_BOX);
|
||||
waitForChartLoad(TREEMAP);
|
||||
waitForChartLoad(BIG_NUMBER);
|
||||
waitForChartLoad(TABLE);
|
||||
@@ -96,7 +94,6 @@ describe('Dashboard tabs', () => {
|
||||
|
||||
it.skip('should send new queries when tab becomes visible', () => {
|
||||
// landing in first tab
|
||||
waitForChartLoad(FILTER_BOX);
|
||||
waitForChartLoad(TREEMAP);
|
||||
|
||||
getChartAliasBySpec(TREEMAP).then(treemapAlias => {
|
||||
|
||||
@@ -23,7 +23,6 @@ import { ChartSpec, waitForChartLoad } from 'cypress/utils';
|
||||
export const WORLD_HEALTH_CHARTS = [
|
||||
{ name: '% Rural', viz: 'world_map' },
|
||||
{ name: 'Most Populated Countries', viz: 'table' },
|
||||
{ name: 'Region Filter', viz: 'filter_box' },
|
||||
{ name: "World's Population", viz: 'big_number' },
|
||||
{ name: 'Growth Rate', viz: 'line' },
|
||||
{ name: 'Rural Breakdown', viz: 'sunburst' },
|
||||
|
||||
@@ -35,9 +35,9 @@ describe('Dashboards filters', () => {
|
||||
setFilter('Owner', 'admin user');
|
||||
});
|
||||
|
||||
it('should allow filtering by "Created by" correctly', () => {
|
||||
setFilter('Created by', 'alpha user');
|
||||
setFilter('Created by', 'admin user');
|
||||
it('should allow filtering by "Modified by" correctly', () => {
|
||||
setFilter('Modified by', 'alpha user');
|
||||
setFilter('Modified by', 'admin user');
|
||||
});
|
||||
|
||||
it('should allow filtering by "Status" correctly', () => {
|
||||
|
||||
@@ -54,13 +54,11 @@ describe('Dashboards list', () => {
|
||||
|
||||
it('should load rows in list mode', () => {
|
||||
cy.getBySel('listview-table').should('be.visible');
|
||||
cy.getBySel('sort-header').eq(1).contains('Title');
|
||||
cy.getBySel('sort-header').eq(2).contains('Modified by');
|
||||
cy.getBySel('sort-header').eq(3).contains('Status');
|
||||
cy.getBySel('sort-header').eq(4).contains('Modified');
|
||||
cy.getBySel('sort-header').eq(5).contains('Created by');
|
||||
cy.getBySel('sort-header').eq(6).contains('Owners');
|
||||
cy.getBySel('sort-header').eq(7).contains('Actions');
|
||||
cy.getBySel('sort-header').eq(1).contains('Name');
|
||||
cy.getBySel('sort-header').eq(2).contains('Status');
|
||||
cy.getBySel('sort-header').eq(3).contains('Owners');
|
||||
cy.getBySel('sort-header').eq(4).contains('Last modified');
|
||||
cy.getBySel('sort-header').eq(5).contains('Actions');
|
||||
});
|
||||
|
||||
it('should sort correctly in list mode', () => {
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
*/
|
||||
import '@cypress/code-coverage/support';
|
||||
import '@applitools/eyes-cypress/commands';
|
||||
import failOnConsoleError, { Config } from 'cypress-fail-on-console-error';
|
||||
import failOnConsoleError from 'cypress-fail-on-console-error';
|
||||
|
||||
require('cy-verify-downloads').addCustomCommand();
|
||||
|
||||
|
||||
25
superset-frontend/package-lock.json
generated
@@ -186,6 +186,7 @@
|
||||
"@testing-library/react-hooks": "^5.0.3",
|
||||
"@testing-library/user-event": "^12.7.0",
|
||||
"@types/classnames": "^2.2.10",
|
||||
"@types/dom-to-image": "^2.6.7",
|
||||
"@types/enzyme": "^3.10.5",
|
||||
"@types/enzyme-adapter-react-16": "^1.0.6",
|
||||
"@types/fetch-mock": "^7.3.2",
|
||||
@@ -19248,6 +19249,12 @@
|
||||
"@types/ms": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/dom-to-image": {
|
||||
"version": "2.6.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/dom-to-image/-/dom-to-image-2.6.7.tgz",
|
||||
"integrity": "sha512-me5VbCv+fcXozblWwG13krNBvuEOm6kA5xoa4RrjDJCNFOZSWR3/QLtOXimBHk1Fisq69Gx3JtOoXtg1N1tijg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/enzyme": {
|
||||
"version": "3.10.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/enzyme/-/enzyme-3.10.10.tgz",
|
||||
@@ -29511,9 +29518,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/dom-to-image-more": {
|
||||
"version": "2.10.1",
|
||||
"resolved": "https://registry.npmjs.org/dom-to-image-more/-/dom-to-image-more-2.10.1.tgz",
|
||||
"integrity": "sha512-gMG28V47WGj5/xvrsbSPJAWSaV7CBh4teLErn1iGD1sa29HsFsHxvnoLj8VxVvfqnjPgsiUGs2IV2VAxLJGb+A=="
|
||||
"version": "2.16.0",
|
||||
"resolved": "https://registry.npmjs.org/dom-to-image-more/-/dom-to-image-more-2.16.0.tgz",
|
||||
"integrity": "sha512-RyjtkaM/zVy90uJ20lT+/G7MwBZx6l/ePliq5CQOeAnPeew7aUGS6IqRWBkHpstU+POmhaKA8A9H9qf476gisQ=="
|
||||
},
|
||||
"node_modules/dom-to-pdf": {
|
||||
"version": "0.3.2",
|
||||
@@ -79208,6 +79215,12 @@
|
||||
"@types/ms": "*"
|
||||
}
|
||||
},
|
||||
"@types/dom-to-image": {
|
||||
"version": "2.6.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/dom-to-image/-/dom-to-image-2.6.7.tgz",
|
||||
"integrity": "sha512-me5VbCv+fcXozblWwG13krNBvuEOm6kA5xoa4RrjDJCNFOZSWR3/QLtOXimBHk1Fisq69Gx3JtOoXtg1N1tijg==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/enzyme": {
|
||||
"version": "3.10.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/enzyme/-/enzyme-3.10.10.tgz",
|
||||
@@ -87324,9 +87337,9 @@
|
||||
"from": "dom-to-image@git+https://github.com/dmapper/dom-to-image.git"
|
||||
},
|
||||
"dom-to-image-more": {
|
||||
"version": "2.10.1",
|
||||
"resolved": "https://registry.npmjs.org/dom-to-image-more/-/dom-to-image-more-2.10.1.tgz",
|
||||
"integrity": "sha512-gMG28V47WGj5/xvrsbSPJAWSaV7CBh4teLErn1iGD1sa29HsFsHxvnoLj8VxVvfqnjPgsiUGs2IV2VAxLJGb+A=="
|
||||
"version": "2.16.0",
|
||||
"resolved": "https://registry.npmjs.org/dom-to-image-more/-/dom-to-image-more-2.16.0.tgz",
|
||||
"integrity": "sha512-RyjtkaM/zVy90uJ20lT+/G7MwBZx6l/ePliq5CQOeAnPeew7aUGS6IqRWBkHpstU+POmhaKA8A9H9qf476gisQ=="
|
||||
},
|
||||
"dom-to-pdf": {
|
||||
"version": "0.3.2",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "superset",
|
||||
"version": "0.0.0-dev",
|
||||
"version": "3.1.0",
|
||||
"description": "Superset is a data exploration platform designed to be visual, intuitive, and interactive.",
|
||||
"keywords": [
|
||||
"big",
|
||||
@@ -251,6 +251,7 @@
|
||||
"@testing-library/react-hooks": "^5.0.3",
|
||||
"@testing-library/user-event": "^12.7.0",
|
||||
"@types/classnames": "^2.2.10",
|
||||
"@types/dom-to-image": "^2.6.7",
|
||||
"@types/enzyme": "^3.10.5",
|
||||
"@types/enzyme-adapter-react-16": "^1.0.6",
|
||||
"@types/fetch-mock": "^7.3.2",
|
||||
|
||||
@@ -17,15 +17,16 @@
|
||||
* under the License.
|
||||
*/
|
||||
import {
|
||||
t,
|
||||
QueryMode,
|
||||
DTTM_ALIAS,
|
||||
GenericDataType,
|
||||
QueryColumn,
|
||||
DatasourceType,
|
||||
QueryMode,
|
||||
t,
|
||||
} from '@superset-ui/core';
|
||||
import { ColumnMeta, SortSeriesData, SortSeriesType } from './types';
|
||||
|
||||
export const DEFAULT_MAX_ROW = 100000;
|
||||
|
||||
// eslint-disable-next-line import/prefer-default-export
|
||||
export const TIME_FILTER_LABELS = {
|
||||
time_range: t('Time Range'),
|
||||
@@ -41,6 +42,7 @@ export const COLUMN_NAME_ALIASES: Record<string, string> = {
|
||||
export const DATASET_TIME_COLUMN_OPTION: ColumnMeta = {
|
||||
verbose_name: COLUMN_NAME_ALIASES[DTTM_ALIAS],
|
||||
column_name: DTTM_ALIAS,
|
||||
type: 'TIMESTAMP',
|
||||
type_generic: GenericDataType.TEMPORAL,
|
||||
description: t(
|
||||
'A reference to the [Time] configuration, taking granularity into account',
|
||||
@@ -49,8 +51,9 @@ export const DATASET_TIME_COLUMN_OPTION: ColumnMeta = {
|
||||
|
||||
export const QUERY_TIME_COLUMN_OPTION: QueryColumn = {
|
||||
column_name: DTTM_ALIAS,
|
||||
type: DatasourceType.Query,
|
||||
is_dttm: false,
|
||||
is_dttm: true,
|
||||
type: 'TIMESTAMP',
|
||||
type_generic: GenericDataType.TEMPORAL,
|
||||
};
|
||||
|
||||
export const QueryModeLabel = {
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { DatasourceType } from '@superset-ui/core';
|
||||
import { DatasourceType, GenericDataType } from '@superset-ui/core';
|
||||
import { Dataset } from './types';
|
||||
|
||||
export const TestDataset: Dataset = {
|
||||
@@ -37,7 +37,7 @@ export const TestDataset: Dataset = {
|
||||
is_dttm: false,
|
||||
python_date_format: null,
|
||||
type: 'BIGINT',
|
||||
type_generic: 0,
|
||||
type_generic: GenericDataType.NUMERIC,
|
||||
verbose_name: null,
|
||||
warning_markdown: null,
|
||||
},
|
||||
@@ -55,7 +55,7 @@ export const TestDataset: Dataset = {
|
||||
is_dttm: false,
|
||||
python_date_format: null,
|
||||
type: 'VARCHAR(16)',
|
||||
type_generic: 1,
|
||||
type_generic: GenericDataType.STRING,
|
||||
verbose_name: '',
|
||||
warning_markdown: null,
|
||||
},
|
||||
@@ -73,7 +73,7 @@ export const TestDataset: Dataset = {
|
||||
is_dttm: false,
|
||||
python_date_format: null,
|
||||
type: 'VARCHAR(10)',
|
||||
type_generic: 1,
|
||||
type_generic: GenericDataType.STRING,
|
||||
verbose_name: null,
|
||||
warning_markdown: null,
|
||||
},
|
||||
@@ -91,7 +91,7 @@ export const TestDataset: Dataset = {
|
||||
is_dttm: true,
|
||||
python_date_format: null,
|
||||
type: 'TIMESTAMP WITHOUT TIME ZONE',
|
||||
type_generic: 2,
|
||||
type_generic: GenericDataType.TEMPORAL,
|
||||
verbose_name: null,
|
||||
warning_markdown: null,
|
||||
},
|
||||
@@ -109,7 +109,7 @@ export const TestDataset: Dataset = {
|
||||
is_dttm: false,
|
||||
python_date_format: null,
|
||||
type: 'VARCHAR(255)',
|
||||
type_generic: 1,
|
||||
type_generic: GenericDataType.STRING,
|
||||
verbose_name: null,
|
||||
warning_markdown: null,
|
||||
},
|
||||
|
||||
@@ -20,6 +20,7 @@ import { hasGenericChartAxes, t } from '@superset-ui/core';
|
||||
import { ControlPanelSectionConfig, ControlSetRow } from '../types';
|
||||
import {
|
||||
contributionModeControl,
|
||||
xAxisForceCategoricalControl,
|
||||
xAxisSortAscControl,
|
||||
xAxisSortControl,
|
||||
xAxisSortSeriesAscendingControl,
|
||||
@@ -55,6 +56,7 @@ export const echartsTimeSeriesQueryWithXAxisSort: ControlPanelSectionConfig = {
|
||||
controlSetRows: [
|
||||
[hasGenericChartAxes ? 'x_axis' : null],
|
||||
[hasGenericChartAxes ? 'time_grain_sqla' : null],
|
||||
[hasGenericChartAxes ? xAxisForceCategoricalControl : null],
|
||||
[hasGenericChartAxes ? xAxisSortControl : null],
|
||||
[hasGenericChartAxes ? xAxisSortAscControl : null],
|
||||
[hasGenericChartAxes ? xAxisSortSeriesControl : null],
|
||||
|
||||
@@ -20,9 +20,9 @@
|
||||
import {
|
||||
ContributionType,
|
||||
ensureIsArray,
|
||||
GenericDataType,
|
||||
getColumnLabel,
|
||||
getMetricLabel,
|
||||
isDefined,
|
||||
QueryFormColumn,
|
||||
QueryFormMetric,
|
||||
t,
|
||||
@@ -38,6 +38,7 @@ import {
|
||||
DEFAULT_XAXIS_SORT_SERIES_DATA,
|
||||
SORT_SERIES_CHOICES,
|
||||
} from '../constants';
|
||||
import { checkColumnType } from '../utils/checkColumnType';
|
||||
|
||||
export const contributionModeControl = {
|
||||
name: 'contributionMode',
|
||||
@@ -54,18 +55,29 @@ export const contributionModeControl = {
|
||||
},
|
||||
};
|
||||
|
||||
function isTemporal(controls: ControlStateMapping): boolean {
|
||||
return !(
|
||||
isDefined(controls?.x_axis?.value) &&
|
||||
!isTemporalColumn(
|
||||
function isForcedCategorical(controls: ControlStateMapping): boolean {
|
||||
return (
|
||||
checkColumnType(
|
||||
getColumnLabel(controls?.x_axis?.value as QueryFormColumn),
|
||||
controls?.datasource?.datasource,
|
||||
[GenericDataType.NUMERIC],
|
||||
) && !!controls?.xAxisForceCategorical?.value
|
||||
);
|
||||
}
|
||||
|
||||
function isSortable(controls: ControlStateMapping): boolean {
|
||||
return (
|
||||
isForcedCategorical(controls) ||
|
||||
checkColumnType(
|
||||
getColumnLabel(controls?.x_axis?.value as QueryFormColumn),
|
||||
controls?.datasource?.datasource,
|
||||
[GenericDataType.STRING, GenericDataType.BOOLEAN],
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
const xAxisSortVisibility = ({ controls }: { controls: ControlStateMapping }) =>
|
||||
!isTemporal(controls) &&
|
||||
isSortable(controls) &&
|
||||
ensureIsArray(controls?.groupby?.value).length === 0 &&
|
||||
ensureIsArray(controls?.metrics?.value).length === 1;
|
||||
|
||||
@@ -74,7 +86,7 @@ const xAxisMultiSortVisibility = ({
|
||||
}: {
|
||||
controls: ControlStateMapping;
|
||||
}) =>
|
||||
!isTemporal(controls) &&
|
||||
isSortable(controls) &&
|
||||
(!!ensureIsArray(controls?.groupby?.value).length ||
|
||||
ensureIsArray(controls?.metrics?.value).length > 1);
|
||||
|
||||
@@ -141,7 +153,29 @@ export const xAxisSortAscControl = {
|
||||
: t('X-Axis Sort Ascending'),
|
||||
default: true,
|
||||
description: t('Whether to sort ascending or descending on the base Axis.'),
|
||||
visibility: xAxisSortVisibility,
|
||||
visibility: ({ controls }: { controls: ControlStateMapping }) =>
|
||||
controls?.x_axis_sort?.value !== undefined &&
|
||||
xAxisSortVisibility({ controls }),
|
||||
},
|
||||
};
|
||||
|
||||
export const xAxisForceCategoricalControl = {
|
||||
name: 'xAxisForceCategorical',
|
||||
config: {
|
||||
type: 'CheckboxControl',
|
||||
label: () => t('Force categorical'),
|
||||
default: false,
|
||||
description: t('Treat values as categorical.'),
|
||||
initialValue: (control: ControlState, state: ControlPanelState | null) =>
|
||||
state?.form_data?.x_axis_sort !== undefined || control.value,
|
||||
renderTrigger: true,
|
||||
visibility: ({ controls }: { controls: ControlStateMapping }) =>
|
||||
checkColumnType(
|
||||
getColumnLabel(controls?.x_axis?.value as QueryFormColumn),
|
||||
controls?.datasource?.datasource,
|
||||
[GenericDataType.NUMERIC],
|
||||
),
|
||||
shouldMapStateToProps: () => true,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -173,6 +207,8 @@ export const xAxisSortSeriesAscendingControl = {
|
||||
default: DEFAULT_XAXIS_SORT_SERIES_DATA.sort_series_ascending,
|
||||
description: t('Whether to sort ascending or descending on the base Axis.'),
|
||||
renderTrigger: true,
|
||||
visibility: xAxisMultiSortVisibility,
|
||||
visibility: ({ controls }: { controls: ControlStateMapping }) =>
|
||||
controls?.x_axis_sort_series?.value !== undefined &&
|
||||
xAxisMultiSortVisibility({ controls }),
|
||||
},
|
||||
};
|
||||
|
||||
@@ -47,6 +47,7 @@ import {
|
||||
isDefined,
|
||||
hasGenericChartAxes,
|
||||
NO_TIME_RANGE,
|
||||
validateMaxValue,
|
||||
} from '@superset-ui/core';
|
||||
|
||||
import {
|
||||
@@ -58,7 +59,7 @@ import {
|
||||
DEFAULT_TIME_FORMAT,
|
||||
DEFAULT_NUMBER_FORMAT,
|
||||
} from '../utils';
|
||||
import { TIME_FILTER_LABELS } from '../constants';
|
||||
import { DEFAULT_MAX_ROW, TIME_FILTER_LABELS } from '../constants';
|
||||
import {
|
||||
SharedControlConfig,
|
||||
Dataset,
|
||||
@@ -243,7 +244,12 @@ const row_limit: SharedControlConfig<'SelectControl'> = {
|
||||
type: 'SelectControl',
|
||||
freeForm: true,
|
||||
label: t('Row limit'),
|
||||
validators: [legacyValidateInteger],
|
||||
clearable: false,
|
||||
validators: [
|
||||
legacyValidateInteger,
|
||||
(v, state) =>
|
||||
validateMaxValue(v, state?.common?.conf?.SQL_MAX_ROW || DEFAULT_MAX_ROW),
|
||||
],
|
||||
default: 10000,
|
||||
choices: formatSelectOptions(ROW_LIMIT_OPTIONS),
|
||||
description: t(
|
||||
|
||||
@@ -479,13 +479,15 @@ export function isControlPanelSectionConfig(
|
||||
export function isDataset(
|
||||
datasource: Dataset | QueryResponse | null | undefined,
|
||||
): datasource is Dataset {
|
||||
return !!datasource && 'columns' in datasource;
|
||||
return (
|
||||
!!datasource && 'columns' in datasource && !('sqlEditorId' in datasource)
|
||||
);
|
||||
}
|
||||
|
||||
export function isQueryResponse(
|
||||
datasource: Dataset | QueryResponse | null | undefined,
|
||||
): datasource is QueryResponse {
|
||||
return !!datasource && 'results' in datasource && 'sql' in datasource;
|
||||
return !!datasource && 'results' in datasource && 'sqlEditorId' in datasource;
|
||||
}
|
||||
|
||||
export enum SortSeriesType {
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { ensureIsArray, GenericDataType, ValueOf } from '@superset-ui/core';
|
||||
import {
|
||||
ControlPanelState,
|
||||
isDataset,
|
||||
isQueryResponse,
|
||||
} from '@superset-ui/chart-controls';
|
||||
|
||||
export function checkColumnType(
|
||||
columnName: string,
|
||||
datasource: ValueOf<Pick<ControlPanelState, 'datasource'>>,
|
||||
columnTypes: GenericDataType[],
|
||||
): boolean {
|
||||
if (isDataset(datasource)) {
|
||||
return ensureIsArray(datasource.columns).some(
|
||||
c =>
|
||||
c.type_generic !== undefined &&
|
||||
columnTypes.includes(c.type_generic) &&
|
||||
columnName === c.column_name,
|
||||
);
|
||||
}
|
||||
if (isQueryResponse(datasource)) {
|
||||
return ensureIsArray(datasource.columns)
|
||||
.filter(
|
||||
c =>
|
||||
c.type_generic !== undefined && columnTypes.includes(c.type_generic),
|
||||
)
|
||||
.map(c => c.column_name)
|
||||
.some(c => columnName === c);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -17,7 +17,7 @@
|
||||
* under the License.
|
||||
*/
|
||||
import { QueryResponse } from '@superset-ui/core';
|
||||
import { Dataset, isColumnMeta, isDataset } from '../types';
|
||||
import { Dataset, isDataset, isQueryResponse } from '../types';
|
||||
|
||||
/**
|
||||
* Convert Datasource columns to column choices
|
||||
@@ -25,11 +25,13 @@ import { Dataset, isColumnMeta, isDataset } from '../types';
|
||||
export default function columnChoices(
|
||||
datasource?: Dataset | QueryResponse | null,
|
||||
): [string, string][] {
|
||||
if (isDataset(datasource) && isColumnMeta(datasource.columns[0])) {
|
||||
if (isDataset(datasource) || isQueryResponse(datasource)) {
|
||||
return datasource.columns
|
||||
.map((col): [string, string] => [
|
||||
col.column_name,
|
||||
col.verbose_name || col.column_name,
|
||||
'verbose_name' in col
|
||||
? col.verbose_name || col.column_name
|
||||
: col.column_name,
|
||||
])
|
||||
.sort((opt1, opt2) =>
|
||||
opt1[1].toLowerCase() > opt2[1].toLowerCase() ? 1 : -1,
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
export * from './checkColumnType';
|
||||
export * from './selectOptions';
|
||||
export * from './D3Formatting';
|
||||
export * from './expandControlConfig';
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { GenericDataType, testQueryResponse } from '@superset-ui/core';
|
||||
import { checkColumnType, TestDataset } from '../../src';
|
||||
|
||||
test('checkColumnType columns from a Dataset', () => {
|
||||
expect(
|
||||
checkColumnType('num', TestDataset, [GenericDataType.NUMERIC]),
|
||||
).toEqual(true);
|
||||
expect(checkColumnType('num', TestDataset, [GenericDataType.STRING])).toEqual(
|
||||
false,
|
||||
);
|
||||
expect(
|
||||
checkColumnType('gender', TestDataset, [GenericDataType.STRING]),
|
||||
).toEqual(true);
|
||||
expect(
|
||||
checkColumnType('gender', TestDataset, [GenericDataType.NUMERIC]),
|
||||
).toEqual(false);
|
||||
});
|
||||
|
||||
test('checkColumnType from a QueryResponse', () => {
|
||||
expect(
|
||||
checkColumnType('Column 1', testQueryResponse, [GenericDataType.STRING]),
|
||||
).toEqual(true);
|
||||
expect(
|
||||
checkColumnType('Column 1', testQueryResponse, [GenericDataType.NUMERIC]),
|
||||
).toEqual(false);
|
||||
});
|
||||
|
||||
test('checkColumnType from null', () => {
|
||||
expect(checkColumnType('col', null, [])).toEqual(false);
|
||||
});
|
||||
@@ -16,7 +16,11 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { DatasourceType, testQueryResponse } from '@superset-ui/core';
|
||||
import {
|
||||
DatasourceType,
|
||||
GenericDataType,
|
||||
testQueryResponse,
|
||||
} from '@superset-ui/core';
|
||||
import { columnChoices } from '../../src';
|
||||
|
||||
describe('columnChoices()', () => {
|
||||
@@ -31,14 +35,20 @@ describe('columnChoices()', () => {
|
||||
columns: [
|
||||
{
|
||||
column_name: 'fiz',
|
||||
type: 'INT',
|
||||
type_generic: GenericDataType.NUMERIC,
|
||||
},
|
||||
{
|
||||
column_name: 'about',
|
||||
verbose_name: 'right',
|
||||
type: 'VARCHAR',
|
||||
type_generic: GenericDataType.STRING,
|
||||
},
|
||||
{
|
||||
column_name: 'foo',
|
||||
verbose_name: 'bar',
|
||||
verbose_name: undefined,
|
||||
type: 'TIMESTAMP',
|
||||
type_generic: GenericDataType.TEMPORAL,
|
||||
},
|
||||
],
|
||||
verbose_map: {},
|
||||
@@ -48,8 +58,8 @@ describe('columnChoices()', () => {
|
||||
description: 'this is my datasource',
|
||||
}),
|
||||
).toEqual([
|
||||
['foo', 'bar'],
|
||||
['fiz', 'fiz'],
|
||||
['foo', 'foo'],
|
||||
['about', 'right'],
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -16,7 +16,11 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { testQueryResponse, testQueryResults } from '@superset-ui/core';
|
||||
import {
|
||||
GenericDataType,
|
||||
testQueryResponse,
|
||||
testQueryResults,
|
||||
} from '@superset-ui/core';
|
||||
import {
|
||||
Dataset,
|
||||
getTemporalColumns,
|
||||
@@ -55,8 +59,9 @@ test('get temporal columns from a QueryResponse', () => {
|
||||
temporalColumns: [
|
||||
{
|
||||
column_name: 'Column 2',
|
||||
type: 'TIMESTAMP',
|
||||
is_dttm: true,
|
||||
type: 'TIMESTAMP',
|
||||
type_generic: GenericDataType.TEMPORAL,
|
||||
},
|
||||
],
|
||||
defaultTemporalColumn: 'Column 2',
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
export { default as ChartClient } from './clients/ChartClient';
|
||||
export { default as ChartMetadata } from './models/ChartMetadata';
|
||||
export { default as ChartPlugin } from './models/ChartPlugin';
|
||||
export { default as ChartProps } from './models/ChartProps';
|
||||
export { default as ChartProps, ChartPropsConfig } from './models/ChartProps';
|
||||
|
||||
export { default as createLoadableRenderer } from './components/createLoadableRenderer';
|
||||
export { default as reactify } from './components/reactify';
|
||||
|
||||
@@ -67,6 +67,7 @@ function SafeMarkdown({
|
||||
rehypePlugins={rehypePlugins}
|
||||
remarkPlugins={[remarkGfm]}
|
||||
skipHtml={false}
|
||||
transformLinkUri={null}
|
||||
>
|
||||
{source}
|
||||
</ReactMarkdown>
|
||||
|
||||
@@ -31,6 +31,7 @@ import { Maybe } from '../../types';
|
||||
import { PostProcessingRule } from './PostProcessing';
|
||||
import { JsonObject } from '../../connection';
|
||||
import { TimeGranularity } from '../../time-format';
|
||||
import { GenericDataType } from './QueryResponse';
|
||||
|
||||
export type BaseQueryObjectFilterClause = {
|
||||
col: QueryFormColumn;
|
||||
@@ -250,6 +251,7 @@ export type QueryColumn = {
|
||||
name?: string;
|
||||
column_name: string;
|
||||
type: string | null;
|
||||
type_generic: GenericDataType;
|
||||
is_dttm: boolean;
|
||||
};
|
||||
|
||||
@@ -383,16 +385,19 @@ export const testQuery: Query = {
|
||||
column_name: 'Column 1',
|
||||
type: 'STRING',
|
||||
is_dttm: false,
|
||||
type_generic: GenericDataType.STRING,
|
||||
},
|
||||
{
|
||||
column_name: 'Column 3',
|
||||
type: 'STRING',
|
||||
is_dttm: false,
|
||||
type_generic: GenericDataType.STRING,
|
||||
},
|
||||
{
|
||||
column_name: 'Column 2',
|
||||
type: 'TIMESTAMP',
|
||||
is_dttm: true,
|
||||
type_generic: GenericDataType.TEMPORAL,
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -404,16 +409,19 @@ export const testQueryResults = {
|
||||
{
|
||||
column_name: 'Column 1',
|
||||
type: 'STRING',
|
||||
type_generic: GenericDataType.STRING,
|
||||
is_dttm: false,
|
||||
},
|
||||
{
|
||||
column_name: 'Column 3',
|
||||
type: 'STRING',
|
||||
type_generic: GenericDataType.STRING,
|
||||
is_dttm: false,
|
||||
},
|
||||
{
|
||||
column_name: 'Column 2',
|
||||
type: 'TIMESTAMP',
|
||||
type_generic: GenericDataType.TEMPORAL,
|
||||
is_dttm: true,
|
||||
},
|
||||
],
|
||||
@@ -425,16 +433,19 @@ export const testQueryResults = {
|
||||
{
|
||||
column_name: 'Column 1',
|
||||
type: 'STRING',
|
||||
type_generic: GenericDataType.STRING,
|
||||
is_dttm: false,
|
||||
},
|
||||
{
|
||||
column_name: 'Column 3',
|
||||
type: 'STRING',
|
||||
type_generic: GenericDataType.STRING,
|
||||
is_dttm: false,
|
||||
},
|
||||
{
|
||||
column_name: 'Column 2',
|
||||
type: 'TIMESTAMP',
|
||||
type_generic: GenericDataType.TEMPORAL,
|
||||
is_dttm: true,
|
||||
},
|
||||
],
|
||||
|
||||
@@ -22,3 +22,5 @@ export { default as legacyValidateNumber } from './legacyValidateNumber';
|
||||
export { default as validateInteger } from './validateInteger';
|
||||
export { default as validateNumber } from './validateNumber';
|
||||
export { default as validateNonEmpty } from './validateNonEmpty';
|
||||
export { default as validateMaxValue } from './validateMaxValue';
|
||||
export { default as validateMapboxStylesUrl } from './validateMapboxStylesUrl';
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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 { t } from '../translation';
|
||||
|
||||
/**
|
||||
* Validate a [Mapbox styles URL](https://docs.mapbox.com/help/glossary/style-url/)
|
||||
* @param v
|
||||
*/
|
||||
export default function validateMapboxStylesUrl(v: unknown) {
|
||||
if (
|
||||
typeof v === 'string' &&
|
||||
v.trim().length > 0 &&
|
||||
v.trim().startsWith('mapbox://styles/')
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return t('is expected to be a Mapbox URL');
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import { t } from '../translation';
|
||||
|
||||
export default function validateMaxValue(v: unknown, max: Number) {
|
||||
if (Number(v) > +max) {
|
||||
return t('Value cannot exceed %s', max);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
* 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 { validateMapboxStylesUrl } from '@superset-ui/core';
|
||||
import './setup';
|
||||
|
||||
describe('validateMapboxStylesUrl', () => {
|
||||
it('should validate mapbox style URLs', () => {
|
||||
expect(
|
||||
validateMapboxStylesUrl('mapbox://styles/mapbox/streets-v9'),
|
||||
).toEqual(false);
|
||||
expect(
|
||||
validateMapboxStylesUrl(
|
||||
'mapbox://styles/foobar/clp2dr5r4008a01pcg4ad45m8',
|
||||
),
|
||||
).toEqual(false);
|
||||
});
|
||||
|
||||
[
|
||||
123,
|
||||
['mapbox://styles/mapbox/streets-v9'],
|
||||
{ url: 'mapbox://styles/mapbox/streets-v9' },
|
||||
'https://superset.apache.org/',
|
||||
'mapbox://tileset/mapbox/streets-v9',
|
||||
].forEach(value => {
|
||||
it(`should not validate ${value}`, () => {
|
||||
expect(validateMapboxStylesUrl(value)).toEqual(
|
||||
'is expected to be a Mapbox URL',
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import { validateMaxValue } from '@superset-ui/core';
|
||||
import './setup';
|
||||
|
||||
test('validateInteger returns the warning message if invalid', () => {
|
||||
expect(validateMaxValue(10.1, 10)).toBeTruthy();
|
||||
expect(validateMaxValue(1, 0)).toBeTruthy();
|
||||
expect(validateMaxValue('2', 1)).toBeTruthy();
|
||||
});
|
||||
|
||||
test('validateInteger returns false if the input is valid', () => {
|
||||
expect(validateMaxValue(0, 1)).toBeFalsy();
|
||||
expect(validateMaxValue(10, 10)).toBeFalsy();
|
||||
expect(validateMaxValue(undefined, 1)).toBeFalsy();
|
||||
expect(validateMaxValue(NaN, NaN)).toBeFalsy();
|
||||
expect(validateMaxValue(null, 1)).toBeFalsy();
|
||||
expect(validateMaxValue('1', 1)).toBeFalsy();
|
||||
expect(validateMaxValue('a', 1)).toBeFalsy();
|
||||
});
|
||||
@@ -16,7 +16,12 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { FeatureFlag, isFeatureEnabled, t } from '@superset-ui/core';
|
||||
import {
|
||||
FeatureFlag,
|
||||
isFeatureEnabled,
|
||||
t,
|
||||
validateMapboxStylesUrl,
|
||||
} from '@superset-ui/core';
|
||||
import {
|
||||
columnChoices,
|
||||
ControlPanelConfig,
|
||||
@@ -224,6 +229,8 @@ const config: ControlPanelConfig = {
|
||||
label: t('Map Style'),
|
||||
clearable: false,
|
||||
renderTrigger: true,
|
||||
freeForm: true,
|
||||
validators: [validateMapboxStylesUrl],
|
||||
choices: [
|
||||
['mapbox://styles/mapbox/streets-v9', t('Streets')],
|
||||
['mapbox://styles/mapbox/dark-v9', t('Dark')],
|
||||
@@ -236,7 +243,10 @@ const config: ControlPanelConfig = {
|
||||
['mapbox://styles/mapbox/outdoors-v9', t('Outdoors')],
|
||||
],
|
||||
default: 'mapbox://styles/mapbox/light-v9',
|
||||
description: t('Base layer map style'),
|
||||
description: t(
|
||||
'Base layer map style. See Mapbox documentation: %s',
|
||||
'https://docs.mapbox.com/help/glossary/style-url/',
|
||||
),
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
@@ -27,7 +27,8 @@ export default {
|
||||
label: t('Map'),
|
||||
expanded: true,
|
||||
controlSetRows: [
|
||||
[mapboxStyle, viewport],
|
||||
[mapboxStyle],
|
||||
[viewport],
|
||||
[
|
||||
{
|
||||
name: 'deck_slices',
|
||||
|
||||
|
After Width: | Height: | Size: 150 KiB |
@@ -18,6 +18,7 @@
|
||||
*/
|
||||
import { t, ChartMetadata, ChartPlugin } from '@superset-ui/core';
|
||||
import thumbnail from './images/thumbnail.png';
|
||||
import example from './images/example.png';
|
||||
import transformProps from '../transformProps';
|
||||
import controlPanel from './controlPanel';
|
||||
|
||||
@@ -25,6 +26,7 @@ const metadata = new ChartMetadata({
|
||||
category: t('Map'),
|
||||
credits: ['https://uber.github.io/deck.gl'],
|
||||
description: t('Compose multiple layers together to form complex visuals.'),
|
||||
exampleGallery: [{ url: example }],
|
||||
name: t('deck.gl Multiple Layers'),
|
||||
thumbnail,
|
||||
useLegacyApi: true,
|
||||
|
||||
@@ -76,10 +76,7 @@ const config: ControlPanelConfig = {
|
||||
},
|
||||
{
|
||||
label: t('Map'),
|
||||
controlSetRows: [
|
||||
[mapboxStyle, viewport],
|
||||
[autozoom, null],
|
||||
],
|
||||
controlSetRows: [[mapboxStyle], [autozoom, viewport]],
|
||||
},
|
||||
{
|
||||
label: t('Arc'),
|
||||
|
||||
|
After Width: | Height: | Size: 70 KiB |
@@ -18,6 +18,7 @@
|
||||
*/
|
||||
import { t, ChartMetadata, ChartPlugin } from '@superset-ui/core';
|
||||
import thumbnail from './images/thumbnail.png';
|
||||
import example from './images/example.png';
|
||||
import transformProps from '../../transformProps';
|
||||
import controlPanel from './controlPanel';
|
||||
|
||||
@@ -29,6 +30,7 @@ const metadata = new ChartMetadata({
|
||||
),
|
||||
name: t('deck.gl Arc'),
|
||||
thumbnail,
|
||||
exampleGallery: [{ url: example }],
|
||||
useLegacyApi: true,
|
||||
tags: [t('deckGL'), t('Geo'), t('3D'), t('Relational'), t('Web')],
|
||||
});
|
||||
|
||||
@@ -52,8 +52,8 @@ const config: ControlPanelConfig = {
|
||||
label: t('Map'),
|
||||
expanded: true,
|
||||
controlSetRows: [
|
||||
[mapboxStyle, viewport],
|
||||
[autozoom],
|
||||
[mapboxStyle],
|
||||
[autozoom, viewport],
|
||||
[
|
||||
{
|
||||
name: 'cellSize',
|
||||
|
||||
|
After Width: | Height: | Size: 136 KiB |
@@ -20,6 +20,7 @@ import { t, ChartMetadata, ChartPlugin } from '@superset-ui/core';
|
||||
import transformProps from '../../transformProps';
|
||||
import controlPanel from './controlPanel';
|
||||
import thumbnail from './images/thumbnail.png';
|
||||
import example from './images/example.png';
|
||||
|
||||
const metadata = new ChartMetadata({
|
||||
category: t('Map'),
|
||||
@@ -27,7 +28,8 @@ const metadata = new ChartMetadata({
|
||||
description: t(
|
||||
'Uses Gaussian Kernel Density Estimation to visualize spatial distribution of data',
|
||||
),
|
||||
name: t('deck.gl Countour'),
|
||||
exampleGallery: [{ url: example }],
|
||||
name: t('deck.gl Contour'),
|
||||
thumbnail,
|
||||
useLegacyApi: true,
|
||||
tags: [t('deckGL'), t('Spatial'), t('Comparison'), t('Experimental')],
|
||||
|
||||
|
After Width: | Height: | Size: 219 KiB |
@@ -18,6 +18,7 @@
|
||||
*/
|
||||
import { t, ChartMetadata, ChartPlugin } from '@superset-ui/core';
|
||||
import thumbnail from './images/thumbnail.png';
|
||||
import example from './images/example.png';
|
||||
import transformProps from '../../transformProps';
|
||||
import controlPanel from './controlPanel';
|
||||
|
||||
@@ -27,6 +28,7 @@ const metadata = new ChartMetadata({
|
||||
description: t(
|
||||
'The GeoJsonLayer takes in GeoJSON formatted data and renders it as interactive polygons, lines and points (circles, icons and/or texts).',
|
||||
),
|
||||
exampleGallery: [{ url: example }],
|
||||
name: t('deck.gl Geojson'),
|
||||
thumbnail,
|
||||
useLegacyApi: true,
|
||||
|
||||
@@ -53,7 +53,8 @@ const config: ControlPanelConfig = {
|
||||
{
|
||||
label: t('Map'),
|
||||
controlSetRows: [
|
||||
[mapboxStyle, viewport],
|
||||
[mapboxStyle],
|
||||
[viewport],
|
||||
['color_scheme'],
|
||||
[autozoom],
|
||||
[gridSize],
|
||||
|
||||
|
After Width: | Height: | Size: 369 KiB |
@@ -18,6 +18,7 @@
|
||||
*/
|
||||
import { t, ChartMetadata, ChartPlugin } from '@superset-ui/core';
|
||||
import thumbnail from './images/thumbnail.png';
|
||||
import example from './images/example.png';
|
||||
import transformProps from '../../transformProps';
|
||||
import controlPanel from './controlPanel';
|
||||
|
||||
@@ -29,6 +30,7 @@ const metadata = new ChartMetadata({
|
||||
),
|
||||
name: t('deck.gl Grid'),
|
||||
thumbnail,
|
||||
exampleGallery: [{ url: example }],
|
||||
useLegacyApi: true,
|
||||
tags: [t('deckGL'), t('3D'), t('Comparison'), t('Experimental')],
|
||||
});
|
||||
|
||||
@@ -99,7 +99,8 @@ const config: ControlPanelConfig = {
|
||||
{
|
||||
label: t('Map'),
|
||||
controlSetRows: [
|
||||
[mapboxStyle, viewport],
|
||||
[mapboxStyle],
|
||||
[viewport],
|
||||
['linear_color_scheme'],
|
||||
[autozoom],
|
||||
[
|
||||
|
||||
|
After Width: | Height: | Size: 259 KiB |
@@ -20,6 +20,7 @@ import { t, ChartMetadata, ChartPlugin } from '@superset-ui/core';
|
||||
import transformProps from '../../transformProps';
|
||||
import controlPanel from './controlPanel';
|
||||
import thumbnail from './images/thumbnail.png';
|
||||
import example from './images/example.png';
|
||||
|
||||
const metadata = new ChartMetadata({
|
||||
category: t('Map'),
|
||||
@@ -27,6 +28,7 @@ const metadata = new ChartMetadata({
|
||||
description: t(
|
||||
'Uses Gaussian Kernel Density Estimation to visualize spatial distribution of data',
|
||||
),
|
||||
exampleGallery: [{ url: example }],
|
||||
name: t('deck.gl Heatmap'),
|
||||
thumbnail,
|
||||
useLegacyApi: true,
|
||||
|
||||
@@ -53,8 +53,8 @@ const config: ControlPanelConfig = {
|
||||
{
|
||||
label: t('Map'),
|
||||
controlSetRows: [
|
||||
[mapboxStyle, viewport],
|
||||
['color_scheme'],
|
||||
[mapboxStyle],
|
||||
['color_scheme', viewport],
|
||||
[autozoom],
|
||||
[gridSize],
|
||||
[extruded],
|
||||
|
||||
|
After Width: | Height: | Size: 262 KiB |
@@ -18,6 +18,7 @@
|
||||
*/
|
||||
import { t, ChartMetadata, ChartPlugin } from '@superset-ui/core';
|
||||
import thumbnail from './images/thumbnail.png';
|
||||
import example from './images/example.png';
|
||||
import transformProps from '../../transformProps';
|
||||
import controlPanel from './controlPanel';
|
||||
|
||||
@@ -27,6 +28,7 @@ const metadata = new ChartMetadata({
|
||||
description: t(
|
||||
'Overlays a hexagonal grid on a map, and aggregates data within the boundary of each cell.',
|
||||
),
|
||||
exampleGallery: [{ url: example }],
|
||||
name: t('deck.gl 3D Hexagon'),
|
||||
thumbnail,
|
||||
useLegacyApi: true,
|
||||
|
||||
@@ -67,7 +67,8 @@ const config: ControlPanelConfig = {
|
||||
label: t('Map'),
|
||||
expanded: true,
|
||||
controlSetRows: [
|
||||
[mapboxStyle, viewport],
|
||||
[mapboxStyle],
|
||||
[viewport],
|
||||
['color_picker'],
|
||||
[lineWidth],
|
||||
[
|
||||
|
||||
|
After Width: | Height: | Size: 165 KiB |
@@ -18,6 +18,7 @@
|
||||
*/
|
||||
import { t, ChartMetadata, ChartPlugin } from '@superset-ui/core';
|
||||
import thumbnail from './images/thumbnail.png';
|
||||
import example from './images/example.png';
|
||||
import transformProps from '../../transformProps';
|
||||
import controlPanel from './controlPanel';
|
||||
|
||||
@@ -27,6 +28,7 @@ const metadata = new ChartMetadata({
|
||||
description: t('Visualizes connected points, which form a path, on a map.'),
|
||||
name: t('deck.gl Path'),
|
||||
thumbnail,
|
||||
exampleGallery: [{ url: example }],
|
||||
useLegacyApi: true,
|
||||
tags: [t('deckGL'), t('Web')],
|
||||
});
|
||||
|
||||
|
After Width: | Height: | Size: 161 KiB |
@@ -18,6 +18,7 @@
|
||||
*/
|
||||
import { t, ChartMetadata, ChartPlugin } from '@superset-ui/core';
|
||||
import thumbnail from './images/thumbnail.png';
|
||||
import example from './images/example.png';
|
||||
import transformProps from '../../transformProps';
|
||||
import controlPanel from './controlPanel';
|
||||
|
||||
@@ -29,6 +30,7 @@ const metadata = new ChartMetadata({
|
||||
),
|
||||
name: t('deck.gl Polygon'),
|
||||
thumbnail,
|
||||
exampleGallery: [{ url: example }],
|
||||
useLegacyApi: true,
|
||||
tags: [
|
||||
t('deckGL'),
|
||||
|
||||
@@ -62,10 +62,7 @@ const config: ControlPanelConfig = {
|
||||
{
|
||||
label: t('Map'),
|
||||
expanded: true,
|
||||
controlSetRows: [
|
||||
[mapboxStyle, viewport],
|
||||
[autozoom, null],
|
||||
],
|
||||
controlSetRows: [[mapboxStyle], [autozoom, viewport]],
|
||||
},
|
||||
{
|
||||
label: t('Point Size'),
|
||||
|
||||
|
After Width: | Height: | Size: 213 KiB |
@@ -18,6 +18,7 @@
|
||||
*/
|
||||
import { t, ChartMetadata, ChartPlugin } from '@superset-ui/core';
|
||||
import thumbnail from './images/thumbnail.png';
|
||||
import example from './images/example.png';
|
||||
import transformProps from '../../transformProps';
|
||||
import controlPanel from './controlPanel';
|
||||
|
||||
@@ -29,6 +30,7 @@ const metadata = new ChartMetadata({
|
||||
),
|
||||
name: t('deck.gl Scatterplot'),
|
||||
thumbnail,
|
||||
exampleGallery: [{ url: example }],
|
||||
useLegacyApi: true,
|
||||
tags: [
|
||||
t('deckGL'),
|
||||
|
||||
@@ -52,10 +52,7 @@ const config: ControlPanelConfig = {
|
||||
},
|
||||
{
|
||||
label: t('Map'),
|
||||
controlSetRows: [
|
||||
[mapboxStyle, viewport],
|
||||
[autozoom, null],
|
||||
],
|
||||
controlSetRows: [[mapboxStyle], [autozoom, viewport]],
|
||||
},
|
||||
{
|
||||
label: t('Grid'),
|
||||
|
||||
|
After Width: | Height: | Size: 101 KiB |
@@ -18,6 +18,7 @@
|
||||
*/
|
||||
import { t, ChartMetadata, ChartPlugin } from '@superset-ui/core';
|
||||
import thumbnail from './images/thumbnail.png';
|
||||
import example from './images/example.png';
|
||||
import transformProps from '../../transformProps';
|
||||
import controlPanel from './controlPanel';
|
||||
|
||||
@@ -29,6 +30,7 @@ const metadata = new ChartMetadata({
|
||||
),
|
||||
name: t('deck.gl Screen Grid'),
|
||||
thumbnail,
|
||||
exampleGallery: [{ url: example }],
|
||||
useLegacyApi: true,
|
||||
tags: [
|
||||
t('deckGL'),
|
||||
|
||||
@@ -25,6 +25,7 @@ import {
|
||||
isFeatureEnabled,
|
||||
t,
|
||||
validateNonEmpty,
|
||||
validateMapboxStylesUrl,
|
||||
} from '@superset-ui/core';
|
||||
import { D3_FORMAT_OPTIONS, sharedControls } from '@superset-ui/chart-controls';
|
||||
import { columnChoices, PRIMARY_COLOR } from './controls';
|
||||
@@ -370,6 +371,8 @@ export const mapboxStyle = {
|
||||
label: t('Map Style'),
|
||||
clearable: false,
|
||||
renderTrigger: true,
|
||||
freeForm: true,
|
||||
validators: [validateMapboxStylesUrl],
|
||||
choices: [
|
||||
['mapbox://styles/mapbox/streets-v9', t('Streets')],
|
||||
['mapbox://styles/mapbox/dark-v9', t('Dark')],
|
||||
@@ -379,7 +382,10 @@ export const mapboxStyle = {
|
||||
['mapbox://styles/mapbox/outdoors-v9', t('Outdoors')],
|
||||
],
|
||||
default: 'mapbox://styles/mapbox/light-v9',
|
||||
description: t('Base layer map style'),
|
||||
description: t(
|
||||
'Base layer map style. See Mapbox documentation: %s',
|
||||
'https://docs.mapbox.com/help/glossary/style-url/',
|
||||
),
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
* under the License.
|
||||
*/
|
||||
import { DEFAULT_LEGEND_FORM_DATA } from '../constants';
|
||||
import { defaultXAxis } from '../defaults';
|
||||
import { EchartsBubbleFormData } from './types';
|
||||
|
||||
export const DEFAULT_FORM_DATA: Partial<EchartsBubbleFormData> = {
|
||||
@@ -26,9 +27,11 @@ export const DEFAULT_FORM_DATA: Partial<EchartsBubbleFormData> = {
|
||||
logYAxis: false,
|
||||
xAxisTitleMargin: 30,
|
||||
yAxisTitleMargin: 30,
|
||||
truncateXAxis: false,
|
||||
truncateYAxis: false,
|
||||
xAxisBounds: [null, null],
|
||||
yAxisBounds: [null, null],
|
||||
xAxisLabelRotation: 0,
|
||||
xAxisLabelRotation: defaultXAxis.xAxisLabelRotation,
|
||||
opacity: 0.6,
|
||||
};
|
||||
|
||||
|
||||
@@ -26,10 +26,15 @@ import {
|
||||
} from '@superset-ui/chart-controls';
|
||||
|
||||
import { DEFAULT_FORM_DATA } from './constants';
|
||||
import { legendSection } from '../controls';
|
||||
import {
|
||||
legendSection,
|
||||
truncateXAxis,
|
||||
xAxisBounds,
|
||||
xAxisLabelRotation,
|
||||
} from '../controls';
|
||||
import { defaultYAxis } from '../defaults';
|
||||
|
||||
const { logAxis, truncateYAxis, yAxisBounds, xAxisLabelRotation, opacity } =
|
||||
DEFAULT_FORM_DATA;
|
||||
const { logAxis, truncateYAxis, yAxisBounds, opacity } = DEFAULT_FORM_DATA;
|
||||
|
||||
const config: ControlPanelConfig = {
|
||||
controlPanelSections: [
|
||||
@@ -127,26 +132,7 @@ const config: ControlPanelConfig = {
|
||||
},
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
name: 'xAxisLabelRotation',
|
||||
config: {
|
||||
type: 'SelectControl',
|
||||
freeForm: true,
|
||||
clearable: false,
|
||||
label: t('Rotate x axis label'),
|
||||
choices: [
|
||||
[0, '0°'],
|
||||
[45, '45°'],
|
||||
],
|
||||
default: xAxisLabelRotation,
|
||||
renderTrigger: true,
|
||||
description: t(
|
||||
'Input field supports custom rotation. e.g. 30 for 30°',
|
||||
),
|
||||
},
|
||||
},
|
||||
],
|
||||
[xAxisLabelRotation],
|
||||
[
|
||||
{
|
||||
name: 'x_axis_title_margin',
|
||||
@@ -211,7 +197,7 @@ const config: ControlPanelConfig = {
|
||||
[0, '0°'],
|
||||
[45, '45°'],
|
||||
],
|
||||
default: xAxisLabelRotation,
|
||||
default: defaultYAxis.yAxisLabelRotation,
|
||||
renderTrigger: true,
|
||||
description: t(
|
||||
'Input field supports custom rotation. e.g. 30 for 30°',
|
||||
@@ -246,6 +232,8 @@ const config: ControlPanelConfig = {
|
||||
},
|
||||
},
|
||||
],
|
||||
[truncateXAxis],
|
||||
[xAxisBounds],
|
||||
[
|
||||
{
|
||||
name: 'truncateYAxis',
|
||||
|
||||
@@ -28,9 +28,9 @@ import {
|
||||
import { EchartsBubbleChartProps, EchartsBubbleFormData } from './types';
|
||||
import { DEFAULT_FORM_DATA, MINIMUM_BUBBLE_SIZE } from './constants';
|
||||
import { defaultGrid } from '../defaults';
|
||||
import { getLegendProps } from '../utils/series';
|
||||
import { getLegendProps, getMinAndMaxFromBounds } from '../utils/series';
|
||||
import { Refs } from '../types';
|
||||
import { parseYAxisBound } from '../utils/controls';
|
||||
import { parseAxisBound } from '../utils/controls';
|
||||
import { getDefaultTooltip } from '../utils/tooltip';
|
||||
import { getPadding } from '../Timeseries/transformers';
|
||||
import { convertInteger } from '../utils/convertInteger';
|
||||
@@ -84,6 +84,7 @@ export default function transformProps(chartProps: EchartsBubbleChartProps) {
|
||||
series: bubbleSeries,
|
||||
xAxisLabel: bubbleXAxisTitle,
|
||||
yAxisLabel: bubbleYAxisTitle,
|
||||
xAxisBounds,
|
||||
xAxisFormat,
|
||||
yAxisFormat,
|
||||
yAxisBounds,
|
||||
@@ -91,6 +92,7 @@ export default function transformProps(chartProps: EchartsBubbleChartProps) {
|
||||
logYAxis,
|
||||
xAxisTitleMargin,
|
||||
yAxisTitleMargin,
|
||||
truncateXAxis,
|
||||
truncateYAxis,
|
||||
xAxisLabelRotation,
|
||||
yAxisLabelRotation,
|
||||
@@ -141,7 +143,8 @@ export default function transformProps(chartProps: EchartsBubbleChartProps) {
|
||||
const yAxisFormatter = getNumberFormatter(yAxisFormat);
|
||||
const tooltipSizeFormatter = getNumberFormatter(tooltipSizeFormat);
|
||||
|
||||
const [min, max] = yAxisBounds.map(parseYAxisBound);
|
||||
const [xAxisMin, xAxisMax] = (xAxisBounds || []).map(parseAxisBound);
|
||||
const [yAxisMin, yAxisMax] = (yAxisBounds || []).map(parseAxisBound);
|
||||
|
||||
const padding = getPadding(
|
||||
showLegend,
|
||||
@@ -155,6 +158,7 @@ export default function transformProps(chartProps: EchartsBubbleChartProps) {
|
||||
convertInteger(xAxisTitleMargin),
|
||||
);
|
||||
|
||||
const xAxisType = logXAxis ? AxisType.log : AxisType.value;
|
||||
const echartOptions: EChartsCoreOption = {
|
||||
series,
|
||||
xAxis: {
|
||||
@@ -172,7 +176,8 @@ export default function transformProps(chartProps: EchartsBubbleChartProps) {
|
||||
fontWight: 'bolder',
|
||||
},
|
||||
nameGap: convertInteger(xAxisTitleMargin),
|
||||
type: logXAxis ? AxisType.log : AxisType.value,
|
||||
type: xAxisType,
|
||||
...getMinAndMaxFromBounds(xAxisType, truncateXAxis, xAxisMin, xAxisMax),
|
||||
},
|
||||
yAxis: {
|
||||
axisLabel: { formatter: yAxisFormatter },
|
||||
@@ -189,8 +194,8 @@ export default function transformProps(chartProps: EchartsBubbleChartProps) {
|
||||
fontWight: 'bolder',
|
||||
},
|
||||
nameGap: convertInteger(yAxisTitleMargin),
|
||||
min,
|
||||
max,
|
||||
min: yAxisMin,
|
||||
max: yAxisMax,
|
||||
type: logYAxis ? AxisType.log : AxisType.value,
|
||||
},
|
||||
legend: {
|
||||
|
||||
@@ -32,7 +32,14 @@ import {
|
||||
|
||||
import { DEFAULT_FORM_DATA } from './types';
|
||||
import { EchartsTimeseriesSeriesType } from '../Timeseries/types';
|
||||
import { legendSection, richTooltipSection } from '../controls';
|
||||
import {
|
||||
legendSection,
|
||||
minorTicks,
|
||||
richTooltipSection,
|
||||
truncateXAxis,
|
||||
xAxisBounds,
|
||||
xAxisLabelRotation,
|
||||
} from '../controls';
|
||||
|
||||
const {
|
||||
area,
|
||||
@@ -49,7 +56,6 @@ const {
|
||||
truncateYAxis,
|
||||
yAxisBounds,
|
||||
zoomable,
|
||||
xAxisLabelRotation,
|
||||
yAxisIndex,
|
||||
} = DEFAULT_FORM_DATA;
|
||||
|
||||
@@ -311,29 +317,11 @@ const config: ControlPanelConfig = {
|
||||
},
|
||||
},
|
||||
],
|
||||
[minorTicks],
|
||||
...legendSection,
|
||||
[<ControlSubSectionHeader>{t('X Axis')}</ControlSubSectionHeader>],
|
||||
['x_axis_time_format'],
|
||||
[
|
||||
{
|
||||
name: 'xAxisLabelRotation',
|
||||
config: {
|
||||
type: 'SelectControl',
|
||||
freeForm: true,
|
||||
clearable: false,
|
||||
label: t('Rotate x axis label'),
|
||||
choices: [
|
||||
[0, '0°'],
|
||||
[45, '45°'],
|
||||
],
|
||||
default: xAxisLabelRotation,
|
||||
renderTrigger: true,
|
||||
description: t(
|
||||
'Input field supports custom rotation. e.g. 30 for 30°',
|
||||
),
|
||||
},
|
||||
},
|
||||
],
|
||||
[xAxisLabelRotation],
|
||||
...richTooltipSection,
|
||||
// eslint-disable-next-line react/jsx-key
|
||||
[<ControlSubSectionHeader>{t('Y Axis')}</ControlSubSectionHeader>],
|
||||
@@ -349,6 +337,8 @@ const config: ControlPanelConfig = {
|
||||
},
|
||||
},
|
||||
],
|
||||
[truncateXAxis],
|
||||
[xAxisBounds],
|
||||
[
|
||||
{
|
||||
name: 'truncateYAxis',
|
||||
|
||||
@@ -20,32 +20,32 @@
|
||||
import { invert } from 'lodash';
|
||||
import {
|
||||
AnnotationLayer,
|
||||
buildCustomFormatters,
|
||||
CategoricalColorNamespace,
|
||||
CurrencyFormatter,
|
||||
ensureIsArray,
|
||||
GenericDataType,
|
||||
getCustomFormatter,
|
||||
getNumberFormatter,
|
||||
getXAxisLabel,
|
||||
isDefined,
|
||||
isEventAnnotationLayer,
|
||||
isFormulaAnnotationLayer,
|
||||
isIntervalAnnotationLayer,
|
||||
isPhysicalColumn,
|
||||
isTimeseriesAnnotationLayer,
|
||||
QueryFormData,
|
||||
QueryFormMetric,
|
||||
TimeseriesChartDataResponseResult,
|
||||
TimeseriesDataRecord,
|
||||
getXAxisLabel,
|
||||
isPhysicalColumn,
|
||||
isDefined,
|
||||
ensureIsArray,
|
||||
buildCustomFormatters,
|
||||
ValueFormatter,
|
||||
QueryFormMetric,
|
||||
getCustomFormatter,
|
||||
CurrencyFormatter,
|
||||
} from '@superset-ui/core';
|
||||
import { getOriginalSeries } from '@superset-ui/chart-controls';
|
||||
import { EChartsCoreOption, SeriesOption } from 'echarts';
|
||||
import {
|
||||
DEFAULT_FORM_DATA,
|
||||
EchartsMixedTimeseriesFormData,
|
||||
EchartsMixedTimeseriesChartTransformedProps,
|
||||
EchartsMixedTimeseriesFormData,
|
||||
EchartsMixedTimeseriesProps,
|
||||
} from './types';
|
||||
import {
|
||||
@@ -53,16 +53,17 @@ import {
|
||||
ForecastSeriesEnum,
|
||||
Refs,
|
||||
} from '../types';
|
||||
import { parseYAxisBound } from '../utils/controls';
|
||||
import { parseAxisBound } from '../utils/controls';
|
||||
import {
|
||||
getOverMaxHiddenFormatter,
|
||||
dedupSeries,
|
||||
extractDataTotalValues,
|
||||
extractSeries,
|
||||
extractShowValueIndexes,
|
||||
getAxisType,
|
||||
getColtypesMapping,
|
||||
getLegendProps,
|
||||
extractDataTotalValues,
|
||||
extractShowValueIndexes,
|
||||
getMinAndMaxFromBounds,
|
||||
getOverMaxHiddenFormatter,
|
||||
} from '../utils/series';
|
||||
import {
|
||||
extractAnnotationLabels,
|
||||
@@ -84,7 +85,7 @@ import {
|
||||
transformSeries,
|
||||
transformTimeseriesAnnotation,
|
||||
} from '../Timeseries/transformers';
|
||||
import { TIMESERIES_CONSTANTS, TIMEGRAIN_TO_TIMESTAMP } from '../constants';
|
||||
import { TIMEGRAIN_TO_TIMESTAMP, TIMESERIES_CONSTANTS } from '../constants';
|
||||
import { getDefaultTooltip } from '../utils/tooltip';
|
||||
import {
|
||||
getTooltipTimeFormatter,
|
||||
@@ -159,6 +160,7 @@ export default function transformProps(
|
||||
opacity,
|
||||
opacityB,
|
||||
minorSplitLine,
|
||||
minorTicks,
|
||||
seriesType,
|
||||
seriesTypeB,
|
||||
showLegend,
|
||||
@@ -166,6 +168,7 @@ export default function transformProps(
|
||||
showValueB,
|
||||
stack,
|
||||
stackB,
|
||||
truncateXAxis,
|
||||
truncateYAxis,
|
||||
tooltipTimeFormat,
|
||||
yAxisFormat,
|
||||
@@ -181,10 +184,12 @@ export default function transformProps(
|
||||
zoomable,
|
||||
richTooltip,
|
||||
tooltipSortByMetric,
|
||||
xAxisBounds,
|
||||
xAxisLabelRotation,
|
||||
groupby,
|
||||
groupbyB,
|
||||
xAxis: xAxisOrig,
|
||||
xAxisForceCategorical,
|
||||
xAxisTitle,
|
||||
yAxisTitle,
|
||||
xAxisTitleMargin,
|
||||
@@ -223,7 +228,7 @@ export default function transformProps(
|
||||
|
||||
const dataTypes = getColtypesMapping(queriesData[0]);
|
||||
const xAxisDataType = dataTypes?.[xAxisLabel] ?? dataTypes?.[xAxisOrig];
|
||||
const xAxisType = getAxisType(xAxisDataType);
|
||||
const xAxisType = getAxisType(stack, xAxisForceCategorical, xAxisDataType);
|
||||
const series: SeriesOption[] = [];
|
||||
const formatter = contributionMode
|
||||
? getNumberFormatter(',.0%')
|
||||
@@ -345,9 +350,10 @@ export default function transformProps(
|
||||
});
|
||||
|
||||
// yAxisBounds need to be parsed to replace incompatible values with undefined
|
||||
let [min, max] = (yAxisBounds || []).map(parseYAxisBound);
|
||||
const [xAxisMin, xAxisMax] = (xAxisBounds || []).map(parseAxisBound);
|
||||
let [yAxisMin, yAxisMax] = (yAxisBounds || []).map(parseAxisBound);
|
||||
let [minSecondary, maxSecondary] = (yAxisBoundsSecondary || []).map(
|
||||
parseYAxisBound,
|
||||
parseAxisBound,
|
||||
);
|
||||
|
||||
const array = ensureIsArray(chartProps.rawFormData?.time_compare);
|
||||
@@ -386,7 +392,7 @@ export default function transformProps(
|
||||
formatter:
|
||||
seriesType === EchartsTimeseriesSeriesType.Bar
|
||||
? getOverMaxHiddenFormatter({
|
||||
max,
|
||||
max: yAxisMax,
|
||||
formatter: seriesFormatter,
|
||||
})
|
||||
: seriesFormatter,
|
||||
@@ -447,8 +453,8 @@ export default function transformProps(
|
||||
|
||||
// default to 0-100% range when doing row-level contribution chart
|
||||
if (contributionMode === 'row' && stack) {
|
||||
if (min === undefined) min = 0;
|
||||
if (max === undefined) max = 1;
|
||||
if (yAxisMin === undefined) yAxisMin = 0;
|
||||
if (yAxisMax === undefined) yAxisMax = 1;
|
||||
if (minSecondary === undefined) minSecondary = 0;
|
||||
if (maxSecondary === undefined) maxSecondary = 1;
|
||||
}
|
||||
@@ -495,18 +501,29 @@ export default function transformProps(
|
||||
formatter: xAxisFormatter,
|
||||
rotate: xAxisLabelRotation,
|
||||
},
|
||||
minorTick: { show: minorTicks },
|
||||
minInterval:
|
||||
xAxisType === 'time' && timeGrainSqla
|
||||
? TIMEGRAIN_TO_TIMESTAMP[timeGrainSqla]
|
||||
: 0,
|
||||
...getMinAndMaxFromBounds(
|
||||
xAxisType,
|
||||
truncateXAxis,
|
||||
xAxisMin,
|
||||
xAxisMax,
|
||||
seriesType === EchartsTimeseriesSeriesType.Bar ||
|
||||
seriesTypeB === EchartsTimeseriesSeriesType.Bar
|
||||
? EchartsTimeseriesSeriesType.Bar
|
||||
: undefined,
|
||||
),
|
||||
},
|
||||
yAxis: [
|
||||
{
|
||||
...defaultYAxis,
|
||||
type: logAxis ? 'log' : 'value',
|
||||
min,
|
||||
max,
|
||||
minorTick: { show: true },
|
||||
min: yAxisMin,
|
||||
max: yAxisMax,
|
||||
minorTick: { show: minorTicks },
|
||||
minorSplitLine: { show: minorSplitLine },
|
||||
axisLabel: {
|
||||
formatter: getYAxisFormatter(
|
||||
@@ -527,7 +544,7 @@ export default function transformProps(
|
||||
type: logAxisSecondary ? 'log' : 'value',
|
||||
min: minSecondary,
|
||||
max: maxSecondary,
|
||||
minorTick: { show: true },
|
||||
minorTick: { show: minorTicks },
|
||||
splitLine: { show: false },
|
||||
minorSplitLine: { show: minorSplitLine },
|
||||
axisLabel: {
|
||||
|
||||
@@ -45,6 +45,7 @@ export type EchartsMixedTimeseriesFormData = QueryFormData & {
|
||||
annotationLayers: AnnotationLayer[];
|
||||
// shared properties
|
||||
minorSplitLine: boolean;
|
||||
minorTicks: boolean;
|
||||
logAxis: boolean;
|
||||
logAxisSecondary: boolean;
|
||||
yAxisFormat?: string;
|
||||
@@ -104,6 +105,8 @@ export const DEFAULT_FORM_DATA: EchartsMixedTimeseriesFormData = {
|
||||
yAxisFormatSecondary: TIMESERIES_DEFAULTS.yAxisFormat,
|
||||
yAxisTitleSecondary: DEFAULT_TITLE_FORM_DATA.yAxisTitle,
|
||||
tooltipTimeFormat: TIMESERIES_DEFAULTS.tooltipTimeFormat,
|
||||
xAxisBounds: TIMESERIES_DEFAULTS.xAxisBounds,
|
||||
xAxisForceCategorical: TIMESERIES_DEFAULTS.xAxisForceCategorical,
|
||||
xAxisTimeFormat: TIMESERIES_DEFAULTS.xAxisTimeFormat,
|
||||
area: TIMESERIES_DEFAULTS.area,
|
||||
areaB: TIMESERIES_DEFAULTS.area,
|
||||
|
||||
@@ -37,6 +37,10 @@ import {
|
||||
richTooltipSection,
|
||||
seriesOrderSection,
|
||||
percentageThresholdControl,
|
||||
xAxisLabelRotation,
|
||||
truncateXAxis,
|
||||
xAxisBounds,
|
||||
minorTicks,
|
||||
} from '../../controls';
|
||||
import { AreaChartStackControlOptions } from '../../constants';
|
||||
|
||||
@@ -51,7 +55,6 @@ const {
|
||||
truncateYAxis,
|
||||
yAxisBounds,
|
||||
zoomable,
|
||||
xAxisLabelRotation,
|
||||
} = DEFAULT_FORM_DATA;
|
||||
const config: ControlPanelConfig = {
|
||||
controlPanelSections: [
|
||||
@@ -167,6 +170,7 @@ const config: ControlPanelConfig = {
|
||||
},
|
||||
},
|
||||
],
|
||||
[minorTicks],
|
||||
[
|
||||
{
|
||||
name: 'zoomable',
|
||||
@@ -191,26 +195,7 @@ const config: ControlPanelConfig = {
|
||||
},
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
name: 'xAxisLabelRotation',
|
||||
config: {
|
||||
type: 'SelectControl',
|
||||
freeForm: true,
|
||||
clearable: false,
|
||||
label: t('Rotate x axis label'),
|
||||
choices: [
|
||||
[0, '0°'],
|
||||
[45, '45°'],
|
||||
],
|
||||
default: xAxisLabelRotation,
|
||||
renderTrigger: true,
|
||||
description: t(
|
||||
'Input field supports custom rotation. e.g. 30 for 30°',
|
||||
),
|
||||
},
|
||||
},
|
||||
],
|
||||
[xAxisLabelRotation],
|
||||
...richTooltipSection,
|
||||
// eslint-disable-next-line react/jsx-key
|
||||
[<ControlSubSectionHeader>{t('Y Axis')}</ControlSubSectionHeader>],
|
||||
@@ -240,6 +225,8 @@ const config: ControlPanelConfig = {
|
||||
},
|
||||
},
|
||||
],
|
||||
[truncateXAxis],
|
||||
[xAxisBounds],
|
||||
[
|
||||
{
|
||||
name: 'truncateYAxis',
|
||||
|
||||
@@ -32,9 +32,13 @@ import {
|
||||
} from '@superset-ui/chart-controls';
|
||||
import {
|
||||
legendSection,
|
||||
minorTicks,
|
||||
richTooltipSection,
|
||||
seriesOrderSection,
|
||||
showValueSection,
|
||||
truncateXAxis,
|
||||
xAxisBounds,
|
||||
xAxisLabelRotation,
|
||||
} from '../../../controls';
|
||||
|
||||
import { OrientationType } from '../../types';
|
||||
@@ -49,7 +53,6 @@ const {
|
||||
truncateYAxis,
|
||||
yAxisBounds,
|
||||
zoomable,
|
||||
xAxisLabelRotation,
|
||||
orientation,
|
||||
} = DEFAULT_FORM_DATA;
|
||||
|
||||
@@ -163,21 +166,9 @@ function createAxisControl(axis: 'x' | 'y'): ControlSetRow[] {
|
||||
],
|
||||
[
|
||||
{
|
||||
name: 'xAxisLabelRotation',
|
||||
name: xAxisLabelRotation.name,
|
||||
config: {
|
||||
type: 'SelectControl',
|
||||
freeForm: true,
|
||||
clearable: false,
|
||||
label: t('Rotate axis label'),
|
||||
choices: [
|
||||
[0, '0°'],
|
||||
[45, '45°'],
|
||||
],
|
||||
default: xAxisLabelRotation,
|
||||
renderTrigger: true,
|
||||
description: t(
|
||||
'Input field supports custom rotation. e.g. 30 for 30°',
|
||||
),
|
||||
...xAxisLabelRotation.config,
|
||||
visibility: ({ controls }: ControlPanelsContainerProps) =>
|
||||
isXAxis ? isVertical(controls) : isHorizontal(controls),
|
||||
},
|
||||
@@ -223,6 +214,8 @@ function createAxisControl(axis: 'x' | 'y'): ControlSetRow[] {
|
||||
},
|
||||
},
|
||||
],
|
||||
[truncateXAxis],
|
||||
[xAxisBounds],
|
||||
[
|
||||
{
|
||||
name: 'truncateYAxis',
|
||||
@@ -307,6 +300,7 @@ const config: ControlPanelConfig = {
|
||||
...seriesOrderSection,
|
||||
['color_scheme'],
|
||||
...showValueSection,
|
||||
[minorTicks],
|
||||
[
|
||||
{
|
||||
name: 'zoomable',
|
||||
|
||||
@@ -35,9 +35,13 @@ import {
|
||||
} from '../../constants';
|
||||
import {
|
||||
legendSection,
|
||||
minorTicks,
|
||||
richTooltipSection,
|
||||
seriesOrderSection,
|
||||
showValueSection,
|
||||
truncateXAxis,
|
||||
xAxisBounds,
|
||||
xAxisLabelRotation,
|
||||
} from '../../../controls';
|
||||
|
||||
const {
|
||||
@@ -52,7 +56,6 @@ const {
|
||||
truncateYAxis,
|
||||
yAxisBounds,
|
||||
zoomable,
|
||||
xAxisLabelRotation,
|
||||
} = DEFAULT_FORM_DATA;
|
||||
const config: ControlPanelConfig = {
|
||||
controlPanelSections: [
|
||||
@@ -167,6 +170,7 @@ const config: ControlPanelConfig = {
|
||||
},
|
||||
},
|
||||
],
|
||||
[minorTicks],
|
||||
...legendSection,
|
||||
[<ControlSubSectionHeader>{t('X Axis')}</ControlSubSectionHeader>],
|
||||
[
|
||||
@@ -179,26 +183,7 @@ const config: ControlPanelConfig = {
|
||||
},
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
name: 'xAxisLabelRotation',
|
||||
config: {
|
||||
type: 'SelectControl',
|
||||
freeForm: true,
|
||||
clearable: false,
|
||||
label: t('Rotate x axis label'),
|
||||
choices: [
|
||||
[0, '0°'],
|
||||
[45, '45°'],
|
||||
],
|
||||
default: xAxisLabelRotation,
|
||||
renderTrigger: true,
|
||||
description: t(
|
||||
'Input field supports custom rotation. e.g. 30 for 30°',
|
||||
),
|
||||
},
|
||||
},
|
||||
],
|
||||
[xAxisLabelRotation],
|
||||
...richTooltipSection,
|
||||
// eslint-disable-next-line react/jsx-key
|
||||
[<ControlSubSectionHeader>{t('Y Axis')}</ControlSubSectionHeader>],
|
||||
@@ -228,6 +213,8 @@ const config: ControlPanelConfig = {
|
||||
},
|
||||
},
|
||||
],
|
||||
[truncateXAxis],
|
||||
[xAxisBounds],
|
||||
[
|
||||
{
|
||||
name: 'truncateYAxis',
|
||||
|
||||
@@ -34,9 +34,13 @@ import {
|
||||
} from '../../constants';
|
||||
import {
|
||||
legendSection,
|
||||
minorTicks,
|
||||
richTooltipSection,
|
||||
seriesOrderSection,
|
||||
showValueSection,
|
||||
truncateXAxis,
|
||||
xAxisBounds,
|
||||
xAxisLabelRotation,
|
||||
} from '../../../controls';
|
||||
|
||||
const {
|
||||
@@ -48,7 +52,6 @@ const {
|
||||
truncateYAxis,
|
||||
yAxisBounds,
|
||||
zoomable,
|
||||
xAxisLabelRotation,
|
||||
} = DEFAULT_FORM_DATA;
|
||||
const config: ControlPanelConfig = {
|
||||
controlPanelSections: [
|
||||
@@ -109,6 +112,7 @@ const config: ControlPanelConfig = {
|
||||
},
|
||||
},
|
||||
],
|
||||
[minorTicks],
|
||||
...legendSection,
|
||||
[<ControlSubSectionHeader>{t('X Axis')}</ControlSubSectionHeader>],
|
||||
|
||||
@@ -122,26 +126,7 @@ const config: ControlPanelConfig = {
|
||||
},
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
name: 'xAxisLabelRotation',
|
||||
config: {
|
||||
type: 'SelectControl',
|
||||
freeForm: true,
|
||||
clearable: false,
|
||||
label: t('Rotate x axis label'),
|
||||
choices: [
|
||||
[0, '0°'],
|
||||
[45, '45°'],
|
||||
],
|
||||
default: xAxisLabelRotation,
|
||||
renderTrigger: true,
|
||||
description: t(
|
||||
'Input field supports custom rotation. e.g. 30 for 30°',
|
||||
),
|
||||
},
|
||||
},
|
||||
],
|
||||
[xAxisLabelRotation],
|
||||
// eslint-disable-next-line react/jsx-key
|
||||
...richTooltipSection,
|
||||
// eslint-disable-next-line react/jsx-key
|
||||
@@ -172,6 +157,8 @@ const config: ControlPanelConfig = {
|
||||
},
|
||||
},
|
||||
],
|
||||
[truncateXAxis],
|
||||
[xAxisBounds],
|
||||
[
|
||||
{
|
||||
name: 'truncateYAxis',
|
||||
|
||||
@@ -34,9 +34,13 @@ import {
|
||||
} from '../../constants';
|
||||
import {
|
||||
legendSection,
|
||||
minorTicks,
|
||||
richTooltipSection,
|
||||
seriesOrderSection,
|
||||
showValueSectionWithoutStack,
|
||||
truncateXAxis,
|
||||
xAxisBounds,
|
||||
xAxisLabelRotation,
|
||||
} from '../../../controls';
|
||||
|
||||
const {
|
||||
@@ -48,7 +52,6 @@ const {
|
||||
truncateYAxis,
|
||||
yAxisBounds,
|
||||
zoomable,
|
||||
xAxisLabelRotation,
|
||||
} = DEFAULT_FORM_DATA;
|
||||
const config: ControlPanelConfig = {
|
||||
controlPanelSections: [
|
||||
@@ -109,6 +112,7 @@ const config: ControlPanelConfig = {
|
||||
},
|
||||
},
|
||||
],
|
||||
[minorTicks],
|
||||
...legendSection,
|
||||
[<ControlSubSectionHeader>{t('X Axis')}</ControlSubSectionHeader>],
|
||||
[
|
||||
@@ -121,26 +125,7 @@ const config: ControlPanelConfig = {
|
||||
},
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
name: 'xAxisLabelRotation',
|
||||
config: {
|
||||
type: 'SelectControl',
|
||||
freeForm: true,
|
||||
clearable: false,
|
||||
label: t('Rotate x axis label'),
|
||||
choices: [
|
||||
[0, '0°'],
|
||||
[45, '45°'],
|
||||
],
|
||||
default: xAxisLabelRotation,
|
||||
renderTrigger: true,
|
||||
description: t(
|
||||
'Input field supports custom rotation. e.g. 30 for 30°',
|
||||
),
|
||||
},
|
||||
},
|
||||
],
|
||||
[xAxisLabelRotation],
|
||||
// eslint-disable-next-line react/jsx-key
|
||||
...richTooltipSection,
|
||||
// eslint-disable-next-line react/jsx-key
|
||||
@@ -172,6 +157,8 @@ const config: ControlPanelConfig = {
|
||||
},
|
||||
},
|
||||
],
|
||||
[truncateXAxis],
|
||||
[xAxisBounds],
|
||||
[
|
||||
{
|
||||
name: 'truncateYAxis',
|
||||
|
||||
@@ -32,9 +32,13 @@ import { EchartsTimeseriesSeriesType } from '../../types';
|
||||
import { DEFAULT_FORM_DATA, TIME_SERIES_DESCRIPTION_TEXT } from '../constants';
|
||||
import {
|
||||
legendSection,
|
||||
minorTicks,
|
||||
richTooltipSection,
|
||||
seriesOrderSection,
|
||||
showValueSection,
|
||||
truncateXAxis,
|
||||
xAxisBounds,
|
||||
xAxisLabelRotation,
|
||||
} from '../../controls';
|
||||
|
||||
const {
|
||||
@@ -48,7 +52,6 @@ const {
|
||||
truncateYAxis,
|
||||
yAxisBounds,
|
||||
zoomable,
|
||||
xAxisLabelRotation,
|
||||
} = DEFAULT_FORM_DATA;
|
||||
const config: ControlPanelConfig = {
|
||||
controlPanelSections: [
|
||||
@@ -161,6 +164,7 @@ const config: ControlPanelConfig = {
|
||||
},
|
||||
},
|
||||
],
|
||||
[minorTicks],
|
||||
...legendSection,
|
||||
[<ControlSubSectionHeader>{t('X Axis')}</ControlSubSectionHeader>],
|
||||
[
|
||||
@@ -173,26 +177,7 @@ const config: ControlPanelConfig = {
|
||||
},
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
name: 'xAxisLabelRotation',
|
||||
config: {
|
||||
type: 'SelectControl',
|
||||
freeForm: true,
|
||||
clearable: false,
|
||||
label: t('Rotate x axis label'),
|
||||
choices: [
|
||||
[0, '0°'],
|
||||
[45, '45°'],
|
||||
],
|
||||
default: xAxisLabelRotation,
|
||||
renderTrigger: true,
|
||||
description: t(
|
||||
'Input field supports custom rotation. e.g. 30 for 30°',
|
||||
),
|
||||
},
|
||||
},
|
||||
],
|
||||
[xAxisLabelRotation],
|
||||
...richTooltipSection,
|
||||
// eslint-disable-next-line react/jsx-key
|
||||
[<ControlSubSectionHeader>{t('Y Axis')}</ControlSubSectionHeader>],
|
||||
@@ -222,6 +207,8 @@ const config: ControlPanelConfig = {
|
||||
},
|
||||
},
|
||||
],
|
||||
[truncateXAxis],
|
||||
[xAxisBounds],
|
||||
[
|
||||
{
|
||||
name: 'truncateYAxis',
|
||||
|
||||
@@ -30,6 +30,7 @@ import {
|
||||
DEFAULT_LEGEND_FORM_DATA,
|
||||
DEFAULT_TITLE_FORM_DATA,
|
||||
} from '../constants';
|
||||
import { defaultXAxis } from '../defaults';
|
||||
|
||||
// @ts-ignore
|
||||
export const DEFAULT_FORM_DATA: EchartsTimeseriesFormData = {
|
||||
@@ -57,11 +58,13 @@ export const DEFAULT_FORM_DATA: EchartsTimeseriesFormData = {
|
||||
seriesType: EchartsTimeseriesSeriesType.Line,
|
||||
stack: false,
|
||||
tooltipTimeFormat: 'smart_date',
|
||||
truncateXAxis: true,
|
||||
truncateYAxis: false,
|
||||
yAxisBounds: [null, null],
|
||||
zoomable: false,
|
||||
richTooltip: true,
|
||||
xAxisLabelRotation: 0,
|
||||
xAxisForceCategorical: false,
|
||||
xAxisLabelRotation: defaultXAxis.xAxisLabelRotation,
|
||||
groupby: [],
|
||||
showValue: false,
|
||||
onlyTotal: false,
|
||||
|
||||
@@ -54,7 +54,7 @@ import {
|
||||
} from './types';
|
||||
import { DEFAULT_FORM_DATA } from './constants';
|
||||
import { ForecastSeriesEnum, ForecastValue, Refs } from '../types';
|
||||
import { parseYAxisBound } from '../utils/controls';
|
||||
import { parseAxisBound } from '../utils/controls';
|
||||
import {
|
||||
calculateLowerLogTick,
|
||||
dedupSeries,
|
||||
@@ -64,6 +64,7 @@ import {
|
||||
getAxisType,
|
||||
getColtypesMapping,
|
||||
getLegendProps,
|
||||
getMinAndMaxFromBounds,
|
||||
} from '../utils/series';
|
||||
import {
|
||||
extractAnnotationLabels,
|
||||
@@ -145,6 +146,7 @@ export default function transformProps(
|
||||
markerSize,
|
||||
metrics,
|
||||
minorSplitLine,
|
||||
minorTicks,
|
||||
onlyTotal,
|
||||
opacity,
|
||||
orientation,
|
||||
@@ -161,8 +163,11 @@ export default function transformProps(
|
||||
stack,
|
||||
tooltipTimeFormat,
|
||||
tooltipSortByMetric,
|
||||
truncateXAxis,
|
||||
truncateYAxis,
|
||||
xAxis: xAxisOrig,
|
||||
xAxisBounds,
|
||||
xAxisForceCategorical,
|
||||
xAxisLabelRotation,
|
||||
xAxisSortSeries,
|
||||
xAxisSortSeriesAscending,
|
||||
@@ -244,7 +249,7 @@ export default function transformProps(
|
||||
const isAreaExpand = stack === StackControlsValue.Expand;
|
||||
const xAxisDataType = dataTypes?.[xAxisLabel] ?? dataTypes?.[xAxisOrig];
|
||||
|
||||
const xAxisType = getAxisType(xAxisDataType);
|
||||
const xAxisType = getAxisType(stack, xAxisForceCategorical, xAxisDataType);
|
||||
const series: SeriesOption[] = [];
|
||||
|
||||
const forcePercentFormatter = Boolean(contributionMode || isAreaExpand);
|
||||
@@ -388,15 +393,20 @@ export default function transformProps(
|
||||
}
|
||||
});
|
||||
|
||||
// yAxisBounds need to be parsed to replace incompatible values with undefined
|
||||
let [min, max] = (yAxisBounds || []).map(parseYAxisBound);
|
||||
// axis bounds need to be parsed to replace incompatible values with undefined
|
||||
const [xAxisMin, xAxisMax] = (xAxisBounds || []).map(parseAxisBound);
|
||||
let [yAxisMin, yAxisMax] = (yAxisBounds || []).map(parseAxisBound);
|
||||
|
||||
// default to 0-100% range when doing row-level contribution chart
|
||||
if ((contributionMode === 'row' || isAreaExpand) && stack) {
|
||||
if (min === undefined) min = 0;
|
||||
if (max === undefined) max = 1;
|
||||
} else if (logAxis && min === undefined && minPositiveValue !== undefined) {
|
||||
min = calculateLowerLogTick(minPositiveValue);
|
||||
if (yAxisMin === undefined) yAxisMin = 0;
|
||||
if (yAxisMax === undefined) yAxisMax = 1;
|
||||
} else if (
|
||||
logAxis &&
|
||||
yAxisMin === undefined &&
|
||||
minPositiveValue !== undefined
|
||||
) {
|
||||
yAxisMin = calculateLowerLogTick(minPositiveValue);
|
||||
}
|
||||
|
||||
const tooltipFormatter =
|
||||
@@ -448,17 +458,26 @@ export default function transformProps(
|
||||
formatter: xAxisFormatter,
|
||||
rotate: xAxisLabelRotation,
|
||||
},
|
||||
minorTick: { show: minorTicks },
|
||||
minInterval:
|
||||
xAxisType === AxisType.time && timeGrainSqla
|
||||
? TIMEGRAIN_TO_TIMESTAMP[timeGrainSqla]
|
||||
: 0,
|
||||
...getMinAndMaxFromBounds(
|
||||
xAxisType,
|
||||
truncateXAxis,
|
||||
xAxisMin,
|
||||
xAxisMax,
|
||||
seriesType,
|
||||
),
|
||||
};
|
||||
|
||||
let yAxis: any = {
|
||||
...defaultYAxis,
|
||||
type: logAxis ? AxisType.log : AxisType.value,
|
||||
min,
|
||||
max,
|
||||
minorTick: { show: true },
|
||||
min: yAxisMin,
|
||||
max: yAxisMax,
|
||||
minorTick: { show: minorTicks },
|
||||
minorSplitLine: { show: minorSplitLine },
|
||||
axisLabel: {
|
||||
formatter: getYAxisFormatter(
|
||||
|
||||
@@ -68,6 +68,7 @@ export type EchartsTimeseriesFormData = QueryFormData & {
|
||||
markerSize: number;
|
||||
metrics: QueryFormMetric[];
|
||||
minorSplitLine: boolean;
|
||||
minorTicks: boolean;
|
||||
opacity: number;
|
||||
orderDesc: boolean;
|
||||
rowLimit: number;
|
||||
@@ -75,10 +76,13 @@ export type EchartsTimeseriesFormData = QueryFormData & {
|
||||
stack: StackType;
|
||||
timeCompare?: string[];
|
||||
tooltipTimeFormat?: string;
|
||||
truncateXAxis: boolean;
|
||||
truncateYAxis: boolean;
|
||||
yAxisFormat?: string;
|
||||
xAxisForceCategorical?: boolean;
|
||||
xAxisTimeFormat?: string;
|
||||
timeGrainSqla?: TimeGranularity;
|
||||
xAxisBounds: [number | undefined | null, number | undefined | null];
|
||||
yAxisBounds: [number | undefined | null, number | undefined | null];
|
||||
zoomable: boolean;
|
||||
richTooltip: boolean;
|
||||
|
||||
@@ -19,15 +19,14 @@
|
||||
import {
|
||||
buildQueryContext,
|
||||
ensureIsArray,
|
||||
getXAxisColumn,
|
||||
isXAxisSet,
|
||||
QueryFormData,
|
||||
} from '@superset-ui/core';
|
||||
|
||||
export default function buildQuery(formData: QueryFormData) {
|
||||
const { x_axis, granularity_sqla, groupby } = formData;
|
||||
const columns = [
|
||||
...(isXAxisSet(formData) ? ensureIsArray(getXAxisColumn(formData)) : []),
|
||||
...ensureIsArray(formData.groupby),
|
||||
...ensureIsArray(x_axis || granularity_sqla),
|
||||
...ensureIsArray(groupby),
|
||||
];
|
||||
return buildQueryContext(formData, baseQueryObject => [
|
||||
{
|
||||
|
||||
@@ -17,25 +17,27 @@
|
||||
* under the License.
|
||||
*/
|
||||
import React from 'react';
|
||||
import { t } from '@superset-ui/core';
|
||||
import { hasGenericChartAxes, t } from '@superset-ui/core';
|
||||
import {
|
||||
ControlPanelConfig,
|
||||
ControlSubSectionHeader,
|
||||
D3_TIME_FORMAT_DOCS,
|
||||
DEFAULT_TIME_FORMAT,
|
||||
formatSelectOptions,
|
||||
sections,
|
||||
sharedControls,
|
||||
} from '@superset-ui/chart-controls';
|
||||
import { showValueControl } from '../controls';
|
||||
|
||||
const config: ControlPanelConfig = {
|
||||
controlPanelSections: [
|
||||
sections.genericTime,
|
||||
{
|
||||
label: t('Query'),
|
||||
expanded: true,
|
||||
controlSetRows: [
|
||||
['x_axis'],
|
||||
['time_grain_sqla'],
|
||||
[hasGenericChartAxes ? 'x_axis' : null],
|
||||
[hasGenericChartAxes ? 'time_grain_sqla' : null],
|
||||
['groupby'],
|
||||
['metric'],
|
||||
['adhoc_filters'],
|
||||
|
||||
@@ -61,7 +61,7 @@ export default class EchartsWaterfallChartPlugin extends ChartPlugin<
|
||||
{ url: example3 },
|
||||
],
|
||||
name: t('Waterfall Chart'),
|
||||
tags: [t('Categorical'), t('Comparison'), t('ECharts')],
|
||||
tags: [t('Categorical'), t('Comparison'), t('ECharts'), t('Popular')],
|
||||
thumbnail,
|
||||
}),
|
||||
transformProps,
|
||||
|
||||
@@ -185,6 +185,7 @@ export default function transformProps(
|
||||
const { setDataMask = () => {}, onContextMenu, onLegendStateChanged } = hooks;
|
||||
const {
|
||||
currencyFormat,
|
||||
granularitySqla = '',
|
||||
groupby,
|
||||
increaseColor,
|
||||
decreaseColor,
|
||||
@@ -213,7 +214,10 @@ export default function transformProps(
|
||||
const breakdownName = isAdhocColumn(breakdownColumn)
|
||||
? breakdownColumn.label!
|
||||
: breakdownColumn;
|
||||
const xAxisName = isAdhocColumn(xAxis) ? xAxis.label! : xAxis;
|
||||
const xAxisColumn = xAxis || granularitySqla;
|
||||
const xAxisName = isAdhocColumn(xAxisColumn)
|
||||
? xAxisColumn.label!
|
||||
: xAxisColumn;
|
||||
const metricLabel = getMetricLabel(metric);
|
||||
|
||||
const transformedData = transformer({
|
||||
|
||||
@@ -29,6 +29,7 @@ import {
|
||||
} from '@superset-ui/chart-controls';
|
||||
import { DEFAULT_LEGEND_FORM_DATA, StackControlOptions } from './constants';
|
||||
import { DEFAULT_FORM_DATA } from './Timeseries/constants';
|
||||
import { defaultXAxis } from './defaults';
|
||||
|
||||
const { legendMargin, legendOrientation, legendType, showLegend } =
|
||||
DEFAULT_LEGEND_FORM_DATA;
|
||||
@@ -243,8 +244,79 @@ const sortSeriesAscending: ControlSetItem = {
|
||||
},
|
||||
};
|
||||
|
||||
export const xAxisLabelRotation = {
|
||||
name: 'xAxisLabelRotation',
|
||||
config: {
|
||||
type: 'SelectControl',
|
||||
freeForm: true,
|
||||
clearable: false,
|
||||
label: t('Rotate x axis label'),
|
||||
choices: [
|
||||
[0, '0°'],
|
||||
[45, '45°'],
|
||||
[90, '90°'],
|
||||
],
|
||||
default: defaultXAxis.xAxisLabelRotation,
|
||||
renderTrigger: true,
|
||||
description: t('Input field supports custom rotation. e.g. 30 for 30°'),
|
||||
},
|
||||
};
|
||||
|
||||
export const seriesOrderSection: ControlSetRow[] = [
|
||||
[<ControlSubSectionHeader>{t('Series Order')}</ControlSubSectionHeader>],
|
||||
[sortSeriesType],
|
||||
[sortSeriesAscending],
|
||||
];
|
||||
|
||||
export const truncateXAxis: ControlSetItem = {
|
||||
name: 'truncateXAxis',
|
||||
config: {
|
||||
type: 'CheckboxControl',
|
||||
label: t('Truncate X Axis'),
|
||||
default: DEFAULT_FORM_DATA.truncateXAxis,
|
||||
renderTrigger: true,
|
||||
description: t(
|
||||
'Truncate X Axis. Can be overridden by specifying a min or max bound. Only applicable for numercal X axis.',
|
||||
),
|
||||
},
|
||||
};
|
||||
|
||||
export const xAxisBounds: ControlSetItem = {
|
||||
name: 'xAxisBounds',
|
||||
config: {
|
||||
type: 'BoundsControl',
|
||||
label: t('X Axis Bounds'),
|
||||
renderTrigger: true,
|
||||
default: DEFAULT_FORM_DATA.xAxisBounds,
|
||||
description: t(
|
||||
'Bounds for numerical X axis. Not applicable for temporal or categorical axes. ' +
|
||||
'When left empty, the bounds are dynamically defined based on the min/max of the data. ' +
|
||||
"Note that this feature will only expand the axis range. It won't " +
|
||||
"narrow the data's extent.",
|
||||
),
|
||||
visibility: ({ controls }: ControlPanelsContainerProps) =>
|
||||
Boolean(controls?.truncateXAxis?.value),
|
||||
},
|
||||
};
|
||||
|
||||
export const minorTicks: ControlSetItem = {
|
||||
name: 'minorTicks',
|
||||
config: {
|
||||
type: 'CheckboxControl',
|
||||
label: t('Minor ticks'),
|
||||
default: false,
|
||||
renderTrigger: true,
|
||||
description: t('Show minor ticks on axes.'),
|
||||
},
|
||||
};
|
||||
|
||||
export const forceCategorical: ControlSetItem = {
|
||||
name: 'forceCategorical',
|
||||
config: {
|
||||
type: 'CheckboxControl',
|
||||
label: t('Force categorical'),
|
||||
default: false,
|
||||
renderTrigger: true,
|
||||
description: t('Make the x-axis categorical'),
|
||||
},
|
||||
};
|
||||
|
||||
@@ -24,6 +24,11 @@ export const defaultGrid = {
|
||||
|
||||
export const defaultYAxis = {
|
||||
scale: true,
|
||||
yAxisLabelRotation: 0,
|
||||
};
|
||||
|
||||
export const defaultXAxis = {
|
||||
xAxisLabelRotation: 0,
|
||||
};
|
||||
|
||||
export const defaultLegendPadding = {
|
||||
|
||||