mirror of
https://github.com/apache/superset.git
synced 2026-07-03 13:25:32 +00:00
Compare commits
191 Commits
control-pa
...
Simplified
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
de8282cea0 | ||
|
|
710c6f9412 | ||
|
|
8c7a3bf85a | ||
|
|
3be6cef597 | ||
|
|
d217a78857 | ||
|
|
63b97ab76d | ||
|
|
6b9122bb3b | ||
|
|
5a59dcf06e | ||
|
|
fb6ad3240f | ||
|
|
2eadc1f086 | ||
|
|
d1bc986d93 | ||
|
|
0b263697ca | ||
|
|
f0b86f877f | ||
|
|
a91daab1f7 | ||
|
|
54cc69a382 | ||
|
|
41464931a4 | ||
|
|
e01c8792ec | ||
|
|
4b33353165 | ||
|
|
8b815a3aac | ||
|
|
2a96a9c734 | ||
|
|
b73ee7f2e0 | ||
|
|
f85175e16d | ||
|
|
305b6df6e3 | ||
|
|
64f8140731 | ||
|
|
5820d31b5c | ||
|
|
29e3f4bcc4 | ||
|
|
b02d18a39e | ||
|
|
d466383df2 | ||
|
|
3ec3f0a610 | ||
|
|
ab95bff7b6 | ||
|
|
b3edbe45cf | ||
|
|
ccc2f66e92 | ||
|
|
5d42dfb1e6 | ||
|
|
fa9d2cefcc | ||
|
|
f19c4280c0 | ||
|
|
402c29c2bc | ||
|
|
3e29777526 | ||
|
|
2518190b2d | ||
|
|
31aad28a31 | ||
|
|
58edc79820 | ||
|
|
a729f04695 | ||
|
|
849d426e06 | ||
|
|
bc5da631c8 | ||
|
|
9bb69ab311 | ||
|
|
dc9dd5fabf | ||
|
|
4511e1c28d | ||
|
|
e79778ac6d | ||
|
|
d5a98e0189 | ||
|
|
73768f6313 | ||
|
|
eb14c762af | ||
|
|
a74ef412fb | ||
|
|
60cd2550a7 | ||
|
|
576ad85eb4 | ||
|
|
f2a9f31135 | ||
|
|
98c0fdc7e8 | ||
|
|
bdb79a0630 | ||
|
|
fbd7c0ce01 | ||
|
|
b9ac800bfb | ||
|
|
eecb537808 | ||
|
|
09d3f60d85 | ||
|
|
c03bf80864 | ||
|
|
299cea0601 | ||
|
|
a12ccf2c1d | ||
|
|
1c56857f0c | ||
|
|
3d443e0126 | ||
|
|
ec2d3307fd | ||
|
|
e4d8f7af61 | ||
|
|
19f840cde7 | ||
|
|
c9ff09a418 | ||
|
|
ee3befb9fc | ||
|
|
16981d6316 | ||
|
|
34131c2948 | ||
|
|
87deb19bcb | ||
|
|
6fef6ac3a2 | ||
|
|
4433ef47fe | ||
|
|
4d5f70c694 | ||
|
|
f8fd2ec4ad | ||
|
|
4a5d978abb | ||
|
|
e0ebeacd4d | ||
|
|
d9a1db044a | ||
|
|
47c5334502 | ||
|
|
950a21a020 | ||
|
|
bad48d0722 | ||
|
|
c8edd1fb25 | ||
|
|
53a121d9e1 | ||
|
|
74b63a4ba4 | ||
|
|
362948324c | ||
|
|
4cac7feb67 | ||
|
|
d6b2e86155 | ||
|
|
7132d5a86a | ||
|
|
55f18a34a9 | ||
|
|
2c3ba95768 | ||
|
|
6ede3271ff | ||
|
|
0e9c0f621a | ||
|
|
47c1e09c75 | ||
|
|
9a2b1a5cf7 | ||
|
|
9c12b1c7da | ||
|
|
0db59b45b8 | ||
|
|
ef0ede7c13 | ||
|
|
62b94d5abf | ||
|
|
318eff7327 | ||
|
|
211564a6da | ||
|
|
7a8e8f890f | ||
|
|
7b47e43fd0 | ||
|
|
fc857d987b | ||
|
|
a849c29288 | ||
|
|
1f013055d2 | ||
|
|
2e887598ba | ||
|
|
aa94488065 | ||
|
|
163b71e019 | ||
|
|
a098809294 | ||
|
|
95325c4673 | ||
|
|
68c9a8177c | ||
|
|
f314685a8e | ||
|
|
0b34197815 | ||
|
|
b627011463 | ||
|
|
2aa9348759 | ||
|
|
6217cb636f | ||
|
|
2a458a4802 | ||
|
|
989744aba2 | ||
|
|
4dfee727e8 | ||
|
|
b2fd56094f | ||
|
|
03146b21be | ||
|
|
e0172a24b8 | ||
|
|
bd42e336c7 | ||
|
|
84d3e3d25f | ||
|
|
a194393efc | ||
|
|
bc8e9513bf | ||
|
|
f4094829c2 | ||
|
|
657377b0ab | ||
|
|
8019c8b665 | ||
|
|
4c73b040c8 | ||
|
|
d3a208eb8a | ||
|
|
7d0cb39f2a | ||
|
|
553932dc72 | ||
|
|
da7a74e604 | ||
|
|
15f3ea8d05 | ||
|
|
62350f2e5f | ||
|
|
e5ddb3bbd6 | ||
|
|
f425c9d315 | ||
|
|
a8500abd8f | ||
|
|
ee9ece8992 | ||
|
|
7468904968 | ||
|
|
8a68a96f77 | ||
|
|
fa34e0fae3 | ||
|
|
54679c5f49 | ||
|
|
d1d9011f4d | ||
|
|
9f476b2ce2 | ||
|
|
70ef40eb33 | ||
|
|
2e5016713a | ||
|
|
9a5e8a4b70 | ||
|
|
daa4b1dc65 | ||
|
|
c7aeb2160e | ||
|
|
4834390e6a | ||
|
|
bdd50c7553 | ||
|
|
999dca76c1 | ||
|
|
63e17ca546 | ||
|
|
a3bfbd0186 | ||
|
|
cc9fd88c0d | ||
|
|
96b0bcfd78 | ||
|
|
4ac0bb1bed | ||
|
|
92680b3fe4 | ||
|
|
4f5f8fd216 | ||
|
|
36f7a3f524 | ||
|
|
0fdcd8b27e | ||
|
|
20b1eabb9b | ||
|
|
b7ac697dce | ||
|
|
abf2943e4d | ||
|
|
43721f1206 | ||
|
|
0e8fa54f81 | ||
|
|
ad2998598f | ||
|
|
69d5f766a8 | ||
|
|
18c2376b50 | ||
|
|
39f1b714a5 | ||
|
|
0baac62099 | ||
|
|
046c096d86 | ||
|
|
de3af85ee1 | ||
|
|
cc1bb69671 | ||
|
|
30ca30370d | ||
|
|
710406aa76 | ||
|
|
ee3a56714e | ||
|
|
a095b08758 | ||
|
|
bfdab40aaf | ||
|
|
55d9d57112 | ||
|
|
f3e4347a8b | ||
|
|
d4351668ba | ||
|
|
ac66ae813f | ||
|
|
038ef32454 | ||
|
|
994de1f812 | ||
|
|
36f3cd1f70 | ||
|
|
ef9e5e523d |
9
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
9
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
@@ -15,14 +15,9 @@ body:
|
||||
id: bug-description
|
||||
attributes:
|
||||
label: Bug description
|
||||
description: A clear and concise description of what the bug is.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: repro-steps
|
||||
attributes:
|
||||
label: How to reproduce the bug
|
||||
description: A clear description of what the bug is, including reproduction steps and expected behavior.
|
||||
placeholder: |
|
||||
The bug is that...
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
|
||||
21
.github/workflows/bashlib.sh
vendored
21
.github/workflows/bashlib.sh
vendored
@@ -162,7 +162,11 @@ cypress-run-all() {
|
||||
USE_DASHBOARD_FLAG='--use-dashboard'
|
||||
fi
|
||||
|
||||
python ../../scripts/cypress_run.py --parallelism $PARALLELISM --parallelism-id $PARALLEL_ID $USE_DASHBOARD_FLAG
|
||||
# UNCOMMENT the next few commands to monitor memory usage
|
||||
# monitor_memory & # Start memory monitoring in the background
|
||||
# memoryMonitorPid=$!
|
||||
python ../../scripts/cypress_run.py --parallelism $PARALLELISM --parallelism-id $PARALLEL_ID --group $PARALLEL_ID --retries 5 $USE_DASHBOARD_FLAG
|
||||
# kill $memoryMonitorPid
|
||||
|
||||
# After job is done, print out Flask log for debugging
|
||||
echo "::group::Flask log for default run"
|
||||
@@ -178,6 +182,21 @@ eyes-storybook-dependencies() {
|
||||
say "::endgroup::"
|
||||
}
|
||||
|
||||
monitor_memory() {
|
||||
# This is a small utility to monitor memory usage. Useful for debugging memory in GHA.
|
||||
# To use wrap your command as follows
|
||||
#
|
||||
# monitor_memory & # Start memory monitoring in the background
|
||||
# memoryMonitorPid=$!
|
||||
# YOUR_COMMAND_HERE
|
||||
# kill $memoryMonitorPid
|
||||
while true; do
|
||||
echo "$(date) - Top 5 memory-consuming processes:"
|
||||
ps -eo pid,comm,%mem --sort=-%mem | head -n 6 # First line is the header, next 5 are top processes
|
||||
sleep 2
|
||||
done
|
||||
}
|
||||
|
||||
cypress-run-applitools() {
|
||||
cd "$GITHUB_WORKSPACE/superset-frontend/cypress-base"
|
||||
|
||||
|
||||
2
.github/workflows/dependency-review.yml
vendored
2
.github/workflows/dependency-review.yml
vendored
@@ -32,4 +32,4 @@ jobs:
|
||||
# license: https://applitools.com/legal/open-source-terms-of-use/
|
||||
# pkg:npm/node-forge@1.3.1
|
||||
# selecting BSD-3-Clause licensing terms for node-forge to ensure compatibility with Apache
|
||||
allow-dependencies-licenses: pkg:npm/store2@2.14.2, pkg:npm/applitools/core, pkg:npm/applitools/core-base, pkg:npm/applitools/css-tree, pkg:npm/applitools/ec-client, pkg:npm/applitools/eg-socks5-proxy-server, pkg:npm/applitools/eyes, pkg:npm/applitools/eyes-cypress, pkg:npm/applitools/nml-client, pkg:npm/applitools/tunnel-client, pkg:npm/applitools/utils, pkg:npm/node-forge@1.3.1
|
||||
allow-dependencies-licenses: pkg:npm/store2@2.14.2, pkg:npm/applitools/core, pkg:npm/applitools/core-base, pkg:npm/applitools/css-tree, pkg:npm/applitools/ec-client, pkg:npm/applitools/eg-socks5-proxy-server, pkg:npm/applitools/eyes, pkg:npm/applitools/eyes-cypress, pkg:npm/applitools/nml-client, pkg:npm/applitools/tunnel-client, pkg:npm/applitools/utils, pkg:npm/node-forge@1.3.1, pkg:npm/rgbcolor
|
||||
|
||||
2
.github/workflows/docker.yml
vendored
2
.github/workflows/docker.yml
vendored
@@ -21,7 +21,7 @@ jobs:
|
||||
steps:
|
||||
- id: set_matrix
|
||||
run: |
|
||||
MATRIX_CONFIG=$(if [ "${{ github.event_name }}" == "pull_request" ]; then echo '["dev"]'; else echo '["dev", "lean", "py310", "websocket", "dockerize"]'; fi)
|
||||
MATRIX_CONFIG=$(if [ "${{ github.event_name }}" == "pull_request" ]; then echo '["dev"]'; else echo '["dev", "lean", "py310", "websocket", "dockerize", "py311"]'; fi)
|
||||
echo "matrix_config=${MATRIX_CONFIG}" >> $GITHUB_OUTPUT
|
||||
echo $GITHUB_OUTPUT
|
||||
|
||||
|
||||
11
.github/workflows/superset-docs-verify.yml
vendored
11
.github/workflows/superset-docs-verify.yml
vendored
@@ -4,6 +4,7 @@ on:
|
||||
pull_request:
|
||||
paths:
|
||||
- "docs/**"
|
||||
- ".github/workflows/superset-docs-verify.yml"
|
||||
types: [synchronize, opened, reopened, ready_for_review]
|
||||
|
||||
# cancel previous workflow jobs for PRs
|
||||
@@ -19,7 +20,9 @@ jobs:
|
||||
continue-on-error: true # This will make the job advisory (non-blocking, no red X)
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: JustinBeckwith/linkinator-action@v1.10.4
|
||||
# Do not bump this linkinator-action version without opening
|
||||
# an ASF Infra ticket to allow the new verison first!
|
||||
- uses: JustinBeckwith/linkinator-action@v1.11.0
|
||||
with:
|
||||
paths: "**/*.md, **/*.mdx"
|
||||
linksToSkip: >-
|
||||
@@ -40,6 +43,12 @@ jobs:
|
||||
https://dev.mysql.com/doc/refman/5.7/en/innodb-limits.html,
|
||||
^https://img\.shields\.io/.*,
|
||||
https://vkusvill.ru/
|
||||
https://www.linkedin.com/in/mark-thomas-b16751158/
|
||||
https://theiconic.com.au/
|
||||
https://wattbewerb.de/
|
||||
https://timbr.ai/
|
||||
https://opensource.org/license/apache-2-0
|
||||
https://www.plaidcloud.com/
|
||||
build-deploy:
|
||||
name: Build & Deploy
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
4
.github/workflows/superset-e2e.yml
vendored
4
.github/workflows/superset-e2e.yml
vendored
@@ -48,7 +48,8 @@ jobs:
|
||||
PYTHONPATH: ${{ github.workspace }}
|
||||
REDIS_PORT: 16379
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
USE_DASHBOARD: ${{ github.event.inputs.use_dashboard || (github.ref == 'refs/heads/master' && 'true') || 'false' }}
|
||||
# use the dashboard feature when running manually OR merging to master
|
||||
USE_DASHBOARD: ${{ github.event.inputs.use_dashboard == 'true'|| (github.ref == 'refs/heads/master' && 'true') || 'false' }}
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:15-alpine
|
||||
@@ -131,6 +132,7 @@ jobs:
|
||||
PARALLEL_ID: ${{ matrix.parallel_id }}
|
||||
PARALLELISM: 6
|
||||
CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
|
||||
NODE_OPTIONS: "--max-old-space-size=4096"
|
||||
with:
|
||||
run: cypress-run-all ${{ env.USE_DASHBOARD }}
|
||||
- name: Upload Artifacts
|
||||
|
||||
2
.github/workflows/tag-release.yml
vendored
2
.github/workflows/tag-release.yml
vendored
@@ -42,7 +42,7 @@ jobs:
|
||||
runs-on: ubuntu-22.04
|
||||
strategy:
|
||||
matrix:
|
||||
build_preset: ["dev", "lean", "py310", "websocket", "dockerize"]
|
||||
build_preset: ["dev", "lean", "py310", "websocket", "dockerize", "py311"]
|
||||
fail-fast: false
|
||||
steps:
|
||||
- name: Set up QEMU
|
||||
|
||||
@@ -80,9 +80,9 @@ If you believe someone is violating this code of conduct, you may reply to them
|
||||
|
||||
Or one of our volunteers:
|
||||
|
||||
* [Mark Thomas](http://home.apache.org/~markt/coc.html)
|
||||
* [Joan Touzet](http://home.apache.org/~wohali/)
|
||||
* [Sharan Foga](http://home.apache.org/~sharan/coc.html)
|
||||
* [Mark Thomas](https://www.linkedin.com/in/mark-thomas-b16751158/)
|
||||
* [Joan Touzet](https://www.apache.org/foundation/conduct-team/wohali.html)
|
||||
* [Sharan Foga](https://www.linkedin.com/in/sfoga/)
|
||||
|
||||
If the violation is in documentation or code, for example inappropriate pronoun usage or word choice within official documentation, we ask that people report these privately to the project in question at <private@project.apache.org>, and, if they have sufficient ability within the project, to resolve or remove the concerning material, being mindful of the perspective of the person originally reporting the issue.
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ under the License.
|
||||
|
||||
# Superset
|
||||
|
||||
[](https://opensource.org/licenses/Apache-2.0)
|
||||
[](https://opensource.org/license/apache-2-0)
|
||||
[](https://github.com/apache/superset/tree/latest)
|
||||
[](https://github.com/apache/superset/actions)
|
||||
[](https://badge.fury.io/py/apache-superset)
|
||||
@@ -134,6 +134,8 @@ Here are some of the major database solutions that are supported:
|
||||
<img src="https://superset.apache.org/img/databases/starrocks.png" alt="starrocks" border="0" width="200" />
|
||||
<img src="https://superset.apache.org/img/databases/doris.png" alt="doris" border="0" width="200" />
|
||||
<img src="https://superset.apache.org/img/databases/oceanbase.svg" alt="oceanbase" border="0" width="220" />
|
||||
<img src="https://superset.apache.org/img/databases/sap-hana.png" alt="oceanbase" border="0" width="220" />
|
||||
<img src="https://superset.apache.org/img/databases/denodo.png" alt="denodo" border="0" width="200" />
|
||||
</p>
|
||||
|
||||
**A more comprehensive list of supported databases** along with the configuration instructions can be found [here](https://superset.apache.org/docs/configuration/databases).
|
||||
|
||||
@@ -137,4 +137,4 @@ There is now a [metadata bar](https://github.com/apache/superset/pull/27857) add
|
||||
|
||||
## Change to Docker image builds
|
||||
|
||||
Starting in 4.1.0, the release's docker image does not ship with drivers needed to operate Superset. Users may need to install a driver for their metadata database (MySQL or Postgres) as well as the driver for their data warehouse. This is a result of changes to the `lean` docker image that official releases come from; see [Docker Build Presets](/docs/installation/docker-builds/#build-presets) for more details.
|
||||
Starting in 4.1.0, the release's docker image does not ship with drivers needed to operate Superset. Users may need to install a driver for their metadata database (MySQL or Postgres) as well as the driver for their data warehouse. This is a result of changes to the `lean` docker image that official releases come from; see [Docker Build Presets](/docs/docs/installation/docker-builds.mdx#build-presets) for more details.
|
||||
|
||||
@@ -80,11 +80,11 @@ Join our growing community!
|
||||
- [Caizin](https://caizin.com/) [@tejaskatariya]
|
||||
- [Careem](https://www.careem.com/) [@SamraHanifCareem]
|
||||
- [Cloudsmith](https://cloudsmith.io) [@alancarson]
|
||||
- [CnOvit](https://www.cnovit.com/) [@xieshaohu]
|
||||
- [Cyberhaven](https://www.cyberhaven.com/) [@toliver-ch]
|
||||
- [Deepomatic](https://deepomatic.com/) [@Zanoellia]
|
||||
- [Dial Once](https://www.dial-once.com/)
|
||||
- [Dremio](https://dremio.com) [@narendrans]
|
||||
- [EFinance](https://www.efinance.com.eg) [@habeeb556]
|
||||
- [Elestio](https://elest.io/) [@kaiwalyakoparkar]
|
||||
- [ELMO Cloud HR & Payroll](https://elmosoftware.com.au/)
|
||||
- [Endress+Hauser](https://www.endress.com/) [@rumbin]
|
||||
@@ -96,7 +96,7 @@ Join our growing community!
|
||||
- [jampp](https://jampp.com/)
|
||||
- [Konfío](https://konfio.mx) [@uis-rodriguez]
|
||||
- [Mainstrat](https://mainstrat.com/)
|
||||
- [mishmash io](https://mishmash.io/)[@mishmash-io]
|
||||
- [mishmash io](https://mishmash.io/) [@mishmash-io]
|
||||
- [Myra Labs](https://www.myralabs.com/) [@viksit]
|
||||
- [Nielsen](https://www.nielsen.com/) [@amitNielsen]
|
||||
- [Ona](https://ona.io) [@pld]
|
||||
@@ -104,6 +104,7 @@ Join our growing community!
|
||||
- [Oslandia](https://oslandia.com)
|
||||
- [Peak AI](https://www.peak.ai/) [@azhar22k]
|
||||
- [PeopleDoc](https://www.people-doc.com) [@rodo]
|
||||
- [PlaidCloud](https://www.plaidcloud.com)
|
||||
- [Preset, Inc.](https://preset.io)
|
||||
- [PubNub](https://pubnub.com) [@jzucker2]
|
||||
- [ReadyTech](https://www.readytech.io)
|
||||
@@ -116,7 +117,7 @@ Join our growing community!
|
||||
- [timbr.ai](https://timbr.ai/) [@semantiDan]
|
||||
- [Tobii](https://www.tobii.com/) [@dwa]
|
||||
- [Tooploox](https://www.tooploox.com/) [@jakubczaplicki]
|
||||
- [Unvired](https://unvired.com)[@srinisubramanian]
|
||||
- [Unvired](https://unvired.com) [@srinisubramanian]
|
||||
- [Whale](https://whale.im)
|
||||
- [Windsor.ai](https://www.windsor.ai/) [@octaviancorlade]
|
||||
- [Zeta](https://www.zeta.tech/) [@shaikidris]
|
||||
@@ -129,7 +130,7 @@ Join our growing community!
|
||||
- [Kuaishou](https://www.kuaishou.com/) [@zhaoyu89730105]
|
||||
- [Netflix](https://www.netflix.com/)
|
||||
- [Prensa Iberica](https://www.prensaiberica.es/) [@zamar-roura]
|
||||
- [TME QQMUSIC/WESING](https://www.tencentmusic.com/)[@shenyuanli,@marklaw]
|
||||
- [TME QQMUSIC/WESING](https://www.tencentmusic.com/) [@shenyuanli,@marklaw]
|
||||
- [Xite](https://xite.com/) [@shashankkoppar]
|
||||
- [Zaihang](https://www.zaih.com/)
|
||||
|
||||
@@ -138,7 +139,7 @@ Join our growing community!
|
||||
- [Brilliant.org](https://brilliant.org/)
|
||||
- [Platzi.com](https://platzi.com/)
|
||||
- [Sunbird](https://www.sunbird.org/) [@eksteporg]
|
||||
- [The GRAPH Network](https://thegraphnetwork.org/)[@fccoelho]
|
||||
- [The GRAPH Network](https://thegraphnetwork.org/) [@fccoelho]
|
||||
- [Udemy](https://www.udemy.com/) [@sungjuly]
|
||||
- [VIPKID](https://www.vipkid.com.cn/) [@illpanda]
|
||||
- [WikiMedia Foundation](https://wikimediafoundation.org) [@vg]
|
||||
@@ -153,21 +154,24 @@ Join our growing community!
|
||||
### Healthcare
|
||||
- [Amino](https://amino.com) [@shkr]
|
||||
- [Bluesquare](https://www.bluesquarehub.com/) [@madewulf]
|
||||
- [Care](https://www.getcare.io/)[@alandao2021]
|
||||
- [Care](https://www.getcare.io/) [@alandao2021]
|
||||
- [Living Goods](https://www.livinggoods.org) [@chelule]
|
||||
- [Maieutical Labs](https://maieuticallabs.it) [@xrmx]
|
||||
- [Medic](https://medic.org) [@1yuv]
|
||||
- [REDCap Cloud](https://www.redcapcloud.com/)
|
||||
- [TrustMedis](https://trustmedis.com/) [@famasya]
|
||||
- [WeSure](https://www.wesure.cn/)
|
||||
- [2070Health](https://2070health.com/)
|
||||
|
||||
### HR / Staffing
|
||||
- [Swile](https://www.swile.co/) [@PaoloTerzi]
|
||||
- [Symmetrics](https://www.symmetrics.fyi)
|
||||
- [bluquist](https://bluquist.com/)
|
||||
|
||||
### Government
|
||||
### Government / Non-Profit
|
||||
- [City of Ann Arbor, MI](https://www.a2gov.org/) [@sfirke]
|
||||
- [RIS3 Strategy of CZ, MIT CR](https://www.ris3.cz/) [@RIS3CZ]
|
||||
- [NRLM - Sarathi, India](https://pib.gov.in/PressReleasePage.aspx?PRID=1999586)
|
||||
|
||||
### Travel
|
||||
- [Agoda](https://www.agoda.com/) [@lostseaway, @maiake, @obombayo]
|
||||
@@ -184,6 +188,6 @@ Join our growing community!
|
||||
- [komoot](https://www.komoot.com/) [@christophlingg]
|
||||
- [Let's Roam](https://www.letsroam.com/)
|
||||
- [Onebeat](https://1beat.com/) [@GuyAttia]
|
||||
- [Twitter](https://twitter.com/)
|
||||
- [X](https://x.com/)
|
||||
- [VLMedia](https://www.vlmedia.com.tr/) [@ibotheperfect]
|
||||
- [Yahoo!](https://yahoo.com/)
|
||||
|
||||
@@ -22,7 +22,11 @@ set -e
|
||||
#
|
||||
/app/docker/docker-bootstrap.sh
|
||||
|
||||
STEP_CNT=4
|
||||
if [ "$SUPERSET_LOAD_EXAMPLES" = "yes" ]; then
|
||||
STEP_CNT=4
|
||||
else
|
||||
STEP_CNT=3
|
||||
fi
|
||||
|
||||
echo_step() {
|
||||
cat <<EOF
|
||||
|
||||
@@ -16,6 +16,7 @@ KIND, either express or implied. See the License for the
|
||||
specific language governing permissions and limitations
|
||||
under the License.
|
||||
-->
|
||||
|
||||
This is the public documentation site for Superset, built using
|
||||
[Docusaurus 2](https://docusaurus.io/). See
|
||||
[CONTRIBUTING.md](../CONTRIBUTING.md#documentation) for documentation on
|
||||
|
||||
@@ -13,7 +13,7 @@ SimpleCache (in-memory), or the local filesystem.
|
||||
[Custom cache backends](https://flask-caching.readthedocs.io/en/latest/#custom-cache-backends)
|
||||
are also supported.
|
||||
|
||||
Caching can be configured by providing a dictionaries in
|
||||
Caching can be configured by providing dictionaries in
|
||||
`superset_config.py` that comply with [the Flask-Caching config specifications](https://flask-caching.readthedocs.io/en/latest/#configuring-flask-caching).
|
||||
|
||||
The following cache configurations can be customized in this way:
|
||||
@@ -22,7 +22,7 @@ The following cache configurations can be customized in this way:
|
||||
- Metadata cache (optional): `CACHE_CONFIG`
|
||||
- Charting data queried from datasets (optional): `DATA_CACHE_CONFIG`
|
||||
|
||||
For example, to configure the filter state cache using redis:
|
||||
For example, to configure the filter state cache using Redis:
|
||||
|
||||
```python
|
||||
FILTER_STATE_CACHE_CONFIG = {
|
||||
|
||||
@@ -55,7 +55,8 @@ are compatible with Superset.
|
||||
| [ClickHouse](/docs/configuration/databases#clickhouse) | `pip install clickhouse-connect` | `clickhousedb://{username}:{password}@{hostname}:{port}/{database}` |
|
||||
| [CockroachDB](/docs/configuration/databases#cockroachdb) | `pip install cockroachdb` | `cockroachdb://root@{hostname}:{port}/{database}?sslmode=disable` |
|
||||
| [Couchbase](/docs/configuration/databases#couchbase) | `pip install couchbase-sqlalchemy` | `couchbase://{username}:{password}@{hostname}:{port}?truststorepath={ssl certificate path}` |
|
||||
| [Dremio](/docs/configuration/databases#dremio) | `pip install sqlalchemy_dremio` |`dremio+flight://{username}:{password}@{host}:31010, For ODBC dremio+pyodbc://{username}:{password}@{host}:32010` |
|
||||
| [Denodo](/docs/configuration/databases#denodo) | `pip install denodo-sqlalchemy` | `denodo://{username}:{password}@{hostname}:{port}/{database}` |
|
||||
| [Dremio](/docs/configuration/databases#dremio) | `pip install sqlalchemy_dremio` |`dremio+flight://{username}:{password}@{host}:32010`, often useful: `?UseEncryption=true/false`. For Legacy ODBC: `dremio+pyodbc://{username}:{password}@{host}:31010` |
|
||||
| [Elasticsearch](/docs/configuration/databases#elasticsearch) | `pip install elasticsearch-dbapi` | `elasticsearch+http://{user}:{password}@{host}:9200/` |
|
||||
| [Exasol](/docs/configuration/databases#exasol) | `pip install sqlalchemy-exasol` | `exa+pyodbc://{username}:{password}@{hostname}:{port}/my_schema?CONNECTIONLCALL=en_US.UTF-8&driver=EXAODBC` |
|
||||
| [Google BigQuery](/docs/configuration/databases#google-bigquery) | `pip install sqlalchemy-bigquery` | `bigquery://{project_id}` |
|
||||
@@ -512,6 +513,16 @@ For a connection to a SQL endpoint you need to use the HTTP path from the endpoi
|
||||
```
|
||||
|
||||
|
||||
#### Denodo
|
||||
|
||||
The recommended connector library for Denodo is
|
||||
[denodo-sqlalchemy](https://pypi.org/project/denodo-sqlalchemy/).
|
||||
|
||||
The expected connection string is formatted as follows (default port is 9996):
|
||||
|
||||
```
|
||||
denodo://{username}:{password}@{hostname}:{port}/{database}
|
||||
```
|
||||
|
||||
|
||||
#### Dremio
|
||||
@@ -1307,6 +1318,10 @@ Here's what the connection string looks like:
|
||||
starrocks://<User>:<Password>@<Host>:<Port>/<Catalog>.<Database>
|
||||
```
|
||||
|
||||
:::note
|
||||
StarRocks maintains their Superset docuementation [here](https://docs.starrocks.io/docs/integrations/BI_integrations/Superset/).
|
||||
:::
|
||||
|
||||
#### Teradata
|
||||
|
||||
The recommended connector library is
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
---
|
||||
title: Network and Security Settings
|
||||
sidebar_position: 7
|
||||
|
||||
@@ -48,12 +48,15 @@ WHERE (
|
||||
{% if to_dttm is not none %}
|
||||
dttm_col < '{{ to_dttm }}' AND
|
||||
{% endif %}
|
||||
true
|
||||
1 = 1
|
||||
)
|
||||
```
|
||||
|
||||
Note how the Jinja parameters are called within double brackets in the query, and without in the
|
||||
logic blocks.
|
||||
The `1 = 1` at the end ensures a value is present for the `WHERE` clause even when
|
||||
the time filter is not set. For many database engines, this could be replaced with `true`.
|
||||
|
||||
Note that the Jinja parameters are called within _double_ brackets in the query and with
|
||||
_single_ brackets in the logic blocks.
|
||||
|
||||
To add custom functionality to the Jinja context, you need to overload the default Jinja
|
||||
context in your environment by defining the `JINJA_CONTEXT_ADDONS` in your superset configuration
|
||||
|
||||
@@ -29,7 +29,7 @@ cd superset
|
||||
|
||||
## docker compose (recommended!)
|
||||
|
||||
Setting things up to squeeze an "hello world" into any part of Superset should be as simple as
|
||||
Setting things up to squeeze a "hello world" into any part of Superset should be as simple as
|
||||
|
||||
```bash
|
||||
docker compose up
|
||||
@@ -45,7 +45,7 @@ Note that:
|
||||
- **Postgres** as the metadata database and to store example datasets, charts and dashboards which
|
||||
should be populated upon startup
|
||||
- **Redis** as the message queue for our async backend and caching backend
|
||||
- It'll load up examples into the database upon first startup
|
||||
- It'll load up examples into the database upon the first startup
|
||||
- all other details and pointers available in
|
||||
[docker-compose.yml](https://github.com/apache/superset/blob/master/docker-compose.yml)
|
||||
- The local repository is mounted within the services, meaning updating
|
||||
@@ -53,6 +53,13 @@ Note that:
|
||||
- Superset is served at localhost:8088/
|
||||
- You can login with admin/admin
|
||||
|
||||
:::note
|
||||
Installing and building Node modules for Apache Superset inside `superset-node` can take a
|
||||
significant amount of time. This is normal due to the size of the dependencies. Please be
|
||||
patient while the process completes, as long wait times do not indicate an issue with your setup.
|
||||
If delays seem excessive, check your internet connection or system resources.
|
||||
:::
|
||||
|
||||
:::caution
|
||||
Since `docker compose` is primarily designed to run a set of containers on **a single host**
|
||||
and can't credibly support **high availability** as a result, we do not support nor recommend
|
||||
@@ -136,12 +143,11 @@ You can also run the pre-commit checks manually in various ways:
|
||||
Replace `<hook_id>` with the ID of the specific hook you want to run. You can find the list
|
||||
of available hooks in the `.pre-commit-config.yaml` file.
|
||||
|
||||
|
||||
## Alternatives to `docker compose`
|
||||
|
||||
:::caution
|
||||
This part of the documentation is a patchwork of information related to setting up
|
||||
development environments without `docker compose` and are documented/supported to varying
|
||||
development environments without `docker compose` and is documented/supported to varying
|
||||
degrees. It's been difficult to maintain this wide array of methods and insure they're
|
||||
functioning across environments.
|
||||
:::
|
||||
@@ -181,11 +187,11 @@ superset load-examples
|
||||
|
||||
# Start the Flask dev web server from inside your virtualenv.
|
||||
# Note that your page may not have CSS at this point.
|
||||
# See instructions below how to build the front-end assets.
|
||||
# See instructions below on how to build the front-end assets.
|
||||
superset run -p 8088 --with-threads --reload --debugger --debug
|
||||
```
|
||||
|
||||
Or you can install via our Makefile
|
||||
Or you can install it via our Makefile
|
||||
|
||||
```bash
|
||||
# Create a virtual environment and activate it (recommended)
|
||||
@@ -203,7 +209,7 @@ $ make pre-commit
|
||||
```
|
||||
|
||||
**Note: the FLASK_APP env var should not need to be set, as it's currently controlled
|
||||
via `.flaskenv`, however if needed, it should be set to `superset.app:create_app()`**
|
||||
via `.flaskenv`, however, if needed, it should be set to `superset.app:create_app()`**
|
||||
|
||||
If you have made changes to the FAB-managed templates, which are not built the same way as the newer, React-powered front-end assets, you need to start the app without the `--with-threads` argument like so:
|
||||
`superset run -p 8088 --reload --debugger --debug`
|
||||
@@ -306,7 +312,7 @@ cd superset-frontend
|
||||
npm ci
|
||||
```
|
||||
|
||||
Note that Superset uses [Scarf](https://docs.scarf.sh) to capture telemetry/analytics about versions being installed, including the `scarf-js` npm package and an analytics pixel. As noted elsewhere in this documentation, Scarf gathers aggregated stats for the sake of security/release strategy, and does not capture/retain PII. [You can read here](https://docs.scarf.sh/package-analytics/) about the `scarf-js` package, and various means to opt out of it, but you can opt out of the npm package _and_ the pixel by setting the `SCARF_ANALYTICS` environment variable to `false` or opt out of the pixel by adding this setting in `superset-frontent/package.json`:
|
||||
Note that Superset uses [Scarf](https://docs.scarf.sh) to capture telemetry/analytics about versions being installed, including the `scarf-js` npm package and an analytics pixel. As noted elsewhere in this documentation, Scarf gathers aggregated stats for the sake of security/release strategy and does not capture/retain PII. [You can read here](https://docs.scarf.sh/package-analytics/) about the `scarf-js` package, and various means to opt out of it, but you can opt out of the npm package _and_ the pixel by setting the `SCARF_ANALYTICS` environment variable to `false` or opt out of the pixel by adding this setting in `superset-frontent/package.json`:
|
||||
|
||||
```json
|
||||
// your-package/package.json
|
||||
@@ -334,7 +340,7 @@ 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.
|
||||
You can address this error by increasing the number of inotify watchers.
|
||||
|
||||
The current value of max watches can be checked with:
|
||||
|
||||
@@ -345,13 +351,13 @@ 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.
|
||||
Open the file in an 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.
|
||||
Save the file and exit the editor.
|
||||
To confirm that the change succeeded, run the following command to load the updated value of max_user_watches from `sysctl.conf`:
|
||||
|
||||
```bash
|
||||
@@ -449,7 +455,7 @@ pre-commit install
|
||||
|
||||
A series of checks will now run when you make a git commit.
|
||||
|
||||
Alternatively it is possible to run pre-commit via tox:
|
||||
Alternatively, it is possible to run pre-commit via tox:
|
||||
|
||||
```bash
|
||||
tox -e pre-commit
|
||||
@@ -533,7 +539,7 @@ commands are invoked.
|
||||
There is also a utility script included in the Superset codebase to run python integration tests. The [readme can be
|
||||
found here](https://github.com/apache/superset/tree/master/scripts/tests)
|
||||
|
||||
To run all integration tests for example, run this script from the root directory:
|
||||
To run all integration tests, for example, run this script from the root directory:
|
||||
|
||||
```bash
|
||||
scripts/tests/run.sh
|
||||
@@ -608,14 +614,14 @@ As an alternative you can use docker compose environment for testing:
|
||||
Make sure you have added below line to your /etc/hosts file:
|
||||
`127.0.0.1 db`
|
||||
|
||||
If you already have launched Docker environment please use the following command to assure a fresh database instance:
|
||||
If you already have launched Docker environment please use the following command to ensure a fresh database instance:
|
||||
`docker compose down -v`
|
||||
|
||||
Launch environment:
|
||||
|
||||
`CYPRESS_CONFIG=true docker compose up`
|
||||
|
||||
It will serve backend and frontend on port 8088.
|
||||
It will serve the backend and frontend on port 8088.
|
||||
|
||||
Run Cypress tests:
|
||||
|
||||
@@ -657,7 +663,7 @@ For debugging locally using VSCode, you can configure a launch configuration fil
|
||||
Follow these instructions to debug the Flask app running inside a docker container. Note that
|
||||
this will run a barebones Superset web server,
|
||||
|
||||
First add the following to the ./docker-compose.yaml file
|
||||
First, add the following to the ./docker-compose.yaml file
|
||||
|
||||
```diff
|
||||
superset:
|
||||
@@ -779,11 +785,11 @@ Often in a Kubernetes environment nodes are not addressable from outside the clu
|
||||
kubectl port-forward pod/superset-<some random id> 5678:5678
|
||||
```
|
||||
|
||||
You can now launch your VSCode debugger with the same config as above. VSCode will connect to to 127.0.0.1:5678 which is forwarded by kubectl to your remote kubernetes POD.
|
||||
You can now launch your VSCode debugger with the same config as above. VSCode will connect to 127.0.0.1:5678 which is forwarded by kubectl to your remote kubernetes POD.
|
||||
|
||||
### Storybook
|
||||
|
||||
Superset includes a [Storybook](https://storybook.js.org/) to preview the layout/styling of various Superset components, and variations thereof. To open and view the Storybook:
|
||||
Superset includes a [Storybook](https://storybook.js.org/) to preview the layout/styling of various Superset components and variations thereof. To open and view the Storybook:
|
||||
|
||||
```bash
|
||||
cd superset-frontend
|
||||
@@ -933,7 +939,7 @@ To fix it:
|
||||
from alembic import op
|
||||
```
|
||||
|
||||
Alternatively you may also run `superset db merge` to create a migration script
|
||||
Alternatively, you may also run `superset db merge` to create a migration script
|
||||
just for merging the heads.
|
||||
|
||||
```bash
|
||||
|
||||
@@ -174,13 +174,16 @@ You can take a look at this Flask-AppBuilder
|
||||
## Is there a way to force the dashboard to use specific colors?
|
||||
|
||||
It is possible on a per-dashboard basis by providing a mapping of labels to colors in the JSON
|
||||
Metadata attribute using the `label_colors` key.
|
||||
Metadata attribute using the `label_colors` key. You can use either the full hex color, a named color,
|
||||
like `red`, `coral` or `lightblue`, or the index in the current color palette (0 for first color, 1 for
|
||||
second etc). Example:
|
||||
|
||||
```json
|
||||
{
|
||||
"label_colors": {
|
||||
"Girls": "#FF69B4",
|
||||
"Boys": "#ADD8E6"
|
||||
"foo": "#FF69B4",
|
||||
"bar": "lightblue",
|
||||
"baz": 0
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -22,18 +22,18 @@ level dependencies.
|
||||
|
||||
**Debian and Ubuntu**
|
||||
|
||||
The following command will ensure that the required dependencies are installed:
|
||||
|
||||
```bash
|
||||
sudo apt-get install build-essential libssl-dev libffi-dev python-dev python-pip libsasl2-dev libldap2-dev default-libmysqlclient-dev
|
||||
```
|
||||
|
||||
In Ubuntu 20.04 the following command will ensure that the required dependencies are installed:
|
||||
In Ubuntu **20.04 and 22.04** the following command will ensure that the required dependencies are installed:
|
||||
|
||||
```bash
|
||||
sudo apt-get install build-essential libssl-dev libffi-dev python3-dev python3-pip libsasl2-dev libldap2-dev default-libmysqlclient-dev
|
||||
```
|
||||
|
||||
In Ubuntu **before 20.04** the following command will ensure that the required dependencies are installed:
|
||||
|
||||
```bash
|
||||
sudo apt-get install build-essential libssl-dev libffi-dev python-dev python-pip libsasl2-dev libldap2-dev default-libmysqlclient-dev
|
||||
```
|
||||
|
||||
**Fedora and RHEL-derivative Linux distributions**
|
||||
|
||||
Install the following packages using the `yum` package manager:
|
||||
|
||||
@@ -19,17 +19,17 @@
|
||||
"dependencies": {
|
||||
"@algolia/client-search": "^4.24.0",
|
||||
"@ant-design/icons": "^5.4.0",
|
||||
"@docsearch/react": "^3.6.1",
|
||||
"@docsearch/react": "^3.6.3",
|
||||
"@docusaurus/core": "^3.5.2",
|
||||
"@docusaurus/plugin-client-redirects": "^3.5.2",
|
||||
"@docusaurus/preset-classic": "^3.5.2",
|
||||
"@emotion/core": "^10.1.1",
|
||||
"@emotion/styled": "^10.0.27",
|
||||
"@mdx-js/react": "^3.0.0",
|
||||
"@saucelabs/theme-github-codeblock": "^0.2.3",
|
||||
"@mdx-js/react": "^3.1.0",
|
||||
"@saucelabs/theme-github-codeblock": "^0.3.0",
|
||||
"@superset-ui/style": "^0.14.23",
|
||||
"@svgr/webpack": "^8.1.0",
|
||||
"antd": "^5.20.5",
|
||||
"antd": "^5.21.6",
|
||||
"buffer": "^6.0.3",
|
||||
"clsx": "^2.1.1",
|
||||
"docusaurus-plugin-less": "^2.0.2",
|
||||
@@ -48,9 +48,9 @@
|
||||
"devDependencies": {
|
||||
"@docusaurus/module-type-aliases": "^3.5.2",
|
||||
"@docusaurus/tsconfig": "^3.5.2",
|
||||
"@types/react": "^18.3.5",
|
||||
"typescript": "^5.5.4",
|
||||
"webpack": "^5.94.0"
|
||||
"@types/react": "^18.3.12",
|
||||
"typescript": "^5.6.3",
|
||||
"webpack": "^5.96.1"
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
|
||||
@@ -132,4 +132,9 @@ export const Databases = [
|
||||
href: 'https://www.couchbase.com/',
|
||||
imgName: 'couchbase.svg',
|
||||
},
|
||||
{
|
||||
title: 'Denodo',
|
||||
href: 'https://www.denodo.com/',
|
||||
imgName: 'denodo.png',
|
||||
},
|
||||
];
|
||||
|
||||
BIN
docs/static/img/databases/denodo.png
vendored
Normal file
BIN
docs/static/img/databases/denodo.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
102
docs/static/resources/openapi.json
vendored
102
docs/static/resources/openapi.json
vendored
@@ -116,7 +116,8 @@
|
||||
"GENERIC_BACKEND_ERROR",
|
||||
"INVALID_PAYLOAD_FORMAT_ERROR",
|
||||
"INVALID_PAYLOAD_SCHEMA_ERROR",
|
||||
"REPORT_NOTIFICATION_ERROR"
|
||||
"REPORT_NOTIFICATION_ERROR",
|
||||
"RESULT_TOO_LARGE_ERROR"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
@@ -3007,6 +3008,33 @@
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"DashboardNativeFiltersConfigUpdateSchema": {
|
||||
"properties": {
|
||||
"deleted": {
|
||||
"description": "List of filter ids to delete",
|
||||
"items": {
|
||||
"type": "integer"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"modified": {
|
||||
"description": "List of filter objects to update",
|
||||
"items": {
|
||||
"type": "object"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"reordered": {
|
||||
"description": "List of filter ids in the new order",
|
||||
"items": {
|
||||
"type": "integer"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"required": ["deleted", "modified", "reordered"],
|
||||
"type": "object"
|
||||
},
|
||||
"DashboardCopySchema": {
|
||||
"properties": {
|
||||
"css": {
|
||||
@@ -3052,6 +3080,12 @@
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"column_names": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"currency_formats": {
|
||||
"type": "object"
|
||||
},
|
||||
@@ -13488,6 +13522,72 @@
|
||||
"tags": ["Dashboards"]
|
||||
}
|
||||
},
|
||||
"/api/v1/dashboard/{id_or_slug}/filters/": {
|
||||
"put": {
|
||||
"description": "Update the filters for a given dashboard",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "path",
|
||||
"name": "id_or_slug",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/DashboardNativeFiltersConfigUpdateSchema"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": true
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"properties": {
|
||||
"result": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object"
|
||||
}
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "Successfully updated the filters"
|
||||
},
|
||||
"400": {
|
||||
"$ref": "#/components/responses/400"
|
||||
},
|
||||
"401": {
|
||||
"$ref": "#/components/responses/401"
|
||||
},
|
||||
"403": {
|
||||
"$ref": "#/components/responses/403"
|
||||
},
|
||||
"404": {
|
||||
"$ref": "#/components/responses/404"
|
||||
},
|
||||
"500": {
|
||||
"$ref": "#/components/responses/500"
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"jwt": []
|
||||
}
|
||||
],
|
||||
"tags": ["Dashboards"]
|
||||
}
|
||||
},
|
||||
"/api/v1/dashboard/{id_or_slug}/copy/": {
|
||||
"post": {
|
||||
"parameters": [
|
||||
|
||||
588
docs/yarn.lock
588
docs/yarn.lock
@@ -17,12 +17,17 @@
|
||||
dependencies:
|
||||
"@algolia/autocomplete-shared" "1.9.3"
|
||||
|
||||
"@algolia/autocomplete-preset-algolia@1.9.3":
|
||||
version "1.9.3"
|
||||
resolved "https://registry.yarnpkg.com/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.9.3.tgz#64cca4a4304cfcad2cf730e83067e0c1b2f485da"
|
||||
integrity sha512-d4qlt6YmrLMYy95n5TB52wtNDr6EgAIPH81dvvvW8UmuWRgxEtY0NJiPwl/h95JtG2vmRM804M0DSwMCNZlzRA==
|
||||
"@algolia/autocomplete-preset-algolia@1.17.6":
|
||||
version "1.17.6"
|
||||
resolved "https://registry.yarnpkg.com/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.17.6.tgz#465b652bff5c262aad4da2488d78629cfa906be6"
|
||||
integrity sha512-Cvg5JENdSCMuClwhJ1ON1/jSuojaYMiUW2KePm18IkdCzPJj/NXojaOxw58RFtQFpJgfVW8h2E8mEoDtLlMdeA==
|
||||
dependencies:
|
||||
"@algolia/autocomplete-shared" "1.9.3"
|
||||
"@algolia/autocomplete-shared" "1.17.6"
|
||||
|
||||
"@algolia/autocomplete-shared@1.17.6":
|
||||
version "1.17.6"
|
||||
resolved "https://registry.yarnpkg.com/@algolia/autocomplete-shared/-/autocomplete-shared-1.17.6.tgz#ad951632b6d477d4ba9a68a347e1702d26009d58"
|
||||
integrity sha512-aq/3V9E00Tw2GC/PqgyPGXtqJUlVc17v4cn1EUhSc+O/4zd04Uwb3UmPm8KDaYQQOrkt1lwvCj2vG2wRE5IKhw==
|
||||
|
||||
"@algolia/autocomplete-shared@1.9.3":
|
||||
version "1.9.3"
|
||||
@@ -53,6 +58,16 @@
|
||||
dependencies:
|
||||
"@algolia/cache-common" "4.23.3"
|
||||
|
||||
"@algolia/client-abtesting@5.12.0":
|
||||
version "5.12.0"
|
||||
resolved "https://registry.yarnpkg.com/@algolia/client-abtesting/-/client-abtesting-5.12.0.tgz#45175422ee85d505ff6a16d1634a739478a6ad0b"
|
||||
integrity sha512-hx4eVydkm3yrFCFxmcBtSzI/ykt0cZ6sDWch+v3JTgKpD2WtosMJU3Upv1AjQ4B6COSHCOWEX3vfFxW6OoH6aA==
|
||||
dependencies:
|
||||
"@algolia/client-common" "5.12.0"
|
||||
"@algolia/requester-browser-xhr" "5.12.0"
|
||||
"@algolia/requester-fetch" "5.12.0"
|
||||
"@algolia/requester-node-http" "5.12.0"
|
||||
|
||||
"@algolia/client-account@4.23.3":
|
||||
version "4.23.3"
|
||||
resolved "https://registry.yarnpkg.com/@algolia/client-account/-/client-account-4.23.3.tgz#8751bbf636e6741c95e7c778488dee3ee430ac6f"
|
||||
@@ -72,6 +87,16 @@
|
||||
"@algolia/requester-common" "4.23.3"
|
||||
"@algolia/transporter" "4.23.3"
|
||||
|
||||
"@algolia/client-analytics@5.12.0":
|
||||
version "5.12.0"
|
||||
resolved "https://registry.yarnpkg.com/@algolia/client-analytics/-/client-analytics-5.12.0.tgz#e387f4de01f4fb549b7506762003bef335be2927"
|
||||
integrity sha512-EpTsSv6IW8maCfXCDIptgT7+mQJj7pImEkcNUnxR8yUKAHzTogTXv9yGm2WXOZFVuwstd2i0sImhQ1Vz8RH/hA==
|
||||
dependencies:
|
||||
"@algolia/client-common" "5.12.0"
|
||||
"@algolia/requester-browser-xhr" "5.12.0"
|
||||
"@algolia/requester-fetch" "5.12.0"
|
||||
"@algolia/requester-node-http" "5.12.0"
|
||||
|
||||
"@algolia/client-common@4.23.3":
|
||||
version "4.23.3"
|
||||
resolved "https://registry.yarnpkg.com/@algolia/client-common/-/client-common-4.23.3.tgz#891116aa0db75055a7ecc107649f7f0965774704"
|
||||
@@ -88,6 +113,21 @@
|
||||
"@algolia/requester-common" "4.24.0"
|
||||
"@algolia/transporter" "4.24.0"
|
||||
|
||||
"@algolia/client-common@5.12.0":
|
||||
version "5.12.0"
|
||||
resolved "https://registry.yarnpkg.com/@algolia/client-common/-/client-common-5.12.0.tgz#e33b6fefb333beb56eb58ab7424fcd7ec11ac7d0"
|
||||
integrity sha512-od3WmO8qxyfNhKc+K3D17tvun3IMs/xMNmxCG9MiElAkYVbPPTRUYMkRneCpmJyQI0hNx2/EA4kZgzVfQjO86Q==
|
||||
|
||||
"@algolia/client-insights@5.12.0":
|
||||
version "5.12.0"
|
||||
resolved "https://registry.yarnpkg.com/@algolia/client-insights/-/client-insights-5.12.0.tgz#bb80c4227178b452dd93a649b9991b8140cba52d"
|
||||
integrity sha512-8alajmsYUd+7vfX5lpRNdxqv3Xx9clIHLUItyQK0Z6gwGMbVEFe6YYhgDtwslMAP0y6b0WeJEIZJMLgT7VYpRw==
|
||||
dependencies:
|
||||
"@algolia/client-common" "5.12.0"
|
||||
"@algolia/requester-browser-xhr" "5.12.0"
|
||||
"@algolia/requester-fetch" "5.12.0"
|
||||
"@algolia/requester-node-http" "5.12.0"
|
||||
|
||||
"@algolia/client-personalization@4.23.3":
|
||||
version "4.23.3"
|
||||
resolved "https://registry.yarnpkg.com/@algolia/client-personalization/-/client-personalization-4.23.3.tgz#35fa8e5699b0295fbc400a8eb211dc711e5909db"
|
||||
@@ -97,6 +137,26 @@
|
||||
"@algolia/requester-common" "4.23.3"
|
||||
"@algolia/transporter" "4.23.3"
|
||||
|
||||
"@algolia/client-personalization@5.12.0":
|
||||
version "5.12.0"
|
||||
resolved "https://registry.yarnpkg.com/@algolia/client-personalization/-/client-personalization-5.12.0.tgz#ad711245403754686efff6a65d6c83877e64ecfa"
|
||||
integrity sha512-bUV9HtfkTBgpoVhxFrMkmVPG03ZN1Rtn51kiaEtukucdk3ggjR9Qu1YUfRSU2lFgxr9qJc8lTxwfvhjCeJRcqw==
|
||||
dependencies:
|
||||
"@algolia/client-common" "5.12.0"
|
||||
"@algolia/requester-browser-xhr" "5.12.0"
|
||||
"@algolia/requester-fetch" "5.12.0"
|
||||
"@algolia/requester-node-http" "5.12.0"
|
||||
|
||||
"@algolia/client-query-suggestions@5.12.0":
|
||||
version "5.12.0"
|
||||
resolved "https://registry.yarnpkg.com/@algolia/client-query-suggestions/-/client-query-suggestions-5.12.0.tgz#fc3bbf6d86e8989bb8487dc69ec49743fa75ceb4"
|
||||
integrity sha512-Q5CszzGWfxbIDs9DJ/QJsL7bP6h+lJMg27KxieEnI9KGCu0Jt5iFA3GkREkgRZxRdzlHbZKkrIzhtHVbSHw/rg==
|
||||
dependencies:
|
||||
"@algolia/client-common" "5.12.0"
|
||||
"@algolia/requester-browser-xhr" "5.12.0"
|
||||
"@algolia/requester-fetch" "5.12.0"
|
||||
"@algolia/requester-node-http" "5.12.0"
|
||||
|
||||
"@algolia/client-search@4.23.3":
|
||||
version "4.23.3"
|
||||
resolved "https://registry.yarnpkg.com/@algolia/client-search/-/client-search-4.23.3.tgz#a3486e6af13a231ec4ab43a915a1f318787b937f"
|
||||
@@ -106,6 +166,16 @@
|
||||
"@algolia/requester-common" "4.23.3"
|
||||
"@algolia/transporter" "4.23.3"
|
||||
|
||||
"@algolia/client-search@5.12.0":
|
||||
version "5.12.0"
|
||||
resolved "https://registry.yarnpkg.com/@algolia/client-search/-/client-search-5.12.0.tgz#cd3eb4854664177d6e992bb2b942e2a12e4cb919"
|
||||
integrity sha512-R3qzEytgVLHOGNri+bpta6NtTt7YtkvUe/QBcAmMDjW4Jk1P0eBYIPfvnzIPbINRsLxIq9fZs9uAYBgsrts4Zg==
|
||||
dependencies:
|
||||
"@algolia/client-common" "5.12.0"
|
||||
"@algolia/requester-browser-xhr" "5.12.0"
|
||||
"@algolia/requester-fetch" "5.12.0"
|
||||
"@algolia/requester-node-http" "5.12.0"
|
||||
|
||||
"@algolia/client-search@^4.24.0":
|
||||
version "4.24.0"
|
||||
resolved "https://registry.yarnpkg.com/@algolia/client-search/-/client-search-4.24.0.tgz#75e6c02d33ef3e0f34afd9962c085b856fc4a55f"
|
||||
@@ -120,6 +190,16 @@
|
||||
resolved "https://registry.yarnpkg.com/@algolia/events/-/events-4.0.1.tgz#fd39e7477e7bc703d7f893b556f676c032af3950"
|
||||
integrity sha512-FQzvOCgoFXAbf5Y6mYozw2aj5KCJoA3m4heImceldzPSMbdyS4atVjJzXKMsfX3wnZTFYwkkt8/z8UesLHlSBQ==
|
||||
|
||||
"@algolia/ingestion@1.12.0":
|
||||
version "1.12.0"
|
||||
resolved "https://registry.yarnpkg.com/@algolia/ingestion/-/ingestion-1.12.0.tgz#01a297fb2a58019595e5d74e95939da033a18194"
|
||||
integrity sha512-zpHo6qhR22tL8FsdSI4DvEraPDi/019HmMrCFB/TUX98yzh5ooAU7sNW0qPL1I7+S++VbBmNzJOEU9VI8tEC8A==
|
||||
dependencies:
|
||||
"@algolia/client-common" "5.12.0"
|
||||
"@algolia/requester-browser-xhr" "5.12.0"
|
||||
"@algolia/requester-fetch" "5.12.0"
|
||||
"@algolia/requester-node-http" "5.12.0"
|
||||
|
||||
"@algolia/logger-common@4.23.3":
|
||||
version "4.23.3"
|
||||
resolved "https://registry.yarnpkg.com/@algolia/logger-common/-/logger-common-4.23.3.tgz#35c6d833cbf41e853a4f36ba37c6e5864920bfe9"
|
||||
@@ -137,6 +217,16 @@
|
||||
dependencies:
|
||||
"@algolia/logger-common" "4.23.3"
|
||||
|
||||
"@algolia/monitoring@1.12.0":
|
||||
version "1.12.0"
|
||||
resolved "https://registry.yarnpkg.com/@algolia/monitoring/-/monitoring-1.12.0.tgz#f510bfd9d09352b31ccce293d1fd84cdea59354c"
|
||||
integrity sha512-i2AJZED/zf4uhxezAJUhMKoL5QoepCBp2ynOYol0N76+TSoohaMADdPnWCqOULF4RzOwrG8wWynAwBlXsAI1RQ==
|
||||
dependencies:
|
||||
"@algolia/client-common" "5.12.0"
|
||||
"@algolia/requester-browser-xhr" "5.12.0"
|
||||
"@algolia/requester-fetch" "5.12.0"
|
||||
"@algolia/requester-node-http" "5.12.0"
|
||||
|
||||
"@algolia/recommend@4.23.3":
|
||||
version "4.23.3"
|
||||
resolved "https://registry.yarnpkg.com/@algolia/recommend/-/recommend-4.23.3.tgz#53d4f194d22d9c72dc05f3f7514c5878f87c5890"
|
||||
@@ -154,6 +244,16 @@
|
||||
"@algolia/requester-node-http" "4.23.3"
|
||||
"@algolia/transporter" "4.23.3"
|
||||
|
||||
"@algolia/recommend@5.12.0":
|
||||
version "5.12.0"
|
||||
resolved "https://registry.yarnpkg.com/@algolia/recommend/-/recommend-5.12.0.tgz#bc9f69c78c08ba9a3579e7fe2a0f4037b494cc55"
|
||||
integrity sha512-0jmZyKvYnB/Bj5c7WKsKedOUjnr0UtXm0LVFUdQrxXfqOqvWv9n6Vpr65UjdYG4Q49kRQxhlwtal9WJYrYymXg==
|
||||
dependencies:
|
||||
"@algolia/client-common" "5.12.0"
|
||||
"@algolia/requester-browser-xhr" "5.12.0"
|
||||
"@algolia/requester-fetch" "5.12.0"
|
||||
"@algolia/requester-node-http" "5.12.0"
|
||||
|
||||
"@algolia/requester-browser-xhr@4.23.3":
|
||||
version "4.23.3"
|
||||
resolved "https://registry.yarnpkg.com/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.23.3.tgz#9e47e76f60d540acc8b27b4ebc7a80d1b41938b9"
|
||||
@@ -161,6 +261,13 @@
|
||||
dependencies:
|
||||
"@algolia/requester-common" "4.23.3"
|
||||
|
||||
"@algolia/requester-browser-xhr@5.12.0":
|
||||
version "5.12.0"
|
||||
resolved "https://registry.yarnpkg.com/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.12.0.tgz#dba0072d5098a145e4724a723ea1c765b4af0cb6"
|
||||
integrity sha512-KxwleraFuVoEGCoeW6Y1RAEbgBMS7SavqeyzWdtkJc6mXeCOJXn1iZitb8Tyn2FcpMNUKlSm0adrUTt7G47+Ow==
|
||||
dependencies:
|
||||
"@algolia/client-common" "5.12.0"
|
||||
|
||||
"@algolia/requester-common@4.23.3":
|
||||
version "4.23.3"
|
||||
resolved "https://registry.yarnpkg.com/@algolia/requester-common/-/requester-common-4.23.3.tgz#7dbae896e41adfaaf1d1fa5f317f83a99afb04b3"
|
||||
@@ -171,6 +278,13 @@
|
||||
resolved "https://registry.yarnpkg.com/@algolia/requester-common/-/requester-common-4.24.0.tgz#1c60c198031f48fcdb9e34c4057a3ea987b9a436"
|
||||
integrity sha512-k3CXJ2OVnvgE3HMwcojpvY6d9kgKMPRxs/kVohrwF5WMr2fnqojnycZkxPoEg+bXm8fi5BBfFmOqgYztRtHsQA==
|
||||
|
||||
"@algolia/requester-fetch@5.12.0":
|
||||
version "5.12.0"
|
||||
resolved "https://registry.yarnpkg.com/@algolia/requester-fetch/-/requester-fetch-5.12.0.tgz#4db2772b9b0699fdfadbcd7b87e0608a4acf8363"
|
||||
integrity sha512-FuDZXUGU1pAg2HCnrt8+q1VGHKChV/LhvjvZlLOT7e56GJie6p+EuLu4/hMKPOVuQQ8XXtrTHKIU3Lw+7O5/bQ==
|
||||
dependencies:
|
||||
"@algolia/client-common" "5.12.0"
|
||||
|
||||
"@algolia/requester-node-http@4.23.3":
|
||||
version "4.23.3"
|
||||
resolved "https://registry.yarnpkg.com/@algolia/requester-node-http/-/requester-node-http-4.23.3.tgz#c9f94a5cb96a15f48cea338ab6ef16bbd0ff989f"
|
||||
@@ -178,6 +292,13 @@
|
||||
dependencies:
|
||||
"@algolia/requester-common" "4.23.3"
|
||||
|
||||
"@algolia/requester-node-http@5.12.0":
|
||||
version "5.12.0"
|
||||
resolved "https://registry.yarnpkg.com/@algolia/requester-node-http/-/requester-node-http-5.12.0.tgz#6c6bb47df33351b819790f26346632196c97a3c7"
|
||||
integrity sha512-ncDDY7CxZhMs6LIoPl+vHFQceIBhYPY5EfuGF1V7beO0U38xfsCYEyutEFB2kRzf4D9Gqppn3iWX71sNtrKcuw==
|
||||
dependencies:
|
||||
"@algolia/client-common" "5.12.0"
|
||||
|
||||
"@algolia/transporter@4.23.3":
|
||||
version "4.23.3"
|
||||
resolved "https://registry.yarnpkg.com/@algolia/transporter/-/transporter-4.23.3.tgz#545b045b67db3850ddf0bbecbc6c84ff1f3398b7"
|
||||
@@ -211,19 +332,19 @@
|
||||
dependencies:
|
||||
"@ctrl/tinycolor" "^3.6.1"
|
||||
|
||||
"@ant-design/cssinjs-utils@^1.0.3":
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@ant-design/cssinjs-utils/-/cssinjs-utils-1.0.3.tgz#d68e46be9680cf9f416374a03aff0dd11bd1728d"
|
||||
integrity sha512-BrztZZKuoYcJK8uEH40ylBemf/Mu/QPiDos56g2bv6eUoniQkgQHOCOvA3+pncoFO1TaS8xcUCIqGzDA0I+ZVQ==
|
||||
"@ant-design/cssinjs-utils@^1.1.1":
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@ant-design/cssinjs-utils/-/cssinjs-utils-1.1.1.tgz#57abb43671023f937348bd33442862c60ac8e8b2"
|
||||
integrity sha512-2HAiyGGGnM0es40SxdszeQAU5iWp41wBIInq+ONTCKjlSKOrzQfnw4JDtB8IBmqE6tQaEKwmzTP2LGdt5DSwYQ==
|
||||
dependencies:
|
||||
"@ant-design/cssinjs" "^1.21.0"
|
||||
"@babel/runtime" "^7.23.2"
|
||||
rc-util "^5.38.0"
|
||||
|
||||
"@ant-design/cssinjs@^1.21.0":
|
||||
version "1.21.0"
|
||||
resolved "https://registry.yarnpkg.com/@ant-design/cssinjs/-/cssinjs-1.21.0.tgz#de7289bfd71c7a494a28b96569ad88f999619105"
|
||||
integrity sha512-gIilraPl+9EoKdYxnupxjHB/Q6IHNRjEXszKbDxZdsgv4sAZ9pjkCq8yanDWNvyfjp4leir2OVAJm0vxwKK8YA==
|
||||
"@ant-design/cssinjs@^1.21.0", "@ant-design/cssinjs@^1.21.1":
|
||||
version "1.21.1"
|
||||
resolved "https://registry.yarnpkg.com/@ant-design/cssinjs/-/cssinjs-1.21.1.tgz#7320813c5f747e0cde52c388eff5198d78d57230"
|
||||
integrity sha512-tyWnlK+XH7Bumd0byfbCiZNK43HEubMoCcu9VxwsAwiHdHTgWa+tMN0/yvxa+e8EzuFP1WdUNNPclRpVtD33lg==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.11.1"
|
||||
"@emotion/hash" "^0.8.0"
|
||||
@@ -231,7 +352,7 @@
|
||||
classnames "^2.3.1"
|
||||
csstype "^3.1.3"
|
||||
rc-util "^5.35.0"
|
||||
stylis "^4.0.13"
|
||||
stylis "^4.3.3"
|
||||
|
||||
"@ant-design/fast-color@^2.0.6":
|
||||
version "2.0.6"
|
||||
@@ -245,10 +366,10 @@
|
||||
resolved "https://registry.yarnpkg.com/@ant-design/icons-svg/-/icons-svg-4.4.2.tgz#ed2be7fb4d82ac7e1d45a54a5b06d6cecf8be6f6"
|
||||
integrity sha512-vHbT+zJEVzllwP+CM+ul7reTEfBR0vgxFe7+lREAsAA7YGsYpboiq2sQNeQeRvh09GfQgs/GyFEvZpJ9cLXpXA==
|
||||
|
||||
"@ant-design/icons@^5.4.0":
|
||||
version "5.4.0"
|
||||
resolved "https://registry.yarnpkg.com/@ant-design/icons/-/icons-5.4.0.tgz#4bd8f335c68207cc06fe9943d164a81cdfcfbeac"
|
||||
integrity sha512-QZbWC5xQYexCI5q4/fehSEkchJr5UGtvAJweT743qKUQQGs9IH2DehNLP49DJ3Ii9m9CijD2HN6fNy3WKhIFdA==
|
||||
"@ant-design/icons@^5.4.0", "@ant-design/icons@^5.5.1":
|
||||
version "5.5.1"
|
||||
resolved "https://registry.yarnpkg.com/@ant-design/icons/-/icons-5.5.1.tgz#4ff57b2a0d3bafae3d990c2781fd857ead36c935"
|
||||
integrity sha512-0UrM02MA2iDIgvLatWrj6YTCYe0F/cwXvVE0E2SqGrL7PZireQwgEKTKBisWpZyal5eXZLvuM98kju6YtYne8w==
|
||||
dependencies:
|
||||
"@ant-design/colors" "^7.0.0"
|
||||
"@ant-design/icons-svg" "^4.4.0"
|
||||
@@ -1274,10 +1395,10 @@
|
||||
core-js-pure "^3.30.2"
|
||||
regenerator-runtime "^0.14.0"
|
||||
|
||||
"@babel/runtime@^7.1.2", "@babel/runtime@^7.10.1", "@babel/runtime@^7.10.3", "@babel/runtime@^7.10.4", "@babel/runtime@^7.11.1", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.16.7", "@babel/runtime@^7.18.0", "@babel/runtime@^7.18.3", "@babel/runtime@^7.20.0", "@babel/runtime@^7.20.7", "@babel/runtime@^7.21.0", "@babel/runtime@^7.22.5", "@babel/runtime@^7.22.6", "@babel/runtime@^7.23.2", "@babel/runtime@^7.23.6", "@babel/runtime@^7.23.9", "@babel/runtime@^7.24.4", "@babel/runtime@^7.24.7", "@babel/runtime@^7.24.8", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4":
|
||||
version "7.25.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.25.0.tgz#3af9a91c1b739c569d5d80cc917280919c544ecb"
|
||||
integrity sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw==
|
||||
"@babel/runtime@^7.1.2", "@babel/runtime@^7.10.1", "@babel/runtime@^7.10.3", "@babel/runtime@^7.10.4", "@babel/runtime@^7.11.1", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.16.7", "@babel/runtime@^7.18.0", "@babel/runtime@^7.18.3", "@babel/runtime@^7.20.0", "@babel/runtime@^7.20.7", "@babel/runtime@^7.21.0", "@babel/runtime@^7.22.5", "@babel/runtime@^7.22.6", "@babel/runtime@^7.23.2", "@babel/runtime@^7.23.6", "@babel/runtime@^7.23.9", "@babel/runtime@^7.24.4", "@babel/runtime@^7.24.7", "@babel/runtime@^7.24.8", "@babel/runtime@^7.25.6", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4":
|
||||
version "7.26.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.26.0.tgz#8600c2f595f277c60815256418b85356a65173c1"
|
||||
integrity sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==
|
||||
dependencies:
|
||||
regenerator-runtime "^0.14.0"
|
||||
|
||||
@@ -1335,20 +1456,20 @@
|
||||
resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70"
|
||||
integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==
|
||||
|
||||
"@docsearch/css@3.6.1":
|
||||
version "3.6.1"
|
||||
resolved "https://registry.yarnpkg.com/@docsearch/css/-/css-3.6.1.tgz#f0a728ecb486c81f2d282650fc1820c914913408"
|
||||
integrity sha512-VtVb5DS+0hRIprU2CO6ZQjK2Zg4QU5HrDM1+ix6rT0umsYvFvatMAnf97NHZlVWDaaLlx7GRfR/7FikANiM2Fg==
|
||||
"@docsearch/css@3.6.3":
|
||||
version "3.6.3"
|
||||
resolved "https://registry.yarnpkg.com/@docsearch/css/-/css-3.6.3.tgz#d787cc9d27a7e67305fa47d668656eb2e64c4526"
|
||||
integrity sha512-3uvbg8E7rhqE1C4oBAK3tGlS2qfhi9zpfZgH/yjDPF73vd9B41urVIKujF4rczcF4E3qs34SedhehiDJ4UdNBA==
|
||||
|
||||
"@docsearch/react@^3.5.2", "@docsearch/react@^3.6.1":
|
||||
version "3.6.1"
|
||||
resolved "https://registry.yarnpkg.com/@docsearch/react/-/react-3.6.1.tgz#0f826df08693293806d64277d6d9c38636211b97"
|
||||
integrity sha512-qXZkEPvybVhSXj0K7U3bXc233tk5e8PfhoZ6MhPOiik/qUQxYC+Dn9DnoS7CxHQQhHfCvTiN0eY9M12oRghEXw==
|
||||
"@docsearch/react@^3.5.2", "@docsearch/react@^3.6.3":
|
||||
version "3.6.3"
|
||||
resolved "https://registry.yarnpkg.com/@docsearch/react/-/react-3.6.3.tgz#326a0811306060bfb481df3cd0db51adaa9f737c"
|
||||
integrity sha512-2munr4uBuZq1PG+Ge+F+ldIdxb3Wi8OmEIv2tQQb4RvEvvph+xtQkxwHzVIEnt5s+HecwucuXwB+3JhcZboFLg==
|
||||
dependencies:
|
||||
"@algolia/autocomplete-core" "1.9.3"
|
||||
"@algolia/autocomplete-preset-algolia" "1.9.3"
|
||||
"@docsearch/css" "3.6.1"
|
||||
algoliasearch "^4.19.1"
|
||||
"@algolia/autocomplete-preset-algolia" "1.17.6"
|
||||
"@docsearch/css" "3.6.3"
|
||||
algoliasearch "^5.11.0"
|
||||
|
||||
"@docusaurus/core@3.5.2", "@docusaurus/core@^3.5.2":
|
||||
version "3.5.2"
|
||||
@@ -1991,10 +2112,10 @@
|
||||
unist-util-visit "^5.0.0"
|
||||
vfile "^6.0.0"
|
||||
|
||||
"@mdx-js/react@^3.0.0":
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@mdx-js/react/-/react-3.0.1.tgz#997a19b3a5b783d936c75ae7c47cfe62f967f746"
|
||||
integrity sha512-9ZrPIU4MGf6et1m1ov3zKf+q9+deetI51zprKB1D/z3NOb+rUxxtEl3mCjW5wTGh6VhRdwPueh1oRzi6ezkA8A==
|
||||
"@mdx-js/react@^3.0.0", "@mdx-js/react@^3.1.0":
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@mdx-js/react/-/react-3.1.0.tgz#c4522e335b3897b9a845db1dbdd2f966ae8fb0ed"
|
||||
integrity sha512-QjHtSaoameoalGnKDT3FoIl4+9RwyTmo9ZJGBdLOks/YOiWHoRDI3PUwEzOE7kEmGcV3AFcp9K6dYu9rEuKLAQ==
|
||||
dependencies:
|
||||
"@types/mdx" "^2.0.0"
|
||||
|
||||
@@ -2115,10 +2236,10 @@
|
||||
classnames "^2.3.2"
|
||||
rc-util "^5.24.4"
|
||||
|
||||
"@rc-component/trigger@^2.0.0", "@rc-component/trigger@^2.1.1", "@rc-component/trigger@^2.2.1":
|
||||
version "2.2.2"
|
||||
resolved "https://registry.yarnpkg.com/@rc-component/trigger/-/trigger-2.2.2.tgz#7c8c27ce92cacbb32b1cda70f0533fe52202c41d"
|
||||
integrity sha512-xDyi0fJ3IV6XJEReMOewS9PEnnuLHKz4rjbgIniDsJFHjL5nROuUlu64mfo90jglLDkQUxRwK7aTtumA65/zYQ==
|
||||
"@rc-component/trigger@^2.0.0", "@rc-component/trigger@^2.1.1", "@rc-component/trigger@^2.2.3":
|
||||
version "2.2.3"
|
||||
resolved "https://registry.yarnpkg.com/@rc-component/trigger/-/trigger-2.2.3.tgz#b47e945115e2d0a7f7e067dbb9ed76c91c1b4385"
|
||||
integrity sha512-X1oFIpKoXAMXNDYCviOmTfuNuYxE4h5laBsyCqVAVMjNHxoF3/uiyA7XdegK1XbCvBbCZ6P6byWrEoDRpKL8+A==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.23.2"
|
||||
"@rc-component/portal" "^1.1.0"
|
||||
@@ -2127,10 +2248,10 @@
|
||||
rc-resize-observer "^1.3.1"
|
||||
rc-util "^5.38.0"
|
||||
|
||||
"@saucelabs/theme-github-codeblock@^0.2.3":
|
||||
version "0.2.3"
|
||||
resolved "https://registry.yarnpkg.com/@saucelabs/theme-github-codeblock/-/theme-github-codeblock-0.2.3.tgz#706a43292f600532271979941b0155db667c2c21"
|
||||
integrity sha512-GSl3Lr/jOWm4OP3BPX2vXxc8FMSOXj1mJnls6cUqMwlGOfKQ1Ia9pq1O9/ES+5TrZHIzAws/n5FFSn1OkGJw/Q==
|
||||
"@saucelabs/theme-github-codeblock@^0.3.0":
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@saucelabs/theme-github-codeblock/-/theme-github-codeblock-0.3.0.tgz#7936bc6aa97a15f2483ac143df4918c8d2baf5f0"
|
||||
integrity sha512-+8xWxBfN+I8StJ0QXERMbGf+BHwRXHWV3mFl9uDayXERiZ/rR93d0nAS3s9s/rKjqh/YSm/4dThEkBNBLnGs4Q==
|
||||
|
||||
"@sideway/address@^4.1.5":
|
||||
version "4.1.5"
|
||||
@@ -2738,6 +2859,22 @@
|
||||
dependencies:
|
||||
"@types/ms" "*"
|
||||
|
||||
"@types/eslint-scope@^3.7.7":
|
||||
version "3.7.7"
|
||||
resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.7.tgz#3108bd5f18b0cdb277c867b3dd449c9ed7079ac5"
|
||||
integrity sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==
|
||||
dependencies:
|
||||
"@types/eslint" "*"
|
||||
"@types/estree" "*"
|
||||
|
||||
"@types/eslint@*":
|
||||
version "9.6.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-9.6.1.tgz#d5795ad732ce81715f27f75da913004a56751584"
|
||||
integrity sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==
|
||||
dependencies:
|
||||
"@types/estree" "*"
|
||||
"@types/json-schema" "*"
|
||||
|
||||
"@types/estree-jsx@^1.0.0":
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/estree-jsx/-/estree-jsx-1.0.5.tgz#858a88ea20f34fe65111f005a689fa1ebf70dc18"
|
||||
@@ -2745,10 +2882,10 @@
|
||||
dependencies:
|
||||
"@types/estree" "*"
|
||||
|
||||
"@types/estree@*", "@types/estree@^1.0.0", "@types/estree@^1.0.5":
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4"
|
||||
integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==
|
||||
"@types/estree@*", "@types/estree@^1.0.0", "@types/estree@^1.0.6":
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.6.tgz#628effeeae2064a1b4e79f78e81d87b7e5fc7b50"
|
||||
integrity sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==
|
||||
|
||||
"@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.33":
|
||||
version "4.19.0"
|
||||
@@ -2835,7 +2972,7 @@
|
||||
dependencies:
|
||||
"@types/istanbul-lib-report" "*"
|
||||
|
||||
"@types/json-schema@^7.0.4", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9":
|
||||
"@types/json-schema@*", "@types/json-schema@^7.0.4", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9":
|
||||
version "7.0.15"
|
||||
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841"
|
||||
integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==
|
||||
@@ -2939,10 +3076,10 @@
|
||||
"@types/history" "^4.7.11"
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react@*", "@types/react@^18.3.5":
|
||||
version "18.3.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.3.5.tgz#5f524c2ad2089c0ff372bbdabc77ca2c4dbadf8f"
|
||||
integrity sha512-WeqMfGJLGuLCqHGYRGHxnKrXcTitc6L/nBUWfWPcTarG3t9PsquqUMuVeXZeca+mglY4Vo5GZjCi0A3Or2lnxA==
|
||||
"@types/react@*", "@types/react@^18.3.12":
|
||||
version "18.3.12"
|
||||
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.3.12.tgz#99419f182ccd69151813b7ee24b792fe08774f60"
|
||||
integrity sha512-D2wOSq/d6Agt28q7rSI3jhU7G6aiuzljDGZ2hTZHIkrTLUI+AF3WMeKkEZ9nN2fkBAlcktT6vcZjDFiIhMYEQw==
|
||||
dependencies:
|
||||
"@types/prop-types" "*"
|
||||
csstype "^3.0.2"
|
||||
@@ -3168,11 +3305,6 @@ accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.8:
|
||||
mime-types "~2.1.34"
|
||||
negotiator "0.6.3"
|
||||
|
||||
acorn-import-attributes@^1.9.5:
|
||||
version "1.9.5"
|
||||
resolved "https://registry.yarnpkg.com/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz#7eb1557b1ba05ef18b5ed0ec67591bfab04688ef"
|
||||
integrity sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==
|
||||
|
||||
acorn-jsx@^5.0.0:
|
||||
version "5.3.2"
|
||||
resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937"
|
||||
@@ -3183,10 +3315,10 @@ acorn-walk@^8.0.0:
|
||||
resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.2.tgz#7703af9415f1b6db9315d6895503862e231d34aa"
|
||||
integrity sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==
|
||||
|
||||
acorn@^8.0.0, acorn@^8.0.4, acorn@^8.7.1, acorn@^8.8.2:
|
||||
version "8.11.3"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.3.tgz#71e0b14e13a4ec160724b38fb7b0f233b1b81d7a"
|
||||
integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==
|
||||
acorn@^8.0.0, acorn@^8.0.4, acorn@^8.14.0, acorn@^8.8.2:
|
||||
version "8.14.0"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.14.0.tgz#063e2c70cac5fb4f6467f0b11152e04c682795b0"
|
||||
integrity sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==
|
||||
|
||||
address@^1.0.1, address@^1.1.2:
|
||||
version "1.2.2"
|
||||
@@ -3247,7 +3379,7 @@ algoliasearch-helper@^3.13.3:
|
||||
dependencies:
|
||||
"@algolia/events" "^4.0.1"
|
||||
|
||||
algoliasearch@^4.18.0, algoliasearch@^4.19.1:
|
||||
algoliasearch@^4.18.0:
|
||||
version "4.23.3"
|
||||
resolved "https://registry.yarnpkg.com/algoliasearch/-/algoliasearch-4.23.3.tgz#e09011d0a3b0651444916a3e6bbcba064ec44b60"
|
||||
integrity sha512-Le/3YgNvjW9zxIQMRhUHuhiUjAlKY/zsdZpfq4dlLqg6mEm0nL6yk+7f2hDOtLpxsgE4jSzDmvHL7nXdBp5feg==
|
||||
@@ -3268,6 +3400,25 @@ algoliasearch@^4.18.0, algoliasearch@^4.19.1:
|
||||
"@algolia/requester-node-http" "4.23.3"
|
||||
"@algolia/transporter" "4.23.3"
|
||||
|
||||
algoliasearch@^5.11.0:
|
||||
version "5.12.0"
|
||||
resolved "https://registry.yarnpkg.com/algoliasearch/-/algoliasearch-5.12.0.tgz#2e822a7916d691e55058ea7dba277d5110969dd0"
|
||||
integrity sha512-psGBRYdGgik8I6m28iAB8xpubvjEt7UQU+w5MAJUA2324WHiGoHap5BPkkjB14rMaXeRts6pmOsrVIglGyOVwg==
|
||||
dependencies:
|
||||
"@algolia/client-abtesting" "5.12.0"
|
||||
"@algolia/client-analytics" "5.12.0"
|
||||
"@algolia/client-common" "5.12.0"
|
||||
"@algolia/client-insights" "5.12.0"
|
||||
"@algolia/client-personalization" "5.12.0"
|
||||
"@algolia/client-query-suggestions" "5.12.0"
|
||||
"@algolia/client-search" "5.12.0"
|
||||
"@algolia/ingestion" "1.12.0"
|
||||
"@algolia/monitoring" "1.12.0"
|
||||
"@algolia/recommend" "5.12.0"
|
||||
"@algolia/requester-browser-xhr" "5.12.0"
|
||||
"@algolia/requester-fetch" "5.12.0"
|
||||
"@algolia/requester-node-http" "5.12.0"
|
||||
|
||||
ansi-align@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.1.tgz#0cdf12e111ace773a86e9a1fad1225c43cb19a59"
|
||||
@@ -3309,57 +3460,57 @@ ansi-styles@^6.1.0:
|
||||
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5"
|
||||
integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==
|
||||
|
||||
antd@^5.20.5:
|
||||
version "5.20.5"
|
||||
resolved "https://registry.yarnpkg.com/antd/-/antd-5.20.5.tgz#a55d5023759b08e501cabef3700d59664453fce0"
|
||||
integrity sha512-w/oVwoZAt5qP0PKhOkCmYXe06kXuoTh7UdQlltba/IzpbCCEh465z3Qw3i9HZY745HtOIS6ze707mVsORzN18g==
|
||||
antd@^5.21.6:
|
||||
version "5.21.6"
|
||||
resolved "https://registry.yarnpkg.com/antd/-/antd-5.21.6.tgz#60d8eb442f7f8019bab198e30ea5a8d6d224a6ce"
|
||||
integrity sha512-EviOde/VEu+OsIKH5t6YXTMmmNeg9R85m0W5zXAo+Np8Latg9q10691JvAqOTMpnrRmbdeKUQL1Krp69Bzbe/g==
|
||||
dependencies:
|
||||
"@ant-design/colors" "^7.1.0"
|
||||
"@ant-design/cssinjs" "^1.21.0"
|
||||
"@ant-design/cssinjs-utils" "^1.0.3"
|
||||
"@ant-design/icons" "^5.4.0"
|
||||
"@ant-design/cssinjs" "^1.21.1"
|
||||
"@ant-design/cssinjs-utils" "^1.1.1"
|
||||
"@ant-design/icons" "^5.5.1"
|
||||
"@ant-design/react-slick" "~1.1.2"
|
||||
"@babel/runtime" "^7.24.8"
|
||||
"@babel/runtime" "^7.25.6"
|
||||
"@ctrl/tinycolor" "^3.6.1"
|
||||
"@rc-component/color-picker" "~2.0.1"
|
||||
"@rc-component/mutate-observer" "^1.1.0"
|
||||
"@rc-component/qrcode" "~1.0.0"
|
||||
"@rc-component/tour" "~1.15.1"
|
||||
"@rc-component/trigger" "^2.2.1"
|
||||
"@rc-component/trigger" "^2.2.3"
|
||||
classnames "^2.5.1"
|
||||
copy-to-clipboard "^3.3.3"
|
||||
dayjs "^1.11.11"
|
||||
rc-cascader "~3.28.0"
|
||||
rc-cascader "~3.28.2"
|
||||
rc-checkbox "~3.3.0"
|
||||
rc-collapse "~3.7.3"
|
||||
rc-dialog "~9.5.2"
|
||||
rc-collapse "~3.8.0"
|
||||
rc-dialog "~9.6.0"
|
||||
rc-drawer "~7.2.0"
|
||||
rc-dropdown "~4.2.0"
|
||||
rc-field-form "~2.4.0"
|
||||
rc-image "~7.9.0"
|
||||
rc-image "~7.11.0"
|
||||
rc-input "~1.6.3"
|
||||
rc-input-number "~9.2.0"
|
||||
rc-mentions "~2.15.0"
|
||||
rc-menu "~9.14.1"
|
||||
rc-motion "^2.9.2"
|
||||
rc-notification "~5.6.0"
|
||||
rc-pagination "~4.2.0"
|
||||
rc-picker "~4.6.14"
|
||||
rc-mentions "~2.16.1"
|
||||
rc-menu "~9.15.1"
|
||||
rc-motion "^2.9.3"
|
||||
rc-notification "~5.6.2"
|
||||
rc-pagination "~4.3.0"
|
||||
rc-picker "~4.6.15"
|
||||
rc-progress "~4.0.0"
|
||||
rc-rate "~2.13.0"
|
||||
rc-resize-observer "^1.4.0"
|
||||
rc-segmented "~2.3.0"
|
||||
rc-select "~14.15.1"
|
||||
rc-slider "~11.1.5"
|
||||
rc-segmented "~2.5.0"
|
||||
rc-select "~14.15.2"
|
||||
rc-slider "~11.1.7"
|
||||
rc-steps "~6.0.1"
|
||||
rc-switch "~4.1.0"
|
||||
rc-table "~7.45.7"
|
||||
rc-tabs "~15.1.1"
|
||||
rc-textarea "~1.8.1"
|
||||
rc-tooltip "~6.2.0"
|
||||
rc-table "~7.47.5"
|
||||
rc-tabs "~15.3.0"
|
||||
rc-textarea "~1.8.2"
|
||||
rc-tooltip "~6.2.1"
|
||||
rc-tree "~5.9.0"
|
||||
rc-tree-select "~5.23.0"
|
||||
rc-upload "~4.7.0"
|
||||
rc-upload "~4.8.1"
|
||||
rc-util "^5.43.0"
|
||||
scroll-into-view-if-needed "^3.1.0"
|
||||
throttle-debounce "^5.0.2"
|
||||
@@ -3641,15 +3792,15 @@ braces@^3.0.3, braces@~3.0.2:
|
||||
dependencies:
|
||||
fill-range "^7.1.1"
|
||||
|
||||
browserslist@^4.0.0, browserslist@^4.18.1, browserslist@^4.21.10, browserslist@^4.22.2, browserslist@^4.23.0:
|
||||
version "4.23.0"
|
||||
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.23.0.tgz#8f3acc2bbe73af7213399430890f86c63a5674ab"
|
||||
integrity sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==
|
||||
browserslist@^4.0.0, browserslist@^4.18.1, browserslist@^4.22.2, browserslist@^4.23.0, browserslist@^4.24.0:
|
||||
version "4.24.2"
|
||||
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.24.2.tgz#f5845bc91069dbd55ee89faf9822e1d885d16580"
|
||||
integrity sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==
|
||||
dependencies:
|
||||
caniuse-lite "^1.0.30001587"
|
||||
electron-to-chromium "^1.4.668"
|
||||
node-releases "^2.0.14"
|
||||
update-browserslist-db "^1.0.13"
|
||||
caniuse-lite "^1.0.30001669"
|
||||
electron-to-chromium "^1.5.41"
|
||||
node-releases "^2.0.18"
|
||||
update-browserslist-db "^1.1.1"
|
||||
|
||||
buffer-from@^1.0.0:
|
||||
version "1.1.2"
|
||||
@@ -3744,11 +3895,16 @@ caniuse-api@^3.0.0:
|
||||
lodash.memoize "^4.1.2"
|
||||
lodash.uniq "^4.5.0"
|
||||
|
||||
caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001587, caniuse-lite@^1.0.30001599:
|
||||
caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001599:
|
||||
version "1.0.30001614"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001614.tgz#f894b4209376a0bf923d67d9c361d96b1dfebe39"
|
||||
integrity sha512-jmZQ1VpmlRwHgdP1/uiKzgiAuGOfLEJsYFP4+GBou/QQ4U6IOJCB4NP1c+1p9RGLpwObcT94jA5/uO+F1vBbog==
|
||||
|
||||
caniuse-lite@^1.0.30001669:
|
||||
version "1.0.30001677"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001677.tgz#27c2e2c637e007cfa864a16f7dfe7cde66b38b5f"
|
||||
integrity sha512-fmfjsOlJUpMWu+mAAtZZZHz7UEwsUxIIvu1TJfO1HqFQvB/B+ii0xr9B5HpbZY/mC4XZ8SvjHJqtAY6pDPQEog==
|
||||
|
||||
ccount@^2.0.0:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/ccount/-/ccount-2.0.1.tgz#17a3bf82302e0870d6da43a01311a8bc02a3ecf5"
|
||||
@@ -4637,10 +4793,10 @@ ee-first@1.1.1:
|
||||
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
|
||||
integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==
|
||||
|
||||
electron-to-chromium@^1.4.668:
|
||||
version "1.4.752"
|
||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.752.tgz#99227455547c8254488e3dab7d316c34a2c067b8"
|
||||
integrity sha512-P3QJreYI/AUTcfBVrC4zy9KvnZWekViThgQMX/VpJ+IsOBbcX5JFpORM4qWapwWQ+agb2nYAOyn/4PMXOk0m2Q==
|
||||
electron-to-chromium@^1.5.41:
|
||||
version "1.5.50"
|
||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.50.tgz#d9ba818da7b2b5ef1f3dd32bce7046feb7e93234"
|
||||
integrity sha512-eMVObiUQ2LdgeO1F/ySTXsvqvxb6ZH2zPGaMYsWzRDdOddUa77tdmI0ltg+L16UpbWdhPmuF3wIQYyQq65WfZw==
|
||||
|
||||
emoji-regex@^8.0.0:
|
||||
version "8.0.0"
|
||||
@@ -4742,11 +4898,16 @@ es-module-lexer@^1.2.1:
|
||||
resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.5.2.tgz#00b423304f2500ac59359cc9b6844951f372d497"
|
||||
integrity sha512-l60ETUTmLqbVbVHv1J4/qj+M8nq7AwMzEcg3kmJDt9dCNrTk+yHcYFf/Kw75pMDwd9mPcIGCG5LcS20SxYRzFA==
|
||||
|
||||
escalade@^3.1.1, escalade@^3.1.2:
|
||||
escalade@^3.1.1:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.2.tgz#54076e9ab29ea5bf3d8f1ed62acffbb88272df27"
|
||||
integrity sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==
|
||||
|
||||
escalade@^3.2.0:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5"
|
||||
integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==
|
||||
|
||||
escape-goat@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/escape-goat/-/escape-goat-4.0.0.tgz#9424820331b510b0666b98f7873fe11ac4aa8081"
|
||||
@@ -5703,9 +5864,9 @@ http-parser-js@>=0.5.1:
|
||||
integrity sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==
|
||||
|
||||
http-proxy-middleware@^2.0.3:
|
||||
version "2.0.6"
|
||||
resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz#e1a4dd6979572c7ab5a4e4b55095d1f32a74963f"
|
||||
integrity sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==
|
||||
version "2.0.7"
|
||||
resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz#915f236d92ae98ef48278a95dedf17e991936ec6"
|
||||
integrity sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA==
|
||||
dependencies:
|
||||
"@types/http-proxy" "^1.17.8"
|
||||
http-proxy "^1.18.1"
|
||||
@@ -7294,10 +7455,10 @@ node-forge@^1:
|
||||
resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3"
|
||||
integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==
|
||||
|
||||
node-releases@^2.0.14:
|
||||
version "2.0.14"
|
||||
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.14.tgz#2ffb053bceb8b2be8495ece1ab6ce600c4461b0b"
|
||||
integrity sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==
|
||||
node-releases@^2.0.18:
|
||||
version "2.0.18"
|
||||
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.18.tgz#f010e8d35e2fe8d6b2944f03f70213ecedc4ca3f"
|
||||
integrity sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==
|
||||
|
||||
normalize-path@^3.0.0, normalize-path@~3.0.0:
|
||||
version "3.0.0"
|
||||
@@ -7647,6 +7808,11 @@ picocolors@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c"
|
||||
integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==
|
||||
|
||||
picocolors@^1.1.0:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b"
|
||||
integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==
|
||||
|
||||
picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3, picomatch@^2.3.1:
|
||||
version "2.3.1"
|
||||
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
|
||||
@@ -8184,10 +8350,10 @@ raw-body@2.5.2:
|
||||
iconv-lite "0.4.24"
|
||||
unpipe "1.0.0"
|
||||
|
||||
rc-cascader@~3.28.0:
|
||||
version "3.28.1"
|
||||
resolved "https://registry.yarnpkg.com/rc-cascader/-/rc-cascader-3.28.1.tgz#ea8a3de60521290096bab7e3fbe8ca097b976468"
|
||||
integrity sha512-9+8oHIMWVLHxuaapDiqFNmD9KSyKN/P4bo9x/MBuDbyTqP8f2/POmmZxdXWBO3yq/uE3pKyQCXYNUxrNfHRv2A==
|
||||
rc-cascader@~3.28.2:
|
||||
version "3.28.2"
|
||||
resolved "https://registry.yarnpkg.com/rc-cascader/-/rc-cascader-3.28.2.tgz#91720d3498261a7bff9fffc953501a8830f601fb"
|
||||
integrity sha512-8f+JgM83iLTvjgdkgU7GfI4qY8icXOBP0cGZjOdx2iJAkEe8ucobxDQAVE69UD/c3ehCxZlcgEHeD5hFmypbUw==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.12.5"
|
||||
array-tree-filter "^2.1.0"
|
||||
@@ -8205,20 +8371,20 @@ rc-checkbox@~3.3.0:
|
||||
classnames "^2.3.2"
|
||||
rc-util "^5.25.2"
|
||||
|
||||
rc-collapse@~3.7.3:
|
||||
version "3.7.3"
|
||||
resolved "https://registry.yarnpkg.com/rc-collapse/-/rc-collapse-3.7.3.tgz#68161683d8fd1004bef4eb281fc106f3c8dc16eb"
|
||||
integrity sha512-60FJcdTRn0X5sELF18TANwtVi7FtModq649H11mYF1jh83DniMoM4MqY627sEKRCTm4+WXfGDcB7hY5oW6xhyw==
|
||||
rc-collapse@~3.8.0:
|
||||
version "3.8.0"
|
||||
resolved "https://registry.yarnpkg.com/rc-collapse/-/rc-collapse-3.8.0.tgz#02bcf81e1601aa185cd3b9fab0ceefd8dc11aefb"
|
||||
integrity sha512-YVBkssrKPBG09TGfcWWGj8zJBYD9G3XuTy89t5iUmSXrIXEAnO1M+qjUxRW6b4Qi0+wNWG6MHJF/+US+nmIlzA==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.10.1"
|
||||
classnames "2.x"
|
||||
rc-motion "^2.3.4"
|
||||
rc-util "^5.27.0"
|
||||
|
||||
rc-dialog@~9.5.2:
|
||||
version "9.5.2"
|
||||
resolved "https://registry.yarnpkg.com/rc-dialog/-/rc-dialog-9.5.2.tgz#4cf7cca23aedb6fd3d9344ea8ffd14daa94ee3a0"
|
||||
integrity sha512-qVUjc8JukG+j/pNaHVSRa2GO2/KbV2thm7yO4hepQ902eGdYK913sGkwg/fh9yhKYV1ql3BKIN2xnud3rEXAPw==
|
||||
rc-dialog@~9.6.0:
|
||||
version "9.6.0"
|
||||
resolved "https://registry.yarnpkg.com/rc-dialog/-/rc-dialog-9.6.0.tgz#dc7a255c6ad1cb56021c3a61c7de86ee88c7c371"
|
||||
integrity sha512-ApoVi9Z8PaCQg6FsUzS8yvBEQy0ZL2PkuvAgrmohPkN3okps5WZ5WQWPc1RNuiOKaAYv8B97ACdsFU5LizzCqg==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.10.1"
|
||||
"@rc-component/portal" "^1.0.0-8"
|
||||
@@ -8256,15 +8422,15 @@ rc-field-form@~2.4.0:
|
||||
"@rc-component/async-validator" "^5.0.3"
|
||||
rc-util "^5.32.2"
|
||||
|
||||
rc-image@~7.9.0:
|
||||
version "7.9.0"
|
||||
resolved "https://registry.yarnpkg.com/rc-image/-/rc-image-7.9.0.tgz#2d700a5cf891bb3d0d800b7c38348927ebb9f49b"
|
||||
integrity sha512-l4zqO5E0quuLMCtdKfBgj4Suv8tIS011F5k1zBBlK25iMjjiNHxA0VeTzGFtUZERSA45gvpXDg8/P6qNLjR25g==
|
||||
rc-image@~7.11.0:
|
||||
version "7.11.0"
|
||||
resolved "https://registry.yarnpkg.com/rc-image/-/rc-image-7.11.0.tgz#18c77ea557a6fdbe26856c688a9aace1505c0e77"
|
||||
integrity sha512-aZkTEZXqeqfPZtnSdNUnKQA0N/3MbgR7nUnZ+/4MfSFWPFHZau4p5r5ShaI0KPEMnNjv4kijSCFq/9wtJpwykw==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.11.2"
|
||||
"@rc-component/portal" "^1.0.2"
|
||||
classnames "^2.2.6"
|
||||
rc-dialog "~9.5.2"
|
||||
rc-dialog "~9.6.0"
|
||||
rc-motion "^2.6.2"
|
||||
rc-util "^5.34.1"
|
||||
|
||||
@@ -8288,23 +8454,23 @@ rc-input@~1.6.0, rc-input@~1.6.3:
|
||||
classnames "^2.2.1"
|
||||
rc-util "^5.18.1"
|
||||
|
||||
rc-mentions@~2.15.0:
|
||||
version "2.15.0"
|
||||
resolved "https://registry.yarnpkg.com/rc-mentions/-/rc-mentions-2.15.0.tgz#ada022b32e68fa067a859ee0024c3f2aa7a9c871"
|
||||
integrity sha512-f5v5i7VdqvBDXbphoqcQWmXDif2Msd2arritVoWybrVDuHE6nQ7XCYsybHbV//WylooK52BFDouFvyaRDtXZEw==
|
||||
rc-mentions@~2.16.1:
|
||||
version "2.16.1"
|
||||
resolved "https://registry.yarnpkg.com/rc-mentions/-/rc-mentions-2.16.1.tgz#5e54ebe3ce6cd79838846ff1c8cfaf2e7aa15cec"
|
||||
integrity sha512-GnhSTGP9Mtv6pqFFGQze44LlrtWOjHNrUUAcsdo9DnNAhN4pwVPEWy4z+2jpjkiGlJ3VoXdvMHcNDQdfI9fEaw==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.22.5"
|
||||
"@rc-component/trigger" "^2.0.0"
|
||||
classnames "^2.2.6"
|
||||
rc-input "~1.6.0"
|
||||
rc-menu "~9.14.0"
|
||||
rc-menu "~9.15.1"
|
||||
rc-textarea "~1.8.0"
|
||||
rc-util "^5.34.1"
|
||||
|
||||
rc-menu@~9.14.0, rc-menu@~9.14.1:
|
||||
version "9.14.1"
|
||||
resolved "https://registry.yarnpkg.com/rc-menu/-/rc-menu-9.14.1.tgz#5c2aea72bdce421e9d50bf721ad8b76c154ae66f"
|
||||
integrity sha512-5wlRb3M8S4yGlWhSoEYJ7ZVRElyScdcpUHxgiLxkeig1tEdyKrnED3B2fhpN0Rrpdp9jyhnmZR/Lwq2fH5VvDQ==
|
||||
rc-menu@~9.15.1:
|
||||
version "9.15.1"
|
||||
resolved "https://registry.yarnpkg.com/rc-menu/-/rc-menu-9.15.1.tgz#d8b38ea534a7f596a8da063881519e7eaafca698"
|
||||
integrity sha512-UKporqU6LPfHnpPmtP6hdEK4iO5Q+b7BRv/uRpxdIyDGplZy9jwUjsnpev5bs3PQKB0H0n34WAPDfjAfn3kAPA==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.10.1"
|
||||
"@rc-component/trigger" "^2.0.0"
|
||||
@@ -8313,19 +8479,19 @@ rc-menu@~9.14.0, rc-menu@~9.14.1:
|
||||
rc-overflow "^1.3.1"
|
||||
rc-util "^5.27.0"
|
||||
|
||||
rc-motion@^2.0.0, rc-motion@^2.0.1, rc-motion@^2.3.0, rc-motion@^2.3.4, rc-motion@^2.4.3, rc-motion@^2.4.4, rc-motion@^2.6.1, rc-motion@^2.6.2, rc-motion@^2.9.0, rc-motion@^2.9.2:
|
||||
version "2.9.2"
|
||||
resolved "https://registry.yarnpkg.com/rc-motion/-/rc-motion-2.9.2.tgz#f7c6d480250df8a512d0cfdce07ff3da906958cf"
|
||||
integrity sha512-fUAhHKLDdkAXIDLH0GYwof3raS58dtNUmzLF2MeiR8o6n4thNpSDQhOqQzWE4WfFZDCi9VEN8n7tiB7czREcyw==
|
||||
rc-motion@^2.0.0, rc-motion@^2.0.1, rc-motion@^2.3.0, rc-motion@^2.3.4, rc-motion@^2.4.3, rc-motion@^2.4.4, rc-motion@^2.6.1, rc-motion@^2.6.2, rc-motion@^2.9.0, rc-motion@^2.9.3:
|
||||
version "2.9.3"
|
||||
resolved "https://registry.yarnpkg.com/rc-motion/-/rc-motion-2.9.3.tgz#b1bdaf816f1ccb3e4b3b0c531c3037a59286379e"
|
||||
integrity sha512-rkW47ABVkic7WEB0EKJqzySpvDqwl60/tdkY7hWP7dYnh5pm0SzJpo54oW3TDUGXV5wfxXFmMkxrzRRbotQ0+w==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.11.1"
|
||||
classnames "^2.2.1"
|
||||
rc-util "^5.43.0"
|
||||
|
||||
rc-notification@~5.6.0:
|
||||
version "5.6.0"
|
||||
resolved "https://registry.yarnpkg.com/rc-notification/-/rc-notification-5.6.0.tgz#1639aa30686d79ee4bb8ace05a698a5a104aaa74"
|
||||
integrity sha512-TGQW5T7waOxLwgJG7fXcw8l7AQiFOjaZ7ISF5PrU526nunHRNcTMuzKihQHaF4E/h/KfOCDk3Mv8eqzbu2e28w==
|
||||
rc-notification@~5.6.2:
|
||||
version "5.6.2"
|
||||
resolved "https://registry.yarnpkg.com/rc-notification/-/rc-notification-5.6.2.tgz#8525b32d49dd96ec974acae61d1d1eabde61463a"
|
||||
integrity sha512-Id4IYMoii3zzrG0lB0gD6dPgJx4Iu95Xu0BQrhHIbp7ZnAZbLqdqQ73aIWH0d0UFcElxwaKjnzNovTjo7kXz7g==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.10.1"
|
||||
classnames "2.x"
|
||||
@@ -8342,19 +8508,19 @@ rc-overflow@^1.3.1, rc-overflow@^1.3.2:
|
||||
rc-resize-observer "^1.0.0"
|
||||
rc-util "^5.37.0"
|
||||
|
||||
rc-pagination@~4.2.0:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/rc-pagination/-/rc-pagination-4.2.0.tgz#b7222b429dec38f6c74e139a30ae7765e9a0b8a6"
|
||||
integrity sha512-V6qeANJsT6tmOcZ4XiUmj8JXjRLbkusuufpuoBw2GiAn94fIixYjFLmbruD1Sbhn8fPLDnWawPp4CN37zQorvw==
|
||||
rc-pagination@~4.3.0:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.yarnpkg.com/rc-pagination/-/rc-pagination-4.3.0.tgz#c6022f820aa3a45fd734ae33a2915d39597dce1d"
|
||||
integrity sha512-UubEWA0ShnroQ1tDa291Fzw6kj0iOeF26IsUObxYTpimgj4/qPCWVFl18RLZE+0Up1IZg0IK4pMn6nB3mjvB7g==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.10.1"
|
||||
classnames "^2.3.2"
|
||||
rc-util "^5.38.0"
|
||||
|
||||
rc-picker@~4.6.14:
|
||||
version "4.6.14"
|
||||
resolved "https://registry.yarnpkg.com/rc-picker/-/rc-picker-4.6.14.tgz#86f6836794a593a54b929cfde201f42f02ef85b0"
|
||||
integrity sha512-7DuTfUFdkxmsNpWQ0TWv6FPGna5e6KKC4nxtx3x9xhumLz7jb3fhlDdWQvqEL6tpt9DOb1+N5j+wB+lDOSS9kg==
|
||||
rc-picker@~4.6.15:
|
||||
version "4.6.15"
|
||||
resolved "https://registry.yarnpkg.com/rc-picker/-/rc-picker-4.6.15.tgz#1531c9c382a295e2d1f1f38440d6678b09cd0468"
|
||||
integrity sha512-OWZ1yrMie+KN2uEUfYCfS4b2Vu6RC1FWwNI0s+qypsc3wRt7g+peuZKVIzXCTaJwyyZruo80+akPg2+GmyiJjw==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.24.7"
|
||||
"@rc-component/trigger" "^2.0.0"
|
||||
@@ -8391,20 +8557,20 @@ rc-resize-observer@^1.0.0, rc-resize-observer@^1.1.0, rc-resize-observer@^1.3.1,
|
||||
rc-util "^5.38.0"
|
||||
resize-observer-polyfill "^1.5.1"
|
||||
|
||||
rc-segmented@~2.3.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/rc-segmented/-/rc-segmented-2.3.0.tgz#b3fe080fb434a266c02e30bb62a47d2c6e094341"
|
||||
integrity sha512-I3FtM5Smua/ESXutFfb8gJ8ZPcvFR+qUgeeGFQHBOvRiRKyAk4aBE5nfqrxXx+h8/vn60DQjOt6i4RNtrbOobg==
|
||||
rc-segmented@~2.5.0:
|
||||
version "2.5.0"
|
||||
resolved "https://registry.yarnpkg.com/rc-segmented/-/rc-segmented-2.5.0.tgz#3b5423adf57459345c77c39c7581fde786a16c11"
|
||||
integrity sha512-B28Fe3J9iUFOhFJET3RoXAPFJ2u47QvLSYcZWC4tFYNGPEjug5LAxEasZlA/PpAxhdOPqGWsGbSj7ftneukJnw==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.11.1"
|
||||
classnames "^2.2.1"
|
||||
rc-motion "^2.4.4"
|
||||
rc-util "^5.17.0"
|
||||
|
||||
rc-select@~14.15.0, rc-select@~14.15.1:
|
||||
version "14.15.1"
|
||||
resolved "https://registry.yarnpkg.com/rc-select/-/rc-select-14.15.1.tgz#1c8ab356cfdf1b24e974d62aec752620845d95a7"
|
||||
integrity sha512-mGvuwW1RMm1NCSI8ZUoRoLRK51R2Nb+QJnmiAvbDRcjh2//ulCkxeV6ZRFTECPpE1t2DPfyqZMPw90SVJzQ7wQ==
|
||||
rc-select@~14.15.0, rc-select@~14.15.2:
|
||||
version "14.15.2"
|
||||
resolved "https://registry.yarnpkg.com/rc-select/-/rc-select-14.15.2.tgz#d85fcf3a708bdf837b003feeed653347b8980ad0"
|
||||
integrity sha512-oNoXlaFmpqXYcQDzcPVLrEqS2J9c+/+oJuGrlXeVVX/gVgrbHa5YcyiRUXRydFjyuA7GP3elRuLF7Y3Tfwltlw==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.10.1"
|
||||
"@rc-component/trigger" "^2.1.1"
|
||||
@@ -8414,10 +8580,10 @@ rc-select@~14.15.0, rc-select@~14.15.1:
|
||||
rc-util "^5.16.1"
|
||||
rc-virtual-list "^3.5.2"
|
||||
|
||||
rc-slider@~11.1.5:
|
||||
version "11.1.5"
|
||||
resolved "https://registry.yarnpkg.com/rc-slider/-/rc-slider-11.1.5.tgz#9a596464a36d78feb90589fee4eb0bf7cec40584"
|
||||
integrity sha512-b77H5PbjMKsvkYXAYIkn50QuFX6ICQmCTibDinI9q+BHx65/TV4TeU25+oadhSRzykxs0/vBWeKBwRyySOeWlg==
|
||||
rc-slider@~11.1.7:
|
||||
version "11.1.7"
|
||||
resolved "https://registry.yarnpkg.com/rc-slider/-/rc-slider-11.1.7.tgz#3de333b1ec84d53a7bda2f816bb4779423628f09"
|
||||
integrity sha512-ytYbZei81TX7otdC0QvoYD72XSlxvTihNth5OeZ6PMXyEDq/vHdWFulQmfDGyXK1NwKwSlKgpvINOa88uT5g2A==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.10.1"
|
||||
classnames "^2.2.5"
|
||||
@@ -8441,35 +8607,35 @@ rc-switch@~4.1.0:
|
||||
classnames "^2.2.1"
|
||||
rc-util "^5.30.0"
|
||||
|
||||
rc-table@~7.45.7:
|
||||
version "7.45.7"
|
||||
resolved "https://registry.yarnpkg.com/rc-table/-/rc-table-7.45.7.tgz#f7c509e05c677a30ad5b212750122da6f5318004"
|
||||
integrity sha512-wi9LetBL1t1csxyGkMB2p3mCiMt+NDexMlPbXHvQFmBBAsMxrgNSAPwUci2zDLUq9m8QdWc1Nh8suvrpy9mXrg==
|
||||
rc-table@~7.47.5:
|
||||
version "7.47.5"
|
||||
resolved "https://registry.yarnpkg.com/rc-table/-/rc-table-7.47.5.tgz#3c530200baa82346c7e72fe9b1dbd47d4aa15838"
|
||||
integrity sha512-fzq+V9j/atbPIcvs3emuclaEoXulwQpIiJA6/7ey52j8+9cJ4P8DGmp4YzfUVDrb3qhgedcVeD6eRgUrokwVEQ==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.10.1"
|
||||
"@rc-component/context" "^1.4.0"
|
||||
classnames "^2.2.5"
|
||||
rc-resize-observer "^1.1.0"
|
||||
rc-util "^5.37.0"
|
||||
rc-util "^5.41.0"
|
||||
rc-virtual-list "^3.14.2"
|
||||
|
||||
rc-tabs@~15.1.1:
|
||||
version "15.1.1"
|
||||
resolved "https://registry.yarnpkg.com/rc-tabs/-/rc-tabs-15.1.1.tgz#99f4c7647e01d3e22216d94222d717e928ed98d0"
|
||||
integrity sha512-Tc7bJvpEdkWIVCUL7yQrMNBJY3j44NcyWS48jF/UKMXuUlzaXK+Z/pEL5LjGcTadtPvVmNqA40yv7hmr+tCOAw==
|
||||
rc-tabs@~15.3.0:
|
||||
version "15.3.0"
|
||||
resolved "https://registry.yarnpkg.com/rc-tabs/-/rc-tabs-15.3.0.tgz#3fcc332fbb9307d5eb147e0404daca871fb92a89"
|
||||
integrity sha512-lzE18r+zppT/jZWOAWS6ntdkDUKHOLJzqMi5UAij1LeKwOaQaupupAoI9Srn73GRzVpmGznkECMRrzkRusC40A==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.11.2"
|
||||
classnames "2.x"
|
||||
rc-dropdown "~4.2.0"
|
||||
rc-menu "~9.14.0"
|
||||
rc-menu "~9.15.1"
|
||||
rc-motion "^2.6.2"
|
||||
rc-resize-observer "^1.0.0"
|
||||
rc-util "^5.34.1"
|
||||
|
||||
rc-textarea@~1.8.0, rc-textarea@~1.8.1:
|
||||
version "1.8.1"
|
||||
resolved "https://registry.yarnpkg.com/rc-textarea/-/rc-textarea-1.8.1.tgz#0313ed2e7980269e1bd4f3c203a4e9a84cad8e2d"
|
||||
integrity sha512-bm36N2ZqwZAP60ZQg2OY9mPdqWC+m6UTjHc+CqEZOxb3Ia29BGHazY/s5bI8M4113CkqTzhtFUDNA078ZiOx3Q==
|
||||
rc-textarea@~1.8.0, rc-textarea@~1.8.2:
|
||||
version "1.8.2"
|
||||
resolved "https://registry.yarnpkg.com/rc-textarea/-/rc-textarea-1.8.2.tgz#57a6847304551c1883fc3fb0c5076d587f70bf7f"
|
||||
integrity sha512-UFAezAqltyR00a8Lf0IPAyTd29Jj9ee8wt8DqXyDMal7r/Cg/nDt3e1OOv3Th4W6mKaZijjgwuPXhAfVNTN8sw==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.10.1"
|
||||
classnames "^2.2.1"
|
||||
@@ -8477,10 +8643,10 @@ rc-textarea@~1.8.0, rc-textarea@~1.8.1:
|
||||
rc-resize-observer "^1.0.0"
|
||||
rc-util "^5.27.0"
|
||||
|
||||
rc-tooltip@~6.2.0:
|
||||
version "6.2.0"
|
||||
resolved "https://registry.yarnpkg.com/rc-tooltip/-/rc-tooltip-6.2.0.tgz#4dd7575674137a5b14f118a5c16435d3f5e4a9c9"
|
||||
integrity sha512-iS/3iOAvtDh9GIx1ulY7EFUXUtktFccNLsARo3NPgLf0QW9oT0w3dA9cYWlhqAKmD+uriEwdWz1kH0Qs4zk2Aw==
|
||||
rc-tooltip@~6.2.1:
|
||||
version "6.2.1"
|
||||
resolved "https://registry.yarnpkg.com/rc-tooltip/-/rc-tooltip-6.2.1.tgz#9a8f0335c86443a0c20c2557933205f645a381b7"
|
||||
integrity sha512-rws0duD/3sHHsD905Nex7FvoUGy2UBQRhTkKxeEvr2FB+r21HsOxcDJI0TzyO8NHhnAA8ILr8pfbSBg5Jj5KBg==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.11.2"
|
||||
"@rc-component/trigger" "^2.0.0"
|
||||
@@ -8508,16 +8674,16 @@ rc-tree@~5.9.0:
|
||||
rc-util "^5.16.1"
|
||||
rc-virtual-list "^3.5.1"
|
||||
|
||||
rc-upload@~4.7.0:
|
||||
version "4.7.0"
|
||||
resolved "https://registry.yarnpkg.com/rc-upload/-/rc-upload-4.7.0.tgz#719c6e66549844f4db8c57f066f2758c0a43b525"
|
||||
integrity sha512-eUwxYNHlsYe5vYhKFAUGrQG95JrnPzY+BmPi1Daq39fWNl/eOc7v4UODuWrVp2LFkQBuV3cMCG/I68iub6oBrg==
|
||||
rc-upload@~4.8.1:
|
||||
version "4.8.1"
|
||||
resolved "https://registry.yarnpkg.com/rc-upload/-/rc-upload-4.8.1.tgz#ac55f2bc101b95b52a6e47f3c18f0f55b54e16d2"
|
||||
integrity sha512-toEAhwl4hjLAI1u8/CgKWt30BR06ulPa4iGQSMvSXoHzO88gPCslxqV/mnn4gJU7PDoltGIC9Eh+wkeudqgHyw==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.18.3"
|
||||
classnames "^2.2.5"
|
||||
rc-util "^5.2.0"
|
||||
|
||||
rc-util@^5.0.1, rc-util@^5.16.1, rc-util@^5.17.0, rc-util@^5.18.1, rc-util@^5.2.0, rc-util@^5.20.1, rc-util@^5.21.0, rc-util@^5.24.4, rc-util@^5.25.2, rc-util@^5.27.0, rc-util@^5.30.0, rc-util@^5.31.1, rc-util@^5.32.2, rc-util@^5.34.1, rc-util@^5.35.0, rc-util@^5.36.0, rc-util@^5.37.0, rc-util@^5.38.0, rc-util@^5.38.1, rc-util@^5.40.1, rc-util@^5.43.0:
|
||||
rc-util@^5.0.1, rc-util@^5.16.1, rc-util@^5.17.0, rc-util@^5.18.1, rc-util@^5.2.0, rc-util@^5.20.1, rc-util@^5.21.0, rc-util@^5.24.4, rc-util@^5.25.2, rc-util@^5.27.0, rc-util@^5.30.0, rc-util@^5.31.1, rc-util@^5.32.2, rc-util@^5.34.1, rc-util@^5.35.0, rc-util@^5.36.0, rc-util@^5.37.0, rc-util@^5.38.0, rc-util@^5.38.1, rc-util@^5.40.1, rc-util@^5.41.0, rc-util@^5.43.0:
|
||||
version "5.43.0"
|
||||
resolved "https://registry.yarnpkg.com/rc-util/-/rc-util-5.43.0.tgz#bba91fbef2c3e30ea2c236893746f3e9b05ecc4c"
|
||||
integrity sha512-AzC7KKOXFqAdIBqdGWepL9Xn7cm3vnAmjlHqUnoQaTMZYhM4VlXGLkkHHxj/BZ7Td0+SOPKB4RGPboBVKT9htw==
|
||||
@@ -9668,10 +9834,10 @@ stylehacks@^6.1.1:
|
||||
browserslist "^4.23.0"
|
||||
postcss-selector-parser "^6.0.16"
|
||||
|
||||
stylis@^4.0.13:
|
||||
version "4.3.2"
|
||||
resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.3.2.tgz#8f76b70777dd53eb669c6f58c997bf0a9972e444"
|
||||
integrity sha512-bhtUjWd/z6ltJiQwg0dUfxEJ+W+jdqQd8TbWLWyeIJHlnsqmGLRFFd8e5mA0AZi/zx90smXRlN66YMTcaSFifg==
|
||||
stylis@^4.3.3:
|
||||
version "4.3.4"
|
||||
resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.3.4.tgz#ca5c6c4a35c4784e4e93a2a24dc4e9fa075250a4"
|
||||
integrity sha512-osIBl6BGUmSfDkyH2mB7EFvCJntXDrLhKjHTRj/rK6xLH0yuPrHULDRQzKokSOD4VoorhtKpfcfW1GAntu8now==
|
||||
|
||||
supports-color@^5.3.0:
|
||||
version "5.5.0"
|
||||
@@ -9984,10 +10150,10 @@ types-ramda@^0.30.0:
|
||||
dependencies:
|
||||
ts-toolbelt "^9.6.0"
|
||||
|
||||
typescript@^5.5.4:
|
||||
version "5.5.4"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.5.4.tgz#d9852d6c82bad2d2eda4fd74a5762a8f5909e9ba"
|
||||
integrity sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==
|
||||
typescript@^5.6.3:
|
||||
version "5.6.3"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.6.3.tgz#5f3449e31c9d94febb17de03cc081dd56d81db5b"
|
||||
integrity sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==
|
||||
|
||||
undici-types@~5.26.4:
|
||||
version "5.26.5"
|
||||
@@ -10110,13 +10276,13 @@ unraw@^3.0.0:
|
||||
resolved "https://registry.yarnpkg.com/unraw/-/unraw-3.0.0.tgz#73443ed70d2ab09ccbac2b00525602d5991fbbe3"
|
||||
integrity sha512-08/DA66UF65OlpUDIQtbJyrqTR0jTAlJ+jsnkQ4jxR7+K5g5YG1APZKQSMCE1vqqmD+2pv6+IdEjmopFatacvg==
|
||||
|
||||
update-browserslist-db@^1.0.13:
|
||||
version "1.0.14"
|
||||
resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.14.tgz#46a9367c323f8ade9a9dddb7f3ae7814b3a0b31c"
|
||||
integrity sha512-JixKH8GR2pWYshIPUg/NujK3JO7JiqEEUiNArE86NQyrgUuZeTlZQN3xuS/yiV5Kb48ev9K6RqNkaJjXsdg7Jw==
|
||||
update-browserslist-db@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz#80846fba1d79e82547fb661f8d141e0945755fe5"
|
||||
integrity sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==
|
||||
dependencies:
|
||||
escalade "^3.1.2"
|
||||
picocolors "^1.0.0"
|
||||
escalade "^3.2.0"
|
||||
picocolors "^1.1.0"
|
||||
|
||||
update-notifier@^6.0.2:
|
||||
version "6.0.2"
|
||||
@@ -10336,18 +10502,18 @@ webpack-sources@^3.2.3:
|
||||
resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde"
|
||||
integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==
|
||||
|
||||
webpack@^5.88.1, webpack@^5.94.0:
|
||||
version "5.94.0"
|
||||
resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.94.0.tgz#77a6089c716e7ab90c1c67574a28da518a20970f"
|
||||
integrity sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg==
|
||||
webpack@^5.88.1, webpack@^5.96.1:
|
||||
version "5.96.1"
|
||||
resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.96.1.tgz#3676d1626d8312b6b10d0c18cc049fba7ac01f0c"
|
||||
integrity sha512-l2LlBSvVZGhL4ZrPwyr8+37AunkcYj5qh8o6u2/2rzoPc8gxFJkLj1WxNgooi9pnoc06jh0BjuXnamM4qlujZA==
|
||||
dependencies:
|
||||
"@types/estree" "^1.0.5"
|
||||
"@types/eslint-scope" "^3.7.7"
|
||||
"@types/estree" "^1.0.6"
|
||||
"@webassemblyjs/ast" "^1.12.1"
|
||||
"@webassemblyjs/wasm-edit" "^1.12.1"
|
||||
"@webassemblyjs/wasm-parser" "^1.12.1"
|
||||
acorn "^8.7.1"
|
||||
acorn-import-attributes "^1.9.5"
|
||||
browserslist "^4.21.10"
|
||||
acorn "^8.14.0"
|
||||
browserslist "^4.24.0"
|
||||
chrome-trace-event "^1.0.2"
|
||||
enhanced-resolve "^5.17.1"
|
||||
es-module-lexer "^1.2.1"
|
||||
|
||||
@@ -29,7 +29,7 @@ maintainers:
|
||||
- name: craig-rueda
|
||||
email: craig@craigrueda.com
|
||||
url: https://github.com/craig-rueda
|
||||
version: 0.12.13
|
||||
version: 0.13.0
|
||||
dependencies:
|
||||
- name: postgresql
|
||||
version: 12.1.6
|
||||
|
||||
@@ -23,7 +23,7 @@ NOTE: This file is generated by helm-docs: https://github.com/norwoodj/helm-docs
|
||||
|
||||
# superset
|
||||
|
||||

|
||||

|
||||
|
||||
Apache Superset is a modern, enterprise-ready business intelligence web application
|
||||
|
||||
@@ -69,6 +69,7 @@ On helm this can be set on `extraSecretEnv.SUPERSET_SECRET_KEY` or `configOverri
|
||||
| extraConfigs | object | `{}` | Extra files to mount on `/app/pythonpath` |
|
||||
| extraEnv | object | `{}` | Extra environment variables that will be passed into pods |
|
||||
| extraEnvRaw | list | `[]` | Extra environment variables in RAW format that will be passed into pods |
|
||||
| extraLabels | object | `{}` | Labels to be added to all resources |
|
||||
| extraSecretEnv | object | `{}` | Extra environment variables to pass as secrets |
|
||||
| extraSecrets | object | `{}` | Extra files to mount on `/app/pythonpath` as secrets |
|
||||
| extraVolumeMounts | list | `[]` | |
|
||||
|
||||
@@ -28,6 +28,9 @@ metadata:
|
||||
chart: {{ template "superset.chart" . }}
|
||||
release: {{ .Release.Name }}
|
||||
heritage: {{ .Release.Service }}
|
||||
{{- if .Values.extraLabels }}
|
||||
{{- toYaml .Values.extraLabels | nindent 4 }}
|
||||
{{- end }}
|
||||
data:
|
||||
{{- range $path, $config := .Values.extraConfigs }}
|
||||
{{ $path }}: |
|
||||
|
||||
@@ -28,6 +28,9 @@ metadata:
|
||||
chart: {{ template "superset.chart" . }}
|
||||
release: {{ .Release.Name }}
|
||||
heritage: {{ .Release.Service }}
|
||||
{{- if .Values.extraLabels }}
|
||||
{{- toYaml .Values.extraLabels | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- if .Values.supersetCeleryBeat.deploymentAnnotations }}
|
||||
annotations: {{- toYaml .Values.supersetCeleryBeat.deploymentAnnotations | nindent 4 }}
|
||||
{{- end }}
|
||||
@@ -58,6 +61,9 @@ spec:
|
||||
labels:
|
||||
app: "{{ template "superset.name" . }}-celerybeat"
|
||||
release: {{ .Release.Name }}
|
||||
{{- if .Values.extraLabels }}
|
||||
{{- toYaml .Values.extraLabels | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if .Values.supersetCeleryBeat.podLabels }}
|
||||
{{- toYaml .Values.supersetCeleryBeat.podLabels | nindent 8 }}
|
||||
{{- end }}
|
||||
|
||||
@@ -28,6 +28,9 @@ metadata:
|
||||
chart: {{ template "superset.chart" . }}
|
||||
release: {{ .Release.Name }}
|
||||
heritage: {{ .Release.Service }}
|
||||
{{- if .Values.extraLabels }}
|
||||
{{- toYaml .Values.extraLabels | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- if .Values.supersetCeleryFlower.deploymentAnnotations }}
|
||||
annotations: {{- toYaml .Values.supersetCeleryFlower.deploymentAnnotations | nindent 4 }}
|
||||
{{- end }}
|
||||
@@ -47,6 +50,9 @@ spec:
|
||||
labels:
|
||||
app: "{{ template "superset.name" . }}-flower"
|
||||
release: {{ .Release.Name }}
|
||||
{{- if .Values.extraLabels }}
|
||||
{{- toYaml .Values.extraLabels | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if .Values.supersetCeleryFlower.podLabels }}
|
||||
{{- toYaml .Values.supersetCeleryFlower.podLabels | nindent 8 }}
|
||||
{{- end }}
|
||||
|
||||
@@ -27,6 +27,9 @@ metadata:
|
||||
chart: {{ template "superset.chart" . }}
|
||||
release: {{ .Release.Name }}
|
||||
heritage: {{ .Release.Service }}
|
||||
{{- if .Values.extraLabels }}
|
||||
{{- toYaml .Values.extraLabels | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- if .Values.supersetWorker.deploymentLabels }}
|
||||
{{- toYaml .Values.supersetWorker.deploymentLabels | nindent 4 }}
|
||||
{{- end }}
|
||||
@@ -64,6 +67,9 @@ spec:
|
||||
labels:
|
||||
app: {{ template "superset.name" . }}-worker
|
||||
release: {{ .Release.Name }}
|
||||
{{- if .Values.extraLabels }}
|
||||
{{- toYaml .Values.extraLabels | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if .Values.supersetWorker.podLabels }}
|
||||
{{- toYaml .Values.supersetWorker.podLabels | nindent 8 }}
|
||||
{{- end }}
|
||||
|
||||
@@ -28,6 +28,9 @@ metadata:
|
||||
chart: {{ template "superset.chart" . }}
|
||||
release: {{ .Release.Name }}
|
||||
heritage: {{ .Release.Service }}
|
||||
{{- if .Values.extraLabels }}
|
||||
{{- toYaml .Values.extraLabels | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- if .Values.supersetWebsockets.deploymentAnnotations }}
|
||||
annotations: {{- toYaml .Values.supersetWebsockets.deploymentAnnotations | nindent 4 }}
|
||||
{{- end }}
|
||||
@@ -50,6 +53,9 @@ spec:
|
||||
labels:
|
||||
app: "{{ template "superset.name" . }}-ws"
|
||||
release: {{ .Release.Name }}
|
||||
{{- if .Values.extraLabels }}
|
||||
{{- toYaml .Values.extraLabels | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if .Values.supersetWebsockets.podLabels }}
|
||||
{{- toYaml .Values.supersetWebsockets.podLabels | nindent 8 }}
|
||||
{{- end }}
|
||||
|
||||
@@ -27,6 +27,9 @@ metadata:
|
||||
chart: {{ template "superset.chart" . }}
|
||||
release: {{ .Release.Name }}
|
||||
heritage: {{ .Release.Service }}
|
||||
{{- if .Values.extraLabels }}
|
||||
{{- toYaml .Values.extraLabels | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- if .Values.supersetNode.deploymentLabels }}
|
||||
{{- toYaml .Values.supersetNode.deploymentLabels | nindent 4 }}
|
||||
{{- end }}
|
||||
@@ -66,6 +69,9 @@ spec:
|
||||
labels:
|
||||
app: {{ template "superset.name" . }}
|
||||
release: {{ .Release.Name }}
|
||||
{{- if .Values.extraLabels }}
|
||||
{{- toYaml .Values.extraLabels | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if .Values.supersetNode.podLabels }}
|
||||
{{- toYaml .Values.supersetNode.podLabels | nindent 8 }}
|
||||
{{- end }}
|
||||
|
||||
@@ -27,6 +27,9 @@ metadata:
|
||||
chart: {{ template "superset.chart" . }}
|
||||
release: {{ .Release.Name }}
|
||||
heritage: {{ .Release.Service }}
|
||||
{{- if .Values.extraLabels }}
|
||||
{{- toYaml .Values.extraLabels | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
scaleTargetRef:
|
||||
apiVersion: apps/v1
|
||||
|
||||
@@ -27,6 +27,9 @@ metadata:
|
||||
chart: {{ template "superset.chart" . }}
|
||||
release: {{ .Release.Name }}
|
||||
heritage: {{ .Release.Service }}
|
||||
{{- if .Values.extraLabels }}
|
||||
{{- toYaml .Values.extraLabels | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
scaleTargetRef:
|
||||
apiVersion: apps/v1
|
||||
|
||||
@@ -29,6 +29,9 @@ metadata:
|
||||
chart: {{ template "superset.chart" . }}
|
||||
release: {{ .Release.Name }}
|
||||
heritage: {{ .Release.Service }}
|
||||
{{- if .Values.extraLabels }}
|
||||
{{- toYaml .Values.extraLabels | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- with .Values.ingress.annotations }}
|
||||
annotations: {{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
|
||||
@@ -23,6 +23,10 @@ kind: Job
|
||||
metadata:
|
||||
name: {{ template "superset.fullname" . }}-init-db
|
||||
namespace: {{ .Release.Namespace }}
|
||||
{{- if .Values.extraLabels }}
|
||||
labels:
|
||||
{{- toYaml .Values.extraLabels | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- if .Values.init.jobAnnotations }}
|
||||
annotations: {{- toYaml .Values.init.jobAnnotations | nindent 4 }}
|
||||
{{- end }}
|
||||
|
||||
@@ -31,6 +31,9 @@ metadata:
|
||||
chart: {{ template "superset.chart" $ }}
|
||||
release: {{ $.Release.Name }}
|
||||
heritage: {{ $.Release.Service }}
|
||||
{{- if .Values.extraLabels }}
|
||||
{{- toYaml .Values.extraLabels | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- if .minAvailable }}
|
||||
minAvailable: {{ .minAvailable }}
|
||||
|
||||
@@ -31,6 +31,9 @@ metadata:
|
||||
chart: {{ template "superset.chart" $ }}
|
||||
release: {{ $.Release.Name }}
|
||||
heritage: {{ $.Release.Service }}
|
||||
{{- if .Values.extraLabels }}
|
||||
{{- toYaml .Values.extraLabels | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- if .minAvailable }}
|
||||
minAvailable: {{ .minAvailable }}
|
||||
|
||||
@@ -31,6 +31,9 @@ metadata:
|
||||
chart: {{ template "superset.chart" $ }}
|
||||
release: {{ $.Release.Name }}
|
||||
heritage: {{ $.Release.Service }}
|
||||
{{- if .Values.extraLabels }}
|
||||
{{- toYaml .Values.extraLabels | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- if .minAvailable }}
|
||||
minAvailable: {{ .minAvailable }}
|
||||
|
||||
@@ -31,6 +31,9 @@ metadata:
|
||||
chart: {{ template "superset.chart" $ }}
|
||||
release: {{ $.Release.Name }}
|
||||
heritage: {{ $.Release.Service }}
|
||||
{{- if .Values.extraLabels }}
|
||||
{{- toYaml .Values.extraLabels | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- if .minAvailable }}
|
||||
minAvailable: {{ .minAvailable }}
|
||||
|
||||
@@ -31,6 +31,9 @@ metadata:
|
||||
chart: {{ template "superset.chart" $ }}
|
||||
release: {{ $.Release.Name }}
|
||||
heritage: {{ $.Release.Service }}
|
||||
{{- if .Values.extraLabels }}
|
||||
{{- toYaml .Values.extraLabels | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- if .minAvailable }}
|
||||
minAvailable: {{ .minAvailable }}
|
||||
|
||||
@@ -27,6 +27,9 @@ metadata:
|
||||
chart: {{ template "superset.chart" . }}
|
||||
release: "{{ .Release.Name }}"
|
||||
heritage: "{{ .Release.Service }}"
|
||||
{{- if .Values.extraLabels }}
|
||||
{{- toYaml .Values.extraLabels | nindent 4 }}
|
||||
{{- end }}
|
||||
type: Opaque
|
||||
stringData:
|
||||
REDIS_HOST: {{ tpl .Values.supersetNode.connections.redis_host . | quote }}
|
||||
|
||||
@@ -27,6 +27,9 @@ metadata:
|
||||
chart: {{ template "superset.chart" . }}
|
||||
release: "{{ .Release.Name }}"
|
||||
heritage: "{{ .Release.Service }}"
|
||||
{{- if .Values.extraLabels }}
|
||||
{{- toYaml .Values.extraLabels | nindent 4 }}
|
||||
{{- end }}
|
||||
type: Opaque
|
||||
stringData:
|
||||
superset_config.py: |
|
||||
|
||||
@@ -28,6 +28,9 @@ metadata:
|
||||
chart: {{ template "superset.chart" . }}
|
||||
release: "{{ .Release.Name }}"
|
||||
heritage: "{{ .Release.Service }}"
|
||||
{{- if .Values.extraLabels }}
|
||||
{{- toYaml .Values.extraLabels | nindent 4 }}
|
||||
{{- end }}
|
||||
type: Opaque
|
||||
stringData:
|
||||
config.json: |
|
||||
|
||||
@@ -28,6 +28,9 @@ metadata:
|
||||
chart: {{ template "superset.chart" . }}
|
||||
release: {{ .Release.Name }}
|
||||
heritage: {{ .Release.Service }}
|
||||
{{- if .Values.extraLabels }}
|
||||
{{- toYaml .Values.extraLabels | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- with .Values.supersetCeleryFlower.service.annotations }}
|
||||
annotations: {{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
|
||||
@@ -28,6 +28,9 @@ metadata:
|
||||
chart: {{ template "superset.chart" . }}
|
||||
release: {{ .Release.Name }}
|
||||
heritage: {{ .Release.Service }}
|
||||
{{- if .Values.extraLabels }}
|
||||
{{- toYaml .Values.extraLabels | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- with .Values.supersetWebsockets.service.annotations }}
|
||||
annotations: {{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
|
||||
@@ -27,6 +27,9 @@ metadata:
|
||||
chart: {{ template "superset.chart" . }}
|
||||
release: {{ .Release.Name }}
|
||||
heritage: {{ .Release.Service }}
|
||||
{{- if .Values.extraLabels }}
|
||||
{{- toYaml .Values.extraLabels | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- with .Values.service.annotations }}
|
||||
annotations: {{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
|
||||
@@ -32,6 +32,9 @@ metadata:
|
||||
kubernetes.io/cluster-service: "true"
|
||||
{{- end }}
|
||||
addonmanager.kubernetes.io/mode: Reconcile
|
||||
{{- if .Values.extraLabels }}
|
||||
{{- toYaml .Values.extraLabels | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- if .Values.serviceAccount.annotations }}
|
||||
annotations: {{- toYaml .Values.serviceAccount.annotations | nindent 4 }}
|
||||
{{- end }}
|
||||
|
||||
@@ -27,6 +27,9 @@ nameOverride: ~
|
||||
# -- Provide a name to override the full names of resources
|
||||
fullnameOverride: ~
|
||||
|
||||
# -- Labels to be added to all resources
|
||||
extraLabels: {}
|
||||
|
||||
# -- User ID directive. This user must have enough permissions to run the bootstrap script
|
||||
# Running containers as root is not recommended in production. Change this to another UID - e.g. 1000 to be more secure
|
||||
runAsUser: 0
|
||||
|
||||
@@ -57,6 +57,7 @@ dependencies = [
|
||||
"geopy",
|
||||
"gunicorn>=22.0.0; sys_platform != 'win32'",
|
||||
"hashids>=1.3.1, <2",
|
||||
# known issue with holidays 0.26.0 and above related to prophet lib #25017
|
||||
"holidays>=0.25, <0.26",
|
||||
"humanize",
|
||||
"importlib_metadata",
|
||||
@@ -89,7 +90,7 @@ dependencies = [
|
||||
"slack_sdk>=3.19.0, <4",
|
||||
"sqlalchemy>=1.4, <2",
|
||||
"sqlalchemy-utils>=0.38.3, <0.39",
|
||||
"sqlglot>=23.0.2,<24",
|
||||
"sqlglot>=25.24.0,<26",
|
||||
"sqlparse>=0.5.0",
|
||||
"tabulate>=0.8.9, <0.9",
|
||||
"typing-extensions>=4, <5",
|
||||
@@ -118,6 +119,7 @@ databricks = [
|
||||
"sqlalchemy-databricks>=0.2.0",
|
||||
]
|
||||
db2 = ["ibm-db-sa>0.3.8, <=0.4.0"]
|
||||
denodo = ["denodo-sqlalchemy~=1.0.6"]
|
||||
dremio = ["sqlalchemy-dremio>=1.2.1, <4"]
|
||||
drill = ["sqlalchemy-drill>=1.1.4, <2"]
|
||||
druid = ["pydruid>=0.6.5,<0.7"]
|
||||
@@ -445,6 +447,7 @@ select = [
|
||||
"E7",
|
||||
"E9",
|
||||
"F",
|
||||
"PT009",
|
||||
"TRY201",
|
||||
]
|
||||
ignore = []
|
||||
|
||||
@@ -109,7 +109,7 @@ flask==2.3.3
|
||||
# flask-session
|
||||
# flask-sqlalchemy
|
||||
# flask-wtf
|
||||
flask-appbuilder==4.5.0
|
||||
flask-appbuilder==4.5.2
|
||||
# via apache-superset
|
||||
flask-babel==2.0.0
|
||||
# via flask-appbuilder
|
||||
@@ -350,7 +350,7 @@ sqlalchemy-utils==0.38.3
|
||||
# via
|
||||
# apache-superset
|
||||
# flask-appbuilder
|
||||
sqlglot==23.6.3
|
||||
sqlglot==25.24.0
|
||||
# via apache-superset
|
||||
sqlparse==0.5.0
|
||||
# via apache-superset
|
||||
@@ -385,7 +385,7 @@ vine==5.1.0
|
||||
# kombu
|
||||
wcwidth==0.2.13
|
||||
# via prompt-toolkit
|
||||
werkzeug==3.0.3
|
||||
werkzeug==3.0.6
|
||||
# via
|
||||
# -r requirements/base.in
|
||||
# flask
|
||||
@@ -394,7 +394,7 @@ werkzeug==3.0.3
|
||||
# flask-login
|
||||
wrapt==1.16.0
|
||||
# via deprecated
|
||||
wtforms==3.1.2
|
||||
wtforms==3.2.1
|
||||
# via
|
||||
# apache-superset
|
||||
# flask-appbuilder
|
||||
|
||||
@@ -16,26 +16,18 @@
|
||||
# under the License.
|
||||
|
||||
import argparse
|
||||
import hashlib
|
||||
import os
|
||||
import subprocess
|
||||
from datetime import datetime
|
||||
|
||||
XVFB_PRE_CMD = "xvfb-run --auto-servernum --server-args='-screen 0, 1024x768x24' "
|
||||
REPO = os.getenv("GITHUB_REPOSITORY") or "apache/superset"
|
||||
GITHUB_EVENT_NAME = os.getenv("GITHUB_REPOSITORY") or "push"
|
||||
GITHUB_EVENT_NAME = os.getenv("GITHUB_EVENT_NAME") or "push"
|
||||
CYPRESS_RECORD_KEY = os.getenv("CYPRESS_RECORD_KEY") or ""
|
||||
|
||||
|
||||
def compute_hash(file_path: str) -> str:
|
||||
return hashlib.md5(file_path.encode()).hexdigest()
|
||||
|
||||
|
||||
def compute_group_index(hash_value: str, num_groups: int) -> int:
|
||||
return int(hash_value, 16) % num_groups
|
||||
|
||||
|
||||
def generate_build_id() -> str:
|
||||
"""Generates a build ID based on the current timestamp."""
|
||||
now = datetime.now()
|
||||
rounded_minute = now.minute - (now.minute % 20)
|
||||
rounded_time = now.replace(minute=rounded_minute, second=0, microsecond=0)
|
||||
@@ -44,42 +36,72 @@ def generate_build_id() -> str:
|
||||
)
|
||||
|
||||
|
||||
def get_cypress_cmd(
|
||||
spec_list: list[str], _filter: str, group: str, use_dashboard: bool
|
||||
) -> str:
|
||||
def run_cypress_for_test_file(
|
||||
test_file: str, retries: int, use_dashboard: bool, group: str, dry_run: bool, i: int
|
||||
) -> int:
|
||||
"""Runs Cypress for a single test file and retries upon failure."""
|
||||
cypress_cmd = "./node_modules/.bin/cypress run"
|
||||
|
||||
os.environ["TERM"] = "xterm"
|
||||
os.environ["ELECTRON_DISABLE_GPU"] = "true"
|
||||
build_id = generate_build_id()
|
||||
browser = os.getenv("CYPRESS_BROWSER", "chrome")
|
||||
chrome_flags = "--disable-dev-shm-usage"
|
||||
|
||||
if use_dashboard:
|
||||
# Run using cypress.io service
|
||||
spec: str = "cypress/e2e/*/**/*"
|
||||
cmd = (
|
||||
f"{XVFB_PRE_CMD} "
|
||||
f'{cypress_cmd} --spec "{spec}" --browser {browser} '
|
||||
f"--record --group {group} --tag {REPO},{GITHUB_EVENT_NAME} "
|
||||
f"--parallel --ci-build-id {build_id}"
|
||||
for attempt in range(retries):
|
||||
# Create Cypress command for a single test file
|
||||
cmd: str = ""
|
||||
if use_dashboard:
|
||||
# If/when we want to use cypress' dashboard feature to record the run
|
||||
group_id = f"matrix{group}-file{i}-{attempt}"
|
||||
cmd = (
|
||||
f"{XVFB_PRE_CMD} "
|
||||
f'{cypress_cmd} --spec "{test_file}" --browser {browser} '
|
||||
f"--record --group {group_id} --tag {REPO},{GITHUB_EVENT_NAME} "
|
||||
f"--ci-build-id {build_id} "
|
||||
f"-- {chrome_flags}"
|
||||
)
|
||||
else:
|
||||
os.environ.pop("CYPRESS_RECORD_KEY", None)
|
||||
cmd = (
|
||||
f"{XVFB_PRE_CMD} "
|
||||
f"{cypress_cmd} --browser {browser} "
|
||||
f'--spec "{test_file}" '
|
||||
f"-- {chrome_flags}"
|
||||
)
|
||||
print(f"RUN: {cmd} (Attempt {attempt + 1}/{retries})")
|
||||
if dry_run:
|
||||
# Print the command instead of executing it
|
||||
print(f"DRY RUN: {cmd}")
|
||||
return 0
|
||||
|
||||
process = subprocess.Popen(
|
||||
cmd,
|
||||
shell=True,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT,
|
||||
universal_newlines=True,
|
||||
)
|
||||
else:
|
||||
# Run local, but split the execution
|
||||
os.environ.pop("CYPRESS_RECORD_KEY", None)
|
||||
spec_list_str = ",".join(sorted(spec_list))
|
||||
if _filter:
|
||||
spec_list_str = ",".join(sorted([s for s in spec_list if _filter in s]))
|
||||
cmd = (
|
||||
f"{XVFB_PRE_CMD} "
|
||||
f"{cypress_cmd} --browser {browser} "
|
||||
f'--spec "{spec_list_str}" '
|
||||
)
|
||||
return cmd
|
||||
|
||||
# Stream stdout in real-time
|
||||
if process.stdout:
|
||||
for stdout_line in iter(process.stdout.readline, ""):
|
||||
print(stdout_line, end="")
|
||||
|
||||
process.wait()
|
||||
|
||||
if process.returncode == 0:
|
||||
print(f"Test {test_file} succeeded on attempt {attempt + 1}")
|
||||
return 0
|
||||
else:
|
||||
print(f"Test {test_file} failed on attempt {attempt + 1}")
|
||||
|
||||
print(f"Test {test_file} failed after {retries} retries.")
|
||||
return process.returncode
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Generate Cypress commands based on test file hash"
|
||||
description="Run Cypress tests with retries per test file"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--use-dashboard",
|
||||
@@ -93,9 +115,12 @@ def main() -> None:
|
||||
"--parallelism-id", type=int, required=True, help="ID of the parallelism group"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--filter", type=str, required=False, default=None, help="filter to test"
|
||||
"--filter", type=str, required=False, default=None, help="Filter to test"
|
||||
)
|
||||
parser.add_argument("--group", type=str, default="Default", help="Group name")
|
||||
parser.add_argument(
|
||||
"--retries", type=int, default=3, help="Number of retries per test file"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--dry-run",
|
||||
action="store_true",
|
||||
@@ -109,14 +134,17 @@ def main() -> None:
|
||||
cypress_tests_path = os.path.join(cypress_base_full_path, "cypress/e2e")
|
||||
|
||||
test_files = []
|
||||
file_count = 0
|
||||
for root, _, files in os.walk(cypress_tests_path):
|
||||
for file in files:
|
||||
if file.endswith("test.ts") or file.endswith("test.js"):
|
||||
file_count += 1
|
||||
test_files.append(
|
||||
os.path.join(root, file).replace(cypress_base_full_path, "")
|
||||
)
|
||||
print(f"Found {file_count} test files.")
|
||||
|
||||
# Initialize groups
|
||||
# Initialize groups for round-robin distribution
|
||||
groups: dict[int, list[str]] = {i: [] for i in range(args.parallelism)}
|
||||
|
||||
# Sort test files to ensure deterministic distribution
|
||||
@@ -127,12 +155,21 @@ def main() -> None:
|
||||
group_index = index % args.parallelism
|
||||
groups[group_index].append(test_file)
|
||||
|
||||
# Only run tests for the group that matches the parallelism ID
|
||||
group_id = args.parallelism_id
|
||||
spec_list = groups[group_id]
|
||||
cmd = get_cypress_cmd(spec_list, args.filter, args.group, args.use_dashboard)
|
||||
print(f"RUN: {cmd}")
|
||||
if not args.dry_run:
|
||||
subprocess.run(cmd, shell=True, check=True, stdout=None, stderr=None)
|
||||
|
||||
# Run each test file independently with retry logic or dry-run
|
||||
processed_file_count: int = 0
|
||||
for i, test_file in enumerate(spec_list):
|
||||
result = run_cypress_for_test_file(
|
||||
test_file, args.retries, args.use_dashboard, args.group, args.dry_run, i
|
||||
)
|
||||
if result != 0:
|
||||
print(f"Exiting due to failure in {test_file}")
|
||||
exit(result)
|
||||
processed_file_count += 1
|
||||
print(f"Ran {processed_file_count} test files successfully.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -280,7 +280,6 @@ module.exports = {
|
||||
'theme-colors/no-literal-colors': 0,
|
||||
'translation-vars/no-template-vars': 0,
|
||||
'no-restricted-imports': 0,
|
||||
'jest/no-alias-methods': 0,
|
||||
'react/no-void-elements': 0,
|
||||
},
|
||||
},
|
||||
@@ -371,7 +370,6 @@ module.exports = {
|
||||
'react-prefer-function-component/react-prefer-function-component': 1,
|
||||
'prettier/prettier': 'error',
|
||||
// disabling some things that come with the eslint 7->8 upgrade. Will address these in a separate PR
|
||||
'jest/no-alias-methods': 0,
|
||||
'react/no-unknown-property': 0,
|
||||
'react/no-void-elements': 0,
|
||||
'react/function-component-definition': [
|
||||
|
||||
@@ -0,0 +1,248 @@
|
||||
/**
|
||||
* 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 { nativeFilters } from 'cypress/support/directories';
|
||||
|
||||
import {
|
||||
addCountryNameFilter,
|
||||
applyNativeFilterValueWithIndex,
|
||||
enterNativeFilterEditModal,
|
||||
inputNativeFilterDefaultValue,
|
||||
saveNativeFilterSettings,
|
||||
validateFilterNameOnDashboard,
|
||||
testItems,
|
||||
interceptFilterState,
|
||||
} from './utils';
|
||||
import {
|
||||
prepareDashboardFilters,
|
||||
SAMPLE_CHART,
|
||||
visitDashboard,
|
||||
} from './shared_dashboard_functions';
|
||||
|
||||
function openMoreFilters(waitFilterState = true) {
|
||||
interceptFilterState();
|
||||
cy.getBySel('dropdown-container-btn').click();
|
||||
|
||||
if (waitFilterState) {
|
||||
cy.wait('@postFilterState');
|
||||
}
|
||||
}
|
||||
|
||||
function openVerticalFilterBar() {
|
||||
cy.getBySel('dashboard-filters-panel').should('exist');
|
||||
cy.getBySel('filter-bar__expand-button').click();
|
||||
}
|
||||
|
||||
function setFilterBarOrientation(orientation: 'vertical' | 'horizontal') {
|
||||
cy.getBySel('filterbar-orientation-icon').click();
|
||||
cy.wait(250);
|
||||
cy.getBySel('dropdown-selectable-icon-submenu')
|
||||
.contains('Orientation of filter bar')
|
||||
.should('exist')
|
||||
.trigger('mouseover');
|
||||
|
||||
if (orientation === 'vertical') {
|
||||
cy.get('.ant-dropdown-menu-item-selected')
|
||||
.contains('Horizontal (Top)')
|
||||
.should('exist');
|
||||
cy.get('.ant-dropdown-menu-item').contains('Vertical (Left)').click();
|
||||
cy.getBySel('dashboard-filters-panel').should('exist');
|
||||
} else {
|
||||
cy.get('.ant-dropdown-menu-item-selected')
|
||||
.contains('Vertical (Left)')
|
||||
.should('exist');
|
||||
cy.get('.ant-dropdown-menu-item').contains('Horizontal (Top)').click();
|
||||
cy.getBySel('loading-indicator').should('exist');
|
||||
cy.getBySel('filter-bar').should('exist');
|
||||
cy.getBySel('dashboard-filters-panel').should('not.exist');
|
||||
}
|
||||
}
|
||||
|
||||
describe('Horizontal FilterBar', () => {
|
||||
it('should go from vertical to horizontal and the opposite', () => {
|
||||
visitDashboard();
|
||||
openVerticalFilterBar();
|
||||
setFilterBarOrientation('horizontal');
|
||||
setFilterBarOrientation('vertical');
|
||||
});
|
||||
|
||||
it('should show all default actions in horizontal mode', () => {
|
||||
visitDashboard();
|
||||
openVerticalFilterBar();
|
||||
setFilterBarOrientation('horizontal');
|
||||
cy.getBySel('horizontal-filterbar-empty')
|
||||
.contains('No filters are currently added to this dashboard.')
|
||||
.should('exist');
|
||||
cy.getBySel('filter-bar__create-filter').should('exist');
|
||||
cy.getBySel('filterbar-action-buttons').should('exist');
|
||||
});
|
||||
|
||||
it('should stay in horizontal mode when reloading', () => {
|
||||
visitDashboard();
|
||||
openVerticalFilterBar();
|
||||
setFilterBarOrientation('horizontal');
|
||||
cy.reload();
|
||||
cy.getBySel('dashboard-filters-panel').should('not.exist');
|
||||
});
|
||||
|
||||
it('should show all filters in available space on load', () => {
|
||||
prepareDashboardFilters([
|
||||
{ name: 'test_1', column: 'country_name', datasetId: 2 },
|
||||
{ name: 'test_2', column: 'country_code', datasetId: 2 },
|
||||
{ name: 'test_3', column: 'region', datasetId: 2 },
|
||||
]);
|
||||
setFilterBarOrientation('horizontal');
|
||||
cy.get('.filter-item-wrapper').should('have.length', 3);
|
||||
});
|
||||
|
||||
it('should show "more filters" on window resizing up and down', () => {
|
||||
prepareDashboardFilters([
|
||||
{ name: 'test_1', column: 'country_name', datasetId: 2 },
|
||||
{ name: 'test_2', column: 'country_code', datasetId: 2 },
|
||||
{ name: 'test_3', column: 'region', datasetId: 2 },
|
||||
]);
|
||||
setFilterBarOrientation('horizontal');
|
||||
|
||||
cy.getBySel('form-item-value').should('have.length', 3);
|
||||
cy.viewport(768, 1024);
|
||||
cy.getBySel('form-item-value').should('have.length', 0);
|
||||
openMoreFilters(false);
|
||||
cy.getBySel('form-item-value').should('have.length', 3);
|
||||
|
||||
cy.getBySel('filter-bar').click();
|
||||
cy.viewport(1000, 1024);
|
||||
openMoreFilters(false);
|
||||
cy.getBySel('form-item-value').should('have.length', 3);
|
||||
|
||||
cy.getBySel('filter-bar').click();
|
||||
cy.viewport(1300, 1024);
|
||||
cy.getBySel('form-item-value').should('have.length', 3);
|
||||
cy.getBySel('dropdown-container-btn').should('not.exist');
|
||||
});
|
||||
|
||||
it('should show "more filters" and scroll', () => {
|
||||
prepareDashboardFilters([
|
||||
{ name: 'test_1', column: 'country_name', datasetId: 2 },
|
||||
{ name: 'test_2', column: 'country_code', datasetId: 2 },
|
||||
{ name: 'test_3', column: 'region', datasetId: 2 },
|
||||
{ name: 'test_4', column: 'year', datasetId: 2 },
|
||||
{ name: 'test_5', column: 'country_name', datasetId: 2 },
|
||||
{ name: 'test_6', column: 'country_code', datasetId: 2 },
|
||||
{ name: 'test_7', column: 'region', datasetId: 2 },
|
||||
{ name: 'test_8', column: 'year', datasetId: 2 },
|
||||
{ name: 'test_9', column: 'country_name', datasetId: 2 },
|
||||
{ name: 'test_10', column: 'country_code', datasetId: 2 },
|
||||
{ name: 'test_11', column: 'region', datasetId: 2 },
|
||||
{ name: 'test_12', column: 'year', datasetId: 2 },
|
||||
]);
|
||||
setFilterBarOrientation('horizontal');
|
||||
cy.get('.filter-item-wrapper').should('have.length', 3);
|
||||
openMoreFilters();
|
||||
cy.getBySel('form-item-value').should('have.length', 12);
|
||||
cy.getBySel('filter-control-name').contains('test_10').should('be.visible');
|
||||
cy.getBySel('filter-control-name')
|
||||
.contains('test_12')
|
||||
.should('not.be.visible');
|
||||
cy.get('.ant-popover-inner-content').scrollTo('bottom');
|
||||
cy.getBySel('filter-control-name').contains('test_12').should('be.visible');
|
||||
});
|
||||
|
||||
it('should display newly added filter', () => {
|
||||
visitDashboard();
|
||||
openVerticalFilterBar();
|
||||
setFilterBarOrientation('horizontal');
|
||||
|
||||
enterNativeFilterEditModal(false);
|
||||
addCountryNameFilter();
|
||||
saveNativeFilterSettings([]);
|
||||
validateFilterNameOnDashboard(testItems.topTenChart.filterColumn);
|
||||
});
|
||||
|
||||
it('should spot changes in "more filters" and apply their values', () => {
|
||||
cy.intercept(`/api/v1/chart/data?form_data=**`).as('chart');
|
||||
prepareDashboardFilters([
|
||||
{ name: 'test_1', column: 'country_name', datasetId: 2 },
|
||||
{ name: 'test_2', column: 'country_code', datasetId: 2 },
|
||||
{ name: 'test_3', column: 'region', datasetId: 2 },
|
||||
{ name: 'test_4', column: 'year', datasetId: 2 },
|
||||
{ name: 'test_5', column: 'country_name', datasetId: 2 },
|
||||
{ name: 'test_6', column: 'country_code', datasetId: 2 },
|
||||
{ name: 'test_7', column: 'region', datasetId: 2 },
|
||||
{ name: 'test_8', column: 'year', datasetId: 2 },
|
||||
{ name: 'test_9', column: 'country_name', datasetId: 2 },
|
||||
{ name: 'test_10', column: 'country_code', datasetId: 2 },
|
||||
{ name: 'test_11', column: 'region', datasetId: 2 },
|
||||
{ name: 'test_12', column: 'year', datasetId: 2 },
|
||||
]);
|
||||
setFilterBarOrientation('horizontal');
|
||||
openMoreFilters();
|
||||
applyNativeFilterValueWithIndex(8, testItems.filterDefaultValue);
|
||||
cy.get(nativeFilters.applyFilter).click({ force: true });
|
||||
cy.wait('@chart');
|
||||
cy.get('.antd5-scroll-number.antd5-badge-count').should(
|
||||
'have.attr',
|
||||
'title',
|
||||
'1',
|
||||
);
|
||||
});
|
||||
|
||||
it('should focus filter and open "more filters" programmatically', () => {
|
||||
prepareDashboardFilters([
|
||||
{ name: 'test_1', column: 'country_name', datasetId: 2 },
|
||||
{ name: 'test_2', column: 'country_code', datasetId: 2 },
|
||||
{ name: 'test_3', column: 'region', datasetId: 2 },
|
||||
{ name: 'test_4', column: 'year', datasetId: 2 },
|
||||
{ name: 'test_5', column: 'country_name', datasetId: 2 },
|
||||
{ name: 'test_6', column: 'country_code', datasetId: 2 },
|
||||
{ name: 'test_7', column: 'region', datasetId: 2 },
|
||||
{ name: 'test_8', column: 'year', datasetId: 2 },
|
||||
{ name: 'test_9', column: 'country_name', datasetId: 2 },
|
||||
{ name: 'test_10', column: 'country_code', datasetId: 2 },
|
||||
{ name: 'test_11', column: 'region', datasetId: 2 },
|
||||
{ name: 'test_12', column: 'year', datasetId: 2 },
|
||||
]);
|
||||
setFilterBarOrientation('horizontal');
|
||||
openMoreFilters();
|
||||
applyNativeFilterValueWithIndex(8, testItems.filterDefaultValue);
|
||||
cy.get(nativeFilters.applyFilter).click({ force: true });
|
||||
cy.getBySel('slice-header').within(() => {
|
||||
cy.get('.filter-counts').trigger('mouseover');
|
||||
});
|
||||
cy.get('.filterStatusPopover').contains('test_9').click();
|
||||
cy.getBySel('dropdown-content').should('be.visible');
|
||||
cy.get('.ant-select-focused').should('be.visible');
|
||||
});
|
||||
|
||||
it('should show tag count and one plain tag on focus and only count on blur in select ', () => {
|
||||
prepareDashboardFilters([
|
||||
{ name: 'test_1', column: 'country_name', datasetId: 2 },
|
||||
]);
|
||||
setFilterBarOrientation('horizontal');
|
||||
enterNativeFilterEditModal();
|
||||
inputNativeFilterDefaultValue('Albania');
|
||||
cy.get('.ant-select-selection-search-input').clear({ force: true });
|
||||
inputNativeFilterDefaultValue('Algeria', true);
|
||||
saveNativeFilterSettings([SAMPLE_CHART]);
|
||||
cy.getBySel('filter-bar').within(() => {
|
||||
cy.get(nativeFilters.filterItem).contains('Albania').should('be.visible');
|
||||
cy.get(nativeFilters.filterItem).contains('+ 1 ...').should('be.visible');
|
||||
cy.get('.ant-select-selection-search-input').click();
|
||||
cy.get(nativeFilters.filterItem).contains('+ 2 ...').should('be.visible');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,287 @@
|
||||
/**
|
||||
* 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 qs from 'querystring';
|
||||
import {
|
||||
dashboardView,
|
||||
nativeFilters,
|
||||
exploreView,
|
||||
dataTestChartName,
|
||||
} from 'cypress/support/directories';
|
||||
|
||||
import {
|
||||
addCountryNameFilter,
|
||||
addParentFilterWithValue,
|
||||
applyAdvancedTimeRangeFilterOnDashboard,
|
||||
applyNativeFilterValueWithIndex,
|
||||
cancelNativeFilterSettings,
|
||||
checkNativeFilterTooltip,
|
||||
clickOnAddFilterInModal,
|
||||
collapseFilterOnLeftPanel,
|
||||
deleteNativeFilter,
|
||||
enterNativeFilterEditModal,
|
||||
expandFilterOnLeftPanel,
|
||||
fillNativeFilterForm,
|
||||
getNativeFilterPlaceholderWithIndex,
|
||||
inputNativeFilterDefaultValue,
|
||||
saveNativeFilterSettings,
|
||||
nativeFilterTooltips,
|
||||
undoDeleteNativeFilter,
|
||||
validateFilterContentOnDashboard,
|
||||
valueNativeFilterOptions,
|
||||
validateFilterNameOnDashboard,
|
||||
testItems,
|
||||
WORLD_HEALTH_CHARTS,
|
||||
} from './utils';
|
||||
import {
|
||||
prepareDashboardFilters,
|
||||
SAMPLE_CHART,
|
||||
visitDashboard,
|
||||
} from './shared_dashboard_functions';
|
||||
|
||||
function selectFilter(index: number) {
|
||||
cy.get("[data-test='filter-title-container'] [draggable='true']")
|
||||
.eq(index)
|
||||
.click();
|
||||
}
|
||||
|
||||
function closeFilterModal() {
|
||||
cy.get('body').then($body => {
|
||||
if ($body.find('[data-test="native-filter-modal-cancel-button"]').length) {
|
||||
cy.getBySel('native-filter-modal-cancel-button').click();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
describe('Native filters', () => {
|
||||
describe('Nativefilters initial state not required', () => {
|
||||
it("User can check 'Filter has default value'", () => {
|
||||
prepareDashboardFilters([
|
||||
{ name: 'country_name', column: 'country_name', datasetId: 2 },
|
||||
]);
|
||||
enterNativeFilterEditModal();
|
||||
inputNativeFilterDefaultValue(testItems.filterDefaultValue);
|
||||
});
|
||||
|
||||
it('User can add a new native filter', () => {
|
||||
prepareDashboardFilters([]);
|
||||
|
||||
let filterKey: string;
|
||||
const removeFirstChar = (search: string) =>
|
||||
search.split('').slice(1, search.length).join('');
|
||||
|
||||
cy.location().then(loc => {
|
||||
cy.url().should('contain', 'native_filters_key');
|
||||
const queryParams = qs.parse(removeFirstChar(loc.search));
|
||||
filterKey = queryParams.native_filters_key as string;
|
||||
expect(typeof filterKey).eq('string');
|
||||
});
|
||||
enterNativeFilterEditModal();
|
||||
addCountryNameFilter();
|
||||
saveNativeFilterSettings([SAMPLE_CHART]);
|
||||
cy.location().then(loc => {
|
||||
cy.url().should('contain', 'native_filters_key');
|
||||
const queryParams = qs.parse(removeFirstChar(loc.search));
|
||||
const newfilterKey = queryParams.native_filters_key;
|
||||
expect(newfilterKey).eq(filterKey);
|
||||
});
|
||||
cy.get(nativeFilters.modal.container).should('not.exist');
|
||||
});
|
||||
|
||||
it('User can restore a deleted native filter', () => {
|
||||
prepareDashboardFilters([
|
||||
{ name: 'country_code', column: 'country_code', datasetId: 2 },
|
||||
]);
|
||||
enterNativeFilterEditModal();
|
||||
cy.get(nativeFilters.filtersList.removeIcon).first().click();
|
||||
cy.get('[data-test="restore-filter-button"]')
|
||||
.should('be.visible')
|
||||
.click();
|
||||
cy.get(nativeFilters.modal.container)
|
||||
.find(nativeFilters.filtersPanel.filterName)
|
||||
.should(
|
||||
'have.attr',
|
||||
'value',
|
||||
testItems.topTenChart.filterColumnCountryCode,
|
||||
);
|
||||
});
|
||||
|
||||
it('User can create a time grain filter', () => {
|
||||
prepareDashboardFilters([]);
|
||||
enterNativeFilterEditModal();
|
||||
fillNativeFilterForm(
|
||||
testItems.filterType.timeGrain,
|
||||
testItems.filterType.timeGrain,
|
||||
testItems.datasetForNativeFilter,
|
||||
);
|
||||
saveNativeFilterSettings([SAMPLE_CHART]);
|
||||
applyNativeFilterValueWithIndex(0, testItems.filterTimeGrain);
|
||||
cy.get(nativeFilters.applyFilter).click();
|
||||
cy.url().then(u => {
|
||||
const ur = new URL(u);
|
||||
expect(ur.search).to.include('native_filters');
|
||||
});
|
||||
validateFilterNameOnDashboard(testItems.filterType.timeGrain);
|
||||
validateFilterContentOnDashboard(testItems.filterTimeGrain);
|
||||
});
|
||||
|
||||
it.skip('User can create a time range filter', () => {
|
||||
enterNativeFilterEditModal();
|
||||
fillNativeFilterForm(
|
||||
testItems.filterType.timeRange,
|
||||
testItems.filterType.timeRange,
|
||||
);
|
||||
saveNativeFilterSettings(WORLD_HEALTH_CHARTS);
|
||||
cy.get(dashboardView.salesDashboardSpecific.vehicleSalesFilterTimeRange)
|
||||
.should('be.visible')
|
||||
.click();
|
||||
applyAdvancedTimeRangeFilterOnDashboard('2005-12-17', '2006-12-17');
|
||||
cy.url().then(u => {
|
||||
const ur = new URL(u);
|
||||
expect(ur.search).to.include('native_filters');
|
||||
});
|
||||
validateFilterNameOnDashboard(testItems.filterType.timeRange);
|
||||
cy.get(nativeFilters.filterFromDashboardView.timeRangeFilterContent)
|
||||
.contains('2005-12-17')
|
||||
.should('be.visible');
|
||||
});
|
||||
|
||||
it.skip('User can create a time column filter', () => {
|
||||
enterNativeFilterEditModal();
|
||||
fillNativeFilterForm(
|
||||
testItems.filterType.timeColumn,
|
||||
testItems.filterType.timeColumn,
|
||||
testItems.datasetForNativeFilter,
|
||||
);
|
||||
saveNativeFilterSettings(WORLD_HEALTH_CHARTS);
|
||||
cy.intercept(`/api/v1/chart/data?form_data=**`).as('chart');
|
||||
cy.get(nativeFilters.modal.container).should('not.exist');
|
||||
// assert that native filter is created
|
||||
validateFilterNameOnDashboard(testItems.filterType.timeColumn);
|
||||
applyNativeFilterValueWithIndex(
|
||||
0,
|
||||
testItems.topTenChart.filterColumnYear,
|
||||
);
|
||||
cy.get(nativeFilters.applyFilter).click({ force: true });
|
||||
cy.wait('@chart');
|
||||
validateFilterContentOnDashboard(testItems.topTenChart.filterColumnYear);
|
||||
});
|
||||
|
||||
it('User can create a numerical range filter', () => {
|
||||
visitDashboard();
|
||||
enterNativeFilterEditModal(false);
|
||||
fillNativeFilterForm(
|
||||
testItems.filterType.numerical,
|
||||
testItems.filterNumericalColumn,
|
||||
testItems.datasetForNativeFilter,
|
||||
testItems.filterNumericalColumn,
|
||||
);
|
||||
saveNativeFilterSettings([]);
|
||||
// assertions
|
||||
cy.get(nativeFilters.slider.slider).should('be.visible').click('center');
|
||||
cy.get(nativeFilters.applyFilter).click();
|
||||
// assert that the url contains 'native_filters' in the url
|
||||
cy.url().then(u => {
|
||||
const ur = new URL(u);
|
||||
expect(ur.search).to.include('native_filters');
|
||||
// assert that the start handle has a value
|
||||
cy.get(nativeFilters.slider.startHandle)
|
||||
.invoke('attr', 'aria-valuenow')
|
||||
.should('exist');
|
||||
// assert that the end handle has a value
|
||||
cy.get(nativeFilters.slider.endHandle)
|
||||
.invoke('attr', 'aria-valuenow')
|
||||
.should('exist');
|
||||
// assert slider text matches what we should have
|
||||
cy.get(nativeFilters.slider.sliderText).should('have.text', '49');
|
||||
});
|
||||
});
|
||||
|
||||
it('User can undo deleting a native filter', () => {
|
||||
prepareDashboardFilters([
|
||||
{ name: 'country_name', column: 'country_name', datasetId: 2 },
|
||||
]);
|
||||
enterNativeFilterEditModal();
|
||||
undoDeleteNativeFilter();
|
||||
cy.get(nativeFilters.modal.container)
|
||||
.find(nativeFilters.filtersPanel.filterName)
|
||||
.should('have.attr', 'value', testItems.topTenChart.filterColumn);
|
||||
});
|
||||
|
||||
it('User can cancel changes in native filter', () => {
|
||||
prepareDashboardFilters([
|
||||
{ name: 'country_name', column: 'country_name', datasetId: 2 },
|
||||
]);
|
||||
enterNativeFilterEditModal();
|
||||
cy.getBySel('filters-config-modal__name-input').type('|EDITED', {
|
||||
force: true,
|
||||
});
|
||||
cancelNativeFilterSettings();
|
||||
enterNativeFilterEditModal(false);
|
||||
cy.get(nativeFilters.filtersList.removeIcon).first().click();
|
||||
cy.contains('You have removed this filter.').should('be.visible');
|
||||
});
|
||||
|
||||
it('User can create a value filter', () => {
|
||||
visitDashboard();
|
||||
enterNativeFilterEditModal(false);
|
||||
addCountryNameFilter();
|
||||
cy.get(nativeFilters.filtersPanel.filterTypeInput)
|
||||
.find(nativeFilters.filtersPanel.filterTypeItem)
|
||||
.should('have.text', testItems.filterType.value);
|
||||
saveNativeFilterSettings([]);
|
||||
validateFilterNameOnDashboard(testItems.topTenChart.filterColumn);
|
||||
});
|
||||
|
||||
it('User can apply value filter with selected values', () => {
|
||||
prepareDashboardFilters([
|
||||
{ name: 'country_name', column: 'country_name', datasetId: 2 },
|
||||
]);
|
||||
applyNativeFilterValueWithIndex(0, testItems.filterDefaultValue);
|
||||
cy.get(nativeFilters.applyFilter).click();
|
||||
cy.get(dataTestChartName(testItems.topTenChart.name)).within(() => {
|
||||
cy.contains(testItems.filterDefaultValue).should('be.visible');
|
||||
cy.contains(testItems.filterOtherCountry).should('not.exist');
|
||||
});
|
||||
});
|
||||
|
||||
it('User can stop filtering when filter is removed', () => {
|
||||
prepareDashboardFilters([
|
||||
{ name: 'country_name', column: 'country_name', datasetId: 2 },
|
||||
]);
|
||||
enterNativeFilterEditModal();
|
||||
inputNativeFilterDefaultValue(testItems.filterDefaultValue);
|
||||
saveNativeFilterSettings([SAMPLE_CHART]);
|
||||
cy.get(dataTestChartName(testItems.topTenChart.name)).within(() => {
|
||||
cy.contains(testItems.filterDefaultValue).should('be.visible');
|
||||
cy.contains(testItems.filterOtherCountry).should('not.exist');
|
||||
});
|
||||
cy.get(nativeFilters.filterItem)
|
||||
.contains(testItems.filterDefaultValue)
|
||||
.should('be.visible');
|
||||
validateFilterNameOnDashboard(testItems.topTenChart.filterColumn);
|
||||
enterNativeFilterEditModal(false);
|
||||
deleteNativeFilter();
|
||||
saveNativeFilterSettings([SAMPLE_CHART]);
|
||||
cy.get(dataTestChartName(testItems.topTenChart.name)).within(() => {
|
||||
cy.contains(testItems.filterDefaultValue).should('be.visible');
|
||||
cy.contains(testItems.filterOtherCountry).should('be.visible');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -23,7 +23,6 @@ import {
|
||||
exploreView,
|
||||
dataTestChartName,
|
||||
} from 'cypress/support/directories';
|
||||
import { SAMPLE_DASHBOARD_1 } from 'cypress/utils/urls';
|
||||
|
||||
import {
|
||||
addCountryNameFilter,
|
||||
@@ -48,138 +47,12 @@ import {
|
||||
validateFilterNameOnDashboard,
|
||||
testItems,
|
||||
WORLD_HEALTH_CHARTS,
|
||||
interceptGet,
|
||||
interceptCharts,
|
||||
interceptDatasets,
|
||||
interceptFilterState,
|
||||
} from './utils';
|
||||
|
||||
const SAMPLE_CHART = { name: 'Most Populated Countries', viz: 'table' };
|
||||
|
||||
function visitDashboard(createSample = true) {
|
||||
interceptCharts();
|
||||
interceptGet();
|
||||
interceptDatasets();
|
||||
|
||||
if (createSample) {
|
||||
cy.createSampleDashboards([0]);
|
||||
}
|
||||
|
||||
cy.visit(SAMPLE_DASHBOARD_1);
|
||||
cy.wait('@get');
|
||||
cy.wait('@getCharts');
|
||||
cy.wait('@getDatasets');
|
||||
cy.url().should('contain', 'native_filters_key');
|
||||
}
|
||||
|
||||
function prepareDashboardFilters(
|
||||
filters: { name: string; column: string; datasetId: number }[],
|
||||
) {
|
||||
cy.createSampleDashboards([0]);
|
||||
cy.request({
|
||||
method: 'GET',
|
||||
url: `api/v1/dashboard/1-sample-dashboard`,
|
||||
}).then(res => {
|
||||
const { body } = res;
|
||||
const dashboardId = body.result.id;
|
||||
const allFilters: Record<string, unknown>[] = [];
|
||||
filters.forEach((f, i) => {
|
||||
allFilters.push({
|
||||
id: `NATIVE_FILTER-fLH0pxFQ${i}`,
|
||||
controlValues: {
|
||||
enableEmptyFilter: false,
|
||||
defaultToFirstItem: false,
|
||||
multiSelect: true,
|
||||
searchAllOptions: false,
|
||||
inverseSelection: false,
|
||||
},
|
||||
name: f.name,
|
||||
filterType: 'filter_select',
|
||||
targets: [
|
||||
{
|
||||
datasetId: f.datasetId,
|
||||
column: { name: f.column },
|
||||
},
|
||||
],
|
||||
defaultDataMask: {
|
||||
extraFormData: {},
|
||||
filterState: {},
|
||||
ownState: {},
|
||||
},
|
||||
cascadeParentIds: [],
|
||||
scope: {
|
||||
rootPath: ['ROOT_ID'],
|
||||
excluded: [],
|
||||
},
|
||||
type: 'NATIVE_FILTER',
|
||||
description: '',
|
||||
chartsInScope: [5],
|
||||
tabsInScope: [],
|
||||
});
|
||||
});
|
||||
if (dashboardId) {
|
||||
const jsonMetadata = {
|
||||
native_filter_configuration: allFilters,
|
||||
timed_refresh_immune_slices: [],
|
||||
expanded_slices: {},
|
||||
refresh_frequency: 0,
|
||||
color_scheme: '',
|
||||
label_colors: {},
|
||||
shared_label_colors: {},
|
||||
color_scheme_domain: [],
|
||||
cross_filters_enabled: false,
|
||||
positions: {
|
||||
DASHBOARD_VERSION_KEY: 'v2',
|
||||
ROOT_ID: { type: 'ROOT', id: 'ROOT_ID', children: ['GRID_ID'] },
|
||||
GRID_ID: {
|
||||
type: 'GRID',
|
||||
id: 'GRID_ID',
|
||||
children: ['ROW-0rHnUz4nMA'],
|
||||
parents: ['ROOT_ID'],
|
||||
},
|
||||
HEADER_ID: {
|
||||
id: 'HEADER_ID',
|
||||
type: 'HEADER',
|
||||
meta: { text: '1 - Sample dashboard' },
|
||||
},
|
||||
'CHART-DF6EfI55F-': {
|
||||
type: 'CHART',
|
||||
id: 'CHART-DF6EfI55F-',
|
||||
children: [],
|
||||
parents: ['ROOT_ID', 'GRID_ID', 'ROW-0rHnUz4nMA'],
|
||||
meta: {
|
||||
width: 4,
|
||||
height: 50,
|
||||
chartId: 5,
|
||||
sliceName: 'Most Populated Countries',
|
||||
},
|
||||
},
|
||||
'ROW-0rHnUz4nMA': {
|
||||
type: 'ROW',
|
||||
id: 'ROW-0rHnUz4nMA',
|
||||
children: ['CHART-DF6EfI55F-'],
|
||||
parents: ['ROOT_ID', 'GRID_ID'],
|
||||
meta: { background: 'BACKGROUND_TRANSPARENT' },
|
||||
},
|
||||
},
|
||||
default_filters: '{}',
|
||||
filter_scopes: {},
|
||||
chart_configuration: {},
|
||||
};
|
||||
|
||||
return cy
|
||||
.request({
|
||||
method: 'PUT',
|
||||
url: `api/v1/dashboard/${dashboardId}`,
|
||||
body: {
|
||||
json_metadata: JSON.stringify(jsonMetadata),
|
||||
},
|
||||
})
|
||||
.then(() => visitDashboard(false));
|
||||
}
|
||||
return cy;
|
||||
});
|
||||
}
|
||||
import {
|
||||
prepareDashboardFilters,
|
||||
SAMPLE_CHART,
|
||||
visitDashboard,
|
||||
} from './shared_dashboard_functions';
|
||||
|
||||
function selectFilter(index: number) {
|
||||
cy.get("[data-test='filter-title-container'] [draggable='true']")
|
||||
@@ -195,219 +68,6 @@ function closeFilterModal() {
|
||||
});
|
||||
}
|
||||
|
||||
function openVerticalFilterBar() {
|
||||
cy.getBySel('dashboard-filters-panel').should('exist');
|
||||
cy.getBySel('filter-bar__expand-button').click();
|
||||
}
|
||||
|
||||
function setFilterBarOrientation(orientation: 'vertical' | 'horizontal') {
|
||||
cy.getBySel('filterbar-orientation-icon').click();
|
||||
cy.wait(250);
|
||||
cy.getBySel('dropdown-selectable-icon-submenu')
|
||||
.contains('Orientation of filter bar')
|
||||
.should('exist')
|
||||
.trigger('mouseover');
|
||||
|
||||
if (orientation === 'vertical') {
|
||||
cy.get('.ant-dropdown-menu-item-selected')
|
||||
.contains('Horizontal (Top)')
|
||||
.should('exist');
|
||||
cy.get('.ant-dropdown-menu-item').contains('Vertical (Left)').click();
|
||||
cy.getBySel('dashboard-filters-panel').should('exist');
|
||||
} else {
|
||||
cy.get('.ant-dropdown-menu-item-selected')
|
||||
.contains('Vertical (Left)')
|
||||
.should('exist');
|
||||
cy.get('.ant-dropdown-menu-item').contains('Horizontal (Top)').click();
|
||||
cy.getBySel('loading-indicator').should('exist');
|
||||
cy.getBySel('filter-bar').should('exist');
|
||||
cy.getBySel('dashboard-filters-panel').should('not.exist');
|
||||
}
|
||||
}
|
||||
|
||||
function openMoreFilters(waitFilterState = true) {
|
||||
interceptFilterState();
|
||||
cy.getBySel('dropdown-container-btn').click();
|
||||
|
||||
if (waitFilterState) {
|
||||
cy.wait('@postFilterState');
|
||||
}
|
||||
}
|
||||
|
||||
describe('Horizontal FilterBar', () => {
|
||||
it('should go from vertical to horizontal and the opposite', () => {
|
||||
visitDashboard();
|
||||
openVerticalFilterBar();
|
||||
setFilterBarOrientation('horizontal');
|
||||
setFilterBarOrientation('vertical');
|
||||
});
|
||||
|
||||
it('should show all default actions in horizontal mode', () => {
|
||||
visitDashboard();
|
||||
openVerticalFilterBar();
|
||||
setFilterBarOrientation('horizontal');
|
||||
cy.getBySel('horizontal-filterbar-empty')
|
||||
.contains('No filters are currently added to this dashboard.')
|
||||
.should('exist');
|
||||
cy.getBySel('filter-bar__create-filter').should('exist');
|
||||
cy.getBySel('filterbar-action-buttons').should('exist');
|
||||
});
|
||||
|
||||
it('should stay in horizontal mode when reloading', () => {
|
||||
visitDashboard();
|
||||
openVerticalFilterBar();
|
||||
setFilterBarOrientation('horizontal');
|
||||
cy.reload();
|
||||
cy.getBySel('dashboard-filters-panel').should('not.exist');
|
||||
});
|
||||
|
||||
it('should show all filters in available space on load', () => {
|
||||
prepareDashboardFilters([
|
||||
{ name: 'test_1', column: 'country_name', datasetId: 2 },
|
||||
{ name: 'test_2', column: 'country_code', datasetId: 2 },
|
||||
{ name: 'test_3', column: 'region', datasetId: 2 },
|
||||
]);
|
||||
setFilterBarOrientation('horizontal');
|
||||
cy.get('.filter-item-wrapper').should('have.length', 3);
|
||||
});
|
||||
|
||||
it('should show "more filters" on window resizing up and down', () => {
|
||||
prepareDashboardFilters([
|
||||
{ name: 'test_1', column: 'country_name', datasetId: 2 },
|
||||
{ name: 'test_2', column: 'country_code', datasetId: 2 },
|
||||
{ name: 'test_3', column: 'region', datasetId: 2 },
|
||||
]);
|
||||
setFilterBarOrientation('horizontal');
|
||||
|
||||
cy.getBySel('form-item-value').should('have.length', 3);
|
||||
cy.viewport(768, 1024);
|
||||
cy.getBySel('form-item-value').should('have.length', 0);
|
||||
openMoreFilters(false);
|
||||
cy.getBySel('form-item-value').should('have.length', 3);
|
||||
|
||||
cy.getBySel('filter-bar').click();
|
||||
cy.viewport(1000, 1024);
|
||||
openMoreFilters(false);
|
||||
cy.getBySel('form-item-value').should('have.length', 3);
|
||||
|
||||
cy.getBySel('filter-bar').click();
|
||||
cy.viewport(1300, 1024);
|
||||
cy.getBySel('form-item-value').should('have.length', 3);
|
||||
cy.getBySel('dropdown-container-btn').should('not.exist');
|
||||
});
|
||||
|
||||
it('should show "more filters" and scroll', () => {
|
||||
prepareDashboardFilters([
|
||||
{ name: 'test_1', column: 'country_name', datasetId: 2 },
|
||||
{ name: 'test_2', column: 'country_code', datasetId: 2 },
|
||||
{ name: 'test_3', column: 'region', datasetId: 2 },
|
||||
{ name: 'test_4', column: 'year', datasetId: 2 },
|
||||
{ name: 'test_5', column: 'country_name', datasetId: 2 },
|
||||
{ name: 'test_6', column: 'country_code', datasetId: 2 },
|
||||
{ name: 'test_7', column: 'region', datasetId: 2 },
|
||||
{ name: 'test_8', column: 'year', datasetId: 2 },
|
||||
{ name: 'test_9', column: 'country_name', datasetId: 2 },
|
||||
{ name: 'test_10', column: 'country_code', datasetId: 2 },
|
||||
{ name: 'test_11', column: 'region', datasetId: 2 },
|
||||
{ name: 'test_12', column: 'year', datasetId: 2 },
|
||||
]);
|
||||
setFilterBarOrientation('horizontal');
|
||||
cy.get('.filter-item-wrapper').should('have.length', 3);
|
||||
openMoreFilters();
|
||||
cy.getBySel('form-item-value').should('have.length', 12);
|
||||
cy.getBySel('filter-control-name').contains('test_10').should('be.visible');
|
||||
cy.getBySel('filter-control-name')
|
||||
.contains('test_12')
|
||||
.should('not.be.visible');
|
||||
cy.get('.ant-popover-inner-content').scrollTo('bottom');
|
||||
cy.getBySel('filter-control-name').contains('test_12').should('be.visible');
|
||||
});
|
||||
|
||||
it('should display newly added filter', () => {
|
||||
visitDashboard();
|
||||
openVerticalFilterBar();
|
||||
setFilterBarOrientation('horizontal');
|
||||
|
||||
enterNativeFilterEditModal(false);
|
||||
addCountryNameFilter();
|
||||
saveNativeFilterSettings([]);
|
||||
validateFilterNameOnDashboard(testItems.topTenChart.filterColumn);
|
||||
});
|
||||
|
||||
it('should spot changes in "more filters" and apply their values', () => {
|
||||
cy.intercept(`/api/v1/chart/data?form_data=**`).as('chart');
|
||||
prepareDashboardFilters([
|
||||
{ name: 'test_1', column: 'country_name', datasetId: 2 },
|
||||
{ name: 'test_2', column: 'country_code', datasetId: 2 },
|
||||
{ name: 'test_3', column: 'region', datasetId: 2 },
|
||||
{ name: 'test_4', column: 'year', datasetId: 2 },
|
||||
{ name: 'test_5', column: 'country_name', datasetId: 2 },
|
||||
{ name: 'test_6', column: 'country_code', datasetId: 2 },
|
||||
{ name: 'test_7', column: 'region', datasetId: 2 },
|
||||
{ name: 'test_8', column: 'year', datasetId: 2 },
|
||||
{ name: 'test_9', column: 'country_name', datasetId: 2 },
|
||||
{ name: 'test_10', column: 'country_code', datasetId: 2 },
|
||||
{ name: 'test_11', column: 'region', datasetId: 2 },
|
||||
{ name: 'test_12', column: 'year', datasetId: 2 },
|
||||
]);
|
||||
setFilterBarOrientation('horizontal');
|
||||
openMoreFilters();
|
||||
applyNativeFilterValueWithIndex(8, testItems.filterDefaultValue);
|
||||
cy.get(nativeFilters.applyFilter).click({ force: true });
|
||||
cy.wait('@chart');
|
||||
cy.get('.antd5-scroll-number.antd5-badge-count').should(
|
||||
'have.attr',
|
||||
'title',
|
||||
'1',
|
||||
);
|
||||
});
|
||||
|
||||
it('should focus filter and open "more filters" programmatically', () => {
|
||||
prepareDashboardFilters([
|
||||
{ name: 'test_1', column: 'country_name', datasetId: 2 },
|
||||
{ name: 'test_2', column: 'country_code', datasetId: 2 },
|
||||
{ name: 'test_3', column: 'region', datasetId: 2 },
|
||||
{ name: 'test_4', column: 'year', datasetId: 2 },
|
||||
{ name: 'test_5', column: 'country_name', datasetId: 2 },
|
||||
{ name: 'test_6', column: 'country_code', datasetId: 2 },
|
||||
{ name: 'test_7', column: 'region', datasetId: 2 },
|
||||
{ name: 'test_8', column: 'year', datasetId: 2 },
|
||||
{ name: 'test_9', column: 'country_name', datasetId: 2 },
|
||||
{ name: 'test_10', column: 'country_code', datasetId: 2 },
|
||||
{ name: 'test_11', column: 'region', datasetId: 2 },
|
||||
{ name: 'test_12', column: 'year', datasetId: 2 },
|
||||
]);
|
||||
setFilterBarOrientation('horizontal');
|
||||
openMoreFilters();
|
||||
applyNativeFilterValueWithIndex(8, testItems.filterDefaultValue);
|
||||
cy.get(nativeFilters.applyFilter).click({ force: true });
|
||||
cy.getBySel('slice-header').within(() => {
|
||||
cy.get('.filter-counts').trigger('mouseover');
|
||||
});
|
||||
cy.get('.filterStatusPopover').contains('test_9').click();
|
||||
cy.getBySel('dropdown-content').should('be.visible');
|
||||
cy.get('.ant-select-focused').should('be.visible');
|
||||
});
|
||||
|
||||
it('should show tag count and one plain tag on focus and only count on blur in select ', () => {
|
||||
prepareDashboardFilters([
|
||||
{ name: 'test_1', column: 'country_name', datasetId: 2 },
|
||||
]);
|
||||
setFilterBarOrientation('horizontal');
|
||||
enterNativeFilterEditModal();
|
||||
inputNativeFilterDefaultValue('Albania');
|
||||
cy.get('.ant-select-selection-search-input').clear({ force: true });
|
||||
inputNativeFilterDefaultValue('Algeria', true);
|
||||
saveNativeFilterSettings([SAMPLE_CHART]);
|
||||
cy.getBySel('filter-bar').within(() => {
|
||||
cy.get(nativeFilters.filterItem).contains('Albania').should('be.visible');
|
||||
cy.get(nativeFilters.filterItem).contains('+ 1 ...').should('be.visible');
|
||||
cy.get('.ant-select-selection-search-input').click();
|
||||
cy.get(nativeFilters.filterItem).contains('+ 2 ...').should('be.visible');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Native filters', () => {
|
||||
describe('Nativefilters tests initial state required', () => {
|
||||
beforeEach(() => {
|
||||
@@ -650,220 +310,4 @@ describe('Native filters', () => {
|
||||
cy.contains('Values are dependent on other filters').should('exist');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Nativefilters initial state not required', () => {
|
||||
it("User can check 'Filter has default value'", () => {
|
||||
prepareDashboardFilters([
|
||||
{ name: 'country_name', column: 'country_name', datasetId: 2 },
|
||||
]);
|
||||
enterNativeFilterEditModal();
|
||||
inputNativeFilterDefaultValue(testItems.filterDefaultValue);
|
||||
});
|
||||
|
||||
it('User can add a new native filter', () => {
|
||||
prepareDashboardFilters([]);
|
||||
|
||||
let filterKey: string;
|
||||
const removeFirstChar = (search: string) =>
|
||||
search.split('').slice(1, search.length).join('');
|
||||
|
||||
cy.location().then(loc => {
|
||||
cy.url().should('contain', 'native_filters_key');
|
||||
const queryParams = qs.parse(removeFirstChar(loc.search));
|
||||
filterKey = queryParams.native_filters_key as string;
|
||||
expect(typeof filterKey).eq('string');
|
||||
});
|
||||
enterNativeFilterEditModal();
|
||||
addCountryNameFilter();
|
||||
saveNativeFilterSettings([SAMPLE_CHART]);
|
||||
cy.location().then(loc => {
|
||||
cy.url().should('contain', 'native_filters_key');
|
||||
const queryParams = qs.parse(removeFirstChar(loc.search));
|
||||
const newfilterKey = queryParams.native_filters_key;
|
||||
expect(newfilterKey).eq(filterKey);
|
||||
});
|
||||
cy.get(nativeFilters.modal.container).should('not.exist');
|
||||
});
|
||||
|
||||
it('User can restore a deleted native filter', () => {
|
||||
prepareDashboardFilters([
|
||||
{ name: 'country_code', column: 'country_code', datasetId: 2 },
|
||||
]);
|
||||
enterNativeFilterEditModal();
|
||||
cy.get(nativeFilters.filtersList.removeIcon).first().click();
|
||||
cy.get('[data-test="restore-filter-button"]')
|
||||
.should('be.visible')
|
||||
.click();
|
||||
cy.get(nativeFilters.modal.container)
|
||||
.find(nativeFilters.filtersPanel.filterName)
|
||||
.should(
|
||||
'have.attr',
|
||||
'value',
|
||||
testItems.topTenChart.filterColumnCountryCode,
|
||||
);
|
||||
});
|
||||
|
||||
it('User can create a time grain filter', () => {
|
||||
prepareDashboardFilters([]);
|
||||
enterNativeFilterEditModal();
|
||||
fillNativeFilterForm(
|
||||
testItems.filterType.timeGrain,
|
||||
testItems.filterType.timeGrain,
|
||||
testItems.datasetForNativeFilter,
|
||||
);
|
||||
saveNativeFilterSettings([SAMPLE_CHART]);
|
||||
applyNativeFilterValueWithIndex(0, testItems.filterTimeGrain);
|
||||
cy.get(nativeFilters.applyFilter).click();
|
||||
cy.url().then(u => {
|
||||
const ur = new URL(u);
|
||||
expect(ur.search).to.include('native_filters');
|
||||
});
|
||||
validateFilterNameOnDashboard(testItems.filterType.timeGrain);
|
||||
validateFilterContentOnDashboard(testItems.filterTimeGrain);
|
||||
});
|
||||
|
||||
it.skip('User can create a time range filter', () => {
|
||||
enterNativeFilterEditModal();
|
||||
fillNativeFilterForm(
|
||||
testItems.filterType.timeRange,
|
||||
testItems.filterType.timeRange,
|
||||
);
|
||||
saveNativeFilterSettings(WORLD_HEALTH_CHARTS);
|
||||
cy.get(dashboardView.salesDashboardSpecific.vehicleSalesFilterTimeRange)
|
||||
.should('be.visible')
|
||||
.click();
|
||||
applyAdvancedTimeRangeFilterOnDashboard('2005-12-17', '2006-12-17');
|
||||
cy.url().then(u => {
|
||||
const ur = new URL(u);
|
||||
expect(ur.search).to.include('native_filters');
|
||||
});
|
||||
validateFilterNameOnDashboard(testItems.filterType.timeRange);
|
||||
cy.get(nativeFilters.filterFromDashboardView.timeRangeFilterContent)
|
||||
.contains('2005-12-17')
|
||||
.should('be.visible');
|
||||
});
|
||||
|
||||
it.skip('User can create a time column filter', () => {
|
||||
enterNativeFilterEditModal();
|
||||
fillNativeFilterForm(
|
||||
testItems.filterType.timeColumn,
|
||||
testItems.filterType.timeColumn,
|
||||
testItems.datasetForNativeFilter,
|
||||
);
|
||||
saveNativeFilterSettings(WORLD_HEALTH_CHARTS);
|
||||
cy.intercept(`/api/v1/chart/data?form_data=**`).as('chart');
|
||||
cy.get(nativeFilters.modal.container).should('not.exist');
|
||||
// assert that native filter is created
|
||||
validateFilterNameOnDashboard(testItems.filterType.timeColumn);
|
||||
applyNativeFilterValueWithIndex(
|
||||
0,
|
||||
testItems.topTenChart.filterColumnYear,
|
||||
);
|
||||
cy.get(nativeFilters.applyFilter).click({ force: true });
|
||||
cy.wait('@chart');
|
||||
validateFilterContentOnDashboard(testItems.topTenChart.filterColumnYear);
|
||||
});
|
||||
|
||||
it('User can create a numerical range filter', () => {
|
||||
visitDashboard();
|
||||
enterNativeFilterEditModal(false);
|
||||
fillNativeFilterForm(
|
||||
testItems.filterType.numerical,
|
||||
testItems.filterNumericalColumn,
|
||||
testItems.datasetForNativeFilter,
|
||||
testItems.filterNumericalColumn,
|
||||
);
|
||||
saveNativeFilterSettings([]);
|
||||
// assertions
|
||||
cy.get(nativeFilters.slider.slider).should('be.visible').click('center');
|
||||
cy.get(nativeFilters.applyFilter).click();
|
||||
// assert that the url contains 'native_filters' in the url
|
||||
cy.url().then(u => {
|
||||
const ur = new URL(u);
|
||||
expect(ur.search).to.include('native_filters');
|
||||
// assert that the start handle has a value
|
||||
cy.get(nativeFilters.slider.startHandle)
|
||||
.invoke('attr', 'aria-valuenow')
|
||||
.should('exist');
|
||||
// assert that the end handle has a value
|
||||
cy.get(nativeFilters.slider.endHandle)
|
||||
.invoke('attr', 'aria-valuenow')
|
||||
.should('exist');
|
||||
// assert slider text matches what we should have
|
||||
cy.get(nativeFilters.slider.sliderText).should('have.text', '49');
|
||||
});
|
||||
});
|
||||
|
||||
it('User can undo deleting a native filter', () => {
|
||||
prepareDashboardFilters([
|
||||
{ name: 'country_name', column: 'country_name', datasetId: 2 },
|
||||
]);
|
||||
enterNativeFilterEditModal();
|
||||
undoDeleteNativeFilter();
|
||||
cy.get(nativeFilters.modal.container)
|
||||
.find(nativeFilters.filtersPanel.filterName)
|
||||
.should('have.attr', 'value', testItems.topTenChart.filterColumn);
|
||||
});
|
||||
|
||||
it('User can cancel changes in native filter', () => {
|
||||
prepareDashboardFilters([
|
||||
{ name: 'country_name', column: 'country_name', datasetId: 2 },
|
||||
]);
|
||||
enterNativeFilterEditModal();
|
||||
cy.getBySel('filters-config-modal__name-input').type('|EDITED', {
|
||||
force: true,
|
||||
});
|
||||
cancelNativeFilterSettings();
|
||||
enterNativeFilterEditModal(false);
|
||||
cy.get(nativeFilters.filtersList.removeIcon).first().click();
|
||||
cy.contains('You have removed this filter.').should('be.visible');
|
||||
});
|
||||
|
||||
it('User can create a value filter', () => {
|
||||
visitDashboard();
|
||||
enterNativeFilterEditModal(false);
|
||||
addCountryNameFilter();
|
||||
cy.get(nativeFilters.filtersPanel.filterTypeInput)
|
||||
.find(nativeFilters.filtersPanel.filterTypeItem)
|
||||
.should('have.text', testItems.filterType.value);
|
||||
saveNativeFilterSettings([]);
|
||||
validateFilterNameOnDashboard(testItems.topTenChart.filterColumn);
|
||||
});
|
||||
|
||||
it('User can apply value filter with selected values', () => {
|
||||
prepareDashboardFilters([
|
||||
{ name: 'country_name', column: 'country_name', datasetId: 2 },
|
||||
]);
|
||||
applyNativeFilterValueWithIndex(0, testItems.filterDefaultValue);
|
||||
cy.get(nativeFilters.applyFilter).click();
|
||||
cy.get(dataTestChartName(testItems.topTenChart.name)).within(() => {
|
||||
cy.contains(testItems.filterDefaultValue).should('be.visible');
|
||||
cy.contains(testItems.filterOtherCountry).should('not.exist');
|
||||
});
|
||||
});
|
||||
|
||||
it('User can stop filtering when filter is removed', () => {
|
||||
prepareDashboardFilters([
|
||||
{ name: 'country_name', column: 'country_name', datasetId: 2 },
|
||||
]);
|
||||
enterNativeFilterEditModal();
|
||||
inputNativeFilterDefaultValue(testItems.filterDefaultValue);
|
||||
saveNativeFilterSettings([SAMPLE_CHART]);
|
||||
cy.get(dataTestChartName(testItems.topTenChart.name)).within(() => {
|
||||
cy.contains(testItems.filterDefaultValue).should('be.visible');
|
||||
cy.contains(testItems.filterOtherCountry).should('not.exist');
|
||||
});
|
||||
cy.get(nativeFilters.filterItem)
|
||||
.contains(testItems.filterDefaultValue)
|
||||
.should('be.visible');
|
||||
validateFilterNameOnDashboard(testItems.topTenChart.filterColumn);
|
||||
enterNativeFilterEditModal(false);
|
||||
deleteNativeFilter();
|
||||
saveNativeFilterSettings([SAMPLE_CHART]);
|
||||
cy.get(dataTestChartName(testItems.topTenChart.name)).within(() => {
|
||||
cy.contains(testItems.filterDefaultValue).should('be.visible');
|
||||
cy.contains(testItems.filterOtherCountry).should('be.visible');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,148 @@
|
||||
/**
|
||||
* 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 { SAMPLE_DASHBOARD_1 } from 'cypress/utils/urls';
|
||||
import { interceptCharts, interceptDatasets, interceptGet } from './utils';
|
||||
|
||||
export const SAMPLE_CHART = { name: 'Most Populated Countries', viz: 'table' };
|
||||
|
||||
export function visitDashboard(createSample = true) {
|
||||
interceptCharts();
|
||||
interceptGet();
|
||||
interceptDatasets();
|
||||
|
||||
if (createSample) {
|
||||
cy.createSampleDashboards([0]);
|
||||
}
|
||||
|
||||
cy.visit(SAMPLE_DASHBOARD_1);
|
||||
cy.wait('@get');
|
||||
cy.wait('@getCharts');
|
||||
cy.wait('@getDatasets');
|
||||
cy.url().should('contain', 'native_filters_key');
|
||||
}
|
||||
|
||||
export function prepareDashboardFilters(
|
||||
filters: { name: string; column: string; datasetId: number }[],
|
||||
) {
|
||||
cy.createSampleDashboards([0]);
|
||||
cy.request({
|
||||
method: 'GET',
|
||||
url: `api/v1/dashboard/1-sample-dashboard`,
|
||||
}).then(res => {
|
||||
const { body } = res;
|
||||
const dashboardId = body.result.id;
|
||||
const allFilters: Record<string, unknown>[] = [];
|
||||
filters.forEach((f, i) => {
|
||||
allFilters.push({
|
||||
id: `NATIVE_FILTER-fLH0pxFQ${i}`,
|
||||
controlValues: {
|
||||
enableEmptyFilter: false,
|
||||
defaultToFirstItem: false,
|
||||
multiSelect: true,
|
||||
searchAllOptions: false,
|
||||
inverseSelection: false,
|
||||
},
|
||||
name: f.name,
|
||||
filterType: 'filter_select',
|
||||
targets: [
|
||||
{
|
||||
datasetId: f.datasetId,
|
||||
column: { name: f.column },
|
||||
},
|
||||
],
|
||||
defaultDataMask: {
|
||||
extraFormData: {},
|
||||
filterState: {},
|
||||
ownState: {},
|
||||
},
|
||||
cascadeParentIds: [],
|
||||
scope: {
|
||||
rootPath: ['ROOT_ID'],
|
||||
excluded: [],
|
||||
},
|
||||
type: 'NATIVE_FILTER',
|
||||
description: '',
|
||||
chartsInScope: [5],
|
||||
tabsInScope: [],
|
||||
});
|
||||
});
|
||||
if (dashboardId) {
|
||||
const jsonMetadata = {
|
||||
native_filter_configuration: allFilters,
|
||||
timed_refresh_immune_slices: [],
|
||||
expanded_slices: {},
|
||||
refresh_frequency: 0,
|
||||
color_scheme: '',
|
||||
label_colors: {},
|
||||
shared_label_colors: {},
|
||||
color_scheme_domain: [],
|
||||
cross_filters_enabled: false,
|
||||
positions: {
|
||||
DASHBOARD_VERSION_KEY: 'v2',
|
||||
ROOT_ID: { type: 'ROOT', id: 'ROOT_ID', children: ['GRID_ID'] },
|
||||
GRID_ID: {
|
||||
type: 'GRID',
|
||||
id: 'GRID_ID',
|
||||
children: ['ROW-0rHnUz4nMA'],
|
||||
parents: ['ROOT_ID'],
|
||||
},
|
||||
HEADER_ID: {
|
||||
id: 'HEADER_ID',
|
||||
type: 'HEADER',
|
||||
meta: { text: '1 - Sample dashboard' },
|
||||
},
|
||||
'CHART-DF6EfI55F-': {
|
||||
type: 'CHART',
|
||||
id: 'CHART-DF6EfI55F-',
|
||||
children: [],
|
||||
parents: ['ROOT_ID', 'GRID_ID', 'ROW-0rHnUz4nMA'],
|
||||
meta: {
|
||||
width: 4,
|
||||
height: 50,
|
||||
chartId: 5,
|
||||
sliceName: 'Most Populated Countries',
|
||||
},
|
||||
},
|
||||
'ROW-0rHnUz4nMA': {
|
||||
type: 'ROW',
|
||||
id: 'ROW-0rHnUz4nMA',
|
||||
children: ['CHART-DF6EfI55F-'],
|
||||
parents: ['ROOT_ID', 'GRID_ID'],
|
||||
meta: { background: 'BACKGROUND_TRANSPARENT' },
|
||||
},
|
||||
},
|
||||
default_filters: '{}',
|
||||
filter_scopes: {},
|
||||
chart_configuration: {},
|
||||
};
|
||||
|
||||
return cy
|
||||
.request({
|
||||
method: 'PUT',
|
||||
url: `api/v1/dashboard/${dashboardId}`,
|
||||
body: {
|
||||
json_metadata: JSON.stringify(jsonMetadata),
|
||||
},
|
||||
})
|
||||
.then(() => visitDashboard(false));
|
||||
}
|
||||
return cy;
|
||||
});
|
||||
}
|
||||
@@ -378,7 +378,7 @@ export function cancelNativeFilterSettings() {
|
||||
.should('be.visible')
|
||||
.should('have.text', 'There are unsaved changes.');
|
||||
cy.get(nativeFilters.modal.footer)
|
||||
.find(nativeFilters.modal.yesCancelButton)
|
||||
.find(nativeFilters.modal.confirmCancelButton)
|
||||
.contains('cancel')
|
||||
.click({ force: true });
|
||||
cy.get(nativeFilters.modal.container).should('not.exist');
|
||||
|
||||
@@ -25,7 +25,7 @@ describe('AdhocMetrics', () => {
|
||||
});
|
||||
|
||||
it('Clear metric and set simple adhoc metric', () => {
|
||||
const metric = 'SUM(num_girls)';
|
||||
const metric = 'sum(num_girls)';
|
||||
const metricName = 'Sum Girls';
|
||||
cy.get('[data-test=metrics]')
|
||||
.find('[data-test="remove-control-button"]')
|
||||
|
||||
@@ -100,7 +100,7 @@ describe('Visualization > Table', () => {
|
||||
});
|
||||
cy.verifySliceSuccess({
|
||||
waitAlias: '@chartData',
|
||||
querySubstring: /group by\n.*name/i,
|
||||
querySubstring: /GROUP BY.*name/i,
|
||||
chartSelector: 'table',
|
||||
});
|
||||
});
|
||||
@@ -247,7 +247,7 @@ describe('Visualization > Table', () => {
|
||||
cy.visitChartByParams(formData);
|
||||
cy.verifySliceSuccess({
|
||||
waitAlias: '@chartData',
|
||||
querySubstring: /group by\n.*state/i,
|
||||
querySubstring: /GROUP BY.*state/i,
|
||||
chartSelector: 'table',
|
||||
});
|
||||
cy.get('td').contains(/\d*%/);
|
||||
|
||||
@@ -322,7 +322,9 @@ export const nativeFilters = {
|
||||
footer: '.ant-modal-footer',
|
||||
saveButton: dataTestLocator('native-filter-modal-save-button'),
|
||||
cancelButton: dataTestLocator('native-filter-modal-cancel-button'),
|
||||
yesCancelButton: '[type="button"]',
|
||||
confirmCancelButton: dataTestLocator(
|
||||
'native-filter-modal-confirm-cancel-button',
|
||||
),
|
||||
alertXUnsavedFilters: '.ant-alert-message',
|
||||
tabsList: {
|
||||
filterItemsContainer: dataTestLocator('filter-title-container'),
|
||||
|
||||
742
superset-frontend/cypress-base/package-lock.json
generated
742
superset-frontend/cypress-base/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -56,7 +56,7 @@ module.exports = {
|
||||
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json'],
|
||||
snapshotSerializers: ['@emotion/jest/enzyme-serializer'],
|
||||
transformIgnorePatterns: [
|
||||
'node_modules/(?!d3-(interpolate|color|time)|remark-gfm|markdown-table|micromark-*.|decode-named-character-reference|character-entities|mdast-util-*.|unist-util-*.|ccount|escape-string-regexp|nanoid|@rjsf/*.|sinon|echarts|zrender)',
|
||||
'node_modules/(?!d3-(interpolate|color|time)|remark-gfm|markdown-table|micromark-*.|decode-named-character-reference|character-entities|mdast-util-*.|unist-util-*.|ccount|escape-string-regexp|nanoid|@rjsf/*.|sinon|echarts|zrender|fetch-mock|pretty-ms|parse-ms)',
|
||||
],
|
||||
globals: {
|
||||
__DEV__: true,
|
||||
|
||||
7387
superset-frontend/package-lock.json
generated
7387
superset-frontend/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -44,8 +44,8 @@
|
||||
"build-storybook": "storybook build",
|
||||
"build-translation": "scripts/po2json.sh",
|
||||
"bundle-stats": "cross-env BUNDLE_ANALYZER=true npm run build && npx open-cli ../superset/static/stats/statistics.html",
|
||||
"core:cover": "cross-env NODE_ENV=test jest --coverage --coverageThreshold='{\"global\":{\"statements\":100,\"branches\":100,\"functions\":100,\"lines\":100}}' --collectCoverageFrom='[\"packages/**/src/**/*.{js,ts}\", \"!packages/superset-ui-demo/**/*\"]' packages",
|
||||
"cover": "cross-env NODE_ENV=test jest --coverage",
|
||||
"core:cover": "cross-env NODE_ENV=test NODE_OPTIONS=\"--max-old-space-size=4096\" jest --coverage --coverageThreshold='{\"global\":{\"statements\":100,\"branches\":100,\"functions\":100,\"lines\":100}}' --collectCoverageFrom='[\"packages/**/src/**/*.{js,ts}\", \"!packages/superset-ui-demo/**/*\"]' packages",
|
||||
"cover": "cross-env NODE_ENV=test NODE_OPTIONS=\"--max-old-space-size=4096\" jest --coverage",
|
||||
"dev": "webpack --mode=development --color --watch",
|
||||
"dev-server": "cross-env NODE_ENV=development BABEL_ENV=development node --max_old_space_size=4096 ./node_modules/webpack-dev-server/bin/webpack-dev-server.js --mode=development",
|
||||
"eslint": "eslint --ignore-path=.eslintignore --ext .js,.jsx,.ts,tsx",
|
||||
@@ -65,10 +65,10 @@
|
||||
"prettier": "npm run _prettier -- --write",
|
||||
"prettier-check": "npm run _prettier -- --check",
|
||||
"prod": "npm run build",
|
||||
"prune": "rm -rf ./{packages,plugins}/*/{lib,esm,tsconfig.tsbuildinfo,package-lock.json}",
|
||||
"prune": "rm -rf ./{packages,plugins}/*/{node_modules,lib,esm,tsconfig.tsbuildinfo,package-lock.json} ./.temp_cache",
|
||||
"storybook": "cross-env NODE_ENV=development BABEL_ENV=development storybook dev -p 6006",
|
||||
"tdd": "cross-env NODE_ENV=test jest --watch",
|
||||
"test": "cross-env NODE_ENV=test jest --max-workers=50%",
|
||||
"tdd": "cross-env NODE_ENV=test NODE_OPTIONS=\"--max-old-space-size=4096\" jest --watch",
|
||||
"test": "cross-env NODE_ENV=test NODE_OPTIONS=\"--max-old-space-size=4096\" jest --max-workers=50%",
|
||||
"type": "tsc --noEmit",
|
||||
"update-maps": "jupyter nbconvert --to notebook --execute --inplace 'plugins/legacy-plugin-chart-country-map/scripts/Country Map GeoJSON Generator.ipynb' -Xfrozen_modules=off",
|
||||
"validate-release": "../RELEASING/validate_this_release.sh"
|
||||
@@ -82,14 +82,14 @@
|
||||
"dependencies": {
|
||||
"@ant-design/icons": "^5.2.6",
|
||||
"@emotion/cache": "^11.4.0",
|
||||
"@emotion/react": "^11.13.0",
|
||||
"@emotion/react": "^11.13.3",
|
||||
"@emotion/styled": "^11.3.0",
|
||||
"@fontsource/fira-code": "^5.0.18",
|
||||
"@fontsource/inter": "^5.0.20",
|
||||
"@reduxjs/toolkit": "^1.9.3",
|
||||
"@rjsf/core": "^5.19.3",
|
||||
"@rjsf/core": "^5.21.1",
|
||||
"@rjsf/utils": "^5.19.3",
|
||||
"@rjsf/validator-ajv8": "^5.19.3",
|
||||
"@rjsf/validator-ajv8": "^5.22.3",
|
||||
"@scarf/scarf": "^1.3.0",
|
||||
"@superset-ui/chart-controls": "file:./packages/superset-ui-chart-controls",
|
||||
"@superset-ui/core": "file:./packages/superset-ui-core",
|
||||
@@ -125,7 +125,7 @@
|
||||
"@visx/tooltip": "^3.0.0",
|
||||
"@visx/xychart": "^3.5.1",
|
||||
"abortcontroller-polyfill": "^1.7.5",
|
||||
"ace-builds": "^1.35.4",
|
||||
"ace-builds": "^1.36.3",
|
||||
"antd": "4.10.3",
|
||||
"antd-v5": "npm:antd@^5.18.0",
|
||||
"babel-plugin-typescript-to-proptypes": "^2.0.0",
|
||||
@@ -135,7 +135,9 @@
|
||||
"classnames": "^2.2.5",
|
||||
"core-js": "^3.38.1",
|
||||
"d3-scale": "^2.1.2",
|
||||
"dayjs": "^1.11.13",
|
||||
"dom-to-image-more": "^3.2.0",
|
||||
"dom-to-pdf": "^0.3.2",
|
||||
"emotion-rgba": "0.0.12",
|
||||
"fast-glob": "^3.3.2",
|
||||
"fs-extra": "^11.2.0",
|
||||
@@ -151,6 +153,7 @@
|
||||
"json-bigint": "^1.0.0",
|
||||
"json-stringify-pretty-compact": "^2.0.0",
|
||||
"lodash": "^4.17.21",
|
||||
"luxon": "^3.5.0",
|
||||
"mapbox-gl": "^2.10.0",
|
||||
"markdown-to-jsx": "^7.4.7",
|
||||
"match-sorter": "^6.3.4",
|
||||
@@ -164,7 +167,7 @@
|
||||
"prop-types": "^15.8.1",
|
||||
"query-string": "^6.13.7",
|
||||
"rc-trigger": "^5.3.4",
|
||||
"re-resizable": "^6.9.11",
|
||||
"re-resizable": "^6.10.0",
|
||||
"react": "^16.13.1",
|
||||
"react-ace": "^10.1.0",
|
||||
"react-checkbox-tree": "^1.8.0",
|
||||
@@ -210,7 +213,7 @@
|
||||
"yargs": "^17.7.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@applitools/eyes-storybook": "^3.50.7",
|
||||
"@applitools/eyes-storybook": "^3.50.9",
|
||||
"@babel/cli": "^7.22.6",
|
||||
"@babel/compat-data": "^7.22.6",
|
||||
"@babel/core": "^7.23.9",
|
||||
@@ -226,7 +229,7 @@
|
||||
"@babel/preset-react": "^7.22.5",
|
||||
"@babel/register": "^7.23.7",
|
||||
"@babel/types": "^7.24.9",
|
||||
"@cypress/react": "^5.10.0",
|
||||
"@cypress/react": "^8.0.2",
|
||||
"@emotion/babel-plugin": "^11.11.0",
|
||||
"@emotion/jest": "^11.11.0",
|
||||
"@hot-loader/react-dom": "^16.14.0",
|
||||
@@ -243,10 +246,10 @@
|
||||
"@storybook/react-webpack5": "8.1.11",
|
||||
"@svgr/webpack": "^8.1.0",
|
||||
"@testing-library/dom": "^8.20.1",
|
||||
"@testing-library/jest-dom": "^5.11.6",
|
||||
"@testing-library/jest-dom": "^6.5.0",
|
||||
"@testing-library/react": "^12.1.5",
|
||||
"@testing-library/react-hooks": "^5.1.3",
|
||||
"@testing-library/user-event": "^12.7.0",
|
||||
"@testing-library/react-hooks": "^8.0.1",
|
||||
"@testing-library/user-event": "^12.8.3",
|
||||
"@types/classnames": "^2.2.10",
|
||||
"@types/dom-to-image": "^2.6.7",
|
||||
"@types/enzyme": "^3.10.18",
|
||||
@@ -261,7 +264,7 @@
|
||||
"@types/react-dom": "^16.9.8",
|
||||
"@types/react-gravatar": "^2.6.14",
|
||||
"@types/react-json-tree": "^0.6.11",
|
||||
"@types/react-loadable": "^5.5.6",
|
||||
"@types/react-loadable": "^5.5.11",
|
||||
"@types/react-redux": "^7.1.10",
|
||||
"@types/react-router-dom": "^5.3.3",
|
||||
"@types/react-syntax-highlighter": "^15.5.13",
|
||||
@@ -290,13 +293,13 @@
|
||||
"enzyme": "^3.11.0",
|
||||
"enzyme-adapter-react-16": "^1.15.7",
|
||||
"esbuild": "^0.20.0",
|
||||
"esbuild-loader": "^4.1.0",
|
||||
"esbuild-loader": "^4.2.2",
|
||||
"eslint": "^8.56.0",
|
||||
"eslint-config-airbnb": "^19.0.4",
|
||||
"eslint-config-prettier": "^7.2.0",
|
||||
"eslint-import-resolver-typescript": "^3.6.1",
|
||||
"eslint-import-resolver-typescript": "^3.6.3",
|
||||
"eslint-plugin-cypress": "^3.5.0",
|
||||
"eslint-plugin-file-progress": "^1.4.0",
|
||||
"eslint-plugin-file-progress": "^1.5.0",
|
||||
"eslint-plugin-import": "^2.24.2",
|
||||
"eslint-plugin-jest": "^27.8.0",
|
||||
"eslint-plugin-jest-dom": "^3.6.5",
|
||||
@@ -304,11 +307,11 @@
|
||||
"eslint-plugin-lodash": "^7.4.0",
|
||||
"eslint-plugin-no-only-tests": "^3.3.0",
|
||||
"eslint-plugin-prettier": "^5.1.3",
|
||||
"eslint-plugin-react": "^7.22.0",
|
||||
"eslint-plugin-react": "^7.37.2",
|
||||
"eslint-plugin-react-hooks": "^4.6.0",
|
||||
"eslint-plugin-react-prefer-function-component": "^3.3.0",
|
||||
"eslint-plugin-storybook": "^0.8.0",
|
||||
"eslint-plugin-testing-library": "^6.2.2",
|
||||
"eslint-plugin-testing-library": "^6.4.0",
|
||||
"eslint-plugin-theme-colors": "file:tools/eslint-plugin-theme-colors",
|
||||
"eslint-plugin-translation-vars": "file:tools/eslint-plugin-translation-vars",
|
||||
"exports-loader": "^5.0.0",
|
||||
@@ -334,7 +337,7 @@
|
||||
"open-cli": "^8.0.0",
|
||||
"po2json": "^0.4.5",
|
||||
"prettier": "3.3.3",
|
||||
"prettier-plugin-packagejson": "^2.5.2",
|
||||
"prettier-plugin-packagejson": "^2.5.3",
|
||||
"process": "^0.11.10",
|
||||
"react-resizable": "^3.0.5",
|
||||
"react-test-renderer": "^16.14.0",
|
||||
@@ -353,7 +356,7 @@
|
||||
"webpack-bundle-analyzer": "^4.10.1",
|
||||
"webpack-cli": "^4.10.0",
|
||||
"webpack-dev-server": "^4.15.1",
|
||||
"webpack-manifest-plugin": "^4.1.1",
|
||||
"webpack-manifest-plugin": "^5.0.0",
|
||||
"webpack-sources": "^3.2.3",
|
||||
"webpack-visualizer-plugin2": "^1.1.0",
|
||||
"xdm": "^3.4.0"
|
||||
|
||||
@@ -3,4 +3,5 @@ module.exports = {
|
||||
moduleNameMapper: {
|
||||
'\\.(gif|ttf|eot|png|jpg)$': '<rootDir>/test/__mocks__/mockExportString.js',
|
||||
},
|
||||
testEnvironment: 'jsdom',
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -37,6 +37,7 @@
|
||||
"@babel/cli": "^7.16.0",
|
||||
"@types/jest": "^26.0.4",
|
||||
"jest": "^29.7.0",
|
||||
"jest-environment-jsdom": "^29.7.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"typescript": "^4.1.2"
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
import { t, validateNonEmpty } from '@superset-ui/core';
|
||||
import {
|
||||
ControlPanelConfig,
|
||||
sections,
|
||||
sharedControls,
|
||||
} from '@superset-ui/chart-controls';
|
||||
|
||||
|
||||
@@ -35,10 +35,10 @@
|
||||
"@emotion/react": "^11.4.1",
|
||||
"@superset-ui/core": "*",
|
||||
"@testing-library/dom": "^8.20.1",
|
||||
"@testing-library/jest-dom": "^5.11.6",
|
||||
"@testing-library/jest-dom": "*",
|
||||
"@testing-library/react": "^12.1.5",
|
||||
"@testing-library/react-hooks": "^5.0.3",
|
||||
"@testing-library/user-event": "^12.7.0",
|
||||
"@testing-library/react-hooks": "*",
|
||||
"@testing-library/user-event": "*",
|
||||
"ace-builds": "^1.4.14",
|
||||
"antd": "4.10.3",
|
||||
"brace": "^0.11.1",
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
* under the License.
|
||||
*/
|
||||
import { useState, ReactNode, useLayoutEffect, RefObject } from 'react';
|
||||
import { css, styled, SupersetTheme } from '@superset-ui/core';
|
||||
import { css, SafeMarkdown, styled, SupersetTheme } from '@superset-ui/core';
|
||||
import { Tooltip } from './Tooltip';
|
||||
import { ColumnTypeLabel } from './ColumnTypeLabel/ColumnTypeLabel';
|
||||
import CertifiedIconWithTooltip from './CertifiedIconWithTooltip';
|
||||
@@ -28,6 +28,7 @@ import {
|
||||
getColumnTypeTooltipNode,
|
||||
} from './labelUtils';
|
||||
import { SQLPopover } from './SQLPopover';
|
||||
import InfoTooltipWithTrigger from './InfoTooltipWithTrigger';
|
||||
|
||||
export type ColumnOptionProps = {
|
||||
column: ColumnMeta;
|
||||
@@ -50,6 +51,8 @@ export function ColumnOption({
|
||||
}: ColumnOptionProps) {
|
||||
const { expression, column_name, type_generic } = column;
|
||||
const hasExpression = expression && expression !== column_name;
|
||||
const warningMarkdown =
|
||||
column.warning_markdown || column.warning_text || column.error_text;
|
||||
const type = hasExpression ? 'expression' : type_generic;
|
||||
const [tooltipText, setTooltipText] = useState<ReactNode>(column.column_name);
|
||||
const [columnTypeTooltipText, setcolumnTypeTooltipText] = useState<ReactNode>(
|
||||
@@ -94,6 +97,19 @@ export function ColumnOption({
|
||||
details={column.certification_details}
|
||||
/>
|
||||
)}
|
||||
{warningMarkdown && (
|
||||
<InfoTooltipWithTrigger
|
||||
className="text-warning"
|
||||
icon="warning"
|
||||
tooltip={<SafeMarkdown source={warningMarkdown} />}
|
||||
label={`warn-${column.column_name}`}
|
||||
iconsStyle={{ marginLeft: 0 }}
|
||||
{...(column.error_text && {
|
||||
className: 'text-danger',
|
||||
icon: 'exclamation-circle',
|
||||
})}
|
||||
/>
|
||||
)}
|
||||
</StyleOverrides>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -81,7 +81,8 @@ export function MetricOption({
|
||||
</span>
|
||||
);
|
||||
|
||||
const warningMarkdown = metric.warning_markdown || metric.warning_text;
|
||||
const warningMarkdown =
|
||||
metric.warning_markdown || metric.warning_text || metric.error_text;
|
||||
|
||||
const [tooltipText, setTooltipText] = useState<ReactNode>(metric.metric_name);
|
||||
|
||||
@@ -116,6 +117,10 @@ export function MetricOption({
|
||||
tooltip={<SafeMarkdown source={warningMarkdown} />}
|
||||
label={`warn-${metric.metric_name}`}
|
||||
iconsStyle={{ marginLeft: 0 }}
|
||||
{...(metric.error_text && {
|
||||
className: 'text-danger',
|
||||
icon: 'exclamation-circle',
|
||||
})}
|
||||
/>
|
||||
)}
|
||||
</FlexRowContainer>
|
||||
|
||||
@@ -55,8 +55,7 @@ const TooltipSection = ({
|
||||
text: ReactNode;
|
||||
}) => (
|
||||
<TooltipSectionWrapper>
|
||||
<TooltipSectionLabel>{label}</TooltipSectionLabel>
|
||||
<span>{text}</span>
|
||||
<TooltipSectionLabel>{label}</TooltipSectionLabel>: <span>{text}</span>
|
||||
</TooltipSectionWrapper>
|
||||
);
|
||||
|
||||
@@ -71,12 +70,7 @@ export const getColumnTypeTooltipNode = (column: ColumnMeta): ReactNode => {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<TooltipSection
|
||||
label={t('Column datatype')}
|
||||
text={column.type.toLowerCase()}
|
||||
/>
|
||||
);
|
||||
return <TooltipSection label={t('Column type')} text={column.type} />;
|
||||
};
|
||||
|
||||
export const getColumnTooltipNode = (
|
||||
|
||||
@@ -80,3 +80,6 @@ export const DEFAULT_XAXIS_SORT_SERIES_DATA: SortSeriesData = {
|
||||
};
|
||||
|
||||
export const DEFAULT_DATE_PATTERN = /\d{4}-\d{2}-\d{2}/g;
|
||||
|
||||
// When moment fails to parse a date
|
||||
export const INVALID_DATE = 'Invalid date';
|
||||
|
||||
@@ -18,7 +18,12 @@
|
||||
*/
|
||||
import { t, ComparisonType } from '@superset-ui/core';
|
||||
|
||||
import { ControlPanelSectionConfig } from '../types';
|
||||
import {
|
||||
ControlPanelSectionConfig,
|
||||
ControlPanelState,
|
||||
ControlState,
|
||||
} from '../types';
|
||||
import { INVALID_DATE } from '..';
|
||||
|
||||
const fullChoices = [
|
||||
['1 day ago', t('1 day ago')],
|
||||
@@ -94,9 +99,28 @@ export const timeComparisonControls: ({
|
||||
name: 'start_date_offset',
|
||||
config: {
|
||||
type: 'TimeOffsetControl',
|
||||
label: t('shift start date'),
|
||||
label: t('Shift start date'),
|
||||
visibility: ({ controls }) =>
|
||||
controls?.time_compare.value === 'custom',
|
||||
mapStateToProps: (
|
||||
state: ControlPanelState,
|
||||
controlState: ControlState,
|
||||
) => {
|
||||
const { form_data } = state;
|
||||
const { time_compare } = form_data;
|
||||
const newState = { ...controlState };
|
||||
if (
|
||||
time_compare === 'custom' &&
|
||||
(controlState.value === '' || controlState.value === INVALID_DATE)
|
||||
) {
|
||||
newState.externalValidationErrors = [
|
||||
t('A date is required when using custom date shift'),
|
||||
];
|
||||
} else {
|
||||
newState.externalValidationErrors = [];
|
||||
}
|
||||
return newState;
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
@@ -39,6 +39,7 @@ import {
|
||||
SORT_SERIES_CHOICES,
|
||||
} from '../constants';
|
||||
import { checkColumnType } from '../utils/checkColumnType';
|
||||
import { isSortable } from '../utils/isSortable';
|
||||
|
||||
export const contributionModeControl = {
|
||||
name: 'contributionMode',
|
||||
@@ -55,27 +56,6 @@ export const contributionModeControl = {
|
||||
},
|
||||
};
|
||||
|
||||
function isForcedCategorical(controls: ControlStateMapping): boolean {
|
||||
return (
|
||||
checkColumnType(
|
||||
getColumnLabel(controls?.x_axis?.value as QueryFormColumn),
|
||||
controls?.datasource?.datasource,
|
||||
[GenericDataType.Numeric],
|
||||
) && !!controls?.xAxisForceCategorical?.value
|
||||
);
|
||||
}
|
||||
|
||||
function isSortable(controls: ControlStateMapping): boolean {
|
||||
return (
|
||||
isForcedCategorical(controls) ||
|
||||
checkColumnType(
|
||||
getColumnLabel(controls?.x_axis?.value as QueryFormColumn),
|
||||
controls?.datasource?.datasource,
|
||||
[GenericDataType.String, GenericDataType.Boolean],
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
const xAxisSortVisibility = ({ controls }: { controls: ControlStateMapping }) =>
|
||||
isSortable(controls) &&
|
||||
ensureIsArray(controls?.groupby?.value).length === 0 &&
|
||||
|
||||
@@ -83,6 +83,7 @@ export interface Dataset {
|
||||
owners?: Owner[];
|
||||
filter_select?: boolean;
|
||||
filter_select_enabled?: boolean;
|
||||
column_names?: string[];
|
||||
}
|
||||
|
||||
export interface ControlPanelState {
|
||||
|
||||
@@ -57,6 +57,9 @@ export const D3_FORMAT_OPTIONS: [string, string][] = [
|
||||
...d3Formatted,
|
||||
['DURATION', t('Duration in ms (66000 => 1m 6s)')],
|
||||
['DURATION_SUB', t('Duration in ms (1.40008 => 1ms 400µs 80ns)')],
|
||||
['DURATION_COL', t('Duration in ms (10500 => 0:10.5)')],
|
||||
['MEMORY_DECIMAL', t('Memory in bytes - decimal (1024B => 1.024kB)')],
|
||||
['MEMORY_BINARY', t('Memory in bytes - binary (1024B => 1KiB)')],
|
||||
];
|
||||
|
||||
export const D3_TIME_FORMAT_DOCS = t(
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import {
|
||||
GenericDataType,
|
||||
getColumnLabel,
|
||||
isPhysicalColumn,
|
||||
QueryFormColumn,
|
||||
} from '@superset-ui/core';
|
||||
import { checkColumnType, ControlStateMapping } from '..';
|
||||
|
||||
export function isSortable(controls: ControlStateMapping): boolean {
|
||||
const isForcedCategorical =
|
||||
checkColumnType(
|
||||
getColumnLabel(controls?.x_axis?.value as QueryFormColumn),
|
||||
controls?.datasource?.datasource,
|
||||
[GenericDataType.Numeric],
|
||||
) && !!controls?.xAxisForceCategorical?.value;
|
||||
|
||||
const xAxisValue = controls?.x_axis?.value as QueryFormColumn;
|
||||
|
||||
// Given that we don't know the type of a custom SQL column,
|
||||
// we treat it as sortable and give the responsibility to the
|
||||
// user to provide a sortable result.
|
||||
const isCustomSQL = !isPhysicalColumn(xAxisValue);
|
||||
|
||||
return (
|
||||
isForcedCategorical ||
|
||||
isCustomSQL ||
|
||||
checkColumnType(
|
||||
getColumnLabel(xAxisValue),
|
||||
controls?.datasource?.datasource,
|
||||
[GenericDataType.String, GenericDataType.Boolean],
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -34,6 +34,9 @@ jest.mock('../../src/components/ColumnTypeLabel/ColumnTypeLabel', () => ({
|
||||
<div data-test="mock-column-type-label">{type}</div>
|
||||
),
|
||||
}));
|
||||
jest.mock('../../src/components/InfoTooltipWithTrigger', () => () => (
|
||||
<div data-test="mock-info-tooltip-with-trigger" />
|
||||
));
|
||||
|
||||
const defaultProps: ColumnOptionProps = {
|
||||
column: {
|
||||
@@ -111,3 +114,17 @@ test('dttm column has correct column label if showType is true', () => {
|
||||
String(GenericDataType.Temporal),
|
||||
);
|
||||
});
|
||||
test('doesnt show InfoTooltipWithTrigger when no warning', () => {
|
||||
const { queryByText } = setup();
|
||||
expect(queryByText('mock-info-tooltip-with-trigger')).not.toBeInTheDocument();
|
||||
});
|
||||
test('shows a warning with InfoTooltipWithTrigger when it contains warning', () => {
|
||||
const { getByTestId } = setup({
|
||||
...defaultProps,
|
||||
column: {
|
||||
...defaultProps.column,
|
||||
warning_text: 'This is a warning',
|
||||
},
|
||||
});
|
||||
expect(getByTestId('mock-info-tooltip-with-trigger')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
@@ -90,7 +90,7 @@ test('should get column datatype rendered as tooltip when column has a type', ()
|
||||
</>,
|
||||
);
|
||||
|
||||
expect(screen.getByText('Column datatype')).toBeVisible();
|
||||
expect(screen.getByText('Column type')).toBeVisible();
|
||||
expect(screen.getByText('text')).toBeVisible();
|
||||
});
|
||||
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
* 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 { ControlStateMapping } from '@superset-ui/chart-controls';
|
||||
import { GenericDataType } from '@superset-ui/core';
|
||||
import { isSortable } from '../../src/utils/isSortable';
|
||||
|
||||
const controls: ControlStateMapping = {
|
||||
datasource: {
|
||||
datasource: {
|
||||
columns: [
|
||||
{ column_name: 'a', type_generic: GenericDataType.String },
|
||||
{ column_name: 'b', type_generic: GenericDataType.Numeric },
|
||||
{ column_name: 'c', type_generic: GenericDataType.Boolean },
|
||||
],
|
||||
},
|
||||
type: 'Select',
|
||||
},
|
||||
};
|
||||
|
||||
test('should return true if the column is forced to be categorical', () => {
|
||||
const c: ControlStateMapping = {
|
||||
...controls,
|
||||
x_axis: { value: 'b', type: 'Select' },
|
||||
xAxisForceCategorical: { value: true, type: 'Checkbox' },
|
||||
};
|
||||
expect(isSortable(c)).toBe(true);
|
||||
});
|
||||
|
||||
test('should return true if the column is a custom SQL column', () => {
|
||||
const c: ControlStateMapping = {
|
||||
...controls,
|
||||
x_axis: {
|
||||
value: { label: 'custom_sql', sqlExpression: 'MAX(ID)' },
|
||||
type: 'Select',
|
||||
},
|
||||
};
|
||||
expect(isSortable(c)).toBe(true);
|
||||
});
|
||||
|
||||
test('should return true if the column type is String or Boolean', () => {
|
||||
const c: ControlStateMapping = {
|
||||
...controls,
|
||||
x_axis: { value: 'c', type: 'Checkbox' },
|
||||
};
|
||||
expect(isSortable(c)).toBe(true);
|
||||
});
|
||||
|
||||
test('should return false if none of the conditions are met', () => {
|
||||
const c: ControlStateMapping = {
|
||||
...controls,
|
||||
x_axis: { value: 'b', type: 'Input' },
|
||||
};
|
||||
expect(isSortable(c)).toBe(false);
|
||||
});
|
||||
@@ -25,21 +25,7 @@
|
||||
],
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.25.6",
|
||||
"@testing-library/react-hooks": "^5.1.3",
|
||||
"@types/d3-format": "^1.3.0",
|
||||
"@types/d3-interpolate": "^3.0.4",
|
||||
"@types/d3-scale": "^2.1.1",
|
||||
"@types/d3-time": "^3.0.3",
|
||||
"@types/d3-time-format": "^4.0.3",
|
||||
"@types/enzyme": "^3.10.18",
|
||||
"@types/fetch-mock": "^7.3.8",
|
||||
"@types/json-bigint": "^1.0.4",
|
||||
"@types/lodash": "^4.17.7",
|
||||
"@types/math-expression-evaluator": "^1.3.3",
|
||||
"@types/node": "^22.5.4",
|
||||
"@types/prop-types": "^15.7.2",
|
||||
"@types/rison": "0.0.9",
|
||||
"@types/seedrandom": "^3.0.8",
|
||||
"@vx/responsive": "^0.0.199",
|
||||
"csstype": "^3.1.3",
|
||||
"d3-format": "^1.3.2",
|
||||
@@ -49,9 +35,9 @@
|
||||
"d3-time-format": "^4.1.0",
|
||||
"fetch-retry": "^6.0.0",
|
||||
"jed": "^1.1.1",
|
||||
"lodash": "^4.17.11",
|
||||
"lodash": "^4.17.21",
|
||||
"math-expression-evaluator": "^1.3.8",
|
||||
"pretty-ms": "^7.0.0",
|
||||
"pretty-ms": "^9.1.0",
|
||||
"react-error-boundary": "^1.2.5",
|
||||
"react-markdown": "^8.0.7",
|
||||
"rehype-raw": "^7.0.0",
|
||||
@@ -65,8 +51,21 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@emotion/styled": "^11.3.0",
|
||||
"fetch-mock": "^6.5.2",
|
||||
"jest-mock-console": "^1.0.0",
|
||||
"@types/d3-format": "^1.3.0",
|
||||
"@types/d3-interpolate": "^3.0.4",
|
||||
"@types/d3-scale": "^2.1.1",
|
||||
"@types/d3-time": "^3.0.3",
|
||||
"@types/d3-time-format": "^4.0.3",
|
||||
"@types/enzyme": "^3.10.18",
|
||||
"@types/fetch-mock": "^7.3.8",
|
||||
"@types/lodash": "^4.17.7",
|
||||
"@types/math-expression-evaluator": "^1.3.3",
|
||||
"@types/node": "^22.5.4",
|
||||
"@types/prop-types": "^15.7.2",
|
||||
"@types/rison": "0.0.9",
|
||||
"@types/seedrandom": "^3.0.8",
|
||||
"fetch-mock": "^11.1.4",
|
||||
"jest-mock-console": "^2.0.0",
|
||||
"resize-observer-polyfill": "1.5.1",
|
||||
"timezone-mock": "1.3.6"
|
||||
},
|
||||
@@ -75,9 +74,10 @@
|
||||
"@emotion/react": "^11.4.1",
|
||||
"@emotion/styled": "^11.3.0",
|
||||
"@testing-library/dom": "^8.20.1",
|
||||
"@testing-library/jest-dom": "^5.11.6",
|
||||
"@testing-library/jest-dom": "*",
|
||||
"@testing-library/react": "^12.1.5",
|
||||
"@testing-library/user-event": "^12.7.0",
|
||||
"@testing-library/react-hooks": "*",
|
||||
"@testing-library/user-event": "*",
|
||||
"@types/react": "*",
|
||||
"@types/react-loadable": "*",
|
||||
"@types/tinycolor2": "*",
|
||||
|
||||
@@ -50,6 +50,9 @@ export interface ChartMetadataConfig {
|
||||
labelExplanation?: string | null;
|
||||
queryObjectCount?: number;
|
||||
parseMethod?: ParseMethod;
|
||||
// suppressContextMenu: true hides the default context menu for the chart.
|
||||
// This is useful for viz plugins that define their own context menu.
|
||||
suppressContextMenu?: boolean;
|
||||
}
|
||||
|
||||
export default class ChartMetadata {
|
||||
@@ -91,6 +94,8 @@ export default class ChartMetadata {
|
||||
|
||||
parseMethod: ParseMethod;
|
||||
|
||||
suppressContextMenu?: boolean;
|
||||
|
||||
constructor(config: ChartMetadataConfig) {
|
||||
const {
|
||||
name,
|
||||
@@ -111,6 +116,7 @@ export default class ChartMetadata {
|
||||
labelExplanation = null,
|
||||
queryObjectCount = 1,
|
||||
parseMethod = 'json-bigint',
|
||||
suppressContextMenu = false,
|
||||
} = config;
|
||||
|
||||
this.name = name;
|
||||
@@ -140,6 +146,7 @@ export default class ChartMetadata {
|
||||
this.labelExplanation = labelExplanation;
|
||||
this.queryObjectCount = queryObjectCount;
|
||||
this.parseMethod = parseMethod;
|
||||
this.suppressContextMenu = suppressContextMenu;
|
||||
}
|
||||
|
||||
canBeAnnotationType(type: string): boolean {
|
||||
|
||||
@@ -24,8 +24,8 @@ test('call callback the first time with undefined and value', () => {
|
||||
renderHook(props => useChangeEffect(props.value, props.callback), {
|
||||
initialProps: { value: 'value', callback },
|
||||
});
|
||||
expect(callback).toBeCalledTimes(1);
|
||||
expect(callback).nthCalledWith(1, undefined, 'value');
|
||||
expect(callback).toHaveBeenCalledTimes(1);
|
||||
expect(callback).toHaveBeenNthCalledWith(1, undefined, 'value');
|
||||
});
|
||||
|
||||
test('do not call callback 2 times if the value do not change', () => {
|
||||
@@ -37,7 +37,7 @@ test('do not call callback 2 times if the value do not change', () => {
|
||||
},
|
||||
);
|
||||
hook.rerender({ value: 'value', callback });
|
||||
expect(callback).toBeCalledTimes(1);
|
||||
expect(callback).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
test('call callback whenever the value changes', () => {
|
||||
@@ -49,6 +49,6 @@ test('call callback whenever the value changes', () => {
|
||||
},
|
||||
);
|
||||
hook.rerender({ value: 'value-2', callback });
|
||||
expect(callback).toBeCalledTimes(2);
|
||||
expect(callback).nthCalledWith(2, 'value', 'value-2');
|
||||
expect(callback).toHaveBeenCalledTimes(2);
|
||||
expect(callback).toHaveBeenNthCalledWith(2, 'value', 'value-2');
|
||||
});
|
||||
|
||||
@@ -22,7 +22,7 @@ import { useComponentDidMount } from './useComponentDidMount';
|
||||
test('the effect should only be executed on the first render', () => {
|
||||
const effect = jest.fn();
|
||||
const hook = renderHook(() => useComponentDidMount(effect));
|
||||
expect(effect).toBeCalledTimes(1);
|
||||
expect(effect).toHaveBeenCalledTimes(1);
|
||||
hook.rerender();
|
||||
expect(effect).toBeCalledTimes(1);
|
||||
expect(effect).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
@@ -24,8 +24,8 @@ test('the effect should not be executed on the first render', () => {
|
||||
const hook = renderHook(props => useComponentDidUpdate(props.effect), {
|
||||
initialProps: { effect },
|
||||
});
|
||||
expect(effect).toBeCalledTimes(0);
|
||||
expect(effect).toHaveBeenCalledTimes(0);
|
||||
const changedEffect = jest.fn();
|
||||
hook.rerender({ effect: changedEffect });
|
||||
expect(changedEffect).toBeCalledTimes(1);
|
||||
expect(changedEffect).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import prettyMsFormatter from 'pretty-ms';
|
||||
import prettyMilliseconds, { Options } from 'pretty-ms';
|
||||
import NumberFormatter from '../NumberFormatter';
|
||||
|
||||
export default function createDurationFormatter(
|
||||
@@ -26,13 +26,14 @@ export default function createDurationFormatter(
|
||||
id?: string;
|
||||
label?: string;
|
||||
multiplier?: number;
|
||||
} & prettyMsFormatter.Options = {},
|
||||
} & Options = {},
|
||||
) {
|
||||
const { description, id, label, multiplier = 1, ...prettyMsOptions } = config;
|
||||
|
||||
return new NumberFormatter({
|
||||
description,
|
||||
formatFunc: value => prettyMsFormatter(value * multiplier, prettyMsOptions),
|
||||
formatFunc: value =>
|
||||
prettyMilliseconds(value * multiplier, prettyMsOptions),
|
||||
id: id ?? 'duration_format',
|
||||
label: label ?? `Duration formatter`,
|
||||
});
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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 NumberFormatter from '../NumberFormatter';
|
||||
|
||||
export default function createMemoryFormatter(
|
||||
config: {
|
||||
description?: string;
|
||||
id?: string;
|
||||
label?: string;
|
||||
binary?: boolean;
|
||||
decimals?: number;
|
||||
} = {},
|
||||
) {
|
||||
const { description, id, label, binary, decimals = 2 } = config;
|
||||
|
||||
return new NumberFormatter({
|
||||
description,
|
||||
formatFunc: value => {
|
||||
if (value === 0) return '0B';
|
||||
|
||||
const sign = value > 0 ? '' : '-';
|
||||
const absValue = Math.abs(value);
|
||||
|
||||
const suffixes = binary
|
||||
? ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']
|
||||
: ['B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB', 'RB', 'QB'];
|
||||
const base = binary ? 1024 : 1000;
|
||||
|
||||
const i = Math.min(
|
||||
suffixes.length - 1,
|
||||
Math.floor(Math.log(absValue) / Math.log(base)),
|
||||
);
|
||||
return `${sign}${parseFloat((absValue / Math.pow(base, i)).toFixed(decimals))}${suffixes[i]}`;
|
||||
},
|
||||
id: id ?? 'memory_format',
|
||||
label: label ?? `Memory formatter`,
|
||||
});
|
||||
}
|
||||
@@ -31,5 +31,6 @@ export {
|
||||
export { default as NumberFormatterRegistry } from './NumberFormatterRegistry';
|
||||
export { default as createD3NumberFormatter } from './factories/createD3NumberFormatter';
|
||||
export { default as createDurationFormatter } from './factories/createDurationFormatter';
|
||||
export { default as createMemoryFormatter } from './factories/createMemoryFormatter';
|
||||
export { default as createSiAtMostNDigitFormatter } from './factories/createSiAtMostNDigitFormatter';
|
||||
export { default as createSmartNumberFormatter } from './factories/createSmartNumberFormatter';
|
||||
|
||||
@@ -80,6 +80,24 @@ export type Filter = {
|
||||
description: string;
|
||||
};
|
||||
|
||||
export type AppliedFilter = {
|
||||
values: {
|
||||
filters: Record<string, any>[];
|
||||
} | null;
|
||||
};
|
||||
|
||||
export type AppliedCrossFilterType = {
|
||||
filterType: undefined;
|
||||
targets: number[];
|
||||
scope: number[];
|
||||
} & AppliedFilter;
|
||||
|
||||
export type AppliedNativeFilterType = {
|
||||
filterType: 'filter_select';
|
||||
scope: number[];
|
||||
targets: Partial<NativeFilterTarget>[];
|
||||
} & AppliedFilter;
|
||||
|
||||
export type FilterWithDataMask = Filter & { dataMask: DataMaskWithId };
|
||||
|
||||
export type Divider = Partial<Omit<Filter, 'id' | 'type'>> & {
|
||||
@@ -89,6 +107,24 @@ export type Divider = Partial<Omit<Filter, 'id' | 'type'>> & {
|
||||
type: typeof NativeFilterType.Divider;
|
||||
};
|
||||
|
||||
export function isAppliedCrossFilterType(
|
||||
filterElement: AppliedCrossFilterType | AppliedNativeFilterType | Filter,
|
||||
): filterElement is AppliedCrossFilterType {
|
||||
return (
|
||||
filterElement.filterType === undefined &&
|
||||
filterElement.hasOwnProperty('values')
|
||||
);
|
||||
}
|
||||
|
||||
export function isAppliedNativeFilterType(
|
||||
filterElement: AppliedCrossFilterType | AppliedNativeFilterType | Filter,
|
||||
): filterElement is AppliedNativeFilterType {
|
||||
return (
|
||||
filterElement.filterType === 'filter_select' &&
|
||||
filterElement.hasOwnProperty('values')
|
||||
);
|
||||
}
|
||||
|
||||
export function isNativeFilter(
|
||||
filterElement: Filter | Divider,
|
||||
): filterElement is Filter {
|
||||
|
||||
@@ -71,6 +71,7 @@ export interface Metric {
|
||||
verbose_name?: string;
|
||||
warning_markdown?: Maybe<string>;
|
||||
warning_text?: Maybe<string>;
|
||||
error_text?: string;
|
||||
}
|
||||
|
||||
export function isSavedMetric(metric: any): metric is SavedMetric {
|
||||
|
||||
@@ -227,6 +227,7 @@ export const ErrorTypeEnum = {
|
||||
ASYNC_WORKERS_ERROR: 'ASYNC_WORKERS_ERROR',
|
||||
ADHOC_SUBQUERY_NOT_ALLOWED_ERROR: 'ADHOC_SUBQUERY_NOT_ALLOWED_ERROR',
|
||||
INVALID_SQL_ERROR: 'INVALID_SQL_ERROR',
|
||||
RESULT_TOO_LARGE_ERROR: 'RESULT_TOO_LARGE_ERROR',
|
||||
|
||||
// Generic errors
|
||||
GENERIC_COMMAND_ERROR: 'GENERIC_COMMAND_ERROR',
|
||||
|
||||
@@ -60,6 +60,8 @@ export enum FeatureFlag {
|
||||
UseAnalagousColors = 'USE_ANALAGOUS_COLORS',
|
||||
ForceSqlLabRunAsync = 'SQLLAB_FORCE_RUN_ASYNC',
|
||||
SlackEnableAvatars = 'SLACK_ENABLE_AVATARS',
|
||||
EnableDashboardScreenshotEndpoints = 'ENABLE_DASHBOARD_SCREENSHOT_ENDPOINTS',
|
||||
EnableDashboardDownloadWebDriverScreenshot = 'ENABLE_DASHBOARD_DOWNLOAD_WEBDRIVER_SCREENSHOT',
|
||||
}
|
||||
|
||||
export type ScheduleQueriesProps = {
|
||||
|
||||
@@ -49,7 +49,7 @@ describe('ChartClient', () => {
|
||||
chartClient = new ChartClient();
|
||||
});
|
||||
|
||||
afterEach(fetchMock.restore);
|
||||
afterEach(() => fetchMock.restore());
|
||||
|
||||
describe('new ChartClient(config)', () => {
|
||||
it('creates a client without argument', () => {
|
||||
|
||||
@@ -17,9 +17,10 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import '@testing-library/jest-dom';
|
||||
import { ComponentType } from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import mockConsole, { RestoreConsole } from 'jest-mock-console';
|
||||
import { render as renderTestComponent, screen } from '@testing-library/react';
|
||||
import createLoadableRenderer, {
|
||||
LoadableRenderer as LoadableRendererType,
|
||||
} from '../../../src/chart/components/createLoadableRenderer';
|
||||
@@ -67,7 +68,7 @@ describe('createLoadableRenderer', () => {
|
||||
it('calls onRenderSuccess when succeeds', async () => {
|
||||
const onRenderSuccess = jest.fn();
|
||||
const onRenderFailure = jest.fn();
|
||||
shallow(
|
||||
renderTestComponent(
|
||||
<LoadableRenderer
|
||||
onRenderSuccess={onRenderSuccess}
|
||||
onRenderFailure={onRenderFailure}
|
||||
@@ -95,7 +96,7 @@ describe('createLoadableRenderer', () => {
|
||||
});
|
||||
const onRenderSuccess = jest.fn();
|
||||
const onRenderFailure = jest.fn();
|
||||
shallow(
|
||||
renderTestComponent(
|
||||
<FailedRenderer
|
||||
onRenderSuccess={onRenderSuccess}
|
||||
onRenderFailure={onRenderFailure}
|
||||
@@ -122,7 +123,7 @@ describe('createLoadableRenderer', () => {
|
||||
loading,
|
||||
render,
|
||||
});
|
||||
shallow(<FailedRenderer />);
|
||||
renderTestComponent(<FailedRenderer />);
|
||||
expect(loadChartFailure).toHaveBeenCalledTimes(1);
|
||||
setTimeout(() => {
|
||||
expect(render).not.toHaveBeenCalled();
|
||||
@@ -132,12 +133,12 @@ describe('createLoadableRenderer', () => {
|
||||
|
||||
it('renders the lazy-load components', () =>
|
||||
new Promise(done => {
|
||||
const wrapper = shallow(<LoadableRenderer />);
|
||||
renderTestComponent(<LoadableRenderer />);
|
||||
// lazy-loaded component not rendered immediately
|
||||
expect(wrapper.find(TestComponent)).toHaveLength(0);
|
||||
expect(screen.queryByText('test')).not.toBeInTheDocument();
|
||||
setTimeout(() => {
|
||||
// but rendered after the component is loaded.
|
||||
expect(wrapper.find(TestComponent)).toHaveLength(1);
|
||||
expect(screen.queryByText('test')).toBeInTheDocument();
|
||||
done(undefined);
|
||||
}, 10);
|
||||
}));
|
||||
@@ -149,7 +150,7 @@ describe('createLoadableRenderer', () => {
|
||||
render: () => <div />,
|
||||
});
|
||||
|
||||
expect(() => shallow(<NeverLoadingRenderer />)).not.toThrow();
|
||||
expect(() => renderTestComponent(<NeverLoadingRenderer />)).not.toThrow();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -192,7 +192,7 @@ describe('LabelsColorMap', () => {
|
||||
labelsColorMap.updateColorMap(categoricalNamespace, 'testColors');
|
||||
const colorMap = labelsColorMap.getColorMap();
|
||||
expect(Object.fromEntries(colorMap)).not.toEqual({});
|
||||
expect(getAnalogousColorsSpy).not.toBeCalled();
|
||||
expect(getAnalogousColorsSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should use analagous colors', () => {
|
||||
@@ -207,7 +207,7 @@ describe('LabelsColorMap', () => {
|
||||
labelsColorMap.updateColorMap(categoricalNamespace, 'testColors');
|
||||
const colorMap = labelsColorMap.getColorMap();
|
||||
expect(Object.fromEntries(colorMap)).not.toEqual({});
|
||||
expect(getAnalogousColorsSpy).toBeCalled();
|
||||
expect(getAnalogousColorsSpy).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -22,13 +22,11 @@ import { SupersetClient, SupersetClientClass } from '@superset-ui/core';
|
||||
import { LOGIN_GLOB } from './fixtures/constants';
|
||||
|
||||
describe('SupersetClient', () => {
|
||||
beforeAll(() => {
|
||||
fetchMock.get(LOGIN_GLOB, { result: '' });
|
||||
});
|
||||
beforeAll(() => fetchMock.get(LOGIN_GLOB, { result: '' }));
|
||||
|
||||
afterAll(fetchMock.restore);
|
||||
afterAll(() => fetchMock.restore());
|
||||
|
||||
afterEach(SupersetClient.reset);
|
||||
afterEach(() => SupersetClient.reset());
|
||||
|
||||
it('exposes reset, configure, init, get, post, postForm, isAuthenticated, and reAuthenticate methods', () => {
|
||||
expect(typeof SupersetClient.configure).toBe('function');
|
||||
|
||||
@@ -21,11 +21,12 @@ import { SupersetClientClass, ClientConfig, CallApi } from '@superset-ui/core';
|
||||
import { LOGIN_GLOB } from './fixtures/constants';
|
||||
|
||||
describe('SupersetClientClass', () => {
|
||||
beforeAll(() => {
|
||||
beforeEach(() => {
|
||||
fetchMock.reset();
|
||||
fetchMock.get(LOGIN_GLOB, { result: '' });
|
||||
});
|
||||
|
||||
afterAll(fetchMock.restore);
|
||||
afterAll(() => fetchMock.restore());
|
||||
|
||||
describe('new SupersetClientClass()', () => {
|
||||
it('fallback protocol to https when setting only host', () => {
|
||||
@@ -78,11 +79,10 @@ describe('SupersetClientClass', () => {
|
||||
});
|
||||
|
||||
describe('.init()', () => {
|
||||
afterEach(() => {
|
||||
fetchMock.reset();
|
||||
// reset
|
||||
fetchMock.get(LOGIN_GLOB, { result: 1234 }, { overwriteRoutes: true });
|
||||
});
|
||||
beforeEach(() =>
|
||||
fetchMock.get(LOGIN_GLOB, { result: 1234 }, { overwriteRoutes: true }),
|
||||
);
|
||||
afterEach(() => fetchMock.reset());
|
||||
|
||||
it('calls api/v1/security/csrf_token/ when init() is called if no CSRF token is passed', async () => {
|
||||
expect.assertions(1);
|
||||
@@ -165,7 +165,7 @@ describe('SupersetClientClass', () => {
|
||||
});
|
||||
|
||||
describe('.isAuthenticated()', () => {
|
||||
afterEach(fetchMock.reset);
|
||||
afterEach(() => fetchMock.reset());
|
||||
|
||||
it('returns true if there is a token and false if not', async () => {
|
||||
expect.assertions(2);
|
||||
@@ -254,7 +254,8 @@ describe('SupersetClientClass', () => {
|
||||
});
|
||||
|
||||
describe('requests', () => {
|
||||
afterEach(fetchMock.reset);
|
||||
afterEach(() => fetchMock.restore());
|
||||
|
||||
const protocol = 'https:';
|
||||
const host = 'host';
|
||||
const mockGetEndpoint = '/get/url';
|
||||
@@ -272,13 +273,15 @@ describe('SupersetClientClass', () => {
|
||||
const mockTextJsonResponse = '{ "value": 9223372036854775807 }';
|
||||
const mockPayload = { json: () => Promise.resolve('payload') };
|
||||
|
||||
fetchMock.get(mockGetUrl, mockPayload);
|
||||
fetchMock.post(mockPostUrl, mockPayload);
|
||||
fetchMock.put(mockPutUrl, mockPayload);
|
||||
fetchMock.delete(mockDeleteUrl, mockPayload);
|
||||
fetchMock.delete(mockRequestUrl, mockPayload);
|
||||
fetchMock.get(mockTextUrl, mockTextJsonResponse);
|
||||
fetchMock.post(mockTextUrl, mockTextJsonResponse);
|
||||
beforeEach(() => {
|
||||
fetchMock.get(mockGetUrl, mockPayload);
|
||||
fetchMock.post(mockPostUrl, mockPayload);
|
||||
fetchMock.put(mockPutUrl, mockPayload);
|
||||
fetchMock.delete(mockDeleteUrl, mockPayload);
|
||||
fetchMock.delete(mockRequestUrl, mockPayload);
|
||||
fetchMock.get(mockTextUrl, mockTextJsonResponse);
|
||||
fetchMock.post(mockTextUrl, mockTextJsonResponse);
|
||||
});
|
||||
|
||||
it('checks for authentication before every get and post request', async () => {
|
||||
expect.assertions(6);
|
||||
@@ -623,6 +626,8 @@ describe('SupersetClientClass', () => {
|
||||
let createElement: any;
|
||||
|
||||
beforeEach(async () => {
|
||||
fetchMock.get(LOGIN_GLOB, { result: 1234 }, { overwriteRoutes: true });
|
||||
|
||||
client = new SupersetClientClass({ protocol, host });
|
||||
authSpy = jest.spyOn(SupersetClientClass.prototype, 'ensureAuth');
|
||||
await client.init();
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user