Merge branch 'master' into fix_calendar_heatmap

This commit is contained in:
Mattc1221 2023-12-10 13:40:32 -06:00
commit 12856bbfba
644 changed files with 8139 additions and 6177 deletions

View File

@ -8,5 +8,5 @@ contact_links:
url: https://github.com/apache/superset/discussions/new?category=q-a-help
about: Open a community Q&A thread on GitHub Discussions
- name: Slack
url: bit.ly/join-superset-slack
about: Join the Superset Community on Slack for other discussions/assistance
url: https://bit.ly/join-superset-slack
about: Join the Superset Community on Slack for other discussions and assistance

View File

@ -1,13 +1,13 @@
---
name: SIP
about: "Superset Improvement Proposal. See https://github.com/apache/superset/issues/5602 for details. The purpose of a Superset Improvement Proposal (SIP) is to introduce any major change into Apache Superset, such as a major new feature, subsystem, or piece of functionality, or any change that impacts the public interfaces of the project"
about: "Superset Improvement Proposal. See SIP-0 (https://github.com/apache/superset/issues/5602) for details. A SIP introduces any major change into Apache Superset's code or process."
labels: sip
title: "[SIP] Your Title Here (do not add SIP number)"
assignees: "apache/superset-committers"
---
*Please make sure you are familiar with the SIP process documented*
(here)[https://github.com/apache/superset/issues/5602]. The SIP will be numbered by a committer upon acceptance.
[here](https://github.com/apache/superset/issues/5602). The SIP will be numbered by a committer upon acceptance.
## [SIP] Proposal for ...<title>

4
.github/SECURITY.md vendored
View File

@ -12,8 +12,8 @@ Apache Software Foundation takes a rigorous standpoint in annihilating the secur
in its software projects. Apache Superset is highly sensitive and forthcoming to issues
pertaining to its features and functionality.
If you have any concern or believe you have found a vulnerability in Apache Superset,
please get in touch with the Apache Security Team privately at
e-mail address [security@apache.org](mailto:security@apache.org).
please get in touch with the Apache Superset Security Team privately at
e-mail address [security@superset.apache.org](mailto:security@superset.apache.org).
More details can be found on the ASF website at
[ASF vulnerability reporting process](https://apache.org/security/#reporting-a-vulnerability)

View File

@ -19,8 +19,10 @@ under the License.
## Change Log
- [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.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)
@ -32,6 +34,59 @@ under the License.
- [1.4.2](#142-sat-mar-19-000806-2022-0200)
- [1.4.1](#141)
### 3.0.2 (Mon Nov 20 07:38:38 2023 -0500)
**Fixes**
- [#26037](https://github.com/apache/superset/pull/26037) fix: update FAB to 4.3.10, Azure user info fix (@dpgaspar)
- [#25901](https://github.com/apache/superset/pull/25901) fix(native filters): rendering performance improvement by reduce overrendering (@justinpark)
- [#25985](https://github.com/apache/superset/pull/25985) fix(explore): redandant force param (@justinpark)
- [#25993](https://github.com/apache/superset/pull/25993) fix: Make Select component fire onChange listener when a selection is pasted in (@jfrag1)
- [#25997](https://github.com/apache/superset/pull/25997) fix(rls): Update text from tables to datasets in RLS modal (@yousoph)
- [#25703](https://github.com/apache/superset/pull/25703) fix(helm): Restart all related deployments when bootstrap script changed (@josedev-union)
- [#25973](https://github.com/apache/superset/pull/25973) fix: naming denomalized to denormalized in helpers.py (@hughhhh)
- [#25919](https://github.com/apache/superset/pull/25919) fix: always denorm column value before querying values (@hughhhh)
- [#25947](https://github.com/apache/superset/pull/25947) fix: update flask-caching to avoid breaking redis cache, solves #25339 (@ggbaro)
- [#25903](https://github.com/apache/superset/pull/25903) fix(sqllab): invalid sanitization on comparison symbol (@justinpark)
- [#25857](https://github.com/apache/superset/pull/25857) fix(table): Double percenting ad-hoc percentage metrics (@john-bodley)
- [#25872](https://github.com/apache/superset/pull/25872) fix(trino): allow impersonate_user flag to be imported (@FGrobelny)
- [#25897](https://github.com/apache/superset/pull/25897) fix: trino cursor (@betodealmeida)
- [#25898](https://github.com/apache/superset/pull/25898) fix: database version field (@betodealmeida)
- [#25877](https://github.com/apache/superset/pull/25877) fix: Saving Mixed Chart with dashboard filter applied breaks adhoc_filter_b (@kgabryje)
- [#25842](https://github.com/apache/superset/pull/25842) fix(charts): Time grain is None when dataset uses Jinja (@Antonio-RiveroMartnez)
- [#25843](https://github.com/apache/superset/pull/25843) fix: remove `update_charts_owners` (@betodealmeida)
- [#25707](https://github.com/apache/superset/pull/25707) fix(table chart): Show Cell Bars correctly #25625 (@SA-Ark)
- [#25429](https://github.com/apache/superset/pull/25429) fix: the temporal x-axis results in a none time_range. (@mapledan)
- [#25853](https://github.com/apache/superset/pull/25853) fix: Fires onChange when clearing all values of single select (@michael-s-molina)
- [#25814](https://github.com/apache/superset/pull/25814) fix(sqllab): infinite fetching status after results are landed (@justinpark)
- [#25768](https://github.com/apache/superset/pull/25768) fix(SQL field in edit dataset modal): display full sql query (@rtexelm)
- [#25804](https://github.com/apache/superset/pull/25804) fix: Resolve issue #24195 (@john-bodley)
- [#25801](https://github.com/apache/superset/pull/25801) fix: Revert "fix: Apply normalization to all dttm columns (#25147)" (@john-bodley)
- [#25779](https://github.com/apache/superset/pull/25779) fix: DB-specific quoting in Jinja macro (@betodealmeida)
- [#25640](https://github.com/apache/superset/pull/25640) fix: allow for backward compatible errors (@eschutho)
- [#25741](https://github.com/apache/superset/pull/25741) fix(sqllab): slow pop datasource query (@justinpark)
- [#25756](https://github.com/apache/superset/pull/25756) fix: dataset update uniqueness (@betodealmeida)
- [#25753](https://github.com/apache/superset/pull/25753) fix: Revert "fix(Charts): Set max row limit + removed the option to use an empty row limit value" (@geido)
- [#25732](https://github.com/apache/superset/pull/25732) fix(horizontal filter label): show full tooltip with ellipsis (@rtexelm)
- [#25712](https://github.com/apache/superset/pull/25712) fix: bump to FAB 4.3.9 remove CSP exception (@dpgaspar)
- [#24709](https://github.com/apache/superset/pull/24709) fix(chore): dashboard requests to database equal the number of slices it has (@Always-prog)
- [#25679](https://github.com/apache/superset/pull/25679) fix: remove unnecessary redirect (@Khrol)
- [#25680](https://github.com/apache/superset/pull/25680) fix(sqllab): reinstate "Force trino client async execution" (@giftig)
- [#25657](https://github.com/apache/superset/pull/25657) fix(dremio): Fixes issue with Dremio SQL generation for Charts with Series Limit (@OskarNS)
- [#23638](https://github.com/apache/superset/pull/23638) fix: warning of nth-child (@justinpark)
- [#25658](https://github.com/apache/superset/pull/25658) fix: improve upload ZIP file validation (@dpgaspar)
- [#25495](https://github.com/apache/superset/pull/25495) fix(header navlinks): link navlinks to path prefix (@fisjac)
- [#25112](https://github.com/apache/superset/pull/25112) fix: permalink save/overwrites in explore (@hughhhh)
- [#25493](https://github.com/apache/superset/pull/25493) fix(import): Make sure query context is overwritten for overwriting imports (@jfrag1)
- [#25553](https://github.com/apache/superset/pull/25553) fix: avoid 500 errors with SQLLAB_BACKEND_PERSISTENCE (@Khrol)
- [#25626](https://github.com/apache/superset/pull/25626) fix(sqllab): template validation error within comments (@justinpark)
- [#25523](https://github.com/apache/superset/pull/25523) fix(sqllab): Mistitled for new tab after rename (@justinpark)
**Others**
- [#25995](https://github.com/apache/superset/pull/25995) chore: Optimize fetching samples logic (@john-bodley)
- [#23619](https://github.com/apache/superset/pull/23619) chore(colors): Updating Airbnb brand colors (@john-bodley)
### 3.0.1 (Tue Oct 13 10:32:21 2023 -0700)
**Database Migrations**
@ -849,6 +904,24 @@ 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.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**

View File

@ -180,6 +180,51 @@ See [Translating](#translating) for more details.
There is a dedicated [`apache-superset` tag](https://stackoverflow.com/questions/tagged/apache-superset) on [StackOverflow](https://stackoverflow.com/). Please use it when asking questions.
## Types of Contributors
Following the project governance model of the Apache Software Foundation (ASF), Apache Superset has a specific set of contributor roles:
### PMC Member
A Project Management Committee (PMC) member is a person who has been elected by the PMC to help manage the project. PMC members are responsible for the overall health of the project, including community development, release management, and project governance. PMC members are also responsible for the technical direction of the project.
For more information about Apache Project PMCs, please refer to https://www.apache.org/foundation/governance/pmcs.html
### Committer
A committer is a person who has been elected by the PMC to have write access (commit access) to the code repository. They can modify the code, documentation, and website and accept contributions from others.
The official list of committers and PMC members can be found [here](https://projects.apache.org/committee.html?superset).
### Contributor
A contributor is a person who has contributed to the project in any way, including but not limited to code, tests, documentation, issues, and discussions.
> You can also review the Superset project's guidelines for PMC member promotion here: https://github.com/apache/superset/wiki/Guidelines-for-promoting-Superset-Committers-to-the-Superset-PMC
### Security Team
The security team is a selected subset of PMC members, committers and non-committers who are responsible for handling security issues.
New members of the security team are selected by the PMC members in a vote. You can request to be added to the team by sending a message to private@superset.apache.org. However, the team should be small and focused on solving security issues, so the requests will be evaluated on a case-by-case basis and the team size will be kept relatively small, limited to only actively security-focused contributors.
This security team must follow the [ASF vulnerability handling process](https://apache.org/security/committers.html#asf-project-security-for-committers).
Each new security issue is tracked as a JIRA ticket on the [ASF's JIRA Superset security project](https://issues.apache.org/jira/secure/RapidBoard.jspa?rapidView=588&projectKey=SUPERSETSEC)
Security team members must:
- Have an [ICLA](https://www.apache.org/licenses/contributor-agreements.html) signed with Apache Software Foundation.
- Not reveal information about pending and unfixed security issues to anyone (including their employers) unless specifically authorised by the security team members, e.g., if the security team agrees that diagnosing and solving an issue requires the involvement of external experts.
A release manager, the contributor overseeing the release of a specific version of Apache Superset, is by default a member of the security team. However, they are not expected to be active in assessing, discussing, and fixing security issues.
Security team members should also follow these general expectations:
- Actively participate in assessing, discussing, fixing, and releasing security issues in Superset.
- Avoid discussing security fixes in public forums. Pull request (PR) descriptions should not contain any information about security issues. The corresponding JIRA ticket should contain a link to the PR.
- Security team members who contribute to a fix may be listed as remediation developers in the CVE report, along with their job affiliation (if they choose to include it).
## Pull Request Guidelines
A philosophy we would like to strongly encourage is
@ -424,7 +469,7 @@ Commits to `master` trigger a rebuild and redeploy of the documentation site. Su
Make sure your machine meets the [OS dependencies](https://superset.apache.org/docs/installation/installing-superset-from-scratch#os-dependencies) before following these steps.
You also need to install MySQL or [MariaDB](https://mariadb.com/downloads).
Ensure that you are using Python version 3.8, 3.9, 3.10 or 3.11, then proceed with:
Ensure that you are using Python version 3.9, 3.10 or 3.11, then proceed with:
```bash
# Create a virtual environment and activate it (recommended)
@ -610,6 +655,31 @@ Then put this:
export NODE_OPTIONS=--no-experimental-fetch
```
If while using the above commands you encounter an error related to the limit of file watchers:
```bash
Error: ENOSPC: System limit for number of file watchers reached
```
The error is thrown because the number of files monitored by the system has reached the limit.
You can address this this error by increasing the number of inotify watchers.
The current value of max watches can be checked with:
```bash
cat /proc/sys/fs/inotify/max_user_watches
```
Edit the file /etc/sysctl.conf to increase this value.
The value needs to be decided based on the system memory [(see this StackOverflow answer for more context)](https://stackoverflow.com/questions/535768/what-is-a-reasonable-amount-of-inotify-watches-with-linux).
Open the file in editor and add a line at the bottom specifying the max watches values.
```bash
fs.inotify.max_user_watches=524288
```
Save the file and exit editor.
To confirm that the change succeeded, run the following command to load the updated value of max_user_watches from sysctl.conf:
```bash
sudo sysctl -p
```
#### Webpack dev server
The dev server by default starts at `http://localhost:9000` and proxies the backend requests to `http://localhost:8088`.

View File

@ -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 \

View File

@ -130,6 +130,7 @@ Here are some of the major database solutions that are supported:
<img src="superset-frontend/src/assets/images/yugabyte.png" alt="yugabyte" border="0" width="200" height="80"/>
<img src="superset-frontend/src/assets/images/databend.png" alt="databend" border="0" width="200" height="80"/>
<img src="superset-frontend/src/assets/images/starrocks.png" alt="starrocks" border="0" width="200" height="80"/>
<img src="superset-frontend/src/assets/images/doris.png" alt="doris" border="0" width="200" height="80"/>
</p>
**A more comprehensive list of supported databases** along with the configuration instructions can be found [here](https://superset.apache.org/docs/databases/installing-database-drivers).

View File

@ -30,6 +30,7 @@ partaking in the process should join the channel.
## Release notes for recent releases
- [3.1](release-notes-3-1/README.md)
- [2.0](release-notes-2-0/README.md)
- [1.5](release-notes-1-5/README.md)
- [1.4](release-notes-1-4/README.md)

View File

@ -35,6 +35,12 @@ The PyPI package:
https://pypi.org/project/apache-superset/
The Change Log for the release:
https://github.com/apache/{{ project_module }}/blob/{{ version }}/CHANGELOG.md
The Updating instructions for the release:
https://github.com/apache/{{ project_module }}/blob/{{ version }}/UPDATING.md
If you have any usage questions or have problems when upgrading or
find any issues with enhancements included in this release, please
don't hesitate to let us know by sending feedback to this mailing

View File

@ -0,0 +1,166 @@
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
# Release Notes for Superset 3.1.0
Superset 3.1.0 brings a range of new features and quality of life improvements. This release is a minor version, meaning it doesn't include any breaking changes to ensure a seamless transition for our users. Here are some of the highlights of this release.
### Waterfall chart
The new [Waterfall chart](https://github.com/apache/superset/pull/25557) visualization provides a visual representation of how a value changes over time or across different categories. They are very helpful to show the cumulative effect of positive and negative changes from a starting value. Superset's Waterfall chart supports Breakdowns which can be used to analyze the contribution of different dimensions or factors to a specific metric. By breaking down the data into various categories or dimensions, you can identify the individual components that contribute to the overall variation or change in the metric.
The chart example below displays the total sales grouped by year and broken down by product line.
![Waterfall](media/waterfall_chart.png)
### Bubble Chart ECharts version
The new ECharts [Bubble chart](https://github.com/apache/superset/pull/22107) offers feature parity with the previous NVD3 version which should be removed in the next major release. This work is part of the [ECharts migration effort](https://github.com/apache/superset/issues/10418) to increase consistency and quality of our plugins. We'll add a migration to the new plugin soon which you'll be able to execute using the new CLI command.
![Bubble](media/bubble_chart.png)
### Improved Dataset selectors
The [dataset selectors](https://github.com/apache/superset/pull/25569) have been improved to also display the database and schema names which will help users locate the correct dataset, particularly when there are multiple tables/datasets with the same name that could benefit from disambiguation.
![Dataset](media/dataset_selector.png)
### SQL Lab improvements
SQL Lab received many user experience and performance improvements in this release. Well continue to improve the capabilities of SQL Lab with feedback from the community.
Now users can [automatically format](https://github.com/apache/superset/pull/25344) their SQL queries using the `Ctrl+Shift+F` shortcut or the Format SQL menu option available in the SQL configuration panel. Another improvement is that the results panel now shows the [executed query](https://github.com/apache/superset/pull/24787) which is very helpful when your SQL Lab editor has multiple queries.
![SQL Formatting](media/sql_formatting.png)
In the SQL panel configurations, there's a menu option to show the [keyboard shortcuts](https://github.com/apache/superset/pull/25542) a user has access to.
![Keyboard Shortcuts](media/keyboard_shortcuts.png)
SQL Lab has launched a non-blocking persistence mode, as outlined in [SIP-93](https://github.com/apache/superset/issues/21385). This enhancement ensures that your SQL editor content is preserved, even if your internet or service goes offline. Moreover, it improves user interaction by saving changes in a non-blocking way, similar to how Google Docs does.
Finally, the [SQL Lab module was moved to the Single Page Application](https://github.com/apache/superset/pull/25151) context. This means that both navigation and loading time of that module is significantly faster than previous versions (particularly when navigating to and from this page from other pages in Superset). This also reduces the number of requests to the server and pays some of our technical debt. Try it out! The difference is quite impressive!
### Country Map improvements
The Country Map visualization received some improvements in this release. The community added [France's regions](https://github.com/apache/superset/pull/25676) in addition to its departments and also many [Central Asia countries](https://github.com/apache/superset/pull/24870).
<table>
<tr>
<td width="33%">France's regions</td>
<td width="33%">Kazakhstan</td>
<td width="33%">Kyrgyzstan</td>
</tr>
<tr>
<td width="33%"><img src="media/france.png" width="100%"/></td>
<td width="33%"><img src="media/kazakhstan.png" width="100%"></td>
<td width="33%"><img src="media/kyrgyzstan.png" width="100%"></td>
</tr>
<tr>
<td width="33%">Tajikistan</td>
<td width="33%">Turkmenistan</td>
<td width="33%">Uzbekistan</td>
</tr>
<tr>
<td width="33%"><img src="media/tajikistan.png" width="100%"/></td>
<td width="33%"><img src="media/turkmenistan.png" width="100%"></td>
<td width="33%"><img src="media/uzbekistan.png" width="100%"></td>
</tr>
</table>
### Deck.gl ContourLayer
We [added](https://github.com/apache/superset/pull/24154) the Deck.gl [ContourLayer](https://deck.gl/docs/api-reference/aggregation-layers/contour-layer) which aggregates data into Isolines or Isobands for a given threshold and cell size. By expanding the range of available [Deck.gl](https://deck.gl/) visualization layers, users will have more options to choose from when creating their visualizations. This will allow them to tailor their visualizations to their specific needs and explore their data in different ways.
![Contour](media/contour.png)
### New Databases
Superset has added support for two new databases:
- [Databend](https://databend.rs/), an open-source, elastic, and workload-aware cloud data warehouse built in Rust. You can see the PR [here](https://github.com/apache/superset/pull/23308), and the updated documentation [here](https://superset.apache.org/docs/databases/databend).
- [Apache Doris](https://doris.apache.org/), which is based on the MySQL protocol and introduces the concept of Multi Catalog. You can see the PR [here](https://github.com/apache/superset/pull/24714/) and the updated documentation [here](https://superset.apache.org/docs/databases/doris).
<table>
<tr>
<td width="50%"><img src="media/databend.png" width="100%"/></td>
<td width="50%"><img src="media/doris.png" width="100%"></td>
</tr>
</table>
### CLI command to execute viz migrations
A new [CLI command](https://github.com/apache/superset/pull/25304) called viz-migrations was added to allow users to migrate charts of a specific type. This command is particularly helpful to migrate visualizations to their latest version and at the same time disable their legacy versions with the `VIZ_TYPE_DENYLIST` configuration. The main advantage of this command is that you can migrate your visualizations without needing to wait for a major release, where we generally remove the legacy plugins.
Currently, you can use the command to migrate Area, Bubble, Line, and Sunburst chart types but we'll add more as the ECharts migrations continue. Note that migrations for deprecated charts may be forced in upcoming major versions when the code is removed. Running migrations earlier will allow you to de-risk future upgrades while improving user experience.
```bash
Usage: superset viz-migrations [OPTIONS] COMMAND [ARGS]...
Migrates a viz from one type to another.
Commands:
downgrade Downgrades a viz to the previous version.
upgrade Upgrade a viz to the latest version.
```
Note: When migrating dashboards from one Superset instance to another (using import/export features or the Superset CLI), or restoring a backup of prior charts and dashboards, Superset will apply the existing migrations that are used during version upgrades. This will ensure that your charts and dashboards are using the latest and greatest charts that Superset officially supports.
### Database engine spec improvements
Many database engine improvements were added in this release. Some highlights:
- [feat: improve SQLite DB engine spec](https://github.com/apache/superset/pull/24909)
- [feat: add MotherDuck DB engine spec](https://github.com/apache/superset/pull/24934)
- [feat: Add week time grain for Elasticsearch datasets](https://github.com/apache/superset/pull/25683)
- [feat: method for dynamic allows_alias_in_select](https://github.com/apache/superset/pull/25882)
We even added a new [CLI command](https://github.com/apache/superset/pull/24918) to test DB engine specs, SQLAlchemy dialects, and database connections.
```bash
Usage: superset test-db [OPTIONS] SQLALCHEMY_URI
Run a series of tests against an analytical database.
This command tests:
1. The Superset DB engine spec.
2. The SQLAlchemy dialect.
3. The database connectivity and performance.
It's useful for people developing DB engine specs and/or SQLAlchemy
dialects, and also to test new versions of DB API 2.0 drivers.
Options:
-c, --connect-args TEXT Connect args as JSON or YAML
--help Show this message and exit.
```
### Playwright as an alternative to Selenium
Per [SIP-98](https://github.com/apache/superset/issues/24948), we [introduced Playwright](https://github.com/apache/superset/pull/25247) for rendering charts in Superset reports. [Playwright](https://playwright.dev/) is an open-source library for automating web browsers, similar to Selenium but with better support for modern browser features and improved performance. By using Playwright, we aim to provide a more stable and accurate chart rendering experience in Superset reports, especially for [Deck.gl](https://deck.gl/) charts.
Since configuring Playwright requires installing additional dependencies, in order to prevent breaking changes in existing deployments, we put the new flow behind a feature flag called `PLAYWRIGHT_REPORTS_AND_THUMBNAILS`. Users that don't enable the feature flag will be unaffected by the changes.
### Pandas upgraded to v2
We [upgraded Pandas to v2](https://github.com/apache/superset/pull/24705) and [added performance dependencies](https://github.com/apache/superset/pull/24768) to provide speed improvements, especially when working with large data sets. For the full list of changes, check [Pandas 2.0.0 Release Notes](https://pandas.pydata.org/docs/dev/whatsnew/v2.0.0.html).
### Tags
Tags evolved a lot since 3.0, with many PRs that further improved the feature. During this phase, the community also made [great suggestions](https://github.com/apache/superset/discussions/25918) to make sure the feature is scalable, adhere to our security model, and offer a consistent design. We're still working on this feedback and new improvements will follow. For that reason, we're keeping the feature as beta behind the `TAGGING_SYSTEM` feature flag.

Binary file not shown.

After

Width:  |  Height:  |  Size: 420 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1011 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 411 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 258 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 299 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 463 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 200 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 157 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 319 KiB

View File

@ -111,6 +111,7 @@ Join our growing community!
- [Steamroot](https://streamroot.io/)
- [TechAudit](https://www.techaudit.info) [@ETselikov]
- [Tenable](https://www.tenable.com) [@dflionis]
- [Tentacle](https://public.tentaclecmi.com) [@jdclarke5]
- [timbr.ai](https://timbr.ai/) [@semantiDan]
- [Tobii](http://www.tobii.com/) [@dwa]
- [Tooploox](https://www.tooploox.com/) [@jakubczaplicki]
@ -175,8 +176,10 @@ Join our growing community!
- [Automattic](https://automattic.com/) [@Khrol, @Usiel]
- [Dropbox](https://www.dropbox.com/) [@bkyryliuk]
- [Grassroot](https://www.grassrootinstitute.org/)
- [Increff](https://www.increff.com/) [@ishansinghania]
- [komoot](https://www.komoot.com/) [@christophlingg]
- [Let's Roam](https://www.letsroam.com/)
- [Onebeat](https://1beat.com/) [@GuyAttia]
- [Twitter](https://twitter.com/)
- [VLMedia](https://www.vlmedia.com.tr/) [@ibotheperfect]
- [Yahoo!](https://yahoo.com/)

View File

@ -24,6 +24,7 @@ assists people when migrating to a new version.
## Next
- [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.
- [24657](https://github.com/apache/superset/pull/24657): Bumps the cryptography package to augment the OpenSSL security vulnerability.
### Breaking Changes

View File

@ -1,7 +1,7 @@
---
title: API
hide_title: true
sidebar_position: 9
sidebar_position: 10
---
import { Buffer } from 'buffer';

View File

@ -1,4 +1,4 @@
{
"label": "Contributing",
"position": 6
"position": 7
}

View File

@ -1,4 +1,4 @@
{
"label": "Connecting to Databases",
"position": 3
"position": 5
}

View File

@ -7,87 +7,57 @@ version: 1
## Adding New Database Drivers in Docker
Superset requires a Python database driver to be installed for each additional type of database you
want to connect to. When setting up Superset locally via `docker compose`, the drivers and packages
contained in
[requirements.txt](https://github.com/apache/superset/blob/master/requirements.txt) and
[requirements-dev.txt](https://github.com/apache/superset/blob/master/requirements-dev.txt)
will be installed automatically.
Superset requires a Python database driver to be installed for each additional type of database you want to connect to.
In this section, we'll walk through how to install the MySQL connector library. The connector
library installation process is the same for all additional libraries and we'll end this section
with the recommended connector library for each database.
In this example, we'll walk through how to install the MySQL connector library. The connector library installation process is the same for all additional libraries.
### 1. Determine the driver you need
To figure out how to install the [database driver](/docs/databases/installing-database-drivers) of your choice.
Consult the [list of database drivers](/docs/databases/installing-database-drivers) and find the PyPI package needed to connect to your database. In this example, we're connecting to a MySQL database, so we'll need the `mysqlclient` connector library.
In the example, we'll walk through the process of installing a MySQL driver in Superset.
### 2. Install the driver in the container
### 2. Install MySQL Driver
We need to get the `mysqlclient` library installed into the Superset docker container (it doesn't matter if it's installed on the host machine). We could enter the running container with `docker exec -it <container_name> bash` and run `pip install mysqlclient` there, but that wouldn't persist permanently.
As we are currently running inside of a Docker container via `docker compose`, we cannot simply run
`pip install mysqlclient` on our local shell and expect the drivers to be installed within the
Docker containers for superset.
To address this, the Superset `docker compose` deployment uses the convention of a `requirements-local.txt` file. All packages listed in this file will be installed into the container from PyPI at runtime. This file will be ignored by Git for the purposes of local development.
In order to address this, the Superset `docker compose` setup comes with a mechanism for you to
install packages locally, which will be ignored by Git for the purposes of local development. Please
follow these steps:
Create `requirements-local.txt`
Create the file `requirements-local.txt` in a subdirectory called `docker` that exists in the directory with your `docker-compose.yml` or `docker-compose-non-dev.yml` file.
```
# From the repo root...
# Run from the repo root:
touch ./docker/requirements-local.txt
```
Add the driver selected in step above:
Add the driver identified in step above. You can use a text editor or do it from the command line like:
```
echo "mysqlclient" >> ./docker/requirements-local.txt
```
Rebuild your local image with the new driver baked in:
**If you are running a stock (non-customized) Superset image**, you are done. Launch Superset with `docker compose -f docker-compose-non-dev.yml up` and the driver should be present.
You can check its presence by entering the running container with `docker exec -it <container_name> bash` and running `pip freeze`. The PyPI package should be present in the printed list.
**If you're running a customized docker image**, rebuild your local image with the new driver baked in:
```
docker compose build --force-rm
```
After the rebuild of the Docker images is complete (which may take a few minutes) you can relaunch using the following command:
```
docker compose up
```
The other option is to start Superset via Docker Compose is using the recipe in `docker-compose-non-dev.yml`, which will use pre-built frontend assets and skip the building of front-end assets:
```
docker compose -f docker-compose-non-dev.yml pull
docker compose -f docker-compose-non-dev.yml up
```
After the rebuild of the Docker images is complete, relaunch Superset by running `docker compose up`.
### 3. Connect to MySQL
Now that you've got a MySQL driver installed locally, you should be able to test it out.
Now that you've got a MySQL driver installed in your container, you should be able to connect to your database via the Superset web UI.
We can now create a Datasource in Superset that can be used to connect to a MySQL instance. Assuming
your MySQL instance is running locally and can be accessed via localhost, use the following
connection string in “SQL Alchemy URI”, by going to Sources > Databases > + icon (to add a new
datasource) in Superset.
As an admin user, go to Settings -> Data: Database Connections and click the +DATABASE button. From there, follow the steps on the [Using Database Connection UI page](https://superset.apache.org/docs/databases/db-connection-ui).
For Docker running in Linux:
Consult the page for your specific database type in the Superset documentation to determine the connection string and any other parameters you need to input. For instance, on the [MySQL page](https://superset.apache.org/docs/databases/mysql), we see that the connection string to a local MySQL database differs depending on whether the setup is running on Linux or Mac.
```
mysql://mysqluser:mysqluserpassword@localhost/example?charset=utf8
```
Click the “Test Connection” button, which should result in a popup message saying, "Connection looks good!".
For Docker running in OSX:
### 4. Troubleshooting
```
mysql://mysqluser:mysqluserpassword@docker.for.mac.host.internal/example?charset=utf8
```
If the test fails, review your docker logs for error messages. Superset uses SQLAlchemy to connect to databases; to troubleshoot the connection string for your database, you might start Python in the Superset application container or host environment and try to connect directly to the desired database and fetch data. This eliminates Superset for the purposes of isolating the problem.
Then click “Test Connection”, which should give you an “OK” message. If not, please look at your
terminal for error messages, and reach out for help.
You can repeat this process for every database you want superset to be able to connect to.
Repeat this process for each different type of database you want Superset to be able to connect to.

View File

@ -0,0 +1,26 @@
---
title: Apache Doris
hide_title: true
sidebar_position: 5
version: 1
---
## Doris
The [sqlalchemy-doris](https://pypi.org/project/pydoris/) library is the recommended way to connect to Apache Doris through SQLAlchemy.
You'll need the following setting values to form the connection string:
- **User**: User Name
- **Password**: Password
- **Host**: Doris FE Host
- **Port**: Doris FE port
- **Catalog**: Catalog Name
- **Database**: Database Name
Here's what the connection string looks like:
```
doris://<User>:<Password>@<Host>:<Port>/<Catalog>.<Database>
```

View File

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

View File

@ -14,3 +14,9 @@ The expected connection string is formatted as follows:
```
pinot+http://<pinot-broker-host>:<pinot-broker-port>/query?controller=http://<pinot-controller-host>:<pinot-controller-port>/``
```
The expected connection string using username and password is formatted as follows:
```
pinot://<username>:<password>@<pinot-broker-host>:<pinot-broker-port>/query/sql?controller=http://<pinot-controller-host>:<pinot-controller-port>/verify_ssl=true``
```

View File

@ -56,6 +56,8 @@ In `Secure Extra` field, config as following example:
All fields in `auth_params` are passed directly to the [`KerberosAuthentication`](https://github.com/trinodb/trino-python-client/blob/0.306.0/trino/auth.py#L40) class.
NOTE: Kerberos authentication requires installing the [`trino-python-client`](https://github.com/trinodb/trino-python-client) locally with either the `all` or `kerberos` optional features, i.e., installing `trino[all]` or `trino[kerberos]` respectively.
#### 3. Certificate Authentication
In `Secure Extra` field, config as following example:
```json

View File

@ -1,7 +1,7 @@
---
title: Frequently Asked Questions
hide_title: true
sidebar_position: 7
sidebar_position: 8
---
## Frequently Asked Questions

View File

@ -1,4 +1,4 @@
{
"label": "Installation and Configuration",
"position": 2
"position": 3
}

View File

@ -15,7 +15,7 @@ Here are a **few different ways you can get started with Superset**:
- Install Superset [from scratch](https://superset.apache.org/docs/installation/installing-superset-from-scratch/)
- Deploy Superset locally with one command
[using Docker Compose](installation/installing-superset-using-docker-compose)
[using Docker Compose](https://superset.apache.org/docs/installation/installing-superset-using-docker-compose)
- Deploy Superset [with Kubernetes](https://superset.apache.org/docs/installation/running-on-kubernetes)
- Run a [Docker image](https://hub.docker.com/r/apache/superset) from Dockerhub
- Download Superset [from Pypi here](https://pypi.org/project/apache-superset/)

View File

@ -1,4 +1,4 @@
{
"label": "Miscellaneous",
"position": 5
"position": 6
}

86
docs/docs/quickstart.mdx Normal file
View File

@ -0,0 +1,86 @@
---
title: Quickstart
hide_title: false
sidebar_position: 2
---
**Ready to give Apache Superset a try?** This quickstart will help you run Superset on your local machine in
**5 simple steps**. It assumes that you have [Docker](https://www.docker.com) installed.
### 1. Get Superset
To get started, set the `SUPERSET_VERSION` environment variable with the latest Superset version.
[Click here](https://github.com/apache/superset/releases) to check the latest version.
```
$ export SUPERSET_VERSION=<latest_version>
```
Pull the Superset image from Docker Hub:
```
$ docker pull apache/superset:$SUPERSET_VERSION
```
### 2. Start Superset
:::tip
Note that some configuration is mandatory for Superset in order to start. In particular, Superset will not start without
a user-specified value of `SECRET_KEY` in a Superset configuration file or `SUPERSET_SECRET_KEY` as an environment variable.
Please see [Configuring Superset](https://superset.apache.org/docs/installation/configuring-superset/) for more details.
:::
```
$ docker run -d -p 8080:8088 \
-e "SUPERSET_SECRET_KEY=$(openssl rand -base64 42)" \
-e "TALISMAN_ENABLED=False" \
--name superset apache/superset:$SUPERSET_VERSION
```
### 3. Create an account
```
$ docker exec -it superset superset fab create-admin \
--username admin \
--firstname Admin \
--lastname Admin \
--email admin@localhost \
--password admin
```
### 4. Configure Superset
```
$ docker exec -it superset superset db upgrade &&
docker exec -it superset superset load_examples &&
docker exec -it superset superset init
```
:::tip
This step can take some time. While you wait, feel free to join the official Slack channel to check for new releases,
ask questions, and engage with the community.
[Click here to join.](https://apache-superset.slack.com/join/shared_invite/zt-26ol9ge4y-kzUnSo9inRepOay0ufBTsA#/shared-invite/email)
:::
### 5. Start using Superset
After configuring your fresh instance, head over to [http://localhost:8080](http://localhost:8080) and
log in with the default created account:
```
username: admin
password: admin
```
#### 🎉 Congratulations! Superset is now up and running on your machine! 🎉
### Wrapping Up
Once you're done with Superset, you can stop and remove it just like any other container:
```
$ docker container rm -f superset
```
:::tip
You can use the same container more than once, as Superset will persist data locally. However, make sure to properly stop all
processes by running Docker `stop` command. By doing so, you can avoid data corruption and/or loss of data.
:::
## What's next?
From this point on, you can head on to:
- [Create your first Dashboard](https://superset.apache.org/docs/creating-charts-dashboards/creating-your-first-dashboard)
- [Connect to a Database](https://superset.apache.org/docs/databases/installing-database-drivers)
- [Configure Superset](https://superset.apache.org/docs/installation/configuring-superset/)
Or just explore our Documentation!

View File

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

View File

@ -1,9 +1,27 @@
---
title: CVEs by release
title: CVEs fixed by release
hide_title: true
sidebar_position: 2
---
#### Version 3.0.0
| CVE | Title | Affected |
|:---------------|:------------------------------------------------------------------------|---------:|
| CVE-2023-42502 | Open Redirect Vulnerability | < 3.0.0 |
| CVE-2023-42504 | Lack of rate limiting allows for possible denial of service | < 3.0.0 |
| CVE-2023-42505 | Sensitive information disclosure on db connection details | < 3.0.0 |
#### Version 2.1.2
| CVE | Title | Affected |
|:---------------|:------------------------------------------------------------------------|---------:|
| CVE-2023-40610 | Privilege escalation with default examples database | < 2.1.2 |
| CVE-2023-42501 | Unnecessary read permissions within the Gamma role | < 2.1.2 |
| CVE-2023-43701 | Stored XSS on API endpoint | < 2.1.2 |
#### Version 2.1.1
| CVE | Title | Affected |

View File

@ -117,4 +117,9 @@ export const Databases = [
href: 'https://www.microsoft.com/en-us/sql-server',
imgName: 'msql.png',
},
{
title: 'Apache Doris',
href: 'https://doris.apache.org/',
imgName: 'doris.png',
},
];

View File

@ -117,6 +117,7 @@ a > span > svg {
font-size: 14px;
font-weight: 400;
background-color: #fff;
transition: all 0.5s;
.get-started-button {
border-radius: 10px;

BIN
docs/static/img/databases/doris.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -29,7 +29,7 @@ maintainers:
- name: craig-rueda
email: craig@craigrueda.com
url: https://github.com/craig-rueda
version: 0.10.14
version: 0.11.2
dependencies:
- name: postgresql
version: 12.1.6

View File

@ -23,7 +23,7 @@ NOTE: This file is generated by helm-docs: https://github.com/norwoodj/helm-docs
# superset
![Version: 0.10.14](https://img.shields.io/badge/Version-0.10.14-informational?style=flat-square)
![Version: 0.11.2](https://img.shields.io/badge/Version-0.11.2-informational?style=flat-square)
Apache Superset is a modern, enterprise-ready business intelligence web application
@ -40,6 +40,12 @@ helm repo add superset http://apache.github.io/superset/
helm install my-superset superset/superset
```
Make sure you set your own `SECRET_KEY` to something unique and secret. This secret key is used by Flask for
securely signing the session cookie and will be used to encrypt sensitive data on Superset's metadata database.
It should be a long random bytes or str.
On helm this can be set on `extraSecretEnv.SUPERSET_SECRET_KEY` or `configOverrides.secrets`
## Requirements
| Repository | Name | Version |
@ -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"` | |

View File

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

View File

@ -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", )

View File

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

View File

@ -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 }}

View File

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

View File

@ -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 }}

View File

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

View File

@ -93,6 +93,8 @@ extraSecretEnv: {}
# # Google API Keys: https://console.cloud.google.com/apis/credentials
# GOOGLE_KEY: ...
# GOOGLE_SECRET: ...
# # Generate your own secret key for encryption. Use openssl rand -base64 42 to generate a good key
# SUPERSET_SECRET_KEY: 'CHANGE_ME_TO_A_COMPLEX_RANDOM_SECRET'
# -- Extra files to mount on `/app/pythonpath`
extraConfigs: {}
@ -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: {}

View File

@ -17,4 +17,4 @@
[pytest]
testpaths =
tests
python_files = *_test.py test_*.py *_tests.py
python_files = *_test.py test_*.py *_tests.py *viz/utils.py

View File

@ -18,7 +18,10 @@ apsw==3.42.0.1
async-timeout==4.0.2
# via redis
attrs==23.1.0
# via jsonschema
# via
# cattrs
# jsonschema
# requests-cache
babel==2.9.1
# via flask-babel
backoff==1.11.1
@ -31,10 +34,12 @@ bottleneck==1.3.7
# via pandas
brotli==1.0.9
# via flask-compress
cachelib==0.6.0
cachelib==0.9.0
# via
# flask-caching
# flask-session
cattrs==23.2.1
# via requests-cache
celery==5.2.2
# via apache-superset
certifi==2023.7.22
@ -85,6 +90,8 @@ dnspython==2.1.0
# via email-validator
email-validator==1.1.3
# via flask-appbuilder
exceptiongroup==1.1.1
# via cattrs
flask==2.2.5
# via
# apache-superset
@ -99,11 +106,11 @@ flask==2.2.5
# flask-session
# flask-sqlalchemy
# flask-wtf
flask-appbuilder==4.3.9
flask-appbuilder==4.3.10
# via apache-superset
flask-babel==1.0.0
# via flask-appbuilder
flask-caching==1.11.1
flask-caching==2.1.0
# via apache-superset
flask-compress==1.13
# via apache-superset
@ -136,7 +143,9 @@ geographiclib==1.52
geopy==2.2.0
# via apache-superset
greenlet==2.0.2
# via shillelagh
# via
# shillelagh
# sqlalchemy
gunicorn==21.2.0
# via apache-superset
hashids==1.3.1
@ -152,7 +161,10 @@ idna==3.2
# email-validator
# requests
importlib-metadata==6.6.0
# via apache-superset
# via
# apache-superset
# flask
# shillelagh
importlib-resources==5.12.0
# via limits
isodate==0.6.0
@ -232,6 +244,8 @@ parsedatetime==2.6
# via apache-superset
pgsanity==0.2.9
# via apache-superset
platformdirs==3.8.1
# via requests-cache
polyline==2.0.0
# via apache-superset
prison==0.2.1
@ -285,12 +299,16 @@ pyyaml==6.0.1
redis==4.5.4
# via apache-superset
requests==2.31.0
# via
# requests-cache
# shillelagh
requests-cache==1.1.1
# via shillelagh
rich==13.3.4
# via flask-limiter
selenium==3.141.0
# via apache-superset
shillelagh==1.2.6
shillelagh==1.2.10
# via apache-superset
shortid==0.1.2
# via apache-superset
@ -303,6 +321,7 @@ six==1.16.0
# paramiko
# prison
# python-dateutil
# url-normalize
# wtforms-json
slack-sdk==3.21.3
# via apache-superset
@ -328,14 +347,18 @@ tabulate==0.8.9
typing-extensions==4.4.0
# via
# apache-superset
# cattrs
# flask-limiter
# limits
# shillelagh
tzdata==2023.3
# via pandas
url-normalize==1.4.3
# via requests-cache
urllib3==1.26.6
# via
# requests
# requests-cache
# selenium
vine==5.0.0
# via
@ -363,7 +386,9 @@ wtforms-json==0.3.5
xlsxwriter==3.0.7
# via apache-superset
zipp==3.15.0
# via importlib-metadata
# via
# importlib-metadata
# importlib-resources
# The following packages are considered to be unsafe in a requirements file:
# setuptools

View File

@ -74,8 +74,6 @@ pickleshare==0.7.5
# via ipython
pillow==9.5.0
# via apache-superset
platformdirs==3.8.1
# via pylint
progress==1.6
# via -r requirements/development.in
psycopg2-binary==2.9.6

View File

@ -26,8 +26,6 @@ docker==6.1.1
# via -r requirements/testing.in
ephem==4.1.4
# via lunarcalendar
exceptiongroup==1.1.1
# via pytest
flask-testing==0.8.1
# via -r requirements/testing.in
fonttools==4.39.4
@ -123,8 +121,6 @@ pyee==9.0.4
# via playwright
pyfakefs==5.2.2
# via -r requirements/testing.in
pyhive[presto]==0.7.0
# via apache-superset
pytest==7.3.1
# via
# -r requirements/testing.in
@ -144,8 +140,6 @@ rsa==4.9
# via google-auth
setuptools-git==1.2
# via prophet
shillelagh[gsheetsapi]==1.2.6
# via apache-superset
sqlalchemy-bigquery==1.6.1
# via apache-superset
statsd==4.0.1

View File

@ -85,6 +85,7 @@ else
DEV_TAG="${REPO_NAME}:${LATEST_TAG}-dev"
fi
for BUILD_PLATFORM in $ARCHITECTURE_FOR_BUILD; do
#
# Build the dev image
#
@ -96,7 +97,7 @@ docker buildx build --target dev \
-t "${REPO_NAME}:${SHA}-dev" \
-t "${REPO_NAME}:${REFSPEC}-dev" \
-t "${DEV_TAG}" \
--platform linux/amd64 \
--platform ${BUILD_PLATFORM} \
--label "sha=${SHA}" \
--label "built_at=$(date)" \
--label "target=dev" \
@ -113,7 +114,7 @@ docker buildx build --target lean \
-t "${REPO_NAME}:${SHA}" \
-t "${REPO_NAME}:${REFSPEC}" \
-t "${REPO_NAME}:${LATEST_TAG}" \
--platform linux/amd64 \
--platform ${BUILD_PLATFORM} \
--label "sha=${SHA}" \
--label "built_at=$(date)" \
--label "target=lean" \
@ -130,7 +131,7 @@ docker buildx build --target lean \
-t "${REPO_NAME}:${SHA}-py310" \
-t "${REPO_NAME}:${REFSPEC}-py310" \
-t "${REPO_NAME}:${LATEST_TAG}-py310" \
--platform linux/amd64 \
--platform ${BUILD_PLATFORM} \
--build-arg PY_VER="3.10-slim-bookworm"\
--label "sha=${SHA}" \
--label "built_at=$(date)" \
@ -148,7 +149,7 @@ docker buildx build --target lean \
-t "${REPO_NAME}:${SHA}-py39" \
-t "${REPO_NAME}:${REFSPEC}-py39" \
-t "${REPO_NAME}:${LATEST_TAG}-py39" \
--platform linux/amd64 \
--platform ${BUILD_PLATFORM} \
--build-arg PY_VER="3.9-slim-bullseye"\
--label "sha=${SHA}" \
--label "built_at=$(date)" \
@ -156,8 +157,6 @@ docker buildx build --target lean \
--label "build_actor=${GITHUB_ACTOR}" \
.
for BUILD_PLATFORM in $ARCHITECTURE_FOR_BUILD; do
#
# Build the "websocket" image
#

View File

@ -83,8 +83,8 @@ setup(
"cryptography>=41.0.2, <41.1.0",
"deprecation>=2.1.0, <2.2.0",
"flask>=2.2.5, <3.0.0",
"flask-appbuilder>=4.3.9, <5.0.0",
"flask-caching>=1.11.1, <2.0",
"flask-appbuilder>=4.3.10, <5.0.0",
"flask-caching>=2.1.0, <3",
"flask-compress>=1.13, <2.0",
"flask-talisman>=1.0.0, <2.0",
"flask-login>=0.6.0, < 1.0",
@ -118,7 +118,7 @@ setup(
"PyJWT>=2.4.0, <3.0",
"redis>=4.5.4, <5.0",
"selenium>=3.141.0, <4.10.0",
"shillelagh>=1.2.6,<2.0",
"shillelagh>=1.2.10, <2.0",
"shortid",
"sshtunnel>=0.4.0, <0.5",
"simplejson>=3.15.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",
@ -162,7 +163,7 @@ setup(
"excel": ["xlrd>=1.2.0, <1.3"],
"firebird": ["sqlalchemy-firebird>=0.7.0, <0.8"],
"firebolt": ["firebolt-sqlalchemy>=0.0.1"],
"gsheets": ["shillelagh[gsheetsapi]>=1.2.6, <2"],
"gsheets": ["shillelagh[gsheetsapi]>=1.2.10, <2"],
"hana": ["hdbcli==2.4.162", "sqlalchemy_hana==0.4.0"],
"hive": [
"pyhive[hive]>=0.6.5;python_version<'3.11'",
@ -191,7 +192,7 @@ setup(
"redshift": ["sqlalchemy-redshift>=0.8.1, < 0.9"],
"rockset": ["rockset-sqlalchemy>=0.0.1, <1.0.0"],
"shillelagh": [
"shillelagh[datasetteapi,gsheetsapi,socrata,weatherapi]>=1.2.6,<2"
"shillelagh[datasetteapi,gsheetsapi,socrata,weatherapi]>=1.2.10, <2"
],
"snowflake": ["snowflake-sqlalchemy>=1.2.4, <2"],
"spark": [
@ -201,10 +202,11 @@ 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"],
"doris": ["pydoris>=1.0.0, <2.0.0"],
},
python_requires="~=3.9",
author="Apache Software Foundation",

View File

@ -18,7 +18,7 @@
"@babel/preset-env": "^7.16.11",
"@babel/preset-typescript": "^7.16.7",
"@types/jest": "^27.4.1",
"axios": "^0.25.0",
"axios": "^1.6.0",
"babel-loader": "^8.2.3",
"jest": "^27.5.1",
"typescript": "^4.5.5",
@ -2977,12 +2977,28 @@
"dev": true
},
"node_modules/axios": {
"version": "0.25.0",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.25.0.tgz",
"integrity": "sha512-cD8FOb0tRH3uuEe6+evtAbgJtfxr7ly3fQjYcMcuPlgkwVS9xboaVIpcDV+cYQe+yGykgwZCs1pzjntcGa6l5g==",
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.6.0.tgz",
"integrity": "sha512-EZ1DYihju9pwVB+jg67ogm+Tmqc6JmhamRN6I4Zt8DfZu5lbcQGw3ozH9lFejSJgs/ibaef3A9PMXPLeefFGJg==",
"dev": true,
"dependencies": {
"follow-redirects": "^1.14.7"
"follow-redirects": "^1.15.0",
"form-data": "^4.0.0",
"proxy-from-env": "^1.1.0"
}
},
"node_modules/axios/node_modules/form-data": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
"dev": true,
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"mime-types": "^2.1.12"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/babel-jest": {
@ -4087,9 +4103,9 @@
}
},
"node_modules/follow-redirects": {
"version": "1.14.8",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.8.tgz",
"integrity": "sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA==",
"version": "1.15.3",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz",
"integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==",
"dev": true,
"funding": [
{
@ -7021,6 +7037,12 @@
"node": ">= 6"
}
},
"node_modules/proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
"dev": true
},
"node_modules/psl": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
@ -10431,12 +10453,27 @@
"dev": true
},
"axios": {
"version": "0.25.0",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.25.0.tgz",
"integrity": "sha512-cD8FOb0tRH3uuEe6+evtAbgJtfxr7ly3fQjYcMcuPlgkwVS9xboaVIpcDV+cYQe+yGykgwZCs1pzjntcGa6l5g==",
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.6.0.tgz",
"integrity": "sha512-EZ1DYihju9pwVB+jg67ogm+Tmqc6JmhamRN6I4Zt8DfZu5lbcQGw3ozH9lFejSJgs/ibaef3A9PMXPLeefFGJg==",
"dev": true,
"requires": {
"follow-redirects": "^1.14.7"
"follow-redirects": "^1.15.0",
"form-data": "^4.0.0",
"proxy-from-env": "^1.1.0"
},
"dependencies": {
"form-data": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
"dev": true,
"requires": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"mime-types": "^2.1.12"
}
}
}
},
"babel-jest": {
@ -11279,9 +11316,9 @@
}
},
"follow-redirects": {
"version": "1.14.8",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.8.tgz",
"integrity": "sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA==",
"version": "1.15.3",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz",
"integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==",
"dev": true
},
"form-data": {
@ -13464,6 +13501,12 @@
"sisteransi": "^1.0.5"
}
},
"proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
"dev": true
},
"psl": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",

View File

@ -42,7 +42,7 @@
"@babel/preset-env": "^7.16.11",
"@babel/preset-typescript": "^7.16.7",
"@types/jest": "^27.4.1",
"axios": "^0.25.0",
"axios": "^1.6.0",
"babel-loader": "^8.2.3",
"jest": "^27.5.1",
"typescript": "^4.5.5",

View File

@ -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');
});

View File

@ -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');
});

View File

@ -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');
});
});

View File

@ -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', () => {

View File

@ -515,7 +515,7 @@ describe('Dashboard edit', () => {
// label Anthony
cy.get('[data-test-chart-name="Trends"] .line .nv-legend-symbol')
.eq(2)
.should('have.css', 'fill', 'rgb(0, 122, 135)');
.should('have.css', 'fill', 'rgb(244, 176, 42)');
// open main tab and nested tab
openTab(0, 0);
@ -526,7 +526,7 @@ describe('Dashboard edit', () => {
'[data-test-chart-name="Top 10 California Names Timeseries"] .line .nv-legend-symbol',
)
.first()
.should('have.css', 'fill', 'rgb(0, 122, 135)');
.should('have.css', 'fill', 'rgb(244, 176, 42)');
});
it('should apply the color scheme across main tabs', () => {
@ -557,7 +557,7 @@ describe('Dashboard edit', () => {
cy.get('[data-test-chart-name="Trends"] .line .nv-legend-symbol')
.first()
.should('have.css', 'fill', 'rgb(204, 0, 134)');
.should('have.css', 'fill', 'rgb(156, 52, 152)');
// change scheme now that charts are rendered across the main tabs
editDashboard();

View File

@ -113,7 +113,7 @@ function prepareDashboardFilters(
},
type: 'NATIVE_FILTER',
description: '',
chartsInScope: [6],
chartsInScope: [5],
tabsInScope: [],
});
});
@ -150,7 +150,7 @@ function prepareDashboardFilters(
meta: {
width: 4,
height: 50,
chartId: 6,
chartId: 5,
sliceName: 'Most Populated Countries',
},
},
@ -414,7 +414,7 @@ describe('Native filters', () => {
cy.createSampleDashboards([0]);
});
it('Verify that default value is respected after revisit', () => {
it.only('Verify that default value is respected after revisit', () => {
prepareDashboardFilters([
{ name: 'country_name', column: 'country_name', datasetId: 2 },
]);

View File

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

View File

@ -23,7 +23,6 @@ import { ChartSpec, waitForChartLoad } from 'cypress/utils';
export const WORLD_HEALTH_CHARTS = [
{ name: '% Rural', viz: 'world_map' },
{ name: 'Most Populated Countries', viz: 'table' },
{ name: 'Region Filter', viz: 'filter_box' },
{ name: "World's Population", viz: 'big_number' },
{ name: 'Growth Rate', viz: 'line' },
{ name: 'Rural Breakdown', viz: 'sunburst' },

View File

@ -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', () => {

View File

@ -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', () => {

View File

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

View File

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

View File

@ -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();

View File

@ -1,7 +1,7 @@
{
"lerna": "3.2.1",
"npmClient": "npm",
"packages": ["packages/*", "plugins/*"],
"packages": ["packages/*", "plugins/*", "src/setup/*"],
"useWorkspaces": true,
"version": "0.18.25",
"ignoreChanges": [

View File

@ -10,7 +10,8 @@
"license": "Apache-2.0",
"workspaces": [
"packages/*",
"plugins/*"
"plugins/*",
"src/setup/*"
],
"dependencies": {
"@ant-design/icons": "^5.0.1",
@ -259,7 +260,7 @@
"less-loader": "^10.2.0",
"mini-css-extract-plugin": "^2.7.6",
"mock-socket": "^9.0.3",
"node-fetch": "^2.6.1",
"node-fetch": "^2.6.7",
"prettier": "^2.4.1",
"prettier-plugin-packagejson": "^2.2.15",
"process": "^0.11.10",
@ -47771,9 +47772,9 @@
"dev": true
},
"node_modules/nx/node_modules/axios": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz",
"integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==",
"version": "1.6.1",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.6.1.tgz",
"integrity": "sha512-vfBmhDpKafglh0EldBEbVuoe7DyAavGSLWhuSm5ZSEKQnHhBf0xAAwybbNH1IkrJNGnS/VG4I5yxig1pCEXE4g==",
"dev": true,
"dependencies": {
"follow-redirects": "^1.15.0",
@ -101307,9 +101308,9 @@
"dev": true
},
"axios": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz",
"integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==",
"version": "1.6.1",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.6.1.tgz",
"integrity": "sha512-vfBmhDpKafglh0EldBEbVuoe7DyAavGSLWhuSm5ZSEKQnHhBf0xAAwybbNH1IkrJNGnS/VG4I5yxig1pCEXE4g==",
"dev": true,
"requires": {
"follow-redirects": "^1.15.0",

View File

@ -33,7 +33,8 @@
},
"workspaces": [
"packages/*",
"plugins/*"
"plugins/*",
"src/setup/*"
],
"scripts": {
"_lint": "eslint --ignore-path=.eslintignore --ext .js,.jsx,.ts,tsx .",
@ -324,7 +325,7 @@
"less-loader": "^10.2.0",
"mini-css-extract-plugin": "^2.7.6",
"mock-socket": "^9.0.3",
"node-fetch": "^2.6.1",
"node-fetch": "^2.6.7",
"prettier": "^2.4.1",
"prettier-plugin-packagejson": "^2.2.15",
"process": "^0.11.10",

View File

@ -36,7 +36,6 @@ export interface ChartMetadataConfig {
description?: string;
datasourceCount?: number;
enableNoResults?: boolean;
show?: boolean;
supportedAnnotationTypes?: string[];
thumbnail: string;
useLegacyApi?: boolean;
@ -64,8 +63,6 @@ export default class ChartMetadata {
description: string;
show: boolean;
supportedAnnotationTypes: string[];
thumbnail: string;
@ -100,7 +97,6 @@ export default class ChartMetadata {
canBeAnnotationTypes = [],
credits = [],
description = '',
show = true,
supportedAnnotationTypes = [],
thumbnail,
useLegacyApi = false,
@ -120,7 +116,6 @@ export default class ChartMetadata {
this.name = name;
this.credits = credits;
this.description = description;
this.show = show;
this.canBeAnnotationTypes = canBeAnnotationTypes;
this.canBeAnnotationTypesLookup = canBeAnnotationTypes.reduce(
(prev: LookupTable, type: string) => {

View File

@ -58,7 +58,6 @@ export enum AppSection {
export type FilterState = { value?: any; [key: string]: any };
export type DataMask = {
__cache?: FilterState;
extraFormData?: ExtraFormData;
filterState?: FilterState;
ownState?: JsonObject;

View File

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

View File

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

View File

@ -127,6 +127,14 @@ export interface SQLResultTableExtentionProps {
expandedColumns?: string[];
}
/**
* Interface for extensions to Slice Header
*/
export interface SliceHeaderExtension {
sliceId: number;
dashboardId: number;
}
export type Extensions = Partial<{
'alertsreports.header.icon': React.ComponentType;
'embedded.documentation.configuration_details': React.ComponentType<ConfigDetailsProps>;
@ -147,4 +155,5 @@ export type Extensions = Partial<{
'dataset.delete.related': React.ComponentType<DatasetDeleteRelatedExtensionProps>;
'sqleditor.extension.form': React.ComponentType<SQLFormExtensionProps>;
'sqleditor.extension.resultTable': React.ComponentType<SQLResultTableExtentionProps>;
'dashboard.slice.header': React.ComponentType<SliceHeaderExtension>;
}>;

View File

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

View File

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

View File

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

View File

@ -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');
}

View File

@ -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',
);
});
});
});

View File

@ -42,7 +42,7 @@ export const Basic = () => {
allColumnsY: 'LAT',
clusteringRadius: '60',
globalOpacity: 1,
mapboxColor: 'rgb(0, 122, 135)',
mapboxColor: 'rgb(244, 176, 42)',
mapboxLabel: [],
mapboxStyle: 'mapbox://styles/mapbox/light-v9',
pandasAggfunc: 'sum',

View File

@ -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/',
),
},
},
],

View File

@ -27,7 +27,8 @@ export default {
label: t('Map'),
expanded: true,
controlSetRows: [
[mapboxStyle, viewport],
[mapboxStyle],
[viewport],
[
{
name: 'deck_slices',

View File

@ -76,10 +76,7 @@ const config: ControlPanelConfig = {
},
{
label: t('Map'),
controlSetRows: [
[mapboxStyle, viewport],
[autozoom, null],
],
controlSetRows: [[mapboxStyle], [autozoom, viewport]],
},
{
label: t('Arc'),

View File

@ -52,8 +52,8 @@ const config: ControlPanelConfig = {
label: t('Map'),
expanded: true,
controlSetRows: [
[mapboxStyle, viewport],
[autozoom],
[mapboxStyle],
[autozoom, viewport],
[
{
name: 'cellSize',

View File

@ -53,7 +53,8 @@ const config: ControlPanelConfig = {
{
label: t('Map'),
controlSetRows: [
[mapboxStyle, viewport],
[mapboxStyle],
[viewport],
['color_scheme'],
[autozoom],
[gridSize],

View File

@ -99,7 +99,8 @@ const config: ControlPanelConfig = {
{
label: t('Map'),
controlSetRows: [
[mapboxStyle, viewport],
[mapboxStyle],
[viewport],
['linear_color_scheme'],
[autozoom],
[

View File

@ -53,8 +53,8 @@ const config: ControlPanelConfig = {
{
label: t('Map'),
controlSetRows: [
[mapboxStyle, viewport],
['color_scheme'],
[mapboxStyle],
['color_scheme', viewport],
[autozoom],
[gridSize],
[extruded],

View File

@ -67,7 +67,8 @@ const config: ControlPanelConfig = {
label: t('Map'),
expanded: true,
controlSetRows: [
[mapboxStyle, viewport],
[mapboxStyle],
[viewport],
['color_picker'],
[lineWidth],
[

View File

@ -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'),

View File

@ -52,10 +52,7 @@ const config: ControlPanelConfig = {
},
{
label: t('Map'),
controlSetRows: [
[mapboxStyle, viewport],
[autozoom, null],
],
controlSetRows: [[mapboxStyle], [autozoom, viewport]],
},
{
label: t('Grid'),

View File

@ -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/',
),
},
};

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